diff --git a/config/settings.properties b/config/settings.properties index fdd8f11..ad25994 100644 --- a/config/settings.properties +++ b/config/settings.properties @@ -1,4 +1,4 @@ -#Thu Mar 07 09:41:59 CET 2019 +#Thu Mar 07 13:59:01 CET 2019 count_time=0.1 geometry=fourcv roi=190 45 290 125 diff --git a/script/device/Auto.py b/script/device/Auto.py new file mode 100644 index 0000000..a4a59f2 --- /dev/null +++ b/script/device/Auto.py @@ -0,0 +1,355 @@ +#============================================================================== +# Description This macro provides a set of definitions which allow for +# automatic filter transmission and exposure time adjustments +# during experiments. Type 'autohelp' for information on the +# respective commands and their usage. +# After each count command, the obtained counts are evaluated and +# compared to four global threshold levels defining five +# different ranges of count rates: Poor, Acceptable, Good, +# Optimal, and Saturated. According to this analysis, filters and +# optionally also the exposure time are adjusted automatically. +# The general strategy to determine which action should be taken +# is to optimize the speed of data aquisition, even at the +# possible cost of a moderate reduction in signal-to-noise ratio. +# Presently, only two distinct exposure times are supported, a +# shorter one (t1) and a longer one (t2). +# The actions taken are summarized in the following diagram: +# +# +# Count rate | Threshold | Optimize only | Optimize filters and +# Region | level | filters (Level 1) | exposure time (Level 2) +# --------------------------------------------------------------------------- +# Saturated | | decrease transm. | 1. decrease exptime +# | | | 2. decrease tramsm. +# ------------ TH4 -------------------------------------------------------- +# Optimal | | - | 1. decrease exptime +# | | | +# ------------ TH3 -------------------------------------------------------- +# Good | | increase tramsm. | 1. decrease exptime (>=1s) +# | | | 2. increse transm. +# ------------ TH2 = 1.5* ------------------------------------------------- +# Acceptable | (t2/t1)*TH1 | increase tramsm. | 1. increase transm. +# | | | (no change in exptime) +# ------------ TH1 --------------------------------------------------------- +# Poor | | increase tramsm. | 1. increase trams. +# | | | 2. increase exptime +# --------------------------------------------------------------------------- +# +# Note: In the "Good" region, the expure time is decreased to t1 only +# if t1 is >= 1s, otherwise a 1 second exposure time is used. +# This macro is based on an earlier version by O. Bunk +# and R. Herger +# +# Author: C. M. Schlepuetz (CS) +# Co-author(s): R. Herger (RH), P. R. Willmott (PW) +# Address: Surface Diffraction Station +# Materials Science Beamline X04SA +# Swiss Light Source (SLS) +# Paul Scherrer Institut +# CH - 5232 Villigen PSI + +#auto_set_level - activate or deactivate automatic filter and exposure setting +#auto_set_exposure - define the short and long exposure time used in case of automatic exposure setting +#auto_show - display current automatic filter settings\n") +#auto_show_xposure - display current exposure time settings\n") +#============================================================================== + + + + +def auto_init(): + global AUTO_LEVEL + global AUTO_RETRY_MAX + global AUTO_COUNT_TIME + global AUTO_EXP_LO, AUTO_EXP_HI + global AUTO_THRESH1, AUTO_THRESH2, AUTO_THRESH3, AUTO_THRESH4 + global AUTO_THRESH1_COUNT, AUTO_THRESH2_COUNT + global AUTO_THRESH3_COUNT, AUTO_THRESH4_COUNT + + # for safety, set the thresh values gigantically high to start with + AUTO_THRESH1=1e8; AUTO_THRESH2=1e9; AUTO_THRESH3=1e10; AUTO_THRESH4=1e11 + + # for safety, set the thresh values gigantically high to start with + AUTO_THRESH1_COUNT=100; AUTO_THRESH2_COUNT=100; AUTO_THRESH3_COUNT=100 + AUTO_THRESH4_COUNT=100 + +auto_init() + + + +def auto_set_level(auto_level, max_tries = 20): + """ + Usage : autoSetLevel [] + can be: + 0 - automatic filter and exposure OFF + 1 - automatic filter ON, automatic exposure OFF + 2 - automatic filter and exposure ON + optionally specifies the number of retries before giving up (default = 20) + """ + global AUTO_LEVEL + global AUTO_RETRY_MAX + AUTO_LEVEL = auto_level + AUTO_RETRY_MAX = max_tries + + + # Callbacks + def auto_prescan_head(): + if (AUTO_LEVEL > 0): + filter_trans (1e-10) # if automatic filter setting is active start scan with very lowfilter transmission + + + def auto_user_chk_counts(): + if (AUTO_LEVEL > 0): + success = auto_adjust_redo() # automatic filter and exposure setting (if activated) + + def auto_precount_2() + auto_calc_exposure() # if automatic exposure setting is activated calculate exposure time + + + if (AUTO_LEVEL > 0): + # add autoPrescanHead to user_prescan_head + cdef("user_prescan_head","autoPrescanHead; ","auto_prescan_head_key",0x10) + # add autoUserChkCounts to user_chk_counts + cdef("user_chk_counts","autoUserChkCounts; ","auto_user_chk_counts_key") + + if(AUTO_LEVEL > 1): + # add autoPrecount2 to beginning of user_precount + cdef("user_precount","autoPrecount2; ","aaa_auto_precount_key", 0x10) + + if (AUTO_LEVEL < 2): + cdef("user_precount","","auto_precount_key","delete") + if (AUTO_LEVEL < 1): + # remove autoPrescanHead from user_prescan_head + cdef("user_prescan_head","","auto_prescan_head_key","delete") + + # remove autoUserChkCounts from user_chk_counts + cdef("user_chk_counts","","auto_user_chk_counts_key","delete") + + auto_show() + + +def auto_set_exposure(short_exp, long_exp) + """ + set the standard exposure times used in case of automatic filter and exposure settings. + Usage : autoSetExposure + where is the shorter and + the longer exposure time in seconds [s]. + """ + global AUTO_EXP_LO, AUTO_EXP_HI + global AUTO_THRESH1, AUTO_THRESH2, AUTO_THRESH3, AUTO_THRESH4 + + AUTO_EXP_LO = short_exp + AUTO_EXP_HI = long_exp + if (AUTO_EXP_LO >= AUTO_EXP_HI): + AUTO_EXP_LO = 1 + AUTO_EXP_HI = 10 + print ">> Invalid auto_set_exposure values - set to default values <<" + auto_show_exposure() + # set AUTO_TRESH2 1.5 times higher than ratio of counting times to avoid oscillations + AUTO_THRESH2 = AUTO_THRESH1 * (AUTO_EXP_HI/AUTO_EXP_LO) * 1.5 + + +def auto_show(): + """ + show the auto-level settings. + inform the user on the currently active auto-level + """ + + if (AUTO_LEVEL == 0): + print("auto-level has been set to %d.\n" % AUTO_LEVEL) + print("Automatic filter setting is OFF.\n") + print("Automatic exposure setting is OFF.\n") + elif (AUTO_LEVEL == 1): + print("auto-level has been set to %d.\n" % AUTO_LEVEL) + print("Automatic filter setting is ON.\n") + print("Automatic exposure setting is OFF.\n") + elif (AUTO_LEVEL == 2): + print("auto-level has been set to %d.\n" % AUTO_LEVEL) + print("Automatic filter setting is ON.\n") + print("Automatic exposure setting is ON.\n") + else: + AUTO_LEVEL = 0 + print(">> Unknown auto-level - resetting to %d <<"% AUTO_LEVEL) + print("Automatic filter setting is OFF.\n") + print("Automatic exposure setting is OFF.\n") + + + if(AUTO_LEVEL>1): + auto_show_exposure() + + #TODO: if Image being sampled, show it + #if(((whatis("IMAGE_IS_ON") & 0x08000000) != 0) && (IMAGE_IS_ON == 1)){ + # image_show() + +def auto_show_exposure(): + """ + show the auto-level exposure settings. + """ + print("detector exposure times: short = %d s, long = %d s\n" % (AUTO_EXP_LO,AUTO_EXP_HI)) + + + +def auto_calc_exposure(): + #If automatic exposure setting is activated round the current SPEC COUNT_TIME to either low or high exposure. + global COUNT_TIME + global AUTO_LEVEL + global AUTO_EXP_LO, AUTO_EXP_HI + if (AUTO_LEVEL == 2): + if (COUNT_TIME <= 0.5*(AUTO_EXP_LO+AUTO_EXP_HI)): + COUNT_TIME = AUTO_EXP_LO + else: + COUNT_TIME = AUTO_EXP_HI + return COUNT_TIME + +def autoAdjust(): + # autoAdjust() - automatically adjusts the filter transmission and + # exposure time of the currently active detector to obtain + # the best possible signal level. + # The function returns 1 if transmission or exposure + # time are changed, 0 otherwise. + # This routine should be performed after the counting + # process (this is usually done by autoAdjustRedo() ). + # Internal routine. + # + # Note: For area detectors, the background is not subtracted since over- + # and under-exposure have to be avoided on an absolute scale. + + global COUNT_TIME + + global AUTO_LEVEL + global AUTO_RETRY_MAX + global AUTO_COUNT_TIME + global AUTO_EXP_LO, AUTO_EXP_HI + global AUTO_THRESH1, AUTO_THRESH2, AUTO_THRESH3, AUTO_THRESH4 + global AUTO_THRESH1_COUNT, AUTO_THRESH2_COUNT + global AUTO_THRESH3_COUNT, AUTO_THRESH4_COUNT + + + local autoAdjusted + local autoExposure + local autoTransmVal + + if (AUTO_LEVEL < 1): + return(0) # do nothing when auto-level is zero + + # set exposure times to default if they are not defined yet + if (AUTO_EXP_LO < 0.0000001): + AUTO_EXP_LO = 1 + if (AUTO_EXP_HI < 0.0000001): + AUTO_EXP_HI = 10 + + autoAdjusted = 0 + autoExposure = auto_calc_exposure() + autoTransmVal = caget("X04SA-ES2-FI:TRANSM") + + # try to set filters and exposure time + if (AUTO_THRESH4_COUNT > 2): + # intensity too high -> reduce exposure time or filter transmission + if ((AUTO_LEVEL >= 2) && (autoExposure > AUTO_EXP_LO)): + autoExposure = AUTO_EXP_LO + print("Intensity too high - setting exposure to %d sec\n"% autoExposure) + else: + autoTransmVal /= 10.0 + filterTrans autoTransmVal + print("Intensity too high, reducing transmission to %.3e\n" % caget("X04SA-ES2-FI:TRANSM")) + autoAdjusted = 1 + + if (AUTO_THRESH2_COUNT < 1): + # intensity too low -> take out filter or increase exposure time + if (autoTransmVal < 1.0): + # take out filter + if (autoTransmVal < 1e-10): + autoTransmVal = caget("X04SA-ES2-FI:TRANSM") + + autoTransmVal *= 10.0 + if (AUTO_THRESH1_COUNT < 1) : + autoTransmVal *= 5.0 + + # readjust transmission-soll if it is > 1 now. + if (autoTransmVal > 1.0): + autoTransmVal = 1.0 + filter_trans (autoTransmVal) + print("Intensity too low, increasing transmission to %.3e\n"% caget("X04SA-ES2-FI:TRANSM")) + autoAdjusted = 1 + else: + # increase exposure time? + if ((AUTO_LEVEL >= 2) && (autoExposure < AUTO_EXP_HI))" + # check for long exposure-time + if (AUTO_THRESH1_COUNT < 1): + autoExposure = AUTO_EXP_HI + autoAdjusted = 1 + print("Intensity too low - setting exposure to %d sec\n"% autoExposure) + + if ((AUTO_THRESH3_COUNT < 1) && (AUTO_THRESH2_COUNT > 1)): + # decrease exptime? + if ((AUTO_LEVEL >= 2) && (autoExposure > AUTO_EXP_LO)): + autoExposure = AUTO_EXP_LO + if (autoExposure < 1): + autoExposure = 1 + if (autoExposure != COUNT_TIME): + autoAdjusted = 1 + print("High intensity - setting exposure to %d sec\n" % autoExposure) + else: + # increase transmission ? + if (autoTransmVal < 1.0): + # take out filter + if (autoTransmVal < 1e-10): + autoTransmVal = caget("X04SA-ES2-FI:TRANSM") + autoTransmVal *= 10.0 + # readjust transmission-soll if it is > 1 now. + if (autoTransmVal > 1.0): + autoTransmVal = 1.0 + filterTrans autoTransmVal + print("Intensity too low, increasing transmission to %.3e\n" % caget("X04SA-ES2-FI:TRANSM")) + autoAdjusted = 1 + + if ((AUTO_THRESH4_COUNT < 1) && (AUTO_THRESH3_COUNT > 1)): + # decrease exptime? + if ((AUTO_LEVEL >= 2) && (autoExposure > AUTO_EXP_LO)): + autoExposure = AUTO_EXP_LO + autoAdjusted = 1 + print("High intensity - setting exposure to %d sec\n" % autoExposure) + autoAdjusted = 1 + + if (AUTO_LEVEL == 2): + AUTO_COUNT_TIME = autoExposure + COUNT_TIME = AUTO_COUNT_TIME + _ctime = AUTO_COUNT_TIME # set the counting time for a scan to + return autoAdjusted + + + +def auto_adjust_redo(): + # autoAdjustRedo() - determines whether auto-adjusting has been successful. + # If not, counting is repeated until the best possible + # filter and exposure settings have been obtained. + # This routine is performed after the counting process + # (in user_count_end). + # Internal routine. + # + # Note: This macro makes use of the 'recount' macro which has been added to + # site.mac. + + global AUTO_LEVEL + global AUTO_RETRY_MAX + global AUTO_COUNT_TIME + _success = 1 + if (AUTO_LEVEL < 1): + return(_success) + retryCount = 0 + redo = 1 + while (redo != 0): + redo = 0 + retryCount++ + if (autoAdjust() != 0): + if (retryCount < AUTO_RETRY_MAX): + redo = 1 + else: + eprint " >> Couldn\'t optimize filter and exposure settings. <<" + if (redo != 0): + recount COUNT_TIME + else: + _success = 1 + redo = 0 + + return (_success)