Gatan | AMETEKSkip to Main Content
No options found

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()