ScriptName Functs SuppressReports ErrorsToLog #******************************************************************************************************** Function AutoFocusToZero 3 0 #___________________ AutoFocusToZero ________________ # *** Fancy Atofocus function with a loop, error estimation and fixed pattern noise protection # Input1 -> Integer : Number of Autofocus rounds (Integer >=0). 0 => One autofocus without statisitics (will work well for small changes in autfocus) # 1 (or more) => addtional autofocus rounds will be done and sucsses statisitcs will be recoreded # Input2 -> Real : Pre focus Settlinng time in seconds (Real >= 0) # # Out -> array {3x1} : { MeasuredDefocus (um) , STD(fMeasuredDefocus) (um), Drift (nm/sec), AutoFocusErr 0 -> No Err, NumberOfAutoFocusLoopRepeats } # # Error signals: # AutoFocusErr == 0 : No error detected # AutoFocusErr == 9 : Focus measuements are controlled by the fix pattern, may reslut from exposure or contrast issues (STD(defocus) will be set to -1 and LoopInd =-2) # # Call examples: # CallFunction AutoFocusToZero $NumberOfLoopRepeats $PreFocusSettlingTiemSec $Out # CallFunction AutoFocusToZero 3 5 $Out # SuppressReports NumLoops = $ArgVal1 PreFocusSettling_sec = $ArgVal2 ZeroOffSet = -0.75 # [um] The offset of focus from zero to prevent working close to the fixed pattern FixedPatternErr_TH = 0.05 # [um] Threshold for considering fixed pattern effecs as dominating the measurements Out = 0 echo *** Strating AutoFocusToZero with (1)+$NumLoops focus measurements rounds GoToLowDoseArea F 0 NormalizeAllLenses 0 Delay $PreFocusSettling_sec sec ReportDefocus NominalDefocusStart AutoFocus -1 ReportAutofocus MeasuredDefocus Err ReportFocusDrift XDrif YDrift Drift = SQRT ( $XDrif * $XDrif + $YDrift * $YDrift ) If $Err == 0 DeltaFoc = $ZeroOffSet - $MeasuredDefocus echo Shifitng defocus by $DeltaFoc um towords $ZeroOffSet um DeltaFoc = $ZeroOffSet - $MeasuredDefocus ChangeFocus $DeltaFoc # Shifting the focus away from zero to the ZeroOffSet value echo Round 0 {MeasuredDefocus, Delta towards $ZeroOffSet, ABS(Drift) nm/sec, Err} : { $MeasuredDefocus $DeltaFoc $Drift $Err } EndIf If (ABS ($MeasuredDefocus) < $FixedPatternErr_TH) # If the measured defocus is around Zero it is likely that the measurement is dominated by the detector's fixed pattern (or the focus is acutially very close to Zero) echo ***! Round 0 focus estiamte was too close to 0 um. This may be the result of an artifact due to fixed pattern noise which can happen due to exposure/contrast issues echo ***! Repeating roud 0 focus measurement AutoFocus -1 # Mesuring the defocus for the 2nd time ReportAutofocus MeasuredDefocus Err ReportFocusDrift XDrif YDrift Drift = SQRT ( $XDrif * $XDrif + $YDrift * $YDrift ) DeltaFoc = $ZeroOffSet - $MeasuredDefocus echo Round 0.5 {MeasuredDefocus, Delta towards $ZeroOffSet, ABS(Drift) nm/sec, Err} : { $MeasuredDefocus $DeltaFoc $Drift $Err } If (ABS ($MeasuredDefocus) < $FixedPatternErr_TH) # If the measured defocus is around Zero for 2nd time after focus was changed to ZeroOffSet => Focus measurments are faling !!! echo ***! Round 0.5 focus estiamte was too close to 0 um for the 2nd time! echo ***! Restroing original focus value and exting with an erros signal 9 SetDefocus $NominalDefocusStart Out = {0 -1 -1 9 -2} # Exiting with error signal 9 and negative STD, Drift, and LoppInd values i.e. {AvgDefocus=0 VarDefocus=-1 Drift=-1 Err=-9 LoopInd=-2} Return Else echo Shifitng defocus by $DeltaFoc um towords $ZeroOffSet ChangeFocus $ZeroOffSet # Shifting the focus away from zero to the ZeroOffSet value EndIf EndIf If $NumLoops == 0 AND $Err == 0 # Only Round 0 focus estiamte is uesed for measuring focus location => Shifting to zero based on the laast repositining of the defocus (i.e. -$ZeroOffSet) DeltaFoc = -1 * $ZeroOffSet ChangeFocus $DeltaFoc # Shifting the focus to Zero Out = {0 0 $Drift $Err 0} # { MeasuredDefocus=0 (um) , STD(MeasuredDefocus)=0 (um), Drift (nm/sec) , AutoFocusErr 0=> No Err, NumberOfAutoFocusLoopRepeats=0 } Return ElseIf $NumLoops == 0 AND $Err != 0 Out = {$MeasuredDefocus -1 $Drift $Err 0} echo ***! The only focus measurement returend an error! echo ***! Restroing Original focus vlaue and exting with an error signal $Err SetDefocus $OrigNominalDefocus Return Else SumSQMeasuredDefocus = 0 SumMeasuredDefocus = 0 AutoFocusFaieldFlag = 0 LoopInd = 0 AutoFocusFailedFlag = 0 Loop $NumLoops q1 AutoFocus -1 ReportAutofocus MeasuredDefocus Err ReportFocusDrift XDrif YDrif Drift = SQRT ( $XDrif * $XDrif + $YDrift * $YDrift ) DeltaFoc = $ZeroOffSet - $MeasuredDefocus echo Round $q1 {MeasuredDefocus, Delta towards $ZeroOffSet, ABS(Drift) nm/sec, Err} : { $MeasuredDefocus $DeltaFoc $Drift $Err } If $Err == 0 ChangeFocus $DeltaFoc # Shifting the focus away from zero to the ZeroOffSet value LoopInd = $LoopInd + 1 If $LoopInd == 1 SampDefocus = $MeasuredDefocus Endif SumMeasuredDefocus = $SumMeasuredDefocus + $MeasuredDefocus SumSQMeasuredDefocus = $SumSQMeasuredDefocus + ($MeasuredDefocus - $SampDefocus) * ($MeasuredDefocus - $SampDefocus) Else AutoFocusFailedFlag = $AutoFocusFailedFlag + 1 EndIf EndLoop If $LoopInd > 1 AvgSQDefocus = $SumSQMeasuredDefocus / $LoopInd AvgDefocus = $SumMeasuredDefocus / $LoopInd # echo !!! $AvgDefocus STDDefocus = SQRT (($SumSQMeasuredDefocus - ($SumMeasuredDefocus - $LoopInd * $SampDefocus) * ($SumMeasuredDefocus - $LoopInd * $SampDefocus) / $LoopInd ) / ($LoopInd - 1)) echo Moving focus to zero DeltaFoc = -1 * $MeasuredDefocus # In most casese the last measuremtn is closer to the target then the preceeding ones $AvgDefocus ChangeFocus $DeltaFoc Out = {($AvgDefocus - $ZeroOffSet) $STDDefocus $Drift $Err $LoopInd} # ElseIf $LoopInd == 1 AvgDefocus = $MeasuredDefocus STDDefocus = 0 echo Moving focus to zero DeltaFoc = -1* $AvgDefocus ChangeFocus $DeltaFoc Out = {0 $STDDefocus $Drift $Err $LoopInd} Else AvgDefocus = $MeasuredDefocus STDDefocus = -1 echo Autofocus measurements exit with error - focus was not changed!!! Out = {0 $STDDefocus $Drift $Err $LoopInd} EndIf EndIf GoToLowDoseArea R 0 EndFunction #___________________ AutoFocusToZero ________________ #******************************************************************************************************** Function DelayUntil 2 0 # A loop for delaying and detecting user's Key-Break presses # # Input 1: real => the time in seconds to stop waiting and continue the run by returing to the caller function # # Out : KeyBreak pressed by the user: In case the user pressed one of the pre-decleard flags or -1 if no user key breakes were invoked # # Note! - The function assumes that the clock intiatted by the caller using the ResetClock command SuppressReports 1 TimeToReturn = $ArgVal1 BreakFlag = -1 Loop 999999 BreakFlag = 0 # KeyBreak 0 BreakFlag = 9 # KeyBreak 9 BreakFlag = 8 # KeyBreak 8 BreakFlag = 2 # KeyBreak 2 BreakFlag = 1 # KeyBreak 1 ReportClock CurrentTime #echo If $CurrentTime >= $TimeToReturn If $CurrentTime >= $TimeToReturn BreakFlag = -1 # NO user invoked break Break EndIf EndLoop Out = $BreakFlag EndFunction #___________________ DelayUntil ________________ #******************************************************************************************************** Function LockOnTarget 3 0 # *** Align to item without iamge shift and output the error measurement # # # Input1 -> Integer : maximal number of lock on traget attempts # Input2 -> Real : Allowed error in stageag positioning [um] # # Out array {4x1} : { ImShift_x [um], ImShift_x [um], Abs_ImShift [um], PosErr_X [um], PosErr_Y [um], Abs_PosErr [um], numLoops} [Stage errors in nm on the stage axis system] SuppressReports NumLoops = $ArgVal1 ImShift_ZERO_TH = $ArgVal2 #Out = $ArgVal4 Out = 0 Loop $NumLoops IndLoop RealignToNavItem 1 0 # Realign and restore microscope condtions without cont acquisition ReportImageShift J1 J2 J3 J4 ImShift_X ImShift_Y # Image shift in stage cordinates (um) Abs_ImShift = SQRT ( $ImShift_X * $ImShift_X + $ImShift_Y * $ImShift_Y ) # (um) echo If $Abs_ImShift <= $ImShift_ZERO_TH If $Abs_ImShift <= $ImShift_ZERO_TH ImageShiftByMicrons 0 0 Out = {0 0 0 $ImShift_X $ImShift_Y $Abs_ImShift $IndLoop} # The image shifts measured after RealignToNavItem echo (A) Out = {0 0 0 $ImShift_X $ImShift_Y $Abs_ImShift $IndLoop} # The image shifts measured after RealignToNavItem Return Else Copy A Q # Storing the correctly aligned image (with IS) in buffer Q ResetImageShift 1 EndIf View AlignTo Q 1 ReportAlignShift x_pix y_pix x_nm y_nm StageErrorX_nm StageErrorY_nm # ... relative to the orgianl postion that had IS [nm] (StageError is on the axis system of the stage) ImShift_X = $StageErrorX_nm / 1000 ImShift_Y = $StageErrorY_nm / 1000 Abs_ImShift = SQRT ( $ImShift_X * $ImShift_X + $ImShift_Y * $ImShift_Y ) # (um) echo (B) Out = {0 0 0 $ImShift_X $ImShift_Y $Abs_ImShift $IndLoop} # The image shifts measured after RealignToNavItem Out = {0 0 0 $ImShift_X $ImShift_Y $Abs_ImShift $IndLoop} # The image shifts measured after RealignToNavItem EndLoop EndFunction #___________________ LockOnTarget _______________ #******************************************************************************************************** Function LockOnTargetOld 1 0 # *** Align to item without iamge shift and output the error measurement # Note!!! - This function assumes a run after the navigator realined to an item # # Out array {3x1} : Stage errors in nm on the grid axis system { Err_x, Err_y, absolute_val_tot_Err } SuppressReports 1 #RealignToNavItem 1 0 # Realign and restore microscope condtions without cont acquisition - This line is not requred since the navigator realign to each acquisition item it reaches Copy A Q # Storing the correctly aligned image (with IS) in buffer Q ResetImageShift 1 # Moving the stage to zero the IS View AlignTo Q 1 # Measuring the alignment error of the Zero-IS image ... ReportAlignShift x_pix y_pix x_nm y_nm StageErrorX_nm StageErrorY_nm # ... relative to the orgianl postion that had IS [nm] (StageError is on the axis system of the stage) absErr = SQRT ( $StageErrorX_nm * $StageErrorX_nm + $StageErrorY_nm * $StageErrorY_nm) Out = {$StageErrorX_nm $StageErrorY_nm $absErr } EndFunction #___________________ LockOnTarget _______________