esrf

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

#%TITLE% MCCE.MAC
#%NAME%
#    MCCE (Module de Command et Control des Electrometres) macros
#
#%CATEGORY% Other hardware
#
#%DESCRIPTION%
#The %B%RS422%B% serial interface allows remote reading and programming the
#MCCE. The parameters of the serial line are:%BR%
#		- 8 bits%BR%
#		- no parity%BR%
# 		- 1 stop bit%BR%
#		- 9600 bauds%BR%
#%SETUP%
#The serial line cable is connected to the interface card - either COMU
#2000 (COMU 30), known as IBAM (os9) or RocketPort (linux).
#There should be a "serial line" device servre running, on top of which a
#linux device server Mcce should run as well. Tha macro calles the Mcce device
#server commands only.
#
#%LOG%
#$Log: mcce_tango.mac,v $
#Revision 1.2  2021/07/30 12:36:27  beteva
#cleanup
#
#Revision 1.1  2021/07/30 11:55:34  beteva
#Initial revision
#
#%END%

#%UU% 
#%MDESC% Define all the globals and macros. This is the first macro to
#be executed, when using MCCE.
def mcce_init '{
  global MCCE_DEV MCCE_NO MCCE_SETUPOK
  global MCCE_TYPE MCCE_RANGE MCCE_FREQ MCCE_GAIN MCCE_POL
  global MCCE_OK
  global MCCE_NAMES

}'

#%UU% [<first electrometer device server name> (<second electrometer device server name>...)]
#%MDESC% Establish communication with the MCCE(s). The device server name is in
#database format (e.g. id00/e1/ch1).
def mccesetup '{
    local ch

    MCCE_SETUPOK = 0

    if ($#){
        MCCE_NO = split ("$*",MCCE_DEV)
    }
    else {
        MCCE_NO = getval("How many electrometer channels",MCCE_NO)
        for (ch=0; ch<MCCE_NO; ch++)
            MCCE_DEV[ch]=getval(sprintf("Device server name for ch. #%d",ch+1),MCCE_DEV[ch])
    }

    for (ch=0; ch<MCCE_NO; ch++)
        MCCE_TYPE[ch] = _mcce_type(MCCE_DEV[ch])
    MCCE_SETUPOK = 1
    mccestat
}'


def mccesetup_names '{
    local _ans

    unglobal MCCE_NAMES
    global MCCE_NAMES

    if ($#){
        _ans = split ("$*", MCCE_NAMES)
        if (_ans != MCCE_NO ){
            print "MCCE - mccesetup_name- Warning : number of mcce and number of names do not match"
        }
    }
    else {
        print "no interactive setup_names for now... sorry."
    }
}'


#%UI% (elnb)
#%MDESC% Print the parameters of the %B%elnb%B% electrometer.
def _mccestat(elnb) '{
    local ret
    MCCE_OK[elnb] = 0
    ret = tango_get(MCCE_DEV[elnb], "description")
    return(ret)
}'

#%UU% [<electrometer number> ...]
#%MDESC% Print parameters of the electrometers. If no argument given, the
#macro will print information about all configured electrometers. The input
#parameter can be one or more electrometer numbers (as specified when
#mccesetup executed).
def mccestat '{
  local inp i ch

  if ($# == 0) {
    for (ch=0; ch<MCCE_NO; ch++) {
      printf ("electrometer #%d [device: %s]\n", ch+1, MCCE_DEV[ch])
      ret = _mccestat(ch)
      if (ret == -1)
        eprintf("cannot read parametes, electrometer disabled\n")
      else {
        printf("%s\n", ret)
      }
    }
  } else {
    split ("$*", inp)
    for (ch=0; ch<$#; ch++) {
      ch = inp[i]-1
      if (_mcce_chk(ch+1) == -1)
        continue
      printf ("electrometer #%d [device: %s]\n", ch+1, MCCE_DEV[ch])
      ret = _mccestat(ch)
      if (ret == -1)
        eprintf("cannot read parametes, electrometer disabled\n")
      else {
        printf("%s\n", ret)
      }
    }
  }
}'

def _get_range_scale(elnb) '{
local ret
  ret = tango_get(MCCE_DEV[elnb], "range_scale")
  return substr(ret, 2, length(ret)-2)
}'

def _get_frequency_scale(elnb) '{
local ret
  ret = tango_get(MCCE_DEV[elnb], "frequency_scale")
  return substr(ret, 2, length(ret)-2)
}'

def _get_gain_scale(elnb) '{
local ret
  ret = tango_get(MCCE_DEV[elnb], "gain_scale")
  return substr(ret, 2, length(ret)-2)
}'



#%UU% [<electrometer number> <range> <electrometer number> <range> ...]
#%MDESC% Set the %B%range%B% of the electrometers. This macro follows a
#procedure to change the range. Different scales are possible, depending on
#the electrometer type. The %B%electrometer number%B% cannot exceed the
#configured number of electrometers, but it does not need to be in
#consecutive order, if more then one. When no arguments, the macro will ask
#for confirmation for all the available electrometers.
def mccerange '{
local inp ch i range range_scale

	if ($# == 0) {
		for (ch=0; ch<MCCE_NO; ch++) {
			if (_mcce_chk(ch+1) == -1) {
				continue
			}
			printf ("Range for electrometer #%d [", ch+1)
			range_scale = _get_range_scale(ch)
			printf (" %s", range_scale)
			MCCE_RANGE[ch] = _mcce_getrange(MCCE_DEV[ch])
			range = getval (sprintf (" ] "), MCCE_RANGE[ch])
			if (range == MCCE_RANGE[ch]) {
				printf ("Range %s already set, nothing done\n", range)
			} else {
				if (_mcce_chkrange (ch, range) < 0) {
					printf ("Invalid input, allowed values are:\n")
					printf (" %s", range_scale)
					ch--
				} else {
					printf ("Setting range to %s", range)
					_mcce_setrange (MCCE_DEV[ch], range)
					MCCE_RANGE[ch] = _mcce_getrange(MCCE_DEV[ch])
					printf("New range for electrometer #%d [%s]: %s\n", ch+1, \
							MCCE_DEV[ch], MCCE_RANGE[ch])
				}
			}
		}
	} else {
		split ("$*", inp)
		for (i=0; i<$#/2; i++) {
			ch = inp[2*i] - 1
			range = inp[2*i + 1]
			printf ("range %s\n", range)
			if (_mcce_chk(ch+1) == -1) {
				continue
			}    
			if (range == MCCE_RANGE[ch]) {	
				printf ("Range %s already set, nothing done\n", range)
			} else if (_mcce_chkrange (ch, range) < 0) {
				printf ("Invalid input, allowed values are:\n")
				printf (" %s\n", range_scale)
			} else {
				if (_mcce_setrange(MCCE_DEV[ch], range) < 0) {
					eprintf ("Range not changed\n")
				} else {
				    MCCE_RANGE[ch] = _mcce_getrange (MCCE_DEV[ch])
                    #printf("New range for electrometer #%d (%s): %s\n", ch+1, MCCE_DEV[ch], MCCE_RANGE[ch])
				}
			}
		}
	}
}'

#%UU% [<electrometer number> <polarity> <electrometer number> <polarity> ...]
#%MDESC% Set the polarity of the electrometers. This macro follows a procedur
#(several MCCE commands executed). The electrometer number cannot exceed the
#configured number of electrometers, but it does not need to be in consecutive
#order. When no arguments, the macro asks for confirmation for all the
#available electrometers. Allowed input + or -.
def mccepolarity '{
local inp ch i pol

  if ($# == 0) {
    for (ch=0; ch<MCCE_NO; ch++) {
      if (_mcce_chk(ch+1) == -1)
        continue
      MCCE_POL[ch]=getval(sprintf("Polarity sign for electrometer #%d (%s)", \
			ch+1, MCCE_DEV[ch]), MCCE_POL[ch])
      if ((MCCE_POL[ch] != "+") && (MCCE_POL[ch] != "negative") && \
         (MCCE_POL[ch] != "positive") && (MCCE_POL[ch] != "-")) {
	printf ("Allowed input + or -\n")
        ch--
      } else {
        if (_mcce_setpolarity (MCCE_DEV[ch], MCCE_POL[ch]) < 0)
          eprintf ("Error - cannot change the polarity\n")
        else {
          MCCE_POL[ch] = _mcce_getpolarity(MCCE_DEV[ch])
	  if (MCCE_POL[ch] != 0)
            printf("New polarity for electrometer #%d (%s) : %s\n", ch+1, \
	            MCCE_DEV[ch], MCCE_POL[ch])
        }
      }
    }
  } else {
    split ("$*", inp)
    for (i=0; i<$#/2; i++) {
      ch = inp[2*i] - 1
      pol = inp[2*i + 1]
      if (_mcce_chk(ch+1) == -1)
        continue
      MCCE_POL[ch] = pol
      if (_mcce_setpolarity(MCCE_DEV[ch], MCCE_POL[ch]) < 0)
        eprintf ("Error - cannot change the polarity\n")
      else{
        MCCE_POL[ch]=_mcce_getpolarity(MCCE_DEV[ch])
        if (MCCE_POL[ch] != 0)
          printf("New polarity for electrometer #%d (%s) : %s\n", ch+1, \
		MCCE_DEV[ch], MCCE_POL[ch])
      }
    }
  }
}'

#%UU% [<electrometer number> <frequency> <electrometer number> <frequency> ...]
#%MDESC% Set the frequency filter of the fotovoltaic electrometers. This macro
#follows a procedure (several MCCE commands executed). The electrometer number
#cannot exceed the configured number of electrometers, but it does not need to
#be in consecutive order. When no arguments, the macro asks for confirmation
#for all the available electrometers.
def mccefreq '{
local inp ch i freq

  if ($# == 0) {
    for (ch=0; ch<MCCE_NO; ch++) {
      if (_mcce_chk(ch+1) == -1)
        continue
      if ((MCCE_TYPE[ch] == 4) || (MCCE_TYPE[ch] == 5))
        printf ("Electrometer #%d (%s) has no filter, command ignored\n",\
		ch+1, MCCE_DEV[ch])
      else {
        freq_scale = _get_frequency_scale(ch)
	freq = getval(sprintf("Frequency for electrometer #%d (%s) [%s]", \
		ch+1, MCCE_DEV[ch], freq_scale), MCCE_FREQ[ch])
	if (freq == MCCE_FREQ[ch])
	  printf ("Frequence %d already set, nothing done\n", freq)
	else {
	  if (_mcce_chkfreq (ch, freq) < 0) {
	    printf ("Invalid input, allowed values are: ")
	    printf("%s\n\n", freq_scale)
	    ch--
	  } else {
            if (_mcce_setfreq (MCCE_DEV[ch], freq) < 0)
	      eprintf ("Error - cannot change the frequency\n")
            else {
              MCCE_FREQ[ch] = _mcce_getfreq(MCCE_DEV[ch])
	      if (MCCE_FREQ[ch] != 0)
                printf("New frequency for electrometer #%d (%s) : %s\n", \
			ch+1, MCCE_DEV[ch], MCCE_FREQ[ch])
	    }
	  }
	}
      }
    }
  } else {
    split ("$*", inp)
    for (i=0; i<$#/2; i++) {
      ch = inp[2*i] - 1
      if (_mcce_chk(ch+1) == -1)
        continue
      freq = inp[2*i+1]
      if ((MCCE_TYPE[ch] == 4) || (MCCE_TYPE[ch] == 5))
        printf ("Electrometer #%d (%s) has no filter, command ignored\n",\
		ch+1, MCCE_DEV[ch])
      else {
        if (freq == MCCE_FREQ[ch])
          printf ("Frequence %d already set, nothing done\n", freq)
	else if (_mcce_chkfreq (ch, freq) < 0) {
	  printf ("Invalid input, allowed values are: ")
	  printf ("%s", _get_frequency_scale(ch))
        } else {
	  MCCE_FREQ[ch] = freq
	  if (_mcce_setfreq(MCCE_DEV[ch], MCCE_FREQ[ch]) < 0)
	    eprintf ("Error - cannot change the frequency\n")
	  else {
            MCCE_FREQ[ch] = _mcce_getfreq (MCCE_DEV[ch])
            if (MCCE_FREQ[ch] != 0)
              printf("New frequency for electrometer #%d (%s) : %s\n", \
		ch+1, MCCE_DEV[ch], MCCE_FREQ[ch])
          }
	}
      }
    }
  }
}'

#%UU% [<electrometer number> <gain> <electrometer number> <gain> ...]
#%MDESC% Set the gain of the fotoconductive electrometers. This macro
#follows a procedure (several MCCE commands executed). The electrometer number
#cannot exceed the configured number of electrometers, but it does not need to
#be in consecutive order. When no arguments, the macro asks for confirmation
#for all the available electrometers.
def mccegain '{
local inp ch i gain gain_scale

  if ($# == 0) {
    for (ch=0; ch<MCCE_NO; ch++) {
      if (_mcce_chk(ch+1) == -1)
        continue
      if ((MCCE_TYPE[ch] != 4) && (MCCE_TYPE[ch] != 5))
        printf ("Electrometer #%d (%s) has no gain, command ignored\n", \
		ch+1, MCCE_DEV[ch])
      else {
        gain_scale = _get_gain_scale(ch)
	gain = getval(sprintf("Gain for electrometer #%d (%s) [%s]", \
		ch+1, MCCE_DEV[ch], gain_scale), MCCE_GAIN[ch])
        if (gain == MCCE_GAIN[ch])
          printf ("Gain %d already set, nothing done\n",gain)
	else {
	  if (_mcce_chkgain (ch, gain) < 0) {
	     printf ("Invalid input, allowed values are: ")
	     printf (" %s", gain_scale)
	     ch--
	  } else {
            if (_mcce_setgain (MCCE_DEV[ch], gain) < 0)
	      eprintf ("Error - cannot change the gain\n")
            else {
              MCCE_GAIN[ch] = _mcce_getgain(MCCE_DEV[ch])
	      if (MCCE_GAIN[ch] != 0)
                printf("New gain for electrometer #%d (%s) : %s\n", \
			ch+1, MCCE_DEV[ch], MCCE_GAIN[ch])
	    }
	  }
        }
      }
    }
  } else {
    split ("$*", inp)
    for (i=0; i<$#/2; i++) {
      ch = inp[2*i] - 1
      gain = inp[2*i+1]
      if (_mcce_chk(ch+1) == -1)
        continur
      if ((MCCE_TYPE[ch] != 4) && (MCCE_TYPE[ch] != 5))
        printf ("Electrometer #%d (%s) has no gain, command ignored\n", \
		ch+1, MCCE_DEV[ch])
      else {
        if (gain == MCCE_GAIN[ch])
          printf ("Gain %d already set, nothing done\n",gain)
        else if (_mcce_chkgain (ch, gain) < 0) {
	  printf ("Invalid input, allowed values are: ")
	  printf("%s",_get_gain_scale(ch))
        } else {
	  MCCE_GAIN[ch] = gain
          if (_mcce_setgain (MCCE_DEV[ch], gain) < 0)
	    eprintf ("Error - cannot change the gain\n")
          else {
            MCCE_GAIN[ch]=_mcce_getgain (MCCE_DEV[ch])
            if (MCCE_GAIN[ch] != 0)
              printf("New gain for electrometer #%d (%s) : %s\n", \
			ch+1, MCCE_DEV[ch], MCCE_GAIN[ch])
	  }
        }
      }
    }
  }
}'

######## internal macros ########
#%IU% (device)
#%MDESC%Get the type of the electrometer (values 1-6), -1 if error
def _mcce_type (device) '{
  return (tango_get(device,"type"))
}'

#-------- range --------
#%IU% (device, range)
#%MDESC% Change the electrometer range.
def _mcce_setrange (device, range) '{
    return (tango_put(device,"range", range))
}'

#%IU% (device)
#%MDESC% Get the electrometer range.
def _mcce_getrange (device) '{
  return (tango_get(device,"range"))
}'

#%IU% (elnb, value)
#%MDESC% Check the %B%elnb%B% range input %B%value%B%.
def _mcce_chkrange (elnb, value) '{
local ret

  ret = index(_get_range_scale(elnb), value)
  if (ret > 0)
      return (0)
  return (-1)
}'
#-------- end range --------

#-------- frequency --------
#%IU% (device, freq)
#%MDESC% Change the frequency filter value [Hz] of a fotovoltaic electrometer.
def _mcce_setfreq (device,freq) '{
  return(tango_put(device,"frequency",freq))
}'

#%IU% (device)
#%MDESC% Get the frequency filter value [Hz] of a fotovoltaic electrometer.
def _mcce_getfreq (device) '{
  return(tango_get(device,"frequency"))
}'

#%IU% (elnb, value)
#%MDESC% Check the %B%elnb%B% electrometer frequency filter input %B%value%B%.
def _mcce_chkfreq (elnb, value) '{
local ret val

  ret = _get_frequency_scale(elnb)
  if (index(ret, value) > 0)
    return(0)
  return(-1)
}'
#-------- end frequency --------

#-------- polarity --------
#%IU% (device, pol)
#%MDESC% Change an electrometer polarity sign
def _mcce_setpolarity (device, pol) '{
  tango_put(device,"polarity",pol)
}'

#%IU% (device)
#%MDESC%Get an electrometer polarity sign
def _mcce_getpolarity (device) '{
  return(tango_get(device,"polarity"))
}'
#-------- end polarity --------

#-------- gain --------
#%IU% (device, gain)
#%MDESC% Change the fotoconductive electrometer gain filter.
def _mcce_setgain (device, gain) '{
  return(tango_put(device,"gain",gain))
}'

#%IU% (device)
#%MDESC% Get the fotoconductive electrometer gain filter.
def _mcce_getgain (device) '{
  return(tango_get(device,"gain"))
}'

#%IU% (elnb, value)
#%MDESC% Check the %B%elnb%B% electrometer gain input %B%value%B%.
def _mcce_chkgain (elnb, value) '{
local ret
  ret = _get_gain_scale(elnb)
  if (index(ret, value) > 0)
    return(0)
  return(-1)
}'
#-------- end gain --------

#%UI% (elnb)
#%MDESC% Check if %B%elnb%B% electrometer is configured. Retur 0 if OK,
#-1 if error.
def _mcce_chk(elnb) '{
  if (!MCCE_SETUPOK) {
    eprintf("No electrometers configured.\nPlease, execute")
    tty_cntl("so");eprintf ("mccesetup");tty_cntl("se");eprintf(" first.\n")
    return(-1)
  }
  if ((elnb > MCCE_NO) && (elnb != 0)) {
    eprintf("You have asked information about nonconfigured electrometer\n")
    eprintf("Please, change the input or execute")
    tty_cntl("so");eprintf ("mccesetup");tty_cntl("se");eprintf(" first.\n")
    return(-1)
  }
  if (MCCE_OK[elnb-1] == -1) {
    eprintf ("Electrometer %s disabled.\n", MCCE_DEV[elnb-1])
    return(-1)
  }
  return(0)
}'

#%MACROS%
#%IMACROS%
#%AUTHOR%A. Beteva / BLISS%BR%
#$Revision: 1.2 $, $Date: 2021/07/30 12:36:27 $
#%TOC%