esrf

Beamline Instrument Software Support
SPEC Macro documentation: [ Macro Index | BCU Home ]

#%TITLE% LINEUP.MAC
#
#%NAME%
#  Macros for line up scans.
#
#%CATEGORY% Scans
#
#%DESCRIPTION%
#  The %B%lineup%B% scan can be useful to align a motor at the position of a
#  signal peak. Once the scan is finished the motor is moved to the position
#  of the peak according to a criterion selected by means of %B%lupsetup%B%.
#  %BR%
#  The scan range is defined in relative coordinates as it is done in the
#  %B%dscan%B% macro.%BR%
#  %B%lineup%B% uses the first plotted counter as detector.
#  Use %B%plotselect%B% to change.
#
#%EXAMPLE%
#  lineup chi -1 1 15 1 %BR% %BR%
#%END%


###############################
# Define and iniatialize global variables
#
global LUPmode LUPbg
if (LUPmode == 0) LUPmode="CEN"


#%UU% <motor> <start> <finish> <intervals> <time> [<thrhold>]
#%MDESC%
#  Line up scan. It is similar to a %B%dscan%B% macro but if the scan
#  finishes succesfully the motor is moved to the position of the peak.%BR%
#  The peak position is determined according to the `LUPmode' variable
#  that can be modified with the %B%lupsetup%B% macro.%BR%
#  If the scan is aborted or an error is found the motor is moved back
#  to the original position (starting position).%BR%
#  An optional parameter <thrhold> forces the macro to further checks.
#  If the peak value is lower than the threshold value the macro prints a
#  `No peak found' error. If <thrhold> is negative the actual threshold is
#  the absolute value of <thrhold>.
#  If <thrhold> is positive the counters are run one time interval before
#  starting the scan and then the threshold value is calculated by multiplying
#  <thrhold> by the detector counts. In other words positive values of
#  <thrhold> are relative thresholds.
#
def lineup '{
    local newPK new_pos nps threshold myDET
    local pk_notfound

    if ($# != 5 && $# != 6) {
        print "Usage:  lineup motor start finish intervals time [threshold]"
        exit
    }
    _check0 "$1"
    waitall
    get_angles
    _c1=A[$1]

    local cleanstr
    cleanstr = sprintf("if (LUPbg) BG=_c2; dscan_cleanup $1 %s;", _c1)
    cdef("cleanup_once", cleanstr, "dscan")

    if (PLOT_MODE&2048)
        myDET = PLOT_LIST[0]
    else
        myDET = DET

    if ($# > 5) {
    if (($6) > 0) {
        count $5
        threshold = ($6)*S[myDET]
    } else {
        threshold = fabs($6)
    }
    printf("\nPeak threshold for `%s\' (%s): %g\n\n", \
            cnt_name(myDET), cnt_mne(myDET), threshold)
    } else {
        printf("\nUsing `%s\' (%s). No peak threshold.\n", \
            cnt_name(myDET), cnt_mne(myDET))
    }
    if (LUPbg) {
        _c2=BG
        setplot +64
    }
    ascan "$1" _c1+($2) _c1+($3) $4 $5

    newPK = pl_xMAX

    cdef("cleanup_once", "", "dscan", "delete")

    local pos1, pos2
    if ($2 > $3) {
        pos1=$3
        pos2=$2
    } else {
        pos1=$2
        pos2=$3
    }

    if (newPK <= _c1+(pos1) || newPK >= _c1+(pos2) || \
       ($# > 5 && pl_MAX < threshold)){
        printf("\nNo peak found !")
        eval(cleanstr)

    } else {
        if (LUPmode == "COM") {new_pos = pl_COM; nps=LUPmode}
        else if (LUPmode == "CEN") {new_pos = pl_CFWHM,nps=LUPmode}
        else {new_pos = pl_xMAX; nps="peak"}

        printf("\nMoving %s to %s at %g\n", motor_name($1), nps, new_pos)

        onp; offt
        printf("\nmv $1 %g\n",new_pos)
        offp; ont
        waitmove; get_angles; A[$1]=new_pos
        _move
        printf("\n")
    }
    if (LUPbg) BG=_c2
}'


#%UU% [[ PK | COM | CEN ] <bg_subtraction>
#%MDESC%
#  Lets the user select the final position after a line up and whether or not
#  background subtraction will be performed. The choices are:
#  %UL%
#  %LI% %B%PK%B% - PeaK value of the scan data.
#  %LI% %B%COM%B% - Center Of Mass of the scan data.
#  %LI% %B%CEN%B% - CENter of the FWHM.
#  %XUL%
#  The %B%lineup%B% macro (and %B%xlineup%B% if `xscans.mac' is loaded) are
#  affected.%BR%
#
def lupsetup '{
   local newLUPmode newLUPbg

   if ($# > 2) {
      print "Usage:  lupsetup [[ PK | COM | CEN ]  bckg_subtrct"
      exit
   }

   if ($# > 0) {
      newLUPmode = "$1"
   } else {
      print "\nSelect final position for `lineup\' and `xlineup\':"
      print "\t\t\t (PK) Peak position"
      print "\t\t\t(COM) Center of gravity"
      print "\t\t\t(CEN) Center of half maximum cross-section"
      newLUPmode = getval("  New position",LUPmode)
   }
   if (newLUPmode == "PK" || newLUPmode == "pk")        newLUPmode = "PK"
   else if (newLUPmode == "COM" || newLUPmode == "com") newLUPmode = "COM"
   else if (newLUPmode == "CEN" || newLUPmode == "cen") newLUPmode = "CEN"
   else {
      printf("\'%s\' is not a valid peak position criterion\n", newLUPmode)
      exit
   }

   if ($# == 2)
      newLUPbg = ($2?1:0)
   else
      newLUPbg = yesno("  Use background subtraction", LUPbg)

   if (newLUPmode != LUPmode || newLUPbg != LUPbg){
      LUPmode = newLUPmode
      LUPbg = newLUPbg
      printf("\nFinal position for `lineup\' set to `%s\'.\n", LUPmode)
      printf("Background subtraction will %sbe used.\n", LUPbg?"":"not ")
   }
}'


#%MACROS%
#
#%INTERNALS%
#  %B%lineup%B% is a relative scan (%B%dscan%B%) followed by a movement to
#  the final position. If selected the macro turns on the background
#  subtraction flag to calculate CEN and COM. When the scan is finished this
#  parameter is set back to its original value.
#%AUTHOR% P. Fajardo, (Original 4/94).
#  $Revision: 3.7 $ / $Date: 2017/02/03 14:21:29 $
#%TOC%