esrf

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

#$Log: wagoct.mac,v $
#Revision 1.13  2018/08/28 09:19:38  perez
#Add support of TANGO WAGO DS
#
#Revision 1.12  2007/01/30 12:18:55  beteva
#added test for nb of wago gains, if novelec for backward compatibility
#
#Revision 1.11  2006/12/18 10:30:36  spruce
#wago scale factors are now an order of magnitude bigger (corresponding to hw)
#the minimum threshold value is not scaled with the scale factor
#the comparison for adjusting the gain is always positive to allow negative voltages to work
#
#Revision 1.9  2006/12/05 14:03:51  spruce
#optional 7th parameter allowing a threshold offset for novelec amplifiers
#if undefined this parameter has no effect. If defined it has 2 effects.
#its value is added to the amplifier signal to provide a zero level for zero counts.
#If the voltage is less than this level it is converted to 0
#
#Revision 1.1  2006/11/22 11:52:24  spruce
#Initial revision
#
#Revision 1.8  2006/09/28 16:35:20  spruce
#fixed bug with number of arguments for scale factors
#(this was transparent if they were not being used in wcton)
#
#Revision 1.7  2006/09/27 13:11:17  spruce
#added 2 new optional parameters which will give counts in photons per second if the scale factor and constant are given with wcton
#changed the low threshold of the gain adjustment to be 1/gainfactor so that it works for gainfactors bigger than 10
#
#Revision 1.6  2006/08/22 12:56:47  guijarro
#changed 0.3 to 0.1 for low retval limit
#
#Revision 1.5  2006/06/13 07:06:51  guijarro
#BL_SCALE_FACTOR applied only if Wago counter is Novelec type
#
#Revision 1.4  2006/06/06 08:03:38  beteva
#added BL_SCALE_FACTOR (DS)
#
#Revision 1.3  2006/03/23 17:26:30  rey
#Bug in parameter passing with quotes. Parameter 3 should not have
#quotes.
#
#Revision 1.2  2006/02/15 11:01:44  beteva
#added counter only type. Put absolute value for the reading of the counters - novelecs can give negative voltage. Added wcadjall.
#
#Revision 1.1  2006/02/15 10:39:20  rey
#Initial revision
#
#%NAME%  wagoct.mac
#%DESCRIPTION%
#   Macros to use pseudocounters on wago adc 
#
#%END%

global WAGO_CTDEV[] WAGO_GAINFACTOR[] WAGO_CTGAIN[] WAGO_VOLTAGE_OFFSET[]
global WAGO_NOVELEC WAGO_THERMO WAGO_CTTYPE WAGO_CT WAGO_SCALE_FACTOR[] WAGO_SCALE_CONSTANT[]

WAGO_NOVELEC = 1
WAGO_THERMO  = 2
WAGO_CT = 3

#%UU% [type dev-name ctmne [gainfactor] or wcname wcchan]
#%MDESC%type 1=Novelec (devname ctmne [gainfactor]), type 2=Thermo (dev-name
#ctmne wcname wcchan), type 3=Counter Only.
#  Adds a wago counter definition
def wcton '{
   local devname ctmne wagofactor[] setupOK nb

  if ($# <= 3 || $# >7) {
    print "       ( for type 1=Novelec) "
    print "Usage: wcton wctype dev-name ctmne [gainfactor]"
    print "       or with conversion to photons per second a=scale * x + constant"
    print "Usage: wcton wctype dev-name ctmne [gainfactor] scale constant"
    print "    or ( for type 2=Thermo) "
    print "Usage: wcton wctype dev-name ctmne wcname wcchan"
    print "    or ( for type 3=Counter Only) "
    print "Usage: wcton wctype dev-name ctmne wcname"
  }

  wctype  = $1
  devname = "$2" 
  ctmne   = $3

  if (cnt_num(ctmne) == -1)
    print "Counter $3 is not configured. Ignored as wago counter"
  else {
    if (wctype == WAGO_NOVELEC ) {
      if ($# >= 4 ) {
        nb = split("$4",wagofactor)
	if (nb == 1) {
          wagofactor[1] = wagofactor[2] = wagofactor[0]
        }
      } else {
        wagofactor[0] = 1
        wagofactor[1] = 1
        wagofactor[2] = 1
      }
      WAGO_CTDEV[$3]      = "$2"
      # create 3 gainfactors for each circuit
      WAGO_GAINFACTOR[$3][0] = wagofactor[0]
      WAGO_GAINFACTOR[$3][1] = wagofactor[1]
      WAGO_GAINFACTOR[$3][2] = wagofactor[2]
      WAGO_CTGAIN[$3]     = wcreadgain($3)
      WAGO_CTTYPE[$3]     = WAGO_NOVELEC
      if ($#>=6) {
        WAGO_SCALE_FACTOR[$3] = $5
        WAGO_SCALE_CONSTANT[$3] = $6
      } else {
        WAGO_SCALE_FACTOR[$3] = 1
        WAGO_SCALE_CONSTANT[$3] = 0
      }
      if ($#==7) {
        WAGO_VOLTAGE_OFFSET[$3]=$7
      }  else {
	WAGO_VOLTAGE_OFFSET[$3]=0
      }
      cmd = sprintf("wcreadct(\"%s\",%s)\n", devname, ctmne)
      setupOK = 0
    } else if ( wctype ==  WAGO_THERMO ) {
      wcname = "$4" 
      wcchan = $5 
      WAGO_CTTYPE[$3]     = WAGO_THERMO
      cmd = sprintf("wcreadct(\"%s\",%s,\"%s\",%d)\n", devname, ctmne, wcname, wcchan)
      setupOK = 0
    } else if (wctype = WAGO_CT) {
      wcname = "$4"
      WAGO_CTTYPE[$3] = WAGO_CT
      cmd = sprintf("wcreadct(\"%s\",%s, \"%s\")\n", devname, ctmne, wcname)
      setupOK = 0
    } else  {
      print "Wrong wago counter type"
      setupOK = -1
    }
    if (setupOK == 0)
      cdef("user_getcounts", cmd, cnt_mne(ctmne), 0x02)
  }
}'

#%UU% devname ctmne
#%MDESC%
#  Deletes a wago counter definition
def wctoff '{
   ctmne = "$1"
   cdef("","",ctmne, "delete")
}'

#%UU% ctmne value
#%MDESC%
#  Sets a gain for a counter or show all gains if no parameter is given
def wcgain '{

   if ($# != 2 ) { 
      print "Usage: wcgain [ ctmne value ]"

      wcshowgain()

   }  else {
 
      if ( $2 < 1 || $2 > 3 ) { 
         print "Values for wago gain must be 1, 2 or 3 "
      } else if ( $1 in WAGO_CTDEV ) {
         devname = WAGO_CTDEV[$1]
         wcsetgain( devname, "$1", $2)
      } else {
        print "Unknown wago counter. Define it with \"wcton\"."
      }
   }

}'

#%UU%
#%MDESC%Adjust the gains automatically for all the novelec type counters.
def wcadjall '{
  local id
  
  for (id in WAGO_CTDEV) {
    _wcadj(cnt_mne(id))  
  }
}'

#%UU% ctmne
#%MDESC%
#  Automatically adjusts gain for a counter
def wcadj '{

   local vals dev

   if ($# != 1 ) { 
      print "Usage: wcadj [ ctmne ]"
   }  else {
      _wcadj( "$1" )
   }
}'

def _wcadj( name ) '{

    local ctnum i

    ctnum = cnt_num( name )

    if ( !(ctnum  in WAGO_CTDEV) || ( ctnum == -1 ) ) {
      print "Wago counter not properly defined in setup/config"
    } else {
      dev = WAGO_CTDEV[ctnum]
      for (i=1;i<4;i++) {
        wcsetgain( dev, name, i)
        retval = _wcreadnovel( dev, cnt_num(name) )
        printf("Gain(%d) - count: %3.3f, corrected: %3.3f\n", \
          i, retval, _wccorr(cnt_num(name),retval))
        if ( (1/WAGO_GAINFACTOR[ctnum][i-1] < fabs(retval))  && ( fabs(retval) < 9.89 ) ) {
          break   
        }
      }
    }

    if ( i == 4 ) {   
      if ( retval < 0.01 ) {
        wcsetgain( dev, name, 1)
    }
      return 0
    } else {
      return 1
    }
}'

#%IU% ()
#%MDESC%
#  call internally  to show all current gain values
def wcshowgain() '{
   tty_cntl("md")
   print "\nCurrent WAGO Gains" 
   tty_cntl("me")
   for ( ctmne in WAGO_CTDEV ) {
      if ( WAGO_CTTYPE[ctmne] == WAGO_NOVELEC ) {
          printf("% 8s - %s\n", cnt_mne( ctmne) , wcreadgain( ctmne))
      }
   } 
}'

#%IU%(devname)
#%MDESC%
# Return non null if TACO device name
#
def _wcistaco(dev) '{
   return(substr(dev,length(dev)-1,2) == "wc")
}'

#%IU% 
#%MDESC%
#  call internally to obtain current gain setting
def wcreadgain( ctmne ) '{
   local argout

   devname = WAGO_CTDEV[ctmne]
   if(_wcistaco(devname)) {
    id     = esrf_io(devname,"DevName2Key",sprintf("%s_g",cnt_mne(ctmne)))
    nvals  = esrf_io( devname, "DevReadNoCacheDigi", id, argout )
   } else {
    id     = tango_io(devname,"DevName2Key",sprintf("%s_g",cnt_mne(ctmne)))
    nvals  = tango_io(devname, "DevReadNoCacheDigi", id, argout )
   }


   ret = 0
   for (i=0;i<nvals;i++) {
      if ( argout[i] == 1) {
         ret += (i+1)
      }
   }

   if ( ret > 3 ) {
     print "Strange value"
   }

   WAGO_CTGAIN[ctmne] = ret
   return ret
}'

#%IU% 
#%MDESC%
#  call by internal counting macros to obtain counter value
#  it assigns the S matrix and it also returns the value
#  obtain 
def wcreadct( dev, ctmne, name, chan) '{
   global WAGO_SCALE_FACTOR[] WAGO_SCALE_CONSTANT[]
   local ctval

   if ( WAGO_CTTYPE[ctmne] == WAGO_NOVELEC ) { 
      ctval = _wcreadnovel(dev,ctmne)
      ctval = _wccorr(ctmne, ctval)
      if (WCTDEBUG == 1) printf("%s photon scale factor: %g, constant: %g\n",cnt_name(ctmne),WAGO_SCALE_FACTOR[ctmne],WAGO_SCALE_CONSTANT[ctmne])
      ctval = ctval * WAGO_SCALE_FACTOR[ctmne] + WAGO_SCALE_CONSTANT[ctmne]
   } else if ( WAGO_CTTYPE[ctmne] == WAGO_THERMO ) {
      ctval = _wcreadthermo(dev, name,  chan)
   } else if (WAGO_CTTYPE[ctmne] == WAGO_CT) {
     ctval = _wcreadthermo(dev,name,0)
   }

   S[ctmne] = ctval
   return ctval
}'

def wc_photon_scale(ctmne,ctval) '{
  return ctval*WAGO_SCALE_FACTOR[ctmne] + WAGO_SCALE_CONSTANT[ctmne]
}'

def _wccorr(name,ctval) '{

   local factor retval

   if (WAGO_CTGAIN[name] != 0) {
       factor = pow( WAGO_GAINFACTOR[name][WAGO_CTGAIN[name]-1] , WAGO_CTGAIN[name])
   } else {
       factor = 1
   }
   if(WCTDEBUG == 1) printf("Wago counter %s, novelec voltage is %f, correction factor %f, offset %f\n",cnt_name(name),ctval,factor,WAGO_VOLTAGE_OFFSET[name])

   val = ctval * factor + WAGO_VOLTAGE_OFFSET[name]
   #
   # force to zero counts if we are below the noise threshold
   # this requires that the noise thresholds for the more all gains are well adjusted
   # if not then it is not possible to make the following decision correctly
   # unless we provided a noise threshold level for each possible gain.
   #
   if (fabs(ctval) < fabs(WAGO_VOLTAGE_OFFSET[name]) && WAGO_VOLTAGE_OFFSET[name] != 0) val =0
  
   return fabs(val)

}'

def _wcreadthermo(dev, name, wcchan) '{
   if(_wcistaco(devname)) {
    id      = esrf_io(dev,"DevName2Key",name)
    nvals   = esrf_io(dev,"DevReadNoCachePhys" ,id,vals)
   } else {
    id      = tango_io(dev,"DevName2Key",name)
    nvals   = tango_io(dev,"DevReadNoCachePhys" ,id,vals)
   }
   return vals[wcchan]  
}'

def _wcreadnovel(dev,name) '{
   local id vals
   if(_wcistaco(devname)) {
    id      = esrf_io(dev,"DevName2Key",sprintf("%s_s",cnt_mne(name)))
    nvals   = esrf_io(dev,"DevReadNoCachePhys" ,id,vals)
   } else {
    id      = tango_io(dev,"DevName2Key",sprintf("%s_s",cnt_mne(name)))
    nvals   = tango_io(dev,"DevReadNoCachePhys" ,id,vals)
   }
   return (vals[0])
}'

#%IU% 
#%MDESC%
#  call internally to set a certain gain value
def wcsetgain( dev, name, val ) '{
   local argin
   
   printf("Gain for %s was %d ", name, wcreadgain(cnt_num(name)) )
   if(_wcistaco(devname)) {
    id     = esrf_io(dev,"DevName2Key",sprintf("%s_g",name))
   } else {
    id     = tango_io(dev,"DevName2Key",sprintf("%s_g",name))
   }

   argin[0] = id
   argin[1] = 0
   argin[2] = 0
   argin[3] = 1
   argin[4] = 0
   argin[5] = 2
   argin[6] = 0

   argin[val*2] = 1
   if(_wcistaco(devname)) {
    esrf_io( dev, "DevWriteDigi", argin )
   } else {
    tango_io( dev, "DevWriteDigi", argin )
   }
   # give the amplifier time to react
   sleep(1.0)
   printf(" is now %d\n", wcreadgain(cnt_num(name)))  
}'


#%MACROS%
#%IMACROS%
#%AUTHOR% V. Rey
#%TOC%
#$Revision: 1.13 $, $Date: 2018/08/28 09:19:38 $