esrf

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

#%TITLE% lakeshorecurves.mac
#%NAME%
# Download calibration curves into a LakeShore temperature controller.
#%DESCRIPTION%
# Each LakeShore temperature controller is delivered with his own sensors. ID18
# wish to be able to use all sensors with all the LS controller they have. Thus
# the calibration curves have to be loaded into the controller.
# %BR%
# The marcos have NOT YET been tested for models model 218, 332 or 340.
# There might be chance for other models to work, but tests have been made with
# those models only.
#%END%

if (!(whatis("lsgpib_setup") & 2)) {
#%UU%
#%MDESC%
# Syntax : lsgpib_setup <GPIB unit> <GPIB number>.%BR%
# Set the global LS_ADDR which is used for all gpib access.%BR%
# The lsgpib_setup macro might be taken from lakeshore340 macro set.
# Only define if not present yet.
def lsgpib_setup '{
  global LS_GPIB_ADDR LS_COMM_MODE
  if ($# != 2) {
    printf("Usage: lsgpib_setup <Spec GPIB unit range [0-3]> <Instrument GPIB number>")
  } else {
    gpib_unit = $1 ; gpib_addr = $2
    LS_GPIB_ADDR = sprintf("%1d:%1d",gpib_unit,gpib_addr)
    LS_COMM_MODE = "GPIB"
  }
}'
}

if (!(whatis("_ls_send") & 2)) {
#%IU%
#%MDESC%
#Syntax : _ls_send(command)%BR%
#Internal function to send a command string to the lakeshore. This imp.
#uses gpib at an address defined my the global variable %B%LS_ADDR.%B%
#Returns %B%LSREADERROR%B% if the command could not be sent, otherwise
#%B%LSOK%B% is returned.%BR%
# The _ls_send macro might be taken from lakeshore340 macro set.
# Only define if not present yet.
def _ls_send(command) '{
  local numsent
  local reply
  global LS_GPIB_ADDR
  global LS_COMM_MODE

  if(LS_COMM_MODE == "GPIB"){
	  numsent = gpib_put(LS_GPIB_ADDR,command)
	  if(numsent==0)
		  return "LSREADERROR"
	  else
		  return "LSOK"
  }

  if(LS_COMM_MODE == "SOCKET"){
	  reply = _ls_read(command)
	  if(reply != "LSREADERROR")
		  return "LSOK"
	  else
		  return "LSREADERROR"
  }

  }'
}

if (!(whatis("_ls_read") & 2)) {
#%IU%
#%MDESC%
# Syntax : _ls_read(command)%BR%
# Internal function to send a command string to the lakeshore and get the 
# reply.%BR%
# The _ls_read macro might be taken from lakeshore340 macro set.
# Only define if not present yet.%BR% 
def _ls_read(command) '{
	global LS_COMM_MODE
	global LS_GPIB_ADDR
	global LS_SOCKET_ADDR
	local ans;	
	local test
       	local numsent
	local tosend

	ans = "LSREADERROR"

	if(LS_COMM_MODE == "GPIB"){		
    numsent = gpib_put(LS_GPIB_ADDR,command)
    if(numsent > 0){
       ans = gpib_get(LS_GPIB_ADDR)
    if (ans == "")	
     ans = "LSREADERROR"
    } else {
      print "_ls_read() : Error writing to GPIB"
      ans = "LSREADERROR"
		}
	}    

	if(LS_COMM_MODE == "SOCKET"){
		ans = sock_par(LS_SOCKET_ADDR,"connect")
		if(ans == 1) {
      tosend = sprintf("%s\n",command)
      ans = sock_put(LS_SOCKET_ADDR,tosend)
      ans = sock_get(LS_SOCKET_ADDR,0)
			sock_par(LS_SOCKET_ADDR,"close")
			ans = substr(ans,0,length(ans)-1)
      if(ans == "SERVER_TIMEOUT"){
				print "_ls_read() : Server Timeout"
        ans = "LSREADERROR"
			}
    } else {
			print "_ls_read() : Cannot connect to server."
			ans = "LSREADERROR"
		}
	}

	return ans
}'
}

#%UU%
#%MDESC%
# Syntax : lslistallcurves%BR%
# List out all the curves used in the controller. There are 60 possible curves (1 - 60).
def lslistallcurves '{
  local i, crv, curve[], curve_name[], curve_units[], curve_coeff[], fmt

	curve_units[1] = "mV/K"
	curve_units[2] = "V/K"
	curve_units[3] = "Ohm/K"
	curve_units[4] = "log(Ohm)/K"
	curve_units[5] = "log(Ohm)/log(K)"

	curve_coeff[1] = "negative"
	curve_coeff[2] = "positive"

  fmt = "%2s %-15s %-10s %-10s %-10s %-10s\n"

  global LS_GPIB_ADDR
  if ($# != 0) {
    printf("Usage: lslistallcurves")
  } else {
      printf(fmt, "#", "Name", "Serial #", "Format", "Limit", "Coefficient")

      for(crv = 1; crv < 61; crv++) {
    	  local ans
	      ans = _ls_read(sprintf("CRVHDR? %d",crv))
	      if(ans == "LSREADERROR") {
		      eprint "Error reading curve header", crv
		      exit
	      }

        if (split(ans, curve, ",") != 5) {
		      eprint "Funny answer from controller at curve", crv "."
		      continue
	      }

        printf(fmt, crv, curve[0], curve[1], curve_units[curve[2]], \
          curve[3], curve_coeff[curve[4]])
      }
#      if ( crv < 61 && !yesno("Continue", 1)) break
    }
    printf("\nPlease choose a number to use to load a curve into with the lswritecurve macro\n")
  }
}'

#%UU%
#%MDESC%
# Syntax : lswritecurve [filename] [curvenumber]%BR%
# Reads one sensor calibration curve from harddisk and writes it into the
# lakeshore temperature controller. Only curves 21 to 60 can be written by the user.
# %BR%
#%B%EXAMPLE:%B%%BR%
#%PRE%
#Sensor Model:   CX-1030-CU-1.4L
#Serial Number:  X12379
#Data Format:    4      (Log Ohms/Kelvin)
#SetPoint Limit: 325.      (Kelvin)
#Temperature coefficient:  1 (Negative)
#Number of Breakpoints:   144
# .....
#%PRE%
def lswritecurve '{
	local i, j, ii, dummy, crv, fname
	local curve[], textline, field[], ans

	if ($# == 0) {
    print "Use macro lslistallcurves to get a list of already stored curves!"
		crv   = getval("Number of curve to be written?",21)
		fname = getval("Filename of temperature curve?","X12379.340")
	} else if ($# == 2) {
		crv = $2
		fname = "$1"
	} else {
    print "Please give two or no args, first filename, then curve number"
    exit
  }
	if (crv < 21) {
		eprint "Curve number out of range."
		eprint "Only curves 21 to 60 may be written by the user."
		exit
	}
	if (!file_info(fname)) {
		eprint "File: ",fname,"does not exist!"
		exit
	}

  # this reads the existing entry
  {
    local ans
	  curve_units[1] = "mV/K"
	  curve_units[2] = "V/K"
	  curve_units[3] = "Ohm/K"
	  curve_units[4] = "log(Ohm)/K"
	  curve_units[5] = "log(Ohm)/log(K)"

	  curve_coeff[1] = "negative"
	  curve_coeff[2] = "positive"

    fmt = "%2s %-15s %-10s %-10s %-10s %-10s\n"

	  print "Readings from actual curve", crv, "in LakeShore tc :"
	  ans = _ls_read(sprintf("CRVHDR? %d",crv))
	  if(ans == "LSREADERROR"){
		  eprint "Error reading curve header", crv
		  exit
	  }

    if (split(ans, curve, ",") != 5) {
		  eprint "Funny answer from controller for curve", crv "."
		  exit
	  }

    printf(fmt, "", curve[0], curve[1], curve_units[curve[2]], \
      curve[3], curve_coeff[curve[4]])
  }

  # scan in the informations from the head of the .340 file.
  {
    local stype, sernum, dfmt, sp_lim, coeff, npts
    dfmt = sp_lim = coeff = npts = -1
	  open(fname)
	  i = 0
    textline = getline(fname, 0)
	  while(1) {
      if (split(textline, field, ":") == 1)  break # no : stop!
      # treat contents here, is that a new yacc :-)
      if (field[0] == "Sensor Model")             sscanf(field[1], "%s", stype)
      if (field[0] == "Serial Number")            sscanf(field[1], "%s", sernum)
      if (field[0] == "Data Format")              sscanf(field[1], "%d", dfmt)
      if (field[0] == "SetPoint Limit")           sscanf(field[1], "%f", sp_lim)
      if (field[0] == "Temperature coefficient")  sscanf(field[1], "%d", coeff)
      if (field[0] == "Number of Breakpoints")    sscanf(field[1], "%d", npts)
      textline = getline(fname)
    }

    # Some input checking on Rudolfs request
    if (stype == "") {
      eprint "Data file", fname, "does not have expected line for \"Sensor Model\"!"
      eprint "Aborted !"
      exit
    } else if (sernum == "") {
      eprint "Data file", fname, "does not have expected line for \"Serial Number\"!"
      eprint "Aborted !"
      exit
    } else if (dfmt == -1) {
      eprint "Data file", fname, "does not have expected line for \"Data Format\"!"
      eprint "Aborted !"
      exit
    } else if (sp_lim == -1) {
      eprint "Data file", fname, "does not have expected line for \"SetPoint Limit\"!"
      eprint "Aborted !"
      exit
    } else if (coeff == -1) {
      eprint "Data file", fname, "does not have expected line for \"Temperature coefficient\"!"
      eprint "Aborted !"
      exit
    }

    dummy = sprintf("CRVDEL %d\r\n", crv)
	  ans = _ls_send(dummy)
	  if(ans != "LSOK"){
		  eprint "Error deleting curve number ", crv "."
		  exit
	  }

    dummy = sprintf("CRVHDR %d,%s,%s,%d,%f,%d\r\n", crv, sernum,\
      stype, dfmt, sp_lim, coeff)
	  ans = _ls_send(dummy)
	  if(ans != "LSOK"){
		  eprint "Error listing curve number ", crv "."
		  exit
	  }
  }
  # Well now, to enable for Rudolf to add a header to a simple 2-column file, we have
  # to juggle with sscanf.
  {
    local loop, ii, valunits, val_temp
    loop = 1 # index of point, valid entries 1 - 200
	  while((textline = getline(fname)) != -1) {
      if (sscanf(textline, "%d %g %g", ii, valunits, val_temp) == 3) {
        if (ii == 0 && valunits == 0 && val_temp == 0)
          continue
      } else if (sscanf(textline, "%g %g", valunits, val_temp) == 2) {
        if (valunits == 0 && val_temp == 0)
          continue
      } else {
        continue # thats probably a text line. just forget
      }

	    dummy = sprintf("CRVPT %d,%d,%1.14f,%1.14f\r\n", crv, loop, valunits, val_temp)
	    ans = _ls_send(dummy)
	    if(ans != "LSOK"){
		    eprint "Error listing curve number ", crv "."
		    exit
	    }
      printf(".")
      loop ++
    }
    print
  }

	close(fname)

  print
	print "Curve", crv, "was written to the LakeShore temperature controller."; print

  # this reads the new entry
  {
    local ans
	  curve_units[1] = "mV/K"
	  curve_units[2] = "V/K"
	  curve_units[3] = "Ohm/K"
	  curve_units[4] = "log(Ohm)/K"
	  curve_units[5] = "log(Ohm)/log(K)"

	  curve_coeff[1] = "negative"
	  curve_coeff[2] = "positive"

    fmt = "%2s %-15s %-10s %-10s %-10s %-10s\n"

	  print "Readings from curve", crv, " in LakeShore tc :"
	  ans = _ls_read(sprintf("CRVHDR? %d",crv))
	  if(ans == "LSREADERROR"){
		  eprint "Error reading curve header", crv
		  exit
	  }

    if (split(ans, curve, ",") != 5) {
		  eprint "Funny answer from controller for curve", crv "."
		  exit
	  }

    printf(fmt, "", curve[0], curve[1], curve_units[curve[2]], \
      curve[3], curve_coeff[curve[4]])
  }

	print "Warning: The curve was not saved to the flash memory of the LakeShore tc."

  if (yesno("Do you want to save it ", 1)) {
	    ans = _ls_send("CRVSAV")
	    if(ans != "LSOK"){
		    eprint "Error saving curve number ", crv "."
		    exit
	    } else {
        eprint "Saved curve number ", crv "."
      }
  } else {
    print "Curve", crv, "is not saved yet!!!"; print
    print "To do so execute the command: _ls_send(\"CRVSAV\")"
    print "This will save all changes you made to curves since the controller was switched on."
    print "Otherwise all changes will be lost after it is switched off."
  }

    print "To do so execute the command: _ls_send(\"CRVSAV\")"
    print "This will save all changes you made to curves since the controller was switched on."
    print "Otherwise all changes will be lost after it is switched off."
    print

    print "To make sure the curve was written correctly check it on the front panel"
}'

#%UU%
#%MDESC%
# Syntax : lsreadcurve [curvenumber]%BR%
# Reads one sensor calibration curve from lakeshore temperature controller.
# %BR%
def lsreadcurve '{
	local i, j, ii, dummy, crv, fname
	local curve[], textline, field[], ans

	if ($# == 0) {
    print "Use macro lslistallcurves to get a list of already stored curves!"
		crv   = getval("Number of curve to be written?",21)
		fname = getval("Filename of temperature curve?","X12379.340")
	} else if ($# == 1) {
		crv = $1
	} else {
    print "Please give one or no args"
    exit
  }

  # this reads the existing entry
  {
    local ans
	  curve_units[1] = "mV/K"
	  curve_units[2] = "V/K"
	  curve_units[3] = "Ohm/K"
	  curve_units[4] = "log(Ohm)/K"
	  curve_units[5] = "log(Ohm)/log(K)"

	  curve_coeff[1] = "negative"
	  curve_coeff[2] = "positive"

    fmt = "%2s %-15s %-10s %-10s %-10s %-10s\n"

	  print "Readings from curve", crv, "in LakeShore tc :"
	  ans = _ls_read(sprintf("CRVHDR? %d",crv))
	  if(ans == "LSREADERROR"){
		  eprint "Error reading curve header", crv
		  exit
	  }

    if (split(ans, curve, ",") != 5) {
		  eprint "Funny answer from controller for curve", crv "."
		  exit
	  }

    printf(fmt, "", curve[0], curve[1], curve_units[curve[2]], \
      curve[3], curve_coeff[curve[4]])
  }

  # Well now, to enable for Rudolf to add a header to a simple 2-column file, we have
  # to juggle with sscanf.
  {
    local loop, ii, valunits, val_temp
	  for (loop = 1 ; loop <= 200 ; loop ++) {

      printf("%3d  ", loop)
	    dummy = sprintf("CRVPT? %d,%d\r\n", crv, loop)
	    ans = _ls_read(dummy)
	    if(ans == "LSREADERROR"){
		    eprint "Error listing curve point ", loop "."
		    exit
	    } else
        print ans
    }
    print
  }
}'

#%MACROS%
#%IMACROS%
#%AUTHOR% Holger Witsch, November 2004