esrf

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

#$Log: tab2.mac,v $
#Revision 1.0  2003/09/22 15:13:43  papillon
#Initial revision
#
#
#%TITLE% NTAB2.MAC
#%NAME%
#  Macros to control two leg table(s) with logical motors
#             xtilt and height
#%DESCRIPTION%
#  A table with two legs
#  For geometry 0 (standard):
#     tilt is the angle defined by the two legs. The middle position stays
#     fixed when moving the tilt. height is the height at this point.
#  
#  All motors must be defined in config.
#
#%EXAMPLE%
#%DL%
#%DT% tab2setup 1 0 122 tab1 tab2 xti hgt
#  Defines one table geometry 0 distance 122 mm motor names
#
#%DT% mvr hgt 3
#  Moves relative height 3 mm. this will move all tab motors up 3 mm.
#%DT% ascan xti 0 3 10 1
#  Will scan on angles xti between 0 and 3 stopping in 10 intermediate
#  points and counting for one second at each point
#%XDL%
#%END%
#

#%UU%
#%MDESC%  Setup one table in the system
#
def tab2setup '{
  global TAB2PAR
  local t2_mne t2_geo t2_bl1 t2_bl2 t2_xti t2_hgt t2_d1

  list_test TAB2PAR

#
# Set values.
  if ($# < 7) {
    t2_mne=getval("Name for the table (no space)",sprintf("%d",list_n(TAB2PAR)))
    if (index(t2_mne, " ") != 0) {
      p "Name for table must not contain any space character"
      exit
    }

    if (list_check(TAB2PAR, t2_mne)) {
      t2_geo  = list_getpar(TAB2PAR, t2_mne, "geo")
      t2_d1   = list_getpar(TAB2PAR, t2_mne, "d1")
      t2_bl1  = list_getpar(TAB2PAR, t2_mne, "bl1")
      t2_bl2  = list_getpar(TAB2PAR, t2_mne, "bl2")
      t2_xti  = list_getpar(TAB2PAR, t2_mne, "xti")
      t2_hgt  = list_getpar(TAB2PAR, t2_mne, "hgt")
    } else {
      t2_geo = 0
      t2_d1  = 0
      t2_bl1 = ""
      t2_bl2 = ""
      t2_xti = ""
      t2_hgt = ""
    }
  
    t2_geo = getval("Geometry for table(0=standard,see help for others)",t2_geo)
    t2_d1 = getval("\tDistance between the two legs",t2_d1)
    printf("  Motor names\n")
    t2_bl1 = getval("\tLeg 1",t2_bl1)
    t2_bl2 = getval("\tLeg 2",t2_bl2)
    t2_xti = getval("\tX Tilt(angle between legs)",t2_xti)
    t2_hgt = getval("\tHeight",t2_hgt)
   }
   else {
    t2_mne = "$1"
    t2_geo = $2
    t2_d1  = $3
    t2_bl1 = "$4"
    t2_bl2 = "$5"
    t2_xti = "$6"
    t2_hgt = "$7"
   }

  if (index(t2_mne, " ") != 0) {
    p "Name for table must not contain any space character"
    exit
  }
  if (t2_geo != 0) {
    printf("This geometry is not implemented yet\n")
    exit
  }
  if (motor_num(t2_bl1) == -1) {
    printf("motor \"%s\" does not exist\n", t2_bl1)
    exit
  }
  if (motor_num(t2_bl2) == -1) {
    printf("motor \"%s\" does not exist\n", t2_bl2)
    exit
  }
  if (motor_num(t2_xti) == -1) {
    printf("motor \"%s\" does not exist\n", t2_xti)
    exit
  }
  if (motor_num(t2_hgt) == -1) {
    printf("motor \"%s\" does not exist\n", t2_hgt)
    exit
  }

  _tab2off(t2_mne)
  list_add(TAB2PAR, t2_mne)
  list_setpar(TAB2PAR, t2_mne, "geo", t2_geo)
  list_setpar(TAB2PAR, t2_mne, "d1" , t2_d1)
  list_setpar(TAB2PAR, t2_mne, "bl1", t2_bl1)
  list_setpar(TAB2PAR, t2_mne, "bl2", t2_bl2)
  list_setpar(TAB2PAR, t2_mne, "xti", t2_xti)
  list_setpar(TAB2PAR, t2_mne, "hgt", t2_hgt)
  list_setpar(TAB2PAR, t2_mne, "mne", t2_mne)

  _tab2on(t2_mne)

  setup_tail("tab2", t2_mne)
}'

#%UU% (table-mnemonic)
#%MDESC%
#   Delete definitions for one table
#
def tab2unsetup '{
  local t2_mne

  t2_mne = "$1"
  _tab2off(t2_mne)
  list_remove(TAB2PAR, t2_mne)
}'

#%UU%
#%MDESC% Shows a list with the actual configuration in this system
#
def tab2show '{
  local t2_n

  t2_n = list_n(TAB2PAR)
  printf("%d Two leg tables defined in this system:", t2_n)
  printf("\n\n")

  for (i=1;i<=t2_n;i++) {
    printf("   Table \"%s\" :\n", list_getpar(TAB2PAR, i, "mne"))
    printf("      bl1: %5s          xti: %5s\n",list_getpar(TAB2PAR,i,"bl1"),list_getpar(TAB2PAR,i,"xti"))
    printf("      bl2: %5s          hgt: %5s\n",list_getpar(TAB2PAR,i,"bl2"),list_getpar(TAB2PAR,i,"hgt"))
  }
}'

#%IU%
#%MDESC%
#
# Read position from controller for bl1.
#
def tab2_bl1get '{
  list_setpar(TAB2PAR, "$2", "bl1oldpos", A[$1])
}'

#%IU%
#%MDESC%
#
# Read position from controller for bl2.
#
def tab2_bl2get '{
  list_setpar(TAB2PAR, "$2", "bl2oldpos", A[$1])
}'

#%IU%
#%MDESC%
#  Calculates xti from tab1, tab2
#
def tab2_xtiget '{
  local t2_bl1 t2_bl2 t2_xti t2_hgt 
  local t2_geo t2_d1 t2_tabmne t2_motmne

  t2_motmne = $1
  t2_tabmne = "$2"

  t2_geo = list_getpar(TAB2PAR, t2_tabmne, "geo")
  t2_d1 = list_getpar(TAB2PAR, t2_tabmne, "d1")
  t2_bl1 = motor_num(list_getpar(TAB2PAR, t2_tabmne, "bl1"))
  t2_bl2 = motor_num(list_getpar(TAB2PAR, t2_tabmne, "bl2"))
  t2_xti = motor_num(list_getpar(TAB2PAR, t2_tabmne, "xti"))
  t2_hgt = motor_num(list_getpar(TAB2PAR, t2_tabmne, "hgt"))

  A[t2_motmne] = tab2_tf(2,A[t2_bl1],A[t2_bl2],A[t2_xti],\
			 A[t2_hgt],t2_geo,t2_d1)

  list_setpar(TAB2PAR, t2_tabmne, "xtioldpos", A[t2_motmne])
}'

#%IU%
#%MDESC%
#  Calculates hgt from tab1, tab2
#
def tab2_hgtget '{
  local t2_bl1 t2_bl2 t2_xti t2_hgt 
  local t2_geo t2_d1 t2_tabmne t2_motmne

  t2_motmne = $1
  t2_tabmne = "$2"

  t2_geo = list_getpar(TAB2PAR, t2_tabmne, "geo")
  t2_d1 = list_getpar(TAB2PAR, t2_tabmne, "d1")
  t2_bl1 = motor_num(list_getpar(TAB2PAR, t2_tabmne, "bl1"))
  t2_bl2 = motor_num(list_getpar(TAB2PAR, t2_tabmne, "bl2"))
  t2_xti = motor_num(list_getpar(TAB2PAR, t2_tabmne, "xti"))
  t2_hgt = motor_num(list_getpar(TAB2PAR, t2_tabmne, "hgt"))

  A[t2_motmne] = tab2_tf(3,A[t2_bl1],A[t2_bl2],A[t2_xti],\
			 A[t2_hgt],t2_geo,t2_d1)
  list_setpar(TAB2PAR, t2_tabmne, "hgtoldpos", A[t2_motmne])
}'

#%IU%
#%MDESC%
#  Moves tab1 when xti or hgt change
#
def tab2_bl1move '{
  local t2_bl1 t2_bl2 t2_xti t2_hgt 
  local t2_geo t2_d1 t2_tabmne t2_motmne

  t2_motmne = $1
  t2_tabmne = "$2"
  t2_xti = motor_num(list_getpar(TAB2PAR, t2_tabmne, "xti"))
  t2_hgt = motor_num(list_getpar(TAB2PAR, t2_tabmne, "hgt"))

  if ((list_getpar(TAB2PAR, t2_tabmne, "xtioldpos") != A[t2_xti]) ||\
      (list_getpar(TAB2PAR, t2_tabmne, "hgtoldpos") != A[t2_hgt])) {
    t2_geo = list_getpar(TAB2PAR, t2_tabmne, "geo")
    t2_d1 = list_getpar(TAB2PAR, t2_tabmne, "d1")
    t2_bl1 = motor_num(list_getpar(TAB2PAR, t2_tabmne, "bl1"))
    t2_bl2 = motor_num(list_getpar(TAB2PAR, t2_tabmne, "bl2"))
 
    A[t2_motmne] = tab2_tf(0,A[t2_bl1],A[t2_bl2],A[t2_xti],\
			   A[t2_hgt],t2_geo,t2_d1)
    list_setpar(TAB2PAR, t2_tabmne, "bl1oldpos", A[t2_motmne])
  }
}'

#%IU%
#%MDESC%
#  Moves tab2 when xti or hgt change
#
def tab2_bl2move '{
  local t2_bl1 t2_bl2 t2_xti t2_hgt 
  local t2_geo t2_d1 t2_tabmne t2_motmne

  t2_motmne = $1
  t2_tabmne = "$2"
  t2_xti = motor_num(list_getpar(TAB2PAR, t2_tabmne, "xti"))
  t2_hgt = motor_num(list_getpar(TAB2PAR, t2_tabmne, "hgt"))

  if ((list_getpar(TAB2PAR, t2_tabmne, "xtioldpos") != A[t2_xti]) ||\
      (list_getpar(TAB2PAR, t2_tabmne, "hgtoldpos") != A[t2_hgt])) {
    t2_geo = list_getpar(TAB2PAR, t2_tabmne, "geo")
    t2_d1 = list_getpar(TAB2PAR, t2_tabmne, "d1")
    t2_bl1 = motor_num(list_getpar(TAB2PAR, t2_tabmne, "bl1"))
    t2_bl2 = motor_num(list_getpar(TAB2PAR, t2_tabmne, "bl2"))

    A[t2_motmne] = tab2_tf(1,A[t2_bl1],A[t2_bl2],A[t2_xti],\
			   A[t2_hgt],t2_geo,t2_d1)
    list_setpar(TAB2PAR, t2_tabmne, "bl2oldpos", A[t2_motmne])
  }
}'

#%IU%
#%MDESC%
#
def tab2_xtimove '{
  local t2_bl1 t2_bl2 t2_xti t2_hgt 
  local t2_geo t2_d1 t2_tabmne t2_motmne

  t2_motmne = $1
  t2_tabmne = "$2"
  t2_bl1 = motor_num(list_getpar(TAB2PAR, t2_tabmne, "bl1"))
  t2_bl2 = motor_num(list_getpar(TAB2PAR, t2_tabmne, "bl2"))

  if ((list_getpar(TAB2PAR, t2_tabmne, "bl1oldpos") != A[t2_bl1]) ||\
      (list_getpar(TAB2PAR, t2_tabmne, "bl2oldpos") != A[t2_bl2])) {
    t2_geo = list_getpar(TAB2PAR, t2_tabmne, "geo")
    t2_d1 = list_getpar(TAB2PAR, t2_tabmne, "d1")
    t2_xti = motor_num(list_getpar(TAB2PAR, t2_tabmne, "xti"))
    t2_hgt = motor_num(list_getpar(TAB2PAR, t2_tabmne, "hgt"))

    A[t2_motmne] = tab2_tf(2,A[t2_bl1],A[t2_bl2],A[t2_xti],\
			   A[t2_hgt],t2_geo,t2_d1)
    list_setpar(TAB2PAR, t2_tabmne, "xtioldpos", A[t2_motmne])
  }
}'

#%IU%
#%MDESC%
#
def tab2_hgtmove '{
  local t2_bl1 t2_bl2 t2_xti t2_hgt 
  local t2_geo t2_d1 t2_tabmne t2_motmne

  t2_motmne = $1
  t2_tabmne = "$2"
  t2_bl1 = motor_num(list_getpar(TAB2PAR, t2_tabmne, "bl1"))
  t2_bl2 = motor_num(list_getpar(TAB2PAR, t2_tabmne, "bl2"))

  if ((list_getpar(TAB2PAR, t2_tabmne, "bl1oldpos") != A[t2_bl1]) ||\
      (list_getpar(TAB2PAR, t2_tabmne, "bl2oldpos") != A[t2_bl2])) {
    t2_geo = list_getpar(TAB2PAR, t2_tabmne, "geo")
    t2_d1 = list_getpar(TAB2PAR, t2_tabmne, "d1")
    t2_xti = motor_num(list_getpar(TAB2PAR, t2_tabmne, "xti"))
    t2_hgt = motor_num(list_getpar(TAB2PAR, t2_tabmne, "hgt"))

    A[t2_motmne] = tab2_tf(3,A[t2_bl1],A[t2_bl2],A[t2_xti],\
			   A[t2_hgt],t2_geo,t2_d1)
    list_setpar(TAB2PAR, t2_tabmne, "hgtoldpos", A[t2_motmne])
  }
}'

#%IU% (calcidx , tbl1, tbl2, xti, hgt, mode, d1)
#%MDESC% calcidx gives the index of the value to be calculated. Indexes are 
# starting from 0 (tbl1) and go to 3 (hgt). The 2 leg motors and the 2 pseudo
# motors are all the time given. Depending on calcidx only 2 of them are used
# in the calculation. The mode allows for different geometries.
def tab2_tf(calcidx,t2_bl1,t2_bl2,t2_xti,t2_hgt,mode,t2_d1) '{
  local reverse res
  if (calcidx > 1)
    reverse = 1

  if (mode == 0) {
    if (reverse) {
	res[2] = 1000 * atan( (t2_bl2 - t2_bl1) / t2_d1 ) # xti
	res[3] = (t2_bl1 + t2_bl2) / 2 # hgt
    } else {
	res[0] = t2_hgt - t2_d1 * tan(t2_xti/1000) / 2 # tbl 1
	res[1] = t2_hgt + t2_d1 * tan(t2_xti/1000) / 2 # tbl 2
    }
  }
  return res[calcidx];
}'

#%UU% table-number
#%MDESC%
#
# Sets on the track between table and logical motors
#
def tab2on '{
  local t2_tabmne

  t2_tabmne = "$1"

  if (list_check(TAB2PAR, t2_tabmne)) {
    _tab2on(t2_tabmne)
  } else {
    printf("tab2 \"%s\" does not exist\n", t2_tabmne)
  }
}'

def _tab2on(t2_tabmne) '{
  local t2_bl1 t2_bl2 t2_xti t2_hgt 

  t2_bl1 = list_getpar(TAB2PAR, t2_tabmne, "bl1")
  t2_bl2 = list_getpar(TAB2PAR, t2_tabmne, "bl2")
  t2_xti = list_getpar(TAB2PAR, t2_tabmne, "xti")
  t2_hgt = list_getpar(TAB2PAR, t2_tabmne, "hgt")

  cdef("user_getpangles", sprintf("tab2_bl1get %d %s\n", motor_num(t2_bl1), \
       t2_tabmne), t2_bl1, 0x01)
  cdef("user_checkall",   sprintf("tab2_bl1move %d %s\n",motor_num(t2_bl1), \
       t2_tabmne), t2_bl1, 0x01)

  cdef("user_getpangles", sprintf("tab2_bl2get %d %s\n", motor_num(t2_bl2), \
       t2_tabmne), t2_bl2, 0x01)
  cdef("user_checkall",   sprintf("tab2_bl2move %d %s\n",motor_num(t2_bl2), \
       t2_tabmne), t2_bl2, 0x01)

  cdef("user_getpangles", sprintf("tab2_xtiget %d %s\n", motor_num(t2_xti), \
       t2_tabmne), t2_xti, 0x01)
  cdef("user_checkall",   sprintf("tab2_xtimove %d %s\n",motor_num(t2_xti), \
       t2_tabmne) , t2_xti, 0x01)

  cdef("user_getpangles", sprintf("tab2_hgtget %d %s\n", motor_num(t2_hgt), \
       t2_tabmne), t2_hgt, 0x01)
  cdef("user_checkall",   sprintf("tab2_hgtmove %d %s\n",motor_num(t2_hgt), \
       t2_tabmne) , t2_hgt, 0x01)
  list_setpar(TAB2PAR, t2_tabmne, "state", 1)
}'

#%UU% table-number
#%MDESC% 
#
# Sets off the track between table and logical motors
#
def tab2off '{
  local t2_tabmne

  if ($# == 0) {
    t2_tabmne=getval("table mnemonic to set off",list_getpar(TAB2PAR,1,"mne"))
  } else if ($# == 1) {
    t2_tabmne = "$1"
  } else {
    p "Usage : tab2off [table mnemonic]"
    exit
  }

  if (list_check(TAB2PAR, t2_tabmne)) {
    _tab2off(t2_tabmne)
  } else {
    printf("tab2 \"%s\" does not exist\n", t2_tabmne)
  }
}'

def _tab2off(t2_tabmne) '{
  local t2_bl1 t2_bl2 t2_xti y3_hgt

  t2_bl1  = list_getpar(TAB2PAR, t2_tabmne, "bl1")
  t2_bl2  = list_getpar(TAB2PAR, t2_tabmne, "bl2")
  t2_xti  = list_getpar(TAB2PAR, t2_tabmne, "xti")
  t2_hgt  = list_getpar(TAB2PAR, t2_tabmne, "hgt")
  cdef("", "", t2_bl1, "delete")
  cdef("", "", t2_bl2, "delete")
  cdef("", "", t2_xti, "delete")
  cdef("", "", t2_hgt, "delete")
  list_setpar(TAB2PAR, t2_tabmne, "state", 0)
}'

#%MACROS%
#%IMACROS%
#%DEPENDENCIES%
#  To use the table with its pseudomotors the following must be done
#%UL%
#%LI% The file ntab2.mac has to be read in               done by: startup s.
#    (this file needs: pseudo.mac , stchanges.mac)
#%LI% the pseudo motors have to be configured            done by: SPECADM
#       (Controller NONE, mnemonic as in startupscript)
#%LI% setup the table ( with tab2setup )                done by: startup s.
#%XUL%
#%AUTHOR% Vicente Rey. June 1995
#$Revision: 1.0 $, $Date: 2003/09/22 15:13:43 $
#%TOC%