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 different type of 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 pneumatically via WAGO output modules. The position
#is red from WAGO modules, in a different way, depending on the mechanics.
#The different types are configured as follows:%BR% %BR%
#%B%Type%B%%B%1:%B% This is the standard ESRF configuration - one control bit
#to move a lense, two limit switch bits to read the position. We use WAGO
#output module to insert/extract and WAGO inpit module to read the position. To
#insert the lense in the beam, the control bit is set to 1, to extracrt it - to
#0. The %B%in%B% limit switch bit is %B%1%B% and the %B%out%B% limit switch
#bit is %B%0%B% when in or inverse when the lense is out of the beam. The even
#numbers are the in and the odd numbers are the out bits. One of the lenses is
#actually a pinhole, which can be inserted/extracted. It is shown when reading
#the position, but not changed when controlling all the lenses together.%BR%
#%B%Type%B%%B%2:%B% The same as type one, only there is no pinhole.%BR%
#%B%Type%B%%B%3:%B% Only one WAGO output module with one control/limit switch
#bit to run the transfocator. The bit is set to 1 to insert and to 0 to extract
#a lense. The position of the lense is given from the same bit.%BR%
#%B%Type%B%%B%4:%B% Two limit switch and two control bits, pinhole. To insert
#the lense in the beam, the %B%in%B% bit is set to %B%1%B% and the %B%out%B%
#bit it is set to %B%0%B% or inverse to extract the lense. The even numbers
#are the in and the odd numbers are the out bits. The position is given by a
#WAGO input module. The lense is reported as in the beam when the %B%in%B%
#limit switch bit is %B%1%B% and the %B%out%B% bit is %B%0%B%, out of the beam
#in the opposite configuration. An error is reported if both in and out bits
#have the same value. The even numbers are the in and the odd numbers are the
#out bits.
#%B%Type%B%%B%5:%B% The same as type one, only there are two pinholes. Their
#position has to be specified. When the lenses are in, the two pinholes are
#taken out. When any or both pinholes are in, all the other lenses are taken
#out. When all is out, the two pinholes are out as well.%BR%
#%END%

#%IU% ()
#%MDESC% Initialise the different control types.
def _tfinit() '{
global TFOC_LIST

  TFOC_LIST[1]["name"] = "2 limit switch bits, 1 ctrl bit, 1 pinhole"
  TFOC_LIST[1]["suffix"] = "pos"
  TFOC_LIST[2]["name"] = "2 limit switch bits, 1 ctrl bit"
  TFOC_LIST[2]["suffix"] = "pos"
  TFOC_LIST[3]["name"] = "1 control/limit switch bit"
  TFOC_LIST[3]["suffix"] = "ctrl"
  TFOC_LIST[4]["name"] = "2 limit switch bits, 2 ctrl bits, 1 pinhole"
  TFOC_LIST[4]["suffix"] = "pos"
  TFOC_LIST[5]["name"] = "2 limit switch bits, 1 ctrl bit, 2 pinholes"
  TFOC_LIST[5]["suffix"] = "pos"

  tf_local_macrodefs()

}'

#%UU% <type> <other_parametres>
#%MDESC% Configure the transfocator. The %B%other_parameters%B% depend on the
#control unit %B%type%B%.
def tfsetup '{
global TF_PARS[] _TFNAME
local i nn

  _tfinit()

  if ($# == 0) {
    tty_cntl("md")
    _TFNAME = getval("Transfocator name: ", _TFNAME)
    printf ("Choose the transfocator control type:\n")
    for (i=1; i<= asso_len(TFOC_LIST); i++)
      printf (" %d [%s]\n", i, TFOC_LIST[i]["name"])
    TF_PARS[_TFNAME]["type"] = getval("",TF_PARS[_TFNAME]["type"])
    TF_PARS[_TFNAME]["timeout"] = \
	getval ("Timeout after which we assume moving lenses problem [s]", \
	TF_PARS[_TFNAME]["timeout"])
    tty_cntl("me")
  } else {
    _TFNAME = "$1"
    TF_PARS[_TFNAME]["type"] = $2
    TF_PARS[_TFNAME]["timeout"] = $3
  }

  tf_wago_setup $*

  tf_local_setup()

  if (TF_PARS[_TFNAME]["timeout"] == 0)
    TF_PARS[_TFNAME]["timeout"] = 0.5

  #get the initial state
  _tf_get()

}'

#%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[]["type"])
      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]
  }

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

#%UU% <nb> <root>
#%MDESC% set up transfocator box for %B%nb%B% lenses, controlled by
#wago devices with root name %B%root%B%.
def tf_wago_setup '{
global TF_PARS[]
global TFOC_STATE[]
global TFOC_SAVSTATE[]

  if ($# < 3) {
    tty_cntl("md")
    TF_PARS[_TFNAME]["nb_lens"] = \
    	getval("Total number of lenses (including pinholes):", \
	TF_PARS[_TFNAME]["nb_lens"])
    TF_PARS[_TFNAME]["root"] = \
    	getval("Root name (e.g. tfoc)                      :", \
	TF_PARS[_TFNAME]["root"])
    if ((TF_PARS[_TFNAME]["type"] == 1) || (TF_PARS[_TFNAME]["type"] == 4)) {
      TF_PARS[_TFNAME]["pinhole"] = \
      	getval("Pinhole position                           :", \
	TF_PARS[_TFNAME]["pinhole"])
      TF_PARS[_TFNAME]["pinhole_in"] = \
        yesno("Pinhole in when lense(s) in:",1)
    } else if (TF_PARS[_TFNAME]["type"] == 5) {
      TF_PARS[_TFNAME]["pinhole1"] = \
        getval("First pinhole position (start from 1)      :", \
	TF_PARS[_TFNAME]["pinhole1"])
      TF_PARS[_TFNAME]["pinhole2"] = \
        getval("Second pinhole position (start from 1)     :", \
	TF_PARS[_TFNAME]["pinhole2"])
    } else {
      delete TF_PARS[_TFNAME]["pinhole"]
      delete TF_PARS[_TFNAME]["pinhole1"]
      delete TF_PARS[_TFNAME]["pinhole2"]
      delete TF_PARS[_TFNAME]["pinhole_in"]
    }
  } else {
    TF_PARS[_TFNAME]["nb_lens"]   = int($4)
    TF_PARS[_TFNAME]["root"]     = "$5"
    if ((TF_PARS[_TFNAME]["type"] == 1) || (TF_PARS[_TFNAME]["type"] == 4)) {
      TF_PARS[_TFNAME]["pinhole"] = $6
      TF_PARS[_TFNAME]["pinhole_in"] = $7
    } else if (TF_PARS[_TFNAME]["type"] == 5) {
      TF_PARS[_TFNAME]["pinhole1"] = $6
      TF_PARS[_TFNAME]["pinhole2"] = $7
    } else {
      delete TF_PARS[_TFNAME]["pinhole"]
      delete TF_PARS[_TFNAME]["pinhole1"]
      delete TF_PARS[_TFNAME]["pinhole2"]
      delete TF_PARS[_TFNAME]["pinhole_in"]
    }
  }
  tty_cntl("me")
}'

#%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%
#%MDESC% Read transfocator and display all the lenses positions.
def tfshow  '{
local i nn value name str

  str = ""
  if ($# == 0) {
    for (nn in TF_PARS[]["type"]) {
      value = _tf_get(nn)
      printf ("Transfocator %s (status 0x%x)\n", nn, value)
      if (TF_LENSE[nn]["label1"]) {
        for (i=1;i<=TF_PARS[nn]["nb_lens"]; i++) {
          (value&(1<<(i-1))) ? (str="IN ") : (str="OUT")
          if (value > 1<<TF_PARS[nn]["nb_lens"]) {
            if (value&(1<<i+TF_PARS[nn]["nb_lens"]))
              str = "***"
          }
          printf (" \"%s\"\t- %s\n", TF_LENSE[nn][sprintf ("label%d",i)], str)
        }
      } else {
        for (i=1; i<=TF_PARS[nn]["nb_lens"]; i++) {
          if ((TF_PARS[_TFNAME]["pinhole"] == i) || \
              (TF_PARS[_TFNAME]["pinhole1"] == i) || \
              (TF_PARS[_TFNAME]["pinhole2"] == i))
            lbl = "P"
          else
            lbl = "L"
          if (i<10)
            printf("%s%d  ",lbl, i)
          else
            printf("%sL%d ", lbl, i)
        }
        printf("\n")
        for (i=0; i<TF_PARS[nn]["nb_lens"]; i++) {
          (value&(1<<i)) ? (str="IN ") : (str="OUT")
          if (value > 1<<TF_PARS[nn]["nb_lens"]) {
            if (value&(1<<i+TF_PARS[nn]["nb_lens"]))
              str = "***"
          }
          printf ("%s ", str)      
        }
        printf("\n\n")
      }
    }
  } else {
    _TFNAME = "$1"
    value = _tf_get()
    printf ("Transfocator %s  (status 0x%x)\n", _TFNAME, value)
    for (i=1;i<=TF_PARS[_TFNAME]["nb_lens"]; i++) {
      if (TF_LENSE[_TFNAME][sprintf ("label%d",i)]) {
        printf (" \"%s\"\t- ", TF_LENSE[_TFNAME][sprintf ("label%d",i)])
      } else {
        if (i<10)
          printf("\tL%d  ",i)
        else
          printf("\tL%d ",i)
      }
      (value&(1<<(i-1))) ? (str="IN ") : (str="OUT")
      if (value > 1<<TF_PARS[_TFNAME]["nb_lens"]) {
        if (value&(1<<i+TF_PARS[_TFNAME]["nb_lens"]-1))
          str = "***"
      }
      printf ("%s\n", str)
    }
  }
}'

#%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[]["type"]) {
            if (_tf == nn) {_TFNAME=_tf; _found = 1}
        } 
        if (!_found) print "Invalid transfocator name : "_tf
    }
    printf ("Available transfocator:\n")
    for (nn in TF_PARS[]["type"]) {
        printf("\t - %s", nn)
        if (nn == _TFNAME) {
            printf(" (")
	    tty_cntl("md"); printf("active"); tty_cntl("me")
	    printf(")")
        }
        printf("\n")
     } 
}'

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

  value = _tf_get()
  printf ("Transfocator %s (status 0x%x)\n", _TFNAME, value)
  for (i=1;i<=TF_PARS[_TFNAME]["nb_lens"]; i++) {
    if ((TF_PARS[_TFNAME]["pinhole"] == i) || \
       (TF_PARS[_TFNAME]["pinhole1"] == i) || \
       (TF_PARS[_TFNAME]["pinhole2"] == i))
      lbl = "P"
    else
      lbl = "L"
    if (i<10)
      printf("%s%d  ",lbl, i)
    else
      printf("%sL%d ", lbl, i)
  }
  printf("\n")

  for (i=0;i<TF_PARS[_TFNAME]["nb_lens"];i++) {
    (value&(1<<i)) ? (str="IN ") : (str="OUT")

    if (value >= 1<<TF_PARS[_TFNAME]["nb_lens"]) {
      if (value&(1<<i+TF_PARS[_TFNAME]["nb_lens"]))
        str = "***"
    }
    printf ("%s ", str)
  }
  printf("\n");
}'

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

  if (!name)
    name = _TFNAME
  ret = _tf_read(name)

  if (ret == -1) {
    eprintf ("Cannot read the transfocator hardware, exiting...\n")
    exit
  } else {
    if (TF_PARS[name]["type"] == 1)
      TFOC_STATE[name] = _tf_wagoget_2posbit(name)
    if (TF_PARS[name]["type"] == 2)
      TFOC_STATE[name] = _tf_wagoget_2posbit(name)
    if (TF_PARS[name]["type"] == 3)
      TFOC_STATE[name] = _tf_wagoget_1posbit(name)
    if (TF_PARS[name]["type"] == 4)
      TFOC_STATE[name] = _tf_wagoget_2posbit(name)
    if (TF_PARS[name]["type"] == 5)
      TFOC_STATE[name] = _tf_wagoget_2posbit(name)
  }
  TFOC_SAVSTATE[name] = TFOC_STATE[name]
  return TFOC_STATE[name]
}'

#%IU% (name)
#%MDESC% Read the wago module(s) for 1 limit switch bit per lense. Return the
#sum of all the limit switch bits of the %B%name%B% transfocator or the
#current one if name not specified.
def _tf_wagoget_1posbit(name) '{
local i ret

  if (!name)
    name = _TFNAME
  for (i = 0; i < TF_PARS[name]["nb_lens"]; i++) {
    ret += TFOC_WAGOREAD[i]<<i
  }
  return(ret)
}'

#%IU% (name)
#%MDESC% Read the wago module(s) for 2 limit switch bits per lense. The even
#numbers are the in and the odd numbers are the out bits. Return the sum of
#the limit switch bits as follows: %BR%
#1 - in bit 1 and out bit 0;%BR%
#0 - in bit 0 and out bit 1;%BR%
#1<<nb_of_lenses - in and out bit have the same value%BR%.
#If %B%name%B% not specified, the current transfocator is red.
def _tf_wagoget_2posbit(name) '{
local i ret st

  if (!name)
    name = _TFNAME
  ret = 0
  for (i = 0; i < TF_PARS[name]["nb_lens"]; i++) {
    if ((TFOC_WAGOREAD[2*i] == 0) && (TFOC_WAGOREAD[2*i+1] == 1))
      pos = 0
    else if ((TFOC_WAGOREAD[2*i] == 1) && (TFOC_WAGOREAD[2*i+1] == 0))
      pos = 1<<i
    else
      pos = 1<<(i+TF_PARS[name]["nb_lens"])
    ret += pos
  }
  return(ret)
}'

#%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 tt
local value getvalue notset filt

  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)

  notset = 0

  value = _tf_get()

  if (n == 99) {
    if ((TF_PARS[_TFNAME]["pinhole1"]) && (TF_PARS[_TFNAME]["pinhole2"])) {
      value = (1<<(TF_PARS[_TFNAME]["pinhole1"]-1)) + \
       	       (1<<(TF_PARS[_TFNAME]["pinhole2"]-1))
    } else if (TF_PARS[_TFNAME]["pinhole"]) {
      value = (1<<(TF_PARS[_TFNAME]["pinhole"]-1))
    }
  } else {
    if (TF_PARS[_TFNAME]["type"] == 5) {
      if (n == TF_PARS[_TFNAME]["pinhole1"]) {
        value = (1<<(TF_PARS[_TFNAME]["pinhole1"]-1))
      } else if (n == TF_PARS[_TFNAME]["pinhole2"]) {
        value = (1<<(TF_PARS[_TFNAME]["pinhole2"]-1))
      } else {
        value &= ~(1<<(TF_PARS[_TFNAME]["pinhole1"]-1))
        value &= ~(1<<(TF_PARS[_TFNAME]["pinhole2"]-1))
        #in the wago list the numbering starts from 0, subtract 1
        n -= 1
        filt = 1<<n
        if ((value & filt) == 0) {
          value += filt
        }
      }
    } else {
      #in the wago list the numbering starts from 0, subtract 1
      n -= 1
      filt = 1<<n
      if ((value & filt) == 0) {
        value += filt
      }
    }
  }

  if (_tf_write(value) == -1) {
      notset = 1
  } else {
    tt = time()
    while((time() - tt) < TF_PARS[_TFNAME]["timeout"]) {
      getvalue = _tf_get()
      if (TF_PARS[_TFNAME]["pinhole_in"])
        value |= 1<< (TF_PARS[_TFNAME]["pinhole"]-1)
      if (value != getvalue) {
        sleep(0.5)
        notset = 1
      } else {
        notset = 0
        break
      }
    }
  }
  if (notset)
    printf("It appears the lense could not be inserted.\n")
}'

#%UU% number
#%MDESC% Put the lense %B%number%B% out of the beam.
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)

  #in the wago list the numbering starts from 0, subtract 1
  n -= 1

  notset = 0

  value = _tf_get()
  filt = 1<<n

  if ((value & filt) != 0) {
    value &= ~filt
    if (_tf_write(value) == -1) {
      notset = 1
    } else {
      tt = time()
      while((time() - tt) < TF_PARS[_TFNAME]["timeout"]) {
        getvalue = _tf_get()
        if (value != getvalue) {
          sleep(0.5)
          notset = 1
        } else {
          notset = 0
          break
        }
      }
    }
    if (notset)
      printf("It appears the lense could not be extracted.\n")
  }
}'

#%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)
  _tf_set(value, _TFNAME)
}'

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

#%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
  }

  stat = _tf_get()
  if (st != stat) {
    _tf_write(st)
    tt = time()
    while((time() - tt) < TF_PARS[_TFNAME]["timeout"]) {
      if (TF_PARS[_TFNAME]["pinhole_in"])
        st |= 1<< (TF_PARS[_TFNAME]["pinhole"]-1)
      if (_tf_get() == st)
        break
      sleep(0.5)
    }
    if (_tf_get() != st) 
      printf("It appears that the lenses could not be inserted.\n")
  }
}'


#%UU% 
#%MDESC% Put all the lenses in the beam. Do not touch the pinhole, if any.
def tfinall '{
local value filt[] stat tt notset

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

  value = (1<<TF_PARS[_TFNAME]["nb_lens"]) - 1
  if ((TF_PARS[_TFNAME]["pinhole1"]) && (TF_PARS[_TFNAME]["pinhole2"])) {
    filt[0] = 1<<(TF_PARS[_TFNAME]["pinhole1"] - 1)
    filt[1] = 1<<(TF_PARS[_TFNAME]["pinhole2"] - 1)
    #take the pinholes out
    value &= ~filt[0]
    value &= ~filt[1]
  }

  _tf_write(value)

  tt = time()
  while((time() - tt) < TF_PARS[_TFNAME]["timeout"]) {
    if (_tf_get() == value)
      break
    else
      sleep(0.5)
  }
  if (_tf_get() != value)
    printf("It appears that the lenses could not be inserted.\n")
}'

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

  value = 0
  if (TF_PARS[_TFNAME]["pinhole"]) {
    filt = 1<<(TF_PARS[_TFNAME]["pinhole"] - 1)
    #if pinhole is in, do not take it out
    stat = _tf_get()
    if ((stat&filt) != 0) {
      value = filt
    }
  }
  _tf_write(value)
  tt = time()
  while((time() - tt) < TF_PARS[_TFNAME]["timeout"]) {
    if (_tf_get() == value)
      break
    else
      sleep(0.5)
  }

  if (_tf_get() != value)
    printf("It appears that the lenses could not be extracted.\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_write(value)

}'

#%IU% ()
#%MDESC% Get the wago transfocator value - summ of all inserted lenses.
#Return the number of 
def _tf_read(name) '{
local ch
unglobal TFOC_WAGOREAD
global TFOC_WAGOREAD[]

  if (!name)
    name = _TFNAME
  ch = sprintf ("%s%s",TF_PARS[name]["root"], \
	TFOC_LIST[TF_PARS[name]["type"]]["suffix"])
  return(wago_readch(ch, TFOC_WAGOREAD))

}'

#%IU% (value, name)
#%MDESC% Set the transfocator to %B%value%B% - summ of all inserted lenses.
#The even numbers are the in and the odd numbers are the out bits, when there
#are 2 control bits/lense. Inser the pinhole as well if needed with any other
#lense.
def _tf_write(value, name) '{
local i valarr[]

  if (!name)
    name = _TFNAME

  if ((value > 0) && (value != TF_PARS[name]["pinhole"])) {
    if (TF_PARS[name]["pinhole_in"]) {
    printf ("Will put the pinhole in as well\n")
    #put the pinhole in if needed
    value |= (1<<TF_PARS[name]["pinhole"]-1)
    }    
  }

  if (TF_PARS[name]["type"] != 4) {
    for (i = 0; i < TF_PARS[name]["nb_lens"]; i++) {
     valarr[i] = (value&(1<<i)) ? 1: 0
    }
  } else {
    for (i = 0; i < TF_PARS[name]["nb_lens"]; i++) {
      valarr[2*i] = (value&(1<<(i))) ? 1: 0
      valarr[2*i+1] = (value&(1<<(i))) ? 0: 1
    }
  }

  return(wago_writech(sprintf ("%sctrl", TF_PARS[name]["root"]), valarr))
}'

#%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 wagocore.mac
need XML_utils.mac

#%MACROS%
#%IMACROS%
#%TOC%
#%DEPENDENCIES% wagocore.mac XML_utils.mac%BR%
#%AUTHOR% A.Beteva, BLISS%BR%
#$Revision: 1.6 $, $Date: 2013/06/04 15:08:19 $
#%END%
#%LOG%
#$Log: transfocator.mac,v $
#Revision 1.6  2013/06/04 15:08:19  beteva
#added type 5 pinhole handling.
#
#Revision 1.5  2013/04/03 16:03:21  beteva
#Changed the timeout mechanism for more efficient one.
#Added type5 - 2 pinholes transfocator.
#
#Revision 1.4  2012/10/24 08:47:52  papillon
#* correction for pinhole (set it to 1)
#* added user level tfset/tfget macros
#
#Revision 1.3  2012/05/02 17:14:29  beteva
#Made pinhole in optional. Added tfselect to choose thr current transfocator.
#
#Revision 1.2  2012/03/16 15:04:38  beteva
#Added: timeout to wait for movement; put the pinhole in if any lense inserted
#
#Revision 1.1  2012/03/12 10:12:34  beteva
#Initial revision
#