esrf

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

#%TITLE% TRANSFOCATOR.MAC
#%NAME%
# transfocator.mac - transfocator control
#%DESCRIPTION%
#A set of macros to control transfocators. The macros control one
#transfocator at a time, but allow to show the status of all the
#configured in the same session vessels.
#%SETUP%
#The lenses are controlled by WAGO output/input modules, via TANGO device
#server.
#%END%

#%UU%<name device_name>
#%MDESC% Configure the transfocator. The %B%name%B% is a free string to be
#used to identify the tranfocator, controlled by %B%device_name%B% server.
#If needed, a local setup can be added.
def tfsetup '{
global TF_PARS[] _TFNAME
local i nn

  if ($# == 0) {
    tty_cntl("md")
    _TFNAME = getval("Transfocator name: ", _TFNAME)
    TF_PARS[_TFNAME]["device"] = getval("Device name (e.g.id30/tf/1):", \
    			TF_PARS[_TFNAME]["device"])
    tty_cntl("me")      
  } else {
    _TFNAME = "$1"
    TF_PARS[_TFNAME]["device"] = "$2"
  }

  TF_PARS[_TFNAME]["use"] = 0
  TANGO_ERR = "-1"
  tango_io(TF_PARS[_TFNAME]["device"],"State")
  if (TANGO_ERR) {
    print_tango_err()
    TF_PARS[_TFNAME]["use"] = -1
  } else {
    tango_io(TF_PARS[_TFNAME]["device"],"timeout",5)
  }

  tf_local_setup()
}'

#%UU% [tfname]
#%MDESC% Delete the %B%tfname%B% from the list of the setup transfocators.
def tfdelete '{
local tfname nn str

  if ($# == 0) {
    str = sprintf ("Which transfocator do you want to remove:")
    for (nn in TF_PARS[]["use"])
      str = sprintf ("%s %s", str, nn)
    str = sprintf ("%s?\n",str)
    tfname = input(str)
  } else
    tfname = "$1"

  for (nn in TF_PARS[tfname]) {
    delete TF_PARS[tfname][nn]
  }
}'


#%UU% [name filename root label position]
#%MDESC% Set the transfocator %B%name%B% hardware object parameteres:
#the xml %B%filename%B%; the %B%root%B% path for each lense; the %B%label%B%
#keyword; the %B%position%B%keyword.
#first control (output) channel.
def tfhosetup '{
global TF_HO
local name

  if ($# == 0)
    name = input("Transfocator name:")
  else
    name  = "$1"

  if ($# < 2) {
    TF_HO[name]["filename"] = \
	getval("Transfocator hardware object name", TF_HO[name]["filename"])
    TF_HO[name]["root"] = \
	getval("Transfocator hardware object root", TF_HO[name]["root"])
    TF_HO[name]["label"] = \
	getval("Transfocator hardware object label keyword", \
		TF_HO[name]["label"])
    TF_HO[name]["position"] = \
	getval("Transfocator hardware object position keyword", \
		TF_HO[name]["position"])
	
  } else {
    TF_HO[name]["filename"] = "$2"
    TF_HO[name]["root"] = "$3"
    TF_HO[name]["label"] = "$4"
    TF_HO[name]["position"] = "$5"
  }
  tf_getxml
}'

#%UU% [name]
#%MDESC% Read transfocator and display all the lenses positions if %B%name%B%,
#all the configured transfocators otherwise.
def tfshow  '{
local nn val[] value name

  if ($# == 0) {
    for (nn in TF_PARS[]["use"]) {
      if (TF_PARS[nn]["use"] == -1) {
        continue
      }
      TANGO_ERR = "-1"
      value = tango_get(TF_PARS[nn]["device"],"TfStatus")
      if (TANGO_ERR) {
        print_tango_err()
        TF_PARS[nn]["use"] = -1
        continue
      }
      printf ("Transfocator %s (status 0x%x)\n", nn, value)
      TANGO_ERR = "-1"
      tango_get(TF_PARS[nn]["device"], "ShowLenses", val)
      if (TANGO_ERR) {
        print_tango_err()
        TF_PARS[nn]["use"] = -1
        continue
      }
      printf ("%s\n%s\n", val[0], val[1])
    }
  } else {
    name = "$1"
    if (TF_PARS[name]["use"] == -1) {
      eprintf ("Transfocator %s is unusable, exiting...\n", name)
      exit
    }
    _TFNAME = name
    TANGO_ERR = "-1"
    value = tango_get(TF_PARS[_TFNAME]["device"],"TfStatus")
    if (TANGO_ERR) {
      print_tango_err()
      TF_PARS[_TFNAME]["use"] = -1
    } else {
      printf ("Transfocator %s  (status 0x%x)\n", _TFNAME, value)
      TANGO_ERR = "-1"
      tango_get(TF_PARS[_TFNAME]["device"], "ShowLenses", val)
      if (TANGO_ERR) {
        print_tango_err()
        TF_PARS[_TFNAME]["use"] = -1
      } else {
        printf ("%s\n%s\n", val[0], val[1])
      }
    }
  }
}'

#%UU% [name]
#%MDESC% With no argument displays the available transfocator and shows which
#is currently selected. Otherwise set the %B%name%B% transfocator as the
#current one.
def tfselect '{
local nn _tf _found

  if ($#) {
    _tf = "$1"; _found=0
    for (nn in TF_PARS[]["use"]) {
      if (_tf == nn) {_TFNAME=_tf; _found = 1}
    } 
    if (!_found) printf ("Invalid transfocator name: %s\n", _tf)
  }

  printf ("Available transfocator:\n")
  for (nn in TF_PARS[]["use"]) {
    printf("\t - %s", nn)
    if (nn == _TFNAME) {
      printf(" (")
      tty_cntl("md"); printf("active"); tty_cntl("me")
      printf(")")
    }
    printf("\n")
  } 
}'

#%UU%
#%MDESC% Read transfocator %B%name%B% status, display it and show all the
#lenses positions.
def tfstatus '{
local value name lbl

  name = "$1"

  if (!name)
    name = _TFNAME

  value = _tf_get(name)
  if (value == -1) {
    eprintf ("Cannot read the transfocator hardware, exiting...\n")
    exit
  }

  TANGO_ERR = "-1"
  tango_get(TF_PARS[name]["device"], "ShowLenses",lbl)
  if (TANGO_ERR) {
    print_tango_err()
    TF_PARS[name]["use"] = -1
    exit
  }
  printf ("Transfocator %s (status 0x%x)\n", name, value)
  printf ("%s\n", lbl[0])
  printf("%s\n", lbl[1]);
}'

#%UU% number
#%MDESC% Put the lense %B%number%B% in the beam. If %B%number%B%=99, put
#only the pinhole(s) in, all other lenses out.
def tfin '{
local n

  if (_tf_lock(_TFNAME)) {
    printf("%s\n", TF_PARS[_TFNAME]["lock_msg"])
    exit
  }

  n = $1
  if (n == 0)
    n = getval("Please specify lense number (starting from 1)",1)

  if (n != 99) {
    #in the device server the numbering starts from 0, subtract 1
    n -= 1
  }

  TANGO_ERR = "-1"
  tango_io(TF_PARS[_TFNAME]["device"], "LenseIn", n)
  if (TANGO_ERR) {
    print_tango_err()
    printf("It appears the lense could not be inserted.\n")
  } else
    printf ("Done.\n")
}'

#%UU% number
#%MDESC% Put the lense %B%number%B% out of the beam. If %B%number%B%=99, take
#the pinhole(s) out.
def tfout '{
local n tt
local value getvalue notset filt
  n = $1
  if (n == 0)
    n = getval("Please specify lense number (starting from 1)",1)

  if (n != 99) {
    #in the device server the numbering starts from 0, subtract 1
    n -= 1
  }

  TANGO_ERR = "-1"
  tango_io(TF_PARS[_TFNAME]["device"], "LenseOut", n)
  if (TANGO_ERR) {
    print_tango_err()
    printf("It appears the lense could not be extracted.\n")
  } else
    printf ("Done.\n")
}'

#%UU%
#%MDESC%  Print out status of current transfocator
def tfget '{
  local value
  value = _tf_get(_TFNAME)
  if (value != -1)
    printf("%s status: 0x%x\n\n", _TFNAME, value)
}'

#%IU% ()
#%MDESC% Get the current tranfocator state.
def _tf_get(name) '{
local value

  if (!name)
    name = _TFNAME

  TANGO_ERR = "-1"
  value = tango_get(TF_PARS[name]["device"],"TfStatus")
  if (TANGO_ERR) {
    print_tango_err()
    TF_PARS[name]["use"] = -1
    return(-1)
  }
  return(value)
}'

#%UU% <status>
#%MDESC% Set current transfocator to desired status.
def tfset '{
local value
  if ($# != 1) {
    eprint "Usage: $0 <status>"
    exit
  }
  value= $1
  printf("Setting %s to 0x%x\n", _TFNAME, value)
  if (_tf_set(value, _TFNAME) == -1)
    printf("It appears that the lenses could not be set.\n")
  else
    printf ("Done.\n")
}'

#%IU% (st, name) 
#%MDESC% Set the tranfocator %B%name%B% to a status %B%st%B%. If name not
#specified, the current transfocator is set.
def _tf_set(st, name) '{
local filt stat tt notset

  if (!name)
    name = _TFNAME

  if (_tf_lock(name)) {
    printf("%s\n", TF_PARS[name]["lock_msg"])
    exit
  }
  TANGO_ERR = "-1"
  tango_put(TF_PARS[name]["device"], "TfStatus", st)
  if (TANGO_ERR) {
    print_tango_err()
    return(-1)
  }
  return(0)
}'


#%UU% 
#%MDESC% Put all the lenses in the beam. Do not touch the pinhole, if any.
def tfinall '{

  if (_tf_lock(_TFNAME)) {
    printf("%s\n", TF_PARS[_TFNAME]["lock_msg"])
    exit
  }
  TANGO_ERR = "-1"
  tango_io(TF_PARS[_TFNAME]["device"], "AllIn")
  if (TANGO_ERR) {
    print_tango_err()
    printf("It appears the lenses could not be inserted.\n")
  } else
    printf ("Done.\n")
}'

#%UU% 
#%MDESC% Take all the lenses out of the beam. Do not touch the pinhole, if any.
def tfoutall '{

  if (_tf_lock(_TFNAME)) {
    printf("%s\n", TF_PARS[_TFNAME]["lock_msg"])
    exit
  }
  TANGO_ERR = "-1"
  tango_io(TF_PARS[_TFNAME]["device"], "AllOut")
  if (TANGO_ERR) {
    print_tango_err()
    printf("It appears the lenses could not be extracted.\n")
  } else
    printf ("Done.\n")
}'

#%UU% number
#%MDESC% Toggle the position in the beam of lense %B%number%B%.
def tftoggle '{
local value filt

  value = _tf_get()
  filt =  1<<($1 -1)

  if ((value & filt) == 0)
    value += filt
  else
    value &= ~filt

  _tf_set(value)

}'


#%UU%
#%MDESC% Get the lenses name and ordinal positions (starting from 1) for the
#current transfocator from the default hardware object - xml file.
def tf_getxml '{
local keys

  if (!TF_HO[_TFNAME]["filename"])
    TF_HO[_TFNAME]["filename"] = \
	getval("Transfocator hardware object", TF_HO[_TFNAME]["filename"])
  if (!TF_HO[_TFNAME]["root"])
    TF_HO[_TFNAME]["root"] = \
	getval("Transfocator hardware object root", TF_HO[_TFNAME]["root"])
  if (!TF_HO[_TFNAME]["label"])
    TF_HO[_TFNAME]["label"] = \
	getval("Transfocator hardware object label keyword", \
		TF_HO[_TFNAME]["label"])
  if (!TF_HO[_TFNAME]["position"])
    TF_HO[_TFNAME]["position"] = \
	getval("Transfocator hardware object position keyword", \
		TF_HO[_TFNAME]["position"])

  keys["label"] = TF_HO[_TFNAME]["label"]
  keys["position"] = TF_HO[_TFNAME]["position"]
  _tf_getxml(TF_HO[_TFNAME]["filename"], _TFNAME, \
	TF_HO[_TFNAME]["root"], keys)
}'

#%IU% (ho, tfname, keys_root, keys)
#%MDESC% Get the lense names and corresponding ordinal positions (starting from
#1) for the %B%tfname%B% transfocator from the %B%ho%B% hardware object - xml
#file.
def _tf_getxml(ho, tfname, keys_root, keys) '{
local key name
global TF_LENSE[]

  key = sprintf ("%s/%s", keys_root, keys["label"])
  if (xml_read(ho,key) == -1) {
    eprintf ("Cannot read the axis XML file, names not set\n")
    return(-1)
  }
  for (name in XML_tmp[]["__value__"]) {
    TF_LENSE[tfname][sprintf ("label%d", name+1)] = XML_tmp[name]["__value__"]
  }

  key = sprintf ("%s/%s", keys_root, keys["position"])
  if (xml_read(ho, key) == -1) {
    eprintf ("Cannot read the axis XML file, names not set\n")
    return(-1)
  }
  for (name in XML_tmp[]["__value__"]) {
    TF_LENSE[tfname][sprintf ("pos%d", name+1)] = XML_tmp[name]["__value__"]
  }
  return(0)

}'

#%UU%
#%MDESC% Write the lense names and corresponding ordinal positions (starting
#from 1) for the current transfocator from the default hardware object - xml
#file. The information to write is taken from the TF_LENSE arary.
def tf_writexml '{
local keys

  if (!TF_HO[_TFNAME]["filename"])
    TF_HO[_TFNAME]["filename"] = \
	getval("Transfocator hardware object", TF_HO[_TFNAME]["filename"])
  if (!TF_HO[_TFNAME]["root"])
    TF_HO[_TFNAME]["root"] = \
	getval("Transfocator hardware object root", TF_HO[_TFNAME]["root"])
  if (!TF_HO[_TFNAME]["label"])
    TF_HO[_TFNAME]["label"] = \
	getval("Transfocator hardware object label keyword", \
		TF_HO[_TFNAME]["label"])
  if (!TF_HO[_TFNAME]["position"])
    TF_HO[_TFNAME]["position"] = \
	getval("Transfocator hardware object position keyword", \
		TF_HO[_TFNAME]["position"])

  keys["label"] = TF_HO[_TFNAME]["label"]
  keys["position"] = TF_HO[_TFNAME]["position"]
  _tf_writexml(TF_HO[_TFNAME]["filename"], _TFNAME, \
	TF_HO[_TFNAME]["root"], keys)
}'

#%IU% (ho, tfname, keys_root, keys)
#%MDESC% Write the lense names and corresponding ordinal positions (starting
#from 1) for the %B%tfname%B% transfocator in the %B%ho%B% hardware object -
#xml file. The information to write is taken from the TF_LENSE arary.
def _tf_writexml(ho, tfname, keys_root, keys) '{
local i newname newpos
local key

  for (i=1; i <= TF_PARS[tfname]["nb_lens"]; i++) {
    key = sprintf("%s[%d]/%s",keys_root,i, keys["label"])
    newname = sprintf("%s", TF_LENSE[tfname][sprintf("label%d", i)])
    xml_cache_write(ho, key, newname)
    key = sprintf("%s[%d]/%s",keys_root,i, keys["position"])
    newpos = sprintf("%g", TF_LENSE[tfname][sprintf("pos%d", i)])
    xml_cache_write(ho, key, newpos)
  }  
  xml_do_write()
}'

#%IU% (name)
#%MDESC% Define a local beamline  macro to lock the %B%name%B% transfocators.
#If name not specified, the current transfocator is checked.
def _tf_lock(name) '{

  if (!name)
    name = _TFNAME
  TF_PARS[name]["lock"] = 0

  TF_PARS[name]["lock_msg"] = \
	"Command ignored due to local beamline interdiction"
  
  tf_local_lock(name)

  return(TF_PARS[name]["lock"])
}'

#%IU% (from, name)
#%MDESC% Calculate the lense status from the %B%from%B% parameter, that is:%BR%
#from[0]=1 - energy; from[0]=2 - distance; from[0]=3 - beamsize%BR%
#from[1] - energy [keV]/distance [m]/vertical beam size [mm]%BR%
#from[2] - horizontal beam size. If %B%name%B% not specified, the current
#transfocator is used. Return the lense status to be set if OK, -1 if error.
def tf_calc_lense(from, name) '{
local ret

  if (!name)
    name = _TFNAME

  ret = -1

  ret = tf_local_calc_lense(from, name)
  return(ret)
}'

#%IU% (status, name)
#%MDESC% Calculate the energy from the lense status. If %B%name%B% not
#specified, the current transfocator is used. Return the energy [keV] if OK,
#-1 in case of error.
def tf_calc_energy(status, name) '{
local ret

  if (!name)
    name = _TFNAME

  ret = -1

  ret = tf_local_calc_energy(status, name)
  return(ret)
}'

#%IU% (status, name)
#%MDESC% Calculate the beam size from the lense %B%status%B%. If %B%name%B% not
#specified, the current transfocator is used. Return the beam size [mm] -
#vertical, horizontal if OK, -1 in case of error.
def tf_calc_beamsize(status, name) '{
local ret

  if (!name)
    name = _TFNAME

  ret = -1

  ret = tf_local_calc_beamsize(status, name)
  return(ret)
}'

#%IU% (status, name)
#%MDESC% Calculate the distance  from the lense %B%status%B%. If %B%name%B% not
#specified, the current transfocator is used. Return the distance [m] if OK,
#-1 in case of error.
def tf_calc_distance(status, name) '{
local ret

  if (!name)
    name = _TFNAME

  ret = -1

  ret = tf_local_calc_distance(status, name)
  return(ret)
}'

#%IU% ()
#%MDESC% Define, if not already the case, the local macros, used as hooks.
def tf_local_macrodefs() '{

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

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

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

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

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

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

}'

tf_local_macrodefs()

need XML_utils.mac

#%MACROS%
#%IMACROS%
#%TOC%
#%DEPENDENCIES% XML_utils.mac%BR%
#%AUTHOR% A.Beteva, BLISS%BR%