esrf

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

#%NAME%
#  Macrocontroller to read the xbpm positions, intensity and FWHM
#  
#%DESCRIPTION%
#  Macrocontroller to read the xbpms position X, Y, intensity and FWHM on X, Y.
#%BR% Spec configuration:
#%BR% 
#%BR% --- The controller xbpm must be declared in the SCALERS part
#%BR%\0
#%BR%SCALERS\0\0\0\0\0\0DEVICE\0\0ADDR\0\0<>MODE\0\0NUM\0\0\0\0<>TYPE
#%BR%\0\0\0\0YES\0\0\0\0\0\0\0xbpm\0\0ID24/xbpm/1\0\0\0\04\0\0\0\0\0\0Macro Counter
#%BR%- ADDR: tango device name: this is the 'BeamViewer' device of the xbpmds
#or LimaCCDs server.
#%BR% 
#%BR%The controller parameters (CONPAR):
#%BR%- limadev : 'LimaCCDs' device of a LimaCCDs server - used for roi and
#image saving features. The device server has to be started as opidxx if
#the saving of the image feature is to be used. 
#%BR%Note: the use of a xbpmds (not limads) server does not allow to use the
#roi or image save features.
#%BR%- alias   : an alias name for the xbpm (used only for display).
#%BR%\0
#%BR%--- The counters can be defined in the Scaler (Counter) Configuration
#%BR%\0
#%BR%Number\0\0\0\0\0\0Name\0\0\0Mnemonic\0\0<>Device\0\0Unit\0\0Chan\0\0<>Use\0As\0\0Scale\0Factor
#%BR%\0\0\0\010\0\0x_intens\0\0x_intens\0\0\0MAC_CNT\0\0\0\00\0\0\0\01\0\0\0\0\0counter\0\0\0\0\0\0\0\0\0\01
#%BR%\0\0\0\011\0\0\0\0\0\0\0x_x\0\0\0\0\0\0\0x_x\0\0\0MAC_CNT\0\0\0\00\0\0\0\02\0\0\0\0\0counter\0\0\0\0\0\0\0\0\0\01
#%BR%\0\0\0\012\0\0\0\0\0\0\0x_y\0\0\0\0\0\0\0x_y\0\0\0MAC_CNT\0\0\0\00\0\0\0\03\0\0\0\0\0counter\0\0\0\0\0\0\0\0\0\01
#%BR%\0
#%BR%- Unit refers to the macrocounter index in the SCALERS part (used also as 'unit' argument in the macros)
#%BR%- channel: 1 (for intensity), 2 (for X position), 3 (for Y position), 4 (FWHM X), 5 (FWHM Y)

#%END%

global xbpm_SIMUL xbpm_DEBUG xbpm_CNT[] xbpm_DEV[] xbpm_CNTNB[] xbpm_LIMADEV[] xbpm_OLD[]
global xbpm_STATE[] xbpm_ALIAS[] xbpm_CT
 
#%UU%
#%MDESC% toggle the debug mode
if (!(whatis("__xbpm_debug")  & 2)) rdef __xbpm_debug \'#$*\'
def xbpm_debug '{
  if ((whatis("__xbpm_debug")>>16) <= 3) { # macro length is 3 bytes: comment
     rdef __xbpm_debug "eprint"
     print "xbpm macro debug mode is ON"
     xbpm_DEBUG = 1
  }
  else {
     rdef __xbpm_debug \'#\$*\'
     print "xbpm macro debug mode is OFF"
     xbpm_DEBUG = 0
  }
}'

#%IU% (mne, type, unit, module, chan)
#%MDESC% Called after reading the config file. If return the string ".error.",
#spec will consider the channel unusable.
def xbpm_config(mne, type, unit, module, chan)'{

   __xbpm_debug ">>> xbpm:    ",mne, type, unit, module, chan

  TANGO_ERR = "-1"
  if (type=="ctrl") {
    unglobal xbpm_SIMUL xbpm_STATE xbpm_CNTNB
    global xbpm_SIMUL[] xbpm_STATE[] xbpm_CNTNB[]
    #tango_io(xbpm_ADDR, "State")
    #if (TANGO_ERR){
    #  print_tango_err()
    #  return ".error."
    #}
    #tango_io(xbpm_ADDR,"timeout",10)
    xbpm_DEV[unit] = xbpm_ADDR
    xbpm_LIMADEV[unit] = xbpm_CONPAR["limadev"]
    xbpm_ALIAS[unit] = xbpm_CONPAR["alias"]
    if (whatis("xbpm_local_cmd") == 0)
      eval2("def xbpm_local_cmd()\'{ }\'")
  }
  if (type == "cnt") {
    if (chan > 6) {
      eprintf ("Channel number %d for counter %s invalid, disabling\n", \
	chan, mne)
      return ".error."
    }
    xbpm_CNTNB[unit][chan] = cnt_num(mne)
  }
  if (type == "mot") {
    return
  }
}'

#%IU% (mne, key, p1, p2, unit)
#%MDESC% Execute the command %B%key%B% for the counter %B%mne%B%, with
#parameters %B%p1%B% and %B%p2%B% if needed. The keys used are as follows:%BR%
#%B%"start_one"%B% and %B%"prestart_all"%B% - start the counting
#Parameters: p1 - counting time.%BR%
#Parameters: p2 - 2 (count to a time preset - tcount()).%BR%
#Parameters: unit - the unit number (if me is ..).%BR%
#%B%"counts"%B% - return the current counts.
#Parameters: unit - the unit number (if mne is ..).%BR%
#%B%"get_status%B%" - only used for polling counter
#Parameters:none.%BR%
#%B%"halt_all%B%" - stop the counting and read the controller (all the
#counters in one go)
#Parameters: p1 - controller unit number.%BR%
#Return the string ".error.", spec will consider the channel unusable.
def xbpm_cmd(mne,key,p1,p2,unit)'{
local out[] old_exptime

  __xbpm_debug ">>> xbpm:    ",mne, key, p1, p2, unit

  #hook local actions
  if (xbpm_local_cmd(key, unit) == -1)
    return ".error."
    
  if (key == "prestart_all") {
    if ((xbpm_SIMUL[unit] == 1) || (_xbpmcntstate(unit)  == 1))
      return
    _xbpmena(unit,1)

    #change the count time if different from the ct one
    if (xbpm_CT)
      p1 = xbpm_CT

    TANGO_ERR = "-1"
    
    # Stores exposure time to restore it after counting.
    xbpm_OLD[unit]["exptime"] = tango_get(xbpm_LIMADEV[unit], "video_exposure")

    # Stores "live" mode of LIMACCDS device.
    xbpm_OLD[unit]["live"] = tango_get(xbpm_LIMADEV[unit], "video_live")

    # Stores "live" mode of Beamviewer device.
    xbpm_OLD[unit]["bv_live"] = tango_get(xbpm_ADDR, "LiveState")

    # Stops LIMACCDS "live" mode
    tango_put(xbpm_LIMADEV[unit], "video_live", 0)

    # Stops (if needed) Beamviwer "live" (Live command)
    if(tango_get(xbpm_ADDR, "LiveState") != 0){
        # print "stops bv live"
        tango_io(xbpm_ADDR, "Stop")
    }

    # Change exposure time on booth DS
    tango_put(xbpm_ADDR, "ExposureTime", p1)
    if (TANGO_ERR){
      _geterr(unit)
      _xbpmdisa(unit,1)
      print_tango_err()
      return ".error."
    }
    TANGO_ERR = "-1"
    tango_io(xbpm_ADDR,"AcquirePositions", p1)
  }

  if (key == "halt_all") {
    if ((xbpm_SIMUL[p1] == 1) || (xbpm_STATE[p1] == 1))
      return
    # restores exposure time.
    tango_put(xbpm_LIMADEV[p1], "video_exposure", xbpm_OLD[p1]["exptime"])
    
    TANGO_ERR = "-1"
    tango_get(xbpm_ADDR,"AcquisitionSpectrum", out)
    if (TANGO_ERR){
      tango_put(xbpm_LIMADEV[p1], "video_live", xbpm_OLD[p1]["live"])
      print_tango_err()
      _xbpmdisa(p1,1)
      return ".error."
    }  

    # Restores if needed Beamviewer "live mode".
    if (xbpm_OLD[unit]["bv_live"] != 0){
        tango_io(xbpm_ADDR, "Live")
    }

    # Restores if needed LIMACCDS "live mode".
    tango_put(xbpm_LIMADEV[p1], "video_live", xbpm_OLD[p1]["live"])
    xbpm_CNT[xbpm_ADDR][1] = out[3]
    xbpm_CNT[xbpm_ADDR][2] = out[1]
    xbpm_CNT[xbpm_ADDR][3] = out[2]
    xbpm_CNT[xbpm_ADDR][4] = out[4]
    xbpm_CNT[xbpm_ADDR][5] = out[5]
    if ((xbpm_IMG[p1]["autosave"] == 0) && (xbpm_IMG[p1]["save"] == 1)) {
      if (_xbpm_imgsave(p1) == -1) {
        xbpm_IMG[p1]["save"] = 0
        _xbpmdisa(p1,1)
        return ".error."
      }
    }
  }

  if (key == "counts") {
    local mychan myval

    mychan = counter_par(mne,"channel")
    myval = xbpm_CNT[xbpm_ADDR][mychan]
    return myval
  }
}'

#%IU% (unit,flag)
#%MDESC% Enable the %B%unit%B% number counters.If %B%flag%B%, set only the
#simulation.
def _xbpmena(unit,flag) '{
local i

  xbpm_STATE[unit] = 0
  if (flag) {
    xbpm_SIMUL[unit] = 0
    return(0)
  }
  for (i in xbpm_CNTNB[unit]) {
    counter_par(xbpm_CNTNB[unit][i], "disable", 0)
  }
}'

#%IU% (unit,flag)
#%MDESC% Disable the %B%unit%B% number counters. If %B%flag%B%, set only the
#simulation.
def _xbpmdisa(unit,flag) '{
local i

  if (flag) {
    xbpm_SIMUL[unit] = 1
    return(0)
  }
  for (i in xbpm_CNTNB[unit]) {
    counter_par(xbpm_CNTNB[unit][i], "disable", 1)
  }
}'

#%IU% (unit)
#%MDESC% Check if the %B%unit%B% number counters are enabled/disabled.
def _xbpmcntstate(unit) '{
local stat
  for (i in xbpm_CNTNB[unit]) {
    if (counter_par(xbpm_CNTNB[unit][i], "disable") == 1)
      return(1)
  }
  return(0)
}'

#%UU% [controller name|unit]
#%MDESC% Disable the %B%unit%B% number counters, all if unit not specified.

def xbpmoff '{
    local i n
    n = $#

    if (n>0) {
        i = _xbpm_dev2unit ("$1")
        xbpm_SIMUL[i] = 1
        _xbpmdisa(i)
    } else {
        for (i in xbpm_DEV) {
            xbpm_SIMUL[i] = 1
            _xbpmdisa(i)
        }
    }
}'

#%UU% [unit]
#%MDESC% Enable the %B%unit%B% number counters, all if unit not specified.
def xbpmon '{
    local i n
    n = $#

    if (n>0) {
        i = _xbpm_dev2unit ("$1")
        xbpm_SIMUL[i] = 0
        _xbpmena(i)
    } else {
        for (i in xbpm_DEV) {
            xbpm_SIMUL[i] = 0
            _xbpmena(i)
        }
    }
}'

def _xbpm_dev2unit(name) '{

    local _unit _name

    for (_unit in xbpm_DEV) {
        split (xbpm_DEV[_unit],_name,"/")
        if (_name[2] == name) {
            return _unit
        }
    }
    return name
}'

def xbpm '{

local ch unt name cnts


printf ("unit name     simul counters \n\n")

for (unt in xbpm_DEV) {
    split (xbpm_DEV[unt],name,"/")
    printf ("%4d ",unt)
    printf ("%-8s ",name[2])
    cnts=""
    for (ch in xbpm_CNTNB[unt]) {
        cnts=sprintf("%s%s ", cnts, cnt_mne(xbpm_CNTNB[unt][ch]))
    }
    printf ("%-6s ",xbpm_SIMUL[unt]?"OFF":(cnts==""?"OFF":"/"))
    cnts=cnts==""?"DISABLED in config":cnts
    print cnts
}
}'

#%IU% (unit)
#%MDESC% Take backgroung for the BPM %B%unit%B%.
def _xbpm_takebg(unit) '{

  TANGO_ERR = "-1"
  tango_io(xbpm_DEV[unit], "TakeBackground")
  if (TANGO_ERR){
    print_tango_err()
    return (-1)
  }
  return(0)
}'

#%UU% (unit, tt)
#%MDESC% Take backgroung for %B%unit%B% (as in the spec config) xbpm - close
#safety shutter, take the background, open the safety shutter. If time %B%tt%B%
#[s] specified, change the exposure time.
def xbpm_takebg(unit, tt) '{
local tsave shsave ret[] i

  TANGO_ERR = "-1"
  tsave = tango_get(xbpm_DEV[unit], "ExposureTime")
  if (TANGO_ERR){
    print_tango_err()
    printf ("Background not taken!\n")
    return (-1)
  }  

  if (tt != 0) {
    printf ("Taking background for %0.3f seconds\n", tt)
    TANGO_ERR = "-1"
    tango_put(xbpm_DEV[unit], "ExposureTime", tt)
    if (TANGO_ERR){
      print_tango_err()
      printf ("Background not taken!\n")
      return (-1)
    }
  } else
    printf ("Taking background for %f seconds\n", tsave)

  shsave = _bshstate(SHUTTER["_CURRENT"])
  if (shsave == 3)
    shclose
  if (_xbpm_takebg(unit) == -1)
    eprintf ("Background not taken!\n")
  else {
    tcount(tt); waitcount
    for (i in xbpm_CNT[xbpm_DEV[unit]])
      ret[unit][i] = xbpm_CNT[xbpm_DEV[unit]][i]
  }

  if (shsave == 3)
    shopen
  return(ret)
}'

#%UU% [unit, directory, prefix]
#%MDESC% Save automatically the last gathered image. Set the %B%directory%B%
#where the image with the %B%preffix%B% filename will be saved.
def xbpmimgautosave '{
global xbpm_IMG
local unit i nb_xbpm msg

  if ($# == 3) {
    unit = $1
    xbpm_IMG[unit]["directory"] = "$2"
    xbpm_IMG[unit]["prefix"] = "$3"
  } else {
    nb_xbpm = 0
    for (i in xbpm_DEV) {
      msg = sprintf ("%s%s(%d), ", msg, xbpm_ALIAS[i],i)
      nb_xbpm++
      unit=i
    }

    if (nb_xbpm > 1) {
      printf ("Which BPM do you want to use: %s", msg)
      unit -=1
      unit = getval("", unit)
    }

    if (unit < 0)
      exit
    printf ("Image parameters:\n")
    xbpm_IMG[unit]["directory"] = \
	getval("\tDirectory full path    ", xbpm_IMG[unit]["directory"])
    xbpm_IMG[unit]["prefix"] = \
	getval("\tFile prefix            ", xbpm_IMG[unit]["prefix"])
  }
  flag = yesno("Set the automatic saving of the last immage", 1)
  _xbpm_imgautosave(unit, flag, \
  			xbpm_IMG[unit]["directory"], xbpm_IMG[unit]["prefix"])
}'

#%IU% (unit, flag, dir, pref)
#%MDESC% Eanble (flag = 1)/disable (flag = 0) automatic saving of the last
#image gathered. If %B%dir%B% and %B%pref%B% not specified, the image will
#be saved in a file with set in advanced.
#Return -1 if error from the device server, 0 if OK.
def  _xbpm_imgautosave(unit, flag, dir, pref) '{

  if (flag == 0) {
    xbpm_IMG[unit]["autosave"] = 0
    TANGO_ERR = "-1"
    tango_io(xbpm_DEV[unit], "DisableAutoSaving")
    if (TANGO_ERR) {
      print_tango_err()
      return(-1)
    } else
      printf ("Automatic saving of images stopped\n")
  } else if (flag == 1) {
    if ((dir) && (pref)) {
      xbpm_IMG[unit]["directory"] = dir
      xbpm_IMG[unit]["prefix"] = pref
    }
    argin[0] =  xbpm_IMG[unit]["directory"]
    argin[1] = xbpm_IMG[unit]["prefix"]

    TANGO_ERR = "-1"
    tango_io(xbpm_DEV[unit], "EanableAutoSaving", argin)
    if (TANGO_ERR) {
      print_tango_err()
      xbpm_IMG[unit]["autosave"] = 0
      return (-1)
    } else {
      xbpm_IMG[unit]["autosave"] = 1
      printf ("Automatic saving of images set\n")
    }
  }
  return(0)
}'

######## Commands addressing the LIMA device ########

#%UU% [unit X Y Width Height]
#%MDESC% Set a ROI for the BPM %B%unit%B%.
def xbpmroi '{
global xbpm_ROI
local unit i nb_xbpm
  if ($# == 5) {
    unit = $1
    xbpm_ROI[unit][0] = $2
    xbpm_ROI[unit][1] = $3
    xbpm_ROI[unit][2] = $4
    xbpm_ROI[unit][3] = $5
  } else {
    nb_xbpm = 0
    for (i in xbpm_LIMADEV) {
      msg = sprintf ("%s%s(%d), ", msg, xbpm_ALIAS[i],i)
      nb_xbpm++
      unit=i
    }

    if (nb_xbpm > 1) {
      printf ("Which BPM do you want to use: %s", msg)
      unit -=1
      unit = getval("", unit)
    }
    if (unit < 0)
      exit
    printf ("ROI coordinates and size [pixels]:\n")
    xbpm_ROI[unit][0] = getval("\tX coordinate", xbpm_ROI[unit][0])
    xbpm_ROI[unit][1] = getval("\tY coordinate", xbpm_ROI[unit][1])
    xbpm_ROI[unit][2] = getval("\tWidth       ", xbpm_ROI[unit][2])
    xbpm_ROI[unit][3] = getval("\tHeight      ", xbpm_ROI[unit][3])
  }
  if (_xbpmroiset(unit) == -1)
    _xbpmdisa(unit)

}'

#%UU% [unit]
#%MDESC% Displays the ROI for all the defined BPMs or the BPM %B%unit%B%.
def xbpmroiget '{
local i

  if ($1)
    _xbpmroiget($1)
  else {
    for (i in xbpm_LIMADEV)
      _xbpmroiget(i)
  }
}'

#%IU% (unit)
#%MDESC% Displays the ROI for the BPM %B%unit%B%. 
def _xbpmroiget(unit) '{
local lroi[]

  TANGO_ERR = "-1"
  tango_get(xbpm_LIMADEV[unit],"image_roi", lroi)
  if (TANGO_ERR){
    print_tango_err()
    return (-1)
  }
  printf ("ROI for %s - unit %1d [pixels]:\n", xbpm_DEV[unit], unit)
  printf ("\tX coordinate: %d\n", lroi[0])
  printf ("\tY coordinate: %d\n", lroi[1])
  printf ("\tWidth       : %d\n", lroi[2])
  printf ("\tHeight      : %d\n", lroi[3])

  return(0)
}'

#%IU% (unit)
#%MDESC% Set a ROI for the BPM %B%unit%B% if needed. 
def _xbpmroiset(unit) '{
global xbpm_ROI
local lroi[] setroi ret

  setroi = 0
  TANGO_ERR = "-1"
  tango_get(xbpm_LIMADEV[unit],"image_roi", lroi)
  if (TANGO_ERR){
    print_tango_err()
    return (-1)
  }
  for (i in lroi) {
    if (xbpm_ROI[unit][i] != lroi[i]) {
      lroi[i] = xbpm_ROI[unit][i]
      setroi = 1
    }
  }
  ret = 0
  if (setroi)
    ret = tango_put(xbpm_LIMADEV[unit],"image_roi", lroi)
  return(ret)
}'


#%UU% [unit, directory, prefix, [suffix], [format]]
#%MDESC% Prepare the images for %B%unit%B% (as in the spec config) xbpm to be
#save in a file. Accepted formats are raw ot edf.
def xbpmimgset '{
global xbpm_IMG
local unit i nb_xbpm dt
  if ($# == 5) {
    unit = $1
    xbpm_IMG[unit]["directory"] = "$2"
    xbpm_IMG[unit]["prefix"] = "$3"
    xbpm_IMG[unit]["suffix"] = "$4"
    xbpm_IMG[unit]["format"] = "$5"
  } else {
    nb_xbpm = 0
    for (i in xbpm_LIMADEV) {
      msg = sprintf ("%s%s(%d), ", msg, xbpm_ALIAS[i],i)
      nb_xbpm++
      unit=i
    }

    if (nb_xbpm > 1) {
      printf ("Which BPM do you want to use: %s", msg)
      unit -=1
      unit = getval("", unit)
    }
    if (unit < 0)
      exit
    printf ("Image parameters:\n")
    xbpm_IMG[unit]["directory"] = \
	getval("\tDirectory full path    ", xbpm_IMG[unit]["directory"])
    xbpm_IMG[unit]["prefix"] = \
	getval("\tFile prefix            ", xbpm_IMG[unit]["prefix"])
    xbpm_IMG[unit]["suffix"] = \
	getval("\tFile suffix            ", xbpm_IMG[unit]["suffix"])

    if ((xbpm_IMG[unit]["suffix"] == "EDF") || \
	(xbpm_IMG[unit]["suffix"] == "edf")) {
      xbpm_IMG[unit]["format"] = "EDF"
    }
    if ((xbpm_IMG[unit]["suffix"] == "RAW") || \
	(xbpm_IMG[unit]["suffix"] == "raw")) {
      xbpm_IMG[unit]["format"] = "RAW"
    }
    xbpm_IMG[unit]["format"] = \
	getval("\tImage format (raw, edf)", xbpm_IMG[unit]["format"])
  }
  while ((xbpm_IMG[unit]["format"] != "EDF" ) && \
	(xbpm_IMG[unit]["format"] != "edf" ) && \
	(xbpm_IMG[unit]["format"] != "RAW" ) && \
	(xbpm_IMG[unit]["format"] != "raw" )) {
    eprintf ("Invalid file format %s\n", xbpm_IMG[unit]["format"])
     
    xbpm_IMG[unit]["format"] = \
	getval("\tImage format (raw, edf)", xbpm_IMG[unit]["format"])
  }

  if (_xbpm_imgset(unit) == -1)
    eprintf ("Sorry, impossible to save images\n")
  else {
    dt = ""
    if (asc(xbpm_IMG[unit]["suffix"]) != 46) {
      dt = "."
    }
    printf ("Images will be saved in the %s/%s*%s%s file in %s format\n", \
	xbpm_IMG[unit]["directory"], xbpm_IMG[unit]["prefix"], dt,\
	xbpm_IMG[unit]["suffix"], xbpm_IMG[unit]["format"])
  }
}'

#%IU% (unit)
#%MDESC% Save the last gathered image. Return 0 if image saved, -1 if error.
def _xbpm_imgsave(unit) '{

  if (xbpm_IMG[unit]["save"] == 0)
    return(0)

  TANGO_ERR = "-1"
  tango_io(xbpm_LIMADEV[unit], "writeImage", -1)
  if (TANGO_ERR){
    print_tango_err()
    return (-1)
  }
  return(0)
}'

#%IU% (unit, dir, pref, suf, fmt)
#%MDESC% Prepare the images for %B%unit%B% (as in the spec config) xbpm to be
#save in a file. Accepted formats are raw ot edf.
def _xbpm_imgset(unit, dir, pref, suf, fmt) '{
global xbpm_IMG
local ret cmd

  xbpm_IMG[unit]["save"] = 0

  TANGO_ERR = "-1"
  if (dir)
    xbpm_IMG[unit]["directory"] = dir
  tango_put(xbpm_LIMADEV[unit],"saving_directory", xbpm_IMG[unit]["directory"])
  if (TANGO_ERR){
    print_tango_err()
    return (-1)
  }

  TANGO_ERR = "-1"
  if (pref)
    xbpm_IMG[unit]["prefix"] = pref
  tango_put(xbpm_LIMADEV[unit],"saving_prefix", xbpm_IMG[unit]["prefix"])
  if (TANGO_ERR){
    print_tango_err()
    return (-1)
  }

  if (suf)
    xbpm_IMG[unit]["suffix"] = suf
  TANGO_ERR = "-1"
  tango_put(xbpm_LIMADEV[unit],"saving_suffix", xbpm_IMG[unit]["suffix"])
  if (TANGO_ERR){
    print_tango_err()
    return (-1)
  }

  if (fmt)
    xbpm_IMG[unit]["format"] = fmt

  TANGO_ERR = "-1"
  tango_put(xbpm_LIMADEV[unit],"saving_format", xbpm_IMG[unit]["format"])
  if (TANGO_ERR){
    print_tango_err()
    return (-1)
  }
  xbpm_IMG[unit]["save"] = 1
}'

#%UU%
#%MDESC% Show the image saving parameters, if set.
def xbpmimgparsget '{
local unit sav

  for (unit in xbpm_LIMADEV) {
    printf ("BPM %s(unit #%d) image saving parameters", xbpm_ALIAS[unit], unit)
    if (xbpm_IMG[unit["directory"]) {
      printf (":\n")
      if (_xbpm_imgpars_get(unit) != -1) {
        printf ("\tDirectory full path ", xbpm_IMG[unit]["directory"])
        printf ("\tFile prefix         ", xbpm_IMG[unit]["prefix"])
        printf ("\tFile suffix         ", xbpm_IMG[unit]["suffix"])
        printf ("\tImage format        ", xbpm_IMG[unit]["format"])
        sav = (xbpm_IMG[unit]["save"] == 1) ? "YES" : "NO "
        printf ("\tSave the image: %s ", sav)
      } else {
        eprintf ("Cannot get the image saving parameters\n")
      }
    } else {
      printf (" not set.\n")
    }
  }
}'

#%IU% (unit)
#%MDESC% Get the images parameters for %B%unit%B% (as in the spec config) xbpm.
def _xbpm_imgpars_get(unit) '{
global xbpm_IMG
local ret cmd

  TANGO_ERR = "-1"
  ret = tango_get(xbpm_LIMADEV[unit],"saving_directory")
  if (TANGO_ERR){
    print_tango_err()
    return (-1)
  }
  if (ret)
    xbpm_IMG[unit]["directory"] = ret
  

  TANGO_ERR = "-1"
  ret = tango_get(xbpm_LIMADEV[unit],"saving_prefix")
  if (TANGO_ERR){
    print_tango_err()
    return (-1)
  }
  if (ret)
    xbpm_IMG[unit]["prefix"] = ret

  TANGO_ERR = "-1"
  ret = tango_get(xbpm_LIMADEV[unit],"saving_suffix")
  if (TANGO_ERR){
    print_tango_err()
    return (-1)
  }
  if (ret)
    xbpm_IMG[unit]["suffix"] = ret

  TANGO_ERR = "-1"
  ret = tango_get(xbpm_LIMADEV[unit],"saving_format")
  if (TANGO_ERR){
    print_tango_err()
    return (-1)
  }
  if (ret)
    xbpm_IMG[unit]["format"] = ret
}'

#%UU% (unit, flag)
#%MDESC% Set the image saving %B%flag%B% (1=yes, 0=no) for BPM %B%unit%B%.
def xbpm_imgsave(unit, flag) '{
  if (flag)
    xbpm_IMG[unit]["save"] = 1
  else
    xbpm_IMG[unit]["save"] = 0
}'

######## Commands addressing the LIMA device end ########

######## Beam viewer ########

#%IU% (mne, type, unit, module, chan)
#%MDESC% Called after reading the config file. If return the string ".error.",
#spec will consider the channel unusable.
def xbpmbv_config(mne, type, unit, module, chan)'{

  TANGO_ERR = "-1"
  if (type=="ctrl") {
      unglobal xbpmbv_MNE[]
    tango_io(xbpmbv_ADDR, "State")
    if (TANGO_ERR){
      print_tango_err()
      return ".error."
    }
  }
  if (type == "cnt") {
      global xbpmbv_MNE[]
    counter_par(mne, "dev", xbpmbv_ADDR, "add")
    xbpmbv_MNE[cnt_mne(mne)] = xbpmbv_ADDR
    return
  }
  if (type == "mot") {
    return
  }
}'

#%IU% (mne, key, p1, p2, unit)
#%MDESC% Execute the command %B%key%B% for the counter %B%mne%B%, with
#parameters %B%p1%B% and %B%p2%B% if needed. The keys used are as follows:%BR%
#%B%"start_one"%B% and %B%"prestart_all"%B% - start the counting
#Parameters: p1 - counting time.%BR%
#Parameters: p2 - 2 (count to a time preset - tcount()).%BR%
#Parameters: unit - the unit number (if me is ..).%BR%
#%B%"counts"%B% - return the current counts.
#Parameters: unit - the unit number (if mne is ..).%BR%
#%B%"halt_all%B%" - read the diode only once.
#Parameters: p1 - controller unit number.%BR%
#Return the string ".error.", spec will consider the channel unusable.
def xbpmbv_cmd(mne,key,p1,p2,unit)'{
local out
global xbpmbv_CNT

  if (key == "halt_all") {
    TANGO_ERR = "-1"
    out = tango_get(xbpmbv_ADDR,"DiodeCurrent")
    if (TANGO_ERR){
      print_tango_err()
      return ".error."
    }
    xbpmbv_CNT[xbpmbv_ADDR] = out
  }

  if (key == "counts") {
    return xbpmbv_CNT[xbpmbv_ADDR]
  }
}'

#%UU% <bv1name> <range> [<bv2name> ...]
#%MDESC% Set the range [nA]
def bvrange '{
global xbpm_RANGE[]
local bvr lbvr mne idx aaa
local _bv_mne_list

  xbpm_RANGE[0] = "10nA"
  xbpm_RANGE[1] = "100nA"
  xbpm_RANGE[2] = "1uA"
  xbpm_RANGE[3] = "10uA"
  xbpm_RANGE[4] = "100uA"
  xbpm_RANGE[5] = "1mA"

  mne = "$1"
  if (!mne) {
    idx = 0
    for (i in xbpmbv_MNE) {
      _bv_mne_list[idx] = i
      idx++
    }
    if (idx >= 1) {
      mne =  getval_list_by_key(sprintf ("Which BPM do you want to use"), \
		_bv_mne_list)
    }
  }
  bvr = "$2"

  if (bvr == 0){
    printf("%s\n", _bvrange(mne))
    return(0)
  }

  if (is_number(bvr)) {
    idx = split(bvr,aaa,0) - 2
    bvr = xbpm_RANGE[idx]
  }
  lbvr = _bvrange(mne)
  if (bvr != lbvr)
    return(_bvrange(mne, bvr))
  else
    return(0)
}'

#%IU% (mne, range)
#%MDESC% Change the beam viewer counter %B%mne%B% range.
def _bvrange(mne, range) '{
local dev rr

  dev = counter_par(mne, "dev")
  if (!dev) {
    return "DISABLED"
#    printf ("\tHint: run \"bvstatus\" to see the available viewers.\n")
  } else {
    TANGO_ERR = "-1"
    if (!range)
      rr = tango_get(dev,"DiodeRange")
    else {
      rr = range
      tango_put(dev,"DiodeRange", range)
    }
    if (TANGO_ERR){
      print_tango_err()
      return (-1)
    }
  }
  return(rr)
}'

#%UU% <bv1name> [<bv2name> ...]
#%MDESC% Insert yag screen(s) in the beam.
def bvin  '{
local argv[] cntmne

  if (split("$*",argv)<=0) {
     print "USAGE: $0 <bv1> [<bv2> ...]"
     exit
  }

  for (mne in argv) {
    dev = counter_par(argv[mne], "dev")
    if (!dev) {
      printf ("ERROR: %s is unknown beam viewer.\n", argv[mne])
      printf ("\tHint: run \"bvstatus\" to see the available viewers.\n")
    } else {
      if (_bvcmd(dev, "In") == -1)
        eprintf ("ERROR: could not insert %s YAG screen\n", argv[mne])
    }
  }
}'

#%UU% <bv1name> [<bv2name> ...]
#%MDESC% Extract yag screen(s) from the beam.
def bvout  '{
local argv[] cntmne

  if (split("$*",argv)<=0) {
     print "USAGE: $0 <bv1> [<bv2> ...]"
     exit
  }
  
  for (mne in argv) {
    dev = counter_par(argv[mne], "dev")
    if (!dev) {
      printf ("ERROR: %s is unknown beam viewer.\n", argv[mne])
      printf ("\tHint: run \"bvstatus\" to see the available viewers.\n")
    } else {
      if (_bvcmd(dev, "Out") == -1)
        eprintf ("ERROR: could not extract %s YAG screen.\n", argv[mne])
    }
  }
}'

#%UU% <bv1name> [<bv2name> ...]
#%MDESC% Switch led(s) on.
def bvledon  '{
local argv[] devb

  if (split("$*",argv)<=0) {
     print "USAGE: $0 <bv1> [<bv2> ...]"
     exit
  }
  
  for (mne in argv) {
    dev = counter_par(argv[mne], "dev")
    if (!dev) {
      printf ("ERROR: %s is unknown beam viewer.\n", argv[mne])
      printf ("\tHint: run \"bvstatus\" to see the available viewers.\n")
    } else {
      if (_bvcmd(dev, "LedOn") == -1)
        eprintf ("ERROR: could not switch %s Led on\n", argv[mne])
    }
  }
}'

#%UU% <bv1name> [<bv2name> ...]
#%MDESC% Switch led(s) off.
def bvledoff  '{
local argv[] cntmne

  if (split("$*",argv)<=0) {
     print "USAGE: $0 <bv1> [<bv2> ...]"
     exit
  }
  
  for (mne in argv) {
    dev = counter_par(argv[mne], "dev")
    if (!dev) {
      printf ("ERROR: %s is unknown beam viewer.\n", argv[mne])
      printf ("\tHint: run \"bvstatus\" to see the available viewers.\n")
    } else {
      if (_bvcmd(dev, "LedOff") == -1)
        eprintf ("ERROR: could not switch %s LED off.\n", argv[mne])
    }
  }
}'

def bcin  '{
  bvfoilin $*
}'

#%UU% <bv1name> [<bv2name> ...]
#%MDESC% Insert foil(s) in the beam.
def bvfoilin  '{
local argv[] cntmne

  if (split("$*",argv)<=0) {
     print "USAGE: $0 <bv1> [<bv2> ...]"
     exit
  }
  
  for (mne in argv) {
    dev = counter_par(argv[mne], "dev")
    if (!dev) {
      printf ("ERROR: %s is unknown beam viewer.\n", argv[mne])
      printf ("\tHint: run \"bvstatus\" to see the available viewers.\n")
    } else {
      if (_bvcmd(dev, "FoilIn") == -1)
        eprintf ("ERROR: could not insert %s foil.\n", argv[mne])
    }
  }
}'

def bcout  '{
  bvfoilout $*
}'

#%UU% <bv1name> [<bv2name> ...]
#%MDESC% Extract the foil(s) from the beam.
def bvfoilout  '{
local argv[] cntmne

  if (split("$*",argv)<=0) {
     print "USAGE: $0 <bv1> [<bv2> ...]"
     exit
  }
  
  for (mne in argv) {
    dev = counter_par(argv[mne], "dev")
    if (!dev) {
      printf ("ERROR: %s is unknown beam viewer.\n", argv[mne])
      printf ("\tHint: run \"bvstatus\" to see the available viewers.\n")
    } else {
      if (_bvcmd(dev, "FoilOut") == -1)
        eprintf ("ERROR: could not extract %s foil.\n", argv[mne])
    }
  }
}'

#%IU% (dev, val)
#%MDESC% Execute a command on %B%dev%B% beam viewer. Accepted values are:
#"In"/"Out" for the yag screen, "LedOn"/"LedOff" for the led,
#"FoilIn"/ "FoilOut" for the foil. Return 0 if OK, -1 if error.
def _bvcmd(dev, val) '{

  TANGO_ERR = "-1"
  tango_io(dev, val)
  if (TANGO_ERR) {
    print_tango_err()
    return(-1)
  }
  return(0)
}'

#%UU% [bvmne]
#%MDESC% Print the status of %B%bvmne%B% viewer. With no argument will print
#the status of all the configured in the session beam viewers.
def bvstatus '{
local mne mystr stat

  mne = "$1"
  if (mne) {
    mystr = sprintf ("  Yag: %s", _yagstatus(xbpmbv_MNE[mne]))
    mystr = sprintf ("%s\t Illuminator: %s", mystr, _ledstatus(xbpmbv_MNE[mne]))
    mystr = sprintf ("%s\t Foil: %s\n", mystr, _foilstatus(xbpmbv_MNE[mne]))
    printf ("\n%s", mystr)
  } else {
    for (mne in xbpmbv_MNE) {
      printf ("\n-------- ")
      tty_cntl("mr"); printf (" %s ", mne); tty_cntl("me")
      printf (" --------\n")
      mystr = sprintf ("  Yag: %s", _yagstatus(xbpmbv_MNE[mne]))
      mystr = sprintf ("%s\t Illuminator: %s", mystr, _ledstatus(xbpmbv_MNE[mne]))
      if ((stat = _foilstatus(xbpmbv_MNE[mne])))
        mystr = sprintf ("%s\t Foil: %s", mystr, stat)
      mystr = sprintf ("%s\t Diode Range: %s", mystr, _bvrange(mne))
      printf ("%s\n", mystr)
    }
  }
}'

#%IU% (dev)
#%MDESC% Return the status of the yag screen for %B%dev%B%.
def _yagstatus (dev) '{
local ret

  TANGO_ERR = "-1"
  ret = tango_get(dev, "YagStatus")
  if (TANGO_ERR) {
    print_tango_err()
    return ("unknown")
  }
  return(ret)
}'

#%IU% (dev)
#%MDESC% Return the status of the scattering foil for %B%dev%B%.
def _foilstatus (dev) '{
local ret

  TANGO_ERR = "-1"
  ret = tango_get(dev, "FoilStatus")
  if (TANGO_ERR) {
    # print_tango_err()  # Do not print error : it just means BV has no foil...
    return ("unknown")
  }
  return(ret)
}'

#%IU% (dev)
#%MDESC% Return the status of the illuminator for %B%dev%B%.
def _ledstatus(dev) '{

  TANGO_ERR = "-1"
  ret = tango_get(dev, "LedStatus")
  if (TANGO_ERR) {
    print_tango_err()
    return ("unknown")
  }
  return((ret == 1) ? "on" : "off")
}'

######## Beam viewer end ########

######## Generic commands ########

#%IU% (unit)
#%MDESC% Disable the controller %B%unit%B% if Tango RuntimeError.
def _geterr(unit) '{
local myerr[]

  split(TANGO_ERR_STACK["0"]["desc"], myerr, ":")
  if (myerr[0] == "RuntimeError")
    xbpm_STATE[unit] = 1
  else
    xbpm_STATE[unit] = 0
}'
######## Generic commands end ########

#%MACROS%
#%IMACROS%
#%LOG%
#$Revision: 4.3 $
#$Log: xbpm.mac,v $
#Revision 4.3  2018/04/10 14:50:27  guilloud
#no foil error no more printed to make status readable.
#
#Revision 4.2  2016/12/20 15:44:59  lagier
#    bug fixes
#	init xbpm_CNTNB array (xbpm_config)
#	init xbpm_MNE array (bvrange macro)
#	bvrange
#    xbpmon/off upon controller name as input rather than unit number
#		    controller name is last / field from device server name
#		    new function _xbpm_dev2unit()
#    xbpm new macros that lists configured controllers with their status
#
#Revision 3.2  2013/10/08 13:58:55  beteva
#changed bvrange print and some error messages.
#
#Revision 3.1  2013/10/04 09:08:54  beteva
#Added missing bracket. bvrange takes string or number. Some messages changed.
#
#Revision 3.0  2013/10/02 14:45:56  beteva
#added image autosaving handling macros.
#added beam viewer wago part (xbpmds) macros.
#
#Revision 2.9  2013/09/06 15:10:52  beteva
#Corrected unit number in halt_all.
#Added xbpm_imgsave (set the saving flag to yes/no) and xbpmimgparsget.
#Do not print tango errors, if not asked.
#
#Revision 2.8  2013/07/31 13:05:33  beteva
#return the counting values in xbpm_takebg()
#
#Revision 2.7  2013/05/23 13:38:44  beteva
#added save image functions
#
#Revision 2.6  2013/04/24 13:21:56  beteva
#added xbpm_takebg fuctionalities
#
#Revision 2.5  2013/03/28 14:03:40  domingue
#improve the doc
#
#Revision 2.4  2012/11/28 13:39:48  beteva
#do not enable/disable counter in the middle of the scan - set only the
#simulation flag. Bug fixed in xbpmroi.
#
#Revision 2.3  2012/11/14 10:22:24  beteva
#changed ROIDEV to LIMADEV to be consistent with the device server
#swaped xbpmon/xbpmoff
#added check if the counter is disabled in the prestart_all
#added hook for local actions xbpm_local_cmd
#
#Revision 2.2  2012/11/05 13:55:29  beteva
#Add alias for the ROI.
#Change the count time if need to differ from the ct one.
#
#Revision 2.1  2012/10/15 11:09:57  beteva
#correct xbpmroi to handle unit numbers > number of configured BPMs.
#
#Revision 2.0  2012/10/09 16:08:29  beteva
#changed the macro to handle more than one BPM/spec version
#enable/disable counters if the server is not running any more
#enable/disable counters if the GUI is acquiring
#added exposure time set, ROI set
#
#Revision 1.4  2012/05/22 14:50:16  lagier
#added xbpmon and xbpmoff macros.
#
#Revision 1.3  2011/09/28 13:08:29  guijarro
#fixed bug with intensity(need updated server);
#
#Revision 1.2  2011/09/19 07:36:50  domingue
#handle unknown dimension of output array of GetPosition
#
#Revision 1.1  2011/09/16 13:56:21  domingue
#Initial revision
#
#%AUTHOR% mcd/ab BLISS
#%TOC%