esrf

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

#%TITLE% getbeam.mac
#%NAME% 
#    Macros for optics alignment
#%DESCRIPTION%
# Includes macros for pslit, sslit and slitbox alignment and mono calibration.
# Includes also a menu (getbeam) to select and run alignment procedures.  
#%END%

#%UU% ()
#%MDESC% Set all the motors and counters. Check if exist. Return -1 if any
#error.
def gb_setup() '{

  if (gb_pslit() < 0) {
    if (GB_USE["pslit"] == 0)
      return(-1)
  }
  if (gb_u() < 0) {
    if (GB_USE["undulator"] == 0)
      return(-1)
  }
  if (gb_en() < 0) {
    return(-1)
  }
  if (gb_calibfoils() < 0) {
    if (GB_USE["foil"] == 0)
      return(-1)
  }
  if (gb_sslit() < 0) {
    if (GB_USE["sslit"] == 0)
      return(-1)
  }
}'


#%UU%
#%MDESC% Procedure to align the beam - primary slits, secondary slits. If all
#starts with calibrating the mono, then aligning the pslits and sslits.
def getbeam '{
local selection

  #set the default & specific parameters
  if (gb_setup() < 0)
    exit
  printf ("\n   <OPTICS ALIGNMENT (getbeam)>\n")

  while(1) {
    printf ("\n   Options:\n\n")
    printf ("   1. Pslit alignment   (OH)\n")
    printf ("   2. Mono calibration  (OH)\n")
    printf ("   3. Sslit alignment   (OH)\n")
    printf ("   4. All (pslit+mono+sslit)\n")
    printf ("   5. Mirror align menu (OH)\n" )
    printf ("   6. Slitbox alignment (EH)\n\n" )
    printf ("   0. Quit \n")

    selection =  getval("      select -> ", selection)

    if (dark_current() == -1)
      exit

    if (selection == 1) {
      pslit_align()
    } else if (selection == 2) {
      mono_calib()
    } else if (selection == 3) {
      sslit_align()
    } else if (selection == 4) {
      pslit_align()
      mono_calib()
      sslit_align()
    } else if (selection == 5) {
      mirror_align
    } else if (selection == 6) {
      slitbox_align()
    } else if (selection == 0) {
      gb_setfilters("empty")
      break
    }
  }
}'

#%UU%()
#%MDESC% Align the primary slits to the centre of the beam. Return -1 if error.
def pslit_align() '{
local darkcur zeropos cnt

  #save the slits positions
  gb_save_positions()

  cdef("cleanup_once","gb_pslit_cleanup\n","_gb_")

  tty_cntl("md")
  printf ("Aligning primary slits\n")
  tty_cntl("me")

  #close FE before moving filters to avoid moving them through the beam
  feclose
  #move the filters
  gb_setfilters("pslit")
  if (gb_checkfilters("pslit") == -1) {
     printf("Filters cannot be set. Sorry. Giving up\n")
     exit
  }

  if (GB_DARK_TAKEN == 0) {
    if (dark_current() == -1)
      exit
  }

  eval(sprintf("plotselect %s", GB_PSLIT_CTMNE))
  local_ct_set "pslit"

  darkcur = GB_DARK[GB_PSLIT_CTMNE]
  printf("Dark current for %s is %f\n", GB_PSLIT_CTMNE, darkcur)

  feopen

  if (id_state() != 4) {
    printf ("Frontend cannot open. Giving up\n")
    exit
  }

  #zero gap
  printf ("Looking for zero gap:\n")

  #Opening moderately primary slits and wide secondary slits
  printf("Opening primary slits\n")
  printf ("Set secondary slits wide open\n")

  gb_setslits("pslit", "gap")

  ##  Finding zero for vertical gap
  printf ("- VERTICAL GAP (finding zero)-\n")

  cmd = sprintf ("dscan %s %g %g %d %g", GB_PSLIT_MOT["psu"], \
	GB_PARAMS["first"]["start"], GB_PARAMS["first"]["stop"], \
	GB_PARAMS["first"]["pts"], GB_PARAMS["first"]["ctime"])
  eval (cmd)
  zeropos = slit_find_zero(0.5, GB_PSLIT_CTMNE)

  printf ("\t- moving %s to half height position %g\n", \
	GB_PSLIT_MNE["psu"], zeropos)
  A[GB_PSLIT_MOT["psu"]] = zeropos
  move_em; waitmove; get_angles

  cmd = sprintf ("dscan %s %g %g %d %g", GB_PSLIT_MOT["psd"], \
	GB_PARAMS["second"]["start"], GB_PARAMS["second"]["stop"], \
	GB_PARAMS["second"]["pts"], GB_PARAMS["second"]["ctime"])
  eval (cmd)
  zeropos = slit_find_zero(0.01, GB_PSLIT_CTMNE)

  #  TODO: check here for sensible results or quit
  printf ("\t- moving %s to zero position %g\n", GB_PSLIT_MNE["psd"], zeropos)
  A[GB_PSLIT_MOT["psd"]] = zeropos
  move_em; waitmove; get_angles

  printf ("Setting psvg to zero\n")
  eval(sprintf("set %s 0", GB_PSLIT_MNE["psvg"]))

  printf ("Opening psvg to 1\n")
  A[GB_PSLIT_MOT["psvg"]] = 1
  move_em; waitmove; get_angles

  #  Finding zero for horizontal gap
  printf ("- HORIZONTAL GAP (finding zero)-\n")

  cmd = sprintf ("dscan %s %g %g %d %g", GB_PSLIT_MOT["psr"], \
	GB_PARAMS["first"]["start"], GB_PARAMS["first"]["stop"], \
	GB_PARAMS["first"]["pts"], GB_PARAMS["first"]["ctime"])
  eval (cmd)
  zeropos = slit_find_zero(0.5, GB_PSLIT_CTMNE)

  printf ("\t- moving %s to half height position %g\n", \
		GB_PSLIT_MNE["psr"], zeropos)
  A[GB_PSLIT_MOT["psr"]] = zeropos
  move_em; waitmove; get_angles

  cmd = sprintf ("dscan %s %g %g %d %g", GB_PSLIT_MOT["psl"], \
	GB_PARAMS["second"]["start"], GB_PARAMS["second"]["stop"], \
	GB_PARAMS["second"]["pts"], GB_PARAMS["second"]["ctime"])
  eval (cmd)
  zeropos = slit_find_zero(0.01, GB_PSLIT_CTMNE)

  printf ("\t- moving %s to zero position %g\n", GB_PSLIT_MNE["psl"], zeropos)
  A[GB_PSLIT_MOT["psl"]] = zeropos
  move_em; waitmove; get_angles

  printf ("Setting pshg to zero\n")
  eval(sprintf("set %s 0", GB_PSLIT_MNE["pshg"]))

  #  Finding center for zero offset

  # vertical offset
  printf ("- VERTICAL OFFSET (finding center)-\n")

  gb_setslits("pslit", "voffset")

  cmd = sprintf ("dscan %s %g %g %d %g", GB_PSLIT_MOT["psvo"], \
	GB_PARAMS["voffset"]["start"], GB_PARAMS["voffset"]["stop"], \
	GB_PARAMS["voffset"]["pts"], GB_PARAMS["voffset"]["ctime"])
  eval (cmd)

  cnt = cnt_num(GB_PSLIT_CTMNE)
  _plcom = array_op("com", \
	SCAN_D[:NPTS-1][0],SCAN_D[:NPTS-1][cnt+1] - darkcur)
  printf("Moving %s to center of mass %f\n",  GB_PSLIT_MNE["psvo"], _plcom)
  A[GB_PSLIT_MOT["psvo"]] = _plcom
  move_em;waitmove;get_angles

  printf ("\t- setting psvo to zero\n")
  eval(sprintf("set %s 0", GB_PSLIT_MNE["psvo"]))

  #horizontal offset
  printf ("- HORIZONTAL OFFSET (finding center)-\n")

  gb_setslits("pslit", "hoffset")
 
  cmd = sprintf ("dscan %s %g %g %d %g", GB_PSLIT_MOT["psho"], \
	GB_PARAMS["hoffset"]["start"], GB_PARAMS["hoffset"]["stop"], \
	GB_PARAMS["hoffset"]["pts"], GB_PARAMS["hoffset"]["ctime"])
  eval (cmd)

  _plcom = array_op("cfwhm", \
	SCAN_D[:NPTS-1][0],SCAN_D[:NPTS-1][cnt+1] - darkcur)

  printf("Moving %s to FWHM %f\n", GB_PSLIT_MNE["psho"], _plcom)

  A[GB_PSLIT_MOT["psho"]] = _plcom
  move_em;waitmove;get_angles

  printf ("\t- setting psho to zero\n")
  eval(sprintf("set %s 0", GB_PSLIT_MNE["psho"]))

  gb_restore_positions("pslit")

  cdef("","","_gb_","delete")
  return(0)
}'


#%UU% ()
#%MDESC% Align the secondary slits to the centre of the beam.
#Return -1 if error.
def sslit_align() '{
local darkcur zeropos cnt

  gb_save_positions()

  cdef("cleanup_once","gb_sslit_cleanup\n","_gb_")

  tty_cntl("md")
  printf ("Aligning secondary slits\n")
  tty_cntl("me")

  #close FE before moving filters to avoid moving them through the beam
  feclose

  #move the filters
  gb_setfilters("sslit")
  if (gb_checkfilters("sslit") == -1) {
     printf("Filters cannot be set. Sorry. Giving up\n")
     exit
  }

  if (GB_DARK_TAKEN == 0) {
    if (dark_current() == -1)
      exit
  }

  eval(sprintf("plotselect %s", GB_SSLIT_CTMNE))
  local_ct_set "sslit"

  darkcur = GB_DARK[GB_SSLIT_CTMNE]
  
  printf("Dark current is %f\n", darkcur)

  feopen

  if (id_state() != 4 ) {
      print "Frontend cannot open. Giving up"
      exit
  }

  #zero gap
  printf ("Looking for zero gap:\n")

  #Opening moderately secondary slits and wide primary slits
  printf("Opening primary and secondary slits\n")
  gb_setslits("sslit", "gap")

  ##  Finding zero for vertical gap
  printf ("- VERTICAL GAP (finding zero)-\n")


  cmd = sprintf ("dscan %s %g %g %d %g", GB_SSLIT_MOT["ssu"], \
	GB_PARAMS["first"]["start"], GB_PARAMS["first"]["stop"], \
	GB_PARAMS["first"]["pts"], GB_PARAMS["first"]["ctime"])
  eval (cmd)
  zeropos = slit_find_zero(0.5, GB_SSLIT_CTMNE)

  printf ("\t - moving %s to half height position %g\n", \
		GB_SSLIT_MNE["ssu"], zeropos)
  A[GB_SSLIT_MOT["ssu"]] = zeropos
  move_em; waitmove; get_angles

  cmd = sprintf ("dscan %s %g %g %d %g", GB_PSLIT_MOT["ssd"], \
	GB_PARAMS["second"]["start"], GB_PARAMS["second"]["stop"], \
	GB_PARAMS["second"]["pts"], GB_PARAMS["second"]["ctime"])
  eval (cmd)
  zeropos = slit_find_zero(0.01, GB_SSLIT_CTMNE)

  printf ("\t - moving %s to zero position %g\n", GB_SSLIT_MNE["ssd"], zeropos)
  A[GB_SSLIT_MOT["ssd"]] = zeropos
  move_em; waitmove; get_angles

  printf ("Setting ssvg to zero\n")
  eval(sprintf("set %s 0", GB_SSLIT_MNE["ssvg"]))

  printf ("Opening ssvg to 1\n")
  A[GB_SSLIT_MOT["ssvg"]] = 1
  move_em; waitmove; get_angles

  #  Finding zero for horizontal gap
  printf ("- HORIZONTAL GAP (finding zero)-\n")

  cmd = sprintf ("dscan %s %g %g %d %g", GB_PSLIT_MOT["ssr"], \
	GB_PARAMS["first"]["start"], GB_PARAMS["first"]["stop"], \
	GB_PARAMS["first"]["pts"], GB_PARAMS["first"]["ctime"])
  eval (cmd)
  zeropos = slit_find_zero(0.5, GB_SSLIT_CTMNE)

  printf ("\t - moving ssr to half height position %g\n", zeropos)
  A[GB_SSLIT_MOT["ssr"]] = zeropos
  move_em; waitmove; get_angles

  cmd = sprintf ("dscan %s %g %g %d %g", GB_PSLIT_MOT["ssl"], \
	GB_PARAMS["second"]["start"], GB_PARAMS["second"]["stop"], \
	GB_PARAMS["second"]["pts"], GB_PARAMS["second"]["ctime"])
  eval (cmd)
  zeropos = slit_find_zero(0.01, GB_SSLIT_CTMNE)

  printf ("\t - moving ssl to zero position %g\n", zeropos)
  A[GB_SSLIT_MOT["ssl"]] = zeropos
  move_em; waitmove; get_angles

  printf ("Setting sshg to zero\n")
  eval(sprintf("set %s 0", GB_SSLIT_MNE["sshg"]))

  # Finding centre for zero offset

  # vertical offset
  printf ("- VERTICAL OFFSET (finding center)-\n")

  gb_setslits("sslit", "voffset")

  cmd = sprintf ("dscan %s %g %g %d %g", GB_PSLIT_MOT["ssvo"], \
	GB_PARAMS["voffset"]["start"], GB_PARAMS["voffset"]["stop"], \
	GB_PARAMS["voffset"]["pts"], GB_PARAMS["voffset"]["ctime"])
  eval (cmd) 

  cnt = cnt_num(GB_SSLIT_CTMNE)
  _plcom = array_op("com", \
	SCAN_D[:NPTS-1][0],SCAN_D[:NPTS-1][cnt+1]-darkcur)

  printf("Moving ssvo to center of mass %f\n", _plcom)

  A[GB_SSLIT_MOT["ssvo"]] = _plcom
  move_em;waitmove;get_angles

  printf ("\t - setting ssvo to zero\n")
  eval(sprintf("set %s 0", GB_SSLIT_MNE["ssvo"]))

  #horizontal offset
  printf ("- HORIZONTAL OFFSET (finding center)-\n")

  gb_setslits("pslit", "hoffset")
 

  cmd = sprintf ("dscan %s %g %g %d %g", GB_PSLIT_MOT["ssho"], \
	GB_PARAMS["hoffset"]["start"], GB_PARAMS["hoffset"]["stop"], \
	GB_PARAMS["hoffset"]["pts"], GB_PARAMS["hoffset"]["ctime"])
  eval (cmd)

  _plcom = array_op("cfwhm", \
	SCAN_D[:NPTS-1][0],SCAN_D[:NPTS-1][cnt+1]-darkcur)
  printf("Moving ssho to center of FWHM %f\n", _plcom)
  A[GB_SSLIT_MOT["ssho"]] = _plcom
  move_em;waitmove;get_angles

  printf ("\t - setting ssvo to zero\n")
  eval(sprintf("set %s 0", GB_SSLIT_MNE["ssho"]))

  printf ("\t - FINISHED. Opening sshg to 3, ssvg to 1 \n")
  A[GB_SSLIT_MOT["sshg"]] = 3.0
  A[GB_SSLIT_MOT["ssvg"]] = 1.0
  move_em;waitmove;get_angles
  

  cdef("","","_gb_","delete")
  return(0)
}'

#%IU% ()
#%MDESC% Save position of pslits, sslits and slitbox
def gb_save_positions() '{
global GB_SAVED

  if (GB_USE["pslit"]) {
    GB_SAVED["pslit"]["pshg"] = A[GB_PSLIT_MOT["pshg"]]
    GB_SAVED["pslit"]["psvg"] = A[GB_PSLIT_MOT["psvg"]]
    GB_SAVED["pslit"]["psho"] = A[GB_PSLIT_MOT["psho"]]
    GB_SAVED["pslit"]["psvo"] = A[GB_PSLIT_MOT["psvo"]]
  }

  if (GB_USE["sslit"]) {
    GB_SAVED["sslit"]["sshg"] = A[GB_SSLIT_MOT["sshg"]]
    GB_SAVED["sslit"]["ssvg"] = A[GB_SSLIT_MOT["ssvg"]]
    GB_SAVED["sslit"]["ssho"] = A[GB_SSLIT_MOT["ssho"]]
    GB_SAVED["sslit"]["ssvo"] = A[GB_SSLIT_MOT["ssvo"]]
  }

  if (GB_USE["slitbox"]) {
    GB_SAVED["slitbox"]["s1h"] = A[GB_SB_MOT["s1h"]]
    GB_SAVED["slitbox"]["s1v"] = A[GB_SB_MOT["s1v"]]
    GB_SAVED["slitbox"]["s2h"] = A[GB_SB_MOT["s2h"]]
    GB_SAVED["slitbox"]["s2v"] = A[GB_SB_MOT["s2v"]]
  }
}'

#%IU% (key)
#%MDESC% Restore all positions saved or a name set of it (%B%key%B% is set
#to pslit, sslit, slitbox )
def gb_restore_positions(key) '{
local motnum mne

  printf("Restoring %s to saved positions.\n", key)

  for (mne in GB_SAVED[key]) {
    motnum = motor_num(mne)
    A[motnum] = GB_SAVED[key][mne]
  }

  move_em; waitmove; get_angles
}'


#******** dark current ********
#%IU% ()
#%MDESC% Procedure to take the dark current. Returns 0 if OK, -1 if error. 
def dark_current() '{
global GB_DARK GB_DARK_TAKEN

  GB_DARK_TAKEN = 0

  feclose
  if (id_state() != 3 ) {
     printf ("Frontend cannot open. Giving up dark current measuring.\n")
     GB_DARK["dm2"] = -1
     GB_DARK["i0"] = -1
     return(-1) 
   }
  GB_DARK["dm2"] = getdark(dm2,0.1,10)
  GB_DARK["i0"] = getdark(i0,0.1,10)
  GB_DARK_TAKEN = 1
  return(0)
}'

#%IU%(cnt,cttime,iter)
#%MDESC% Get the dark current of a %B%cnt%B% WAGO counter, for %B%iter%B%
#iterations.
def getdark(cnt,cttime,iter) '{
  local acum ai

  acum = 0
  for (ai=0;ai<iter;ai++) {
    sleep(cttime)
    wcreadct(WAGO_CTDEV[cnt],cnt)
    acum += S[cnt]
  }
  return( acum/(iter+0.0) )
}'

#%IU%(cnt,cttime,iter)
#%MDESC% Get the dark current of a "VCT6 like" %B%cnt%B% counter, counting
#%B%cttime%B%, for %B%iter%B% iterations.
def getdarkct (cnt, cttime,iter) '{
  local acum ai

  acum = 0
  for (ai=0;ai<iter;ai++) {
    tcount(cttime); waitcount; getcounts
    acum += S[cnt]
  }
  return( acum/(iter+0.0) )
}'
#******** end dark current ********

#******** filters procedures ********

#%IU% (key)
#%MDESC% Move the detectors and filters motors to the predefined positions
#as function of the %B%key%B% word (pslit, sslit, empty, mono ...).
def gb_setfilters(key) '{
local motmne motnum rcurr
global GB_FILTERS

  printf("Moving filters to %s position\n",key)

  if (key != "empty") {
    #get the machine current to choose the right white beam attenuator
    rcurr = _rc()
    if (rcurr < 0) {
      printf ("Cannot read the ring current, exiting...\n")
      exit
    }
  }

  if (gb_filters(key, rcurr) < 0)
    exit

  #Close front end before moving filters to avoid moving them through the beam
  if (key != "empty")
    feclose

  waitmove; get_angles
  for (motmne in GB_FILTERS[key]) {
    if (motmne) {
      motnum = motor_num(motmne)
      if (motnum != -1) {
        A[motnum] = GB_FILTERS[key][motmne]
      }
    } else {
      print "Filter motor configuration is wrong. "
      printf("Motor %s is not configured.  Please check it.", motmne)
      exit
    }
  }
  move_em; waitmove; get_angles
}'

#%IU% (key)
#%MDESC% Check that detectors and filters motors are at predefined positions
#  as function of the %B%key%B% word (pslit, sslit, empty...).
def gb_checkfilters(key) '{
  local motmne motnum difpos

  waitmove; get_angles

  for (motmne in GB_FILTERS[key]) {
    motnum = motor_num(motmne) 
    difpos = fabs( A[motnum] - GB_FILTERS[key])
    if (motnum == -1 || difpos > 0.1 )
      return (-1)
  }
}'

#******** end filters procedures ********

#******** slits procedures ********
#%IU% (key)
#%MDESC% Set the primary and secondary slits predefined positions.
def gb_setslits(key, key2) '{

  if (GB_USE[key] != -1) {
    if (gb_positions(key, key2) < 0) {
      eprintf ("Positions not set, nothing moved\n")
      return(-1)
    }
    printf ("Moving mottors, please wait...\n")
    move_em; waitmove; get_angles
  }
}'

#%IU%(sfor,cnt)
#%MDESC%Find the min value position, using the %B%cnt%B% counter data and
#%B%sfor%B% treshold (e.g. sfor=0.5 gives the half height position).
def slit_find_zero(sfor,cnt) '{

  local min max idxmin
  local retpos seachfor
  local float array avarr[(NPTS-1)/2][1]

  cnt = cnt_num(cnt)
  # contract the array by three to get averaging on every three points
  avarr    = array_op("contract", SCAN_D[0:NPTS-1][cnt+1],2)
  max      = array_op("max", avarr)
  min      = array_op("min", avarr)
  seachfor = (max - min) * sfor + min

  idxmin = array_op("i_<=_value", SCAN_D[0:NPTS-1][cnt+1],seachfor)
  retpos = SCAN_D[idxmin-1][0]
  return(retpos)
}'

#******** end slits procedures ********

#******** cleanup procedures ********
#%IU%
#%MDESC% Primaty slits cleanup part.
def gb_pslit_cleanup '{

  feclose

  gb_restore_positions("pslit")
  gb_setfilters("empty")

}'
#%IU%
#%MDESC% Monochromator calibration cleanup
def gb_monocalib_cleanup '{

  feclose

  if (GB_USE["pslit"] != -1)
    gb_restore_positions("pslit")
  if (GB_USE["filter"] != -1)
    gb_setfilters("empty")

}'

#%IU%
#%MDESC% Secondary slits cleanup part.
def gb_sslit_cleanup '{

  feclose

  gb_restore_positions("sslit")
  gb_setfilters("empty")

}'

#******** end cleanup procedures ********

if (whatis("local_ct_set") == 0)
  eval("def local_ct_set\'{ }\'")

if (whatis("_rc") == 0)
  eval("def _rc()\'{ }\'")

#%MACROS%
#%IMACROS%
#%DEPENDENCIES% machinfo.mac getbeam_presets.mac monocalib.mac
#mirror_align.mac slitboxalign.mac
#%TOC%
#%AUTHOR% A.Beteva%BR%
#$Revision: 2.0 $$Date: 2013/05/31 09:31:26 $
#%END%
#%LOG%
#$Log: getbeam.mac,v $
#Revision 2.0  2013/05/31 09:31:26  beteva
#*** empty log message ***
#
#Revision 1.1  2005/08/31 08:20:58  beteva
#Initial revision