esrf

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

#%TITLE%
#   VDL.mac
#%NAME%
#   Macros for data acquisition on vdl boards

#%DESCRIPTION%
# These macros allow to define and run data acquisition on vdl boards
# They use the Spec built in features for the VDL board. The software 
# simulates additional vdl channels to get the results from internal 
# calculation. Imagine the additional channels as if the vdl hardware
# could do the calculations itself.

#%SETUP%
# The meaning of each channels is assigned by assigning a channel
# number:
# %PRE%
#   0         !  ]  raw data  channel a1
#   .         !  ]            channel b1
#   .         !  ]
#   2*multi-1 !  ]            channel bmulti
#   2*multi   !  nb of reads per multiplexed entry
#   2*multi+1 !  live time (*TG) per entry
#   2*multi+2 !  nb of calculations done
#             !  BPM2  !   BPM1  !   PHD2         ! PHD1
#   2*multi+3 !  xb1   !   xb1   !   It/Io 1      ! It/Io 1
#   2*multi+4 !  yb1   !   yb1   !   It/Io 2      ! ln (Io/It) 1
#   2*multi+5 !  xb2   !   sum1  !   ln (Io/It) 1 !
#   2*multi+6 !  yb2   !         !   ln (Io/It) 2 !
#   2*multi+7 !  sum1  !
#   2*multi+8 !  sum2  !
#%PRE%
# As an example consider the channel numbers in the following cases:
#%UL%
#%LI%  BPM1 Beam position monitor with 1 beam 
#           (4 raw data entries per card -> 2 * multiplexed)
#%LI%  BPM2 Beam position monitor with 2 multiplexed beams 
#           (8 raw data entries per card -> 4 * multiplexed)
#%LI%  PHD1 Photodiode with I and I0 
#           (2 entries per card -> 1 * multiplexed)
#%LI%  PHD2 Photodiode with I and I0 multiplexed for 2 beams.
#           (4 raw data entries per card -> 2 * multiplexed)
#%LI%  MAG1 Photodiode with I and I0 1beam but magn. switching 
#%XUL%

#%PRE%
#  Channel No  !  BPM1                !  BPM2
#     0        !  RawData1            !  RawData1 Beam1  
#     1        !  RawData2            !  RawData2 Beam1  
#     2        !  RawData3            !  RawData1 Beam2
#     3        !  RawData4            !  RawData2 Beam2 
#     4        !  No of rawdata reads !  RawData3 Beam1 
#     5        !  Total TG time       !  RawData4 Beam1 
#     6        !  No of calculations  !  RawData3 Beam2 
#     7        !  X (Hor. Beam Pos)   !  RawData4 Beam2
#     8        !  Y (Vert.Beam Pos)   !  No of rawdata reads   
#     9        !  Sum of Rawdatas     !  Total TG time
#    10        !  No of calculations  !  No of calculations
#    11        !                      !  X1 (Hor. Beam1 Pos)
#    12        !                      !  Y1 (Vert Beam1 Pos)
#    13        !                      !  X2 (Hor. Beam2 Pos) 
#    14        !                      !  Y2 (Vert Beam2 Pos)   
#    15        !                      !  Sum1 (Sum of RawD1) 
#    16        !                      !  Sum2 (Sum of RawD2) 
#%PRE%

#%PRE%
#  Channel No  !  PHD1                !    PHD2
#     0        !  RawData Ch A I0     !  RawData1 Ch A Beam1 I0 
#     1        !  RawData Ch B I      !  RawData2 Ch B Beam1 I  
#     2        !  No of rawdata reads !  RawData1 Ch A Beam2 I0 
#     3        !  Total TG time       !  RawData2 Ch B Beam2 I  
#     4        !  No of calculations  !  No of rawdata reads
#     5        !  I/I0                !  Total TG time 
#     6        !  ln (Io/It)          !  No of calculations 
#     7                               ! I/I0  Beam1 
#     8                               ! I/I0  Beam2
#     9                               ! ln (Io/It) Beam1 
#    10                               ! ln (Io/It) Beam2
#%PRE%

#%UU%
#%MDESC%
# Prints the current parameters on the screen
def vdlshowpar '
{
  global VDL_MODETEXT VDL_TMODETEXT

  VDL_MODETEXT[1]=" lock int" ; VDL_MODETEXT[2] = " lock ext"
  VDL_MODETEXT[3]="lock semi" ; VDL_MODETEXT[4] = "prog href"
  VDL_MODETEXT[5]=" prog end" ; VDL_MODETEXT[6] = " trig int"
  VDL_MODETEXT[7]=" trig ext" ; VDL_MODETEXT[6] = "trig semi"

  VDL_TMODTEXT[0]="   live";VDL_TMODTEXT[1]="elapsed" ; 
  VDL_TMODTEXT[2]=" fix no" ;
  VDL_CMODTEXT[0]=" NO";VDL_CMODTEXT[1]="BPM"; VDL_CMODTEXT[2]="PHD" ;
  VDL_CMODTEXT[3]="MAG";

  for (i=0;i<VDL_NB;i++) {
    if (!i) printf(\
" VDL_mode   TD[ms] TG[ms]  Ref   TMode Freq Nacq Calc Mux Mag    DarkA    DarkB \n")
    printf("%s(%1d) %5.0f  %5.0f %4.0f %s  %3d %4d  %s   %1d  %2d %7.3f %7.3f \n",\
	VDL_MODETEXT[counter_par(VDL_DEV[i],"mode")], \
	counter_par(VDL_DEV[i],"mode"), \
 	counter_par(VDL_DEV[i],"TD"), \
	counter_par(VDL_DEV[i],"TG"), \
	counter_par(VDL_DEV[i],"time"), \
	VDL_TMODTEXT[counter_par(VDL_DEV[i],"timemode")],\
	counter_par(VDL_DEV[i],"freq"), \
	counter_par(VDL_DEV[i],"noacq"), \
	VDL_CMODTEXT[counter_par(VDL_DEV[i],"calcmode")],\
	counter_par(VDL_DEV[i],"multiplex"), \
	counter_par(VDL_DEV[i],"magfactor"), \
	counter_par(VDL_DEV[i],"dark_A"), \
	counter_par(VDL_DEV[i],"dark_B") \
)
  }

}'

#%IU% 
#%MDESC% sets the vdl parameters according to the global array VDL_xxx
def vdlsetpar '
  #
  # First assign correct values for VDL_NB and VDL_DEV 
  # (this is necessary if vdlsetpar is called when getconf is executed)
  # Modified by Vicente (7/9/95)
  #
  for (VDL_NB=-1,i=0;i<COUNTERS;i++) {
    if (counter_par(i,"controller")=="VDL") {
      if (VDL_NB < counter_par(i,"vdlunit")) {	
	VDL_NB = counter_par(i,"vdlunit")
      }
      VDL_DEV[counter_par(i,"vdlunit")] = i
    }
  } 
  VDL_NB ++ 
  # End modif

  for (i=0;i<VDL_NB;i++) {
    counter_par(VDL_DEV[i],"mode",VDL_MODE[i])
    counter_par(VDL_DEV[i],"TD",VDL_TD[i])
    counter_par(VDL_DEV[i],"TG",VDL_TG[i])
    counter_par(VDL_DEV[i],"multiplex",VDL_MUA[i])
    counter_par(VDL_DEV[i],"freq",VDL_FRE[i])
    counter_par(VDL_DEV[i],"time",VDL_REF[i])
    counter_par(VDL_DEV[i],"noacq",VDL_NUM[i])
    counter_par(VDL_DEV[i],"dark_A",VDL_DARKA[i])
    counter_par(VDL_DEV[i],"dark_B",VDL_DARKB[i])
    counter_par(VDL_DEV[i],"magfactor",VDL_MAGF[i])
    counter_par(VDL_DEV[i],"timemode",VDL_TMOD[i])
    counter_par(VDL_DEV[i],"calcmode",VDL_CMOD[i])
  }
'

#%IU% 
#%MDESC% fills the global array VDL_xxxx with the vdl parameters.
def vdlgetpar '
  for (i=0;i<VDL_NB;i++) {
    VDL_MODE[i]=counter_par(VDL_DEV[i],"mode")
    VDL_TD[i]=counter_par(VDL_DEV[i],"TD")
    VDL_TG[i]=counter_par(VDL_DEV[i],"TG")
    VDL_MUA[i]=counter_par(VDL_DEV[i],"multiplex")
    VDL_FRE[i]=counter_par(VDL_DEV[i],"freq")
    VDL_REF[i]=counter_par(VDL_DEV[i],"time")
    VDL_NUM[i]= counter_par(VDL_DEV[i],"noacq")
    VDL_DARKA[i] = counter_par(VDL_DEV[i],"dark_A")
    VDL_DARKB[i] = counter_par(VDL_DEV[i],"dark_B")
    VDL_MAGF[i] = counter_par(VDL_DEV[i],"magfactor")
    VDL_TMOD[i]= counter_par(VDL_DEV[i],"timemode")
    VDL_CMOD[i]= counter_par(VDL_DEV[i],"calcmode")
  }
'

#%UU% ["MODE TD TG REF TMOD FRE NOACQ CMOD MULTI MAG DARKA DARKB" 
# "MODE2 .. DARKB2" ...] 
#%MDESC%
# Without parameters ,the uses is asked additional parameters for the vdl 
# cards he configured in SPECs config editor.
# A star (*) in place of a parameter will not change the actual value.
# This allows macros to be written that allow to change only certain values
# (like TD or TG).
# The meaning of the different parameters
# %DL%
# %DT% Mode %DD% The mode parameter of the VDL card. (See hardware reference, 
#     differences are internal-external reference signal, internal-external 
#     start and stop)
#
# %DT% TD %DD% the delay time in ms at each reference cycle.
# %DT% TG %DD% the measuring time in ms at each reference cycle.
#
# %DT% Ref time %DD% depends on the mode.Gives either the internal 
# reference frequency (the ref time is this number in OS9 ticks (= 10ms)) or
# a time out for the other modes (also given in ticks (10ms))
#
# %DT% Time mode %DD% You can choose between 3 different ways the number 
#  of acquisitions is calculated from the user input.
#  %UL%
#  %LI% fixed : User input (as in ct 4 or ct -100) is ignored and the
#      number of acquisitions is taken from the global "no of acq" given
#      above.
#  %LI% elapsed : Spec tries to match the estimated measurement time with
#      the user input. (ct 1 will measure during one second).
#      In this mode, higher multiplexed VDL cards will measure during the
#      same time interval and therefore do less acqisitions per multiplexed
#      entry. If the user asks for a certain number of acqisitions (ct -100)
#      this number will be the real number of acqisitions and has to be divided
#      by the the multiplex factor to get the number of acquisitions per
#      multiplexed entry. (The number will be rounded to a multiple of the
#      multiplex factor). Once again this has been done to match the 
#      measurement times of different VDL cards with different multiplex
#      factor but the same chopper frequency)
#  %LI% live :  The time the user gives will be the live time of the 
#      measurement (TG * no of acquisitions per multiplexed entry).
#      The number of acquisitions given by ct -100 is this time the number
#      of acquisitions per multiplexed entry). This mode is for users
#      who prefer to work with "constant statistics".
#  %XUL%
# It is strongly recommanded to use only one time mode and not to switch 
# between them. Users might otherwise very fast get confused. The recommanded
# time mode is "elapsed" time.
#
# %DT% Frequency chopper %DD% given in Hz. This frequency is used only in
# time mode "elapsed" (see above). It represents the chopper frequency
# and is used to calculate the time an acquisition will take.
#
# %DT% No of Acq %DD% Only used in time mode "fixed" representing the number
# of acquisitions on this VDL card. (The number of raw data is twice 
# (Channel A/B) this number )
# 
# %DT% Calc mode %DD% You have to tell the internal calculation routines 
# if you connected a beam position monitor (BPM), a photo diode with 
# I and I0 (PHD), a photodiode used with magn. field switching (MAG), or 
# you want the software to do no calculations on 
# individual acuisitions.
#
# %DT% Multiplexing %DD% Is the number of times every channel of the VDL 
# card has to be multiplexed to get the number of raw data necessary. 
# (Example: PHD1: 1 , PHD2: 2 , BPM1: 2 , BPM2: 4) 
#
# %DT% Cycles for up field %DD% 
# This number is only used in calc mode 3 (MAG) for magnetic field
# switching (MCD,XMCD). The number specifies after how many cycles 
# the of the chopper the magetic field changes sign.
#
# %DT% DarkA ,DarkB %DD% 
# Only used without chopper (mode 4). The 
# value given will be deduced from the counts read from the VDL.
# DarkA is used for Channel A. DarkB is used for Channel B.
#
# %XDL% 
def vdldevsetup '
{
  local i j pacnt nopa pars
  global VDL_GROUP VDL_NB 
  global VDL_DEV VDL_NOA VDL_DARKA VDL_DARKB VDL_MAGF
  global VDL_TD VDL_TG VDL_NUM VDL_MUA
  global VDL_MODE VDL_REF VDL_TMOD VDL_CMOD VDL_FRE
  global VDL_MODETEXT VDL_TMODETEXT VDL_CMODTEXT

  for (VDL_NB=-1,i=0;i<COUNTERS;i++) {
    if (counter_par(i,"controller")=="VDL") {
      if (VDL_NB < counter_par(i,"vdlunit")) {	
	VDL_NB = counter_par(i,"vdlunit")
      }
      VDL_DEV[counter_par(i,"vdlunit")] = i
    }
  } 
  VDL_NB ++ 

  if (VDL_TD[0]==0) {
    vdlgetpar
  }

  if ($# == 0) {
    vdlshowpar	
    for (i=0;i<VDL_NB;i++) {
      VDL_MODE[i]= getval(sprintf("VDL Mode of %d. dev",i+1),VDL_MODE[i])
      VDL_TD[i]= getval(sprintf("VDL TD [ms] par. of %d. dev ",i+1),VDL_TD[i])
      VDL_TG[i]= getval(sprintf("VDL TG [ms] par. of %d. dev",i+1),VDL_TG[i])
      VDL_REF[i]= getval(sprintf("Ref time of %d. dev [~10ms]",i+1),VDL_REF[i])
      VDL_TMOD[i]= getval(sprintf(\
         "Time mode [0,1,2] for %d Dev. (live,elap.,fixed)",i+1),VDL_TMOD[i])
      if (VDL_TMOD[i] == 1) {
        VDL_FRE[i]=getval(sprintf("Chopper frequency %d. dev",i+1),VDL_FRE[i])
      } else if (VDL_TMOD[i] == 2) {
        VDL_NUM[i]= getval(sprintf("No of aqu. on %d. dev",i+1),VDL_NUM[i])
      }
      VDL_CMOD[i]=getval(sprintf(\
         "Calc mode [0,1,2,3] for %d Dev. (NO,BPM,PHD,MAG)",i+1),VDL_CMOD[i])
      if (VDL_CMOD[i] == 1) {
         print "BPM : 1 Beam Multiplexing = 2 , 2 Beams Multiplexing = 4"
      } else if (VDL_CMOD[i] == 2) {
         print "PHD : 1 Beam Multiplexing = 1 , 2 Beams Multiplexing = 2"
      } else if (VDL_CMOD[i] == 3) {
         print "MAG : 1 Beam Multiplexing = 1 "
      } 
      VDL_MUA[i]=getval(sprintf("Multiplexing (Dev %d)",i+1),VDL_MUA[i])
      if (VDL_CMOD[i] == 3) {
        VDL_MAGF[i]= getval(sprintf(\
	  "Vdl cycles for up field (calc mode 3) on %d. dev",i+1),VDL_MAGF[i])
      }
      if (VDL_MODE[i] == 4) {
        VDL_DARKA[i]= getval(sprintf(\
          "Dark current Channel A [counts/ms] on %d. dev",i+1),VDL_DARKA[i])
        VDL_DARKB[i]= getval(sprintf(\
          "Dark current Channel B [counts/ms] on %d. dev",i+1),VDL_DARKB[i])
      }
    }
  } else {
    nopa = split("$*",pars)
    for (pacnt=0,i=0;i<VDL_NB;i++) {
      if (pars[pacnt] != "*" ) VDL_MODE[i]= pars[pacnt]+0;
      pacnt ++ ; if (pars[pacnt] != "*" ) VDL_TD[i]= pars[pacnt]+0;
      pacnt ++ ; if (pars[pacnt] != "*" ) VDL_TG[i]= pars[pacnt]+0;
      pacnt ++ ; if (pars[pacnt] != "*" ) VDL_REF[i]= pars[pacnt]+0;
      pacnt ++ ; if (pars[pacnt] != "*" ) VDL_TMOD[i]= pars[pacnt]+0;
      pacnt ++ ; if (pars[pacnt] != "*" ) VDL_FRE[i]= pars[pacnt]+0;
      pacnt ++ ; if (pars[pacnt] != "*" ) VDL_NUM[i]= pars[pacnt]+0;
      pacnt ++ ; if (pars[pacnt] != "*" ) VDL_CMOD[i]= pars[pacnt]+0;
      pacnt ++ ; if (pars[pacnt] != "*" ) VDL_MUA[i]= pars[pacnt]+0;
      pacnt ++ ; if (pars[pacnt] != "*" ) VDL_MAGF[i]= pars[pacnt]+0;
      pacnt ++ ; if (pars[pacnt] != "*" ) VDL_DARKA[i]= pars[pacnt]+0;
      pacnt ++ ; if (pars[pacnt] != "*" ) VDL_DARKB[i]= pars[pacnt]+0;
    }
  }

  vdlsetpar	
  cdef ("user_config",";vdlsetpar;","_VDL",0)
}'

#%MACROS%
#%IMACROS%
#%AUTHOR%  J.Klora