esrf

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

#%TITLE% cyber.mac
#%NAME% 
#  Macros to work with the Cyberstar boxes - SCA (Ampli, HV)
#
#%CATEGORY% Detection, Other hardware
#
#%DESCRIPTION%
#  This macro set offers basic commands for the cyberstar modules. 
#  The parameters on the standard SCA unit type and the Electrometer (not yet!) type 
#  can be read and set. For the SCA,  the window between the lower and upper 
#  threshold can be scanned. Multiple SCA units can be defined, each containing
#  one or more channels.
#%OVERVIEW%
# %UL%
#  %LI% The easiest way to inspect and change the cyberstar parameters is
# done with %B%cybermenu%B%.
# %LI% The parameter can be changed individually with the following macros:
# %B% cyberhv, cyberlow, cyberup, cybergain, cyberpeak  %B%
# %LI% A simple scan of the SCA window can be done with : %B% cyberscan%B%
# %LI% The more complicated things like doing a more complicated scan, getting
#   intergated counts, doing peak search are done with the concept of
#   pseudo motors. (Setup of this options should be done by
#   experienced users or your spec administrator)
#%XUL%
#%EXAMPLE%
# %DL%
#   %DT% cybernewsetup 3 cyb 
#   %DD% This prepares the setup of 3 units (to be configured with 
#	%B%cyberunitsetup%B%) and defines the pseudomotor %B%cyb%B%
#	to control the lower threshold of those units.
#
#   %DT% cyberunitsetup 1 0 1 3 2 4 10 5 0.2 
#   %DD% This defines the second cyberstar unit as an SCA (type 0) model PPU5CH
#	(model 1), configured with address 3, on SPECs serial device 2 with 4
#	seconds timeout. The unit has 5 channels, from 10 to 14. The default window 
#	size for scanning is 0.1 V. This means that scans on the motor cyb 
#	will scan the lower threshold and adjust the upper threshold to give a 
#	window of 0.1 V.
#
#  %DT% cybersetup
#   %DD% This macro is kept for compatibility. Use %B%cybernewsetup%B%
#	and %B%cyberunitsetup%B% for more flexible setups
#
# %XDL%
# %B%cybermenu%B% will give you the following screen:
#  %PRE%
#595.SPEC> cybermenu
#Settings on Cyberstar unit 0:
# 0 ::               High Voltage [V] : 400.000
# 1 ::         Lower SCA Threshold[V] : 0.600
# 2 ::         Upper SCA Threshold[V] : 10
# 3 ::                 Input Gain [%] : 40.000
# 4 ::             Peaking Time [ns]  : 500.000
# 5 ::            Remote Forced [0/1] : 0
#Enter number of parameter to change or -1 to exit (-1)? 1
#Set Lower SCA Threshold[V] on unit 0  (0.6)? .5
#%PRE%
#%END%        

#%IU%
#%MEDESC% Initialises the global data for Cyberstars
def cyber_init '{
  global CYBERNRUNIT CYBERUNITDEF CYBERNRCHAN CYBERCHANDEF CYBERCHAN
  global CYBERNRTYPE CYBERTYPEDEF CYBERMODELDEF 
  global CYBERSTRING CYBERTEXT CYBERLMIN CYBERLMAX
  global CYBERNRMNE CYBERMNE CYBERON CYBEROLDPOS
  local to model i j

  CYBERNRTYPE = 1

  CYBERTYPEDEF[0]["name"] = "SCA"
  CYBERTYPEDEF[0]["nrpar"] = 6
  CYBERTYPEDEF[0]["nrmodel"] = 5

  to = cyber_typeoffset(0)
  CYBERTEXT[0+to] = "High Voltage [V]"
  CYBERTEXT[1+to] = "Lower SCA Threshold[V]"
  CYBERTEXT[2+to] = "Upper SCA Threshold[V]"
  CYBERTEXT[3+to] = "Input Gain [%]"  
  CYBERTEXT[4+to] = "Peaking Time [ns] "
  CYBERTEXT[5+to] = "Remote Forced [0/1]" 
  
  model = 0 + to
  CYBERMODELDEF[model]["name"] = "CS93PPU/X1000"
  CYBERMODELDEF[model]["pars"] = "0 1 2 3 4 5"
  CYBERMODELDEF[model]["peaktimes"] = "300 500 1000 3000"

  CYBERSTRING[model][0] = ":SOUR%s:VOLT"
  CYBERLMIN[model][0] = 250;		CYBERLMAX[model][0] = 1250
  CYBERSTRING[model][1] = ":SENS%s:SCA:LOW"
  CYBERLMIN[model][1] = 0;		CYBERLMAX[model][1] = 10
  CYBERSTRING[model][2] = ":SENS%s:SCA:UPP"
  CYBERLMIN[model][2] = 0;		CYBERLMAX[model][2] = 10
  CYBERSTRING[model][3] = ":INP%s:GAIN"
  CYBERLMIN[model][3] = 0;		CYBERLMAX[model][3] = 100
  CYBERSTRING[model][4] = ":SENS%s:PKT"
  CYBERLMIN[model][4] = 300;		CYBERLMAX[model][4] = 3000
  CYBERSTRING[model][5] = ":SYST%s:COMM:REM"
  CYBERLMIN[model][5] = 0;		CYBERLMAX[model][5] = 1

  model = 1 + to
  CYBERMODELDEF[model]["name"] = "PPU5CH"
  CYBERMODELDEF[model]["pars"] = "1 2 3 4"
  CYBERMODELDEF[model]["peaktimes"] = "50 100 300 1000"

  CYBERSTRING[model][1] = ":CONF%s:LL%s"
  CYBERLMIN[model][1] = 0;			CYBERLMAX[model][1] = 4
  CYBERSTRING[model][2] = ":CONF%s:UL%s"
  CYBERLMIN[model][2] = 0;			CYBERLMAX[model][2] = 4
  CYBERSTRING[model][3] = ":CONF%s:GN%s"
  CYBERLMIN[model][3] = 0;			CYBERLMAX[model][3] = 10
  CYBERSTRING[model][4] = ":CONF%s:PT%s"
  CYBERLMIN[model][4] = 50;			CYBERLMAX[model][4] = 1000

  cyber_duplicate(0, 0, 2, "CS96MCD")
  CYBERMODELDEF[2+to]["pars"] = "1 2 3 4" 

  cyber_duplicate(0, 0, 3, "X2000")
  CYBERMODELDEF[3+to]["pars"] = "0 1 2 3 4"
  CYBERMODELDEF[3+to]["peaktimes"] = "50 100 300 1000"
  CYBERLMIN[3+to][0] = 0;		CYBERLMAX[3+to][0] = 1250
  CYBERLMIN[3+to][1] = 0;		CYBERLMAX[3+to][1] = 4
  CYBERLMIN[3+to][2] = 0;		CYBERLMAX[3+to][2] = 4
  CYBERLMIN[3+to][4] = 50;		CYBERLMAX[3+to][4] = 1000

  model = 4 + to
  CYBERMODELDEF[model]["name"] = "X20005CH"
  CYBERMODELDEF[model]["pars"] = "1 2 3 4"
  CYBERMODELDEF[model]["peaktimes"] = "50 100 300 1000"

  CYBERSTRING[model][1] = ":SENS%s:SCA:LOW%s"
  CYBERLMIN[model][1] = 0;			CYBERLMAX[model][1] = 4
  CYBERSTRING[model][2] = ":SENS%s:SCA:UPP%s"
  CYBERLMIN[model][2] = 0;			CYBERLMAX[model][2] = 4
  CYBERSTRING[model][3] = ":INP%s:GAIN%s"
  CYBERLMIN[model][3] = 0;			CYBERLMAX[model][3] = 100
  CYBERSTRING[model][4] = ":SENS%s:PKT%s"
  CYBERLMIN[model][4] = 50;			CYBERLMAX[model][4] = 1000

  for (i = 0; i < CYBERNRTYPE; i++) {
    for (j = 0; j < CYBERTYPEDEF[i]["nrmodel"]; j++) {
      model = j + cyber_typeoffset(i)
      CYBERMODELDEF[model]["type"] = i
      CYBERMODELDEF[model]["typeoffset"] = cyber_typeoffset(i)
    }
  }
}' 

#%IU% (type)
#%MDESC% Returns the offset to add to the model or parameter index depending of the
# unit type
def cyber_typeoffset(type) '{
  return type * 10
}'

#%IU% (type, base, new, name)
#%MDESC% Creates a new model %B%new%B% with name %B%name%B% as a duplicate of 
# model %B%base%B%
def cyber_duplicate(type, base, new, name) '{
  local attr modbase modnew 

  modnew = new + cyber_typeoffset(type)
  modbase = base + cyber_typeoffset(type)

  CYBERMODELDEF[modnew]["name"] = name
  CYBERMODELDEF[modnew]["pars"] = CYBERMODELDEF[modbase]["pars"]
  CYBERMODELDEF[modnew]["peaktimes"] = CYBERMODELDEF[modbase]["peaktimes"]

  for (attr = 0; attr < CYBERTYPEDEF[type]["nrpar"]; attr++) {
    CYBERSTRING[modnew][attr] = CYBERSTRING[modbase][attr]
    CYBERLMIN[modnew][attr]   = CYBERLMIN[modbase][attr] 
    CYBERLMAX[modnew][attr]   = CYBERLMAX[modbase][attr]
  }
}'

#%UU% [<no of cyberstars>] [<serial line of first cyberstar>] 
#      [<default window size[V]>] [<default unit>] [<mne1> <mne2> ...]
#%MDESC% Old setup macro that assumes all units have a single channel,
# do not accept addresses and use serial lines configured consecutive in 
# Spec. Sets up the serial lines to be used for the cyberstar units on the
# beamline. This macro must always be called first.
def cybersetup '{
  local nunit uu mnearr[] sline str dwin dunit

  cyber_init

  if (CYBERNRMNE)
    cyberoff 

  nunit = ($# > 0) ? $1 : getval("How many Cyberstar units do you have", \
				 CYBERNRUNIT)
  str   = "Your first Cyberstar is on which spec serial unit"
  sline = ($# > 1) ? $2 : getval(str, CYBERUNITDEF[0]["serline"])
  str   = "Default window size for threshold scans"
  dwin  = ($# > 2) ? $3 : getval (str, CYBERCHANDEF[0]["win"])
  dunit = ($# > 3) ? $4 : getval("Default Cyberstar unit", CYBERCHAN)

  CYBERNRCHAN = CYBERNRUNIT = nunit
  for (uu = 0; uu < CYBERNRUNIT; uu++) {
    CYBERUNITDEF[uu]["model"] = 0
    CYBERUNITDEF[uu]["addr"] = -1
    CYBERUNITDEF[uu]["serline"] = sline + uu
    CYBERUNITDEF[uu]["nrchan"] = 1

    CYBERCHANDEF[uu]["unit"] = uu
    CYBERCHANDEF[uu]["chan"] = 0

    cyberwindow dwin uu
  }

  cybersetchannel $4

  str = "How many pseudo motors want to configure as thresholds"
  CYBERNRMNE = ($# >= 4) ? (split("$*", mnearr) - 4) : getval(str, CYBERNRMNE)

  for (uu = 0; uu < CYBERNRMNE; uu++) {
    str = sprintf("Mne for pseudo motor for unit %d low threshold", uu)
    CYBERMNE[uu] = ($# >= 4) ? mnearr[uu + 4] : getval(str, CYBERMNE[uu])
    if (motor_mne(motor_num(CYBERMNE[uu])) != CYBERMNE[uu])
      print "Invalid Cyberstart threshold motor:", CYBERMNE[uu]
  }  
    
  if (CYBERNRMNE)
    cyberon 
}'

#%UU% [nrunits] [mne1] [mne2] ...
#%MDESC% This is the new setup macro for the Cyberstar. It does nothing but
# set the total number of units and define the pseudo motors to be used.
# If only one mne is specified, it will work with the active channel when the
# motor is moved, so cybersetchannel must be called first. All the "important"
# information about the hardware is set by calling %B%cyberunitsetup%B% for
# every unit in the system.

def cybernewsetup '{
  local i mnearr[] str
 
  cyber_init

  if (CYBERNRMNE)
    cyberoff 

  CYBERNRCHAN = 0
  CYBERNRUNIT = $# ? $1 : getval("How many Cyberstar units do you have", \
				       CYBERNRUNIT)
  str = "How many pseudo motors want to configure as thresholds"
  CYBERNRMNE = $# ? ($# - 1) : getval(str, CYBERNRMNE) 

  split("$*", mnearr)
  for (i = 0; i < CYBERNRMNE; i++) {
    str = sprintf("Mne for pseudo motor for unit %d low threshold", i)
    CYBERMNE[i] = $# ? mnearr[i + 1] : getval(str, CYBERMNE[i])
    if (motor_mne(motor_num(CYBERMNE[i])) != CYBERMNE[i])
      print "Invalid Cyberstart threshold motor:", CYBERMNE[i]
  }  
}'


#%UU% [unit] [type] [model] [addr] [serline] [timeout] [startchan] [nrchan] [win]
#%MDESC% Initializes the specified unit. Each Cyberstart unit is of a particular
# type (SCA, etc...), and each type has different models. The %B%addr%B% parameter
# specifies the address configured by switches in the box; it must be -1 if the
# unit does not recongize addresses (very old ones). If multiple units are daisy
# chained, they must have the same serial line %B%serline%B% and different addresses.
# Channels are unique in the system, and for the given unit they start from 
# %B%startchan%B%; %B%nrchan%B% says the number of channels in the unit. 
# %B%win%B% is the default window size
def cyberunitsetup '{
  local uu i type to val str fchan lchan dwin

  if (CYBERNRMNE)
    cyberoff 

  uu = ($# > 0) ? $1 : getval("Enter the Cyberstart unit to setup", 0)
  if (uu >= CYBERNRUNIT) {
    print "Invalid unit", uu, "only", CYBERNRUNIT, "configured units in", \
	  "cybernewsetup"
    exit
  }

  if ($# > 1)
    type = $2
  else {
    for (i = 0, str = ""; i < CYBERNRTYPE; i++)
      str = sprintf("%s%s%d: %s", str, (i > 0) ? ", " : "", i, \
		                  CYBERTYPEDEF[i]["name"]) 
    val = CYBERUNITDEF[uu]["model"]
    type = CYBERMODELDEF[val]["type"]
    type = getval(sprintf("Unit %d type (%s)", uu, str), type)
  }
  to = cyber_typeoffset(type)

  if ($# > 2)
    val = $3
  else {
    for (i = 0, str = ""; i < CYBERTYPEDEF[type]["nrmodel"]; i++)
      str = sprintf("%s%s%d: %s", str, (i > 0) ? ", " : "", i, \
		                  CYBERMODELDEF[i+to]["name"]) 
    val = CYBERUNITDEF[uu]["model"] - to
    val = getval(sprintf("Unit %d model (%s)", uu, str), val)
  }
  CYBERUNITDEF[uu]["model"] = val + to

  str = sprintf("Unit %d address (-1 if cmds. accept no addr)", uu)
  val = CYBERUNITDEF[uu]["addr"]
  CYBERUNITDEF[uu]["addr"] = ($# > 3) ? $4 : getval(str, val)

  str = sprintf("Unit %d Spec serial line", uu)
  val = CYBERUNITDEF[uu]["serline"]
  CYBERUNITDEF[uu]["serline"] = ($# > 4) ? $5 : getval(str, val)

  str = sprintf("Unit %d serial line timeout", uu)
  val = CYBERUNITDEF[uu]["timeout"]
  CYBERUNITDEF[uu]["timeout"] = ($# > 5) ? $6 : getval(str, val)

  str = "Nr. of the first channel in the unit"
  val = CYBERUNITDEF[uu]["firstchan"]
  CYBERUNITDEF[uu]["firstchan"] = ($# > 6) ? $7 : getval(str, val)

  str = "Total nr. of channels in the unit"
  val = CYBERUNITDEF[uu]["nrchan"]
  CYBERUNITDEF[uu]["nrchan"] = ($# > 7) ? $8 : getval(str, val ? val : 1)
  if (CYBERUNITDEF[uu]["nrchan"] == 0) {
    print "Invalid unit", uu, "number of channels", CYBERUNITDEF[uu]["nrchan"]
    exit
  }
  fchan = CYBERUNITDEF[uu]["firstchan"]
  lchan = CYBERUNITDEF[uu]["firstchan"] + CYBERUNITDEF[uu]["nrchan"]

  dwin = CYBERCHANDEF[fchan]["win"] 
  dwin = ($# > 8) ? $9 : getval("Default voltage window of the unit", dwin)

  for (i = CYBERNRCHAN; i < fchan; i++)
    CYBERCHANDEF[i]["unit"] = CYBERCHANDEF[i]["chan"] = -1

  for (i = fchan; i < lchan; i++) {
    if ((uu > 0) && (cyber_chan_unit(i, uu) >= 0)) {
      print "Channel", i, "already configured in unit", cyber_chan_unit(i, uu)
      continue
    }

    CYBERCHANDEF[i]["unit"] = uu
    CYBERCHANDEF[i]["chan"] = i - fchan

    ser_par(cyber_serline($1), "timeout", cyber_attr($1, "timeout"))
    cyberwindow dwin i
  }

  if (CYBERNRCHAN < lchan)
    CYBERNRCHAN = lchan

  if (CYBERNRMNE)
    cyberon
}'


#%UU% [channel]
#%MDESC% The cyberstar parameters can be entered in a menu. Enter the
# value printed in front of the parameter and you will be prompted .
# If no channel is given, the default channel is used.
def cybermenu '{
  local chan ii res ans nrpar to

  cybersetchannel $*
  chan = CYBERCHAN
  nrpar = cyber_attr(chan, "nrpar")
  to = cyber_attr(chan, "typeoffset") 

  for (;;) {	
    printf("Settings on Cyberstar unit %d:\n",chan)
    for (ii = 0; ii < nrpar; ii++) {
      if (cyber_support(chan, ii)) {
        sleep(0.1) # GBMV added some sleep here. Gilbert comment it 03/10/97
        res = cyber_get(chan, ii)
      } else
        res = "Not supported"
      printf("%2d :: %30s : %s\n", ii, CYBERTEXT[ii+to], res)
    }
    ans = getval ("Enter number of parameter to change or -1 to exit",-1)
    if ((ans >= 0) && (ans < nrpar) && (int(ans) == ans)) {
      cyber_set ans "none" chan
    } else if (ans == -1)
      break;
  }
}'	

#%IU% (chan, attr)
#%MDESC% Returns the channel/unit/model/type attribute of the specified channel
def cyber_attr(chan, attr) '{
  local aux
  if (attr in CYBERCHANDEF[chan])
    return CYBERCHANDEF[chan][attr]
  aux = CYBERCHANDEF[chan]["unit"]
  if (attr in CYBERUNITDEF[aux])
    return CYBERUNITDEF[aux][attr]
  aux = CYBERUNITDEF[aux]["model"]
  if (attr in CYBERMODELDEF[aux])
    return CYBERMODELDEF[aux][attr]
  aux = CYBERMODELDEF[aux]["type"]
  return CYBERTYPEDEF[aux][attr]
}'

#%IU% (chan, par)
#%MDESC% Returns if parameter is supported by the channel/unit
def cyber_support(chan, par) '{
  local i supp[]

  split(cyber_attr(chan, "pars"), supp)
  for (i in supp)
    if (supp[i] == par)
      return 1
  return 0
}'

#%IU% (parpos, par)
#%MDESC% Returns the channel with index chanparidx in pars, or CYBERCHAN
# if not specified
def cyber_chan(parpos, par) '{
  return (parpos >= 0) ? par : CYBERCHAN
}'

#%IU% (chan, par)
#%MDESC% Returns the correct string to send to the Cyberstar depending on
# the unit model and address
def cyber_string(chan, par) '{
  local uu cc addr model

  uu    = CYBERCHANDEF[chan]["unit"]
  cc    = CYBERCHANDEF[chan]["chan"]
  model = CYBERUNITDEF[uu]["model"]
  addr  = CYBERUNITDEF[uu]["addr"]
  addr  = (addr == -1) ? "" : addr
  if ((addr != "") && (model == 2))
    addr = addr + cc

  return sprintf(CYBERSTRING[model][par], addr, cc + 1)
}'
    
#%IU% (chan)
#%MDESC% Returns the serial line of the given channel
def cyber_serline(chan) '{
  return cyber_attr(chan, "serline")
}'

#%IU% (chan, par, val, rd)
#%MDESC% Check if the parameter is valid for the channel and translate it,
# if necessary, depending if it will be written (rd=0) or read (rd=1)
def cyber_check(chan, par, val, rd) '{
  local model newval pkarr[] nrpk i valid to

  newval = val
  model = cyber_attr(chan, "model")
  to = cyber_attr(chan, "typeoffset")

  if (par == 4)
    nrpk = split(CYBERMODELDEF[model]["peaktimes"], pkarr)

  if (rd) {
    if ((par == 4) && (model == 1))
      newval = pkarr[val]
  } else {
    if ((val < CYBERLMIN[model][par]) || (val > CYBERLMAX[model][par])) {
      printf("%s OUT of bounds (%f < val < %f)\n", CYBERTEXT[par+to], \
	     CYBERLMIN[model][par],CYBERLMAX[model][par])
      newval = -1
    } else if (par == 4) {
      for (i = 0, valid = ""; i < nrpk; i++)
        if (val == pkarr[i])
          break
        else
          valid = sprintf("%s %s", valid, pkarr[i])
      if (i == nrpk) {
        printf("INVALID Peaking Time (valid:%s)\n", valid) 
        newval = -1
      } else if (model == 1)
        newval = i
    }
  }

  return newval
}'


#%IU% (chan, nrunit)
#%MDESC% Returns the unit that holds the specified channel. If nrunit is
# greater than 0, specifies the nr. of units to search. Returns -1 if not
# found
def cyber_chan_unit(chan, nrunit) '{
  local i
  for (i = 0; i < (nrunit ? nrunit : CYBERNRUNIT); i++)
    if ((chan >= CYBERUNITDEF[i]["firstchan"]) && \
        (chan < CYBERUNITDEF[i]["firstchan"] + CYBERUNITDEF[i]["nrchan"]))
      return i
  return -1
}'

#%UU% <start> <finish> <intervals> <time> [window]
#%MDESC% Scans the lower and upper threshold of the default cyberstar module.
# The scans starts at a lower threshold of <start> and scans in
# <interval> number of scan points to <finish>. The count time at every
# scan point is <time>.  An optional parameter [window] can be given
# to modify at the same time the window between lower and upper threshold.
# All values are given in V. Be careful when setting <start> and
# <finish> as finish + window must be an allowed value for the upper
# threshold.

def cyberscan '{
  local chan win

  if (($# != 5) && ($# != 4)) {
    print "Usage:  cyberscan start finish intervals time [window]"
    exit
  } 
  if (CYBERNRMNE == 0) {
    print "No pseudo motor configured for Cyberstart thresholds"
    exit
  } else if (CYBERNRMNE == 1) {
    chan = 0
  } else if (CYBERNRMNE <= CYBERCHAN) {
    print "Motor threshold for Cyberstar channel", CYBERCHAN, "not defined"
    exit
  } else
    chan = CYBERCHAN 

  cyberon 

  if ((_m[0] = motor_num(CYBERMNE[chan])) == -1) {
    printf("Sorry , but %s is not defined\n", CYBERMNE[chan])
    exit
  }

  if ($2 > $1) { 
    _s[0] = $1; _f[0] = $2 
  } else { 
    _s[0] = $2; _f[0] = $1 
  } 
  _n1 = int($3)-1; _ctime = $4
  _nm = 1

  if ($# > 4) {
    win = $5
  } else {
    win = fabs(_f[0]-_s[0])/(_n1+1)
    _f[0] -= win
  }
  cyberwindow win

  _ascan
}'

#%UU% 
#%MDESC% Switches off the use of cyberstar pseudo motors and deletes the macros
#from user_xxxx 
def cyberdelete '{
  local ii
  
  if (!CYBERNRMNE) {
    print "Error: run cybersetup before cyberdelete"
  } else {
    CYBERON = 0
    for (ii=0;ii<CYBERNRMNE;ii++) {
      cdef("","",CYBERMNE[ii],"delete")
    }
  }
}' 

#%UU% 
#%MDESC% Switches off the use of cyberstar pseudo motors
def cyberoff '{
  local ii
  
  if (!CYBERNRMNE) {
    print "Error: run cybersetup before cyberoff"
  } else {
    CYBERON = 0
  }
}' 

#%UU% 
#%MDESC% Switches on the use of cyberstar pseudo motors
def cyberon '{
  local ii
 
  if (!CYBERNRMNE) {
    print "Error: run cybersetup before cyberon"
  } else {
    CYBERON = 1
    for (ii=0;ii<CYBERNRMNE;ii++) {
      local pars
      pars = sprintf("%s %s", CYBERMNE[ii], (CYBERNRMNE > 1) ? ii : "")
      cdef("user_getpangles", sprintf("cyber_getangles %s;", pars), \
	   CYBERMNE[ii], 1)
      cdef("user_checkall", sprintf("cyber_moveall %s;", pars), CYBERMNE[ii], 1)
    }
  }
}' 

#%IU% motor [channel]
#%MDESC% Read the lower threshold and puts the value in the pseudo motor
def cyber_getangles '{
  local ychan
  if (CYBERON) {
    ychan = cyber_chan($# - 2, $2)
    A[$1] = cyber_get(ychan, 1)
    CYBEROLDPOS[$1] = A[$1]
  }
}'

#%IU% motor [channel]
#%MDESC% Used to set the lower and upper threshold
def cyber_moveall '{
  local ychan uplev
  if (CYBERON && (A[$1] != CYBEROLDPOS[$1])) {
    ychan = cyber_chan($# - 2, $2)
    uplev = A[$1] + cyber_attr(ychan, "win")
    cyber_set 1 A[$1] ychan
    cyber_set 2 uplev ychan
    cyber_set 1 A[$1] ychan
  }
}'

#%UU% [window] [channel] 
#%MDESC% The scan window can be set faster with this macro than with
# the cybersetup macro

def cyberwindow '{
  local chan win
  chan = cyber_chan($# - 2, $2)
  win = cyber_attr(chan, "win")
  win = ($#) ? $1 : getval(sprintf("Window size for chan %d threshold scans", \
                                   chan), win)
  CYBERCHANDEF[chan]["win"] = win
}'


#%UU% [unit]
#%MDESC% Sets the default unit (actually channel) to use when no unit is
# specified in commands like set HV. Kept for compatibility, use 
# %B%cybersetchannel%B%
def cybersetunit '{
  cybersetchannel $*
}'

#%UU% [channel]
#%MDESC% Sets the default channel to use in voltage threshold scans or another
# setting macro when the channel is not specified
def cybersetchannel '{
  if ($#) {
    CYBERCHAN = $1
  } else {
    CYBERCHAN = getval("Default cyberstar channel to use", CYBERCHAN)
  }
}'


#%UU% [channel]
#%MDESC% Prints the actual values of a cyberstar channel on the screen.
# If no channel is given, the default is used
def cyberstate '{
  local chan ii res to

  chan = cyber_chan($# - 1, $1)
  to = cyber_attr(chan, "typeoffset")

  printf("Settings on Cyberstar channel %d:\n", chan)
  for (ii=0;ii<cyber_attr(chan, "nrpar");ii++) {
    if (cyber_support(chan, ii)) {
      res = cyber_get(chan, ii)
      printf("%20s : %s\n", CYBERTEXT[ii+to], res)
    }
  }
}'	


#%UU% [HV in Volt] [channel]
#%MDESC% Sets the HV on channel channel or the default channel set by cybersetchannel
def cyberhv '{
  cyber_set 0 $*
}'

#%UU% [low threshold on SCA] [channel]
#%MDESC% Sets the lower threshold on <channel> or the default 
# channel set by cybersetchannel
def cyberlow '{
  cyber_set 1 $*
}'

#%UU% [upper threshold on SCA] [channel]
#%MDESC% Sets the upper threshold on <channel> or the default 
# channel set by cybersetchannel
def cyberup '{
  cyber_set 2 $*
}'

#%UU% [input gain] [channel]
#%MDESC% Sets the input gain on <channel> or the default 
# channel set by cybersetchannel
def cybergain '{
  cyber_set 3 $*
}'

#%UU% [peaking time] [channel]
#%MDESC% Sets the peaking time in ns on <channel> or the default 
# channel set by cybersetchannel
def cyberpeak '{
  cyber_set 4 $*
}'

#%UU% [force remote flag] [channel]
#%MDESC% Sets the force-remote flag on <channel> or the default 
# channel set by cybersetchannel
def cyberremote '{
  cyber_set 5 $*
}'

#%UU% [unit]
#%MDESC% Resets the Cyberstar unit. Not implemented
def cyberreset '{
  print "Does not work yet"
}'


#%IU% <function-id> [value to set] [channel]  
#%MDESC% Set the specified value in the channel
def cyber_set '{
  local val xchan to

  xchan = cyber_chan($# - 3, $3)
  to = cyber_attr(xchan, "typeoffset")
  if (cyber_support(xchan, $1)) {
    if (($# < 2) || ("$2" == "none")) {
      val = cyber_get(xchan, $1)
      val = getval(sprintf("Set %s on channel %d ", CYBERTEXT[$1+to], xchan), val)
    } else
      val = $2

    val = cyber_check(xchan, $1, val, 0)
    if (val != -1)
      cyber_writev xchan cyber_string(xchan,$1) val
  } else
    print CYBERTEXT[$1+to], "not supported for channel", xchan
}'


#%IU% (chan, par)
#%MDESC% Reads and returns the specified parameter %B%par%B% of %B%chan%B%
def cyber_get(chan, par) '{
  local xres
  xres = "Invalid"
  cyber_readf chan cyber_string(chan,par) xres
  xres = cyber_check(chan, par, xres, 1)
  return xres
}'

#%IU% <channel> <id-string-variable> <value>
#%MDESC% Sends the specified string to %B%channel%B% and stores the box response
# in %B%value%B% as a float
def cyber_readf '{
  local str
  cyber_reads $1 $2 str
  sscanf(str,"%f",$3)
}'

#%IU% <channel> <id-string-variable> <value>
#%MDESC% Sends the specified string to %B%channel%B% and stores the box response
# in %B%value%B% as a string
def cyber_reads '{
  ser_par(cyber_serline($1), "flush", 2)
  ser_put(cyber_serline($1), sprintf("%s?\n", $2))
  cyber_accept $1
  # with chained units an extra delay is needed between multiple reads, L.C
  sleep(0.1)
  sscanf(ser_get(cyber_serline($1), "\n"), "%[^\n]", $3)
}'

#%IU% <channel> <id-string-variable> <value>
#%MDESC% Sets the parameter with <id-string> on <channel> to <value>
def cyber_writev '{
  ser_put(cyber_serline($1), sprintf("%s %s\n", $2, $3))
  cyber_accept $1
}'

#%IU% <channel>
#%MDESC% Read a binary 6 and will print an error message and exit in
# case of a timeout
def cyber_accept '{
  sleep(.1)  #Gilbert set .1 instead off .5 03/10/97
  if (ser_get(cyber_serline($1),"\006") == "") {
    printf("Timeout on cyberstar channel %d\n",$1) 
  }
}'

def cyberbody(mode) '{
  if (mode==1) {
     if (CYBERON) {
         cyberoff
     } else {
         cyberon
     }
  }

  if (mode==2) {
     cybermenu
  }

  return(sprintf("%s",CYBERON?"On":"Off"))
}'

#%MACROS%
#%IMACROS%
#%SETUP%
#  %UL%
#    %LI% The serial line used by the cyberstar has to be set up in
# config
#    %LI% A motor has to be defined in config to be used as the lower
# threshold in window scans.
#  %XUL%
#%INTERNALS%
#%DEPENDENCIES%
# The file cyber.mac has to be read in            !done by: startup script
# This file needs pseudo.mac and stchanges.mac
#%AUTHOR% Jorg Klora , 2.95  $Revision: 3.7 $ %BR%
# modified June 3, 1997 - AS
# cybersetup does NOT switch on the cyber counter
#%TOC%