Transfer function, interactive
DigitalMicrograph Script
Interactively draw and modify the contrast transfer function as a LinePlot.
Preview
/////////////////////////////////////////////////////////////////////
// (c) Gatan Inc.
/////////////////////////////////////////////////////////////////////
// Interactively displays the contrast Transfer Function.
// Use up & down keys to change selected value and the following keys
// to select:
// <f> focus
// <a> aperture (illumination)
// <c> Cc
// <s> Cs
// <e> Energy spread
//
// <space> 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()