esrf

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

#%TITLE% CYLSLIT.MAC
#%NAME%
#  Macros for operating cylinder slit gaps.
#
#%CATEGORY% Positioning
#
#%DESCRIPTION%
#%PRE%
#   This macro set allows you to define pseudo motor gap on cylinder slits.
#
#   Since version 2.0 (Feb 2006) this macro file allows also to
#   define new style calculation macro motors on cylinder slits.
#
#   To define new style macro motors you must define:#
#
#   a cylslit controller in config (one controller will work on one or
#   several cylinder slits modules):
#
#   MOTORS       DEVICE    ADDR   <>MODE      NUM               <>TYPE
#      YES       cylslit                        2         Macro Motors
#
#   motors in config referring to that controller. 
#
#   Different cylinder slits can be defined by using additional
#   module numbers in the motor unit/module/channel assignment.
#
#   Config file
#     The following parameters have to be associated in config
#     file to the macro motor.
#
#     Example:
#
#     MOT000 = MAXE:0/0 [...]   roth
#     MOT001 = MAXE:0/1 [...]   rotv
#
#     MOT002 = MAC_MOT:0/0/0 [....]         chg
#     MOTPAR:theta = roth
#     MOTPAR:radius = 15
#
#     MOT003 = MAC_MOT:0/1/0 [....]         cvg
#     MOTPAR:theta = rotv
#     MOTPAR:radius = 15
#
#   Calibration: 
#	Theta set to 0 when beam is cut (gap is 0 too)
#        theta limits set to 0 and arcsin (maxgap/(2*radius)).
#
#%PRE%
#%END%

def cylslit_config(mne,type,unit,module,chan) '{

   local theta radius

   if (type == "ctrl") return

   theta  = motor_par(mne,"theta")
   radius = motor_par(mne,"radius")

   if ( theta ==-1 || motor_num(theta) == -1 || radius <=0 ) {
      return ".error."
   }

   motor_par(motor_num(theta), "gap",  motor_mne(mne), "add")
  
   print "Using Cylinder Slits Macro Motor:",motor_mne(mne),"(gap)", theta,"(rotation)", "radius", radius

   return sprintf("%s", theta)
}'

def cylslit_calc (mne, mode) '{

   local motnum thnum gapnum
   local radius theta cylgap

   if (mne == "..") return

   motnum = motor_num(mne)

   if ( mode == 0) {

      theta  = motor_par(mne, "theta")
      thnum  = motor_num (theta)
      radius = motor_par(motnum,"radius")

      A[motnum] = 2*sin(in_radian(A[thnum]))*radius 
       
   } else {

      cylgap  = motor_par(mne, "gap")
      gapnum  = motor_num (cylgap)
      radius  = motor_par(gapnum,"radius")
       
      A[motnum] = in_degree(asin(A[gapnum]/(radius*2)))
  }
}'


def cylsetup '{

  global CYL_OLD CYL_ON
  global CYL_MOT
  global CYL_NAMES CYL_NO

  local _n _hgap _vgap _hrot _vrot _hrad _vrad

  if ($# != 7) {
      if (CYL_NO) {
	  printf("Current definitions of CYLINDER SLITS:\n")
	  for (i=0;i<CYL_NO;i++) {
	      _n = CYL_NAMES[i]
	      printf("NAME = %s (motors - radius)\n",_n) 
              printf("     horizontal -> %s %s %g \n",\
                CYL_MOT[_n]["hgap"], CYL_MOT[_n]["hrot"], CYL_MOT[_n]["hrad"])
              printf("     vertical   -> %s %s %g \n",\
                CYL_MOT[_n]["vgap"], CYL_MOT[_n]["vrot"], CYL_MOT[_n]["vrad"])
	  }
      }
      _n = getval("Name for this group of slits",CYL_NAMES[CYL_NO-1])
      _hgap = getval("   HORIZONTAL GAP mnemonic",CYL_MOT[_n]["hgap"])
      _hrot = getval("   HORIZONTAL ROTATION MOTOR mnemonic",\
                                                  CYL_MOT[_n]["hrot"])
      _hrad = getval("                 CYLINDER RADIUS (mm)",\
                                                  CYL_MOT[_n]["hrad"])
      _vgap = getval("   VERTICAL GAP mnemonic",  CYL_MOT[_n]["vgap"])
      _vrot = getval("   VERTICAL ROTATION MOTOR mnemonic",\
                                                  CYL_MOT[_n]["vrot"])
      _vrad = getval("                 CYLINDER RADIUS (mm)",\
                                                  CYL_MOT[_n]["vrad"])
  } else {
      _n = "$1"
      _hgap ="$2"
      _hrot ="$3" 
      _hrad = $4
      _vgap ="$5"
      _vrot ="$6"
      _vrad = $7
  }

  cylslits_add(_n,_hgap,_vgap,_hrot,_vrot,_hrad,_vrad)

  setup_tail("cyl",_n)
}'

def cylslits_add(name,hgap,vgap,hrot,vrot,hrd,vrd) '{

     local found

     for (i=0;i<CYL_NO;i++) {
         if (name == CYL_NAMES[i]) {
	     found = 1
	     break
         }
     }

     if (!found) {
	 p "Adding ",name 
         CYL_NAMES[i] = name 
         CYL_NO++
     }
      
     CYL_MOT[name]["hgap"] = hgap 
     CYL_MOT[name]["vgap"] = vgap
     CYL_MOT[name]["hrot"] = hrot
     CYL_MOT[name]["vrot"] = vrot
     CYL_MOT[name]["hrad"] = hrd
     CYL_MOT[name]["vrad"] = vrd
     CYL_MOT[name]["HK"] = PI/2-asin(20/sqrt(pow(hrd,2)+400))
     CYL_MOT[name]["VK"] = PI/2-asin(30/sqrt(pow(vrd,2)+900))
     CYL_MOT[name]["HK2"] = sqrt(pow(hrd,2)+400)
     CYL_MOT[name]["VK2"] = sqrt(pow(vrd,2)+900)

     cylon
}'

def cylon '{
    CYL_ON = 1

    for ( i = 0;i<CYL_NO;i++) {
        name = CYL_NAMES[i]
        cdef("user_checkall",  sprintf("cylslits_move %s\n",name),name)
        cdef("user_getpangles",sprintf("cylslits_get  %s\n",name),name)
        cdef("user_set",sprintf("cylslits_set  %s\n",name),name)
    }

}'

def cyloff '{

    CYL_ON = 0

    for ( i = 0;i<CYL_NO;i++) {
        name = CYL_NAMES[i]
        cdef("", "",name,"delete")
    }
}'

def cylunsetup '{
    local name  tmpno tmpnames

    name = "$1"

    tmpno = 0
    for ( i = 0;i<CYL_NO;i++) {
        if ( name == CYL_NAMES[i] ) {
            cdef("", "",name,"delete")
            continue
        } else {
             tmpnames[tmpno] = CYL_NAMES[i]
             tmpno++
        }
    }
    for (i=0;i<tmpno;i++) {
          CYL_NAMES[i] = tmpnames[i]
    }
    CYL_NO = tmpno
}'



def cylslits_move '{
     local hgapnum vgapnum hrotnum vrotnum hmm vmm hradius vradius
     
     slitname = "$1"
     hgapnum = motor_num(CYL_MOT[slitname]["hgap"])
     vgapnum = motor_num(CYL_MOT[slitname]["vgap"])
     hrotnum = motor_num(CYL_MOT[slitname]["hrot"])
     vrotnum = motor_num(CYL_MOT[slitname]["vrot"])

     error = 0

     if (vrotnum == -1 || hrotnum == -1 || vgapnum == -1 || hgapnum == -1 ) {
          error = 1
     } 

     if (!error) {
         movehrot = ( A[hrotnum] != CYL_OLD[slitname]["hrot"])
         movevrot = ( A[vrotnum] != CYL_OLD[slitname]["vrot"])
         movevgap = ( A[vgapnum] != CYL_OLD[slitname]["vgap"])
         movehgap = ( A[hgapnum] != CYL_OLD[slitname]["hgap"])

         if (movehgap) {
           A[hrotnum] = in_degree(asin(A[hgapnum]/(CYL_MOT[slitname]["hrad"]*2)))
#p "move requested",A[hgapnum],A[hrotnum]
         }
         if (movevgap) {
           A[vrotnum] = in_degree(asin(A[vgapnum]/(CYL_MOT[slitname]["vrad"]*2)))
         }
         if (movehrot) {
           A[hgapnum] = 2*sin(in_radian(A[hrotnum]))*CYL_MOT[slitname]["hrad"]
         }
         if (movevrot) {
           A[vgapnum] = 2*sin(in_radian(A[vrotnum]))*CYL_MOT[slitname]["vrad"]
         }

         _bad_lim = 0
         _chk_lim hgapnum A[hgapnum]
         _chk_lim vgapnum A[vgapnum]
         _chk_lim hrotnum A[hrotnum]
         _chk_lim vrotnum A[vrotnum]

         if (_bad_lim)  {
	     print "CYLINDER SLITS -  Bad limit: resetting"
             A[hrotnum] = CYL_OLD[slitname]["hrot"]
             A[vrotnum] = CYL_OLD[slitname]["vrot"]
             A[vgapnum] = CYL_OLD[slitname]["vgap"]
             A[hgapnum] = CYL_OLD[slitname]["hgap"]
         }
#p "move accepted",A[hgapnum],A[hrotnum]
      }
}
'

def cylslits_get '{
     local hgapnum vgapnum hrotnum vrotnum
     
     slitname = "$1"

     hgapnum = motor_num(CYL_MOT[slitname]["hgap"])
     vgapnum = motor_num(CYL_MOT[slitname]["vgap"])
     hrotnum = motor_num(CYL_MOT[slitname]["hrot"])
     vrotnum = motor_num(CYL_MOT[slitname]["vrot"])

     error = 0
     if (vrotnum == -1 || hrotnum == -1 || vgapnum == -1 || hgapnum == -1 ) {
       error = 1
     } 

     if (!error) {

         A[hgapnum] = 2*sin(in_radian(A[hrotnum]))*CYL_MOT[slitname]["hrad"]
         A[vgapnum] = 2*sin(in_radian(A[vrotnum]))*CYL_MOT[slitname]["vrad"]

#p "read angles",A[hrotnum],A[hgapnum]

         CYL_OLD[slitname]["hgap"] = A[hgapnum] 
         CYL_OLD[slitname]["vgap"] = A[vgapnum] 
         CYL_OLD[slitname]["hrot"] = A[hrotnum] 
         CYL_OLD[slitname]["vrot"] = A[vrotnum] 

     }
}'


def cylslits_set '{

   slitname="$1"

   hgapnum = motor_num(CYL_MOT[slitname]["hgap"])
   vgapnum = motor_num(CYL_MOT[slitname]["vgap"])
   hrotnum   = motor_num(CYL_MOT[slitname]["hrot"])
   vrotnum   = motor_num(CYL_MOT[slitname]["vrot"])

   error = 0

   if (vrotnum == -1 || hrotnum == -1 || vgapnum == -1 || hgapnum == -1 ) {
          error = 1
   } 

   if (!error) {
     if (motor2set == hgapnum) {
         chg_offset (hrotnum, in_degree(asin(position2set/(CYL_MOT[slitname]["hrad"]*2))))
     } 
     if (motor2set == vgapnum) {
         chg_offset (vrotnum, in_degree(asin(position2set/(CUL_MOT[slitname]["vrad"]*2))))
     }
   }
}'

def in_degree (angle) '{
  return deg (angle)
##   return angle
}'

def in_radian (angle) '{
  return rad (angle)
##  return angle
}'