esrf

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

#%TITLE% OXITCSWEEP.MAC
#%NAME% 
#  Macros for Oxford ITC503 Temperature controller. (sweep features)
#
#%CATEGORY% Temperature
#%DESCRIPTION%
# Those macros provide users with the Oxford ITC internal sweep feature access.
#%END%

#---------------------------------------------------------------- OXFORD SWEEPS


#%UU% <startstep> <endstep> <seconds> [flag]"
#%MDESC% Handles a sweep.%BR%
# The steps are between 1 and 32, according to what was input to %B%oxswprog%B% macro; The macro starts the sweep and eventually SPEC counters, and loop reporting counters value till the end of the sweep, to the screen, and eventually to a disk file, if one has been opened using %B%oxswnewfile%B% macro. %B%oxsweep%B% sleeps the specified seconds at each loop turn. The flag can take one of the following values:%BR%
#%UL%
#%LI% 0: The counters value are simply reported at each loop turn"
#%LI% 1: The counters value are integrated while sleeping"
#%LI% 2: The counters value are integrated all along the sweep"
#%XUL%
#The command applies to the current Oxford device.
def oxsweep '{
global OXSWPTS 
local start end delay flag fname tottime
local oswp swp zz stat _time

if (3>$#) {
  print "usage: $0 startstep endstep seconds [0|1|2]"
  print "[0]: The counters value are simply reported"
  print "[1]: The counters value are integrated during sleepsec seconds"
  print "[2]: The counters value are integrated all along the sweep"
  exit
}
start = $1
end  = $2?$2:16
delay = $3
flag = $4

if (OX_FILE) fname=OX_FILE
else fname = "/dev/null"

for (tottime=0,i=start;i<=end;i++) tottime += (OXSW2[i]+OXSW3[i])
tottime*=60

HEADING = "$0 $*"

OX_N = savestdheader(fname,4,OX_N)
print "-----------------"
fprintf(fname,"#C OX DEVICE %s\n",OX_NAME[OXX])
oxstat
sscanf(OX_RESP,"%1s%d%1s%d%1s%d%1s%d%1s%d%1s%d",zz,zz,zz,                                    stat[0],zz,stat[1],zz,swp,zz,stat[2],zz,stat[3])
fprintf(fname,"#C OX HEATER %s\n",(stat[0]-(stat[0]<2?0:2))?"AUTO":"MANUAL")
fprintf(fname,"#C OX GAS %s\n",(stat[0]<2?0:2)?"AUTO":"MANUAL")
fprintf(fname,"#C OX COM %s & %s\n",(stat[1]-(stat[1]<2?0:2))?"REMOTE":"LOCAL",(stat[1]<2?0:2)?"UNLOCKED":"LOCKED")
fprintf(fname,"#C OX SENSOR %d\n",stat[2])
fprintf(fname,"#C OX AUTOPID %d\n",stat[3])

print "-----------------"
oxpar
fprintf(fname,"#C OX PID %g %g %g\n",ox_iof("R8"),ox_iof("R9"),ox_iof("R10"))

fprintf(fname,"#C OX L  EPOCH  ")  
for (i=0;i<COUNTERS;i++) {
  if (counter_par(i,"disable") == 0) {
    fprintf(fname,"%s  ",cnt_name(i))
  }
}
fprintf(fname,"\n")
print "-----------------"
print "OXFORD: you can exit that sweep monitoring typing control-C"
print "        what will NOT stop the sweep"
print "        -> using file:",OX_FILE

cdef("user_cleanup2","oxsw_cleanup","oxswcl",0)

oxswstart start
if (flag==2) {
  count_em tottime + 1
}

for (OXSWPTS=0;;OXSWPTS++) {
  swp=ox_stat(OXX,"S")
  if (!swp) {
    print "-----------------"
    if (!oswp) print "NO SWEEP CURRENTLY RUNNING"
    else {
      oxsw_cleanup
      print "SWEEP OVER"
    }
    break
  } else if (swp!=oswp) {
    print "-----------------"
    zz=swp/2+0
    if (zz>end) {
      print "SWEEP ENDED"
      oxsw_cleanup
      break
    } 
    if (zz==int(zz)) printf("HOLDING AT STEP %d\n",swp)
    else                 printf("SWEEPING TO STEP %d\n",swp)
    
    oswp=swp
    print
    printf("Time ")
    for (i=0;i<COUNTERS;i++) {
      if (counter_par(i,"disable") == 0) {
        printf("%s ",cnt_name(i))
      }
    }
    print
  } 
  if (flag!=1) sleep(delay)
  else {
    count_em delay
    waitcount
  }
  getcounts
  on(fname)
  printf("%g ",_time=time()-OX_EPOCH)
  for (i=0;i<COUNTERS;i++) {
    if (counter_par(i,"disable") == 0) {
      printf("%g ",S[i])
    }
  }
  printf("\n")
  off(fname)
  oxsw_plot
}
}'

def oxsw_cleanup '{
  oxswstop
  if (ox_timeout("X", "S", 0)) {
    print "maximum heater voltage at",OXSW4O,"V..."
  } else {
    print "setting maximum heater voltage back to",OXI_VOLT[OXX],"V..."
    ox_iof (OXX,sprintf("\$M%d", OXI_VOLT[OXX]*10) )
  }
  cdef("","","oxswcl","delete")
}'

#%IU%
#%MDESC% Plot selected counter vs/time
def oxsw_plot '{
global OXSWGRP
local _npts _i

_npts = OXSWPTS
if (PLOT_MODE&2048) {
  OXSWGRP = groupinit (OXSWGRP,4096,PLOT_NO+1)
  data_put(OXSWGRP, _npts, 0,_time)
  for (_i=0;_i<PLOT_NO;_i++) data_put(OXSWGRP, _npts, _i+1,S[PLOT_LIST[_i]])
} else {
  OXSWGRP = groupinit (OXSWGRP,4096,2)
  data_put(OXSWGRP, _npts, 0,_time)
  data_put(OXSWGRP, _npts, 1,S[DET])
}

if (PLOT_MODE&2048 &&  Y_L == cnt_name(DET)) Y_L = cnt_name(PLOT_LIST[0])

if (PLOT_MODE&128) {
  plot_cntl(sprintf("colors=%s",rplot_col))
  plot_cntl("open")
}

if (_npts == 0) {
  plot_cntl("erase")
  plot_range(_sx,_fx,YMIN,"auto")
  plot_move(0,1,T_L)
  plot_move(0,2,Y_L)
  plot_move(0,-1,sprintf("%.8s", X_L))
}
plot_cntl("addpoint")
data_plot(OXSWGRP,0,0,"all")
plot_move(0,0)
}'

#%UU% [internal-flag]
#%MDESC%
#Records a sweep program into the controller memory. You must be in remote control with no sweep running to be allowed to do it. It asks for the following parameters 16 times for one sweep, which is 32 steps:
#%UL%
#%LI%temperature setpoint value, common to 2 consecutive steps.
#%LI%sweep time to setpoint in minutes, for odd numbered steps.
#%LI%hold time at setpoint in minnutes, for even numbered steps.
#%XUL%
#Fill in with 0 the steps you don't use.%BR%
#Only one sweep program is held in the controller at the same time.%BR%
#It is possiblre to save it to a disk file. see macro%B% oxswsave%B%.
#The command applies to the current Oxford device.
def oxswprog '{

global OX_SW_FILE OXSW1 OXSW2 OXSW3 OXSW4
local st1 st2 cmd num2 num1
local cmd zz remlock swp

print;printf("OXFORD ITC %d:\n\n",OXX+1)

ox_iof(OXX,"X")
sscanf(OX_RESP,"%[^C]C%d%[^S]S%d",zz,remlock,zz,swp)
if (!(remlock&1)) {
  print "OXFORD: LOCAL CONTROL- Not allowed to program a sweep"
  exit
}
if (swp) {
  print "OXFORD: Sweep already running- Not allowed to program another sweep"
  if (swp/2==int(swp/2)) printf("OXFORD SWEEP: holding at step %d\n",swp)
  else printf("OXFORD SWEEP: sweeping to step %d\n",swp)
  exit
}
if ("$1"!="oxswload") {
  for (i=0;i<16;i++) {
    printf("STEP %d\n",i*2+1)
    OXSW1[i]=getval(" temperature setpoint value",OXSW1[i])
    OXSW2[i]=getval(" sweep time to setpoint in min.",OXSW2[i])
    printf("STEP %d\n",i*2+2)
    OXSW3[i]=getval(" hold time at setpoint in min.",OXSW3[i-1])
    OXSW4[i]=getval(" maximum heater output voltage.",OXSW4[i-1]?OXSW4[i-1]:OXI_VOLT[OXX])
  }
}

printf ("OXFORD: currently programming the controller ")
for (i=1;i<=16;i++) {
  ox_iof(OXX,sprintf("\$x%d",i)); 
  ox_iof(OXX,"\$y1");  ox_iof(OXX,sprintf("\$s%s",OXSW1[i-1])); 
  ox_iof(OXX,"\$y2");  ox_iof(OXX,sprintf("\$s%s",OXSW2[i-1])); 
  ox_iof(OXX,"\$y3");  ox_iof(OXX,sprintf("\$s%s",OXSW3[i-1]));  
  printf(".")
}
ox_iof(OXX,"\$x0");ox_iof ("\$y0")
printf ("\n        done\n")
 

if (("$1"!="oxswload") &&                                                           yesno("        Do you want to save this sweep program to a file",1)) { 
  printf("        ")
  oxswsave 
}
}'

#%UU% [num] [minutes] [setpoint] [max_voltage]
#%MDESC%
#Changes one sweep step record in the controller memory. You must be in remote control with no sweep running to be allowed to do it. 
#The command applies to the current Oxford device.
def oxswstep '{

local zz remlock swp num 

print;printf("OXFORD ITC %d:\n\n",OXX+1)
ox_iof(OXX,"X")
sscanf(OX_RESP,"%[^C]C%d%[^S]S%d",zz,remlock,zz,swp)
if (!(remlock&1)) {
  print "OXFORD: LOCAL CONTROL- Not allowed to program a sweep"
  exit
}
if (swp) {
  print "OXFORD: Sweep already running- Not allowed to program another sweep"
  if (swp/2==int(swp/2)) printf("OXFORD SWEEP: holding at step %d\n",swp)
  else printf("OXFORD SWEEP: sweeping to step %d\n",swp)
  exit
}

swp=getval("STEP number",$1)
num=(swp/2==int(swp/2))?swp/2-1:int(swp/2)
ox_iof(OXX,sprintf("\$x%d",num+1)); 
OXSW1[num]=getval(" temperature setpoint value",$#>2?$3:OXSW1[num])
ox_iof(OXX,"\$y1");  ox_iof(OXX,sprintf("\$s%s",OXSW1[num])); 
if (swp/2==int(swp/2)) {
  OXSW3[num]=getval(" hold time at setpoint in min.",$#>1?$2:OXSW3[num])
  ox_iof(OXX,"\$y3");  ox_iof(OXX,sprintf("\$s%s",OXSW3[num]));  
} else {
  OXSW2[num]=getval(" sweep time to setpoint in min.",$#>1?$2:OXSW2[num])
  ox_iof(OXX,"\$y2");  ox_iof(OXX,sprintf("\$s%s",OXSW2[num])); 
}

OXSW4[num]=getval(" maximum heater output voltage.",$#>3?$4:(OXSW4[num]?OXSW4[num]:OXI_VOLT[OXX]))

ox_iof(OXX,"\$x0");ox_iof ("\$y0")
printf ("\n        step %d done\n",swp)
 
if (yesno("        Do you want to save this sweep program to a file",1)) { 
  printf("        ")
  oxswsave 
}
}'


#%UU%
#%MDESC%
#Prints out the sweep program held in the controller memory.
#The command applies to the current Oxford device.
def oxswread '{

local cmd

print;printf("OXFORD ITC %d:\n\n",OXX+1)

print "SWEEP"
print "| STEPS | SET  POINT | SWEEP TIME | HOLD  TIME | MAX HEAT V.|"

for (i=1;i<=16;i++) {
  ox_iof (OXX,sprintf("x%d",i))
  ox_iof(OXX,"y1") ; ox_iof ("r") ; OXSW1[i-1]=substr(OX_RESP,2); 
  ox_iof(OXX,"y2") ; ox_iof ("r") ; OXSW2[i-1]=substr(OX_RESP,2); 
  ox_iof(OXX,"y3") ; ox_iof ("r") ; OXSW3[i-1]=substr(OX_RESP,2);
  printf("| %2d %2d | %10f | %10f | %10f | %10f |\n",i*2-1,i*2,OXSW1[i-1],OXSW2[i-1],OXSW3[i-1],OXSW4[i-1])
}
ox_iof(OXX,"\$x0");  ox_iof (OXX,"\$y0")
}'



#%UU% [filename]
#%MDESC% 
#Saves the current sweep program to a disk file.
def oxswsave '{

if (!$#) {
  OX_SW_FILE=getval("Disk file name where to save sweep",OX_SW_FILE)
  if (!unix(sprintf("test -r %s",OX_SW_FILE)) &&                                     !yesno ("That File exists; Overwrite",0)) {
     printf ("Nothing done")
     exit
  }
} else OX_SW_FILE="$1"

unix(sprintf("/bin/rm -f %s",OX_SW_FILE))

printf("---------- SAVED SWEEP PARAMETERS ----------\n")
printf("| NO | SET  POINT | SWEEP TIME | HOLD  TIME | MAX HEAT V.|\n",i)
on(OX_SW_FILE)
for (i=0;i<16;i++) {
  printf("| %2d | %10f | %10f | %10f | %10f |\n",i+1,OXSW1[i],OXSW2[i],OXSW3[i],OXSW4[i])
}
close(OX_SW_FILE)
}'

#%UU% [filename]
#%MDESC%
#Reads in a sweep program from a previously saved disk file and eventually records it into the controller memory.
#The command applies to the current Oxford device.
def oxswload '{

local line val

if (!$#) OX_SW_FILE=getval("Disk file name to load sweep from",OX_SW_FILE)
else OX_SW_FILE="$1"

printf("---------- LOADED SWEEP PARAMETERS ----------\n")
printf("| STEPS | SET  POINT | SWEEP TIME | HOLD  TIME | MAX HEAT V.|\n",i)

for (line=getline(OX_SW_FILE),i=0;line!=-1;line=getline(OX_SW_FILE)) {
  split(line,val)
  OXSW1[i]=val[3]
  OXSW2[i]=val[5]
  OXSW3[i]=val[7]
  OXSW4[i]=val[9]
  printf("| %2d %2d | %10f | %10f | %10f | %10f |\n",i*2+1,i*2+2,OXSW1[i],OXSW2[i],OXSW3[i],OXSW4[i])
  i++
}
getline(OX_SW_FILE,"close")

print;printf("OXFORD ITC %d:\n\n",OXX+1)
if (yesno("Do you want to record this sweep into the controller",1)) { 
  oxswprog "$0"
}
}'

#%UU% [step_no]
#%MDESC%
#Starts a sweep program.%BR%
#You can give as argument the step number at which you want to start sweeping, default being 1. Allowed step numbers are from 1 to 32. 
#The command applies to the current Oxford device.
def oxswstart '{
local stp zz 
print;printf("OXFORD ITC %d:\n\n",OXX+1)
stp=$1?$1:1
ox_iof (OXX,sprintf("S%d",stp))
if (ox_timeout("X","S",stp)>0) \
     printf("OXFORD: Sweep started at step %d\n",stp) 
else {
  printf("OXFORD: No Sweep started\n")
  exit
}
}'

#%UU%
#%MDESC%
#Stops a running sweep.
#The command applies to the current Oxford device.
def oxswstop '{ 
  ox_iof(OXX,"S0") 
  printf("OXFORD ITC %d sweep stopped.\n\n",OXX+1)
}'


#%UU% [interval] 
#%MDESC% Prints out parameters during sweep execution 
#The command applies to the current Oxford device.
def oxswmon '{
 
local oswp swp zz delay 

delay = $1

print "-----------------"
oxstat
print "-----------------"
oxpar
print "-----------------"
print "OXFORD: you can exit that sweep monitoring typing control-C"
print "        what will NOT stop the sweep"
print "        -> using file:",OX_FILE

for (;;sleep(delay)) {
  swp=ox_stat(OXX,"S")
  if (!swp) {
    print "-----------------"
    if (!oswp) print "NO SWEEP CURRENTLY RUNNING"
    else print "SWEEP OVER"
    break
  } else if (swp!=oswp) {
    print "-----------------"
    zz=swp/2+0
    if (zz==int(zz)) printf("HOLDING AT STEP %d\n",swp)
    else                 printf("SWEEPING TO STEP %d\n",swp)
    oswp=swp
    print
    printf("%-10s %-10s %-10s %-10s %-10s %-10s %-10s\n",                                             "SETPT","T1","T2","T3","HEAT (%)","HEAT (V)","GAZ")
  } 
  for (i=0;i<=7;i+=(i==3)?2:1) {
    ox_iof(OXX,sprintf("R%d",i))
    printf("%-10g ",substr(OX_RESP,2))
  }
  printf("\n")
}
}'

#%UU% [filename] [sweep_no]
#%MDESC% Opens the file where to store sweep data. The sweep data are typically temperatures, voltages and others counters values.%BR%
# The file format is the standard scans file one, added specific Oxford information as described here:%BR%
#%DL%
#%DT% #S 1  oxsweep 1 2 30
#%DD% first of all, the #S index here is coherent with a sweep number.
#%DT% #C OX HEATER MANUAL
#%DD% Heater control mode: could have been AUTO
#%DT% #C OX GAS MANUAL
#%DD% Gaz flow control mode: could have been AUTO
#%DT% #C OX COM REMOTE & UNLOCKED
#%DD% Communication status: could have been LOCAL & LOCKED
#%DT% #C OX SENSOR 1
#%DD% Sensor used to eventually feed back the heater control loop; out of 1, 2 or 3
#%DT% #C OX AUTOPID 0
#%DD% If 1, indicates that the Learnt Auto-PID values internal table is used, otherwise, fixed PID values are used.
#%DT% #C OX PID 0 0 0 
#%DD% This is the fixed PID values, set by command %B%oxPID%B%.
#%DT% #C OX L  EPOCH  Seconds  Counter  TEMP1  
#%DD% 2 blank-characters separated list of counter names which values are listed as data, respectively to this kind of column header.  
#%XDL% 
def oxswnewfile '{
global OX_FILE OX_N
local oldfile

oldfile = OX_FILE

if ($#) OX_FILE = "$1"
else    OX_FILE = getval("OXFORD file name",OX_FILE)

if ($# > 1) 
    OX_N = $2
else
    OX_N = 0

if (OX_FILE == "0")    OX_FILE=""
if (OX_FILE == "null") OX_FILE="/dev/null"
if (OX_FILE == "tty")  OX_FILE="/dev/tty"

if ((OX_FILE != "") && (OX_FILE != "/dev/null")) {

  if (!index(OX_FILE, "/") && !unix(sprintf("test -d %s",DATA_DIR)))
    OX_FILE = sprintf("%s/%s",DATA_DIR,OX_FILE)

  if ((OX_FILE != "/dev/tty") && !unix(sprintf("test -r %s >/dev/null 2>&1",OX_FILE))) {
    printf("OXFORD file %s exists \n",OX_FILE)
    OX_N = getval ("       last sweep number",OX_N)
  } else {
    OX_N = 0
#    constant OX_EPOCH 
    savefileheader(OX_FILE,1)
  }
  if (oldfile && (oldfile != "/dev/tty") && (oldfile!=OX_FILE)) close (oldfile)
}

print "OXFORD: Using file",OX_FILE,", Next sweep number is",OX_N+1

}'

#%MACROS%
#%IMACROS%
#%DEPENDENCIES%
#  - The file %B%oxITCsweep.mac%B% has to be read in. It uses %B%ox.mac%B%, %B%saveload.mac%B%.
#%AUTHOR%
#  OXITCSWEEP.MAC - Marie-Claire LAGIER - 96/04/24
#%TOC%