// Probe Broadening

// Estimates the degree of broadening in a STEM probe due to scattering of the beam by the specimen.

// Acknowledgements: The broadening equation is from Williams and Carter, "TEM for Materials Science".

// version:20130210, v1.0, D. R. G. Mitchell, adminnospam@dmscripting.com (remove the nospam to make this work)
// February 2013, www.dmscripting.com



// The default settings - saved to the global info. These get updated everytime the dialog is closed
// with whatever the current settings are


// The voltage in kV

number defaultvoltage=200
if(!getpersistentnumbernote("STEM Tools:Default Settings:Voltage (kV)",defaultvoltage))
	{
		setpersistentnumbernote("STEM Tools:Default Settings:Voltage (kV)",defaultvoltage)
	}


// The Specimen Thickness in nm

number defaultthickness=80
if(!getpersistentnumbernote("STEM Tools:Default Settings:Thickness (nm)",defaultthickness))
	{
		setpersistentnumbernote("STEM Tools:Default Settings:Thickness (nm)",defaultthickness)
	}


// The mean atomic number

number defaultatomicnumber=10
if(!getpersistentnumbernote("STEM Tools:Default Settings:Atomic Number",defaultatomicnumber))
	{
		setpersistentnumbernote("STEM Tools:Default Settings:Atomic Number",defaultatomicnumber)
	}


// The density in g.cm3

number defaultdensity=1.9
if(!getpersistentnumbernote("STEM Tools:Default Settings:Density (g.cm3)",defaultdensity))
	{
		setpersistentnumbernote("STEM Tools:Default Settings:Density (g.cm3)",defaultdensity)
	}


// The Atomic Weight

number defaultatomicweight=102
if(!getpersistentnumbernote("STEM Tools:Default Settings:Atomic Weight",defaultatomicweight))
	{
		setpersistentnumbernote("STEM Tools:Default Settings:Atomic Weight",defaultatomicweight)
	}


// The Initial Probe Diameter before it passes through the specimen (nm)

number defaultinitialprobe=0.4
if(!getpersistentnumbernote("STEM Tools:Default Settings:Initial Probe Diameter (nm)",defaultinitialprobe))
	{
		setpersistentnumbernote("STEM Tools:Default Settings:Initial Probe Diameter (nm)",defaultinitialprobe)
	}



// The Class methods for the dialog

class CreateBroadeningDialog : uiframe
{

// Responds whenever any of the fields are changed

void FieldChanged(object self, taggroup tg)
	{
		// Source the current field values
		
		number voltage=dlggetvalue(self.lookupelement("voltagefield"))
		number thickness=dlggetvalue(self.lookupelement("thicknessfield"))
		number atno=dlggetvalue(self.lookupelement("atnofield"))

		number atwt=dlggetvalue(self.lookupelement("atwtfield"))
		number density=dlggetvalue(self.lookupelement("densityfield"))
		number initialprobe=dlggetvalue(self.lookupelement("initialprobediamfield"))


		// Do the broadening calculation and set report the values in the dialog
		// The equation is sourced from Williams and Carter "TEM for Materials Science"
		// The probe resolution is that at the half way point through the foil

		number broadening=(7.21*100000*(atno/(voltage*1000))*(density/atwt)**0.5*(thickness/10000000)**1.5)*10000000

		self.lookupelement("broadeninglabel").dlgtitle("Probe Broadening :"+format(broadening,"%6.2f")+" nm")
		number resolution=(initialprobe+(broadening+initialprobe))/2
		self.lookupelement("resolutionlabel").dlgtitle("Probe Resolution  :"+format(resolution,"%6.2f")+" nm")
		
		
		// Dump the data in the Results window
		
		Result("\n\nSTEM Probe Broadening due to scattering in the specimen:")
		result("\n\nVoltage : "+voltage+" kV")
		result("\nThickness : "+thickness+" nm")
		result("\nAtomic Number : "+atno)
		result("\n\nDensity : "+density+" g.cm3")
		result("\nAtomic Weight : "+atwt)
		result("\nInitial Probe Diameter : "+initialprobe+" nm")
		
		result("\n\nProbe Broadening : "+format(broadening,"%6.2f")+" nm")
		result("\nProbe Resolution : "+format(resolution, "%6.2f")+" nm (probe width at foil mid-point)")
		result("\n\nEquation from Williams and Carter, TEM for Materials Science.\n\n")
	}


// Function which responds when the calculate button is pressed. the Calculate button performs the same
// function as when a field is changed. The button does not return a taggroup (tg) but the fields do.  
// Therefore the button can not call the FieldsChanged() function. Instead this intermediary function is
// called. A dummy taggroup is provided and it then calls FieldsChanged()

void CalculateResponse(object self)
	{
		taggroup tg
		self.FieldChanged(tg)
	}


// Responds when the dialog is closed, to save the current values as the new defaults, and to save the dialog
// position

void abouttoclosedocument(object self)
	{
		// Source the current settings and write to the Global Info

		number voltage=dlggetvalue(self.lookupelement("voltagefield"))
		setpersistentnumbernote("STEM Tools:Default Settings:Voltage (kV)",voltage)

		number thickness=dlggetvalue(self.lookupelement("thicknessfield"))
		setpersistentnumbernote("STEM Tools:Default Settings:Thickness (nm)",thickness)
				
		number atno=dlggetvalue(self.lookupelement("atnofield"))
		setpersistentnumbernote("STEM Tools:Default Settings:Atomic Number",atno)
		
		number density=dlggetvalue(self.lookupelement("densityfield"))
		setpersistentnumbernote("STEM Tools:Default Settings:Density (g.cm3)",density)
				
		number atwt=dlggetvalue(self.lookupelement("atwtfield"))
		setpersistentnumbernote("STEM Tools:Default Settings:Atomic Weight",atwt)

		number initialprobe=dlggetvalue(self.lookupelement("initialprobediamfield"))
		setpersistentnumbernote("STEM Tools:Default Settings:Initial Probe Diameter (nm)",initialprobe)


		// Get the dialog position

		number xpos, ypos
		documentwindow dialogwindow=getframewindow(self)
		windowgetframeposition(dialogwindow, xpos, ypos)


		// Checks to make sure the dialog is not outside the screen viewing area 
		// this can happen if the dialog is accidentally maximised and then closed.
		// If the position is OK, then it is saved.

		number screenx, screeny
		getscreensize(screenx, screeny)
		if(xpos<0) xpos=142 // This keeps it out from behind the left palette column in GMS 1.x
		if(xpos>screenx) xpos=screenx-(screenx/10)
		if(ypos<0) ypos=20 // This keeps it below the top menu in GMS 1.x
		if(ypos>screeny) ypos=screeny-(screeny/5) // If the dialog is off the right hand edge - put it at 80% of screen width

		setpersistentnumbernote("STEM Tools:Broadening Dialog Position:Left",xpos)
		setpersistentnumbernote("STEM Tools:Broadening Dialog Position:Right",ypos)
	}
	
		
// this function creates a taggroup containing the dialog elements

taggroup MakeBroadeningDialog(object self)
	{
		// Create the dialog
		
		TagGroup BroadeningDialog_items;	
		TagGroup BroadeningDialog = DLGCreateDialog("Probe Broadening", BroadeningDialog_items)


		// Creates the Parameters box

		taggroup ParametersBox_items
		taggroup Parametersbox=dlgcreatebox("  Parameters  ", ParametersBox_items)
		parametersBox.dlgexternalpadding(2,2)
		ParametersBox.dlginternalpadding(10,10)


		// Voltage field
		
		number voltage
		getpersistentnumbernote("STEM Tools:Default Settings:Voltage (kV)",voltage)

		taggroup voltagelabel=dlgcreatelabel("Voltage/kV")
		taggroup voltagefield=dlgcreateintegerfield(voltage, 8).dlgidentifier("voltagefield").dlgchangedmethod("fieldchanged")
		taggroup voltagegroup=dlggroupitems(voltagelabel, voltagefield).dlgtablelayout(1,2,0)
		
		
		// Atomic No. field
		
		number atomicno
		getpersistentnumbernote("STEM Tools:Default Settings:Atomic Number",atomicno)

		taggroup atnolabel=dlgcreatelabel("Atomic No.")
		taggroup atnofield=dlgcreaterealfield(atomicno, 8,3).dlgidentifier("atnofield").dlgchangedmethod("fieldchanged")
		taggroup atnogroup=dlggroupitems(atnolabel, atnofield).dlgtablelayout(1,2,0)


		// Atomic Wt. field
		
		number atwt
		getpersistentnumbernote("STEM Tools:Default Settings:Atomic Weight",atwt)
		taggroup atwtlabel=dlgcreatelabel("Atomic Wt.")
		taggroup atwtfield=dlgcreaterealfield(atwt, 8,3).dlgidentifier("atwtfield").dlgchangedmethod("fieldchanged")
		taggroup atwtgroup=dlggroupitems(atwtlabel, atwtfield).dlgtablelayout(1,2,0)
		
				
		// Thickness. field
		
		number thickness
		getpersistentnumbernote("STEM Tools:Default Settings:Thickness (nm)",thickness)
		taggroup thicknesslabel=dlgcreatelabel("Thickness/nm")
		taggroup thicknessfield=dlgcreaterealfield(thickness, 8,3).dlgidentifier("thicknessfield").dlgchangedmethod("fieldchanged")
		taggroup thicknessgroup=dlggroupitems(thicknesslabel, thicknessfield).dlgtablelayout(1,2,0)
		
				
		// Density field
		
		number density
		getpersistentnumbernote("STEM Tools:Default Settings:Density (g.cm3)",density)
		taggroup densitylabel=dlgcreatelabel("Density/g.cm3")
		taggroup densityfield=dlgcreaterealfield(density, 8,3).dlgidentifier("densityfield").dlgchangedmethod("fieldchanged")
		taggroup densitygroup=dlggroupitems(densitylabel, densityfield).dlgtablelayout(1,2,0)

		
		// Inital Probe Diam

		number initialprobediam
		getpersistentnumbernote("STEM Tools:Default Settings:Initial Probe Diameter (nm)",initialprobediam)
		taggroup initialprobelabel=dlgcreatelabel("Initial Probe Diam/nm")
		taggroup initialprobefield=dlgcreaterealfield(initialprobediam, 8,3).dlgidentifier("initialprobediamfield").dlgchangedmethod("fieldchanged")
		taggroup initialprobegroup=dlggroupitems(initialprobelabel, initialprobefield).dlgtablelayout(1,2,0)


		// Group all the elements and add them to the parameters box

		taggroup leftgroup=dlggroupitems(voltagegroup, atnogroup, atwtgroup).dlgtablelayout(1,3,0)
		taggroup rightgroup=dlggroupitems(thicknessgroup, densitygroup, initialprobegroup)
		taggroup fieldgroup=dlggroupitems(leftgroup, rightgroup).dlgtablelayout(2,1,0)
		ParametersBox_items.dlgaddelement(fieldgroup)


		// Create a results box

		taggroup resultsbox_items
		taggroup resultsbox=dlgcreatebox("  Results  ",resultsbox_items).dlgexternalpadding(2,0).dlginternalpadding(12,8)

		taggroup calcbutton=dlgcreatepushbutton("Calculate","calculateresponse").dlgexternalpadding(0,0)
		taggroup broadeninglabel=dlgcreatelabel("Probe Broadening :                      ").dlgidentifier("broadeninglabel").dlganchor("West")
		taggroup resolutionlabel=dlgcreatelabel("Probe Resolution  :                      ").dlgidentifier("resolutionlabel").dlganchor("West")

		taggroup resultsgroup=dlggroupitems(calcbutton, broadeninglabel, resolutionlabel).dlgtablelayout(1,3,0)
		resultsbox_items.dlgaddelement(resultsgroup)


		// Add all the elements to the dialog
		
		BroadeningDialog_items.dlgaddelement(ParametersBox)
		BroadeningDialog_items.dlgaddelement(ResultsBox)
				
		taggroup footer=dlgcreatelabel("D. R. G. Mitchell, v1.0, Feb. 2013")
		Broadeningdialog.dlgaddelement(footer)
		return BroadeningDialog
	}


// The constructor this calls the makeSBroadeningdialog() function and displays it

createBroadeningDialog(object self)
	{
		// Construct the dialog

		self.init( self.MakeBroadeningDialog() );
		self.display("Beam Broadening")
		
		
		// Source the previous position of the dialog and display it there again
		
		number xpos,ypos
		getpersistentnumbernote("STEM Tools:Broadening Dialog Position:Left",xpos)
		getpersistentnumbernote("STEM Tools:Broadening Dialog Position:Right",ypos)
		
		documentwindow dialogwin=getdocumentwindow(0)
		if(xpos!=0 && ypos!=0) 
			{
				windowsetframeposition(dialogwin, xpos, ypos)
			}
	}


// The destructor is called when the object (the dialog) is closed

~createBroadeningDialog(object self)
	{
	}
}


// allocates the above function which puts it all together

alloc(createBroadeningDialog)

