esrf

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

#%NAME% SPS.MAC
#%TITLE% Utilities for shared memory SPEC arrays
#%DESCRIPTION%
# This file contains some utilities for SPEC shared memory arrays.
#%UL%

#%LI% Functions to read and write shared memory environment variables which
#     can be used to exchange abritrary string values with other programs
#     (SPS_CreateEnv, SPS_PutEnv, SPS_GetEnv)

#%LI% Functions to put standard scan data into shared memory for other
#     programs to use it (shareddata, privatedata)

#%LI% Test routines to produce some example image data

#%XUL%

#%UU% (name, no_items, max_length)
#%MDESC% Create a shared environment array called name (something like
# xxxxx_ENV) which contains strings to be shared with other applications
# in the format identifier=value with maximal string length max_length.
# A maximum of no_items of such lines can be put into this array.
def SPS_CreateEnv (name, no_items, max_length) '{
  shared string array @name[no_items][max_length]
}'

#%UU% (arr, id, value)
#%MDESC% Put the value in the shared memory array arr under the identifier
# id in the format id = value.
def SPS_PutEnv(arr, id, value) '{
  local rows cols i l_id l_value
  rows = array_op("rows",arr)
  cols = array_op("cols",arr)
  for (i = 0; i < rows; i++) {
    if (index(arr[i],"=") == 0)
      break;
    sscanf(arr[i][], "%[^=]=%[^\n]", l_id, l_value)
    if (l_id == id) {
      if (l_value != value) {
  arr[i][] = sprintf("%s=%s\n", id, value)
      }
      return 0;
    }
  }
  if (i < rows - 1) {
    arr[i][] = sprintf("%s=%s\n", id, value)
    return 0
  } else {
    return 1
  }
}'

#%UU% (arr, id)
#%MDESC% Get the value from the shared memory environment array arr with the
# identifier id.
def SPS_GetEnv(arr, id) '{
  local rows i l_id l_value
  rows = array_op("rows",arr)
  for (i = 0; i < rows; i++) {
    if (index(arr[i],"=") == 0)
      break;
    sscanf(arr[i][], "%[^=]=%[^\n]", l_id, l_value)
    if (l_id == id)
      return l_value
  }
  return ""
}'

#cdef("user_scan_plot", "", "SPS_SCAN") # in standard.mac (08/2013 HW)
cdef("scan_plot", "_plot;user_scan_plot;", "SPS_SCAN")

#%UU%
#%MDESC% Put scan data in shared memory.
def shareddata '{
    global SCAN_D_SHARED
    shared string array SCAN_D_ENV [50][1024]
    if (whatis("_plotconfig") & 2) {
        # as of version 6.01.xx, _plotconfig no longer exists and
        # SHARED_SCAN_D is rdefed in standard.mac !
        # use eval(), so that macro expansion won`t throw an error.
        rdef SHARED_SCAN_D \'shared\'
        local xxx
        xxx = "PLOT_MNE[PLOT_MOTS] = \"\" ; _plotconfig()" # be sure that we redo the config
        eval(xxx)
    }
    SCAN_D_SHARED = 1
    cdef ("user_postscan_head","SPS_scanhead ;","SPS_SCAN")
    cdef ("user_scan_plot","SPS_onepoint ;","SPS_SCAN")
    cdef ("cleanup_once","SPS_scanabort ;","SPS_SCAN")
    SPS_scanhead # be sure to fill the memory with some data
    #Should I check SCAN_D exits prior to tag it?
    array_op("untag", SCAN_D)
    array_op("tag", SCAN_D, "scan")
}'

#%UU%
#%MDESC% Put scan data in private memory.
def privatedata '{
    global SCAN_D_SHARED
    if (whatis("_plotconfig") & 2) {
        # as of version 6.01.xx, _plotconfig no longer exists and
        # SHARED_SCAN_D is rdefed in standard.mac !
        rdef SHARED_SCAN_D \'\'
    }
    SCAN_D_SHARED = 0
    cdef ("","","SPS_SCAN","delete")
    PLOT_MNE[PLOT_MOTS] = "" ; _plotconfig() # be sure that we do the config
}'

#%IU%
#%MDESC% This macro is executed once for every scan
#     at the beginning of the scan
def SPS_scanhead '{
plot_defaults($#,"$1","$2","$3","$4")
SPS_PutEnv(SCAN_D_ENV, "title", pl_t)
SPS_PutEnv(SCAN_D_ENV, "xlabel", pl_xl)
axistitles=sprintf("{%s}",pl_xl)
for (i=0; i < COUNTERS; i++)
  axistitles = sprintf("%s %s",axistitles,cnt_mne(i))
SPS_PutEnv(SCAN_D_ENV, "axistitles", axistitles)
SPS_PutEnv(SCAN_D_ENV, "ylabel", "Counts")
SPS_PutEnv(SCAN_D_ENV, "nopts", 0)
SPS_PutEnv(SCAN_D_ENV, "xbeg", _s[0])
SPS_PutEnv(SCAN_D_ENV, "xend", _f[0])
if (PL_Y != "") {
    SPS_PutEnv(SCAN_D_ENV, "plotlist", PL_Y)
}
SPS_PutEnv(SCAN_D_ENV, "datafile", DATAFILE)
SPS_PutEnv(SCAN_D_ENV, "scantype", _stype)
SPS_PutEnv(SCAN_D_ENV, "aborted",0)
SPS_PutEnv(SCAN_D_ENV, "command","done")
SPS_PutEnv(SCAN_D_ENV, "fitresult","0")
if ((whatis("H" ) & 2) == 2){
    if ((whatis("K") & 2) == 2){
        if ((whatis("L") & 2) == 2){
            SPS_PutEnv(SCAN_D_ENV, "H", H)
            SPS_PutEnv(SCAN_D_ENV, "K", K)
            SPS_PutEnv(SCAN_D_ENV, "L", L)
        }
    }
}
}'

#%IU%
#%MDESC% This macro is executed once for every scan
#     at the beginning of the scan
def SPS_scanabort '{
SPS_PutEnv(SCAN_D_ENV, "aborted","1")
}'

#%IU%
#%MDESC% This macro is executed once for every scan point
def SPS_onepoint '{
  SPS_PutEnv(SCAN_D_ENV, "nopts", LDT)
  SPS_PutEnv(SCAN_D_ENV, "peak", 111)
  SPS_PutEnv(SCAN_D_ENV, "peakpos", 34)
  SPS_PutEnv(SCAN_D_ENV, "fwhm", 12.3)
  SPS_PutEnv(SCAN_D_ENV, "fwhmpos", 45)
  SPS_PutEnv(SCAN_D_ENV, "com", 23)
}'

#%UU% [dim] [scale]
#%MDESC% Produce a nice looking double image called image_test[dim][dim].
# Use scale values between 1 and 10.
def testimage '{
if ($# < 1) { dims = 512 } else { dims = $1 }
if ($# < 2) { scale = 5 } else { scale = $2 }

shared array image_test[dims][dims]
for (i = 0; i < dims; i++ )
  for (j = 0; j < dims; j++ )
    image_test[i][j] = 5000 * testfunc(scale * (i / dims - .5), \
                scale * (j / dims - .5))
}'

#%IU%
#%MDESC% testfunctions used by testimage
def testfunc(x, y) '{
return  3 * pow(1-x, 2) * exp(-pow(x, 2) - pow(y+1, 2)) \
        - 10 * (x/5 - pow(x, 3) - pow(y, 5)) * exp (-pow(x, 2) - pow(y, 2)) \
        - 1/3 * exp(- pow(x + 1, 2) - pow(y, 2))
}'


#%UU% [dim] [width] [height]
#%MDESC% Produce a nice looking unsigned short integer grid image called
# image_data. height is a scaling factor for the heigth of the grid peaks.
# width is the width of the individual peaks (always spaced 50 pixels)
def testgrid  '{
if ($# < 1) { dims = 512 } else { dims = $1 }
if ($# < 2) { width = 5 } else { width = $2 }
if ($# < 3) { height = 1000 } else { height = $2 }
shared ushort array image_data[dims][dims]
for (x = 15; x < dims; x += 50) {
  for (y = 35; y < dims; y += 50) {
  xcen = x ; ycen = y ;
  i0 = xcen - width * 2; i1 = xcen + width * 2 + 1;
  j0 = ycen - width * 2; j1 = ycen + width * 2 + 1;
  if (i0 >=0 && j0 >= 0 && i1 < dims && j1 < dims)
    for (i = i0 ; i < i1 ; i ++)
      for (j = j0 ; j < j1 ; j ++) {
        r = sqrt ( pow ( xcen - i,2) + pow ( ycen - j,2));
        image_data[i][j] = height * exp ( - r / pow (width/3,2));
      }
  }
}
}'

#%IMACROS%
#%MACROS%
#%AUTHOR% JK 4.99