esrf

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

#%TITLE% SAVELOAD.MAC 
#%NAME%
# Standard and general SPEC data saving/loading facility. 
#%DESCRIPTION%
# These macros functions provide programmers with the basic data saving possibilities. The standard scan format is kept and added something special for MCA data, including spectrum re-loading. Each macro function deals with a particular set of information or data. 
#%END%d

def savefileheader(file,flag) '{

# ?? savefileheader: local epoch

if (file=="" || file == "0" || open(file)) return -1

#epoch=time()

fprintf(file,"#F %s\n", file)
#fprintf(file,"#E %d\n",epoch)
fprintf(file,"#E %d\n",EPOCH)
fprintf(file,"#D %s\n",date())
fprintf(file,"#C %s  User = %s\n",TITLE,USER)

if (!flag) {
  for (i = 0; i < MOTORS; i += 8) {
    fprintf(file,"#O%d ", i/8)
    for (j = i; j < i + 8 && j < MOTORS; j++)
      if (motor_name(mA[j]) != "unused") \ 
        fprintf(file,"%8s  ", motor_name(mA[j]))
    fprintf(file,"\n")
  }
}
return 0
}'

#%UU% (file,flag,lastindex) 
#%MDESC% Writes to file something close to the standard scan header, using the same syntax, e.g.:
#%PRE%
#	#S 3  ct 0.2
#	#D Mon Nov 20 15:37:58 1995
#	#T 0.2  (Seconds)
#	#G1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#	#Q 
#	#P0 10 112.64444 -27 
#%PRE%
# The <flag> has the following meaning:
#%UL%
#%LI% 0x01 : save #T/#M info ( COUNT_TIME )
#%LI% 0x02 : save #P Motor positions
#%LI% 0x04 : do not save #G, #U, and #M geo parameters
#%XUL%
# The <lastindex> incremented by one is written in place of scan number and returned by the function. The command and the date are held respectively by the variables HEADING and DATE. 
#%PRE% Example :
# SCAN_N=savestdheader(DATAFILE,3,SCAN_N) 
#	would increments scan number and writes down to standard scan file 
#	the information as described above.
#%PRE%
def savestdheader(file,flag,lastindex) '{
if (open(file)) return (-(lastindex+1))
if (file!="") {

  fprintf(file,"\n#S %d  %s\n#D %s\n",++lastindex,HEADING,DATE)

  if (flag&1) {    
    if (COUNT_TIME<0) fprintf(file,"#M %g  (%s)\n", -COUNT_TIME,cnt_name(MON))
    else fprintf(file,"#T %g  (%s)\n", COUNT_TIME,cnt_name(sec))
  }

  if (!(flag&4)) {
    on(file); offt; _head_par G 0; _head_par U 1; _head_par M 2; ont; off(file)
  }

  if (flag&2) {
    local i j k
    fprintf(file,"#Q %s\n", _hkl_val) 
    for (i = 0, k = MOTORS; i < k; i += 8) {
      fprintf(file,"#P%d ", i/8)
      on(file) ; offt; _mo_loop .8g "A[mA[j]]" ; ont; off(file) 
    }
  }
} else lastindex++

return(lastindex)
}'

def savemot '{
    for (i = 0, k = MOTORS; i < k; i += 8) {
      on(DATAFILE) ; offt 
      print 
      qcomment "Saving motor positions"
      fprintf(DATAFILE,"#UMOTNAME%d ", i/8)
      _mo_loop ".8s  " "motor_name(j)" 
      fprintf(DATAFILE,"#UMOTPOS%d ", i/8)
      _mo_loop .8g "A[mA[j]]" 
       ont; off(DATAFILE) 
    }
}'

def savecnt '{
   savemot
   for (i = 0, k = COUNTERS; i < k; i += 8) {
      fprintf(DATAFILE,"#UCTNAME%d ", i/8)
      on(DATAFILE) ; offt; _mo_loop ".8s  "  "cnt_name(j)" ; ont; off(DATAFILE) 
      fprintf(DATAFILE,"#UCTVALS%d ", i/8)
      on(DATAFILE) ; offt; _mo_loop .8g "S[j]" ; ont; off(DATAFILE) 
   }
}'

#%UU% (file)
#%MDESC% Writes to <file> the number and list of counters configured, as it is done when scanning, e.g:
#%PRE%
#	#N 6
#	#L  Seconds  MM/CC  MCAA  MCA  Counter 4  Counter 5
#%PRE%
def savecntheader (file) '{

local i j g

if (file!="") {
  if (open(file)) return -1
  on (file); offt
  Fheader

  g = _ctime < 0? sec:MON

  for (i=j=0;i<COUNTERS;i++) if (i!=g && i!=DET && is_using_counter(i)) j++

  fprintf(file,"#N %d\n", _cols + (MON<0? 2:3) + j)
  fprintf(file,"#L %s%sEpoch",FPRNT,Flabel)

  for (i=0;i<COUNTERS;i++) if (i!=g && i!=DET && is_using_counter(i)) \
    fprintf(file,"  %s",cnt_name(i))

  if (g >= 0) fprintf(file,"  %s",cnt_name(g))
  fprintf(file,"  %s\n",cnt_name(DET))
  off (file); ont
}
return 0
}'




#%UU% (file,fmt,npts,fch,lch,red,pst,elt,ert)
#%MDESC% Writes to <file> some information relevant for a MCA,i.e.:
#%PRE%
# fmt: 	data_dump() format, e.g. "%16C"
# npts:	number of points dumped down
# fch: 	first channel saved
# lch: 	last channel saved
# red: 	data reduction coefficient
# pst:	preset time
# elt:	elapsed live time
# ert: 	elapsed real time
#
# The saved data looks like the following:
#
#	#@MCA %16C		as for dump format
#	#@CHANN 10 1250 1260 1	as for no of chans, fst, lst, reduc coeff 
#	#@CTIME 1 0.49 1	as for preset time, elapsed live time, -real-
#%PRE%
def savemcaheader(file,fmt,npts,fch,lch,red,pst,elt,ert) '{
if (open(file)) return -1
if (file!="") {
    fprintf(file,"#@MCA %s\n",fmt)
    fprintf(file,"#@CHANN %g %g %g %g\n",npts,fch,lch,red)
    fprintf(file,"#@CTIME %g %g %g\n",pst,elt,ert)
}
return 0
}'



#%UU% (file,a,b,c)
#%MDESC% Writes to <file> the MCA calibration fit parameters such as CALIBRATION = a + b*CHANNEL + c*CHANNEL^2 .
# What is saved data looks like the following:
#%PRE%
#	#@CALIB  0 1 0 as for a b c calibration parameters (see above)
# %PRE%

def savemcacalib(file,a,b,c) '{
if (open(file)) return -1
if (file!="") fprintf(file,"#@CALIB  %g %g %g \n",a,b,c)
return 0
}'

#%UU% (file,fch,lch,name)
#%MDESC% Writes to <file> the current MCA ROIs definition. Looks like this:
#%PRE%
#	#@ROI  MCAA  1250  1300		as for roi name, fst and lst channels
#%PRE%
def savemcaroi(file,fch,lch,name) '{
if (open(file)) return -1
if (file!="") fprintf(file,"#@ROI  %s  %g  %g\n",name,fch,lch)
return 0
}'

#%UU% (file)
#%MDESC% Writes to <file> the contents of S[] array on 1 data line. %BR%
#e.g. : 
#%PRE%
#	0.199 62 62 0 0 0 
#%PRE%
def savecounters(file) '{
if (open(file)) return -1
if (file!="") {
    for(i=_sl_j=0;i<COUNTERS;i++) 
      if (is_using_counter(i)) fprintf(file,"%g ",S[i]);
    fprintf(file,"\n")
}
return 0
}'

def savecounters(file) '{
if (file!="") {

  local z

  if (open(file)) return -1

  fprintf(file,"%s%s%d",FPRNT,Fout,time()-EPOCH)

  z = _ctime < 0? sec:MON

  for (i=0;i<COUNTERS;i++)
    if (i != z && i != DET && is_using_counter(i))
      fprintf(file," %g",S[i])
  if (z >= 0) fprintf(file," %g",S[z])
  fprintf(file," %g\n",S[DET]);
}
return 0
}'

#%UU% (file,data,size,fmt)
#%MDESC% Writes to <file> the MCA spectrum held by <data> array, using the format <fmt> coherant to data_dump() function. That function needs to know the size, or number of points to be dumped. The output migth look like the following: (format 16C, for cplot)%BR%
#%PRE%
#	@A 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0\
#	 0 0 32 30 0 0 0 0 0 0 0 0 0 0 0 0\
#	 0 
#%PRE%
def savemcadata(file,data,size,fmt) '{
if (file!="") {
  if (open(file)) return -1  

  fprintf(file,"@A ")
  on(file);offt;data_dump(data,fmt);off(file);ont
#ID18 OFFD NOT NEEDED CAUSE ALREADY OFF AT THAT POINT. SEE _loop !!! 
#on(file);offt;offd;data_dump(data,MCA_FMT);off(file);ont
  return 0
}
return -1
}'

#%UU% <file> <array_name> <column> <scan_no> <scan_pt_no> <mode> <out1> <out2> <out3> <out4>
#%MDESC% Reads from <file> and loads into mca <array_name>[][<column>] the MCA spectrum referrenced by its scan number and eventually its scan point number. <mode = 1> means that the calibration parameters are read from the file together with the data and reported in <out4> string (like "a b c", for E = a + b*ch + c*ch^2). <out1> and <out2> returns the absolute first and last channels and <out3> the reduction coefficient.
def loadmcadata '{

  local file _elem _sno _spno _calib 
  local _line _tok _ind _idx _nn 
  local fch lch rnpts red cal calstr
  
  local offs
  local lea leb lec lwa lwb lwc 

  file="$1"; _elem=$3; _sno=$4?$4:1; _spno=$5?$5:1; _calib=$6
  
  if (getline(file,"open") == -1) {
    printf("File %s doesn\'t exist\n",file)
    exit
  }

  for (_line=getline(file),_ind=0; _line!=-1; _line=getline(file)) { 

    _nn = split(_line,_tok)

    if (_tok[0]=="") continue

    if (!_ind) {
      printf("\rLoad: Looking for spectrum %d/%d ...",$4,$5)
      if ((_tok[0] == "#S") && (_tok[1] == _sno)) _ind++
      continue
    }

    if ((_tok[0] == "#R") || (_tok[0] == "#H") || (_tok[0] == "#S")) break

    if (_tok[0] == "#@CHANN") {
      fch = _tok[2]
      lch = _tok[3]
      rnpts = _tok[1]
      red = _tok[4]
      continue
    }

    if ((_calib)&&(_tok[0] == "#@CALIB"))\
      for (i=0;i<3;i++) cal[i] = _tok[i+1];

    if (substr(_tok[0],1,1)=="#") continue

    if ((substr(_tok[0],0,2) == "@A") && (_ind++ < _spno)) continue

    if (_ind>_spno) {

      _idx = index(_tok[_nn-1],"\\")
      if (_idx) _tok[_nn-1] = substr(_tok[_nn-1],0,_idx-1)
      if (_tok[_nn-1] == "") _nn--

      if (_tok[0] == "@A") {
        for (ii=1 ; ii < _nn ; ii++) $2[ii-1][_elem]=_tok[ii];
        cc = _nn-1
      } else {
        for (ii=0 ; ii < _nn ; ii++) $2[cc+ii][_elem]=_tok[ii];
        cc += _nn
      }
      printf("\rLoad: %d points loaded ...                   ",cc)
      if (!_idx) break
    }
  }

  if (!_ind) {
    printf("\nLoad: Cannot find scan %d in file %s\n",_sno,file)
    exit
  } 
  if (_ind <=_spno) {
    printf("\nLoad: Scan %d in file %s has only %d points\n",_sno,file,_ind-1)
    exit
  } 
  printf("\n      %d points read from file %s\n",cc,file)
  getline(file,"close")

  if (red) printf("      Data reduction coefficient: %d\n",red)
  if (_calib) \
    printf("      Energy calibration E = %g + %g * ch + %g * ch^2\n",cal[0],cal[1],cal[2])
  calstr=sprintf("%g %g %g",cal[0],cal[1],cal[2])

  $7=fch; $8=lch; $9=red; $10=calstr
}'





#%MACROS%
#%DEPENDENCIES%
#%PRE%
#  - The file has %B%saveload.mac%B% to be read in
#%PRE%
#%AUTHOR%
#  SAVELOAD.MAC - Marie-Claire LAGIER - 96/1/8
# %PRE%
#Changed to use macro functions and arrays on 96/03
# %PRE%
# %TOC%