///////////////////////////////////////////////////////////////////// // (c) Gatan Inc. ///////////////////////////////////////////////////////////////////// // Interactively displays the contrast Transfer Function. // Use up & down keys to change selected value and the following keys // to select: // focus // aperture (illumination) // Cc // Cs // Energy spread // // finishes the script. // // For more details, see L. Reimer "Transmission Electron Microscopy", // Second Edition, pages 21, 83 and 225 ff // Scherzer focus is chosen as 1.19 * sqrt(Cs * lambda) ///////////////////////////////////////////////////////////////////// // last modified 10-Sept-2002 RTH image TF, info1, info2, display, final image EnvelopeChrom, EnvelopeSpatial number Cs, Dz, DE, Ub, h_, m_O, c_, E_O, lambda, eV, Cc, scherzerFocus, Ccs number key, DzInc, CsInc, DEInc, Hc, CcInc, alpha, aInc, CcsInc number displayPixels, screensizeX, screensizeY, finalDisplayPixels number ii, jj, displaytoggle, qmax number uparrow, downarrow, leftarrow, rightarrow uparrow = 30; downarrow = 31; leftarrow = 28; rightarrow = 29; string PersistentCcValue, PersistentCsValue, PersistenUbValue, PersistentAlphaValue, PersistentqmaxValue string variable, History, author h_ = 6.6256; // 10^-34 N m s m_O = 9.1091; // 10^-31 kg c_ = 2.9979; // 10^8 m/s E_O = 511; // keV eV = 1.602; // 10^-19 C Ub = 200 // kV lambda = h_*c_/(Sqrt(2*Ub*E_O + Ub*Ub) * eV) / 10 // nm Cs = 1.2 // mm Ccs = 0 // mm // scherzerFocus = 1.19 * sqrt(Cs * lambda * 1000000) // nm //defined again later // Dz = scherzerFocus // nm //defined again later Cc = 0.5 // mm DE = 1 // eV alpha = 0.1 // mrad qmax = 10 // nm^{-1} displayPixels = 626 // number of active pixels for linescan [0,...,625] finalDisplayPixels = 2048 // number of active pixels for linescan [0,...,2047] SetPersistentNumberNote("Private:AnnotationDefaults:Size", 12) // // Determine which envelop functions to use: // author = "Reimer" if(optionDown() == 1) OkDialog("For more details, see L. Reimer : ''Transmission Electron Microscopy''\n"+\ "Second Edition, pages 21, 83 and 225 ff,\nSpringer Series.\n\n" +\ "Scherzer focus is defined positive with Reimer !"); // if(TwoButtonDialog("There are slightly different equations in the literature for the envelop functions.\nWould you prefer to use the equations as given by L. Reimer or by K. Ishizuka?", "Reimer", "Ishizuka")) // author = "Reimer" // else // author = "Ishizuka" // // Ask interactively for the startup values: // GetPersistentNumberNote("TFDisplay:PersistenUbValue", Ub) GetPersistentNumberNote("TFDisplay:PersistentCsValue", Cs) GetPersistentNumberNote("TFDisplay:PersistentCcValue", Cc) GetPersistentNumberNote("TFDisplay:PersistentAlphaValue", alpha) GetPersistentNumberNote("TFDisplay:PersistentqmaxValue", qmax) if(!GetNumber("Enter value for acceleration voltage (in kV)", Ub, Ub) ) Throw(-128) if(!GetNumber("Enter value for spherical aberration coefficient (in mm)", Cs, Cs) ) Throw(-128) if(!GetNumber("Enter value for chromatic aberration coefficient (in mm)", Cc, Cc) ) Throw(-128) if(!GetNumber("Enter value for illumination aperture (in mrad)", alpha, alpha) ) Throw(-128) qmax = 1/qmax if(!GetNumber("Enter value of finest spacing to be displayed"\ + "\n\n in nm !!!!!", qmax, qmax) ) Throw(-128) qmax = 1/qmax // // Store startup values // SetPersistentNumberNote("TFDisplay:PersistenUbValue", Ub) SetPersistentNumberNote("TFDisplay:PersistentCsValue", Cs) SetPersistentNumberNote("TFDisplay:PersistentCcValue", Cc) SetPersistentNumberNote("TFDisplay:PersistentAlphaValue", alpha) SetPersistentNumberNote("TFDisplay:PersistentqmaxValue", qmax) alpha = Round(alpha * 1000)/1000 // unclear why 8 digits behind decimal appear Cs = Round(Cs*1000)/1000 // // Basic start values: // lambda = h_*c_/(Sqrt(2*Ub*E_O + Ub*Ub) * eV) / 10; scherzerFocus = Round(1.19 * sqrt(Cs * lambda * 1000000) * 1000) / 1000; Dz = scherzerFocus; // // Envelope of the transfer function ( Reimer: K_s(q) ) ILLUMINATION APERTURE // if(author == "Reimer") { EnvelopeSpatial := CreateFloatImage("Envelope II for TF", displayPixels, 1) EnvelopeSpatial = Pi() * Cs * 1000000 * lambda**2 * (qmax*icol/(displayPixels-1))**3 - Pi() * Dz * (qmax*icol/(displayPixels-1)) EnvelopeSpatial = EnvelopeSpatial*EnvelopeSpatial * alpha*alpha / (log(2) * 1000000) EnvelopeSpatial = exp(-EnvelopeSpatial) SetDisplayType(EnvelopeSpatial, 4) } if(author == "Ishizuka") { EnvelopeSpatial = 1; } // // Envelope of the transfer function ( Reimer: K_c(q) ) ENERGY SPREAD // if(author == "Reimer") { Hc = (1+Ub/E_O)/(1+Ub/(2*E_O)) * Cc * DE * 1000 / Ub // Hc in nm EnvelopeChrom := CreateFloatImage("Envelope I for TF", displayPixels, 1); EnvelopeChrom = ( Pi()*lambda*Hc*(qmax*icol/(displayPixels-1))*(qmax*icol/(displayPixels-1)) ) / ( 4*sqrt(log(2) ) )**2 // log() == ln() EnvelopeChrom = exp(-EnvelopeChrom); SetDisplayType(EnvelopeChrom, 4); } if(author == "Ishizuka") { EnvelopeChrom = 1; } // // Transfer function // e.g., (Reimer: B(q)) // TF := CreateFloatImage("Transferfunction @ " + Ub + "kV", displayPixels, 1) TF = -2 * sin( Pi()/2 * ( Cs*1000000*lambda**3 *(qmax*icol/(displayPixels-1))**4 -\ 2*Dz*lambda*(qmax*icol/(displayPixels-1))**2 ) +\ (2/3)*Ccs*1000000*lambda**5*(qmax*icol/(displayPixels-1))**6 ) display := TF * EnvelopeChrom * EnvelopeSpatial // // Display stuff for additional info (window(1)) // GetScreenSize(screenSizeX, screenSizeY) info1 := CreateFloatImage("INFO", 256, 160) info1 = 1 SetSurvey(info1, 0) SetLimits(info1, 0,1) DisplayAt(info1, screensizeX - 256 -8, 46) number textline10 = CreateTextAnnotation(info1, 0, 0,"To change the following parameters, \npress:" +\ "\n f ... focus" +\ "\n s ... spherical aberration (Cs)" +\ "\n e ... energy spread" +\ "\n a ... illumination spread (alpha_i)" +\ "\n c ... chromatic aberration (Cc)" +\ "\n tab ... TF <-> |TF|" +\ "\n 5 ... Cs, 5th order" +\ "\nPress space bar to quit.") setAnnotationSize(info1, textline10, 11); setAnnotationFace(info1, textline10, 0); setAnnotationBackground(info1, textline10, 1); setAnnotationJustification(info1, textline10, 0); // // Display stuff for additional info (window(2)) // info2 := CreateFloatImage("INFO 2", 256, 160) info2 = 1 SetSurvey(info2, 0) SetLimits(info2, 0,1) DisplayAt(info2, screensizeX - 256 -8, (46 + 180 + 10)) scherzerFocus = Round(1.19 * sqrt(Cs * lambda * 1000000) * 10) / 10 number textline20 = CreateTextAnnotation(info2, 0, 0,"Current values:" +\ "\n\n focus: " + Dz + " nm" +\ "\n Cs: " + Cs + " mm" +\ "\n Cs(5th): " + Ccs + " mm" +\ "\n Cc: " + Cc + " mm" +\ "\n alpha_i: " + alpha + " mrad" +\ "\n energy spread: " + DE + " eV" +\ "\n scherzer focus: " + scherzerFocus + " nm" +\ "\n wavelength: " + lambda + " nm"); setAnnotationSize(info2, textline20, 11); setAnnotationFace(info2, textline20, 0); setAnnotationBackground(info2, textline20, 1); setAnnotationJustification(info2, textline20, 0); // // Display stuff for linescan + correct SCALING !! // SetName(display, "Transferfunction@" + Ub + "kV") SetDisplayType(display, 4) SetUnitString(display, "1/nm") SetScale(display, qmax/(displayPixels-1), qmax/(displayPixels-1)) LinePlotImageDisplay lpid = display.ImageGetImageDisplay(0); lpid.LinePlotImageDisplaySetDoAutoSurvey(0,0); lpid.LinePlotImageDisplaySetContrastLimits(-2,2); DisplayAt(display, 139, 47) SetWindowSize(display, 534, 220) // // Result window stuff // OpenResultsWindow() Result("\n" + datestamp() + "\n Draw transfer function\n") Result(" according to: ''" + author + "''\n") //////////////////////////////////////////////////////////////////////////////////////////////// // // pre-define variables // variable = "focus"; DEInc = 0.1; DzInc = 2; CsInc = 0.1; CcInc = 0.1; CcsInc = 1; aInc = 0.1; displaytoggle = 0; OpenAndSetProgressWindow("Active: FOCUS", "focus = " + Dz + "; " + DzInc + "nm",\ "Cs = " + Cs + "; " + CsInc + "mm") while(key != 32) { key = GetKey() if(key == 0 && ii == 0 ) DoEvents() else if(key == 0 && ii == 1) { jj += 1 DoEvents() if(jj > 20) { DeleteAnnotation(info2, textline20) scherzerFocus = Round(1.19 * sqrt(Cs * lambda * 1000000) * 10) / 10 textline20 = CreateTextAnnotation(info2, 0, 0,"Current values:" +\ "\n\n focus: " + Dz + " nm" +\ "\n Cs: " + Cs + " mm" +\ "\n Cs(5th): " + Ccs + " mm" +\ "\n Cc: " + Cc + " mm" +\ "\n alpha_i: " + alpha + " mrad" +\ "\n energy spread: " + DE + " eV" +\ "\n scherzer focus: " + scherzerFocus + " nm" +\ "\n wavelength: " + lambda + " nm"); setAnnotationSize(info2, textline20, 11); setAnnotationFace(info2, textline20, 0); setAnnotationBackground(info2, textline20, 1); setAnnotationJustification(info2, textline20, 0); ii = 0 jj = 0 } } // else if(key != 28 && key!= 29 && key != 30 && key != 31) { if(key == 9) //tab key { if(displaytoggle == 0) { display = abs(TF * EnvelopeChrom * EnvelopeSpatial) displaytoggle = 1 } else { display = TF * EnvelopeChrom * EnvelopeSpatial displaytoggle = 0 } } if(key == 97) // "a" key { variable = "illumination aperture" OpenAndSetProgressWindow("Active: illumination", "alpha = " + alpha + "; " + aInc + "mrad",\ "focus = " + Dz + "; " + DzInc + "nm") } if(key == 99) { variable = "chromatic aberration" OpenAndSetProgressWindow("Active: Cc", "Delta E = " + DE + "; " + DEInc + "eV",\ "Cc = " + Cc + "; " + CcInc + "mm") } else if(key == 101) { variable = "energy spread" OpenAndSetProgressWindow("Active: ENERGY SPREAD", "Delta E = " + DE + "; " + DEInc + "eV",\ "Cc = " + Cc + "; " + CcInc + "mm") } else if(key == 102) { variable = "focus" OpenAndSetProgressWindow("Active: FOCUS", "focus = " + Dz + "; " + DzInc + "nm",\ "Cs = " + Cs + "; " + CsInc + "mm") } else if(key == 115) { variable = "sperical aberration" OpenAndSetProgressWindow("Active: Cs", "focus = " + Dz + "; " + DzInc + "nm",\ "Cs = " + Cs + "; " + CsInc + "mm") } else if(key == 53) // number 5 on keyboard { variable = "Cs 5th order" OpenAndSetProgressWindow("Active: Cs 5th order", "Cs(5th) = " + Ccs + "; " + CcsInc + "mm",\ "focus = " + Dz + "; " + DzInc + "nm") } } else if(variable == "focus") { if(key == 30) { Dz += DzInc Dz = Round(Dz*1000)/1000 TF = -2 * sin( Pi()/2 * ( Cs*1000000*lambda**3 *(qmax*icol/(displayPixels-1))**4 -\ 2*Dz*lambda*(qmax*icol/(displayPixels-1))**2 ) +\ (2/3)*Ccs*1000000*lambda**5*(qmax*icol/(displayPixels-1))**6 ) if(displaytoggle == 1) display = abs(TF * EnvelopeChrom * EnvelopeSpatial) else display = TF * EnvelopeChrom * EnvelopeSpatial ii = 1 OpenAndSetProgressWindow("Active: FOCUS", "focus = " + Dz + "; " + DzInc + "nm",\ "Cs = " + Cs + "; " + CsInc + "mm") } else if(key == 31) { Dz += -DzInc Dz = Round(Dz*1000)/1000 TF = -2 * sin( Pi()/2 * ( Cs*1000000*lambda**3 *(qmax*icol/(displayPixels-1))**4 -\ 2*Dz*lambda*(qmax*icol/(displayPixels-1))**2 ) +\ (2/3)*Ccs*1000000*lambda**5*(qmax*icol/(displayPixels-1))**6 ) if(displaytoggle == 1) display = abs(TF * EnvelopeChrom * EnvelopeSpatial) else display = TF * EnvelopeChrom * EnvelopeSpatial ii = 1 OpenAndSetProgressWindow("Active: FOCUS", "focus = " + Dz + "; " + DzInc + "nm",\ "Cs = " + Cs + "; " + CsInc + "mm") } else if(key == 28) { if(DzInc == 10) DzInc = 5 else if(DzInc == 5) DzInc = 2 else if(DzInc == 2) DzInc = 1 else if(DzInc == 1) DzInc = 0.5 else if(DzInc == 0.5) DzInc = 0.2 else if(DzInc == 0.2) DzInc = 0.1 OpenAndSetProgressWindow("Active: FOCUS", "focus = " + Dz + "; " + DzInc + "nm",\ "Cs = " + Cs + "; " + CsInc + "mm") } else if(key == 29) { if(DzInc == 0.1) DzInc = 0.2 else if(DzInc == 0.2) DzInc = 0.5 else if(DzInc == 0.5) DzInc = 1 else if(DzInc == 1) DzInc = 2 else if(DzInc == 2) DzInc = 5 else if(DzInc == 5) DzInc = 10 OpenAndSetProgressWindow("Active: FOCUS", "focus = " + Dz + "; " + DzInc + "nm",\ "Cs = " + Cs + "; " + CsInc + "mm") } } else if(variable == "sperical aberration") { if(key == 30 ) { if(Round(Dz * 10)/10 == Round(1.19 * sqrt(Cs * lambda * 1000000) * 10) / 10 ) { Cs += CsInc Dz = Round(1.19 * sqrt(Cs * lambda * 1000000) * 10) / 10 } else Cs += CsInc Cs = Round(Cs*1000)/1000 TF = -2 * sin( Pi()/2 * ( Cs*1000000*lambda**3 *(qmax*icol/(displayPixels-1))**4 -\ 2*Dz*lambda*(qmax*icol/(displayPixels-1))**2 ) +\ (2/3)*Ccs*1000000*lambda**5*(qmax*icol/(displayPixels-1))**6 ) if(displaytoggle == 1) display = abs(TF * EnvelopeChrom * EnvelopeSpatial) else display = TF * EnvelopeChrom * EnvelopeSpatial ii = 1 OpenAndSetProgressWindow("Active: Cs", "focus = " + Dz + "; " + DzInc + "nm",\ "Cs = " + Cs + "; " + CsInc + "mm") } else if(key == 31 && Cs >= 0.01 ) { if(Cs - CsInc < 0) { while(CsInc > 0.1 && Cs - CsInc < 0) { CsInc = CsInc**2/3 + 0.1*CsInc + 1/15 // converts 1->0.5, 0.5->0.2, 0.2->0.1 CsInc = Round(100*CsInc)/100 } while(CsInc > 0.01 && Cs - CsInc < 0) { CsInc = CsInc**2*10/3 + 0.1*CsInc + 1/150 // converts 0.1->0.05, 0.05->0.02, 0.02->0.01 CsInc = Round(100*CsInc)/100 } } if(Round(Dz * 10)/10 == Round(1.19 * sqrt(Cs * lambda * 1000000) * 10) / 10 && Cs >= CsInc ) { Cs += -CsInc Dz = Round(1.19 * sqrt(Cs * lambda * 1000000) * 10) / 10 } else Cs += -CsInc Cs = Round(Cs*1000)/1000 TF = -2 * sin( Pi()/2 * ( Cs*1000000*lambda**3 *(qmax*icol/(displayPixels-1))**4 -\ 2*Dz*lambda*(qmax*icol/(displayPixels-1))**2 ) +\ (2/3)*Ccs*1000000*lambda**5*(qmax*icol/(displayPixels-1))**6 ) if(displaytoggle == 1) display = abs(TF * EnvelopeChrom * EnvelopeSpatial) else display = TF * EnvelopeChrom * EnvelopeSpatial ii = 1 OpenAndSetProgressWindow("Active: Cs", "focus = " + Dz + "; " + DzInc + "nm",\ "Cs = " + Cs + "; " + CsInc + "mm") } else if(key == 28) { if(CsInc == 1) CsInc = 0.5 else if(CsInc == 0.5) CsInc = 0.2 else if(CsInc == 0.2) CsInc = 0.1 else if(CsInc == 0.1) CsInc = 0.05 else if(CsInc == 0.05) CsInc = 0.02 else if(CsInc == 0.02) CsInc = 0.01 else if(CsInc == 0.01) CsInc = 0.005 else if(CsInc == 0.005) CsInc = 0.002 else if(CsInc == 0.002) CsInc = 0.001 OpenAndSetProgressWindow("Active: Cs", "focus = " + Dz + "; " + DzInc + "nm",\ "Cs = " + Cs + "; " + CsInc + "mm") } else if(key == 29) { if(CsInc == 0.001) CsInc = 0.002 else if(CsInc == 0.002) CsInc = 0.005 else if(CsInc == 0.005) CsInc = 0.01 else if(CsInc == 0.01) CsInc = 0.02 else if(CsInc == 0.02) CsInc = 0.05 else if(CsInc == 0.05) CsInc = 0.1 else if(CsInc == 0.1) CsInc = 0.2 else if(CsInc == 0.2) CsInc = 0.5 else if(CsInc == 0.5) CsInc = 1 OpenAndSetProgressWindow("Active: Cs", "focus = " + Dz + "; " + DzInc + "nm",\ "Cs = " + Cs + "; " + CsInc + "mm") } } else if(variable == "energy spread") { if(key == 30) { DE += DEInc DE = Round(DE*1000)/1000 if(author == "Reimer") { Hc = (1+Ub/E_O)/(1+Ub/(2*E_O)) * Cc * DE * 1000 / Ub // Hc in nm EnvelopeChrom = ( Pi()*lambda*Hc*(qmax*icol/(displayPixels-1))*(qmax*icol/(displayPixels-1)) ) / ( 4*sqrt(log(2) ) )**2 // log() == ln() EnvelopeChrom = exp(-EnvelopeChrom); } if(author == "Ishizuka") { EnvelopeChrom = 1; } if(displaytoggle == 1) display = abs(TF * EnvelopeChrom * EnvelopeSpatial) else display = TF * EnvelopeChrom * EnvelopeSpatial ii = 1; OpenAndSetProgressWindow("Active: ENERGY SPREAD", "Delta E = " + DE + "; " + DEInc + "eV",\ "Cc = " + Cc + "; " + CcInc + "mm") } else if(key == 31 && DE >= 0.01) { if(DE - DEInc < 0) { while(DEInc > 0.1 && DE - DEInc < 0) { DEInc = DEInc**2/3 + 0.1*DEInc + 1/15 // converts 1->0.5, 0.5->0.2, 0.2->0.1 DEInc = Round(100*DEInc)/100 } while(DEInc > 0.01 && DE - DEInc < 0) { DEInc = DEInc**2*10/3 + 0.1*DEInc + 1/150 // converts 0.1->0.05, 0.05->0.02, 0.02->0.01 DEInc = Round(100*DEInc)/100 } } DE += -DEInc DE = Round(DE*1000)/1000 if(author == "Reimer") { Hc = (1+Ub/E_O)/(1+Ub/(2*E_O)) * Cc * DE * 1000 / Ub // Hc in nm EnvelopeChrom = ( Pi()*lambda*Hc*(qmax*icol/(displayPixels-1))*(qmax*icol/(displayPixels-1)) ) / ( 4*sqrt(log(2) ) )**2 // log() == ln() EnvelopeChrom = exp(-EnvelopeChrom); } if(author == "Ishizuka") { EnvelopeChrom = 1; } if(displaytoggle == 1) display = abs(TF * EnvelopeChrom * EnvelopeSpatial) else display = TF * EnvelopeChrom * EnvelopeSpatial ii = 1 OpenAndSetProgressWindow("Active: ENERGY SPREAD", "Delta E = " + DE + "; " + DEInc + "eV",\ "Cc = " + Cc + "; " + CcInc + "mm") } else if(key == 28) { if(DEInc == 1) DEInc = 0.5 else if(DEInc == 0.5) DEInc = 0.2 else if(DEInc == 0.2) DEInc = 0.1 else if(DEInc == 0.1) DEInc = 0.05 else if(DEInc == 0.05) DEInc = 0.02 else if(DEInc == 0.02) DEInc = 0.01 OpenAndSetProgressWindow("Active: ENERGY SPREAD", "Delta E = " + DE + "; " + DEInc + "eV",\ "Cc = " + Cc + "; " + CcInc + "mm") } else if(key == 29) { if(DEInc == 0.01) DEInc = 0.02 else if(DEInc == 0.02) DEInc = 0.05 else if(DEInc == 0.05) DEInc = 0.1 else if(DEInc == 0.1) DEInc = 0.2 else if(DEInc == 0.2) DEInc = 0.5 else if(DEInc == 0.5) DEInc = 1 OpenAndSetProgressWindow("Active: ENERGY SPREAD", "Delta E = " + DE + "; " + DEInc + "eV",\ "Cc = " + Cc + "; " + CcInc + "mm") } } else if(variable == "chromatic aberration") { if(key == 30) { Cc += CcInc Cc = Round(Cc*1000)/1000 if(author == "Reimer") { Hc = (1+Ub/E_O)/(1+Ub/(2*E_O)) * Cc * DE * 1000 / Ub // Hc in nm EnvelopeChrom = ( Pi()*lambda*Hc*(qmax*icol/(displayPixels-1))*(qmax*icol/(displayPixels-1)) ) / ( 4*sqrt(log(2) ) )**2 // log() == ln() EnvelopeChrom = exp(-EnvelopeChrom); } if(author == "Ishizuka") { EnvelopeChrom = 1; } if(displaytoggle == 1) display = abs(TF * EnvelopeChrom * EnvelopeSpatial) else display = TF * EnvelopeChrom * EnvelopeSpatial ii = 1 OpenAndSetProgressWindow("Active: Cc", "Delta E = " + DE + "; " + DEInc + "eV",\ "Cc = " + Cc + "; " + CcInc + "mm") } else if(key == 31 && Cc >= 0.01 ) { if(Cc - CcInc < 0) { while(CcInc > 0.1 && Cc - CcInc < 0) { CcInc = CcInc**2/3 + 0.1*CcInc + 1/15 // converts 1->0.5, 0.5->0.2, 0.2->0.1 CcInc = Round(100*CcInc)/100 } while(CcInc > 0.01 && Cc - CcInc < 0) { CcInc = CcInc**2*10/3 + 0.1*CcInc + 1/150 // converts 0.1->0.05, 0.05->0.02, 0.02->0.01 CcInc = Round(100*CcInc)/100 } } Cc += -CcInc Cc = Round(Cc*1000)/1000 if(author == "Reimer") { Hc = (1+Ub/E_O)/(1+Ub/(2*E_O)) * Cc * DE * 1000 / Ub // Hc in nm EnvelopeChrom = ( Pi()*lambda*Hc*(qmax*icol/(displayPixels-1))*(qmax*icol/(displayPixels-1)) ) / ( 4*sqrt(log(2) ) )**2 // log() == ln() EnvelopeChrom = exp(-EnvelopeChrom); } if(author == "Ishizuka") { EnvelopeChrom = 1; } if(displaytoggle == 1) display = abs(TF * EnvelopeChrom * EnvelopeSpatial) else display = TF * EnvelopeChrom * EnvelopeSpatial ii = 1 OpenAndSetProgressWindow("Active: Cc", "Delta E = " + DE + "; " + DEInc + "eV",\ "Cc = " + Cc + "; " + CcInc + "mm") } else if(key == 28) { if(CcInc == 1) CcInc = 0.5 else if(CcInc == 0.5) CcInc = 0.2 else if(CcInc == 0.2) CcInc = 0.1 else if(CcInc == 0.1) CcInc = 0.05 else if(CcInc == 0.05) CcInc = 0.02 else if(CcInc == 0.02) CcInc = 0.01 OpenAndSetProgressWindow("Active: Cc", "Delta E = " + DE + "; " + DEInc + "eV",\ "Cc = " + Cc + "; " + CcInc + "mm") } else if(key == 29) { if(CcInc == 0.01) CcInc = 0.02 else if(CcInc == 0.02) CcInc = 0.05 else if(CcInc == 0.05) CcInc = 0.1 else if(CcInc == 0.1) CcInc = 0.2 else if(CcInc == 0.2) CcInc = 0.5 else if(CcInc == 0.5) CcInc = 1 OpenAndSetProgressWindow("Active: Cc", "Delta E = " + DE + "; " + DEInc + "eV",\ "Cc = " + Cc + "; " + CcInc + "mm") } } else if( variable == "illumination aperture") { if(key == 30) { alpha += aInc alpha = Round(alpha*1000)/1000 if(author == "Reimer") { EnvelopeSpatial = Pi() * Cs * 1000000 * lambda**2 * (qmax*icol/(displayPixels-1))**3 - Pi() * Dz * (qmax*icol/(displayPixels-1)) EnvelopeSpatial = EnvelopeSpatial*EnvelopeSpatial * alpha*alpha / (log(2) * 1000000) EnvelopeSpatial = exp(-EnvelopeSpatial) } if(author == "Ishizuka") { EnvelopeSpatial = 1; } if(displaytoggle == 1) display = abs(TF * EnvelopeChrom * EnvelopeSpatial) else display = TF * EnvelopeChrom * EnvelopeSpatial ii = 1 OpenAndSetProgressWindow("Active: illumination", "alpha = " + alpha + "; " + aInc + "mrad",\ "focus = " + Dz + "; " + DzInc + "nm") } else if(key == 31 && alpha >= 0.01) // guarantees aInc > 0.01 { if(alpha - aInc < 0) { while(aInc > 0.1 && alpha - aInc < 0) { aInc = aInc**2/3 + 0.1*aInc + 1/15 // converts 1->0.5, 0.5->0.2, 0.2->0.1 aInc = Round(100*aInc)/100 } while(aInc > 0.01 && alpha - aInc < 0) { aInc = aInc**2*10/3 + 0.1*aInc + 1/150 // converts 0.1->0.05, 0.05->0.02, 0.02->0.01 aInc = Round(100*aInc)/100 } } alpha += -aInc alpha = Round(alpha*1000)/1000 if(author == "Reimer") { EnvelopeSpatial = Pi() * Cs * 1000000 * lambda**2 * (qmax*icol/(displayPixels-1))**3 - Pi() * Dz * (qmax*icol/(displayPixels-1)) EnvelopeSpatial = EnvelopeSpatial*EnvelopeSpatial * alpha*alpha / (log(2) * 1000000) EnvelopeSpatial = exp(-EnvelopeSpatial) } if(author == "Ishizuka") { EnvelopeSpatial = 1; } if(displaytoggle == 1) display = abs(TF * EnvelopeChrom * EnvelopeSpatial) else display = TF * EnvelopeChrom * EnvelopeSpatial ii = 1 OpenAndSetProgressWindow("Active: illumination", "alpha = " + alpha + "; " + aInc + "mrad",\ "focus = " + Dz + "; " + DzInc + "nm") } else if(key == 28) { if(aInc == 1) aInc = 0.5 else if(aInc == 0.5) aInc = 0.2 else if(aInc == 0.2) aInc = 0.1 else if(aInc == 0.1) aInc = 0.05 else if(aInc == 0.05) aInc = 0.02 else if(aInc == 0.02) aInc = 0.01 OpenAndSetProgressWindow("Active: illumination", "alpha = " + alpha + "; " + aInc + "mrad",\ "focus = " + Dz + "; " + DzInc + "nm") } else if(key == 29) { if(aInc == 0.01) aInc = 0.02 else if(aInc == 0.02) aInc = 0.05 else if(aInc == 0.05) aInc = 0.1 else if(aInc == 0.1) aInc = 0.2 else if(aInc == 0.2) aInc = 0.5 else if(aInc == 0.5) aInc = 1 OpenAndSetProgressWindow("Active: illumination", "alpha = " + alpha + "; " + aInc + "mrad",\ "focus = " + Dz + "; " + DzInc + "nm") } } else if( variable == "Cs 5th order") { if(key == uparrow) { Ccs += CcsInc Ccs = Round(Ccs*1000)/1000 TF = -2 * sin( Pi()/2 * ( Cs*1000000*lambda**3 *(qmax*icol/(displayPixels-1))**4 -\ 2*Dz*lambda*(qmax*icol/(displayPixels-1))**2 ) +\ (2/3)*Ccs*1000000*lambda**5*(qmax*icol/(displayPixels-1))**6 ) if(displaytoggle == 1) display = abs(TF * EnvelopeChrom * EnvelopeSpatial) else display = TF * EnvelopeChrom * EnvelopeSpatial ii = 1 OpenAndSetProgressWindow("Active: Cs 5th order", "Cs(5th) = " + Ccs + "; " + CcsInc + "mm",\ "focus = " + Dz + "; " + DzInc + "nm") } else if(key == downarrow) { Ccs += -CcsInc Ccs = Round(Ccs*1000)/1000 TF = -2 * sin( Pi()/2 * ( Cs*1000000*lambda**3 *(qmax*icol/(displayPixels-1))**4 -\ 2*Dz*lambda*(qmax*icol/(displayPixels-1))**2 ) +\ (2/3)*Ccs*1000000*lambda**5*(qmax*icol/(displayPixels-1))**6 ) if(displaytoggle == 1) display = abs(TF * EnvelopeChrom * EnvelopeSpatial) else display = TF * EnvelopeChrom * EnvelopeSpatial ii = 1 OpenAndSetProgressWindow("Active: Cs 5th order", "Cs(5th) = " + Ccs + "; " + CcsInc + "mm",\ "focus = " + Dz + "; " + DzInc + "nm") } else if(key == leftarrow) { if(CcsInc == 10) CcsInc = 5 else if(CcsInc == 5) CcsInc = 2 else if(CcsInc == 2) CcsInc = 1 else if(CcsInc == 1) CcsInc = 0.5 else if(CcsInc == 0.5) CcsInc = 0.2 else if(CcsInc == 0.2) CcsInc = 0.1 OpenAndSetProgressWindow("Active: Cs 5th order", "Cs(5th) = " + Ccs + "; " + CcsInc + "mm",\ "focus = " + Dz + "; " + DzInc + "nm") } else if(key == rightarrow) { if(CcsInc == 0.1) CcsInc = 0.2 else if(CcsInc == 0.2) CcsInc = 0.5 else if(CcsInc == 0.5) CcsInc = 1 else if(CcsInc == 1) CcsInc = 2 else if(CcsInc == 2) CcsInc = 5 else if(CcsInc == 5) CcsInc = 10 OpenAndSetProgressWindow("Active: Cs 5th order", "Cs(5th) = " + Ccs + "; " + CcsInc + "mm",\ "focus = " + Dz + "; " + DzInc + "nm") } OpenAndSetProgressWindow("Active: Cs 5th order", "Cs(5th) = " + Ccs + "; " + CcsInc + "mm",\ "focus = " + Dz + "; " + DzInc + "nm") } } Result(" Acceleration voltage = " + Ub + " kV; \n") Result(" Focus value = " + Dz + "nm; " + "Cs = " + Cs + " mm;\n") Result(" Energy spread = " + DE + "eV; " + "Cc = " + Cc + " mm;\n") Result(" Illumination spread = " + alpha + " mrad;\n") Result("************\n\n") // // Clean up: (be prepared for background stuff) // try DeleteImage(info1) catch break try DeleteImage(info2) catch break // // Final output for display // // if(author == "Reimer") { Hc = (1+Ub/E_O)/(1+Ub/(2*E_O)) * Cc * DE * 1000 / Ub // Hc in nm EnvelopeChrom := CreateFloatImage("Envelope I for TF", finalDisplayPixels, 1); EnvelopeChrom = ( Pi()*lambda*Hc*(qmax*icol/(finalDisplayPixels-1))*(qmax*icol/(finalDisplayPixels-1)) ) / ( 4*sqrt(log(2) ) )**2 // log() == ln() EnvelopeChrom = exp(-EnvelopeChrom); SetDisplayType(EnvelopeChrom, 4); } if(author == "Ishizuka") { EnvelopeChrom = 1; } TF := CreateFloatImage("Transferfunction @ " + Ub + "kV", finalDisplayPixels, 1); TF = -2 * sin( Pi()/2 * ( Cs*1000000*lambda**3 *(qmax*icol/(finalDisplayPixels-1))**4 -\ 2*Dz*lambda*(qmax*icol/(finalDisplayPixels-1))**2 ) +\ (2/3)*Ccs*1000000*lambda**5*(qmax*icol/(finalDisplayPixels-1))**6 ) if(author == "Reimer") { EnvelopeSpatial := CreateFloatImage("Envelope II for TF", finalDisplayPixels, 1); EnvelopeSpatial = Pi() * Cs * 1000000 * lambda**2 * (qmax*icol/(finalDisplayPixels-1))**3 - Pi() * Dz * (qmax*icol/(finalDisplayPixels-1)); EnvelopeSpatial = EnvelopeSpatial*EnvelopeSpatial * alpha*alpha / (log(2) * 1000000) EnvelopeSpatial = exp(-EnvelopeSpatial) } if(author == "Ishizuka") { EnvelopeSpatial = 1; } if(displaytoggle == 1) final := abs(TF * EnvelopeChrom * EnvelopeSpatial); else final := TF * EnvelopeChrom * EnvelopeSpatial; SetUnitString(final, "1/nm"); SetScale(final, qmax/(finalDisplayPixels-1), qmax/(finalDisplayPixels-1)); SetName(final, "TF@" + Ub + "kV;Dz=" + Dz + "nm;Cs=" + Cs + "mm"); SetDisplayType(final, 4); LinePlotImageDisplay lpidFull = final.ImageGetImageDisplay(0); lpidFull.LinePlotImageDisplaySetDoAutoSurvey(0,0); lpidFull.LinePlotImageDisplaySetContrastLimits(-2,2); AddStringToList( final, "History", "TransferFunction.s" ); AddStringToList( final, "History", "Acc voltage = " + Ub + " kV"); AddStringToList( final, "History", "Focus = " + Dz + " nm"); AddStringToList( final, "History", "Cs = " + Cs + " mm"); AddStringToList( final, "History", "Cc = " + Cc + " mm"); AddStringToList( final, "History", "illumination alpha = " + alpha + " mrad"); ShowImage(final) SetWindowSize(final, 680, 444) scherzerFocus = Round(1.19 * sqrt(Cs * lambda * 1000000) * 10) / 10 number textline30 = CreateTextAnnotation(final, 224, 64, \ "Contrast Transfer Function (" + author + ")" + \ "\n focus: " + Dz + " nm" + \ "\n Cs: " + Cs + " mm" + \ "\n Cs(5th): " + Ccs + " mm" + \ "\n Cc: " + Cc + " mm" + \ "\n alpha_i: " + alpha + " mrad" + \ "\n energy spread: " + DE + " eV" + \ "\n scherzer focus: " + scherzerFocus + " nm" + \ "\n wavelength: " + lambda + " nm" + \ "\n" + datestamp() ); setAnnotationSize(final, textline30, 12); setAnnotationFace(final, textline30, 0); setAnnotationBackground(final, textline30, 2); setAnnotationJustification(final, textline30, 0); deleteImage(display) CloseProgressWindow()