#%TITLE% multimca.mac
#%NAME%
# Multi Channel Analyser. Macros handling multiple devices at once
#
#%CATEGORY% Detection, MCA
#
#%LOG%
#$Revision: 1.45 $
#$Log: multimca.mac,v $
#Revision 1.45 2022/12/05 16:00:36 witsch
#Introduction of a macro MCA (named Can556), which needs some adaption
#in the code. Some functions didn't go throught the Can556_cmd() and hindere
#the macro MCA's work. The two macro sets were tested together and it worked.
#
#The real use on the beam line needs to be awaited to see, if new problems
#arise.
#
#Revision 1.43 2017/05/29 08:59:07 papillon
#bug in mcaroiload corrected by FS on id10
#
#Revision 1.42 2013/11/19 15:38:38 claustre
#Added support for mythen version 2 (newly supported by spec, see help mythen)
#Since spec 6 auto_run is reset to 0 (was 1 before) update _mcacheckoff
#Replace PyMca with pymca in _mcaguistart(), PyMca script is no longer exist
#
#Revision 1.41 2013/08/21 15:42:36 witsch
#changes to allow easier implementation of mcas with a reduced set
#of commands.
#
#implementation of a roentec
#implementation of a dxp
#
#Revision 1.41 2011/06/11 09:26:35 witsch
#integrate Rontec, close to the Mythen.
#
#Revision 1.40 2011/02/17 16:35:32 claustre
#Thanks to Manu Pap who fixed some bugs introduced into the previous
#version with mythen integration.
#
#Revision 1.39 2010/10/27 07:48:45 beteva
#corrected a typo
#
#Revision 1.38 2010/10/19 14:40:19 homsrego
#identical to 1.37
#
#Revision 1.37 2010/10/19 14:29:34 homsrego
#* _mcacheckoff() : included test for irresponsive devices
#
#Revision 1.36 2010/10/11 09:31:06 witsch
#G. Swislow provided a first implementation for the use of the Mythen in Spec.
#There were some small things to correct and adjust. After that the work
#consisted of adjusting the multimca.mac to for its use.
#
#This meant to exclude certain actions on the Mythen, which were:
#
#the Mythen does not accept TCP connections, exclude the change in the macros.
#the Mythen does not accept commands like select_group, real, elapsed_live,
#elapsed_real, dead, clear. This inability lies in the mca_par builtin
#function. The exclusion take place in the mca_io macro:
#
#Revision 1.35 2009/10/13 12:40:39 papillon
#* change the way cdef are used:
#- create cdefs in mcaon and mcasetup
#- do not remove cdefs in mcaoff
#- let cdef macros defined and use MCA_ON variables
#* check spec auto_run flag before counting
# (after reconfig, auto_run is to 1, but MCA_ON can still be 0:
# force auto_run to 0 if MCA_ON is 0)
#* add a mcaunsetup to cleanup cdefs if needed
#* correct roi counters
#- remove old per counter cdefs not used anymore
#- when multiple mca, rois was all computed for each mca,
# even if roi belongs to another mca
#* mca savings during scans test MCA_ON and not MCA_ACTIVE
#* correct HEADING for file saving in mcaacq
#
#Revision 1.34 2009/07/16 14:11:21 witsch
#mcaacq no longer needs an argument. if no argument is given,
#set count_time to 1 billion seconds, about 11000 days. That should be
#long enough even for ID18.
#
#Revision 1.33 2008/10/03 12:35:16 domingue
#correct user_Fheader and user_scan_loop call
#
#Revision 1.32 2008/08/12 14:15:24 rey
#documentation changes
#
#Revision 1.31 2008/03/18 12:57:22 witsch
#in mcaacq in case of continuing counting for a fixed amount of time, we need to know the elapsed counting time to add the new counting time. Only then the device server will acquire anew.
#
#Revision 1.30 2007/11/05 11:56:30 sole
#Make sure the noclear flag is appropriately handled during scans.
#
#Revision 1.29 2007/10/09 14:05:32 berruyer
#add _MCA_ROI_ADD and _MCA_ROI_DEL for user roi add macros
#
#Revision 1.28 2007/08/23 10:11:11 guijarro
#bug fixes in _mcaroicounts
#
#Revision 1.27 2007/08/23 08:42:56 guijarro
#fix bug with invalid use of 'list_getpar'
#
#Revision 1.26 2007/08/03 08:00:37 berruyer
#fill cntconf field in mcaroimenu
#
#Revision 1.25 2007/08/02 13:34:28 beteva
#added _mcacalibget() and _mcaroisetup() functions. Get the ROI pseudo counters
#setup when _mcasetup() executed and MCA is active.
#
#Revision 1.24 2007/07/31 14:06:22 beteva
#changed ROI handling, added mca_user_roi_add and mca_user_roi_delete,
#added mcatype
#
#Revision 1.23 2007/07/18 15:04:50 witsch
#in function mcawait the wait(0x24) doesn't fulfill the task,
#when using external synchronization. The macro mcaacq will return
#to the prompt right away, when launched with a count time.
#wait(0x24) will not take the main counter (here software counter)
#into account. Change that to wait(0x26).
#
#Revision 1.22 2007/07/12 10:53:09 beteva
#added read ROI spectra only, corrected bugs for the reduction factor
#
#Revision 1.21 2007/05/30 13:11:07 berruyer
#correction of syntax error in mcasetup ($#>$4)
#
#Revision 1.20 2006/07/26 15:21:49 beteva
#added save in one non-standard file option;
#if no save oprions and ROIs configured, read only the ROIs channels and not whole spectra;
#
#Revision 1.19 2006/04/20 16:00:47 beteva
#added change to TCP and big timeout for non MUSST MCA
#
#Revision 1.18 2005/12/13 08:32:31 papillon
#* Changes to integrate MUSST MCA
#
#Revision 1.17 2005/09/21 12:42:57 pepellin
#Use clscreen()
#
#Revision 1.16 2005/05/03 12:32:01 beteva
#added reduced reading if AE scan to save time with the Rontec
#
#Revision 1.15 2005/04/28 09:13:58 papillon
#Missing ; in some cdefs
#
#Revision 1.14 2004/10/05 06:31:50 claustre
#missing local declaration of variables in _mcaroicounts()
#
#Revision 1.13 2004/09/16 08:15:35 sole
#Added support for new PyMca
#
#Revision 1.13 2004/09/10 14:40:50 sole
#Support of new PyMca
#
#Revision 1.12 2004/09/10 14:40:50 papillon
#Correct parameters reading in mcasetup
#
#Revision 1.11 2004/05/13 14:46:39 witsch
#just added changing the plot frequency to the main menu.
#
#Revision 1.10 2004/05/07 13:01:52 beteva
#added _mcagetE() and _mcagetch() functions and print of energy for the roi;
#added choise of the gui to start - changes in mcasetup, mcamenu, mcaguion;
#fixed bug in mcawait
#
#%END%
# -- acquisition
global MCA_ACTIVE[] MCA_ON[]
global MCA_PAR[]
global MCA_IN_SCAN
# -- memory group
global MCA_MEM[]
# -- saving options
global MCA_SAVE[]
global MCA_N
if (whatis("MCA_N")&0x08000000) { MCA_N = 0 }
global MCA_SUFFIX
if (whatis("MCA_SUFFIX")&0x08000000) { MCA_SUFFIX = ".mca" }
# -- plot
global MCA_PID[]
# -- times
global MCA_TIMES[]
# -- rois definition
global MCA_ROI
# implicitely global vars
MCA_AVOID_CMDS_MYTHEN = "select_group real elapsed_live elapsed_real dead clear"
MCA_AVOID_CMDS_ROENTEC = "select_group group_size"
MCA_AVOID_CMDS_DXP = MCA_AVOID_CMDS_ROENTEC
# --- plot refresh
global MCA_PLOT_UPD
if (whatis("MCA_PLOT_UPD") & 0x08000000) MCA_PLOT_UPD = 0.1
need sps
need saveload
#%UU%
#%MDESC%
# Toggles the debug mode.
if (!(whatis("__MultiMCA_debug") & 2)) rdef __MultiMCA_debug \'#$*\'
def MultiMCA_debug '{
if ((whatis("__MultiMCA_debug")>>16) <= 3) { # macro length is 3 bytes: comment
rdef __MultiMCA_debug "eprint \"---> MultiMCA \""
print "MultiMCA macro debug mode is ON"
}
else {
rdef __MultiMCA_debug \'#\$*\'
print "MultiMCA macro debug mode is OFF"
}
}'
#%IU%
#%MDESC%
# Utility to print mca messages
def _mcamsg(no, msg) '{
tty_cntl("md")
if (no == "all") printf("MCA: ")
else printf("MCA device %d: ", no)
tty_cntl("me")
print msg
}'
# ---------------------------------------------------------
# CONFIG MENU
# ---------------------------------------------------------
#%UU% (<message>, <default>)
#%MDESC%
# Prompts for a single letter until a unique one is entered.
def getval_one_char(message, default) '{
local _entry
_entry = getval(message, default)
while ( (length(_entry) < 1) || (length(_entry) > 1) ){
_entry = getval(message, default)
}
return (_entry)
}'
#%UU%
#%MDESC% List all configured MCA devices and their state
def mcalist '{
local no
for (no = 0; no<MCAS; no++)
_mcalist(no)
}'
#%IU% (no)
#%MDESC% short list of the MCA %B%no%B% configuration
def _mcalist(no) '{
local ctrl dev resp
ctrl = mca_spar(no, "controller")
dev = ctrl == "MUSSTMCA"?"GPIB":mca_spar(no, "device_id")
resp = mca_spar(no, "responsive")
tty_cntl("md"); printf("%2d : ", no); tty_cntl("me")
printf("%s - %s - %s - %s - %s\n", \
ctrl, dev, resp?"Responsive":"Unresponsive", \
MCA_ACTIVE[no]?"Active":"Inactive", MCA_ON[no]?"ON":"OFF")
}'
#%IU%
#%MDESC% print the menu of all the set in the config MCAs
def _mcamenu '{
local _mca_u interact ok str
if (!MCAS) {
tty_cntl("md")
printf("No MCA configured !!")
tty_cntl("me")
exit
}
_mca_u = -1
interact = ($# == 0)
while (1) {
ok = 1
if (interact) {
clscreen()
tty_cntl("md")
printf("\n\n\nMCA Devices Configured:\n\n")
tty_cntl("me")
mcalist
tty_cntl("ue")
tty_cntl("md"); printf("\n%2d : ", 99); tty_cntl("me")
printf("Plot Frequency - <%0.1f>\n\n", MCA_PLOT_UPD)
while ((++_mca_u < MCAS) && \
!mca_spar(_mca_u, "responsive"));
_mca_u = (_mca_u < MCAS) ? _mca_u : -1
str = "\n\tMCA number or -1 to Exit"
_mca_u = getval(str, _mca_u)
if (_mca_u < 0)
break
else if (_mca_u == 99) {
print
MCA_PLOT_UPD = getval(" Plot Frequency", MCA_PLOT_UPD)
_mca_u = -1
continue
}
if (!mca_spar(_mca_u, "responsive")) {
str = "\nMCA device %d is Unresponsive. Do " \
"you want to configure it anyway"
ok = yesno(sprintf(str, _mca_u), 0)
}
} else {
_mca_u = int($1)
}
if (_mca_u >= MCAS) {
_mcamsg(_mca_u, "Device not in spec config !!")
ok = 0
}
if (ok)
_mcasubmenu(_mca_u)
if (!interact)
break
}
}'
#%IU% (no)
#%MDESC% Configure the MCA %B%no%B% when using the mcasetup menu
def _mcasubmenu(no) '{
local ii desc option gui str
_mcadefaults(no)
option = 1
while (option) {
clscreen()
tty_cntl("md"); printf("\t\t< MCA SETUP >\n"); tty_cntl("me")
_mcalist(no)
tty_cntl("us")
printf(" \n\n")
tty_cntl("ue")
printf("\n 1 - MCA ACTIVE . . . . . . . . . . . . . . . . . . . :")
tty_cntl("md")
printf("<%s>", MCA_ACTIVE[no]?"YES":"NO")
tty_cntl("me")
printf("\n 2 - AUTO-RUN in ct/scan . . . . . . . . . . . . . . .:")
tty_cntl("md")
printf("<%s>", MCA_ON[no]?"ON":"OFF")
tty_cntl("me")
printf("\n 21 - TIME mode . . . . . . . . . . . . . . . . . :")
tty_cntl("md")
printf("<%s>", MCA_PAR[no]["tmode"]?"Live":"Real")
tty_cntl("me")
printf("\n 22 - SYNCHRO . . . . . . . . . . . . . . . . . . :")
tty_cntl("md")
printf("<%s>", MCA_PAR[no]["sync"]?"External":"Internal")
tty_cntl("me")
printf("\n 23 - AUTO-CLEAR memory . . . . . . . . . . . . . :")
tty_cntl("md")
printf("<%s>", MCA_PAR[no]["noclear"]?"NO":"YES")
tty_cntl("me")
printf("\n 24 - Read ROI(s) spectra only . . . . . . . . . .:")
tty_cntl("md")
printf("<%s>", MCA_PAR[no]["whole"]?"YES":"NO")
tty_cntl("me")
printf("\n 3 - Memory group Size - Active . . . . . . . . . . . :")
tty_cntl("md")
printf("<%d - %d>", MCA_MEM[no]["size"], MCA_MEM[no]["num"])
tty_cntl("me")
printf("\n 4 - SAVE spectrum during SCANS . . . . . . . . . . . :")
tty_cntl("md")
printf("<%s>", MCA_SAVE[no]["scan"]?"YES":"NO")
tty_cntl("me")
printf("\n 5 - SAVE spectrum after CT or MCAACQ . . . . . . . . :")
tty_cntl("md")
printf("<%s>", MCA_SAVE[no]["acq"]?"YES":"NO")
tty_cntl("me")
if ((MCA_SAVE[no]["scan"] == 1) || (MCA_SAVE[no]["acq"] == 1)) {
printf("\n 6 - SAVE options . . . . . . . . . . . . . . . . . . :")
printf("\n 61 - Reduction factor . . . . . . . . . . . . . .:")
tty_cntl("md")
printf("<%d>", MCA_SAVE[no]["red"]>0?MCA_SAVE[no]["red"]:1)
tty_cntl("me")
printf("\n 62 - Data format . . . . . . . . . . . . . . . . :")
tty_cntl("md")
printf("<%s>", MCA_SAVE[no]["fmt"])
tty_cntl("me")
printf("\n 63 - Save to standard datafile . . . . . . . . . :")
tty_cntl("md")
printf("<%s>", MCA_SAVE[no]["std"]?"YES":"NO")
tty_cntl("me")
if (MCA_SAVE[no]["std"]) {
printf("\n Current: %s", DATAFILE)
printf("\n Scan No: %d", SCAN_N)
} else {
tty_cntl("me")
printf("\n 63.1 - Save each spectra in a separate file :")
tty_cntl("md")
printf("<%s>", MCA_SAVE[no]["onefile"]?"YES":"NO")
tty_cntl("me")
if (MCA_SAVE[no]["onefile"]) {
printf("\n ==> Save to: %s_%d_%03d%s", \
MCA_SAVE[no]["prefix"], no, MCA_N, MCA_SUFFIX)
printf("\n or: %s_%d_<s>_<p>%s in scans", \
MCA_SAVE[no]["prefix"], no, MCA_SUFFIX)
} else {
printf("\n ==> Save to: %s%s", \
MCA_SAVE[no]["prefix"], MCA_SUFFIX)
}
}
}
printf("\n 7 - GUI . . . . . . . . . . . . . . . . . . . . . . :")
gui = MCA_PAR[no]["gui"]
gui == 0?(str = "OFF"):gui == 1?(str = "mcatcl"):\
gui == 2?(str = "PyMca"):gui == 3?(str = "newplot"):(str = "????")
tty_cntl("md")
printf("<%s>", str)
tty_cntl("me")
option = getval("\n\n\n\t Option ", 0)
printf("\n\n")
if (option) {
if (option == 1) {
MCA_ACTIVE[no]= MCA_ACTIVE[no]?0:1
if (!MCA_ACTIVE[no] && MCA_ON[no])
_mcaoff(no)
}
if (option == 2) {
if (!MCA_ON[no])
_mcaon(no)
else
_mcaoff(no)
}
if (option == 21) {
if (MCA_PAR[no]["MUSSTMCA"]) {
MCA_PAR[no]["tmode"]= 0
MCA_PAR[no]["type"] = 2
} else
MCA_PAR[no]["tmode"]= MCA_PAR[no]["tmode"]?0:1
}
if (option == 22) {
MCA_PAR[no]["sync"]= MCA_PAR[no]["sync"]?0:1
}
if (option == 23) {
MCA_PAR[no]["noclear"]= MCA_PAR[no]["noclear"]?0:1
}
if (option == 24) {
MCA_PAR[no]["whole"]= MCA_PAR[no]["whole"]?0:1
}
if (option == 3) {
MCA_MEM[no]["size"]= \
getval("- Memory group size", MCA_MEM[no]["size"])
MCA_MEM[no]["num"]= \
getval("- Active group", MCA_MEM[no]["num"])
}
if (option == 4) {
MCA_SAVE[no]["scan"]= MCA_SAVE[no]["scan"]?0:1
if (MCA_ON[no])
_mcaon(no)
}
if (option == 5) {
MCA_SAVE[no]["acq"]= MCA_SAVE[no]["acq"]?0:1
if (MCA_ON[no])
_mcaon(no)
}
if (option == 6 || option == 61) {
MCA_SAVE[no]["red"] = \
getval(" - Mca reduction coefficient", MCA_SAVE[no]["red"])
MCA_SAVE[no]["red"] = MCA_SAVE[no]["red"]>0?MCA_SAVE[no]["red"]:1
}
if (option == 6 || option == 62) {
MCA_SAVE[no]["fmt"]= \
getval(" - Data format", MCA_SAVE[no]["fmt"])
}
if (option == 6 || option == 63) {
MCA_SAVE[no]["std"]= \
yesno(" - Save to standard datafile", MCA_SAVE[no]["std"])
}
if (!MCA_SAVE[no]["std"] && (option == 63.1 || option == 6 || option == 63)) {
MCA_SAVE[no]["onefile"] = \
yesno(" - Save each spectra in separate file?", \
MCA_SAVE[no]["onefile"])
if (MCA_SAVE[no]["onefile"]) {
str = " - File prefix - specify full directory path"
MCA_N = getval(" - Current Mca Number", MCA_N)
} else
str = " - File name - specify full directory path"
MCA_SAVE[no]["prefix"] = \
getval(sprintf ("%s", str), MCA_SAVE[no]["prefix"])
}
if (option == 7) {
if (MCA_PAR[no]["gui"])
_mcaguioff(no)
else {
MCA_PAR[no]["gui"] = \
getval(" - Use which gui (off = 0, mcatcl = 1, PyMca = 2, newplot = 3)", \
MCA_PAR[no]["gui"])
if (MCA_PAR[no]["gui"] != 0)
MCA_PAR[no]["guiconf"] = MCA_PAR[no]["gui"]
_mcaguion(no)
}
}
}
}
if (MCA_ACTIVE[no]) {
_mcasetup(no)
}
else {
_mcamsg(no, "Device INACTIVE.")
}
}'
# ---------------------------------------------------------
# DEVICE ON/OFF
# ---------------------------------------------------------
#%UU% [<device_no>]
#%MDESC% Set all MCA devices ON, or only <device_no>
#%BR% If device is on, it is used in standard acquisition macros (scans, ct)
def mcaon '{
local ii
if ($#)
_mcaon($1)
else {
for (ii = 0; ii<MCAS; ii++)
_mcaon(ii)
}
}'
#%IU% (no)
#%MDESC% Set MCA device %B%no%B% ON
def _mcaon(no) '{
if (mca_spar(no, "auto_run", 1) == -1) {
_mcamsg(no, "Cannot set auto-run. Device set OFF.")
MCA_ON[no]= 0
_mcadeldef(no)
} else {
MCA_ON[no]= 1
MCA_ACTIVE[no]= 1
_mcacdef(no)
#_mcamsg(no, "ON")
}
}'
#%UU%[<device_no>]
#%MDESC% Set all MCA devices OFF, or only <device_no>
def mcaoff '{
local ii
if ($#) _mcaoff($1)
else for (ii = 0; ii < MCAS; ii++)
_mcaoff(ii)
}'
#%IU% (no)
#%MDESC% Set MCA device %B%no%B% OFF
def _mcaoff(no) '{
MCA_ON[no]= 0
mca_spar(no, "auto_run", 0)
#_mcamsg(no, "OFF")
}'
#%IU%
#%MDESC%
# Since spec version 6, this pb is fixed so reconfig set auto_run to 0
# When doing reconfig, spec sets auto_run to 1 even if mca is off in the macro.
# %BR% So, before counting, if mca is off (MCA_ON[]=0), we force auto_run to 0.
# This will avoid difference between MCA_ON and internal auto_run flag.
def _mcacheckoff() '{
local ii
for (ii = 0; ii<MCAS; ii++) {
if ( mca_spar(ii, "responsive")) {
if(MCA_ON[ii]) mca_spar(ii, "auto_run", 1)
else mca_spar(ii, "auto_run",0)
}
}
}'
# ---------------------------------------------------------
# DEVICE ACTIVE
# ---------------------------------------------------------
#%UU% [device_no]
#%MDESC% Set MCA device number <device_no> ACTIVE.
#%BR% If device is active, it is used in mca acquisition macro (mcaacq)
def mcaactive '{
if (!$#) {
printf ("mcaactive [mca_device_no]\n")
} else {
if (mca_spar($1, "responsive") != 1) {
_mcamsg($1, "Device unresponsive. Cannot set active.")
MCA_ACTIVE[$1]= 0
} else {
MCA_ACTIVE[$1]= 1
if (MCA_PAR[$1]["gui"])
_mcaguiopen($1)
_mcamsg($1, "Set ACTIVE.")
}
}
}'
#%UU% [device_no]
#%MDESC% Set MCA device number <device_no> INACTIVE.
def mcainactive '{
if (!$#) {
printf ("mcainactive [mca_device_no]\n")
} else {
MCA_ACTIVE[$1]= 0
if (MCA_PAR[$1]["gui"]) _mcaguiclose($1)
_mcamsg($1, "Set INACTIVE.")
}
}'
# ---------------------------------------------------------
# DEVICE SETUP
# ---------------------------------------------------------
#%UU% <no> [<size> <num> <tmode> <sync> <noclear> <gui> <scan> <acq> <std> <prefix> <red> <fmt> <whole> <type>]
#%MDESC% MCA device setup
#%BR%If no arguments, or only <no>, run an interactive menu.
#%BR%If arguments are given, setup mca silently
#%BR%Arguments are:
#%BR%%B%no%B%: device number as in spec config
#%BR%%B%size%B%: memory size (default read from device)
#%BR%%B%num%B%: memory group number (default 0)
#%BR%%B%tmode%B%: time mode = 0:real time, 1:live time (default 0)
#%BR%%B%sync%B%: sync mode = 0:Internal, 1:External (default 0)
#%BR%%B%noclear%B%: do not clear buffer between several mcaacq (default 0)
#%BR%%B%scan%B%: save spectrum during scans (default 0)
#%BR%%B%acq%B%: save spectrum during mcaacq/ct (default 0)
#%BR%%B%std%B%: save spectrum to standard file (default 0)
#%BR%%B%prefix%B%: mca file prefix (default =\"data\")
#%BR%%B%red%B%: spectrum reduction factor (default = 1 = no reduction)
#%BR%%B%fmt%B%: file dump format as used in data_dump (default = %%16C)
#%BR%%B%whole%B%: read whole spectra or not (default = 0 - whole)
#%BR%%B%type%B%: MCA controller type AIM/MAX = 0, MMAX = 1, MUSST = 2 (default = 0-AIM)
def mcasetup '{
if ($# == 0) {
_mcamenu
} else if ($# == 1) {
_mcamenu $1
} else {
MCA_ACTIVE[$1]= 1
if ($#>1) MCA_MEM[$1]["size"] = $2
if ($#>2) MCA_MEM[$1]["num"] = $3
if ($#>3) MCA_PAR[$1]["tmode"] = $4
if ($#>4) MCA_PAR[$1]["sync"] = $5
if ($#>5) MCA_PAR[$1]["noclear"] = $6
if ($#>6) MCA_PAR[$1]["gui"] = $7
if ($#>7) MCA_SAVE[$1]["scan"] = $8
if ($#>8) MCA_SAVE[$1]["acq"] = $9
if ($#>9) MCA_SAVE[$1]["std"] = $10
if ($#>10) MCA_SAVE[$1]["prefix"] = "$11"
if ($#>11) MCA_SAVE[$1]["red"] = $12
if ($#>12) MCA_SAVE[$1]["fmt"] = "$13"
if ($#>13) MCA_PAR[$1]["whole"] = "$14"
if ($#>14) MCA_PAR[$1]["type"] = $15
_mcadefaults($1)
_mcasetup($1)
MCA_IN_SCAN = 0
}
}'
def mcaunsetup '{
local no
if ($# == 1) {
MCA_ON[no]= 0
MCA_ACTIVE[no]= 0
_mcadeldef(no)
} else {
local no
for (no = 0; no<16; no++)
_mcadeldef(no)
unglobal MCA_ON MCA_ACTIVE
global MCA_ON[] MCA_ACTIVE[]
cdef("", "", "_mca", "delete")
}
}'
#%IU% (no)
#%MDESC% Setup defaults parameters for MCA device <no>.
#
def _mcadefaults(no) '{
local maxsize
if (MCA_MEM[no]["size"] <= 0) {
maxsize = mca_spar(no, "max_channels")
MCA_MEM[no]["size"]= maxsize>0?maxsize:8191
MCA_MEM[no]["num"]= 0
}
MCA_SAVE[no]["red"]= MCA_SAVE[no]["red"]>0?MCA_SAVE[no]["red"]:1
if (!length(MCA_SAVE[no]["prefix"])) MCA_SAVE[no]["prefix"]= "data"
if (!length(MCA_SAVE[no]["fmt"])) MCA_SAVE[no]["fmt"]= "%16C"
if (!MCA_SAVE[no]["scan"]) MCA_SAVE[no]["save"]= 0
if (!MCA_SAVE[no]["acq"]) MCA_SAVE[no]["acq"]= 0
if (!MCA_SAVE[no]["std"]) MCA_SAVE[no]["std"]= 0
if (!MCA_PAR[no]["whole"]) MCA_PAR[no]["whole"]= 0
if (!MCA_PAR[no]["tmode"]) MCA_PAR[no]["tmode"]= 0
if (!MCA_PAR[no]["sync"]) MCA_PAR[no]["sync"]= 0
if (!MCA_PAR[no]["noclear"]) MCA_PAR[no]["noclear"]= 0
if (MCA_PAR[no]["gui"])
MCA_PAR[no]["guiconf"] = MCA_PAR[no]["gui"]
if (!MCA_PAR[no]["guiconf"])
MCA_PAR[no]["guiconf"] = 2
if (!MCA_PAR[no]["type"]) MCA_PAR[no]["type"] = 0
}'
#%IU% (no)
#%MDESC% Setup the MCA device %B%no%B%.
#%BR% If setup failed, the device is set inactive
def _mcasetup(no) '{
local i controller
controller = mca_spar(no, "controller")
# SPEC now support UDP (MYTHEN) and TCP (MYTHEN2) protocol
# depending of the mythen detector fireware version (1.x or 2.x), see help mythen
if (controller == "MYTHEN" || controller == "MYTHEN2") controller = "MYTHEN"
MCA_PAR[no][controller] = 1
if (MCA_PAR[no]["MUSSTMCA"]) {
MCA_PAR[no]["type"] = 2
}
else if (MCA_PAR[no]["PSE_MAC_MCA"]) {
MCA_PAR[no]["device_id"] = mca_spar(no, "device_id")
__MultiMCA_debug "Macro MCA controller !!!! " MCA_PAR[no]["device_id"]
}
else if (MCA_PAR[no]["MYTHEN"]) {
;
}
else {
dev = mca_spar(no, "device_id")
if (dev) {
MCA_PAR[no]["device_id"] = dev
esrf_io(dev, "tcp")
esrf_io(dev, "timeout", 1000)
}
}
if (mca_spar(no, "responsive") != 1) {
_mcamsg(no, "Device unresponsive. Setup aborted.")
MCA_ACTIVE[no]= 0
} else if (!_mcamemsetup(no)) {
_mcamsg(no, "Cannot setup memory. Setup aborted.")
MCA_ACTIVE[no]= 0
} else {
if (MCA_PAR[no]["noclear"]) mca_spar(no, "auto_clear", 0)
else _mcaio(no, "auto_clear", 1)
if (MCA_PAR[no]["MUSSTMCA"]) {
MCA_PAR[no]["tmode"]= 0
}
else {
if (MCA_PAR[no]["tmode"]) mca_spar(no, "live")
else _mcaio(no, "real")
}
if ((! MCA_PAR[no]["MYTHEN"]) && (MCA_PAR[no]["sync"])) {
mca_spar(no, "soft_preset", 0)
if (MCA_PAR[no]["MUSSTMCA"]) mca_spar(no, "gate", 1)
}
else { # MYTHEN and Can556 always in soft_preset
# otherwise, count time will set to zero
mca_spar(no, "soft_preset", 1)
if (MCA_PAR[no]["MUSSTMCA"]) mca_spar(no, "gate", 0)
}
if (MCA_PAR[no]["gui"]) _mcaguion(no)
else _mcaguioff(no)
if (MCA_PAR[no]["whole"] != 0) {
if (MCA_ROI[0] == 0) {
mca_spar(no, "auto_run", 0)
MCA_ON[no] = 0
}
}
_mcaroisetup(no)
_mcacdef(no)
_mcamsg(no, "Setup done.")
}
}'
#%IU% (no)
#%MDESC% Get the pseudo counter configuration for all defined for MCA
#device %B%no%B% ROIs. Return 0 if no ROI configured, nb of rois otherwise.
def _mcaroisetup(no) '{
local i cnt
for (i = 1; i <= MCA_ROI[0]; i++) {
cnt = MCA_ROI[i]
list_setpar(MCA_ROI, cnt, "cntconf", cnt_num(cnt))
}
return(MCA_ROI[0])
}'
#%IU% (no)
#%MDESC% Setup memory parameters for device <no>
#%BR% Return 1 on success, 0 otherwise.
def _mcamemsetup(no) '{
local maxsize, gsize, gnum, maxgrp
if ( ((maxsize = _mcaio(no, "max_channels")) == -1) || \
((gsize = _mcaio(no, "group_size")) == -1) || \
((gnum = _mcaio(no, "select_group")) == -1) ) {
return 0
}
if (MCA_MEM[no]["size"] > maxsize) MCA_MEM[no]["size"] = maxsize
if (MCA_MEM[no]["size"] <= 0) return 0 #HW# changed < to <=, causes div.by.zero further down
if (MCA_MEM[no]["size"] != gsize) {
MCA_MEM[no]["size"] = _mcaio(no, "group_size", MCA_MEM[no]["size"])
if (MCA_MEM[no]["size"] <= 0) return 0 #HW# changed < to <=, causes div.by.zero further down
}
maxgrp = maxsize/MCA_MEM[no]["size"] - 1
if (MCA_MEM[no]["num"]>maxgrp) MCA_MEM[no]["num"] = 0
if (MCA_MEM[no]["num"] != gnum) {
MCA_MEM[no]["num"] = _mcaio(no, "select_group", MCA_MEM[no]["num"])
if (MCA_MEM[no]["num"]<0) return 0
}
_mcaarraycreate(no)
return 1
}'
#%IU% (no, command, argument)
#%MDESC% Send command to device %B%no%B%.
def _mcaio(no, command, argument) '{
local ret
# ~ __MultiMCA_debug "_mcaio(" no", "command", "argument")"
# one works the other doesn`t but both are needed by the present macros
if ((MCA_PAR[no]["MYTHEN"] || \
MCA_PAR[no]["ROENTEC"] || \
MCA_PAR[no]["DXP"]) && (command == "group_size")) {
command = "max_channels"
} else if (MCA_PAR[no]["PSE_MAC_MCA"]) {
if ( command == "start") command = "On"
if ( command == "elapsed_live,") command = "LiveTime"
if ( command == "elapsed_real") command = "RealTime"
if ( command == "dead") return 0
} else {
if (MCA_PAR[no]["MYTHEN"]) {
if (index(MCA_AVOID_CMDS_MYTHEN, command)) {
return
}
}
else if (MCA_PAR[no]["ROENTEC"]) {
if (index(MCA_AVOID_CMDS_ROENTEC, command)) {
return
}
}
else if (MCA_PAR[no]["DXP"]) {
if (index(MCA_AVOID_CMDS_DXP, command)) {
return
}
}
}
if (length(argument)) {
ret = mca_spar(no, command, argument)
if (ret < 0) ret = mca_spar(no, command)
} else {
ret = mca_spar(no, command)
}
return ret
}'
#%IU% (no)
#%MDESC% Hooks MCA operation to the standard macros for device %B%no%B%.
def _mcacdef(no) '{
local key
#general acquitistion
cdef("prompt_mac", "MCA_IN_SCAN=0;", "_mca")
cdef("user_prescan_head", "MCA_IN_SCAN=1;", "_mca")
cdef("user_scan_tail", "MCA_IN_SCAN=0;", "_mca")
cdef("user_countersrun", "if(wait(0x24)) return(1);", "_mca")
cdef("user_prepcount", "_mcacheckoff();", "_mca", 0x10)
key = sprintf("_mca%d", no)
cdef("user_prepcount", sprintf("_mcaclearct(%d);", no), key, 0)
cdef("user_getcounts", sprintf("_mcareadct(%d); _mcareadroi(%d);", no, no), key)
#TIMES#
cdef("user_getcounts", sprintf("S[mcaLt%d]=MCA_TIMES[%d][\"live\"];", \
no, no), sprintf("mcaLt%d", no), 0x02)
cdef("user_getcounts", sprintf("S[mcaRt%d]=MCA_TIMES[%d][\"real\"];", \
no, no), sprintf("mcaRt%d", no), 0x02)
cdef("user_getcounts", sprintf("S[mcaDt%d]=MCA_TIMES[%d][\"dead\"];", \
no, no), sprintf("mcaDt%d", no), 0x02)
cdef("user_Fheader", sprintf("mcasavescanheader %d;", no), key)
cdef("user_scan_loop", sprintf("mcasavescandata %d;", no), key)
cdef("user_handlecounts", "mcasavect;", "_mca")
}'
#%IU% (no)
#%MDESC% Un-Hooks MCA operation to the standard macros for device %B%no%B%.
def _mcadeldef(no) '{
cdef("", "", sprintf("_mca%d", no), "delete")
cdef("", "", sprintf("mcaLt%d", no), "delete")
cdef("", "", sprintf("mcaRt%d", no), "delete")
cdef("", "", sprintf("mcaDt%d", no), "delete")
}'
# ---------------------------------------------------------
# DATA ARRAY
# ---------------------------------------------------------
#%IU% (no)
#%MDESC% Create data array %B%MCA_DATAno%B% where %B%no%B% is the MCA device
#number. If the array already exists, check its size and eventually change it.
def _mcaarraycreate(no) '{
local carr darr size
darr = sprintf("MCA_DATA%d", no)
size = MCA_MEM[no]["size"]
MCA_SAVE[no]["cmin"] = 0
MCA_SAVE[no]["cmax"] = size-1
if (!whatis(darr) || (size != array_op("rows", @darr))) {
shared ulong array @darr[size][2]
}
array_op("fill", @darr[][0])
if (MCA_SAVE[no]["red"]>1) {
darr = sprintf("MCA_DATARED%d", no)
size = MCA_MEM[no]["size"]/MCA_SAVE[no]["red"]
if (!whatis(darr)) {
ulong array @darr[size][2]
} else if (size != array_op("rows", @darr)) {
ulong array @darr[size][2]
}
}
carr = sprintf("MCA_DATA%d_PARAM", no)
if (!whatis(carr)) {
shared double array @carr[3]
}
if (@carr == 0)
@carr[1] = 1
}'
#%IU% (no)
#%MDESC% Reset data array MCA_DATAno where %B%no%B% is the MCA device number.
def _mcaarrayclear(no) '{
local darr
darr = sprintf("MCA_DATA%d", no)
@darr[][1]= 0
}'
#%IU% (no)
#%MDESC% Read in data from MCA to array MCA_DATAno where %B%no%B% is the MCA
#device number.
def _mcaarrayread(no) '{
local darr i j tmpch[]
local chmin chmax
local mne val
darr = sprintf("MCA_DATA%d", no)
if (!MCA_ROI[0]) {
chmin = 0
chmax = MCA_MEM[no]["size"]-1
} else {
if (!MCA_PAR[no]["whole"]) {
chmin = 0
chmax = MCA_MEM[no]["size"]-1
} else {
if (MCA_ROI[MCA_ROI[1]]["device"] == no) {
j = 0
chmin = 0
chmax = 0
for (i = 1; i <= MCA_ROI[0]; i++) {
mne = MCA_ROI[i]
val = cnt_num(mne)
if (val != -1) {
if (counter_par(mne, "disable") == 0) {
tmpch[0] = list_getpar(MCA_ROI, MCA_ROI[i], "min")
tmpch[1] = list_getpar(MCA_ROI, MCA_ROI[i], "max")
if (j == 0) {
chmin = tmpch[0]
chmax = tmpch[1]
} else {
if (tmpch[0] < chmin)
chmin = tmpch[0]
if (tmpch[1] > chmax)
chmax = tmpch[1]
}
j++
}
}
}
}
if (AE_DOSCAN) {
chmin = ch[0]
chmax = ch[1]
}
}
}
MCA_SAVE[no]["cmin"] = chmin
MCA_SAVE[no]["cmax"] = chmax
if (chmin != chmax) {
mca_sget(no, @darr[chmin:chmax][1], chmin, chmax)
}
}'
# ---------------------------------------------------------
# ACQUISITION
# ---------------------------------------------------------
#%IU% ()
#%MDESC% Get number of active mca devices
def _mcanbactive() '{
local nb no
nb = 0
for (no = 0; no < MCAS; no++) nb += MCA_ACTIVE[no]
return nb
}'
#%UU% [counting_time]
#Do an acquisition for %B%counting_time%B% seconds or until manual stop if
#no time sp[ecified.
def mcaacq '{
local no stimer nbmca ask_time actmca
ask_time = $1
HEADING = "mcaacq $*"
stimer = 0
nbmca = 0
mcastop
for (no = 0; no < MCAS; no++) {
if (MCA_ACTIVE[no]) {
__MultiMCA_debug "active "no
if (!MCA_PAR[no]["noclear"]) _mcaclear(no)
if (MCA_PAR[no]["sync"]) {
stimer = 1
__MultiMCA_debug "sync: " MCA_PAR[no]["sync"] " " stimer
} else {
local presetmca
if (MCA_PAR[no]["MUSSTMCA"] || MCA_PAR[no]["PSE_MAC_MCA"] && MCA_PAR[no]["device_id"] == "Can556") {
COUNT_TIME = ask_time
} else {
COUNT_TIME = ask_time ? ask_time : 1000000000 # about 11000 days :-)
}
#HW11/3/2008
# in case of continuing counting for a fixed amount of time,
# we need to know, where we are to add the new count time.
if (COUNT_TIME) {
presetmca = _mcaio(no, "elapsed_live") + COUNT_TIME
}
__MultiMCA_debug "presetmca: " presetmca*1.0
#HW11/3/2008
# Hmm, I guess this needs setting with internal sync.
_mcapreset(no, presetmca)
# _mcapreset(no, COUNT_TIME)
}
nbmca += MCA_ACTIVE[no]
actmca = no
}
}
if (!nbmca) {
_mcamsg("all", "No active MCA device. Abort.")
exit
}
for (no = 0; no < nbmca-1; no++)
print
no = actmca
mcastart
if (stimer)
tcount(COUNT_TIME ? COUNT_TIME : 1800)
mcawait
if (stimer)
stop(2)
mcaread
mcatimes
mcasaveacq
for (no = 0; no < nbmca-1; no++)
print
}'
#%UU% [<device_no>]
#%MDESC% Stop acquisition on all active device or only on %B%device_no%B%.
def mcastop '{
local ii
if ($#) _mcastop($1)
else {
for (ii = 0; ii < MCAS; ii++) {
if (MCA_ACTIVE[ii]) _mcastop(ii)
}
}
}'
#%IU% (no)
#%MDESC% Stop acquisition on device %B%no%B%.
def _mcastop(no) '{
if (MCA_PAR[ii]["sync"]) {
if (wait(0x22)) stop(2)
}
if (MCA_PAR[no]["PSE_MAC_MCA"] && MCA_PAR[no]["device_id"] == "Can556") {
tango_io(mca_spar(no, "address"), "Off")
} else
if (wait(0x24)) mca_spar(no, "halt")
}'
#%UU% [device_no]
#%MDESC% Clear memory for all active device or only on %B%device_no%B%.
def mcaclear '{
local ii
if ($#) {
_mcaio($1, "clear")
_mcaclear($1)
} else {
for (ii = 0; ii < MCAS; ii++) {
if (MCA_ACTIVE[ii]) {
_mcaio(ii, "clear")
_mcaclear(ii)
}
}
}
}'
#%IU% (no)
#%MDESC% Clear the memory and the arrays on MCA %B%no%B%.
def _mcaclear(no) '{
_mcaio(no, "clear")
_mcaarrayclear(no)
}'
#%IU% (no)
#%MDESC% Clear the memory and the arrays for MCA %B%no%B% if the device is on.
def _mcaclearct(no) '{
# Previous behaviour was clear always irrespectively of noclear flag and of being in a scan.
# Now it will always clear the first point of a scan or if noclear flag is 0
# or if we are not in a scan.
if ((NPTS == 0) || (!MCA_PAR[no]["noclear"]) || (!MCA_IN_SCAN))
{
if (MCA_ON[no])
_mcaio(no, "clear")
_mcaarrayclear(no)
}
}'
#%UU% [no] <preset_time>
#%MDESC% Set %B%preset_time%B% [s] for all active MCAs or only on MCA %B%no%B%.
def mcapreset '{
local ii
if ($# == 2) _mcapreset($1, $2)
else if ($# == 1) {
for (ii = 0; ii < MCAS; ii++) {
if (MCA_ACTIVE[ii]) _mcapreset(ii, $1)
}
} else
printf ("USAGE: mcapreset [<mca_no>] <preset_time>\n")
}'
#%IU% (no, pt)
#%MDESC% Set preset time to %B%pt%B% seconds on mca device %B%no%B%.
def _mcapreset(no, pt) '{
__MultiMCA_debug "_mcapreset: " pt
if (MCA_PAR[no]["PSE_MAC_MCA"] && MCA_PAR[no]["device_id"] == "Can556") {
tango_put(mca_spar(no, "address"), "PresetLiveTime", pt)
} else
if (mca_spar(no, "preset", pt)<0) {
_mcamsg(no, "Cannot preset time. Device set inactive.")
MCA_ACTIVE[no]= 0
}
}'
#%UU% [no]
#%MDESC% Start acquisition for all active MCAs or only on MCA %B%no%B%.
#%BR% !!No preset time set inside this macro: use mcapreset before.
def mcastart '{
local ii
if ($#) _mcastart($1)
else for (ii = 0; ii < MCAS; ii++) {
if (MCA_ACTIVE[ii]) _mcastart(ii)
}
}'
#%IU% (no)
#%MDESC% Start acquisition on MCA %B%no%B%.
def _mcastart(no) '{
if (MCA_PAR[no]["PSE_MAC_MCA"] && MCA_PAR[no]["device_id"] == "Can556") {
tango_io(mca_spar(no, "address"), "On")
} else
mca_spar(no, "run")
}'
#%UU% [no]
#%MDESC% Read data and times for all active MCAs or only on MCA %B%no%B%.
def mcaread '{
local ii
if ($#)
_mcaread($1)
else {
for (ii = 0; ii < MCAS; ii++) {
if (MCA_ACTIVE[ii])
_mcaread(ii)
}
}
mca_user_read
}'
#%IU% (no)
#%MDESC%read out data from mca device %B%no%B%
#%BR% Spectrum are stored in array %B%MCA_DATA<no>%B%
#%BR% Times are stored in array %B%MCA_TIMES%B%. To be used in user_getcounts.
def _mcareadct(no) '{
if (MCA_ON[no] == 1) {
if ((MCA_PAR[no]["whole"]) && (MCA_ROI[0] == 0)) {
mca_spar(no, "auto_run", 0)
MCA_ON[no] = 0
return(-1)
}
_mcaarrayread(no)
_mcatimes(no)
}
}'
#%IU% (no)
#%MDESC% read out data from mca device %B%no%B%
#%BR% Spectrum are stored in array %B%MCA_DATA<no>%B%
#%BR% Times are stored in array %B%MCA_TIMES%B%
def _mcaread(no) '{
_mcaarrayread(no)
_mcatimes(no)
}'
#%UU%
#%MDESC% Wait for all device to stop counting
def mcawait '{
local disp key, ii
disp = (MCA_PLOT_UPD<COUNT_TIME)?MCA_PLOT_UPD:COUNT_TIME
def _mca_innerloop \'
mcaread
mcatimes
if (MCA_PAR[no]["gui"])
mcaguiopen
mca_user_waitcounts
key = input(0)
if (key != "" && key != "\004") { mcakey key }
mca_user_key
sleep(disp)
\'
# somehow wait() doesn`t catch the get_status of the Can556_cmd().
# we`ll duplicate code here, ugly, but makes it work today !!!
if(MCA_PAR[no]["PSE_MAC_MCA"] && MCA_PAR[no]["device_id"] == "Can556") {
# no will come from the calling macro
while (!tango_io(mca_spar(no, "address"), "State")) {
_mca_innerloop
}
} else {
while (wait(0x26)) {
_mca_innerloop
}
}
}'
#%UU%
#%MDESC% On-line menu while waiting for acquisition to end.
def mcakey '{
if ($1 == "s"||$1 == "q") {
mcastop
print
_mcamsg("all", "MCA acquisition STOPPED.")
}
}'
# ---------------------------------------------------------
# TIMES REPORTING
# ---------------------------------------------------------
#%IU% (no)
#%MDESC% Read mca times and save it in array %B%MCA_TIMES%B%
def _mcatimes(no) '{
MCA_TIMES[no]["live"]= _mcaio(no, "elapsed_live")
MCA_TIMES[no]["real"]= _mcaio(no, "elapsed_real")
MCA_TIMES[no]["dead"]= _mcaio(no, "dead")
if(MCA_PAR[no]["PSE_MAC_MCA"] && MCA_PAR[no]["device_id"] == "Can556") {
if (MCA_TIMES[no]["real"] == 0)
MCA_TIMES[no]["dead"] = 0
else
MCA_TIMES[no]["dead"] = 100. * (MCA_TIMES[no]["real"] - MCA_TIMES[no]["live"]) / MCA_TIMES[no]["real"]
}
}'
#%UU%
#%MDESC% Print out live, real, dead times for all active devices.
#%BR%!!No read is performed: use macro mcaread before
def mcatimes '{
local pos ii
pos = 1
for (ii = MCAS-1; ii >= 0; ii--) {
if (MCA_ACTIVE[ii]) {
tty_move(0, -1*pos, \
sprintf("MCA %d Elapsed times: live %4.2f real %4.2f sec. dead time %3.2f %% ", \
ii, MCA_TIMES[ii]["live"], MCA_TIMES[ii]["real"], MCA_TIMES[ii]["dead"]))
}
pos++
}
}'
# ---------------------------------------------------------
# CALIBRATION
# ---------------------------------------------------------
#%UU% [ <no> <A> <B> <C> ]
#%MDESC% With no arguments, runs an interactive menu to set calib coeff.
#%BR% With input arguments, change the calibration shared array
def mcacalib '{
if ($# == 4)
_mcacalib($1, $2, $3, $4)
else
mcacalibmenu
}'
#%UU%
#%MDESC% Interactive menu to change calibration for all devices
def mcacalibmenu '{
local option il no carr
local key
while (1) {
il = _mcacalibshow()
tty_move(0, il++, \
"MCA number to change, \[us\]\[md\]S\[se\]\[ue\]ave, \[us\]\[md\]L\[se\]\[ue\]oad or \[us\]\[md\]Q\[se\]\[ue\]uit ? ")
# DOES NOT WORK ANYMORE WITH SPEC > 6.6.4
# while ((key = input(-1)) == "") { sleep(0.1) }
# key = substr(key, 1, 1)
key = getval_one_char("enter key (l, s, q)")
if (key == "q"||key == "Q") {
break
}
else if (key == "s"||key == "S") {
printf("\n")
mcacalibsave
input("\n... Press Enter ..."); continue
} else if (key == "l"||key == "L") {
printf("\n")
mcacalibload
input("\n... Press Enter ..."); continue
} else if (key == "\n")
continue
no = int(key)
if (no >= 0 && no < MCAS) {
printf("\n\n")
carr = sprintf("MCA_DATA%d_PARAM", no)
@carr[0]= getval("\tCoeff.A", @carr[0])
@carr[1]= getval("\tCoeff.B", @carr[1])
@carr[2]= getval("\tCoeff.C", @carr[2])
}
}
}'
#%IU% (no)
#%MDESC% Return the calibration for MCA %B%no%B%.
def _mcacalibget(no) '{
local carr
carr = sprintf("MCA_DATA%d_PARAM", no)
if (!whatis(carr)) {
shared double array @carr[3]
@carr[1] = 1
}
return(@carr)
}'
#%UU%
#%MDESC% Show current calibration of all devices
def mcacalibshow '_mcacalibshow()'
def _mcacalibshow() '{
local il carr
local no
clscreen()
tty_move(0, 1, "\[md\]<MCA CALIBRATION>\[me\]")
tty_move(0, 3, "MCA Coeff.A Coeff.B Coeff.C")
tty_move(0, 4, "--- ---------- ---------- ----------")
il = 5
for (no = 0; no < MCAS; no++) {
carr = sprintf("MCA_DATA%d_PARAM", no)
tty_move(0, il++, sprintf("\[us\]\[md\]%d\[me\]\[ue\] %10.10g %10.10g %10.10g", \
no, @carr[0], @carr[1], @carr[2]))
}
tty_move(0, il++, "")
return (il)
}'
#%IU% (no, ca, cb, cc)
#%MDESC% Change calibration coeff for mca %B%no%B%.
def _mcacalib(no, ca, cb, cc, silent) '{
local carr
carr = sprintf("MCA_DATA%d_PARAM", no)
if (!whatis(carr)) {
if (!silent)
_mcamsg(no, "NO calibration array. Run mcasetup first.")
} else {
@carr[0]= ca
@carr[1]= cb
@carr[2]= cc
}
}'
#%UU% [<filename>]
#%MDESC% Save current calibrations to file
#%BR% If no <filename> is specified, use default one.
#%BR% Default filename is BLISSADM/local/spec/userconf/mcacalib.USER
def mcacalibsave '{
local filename no carr
if ($# == 1) {
filename = "$1"
}
else {
filename = sprintf("%s/local/spec/userconf/mcacalib.%s", BLISSADM, USER)
}
unix(sprintf("/bin/rm -f %s", filename))
if (on(filename) == -1) {
_mcamsg("all", sprintf("Cannot open file %s", filename))
}
else {
offt
for (no = 0; no < MCAS; no++) {
carr = sprintf("MCA_DATA%d_PARAM", no)
printf("%d %g %g %g\n", no, \
@carr[0], @carr[1], @carr[2])
}
ont; close(filename)
_mcamsg("all", sprintf("Calibrations saved to %s", filename))
}
}'
#%UU% [<filename>]
#%MDESC% Load MCA calibrations from file. This overrides current calibrations
#%BR% If no <filename> is specified, use default one.
#%BR% Default filename is BLISSADM/local/spec/userconf/mcacalib.USER
def mcacalibload '{
local file cno totcal line pars[]
if ($# == 1) {
file = "$1"
}
else {
file = sprintf("%s/local/spec/userconf/mcacalib.%s", \
BLISSADM, USER)
}
if (unix(sprintf("test -r %s", file))) {
_mcamsg("all", sprintf("Cannot find calibration file %s", file))
}
else {
totcal = 0
for (line = getline(file);line != -1;line = getline(file)) {
if (split(line, pars) == 4) {
cno = int(pars[0])
if ((cno >= 0) || (cno < MCAS)) {
_mcacalib(cno, pars[1]+0, \
pars[2]+0, pars[3]+0, 1)
totcal++
} else
print "Invalid MCA:", pars[0]
}
}
getline(file, "close")
_mcamsg("all", sprintf("%d calibrations have been loaded from %s", totcal, file))
}
}'
# ---------------------------------------------------------
# ROIS
# ---------------------------------------------------------
#%UU% [<roi_mne> <mca_dev> <roi_min> <roi_max> <roi_alias>]
#%MDESC% Define a new roi. If no arguments is given, call mcaroimenu.
#%BR% %B%roi_mne%B% : counter mnemonic
#%BR% %B%mca_dev%B% : mca device number
#%BR% %B%roi_min%B% : roi first channel
#%BR% %B%roi_max%B% : roi last channel
#%BR% %B%roi_alias%B% : roi alias
#%BR% %B%mmax_ch%B% : mmax channel (if appropriate)
#
def mcaroi '{
if ($# == 4)
_mcaroiadd("$1", $2, $3, $4, "$5", $6)
else
mcaroimenu
}'
#%UU% <roi_mne>
#%MDESC% Deletes ROI <roi_mne>
def mcaroidel '{
if ($# != 1)
printf("USAGE: mcadelroi <roi_mne>\n")
else
_mcaroidel($1)
}'
#%UU%
#%MDESC% Menu to Add/Modify/Delete/Save/Load rois
def mcaroimenu '{
local key nb dev min max nroi
local mmax_ch
local ip
if (list_n(MCA_ROI)<0) list_init MCA_ROI
while (1) {
ip = _mcaroishow()
tty_move(0, ip++, \
"\[md\]A\[se\]dd/\[md\]D\[se\]elete/\[md\]M\[se\]odify, \[md\]S\[se\]ave/\[md\]L\[se\]oad or \[md\]Q\[se\]uit ? ")
printf("\n\n")
key = getval_one_char("enter key (d, a, m, s, l, q)")
printf("\n\n")
if (key == "d"||key == "D") {
roi = getval("\tCounter mnemonic ", 0)
if (roi != "0")
_mcaroidel(roi)
} else if (key == "a" || key == "A") {
roi = getval("\tCounter mnemonic ", 0)
if (roi != "0") {
dev = getval("\tMCA device number ", 0)
min = getval("\tFirst channel ", 0)
max = getval("\tLast channel ", 1023)
alias = getval("\tROI alias ", alias)
if (MCA_PAR[dev]["type"] == 1) {
mmax_ch = getval("\tMMAX channel number (1-8):", 1)
list_setpar(MCA_ROI, roi, "mmax_ch", mmax_ch)
}
_mcaroiadd(roi, dev, min, max, alias, mmax_ch)
}
} else if (key == "m" || key == "M") {
roi = getval("\nCounter mnemonic ", roi)
if (list_check(MCA_ROI, roi) > 0) {
dev = getval("\tMCA device number ", MCA_ROI[roi]["device"])
min = getval("\tFirst channel ", MCA_ROI[roi]["min"])
max = getval("\tLast channel ", MCA_ROI[roi]["max"])
alias = getval("\tROI alias ", MCA_ROI[roi]["alias"])
nroi = getval("\tNew mnemonic ", roi)
if (MCA_PAR[dev]["type"] == 1)
mmax_ch = getval("\tMMAX channel number (1-8):", \
MCA_ROI[roi]["mmax_ch"])
if (nroi == roi) {
MCA_ROI[roi]["device"] = dev
MCA_ROI[roi]["min"] = min
MCA_ROI[roi]["max"] = max
MCA_ROI[roi]["emin"] = _mcagetE(dev, min)
MCA_ROI[roi]["emax"] = _mcagetE(dev, max)
MCA_ROI[roi]["alias"] = alias
MCA_ROI[roi]["cntconf"] = cnt_num(roi)
if (MCA_PAR[dev]["type"] == 1) {
MCA_ROI[roi]["mmax_ch"] = mmax_ch
_mcammaxroiadd(dev, MCA_ROI[roi]["emin"], MCA_ROI[roi]["emax"], \
alias, mmax_ch, 11)
}
} else {
_mcaroidel(roi)
_mcaroiadd(nroi, dev, min, max, alias, mmax_ch)
}
}
} else if (key == "s" || key == "S") {
mcaroisave
input("... Press Enter ...")
} else if (key == "l" || key == "L") {
mcaroiload
input("... Press Enter ...")
} else if (key == "q" || key == "Q") {
break
}
}
}'
#%UU%
#%MDESC% Show ROIs definition
#
def mcaroishow '_mcaroishow()'
def _mcaroishow() '{
local ip im ir nroi
local chmin chmax emin emax str alias
local carr
local mstr[] mmax_ch
if ((nroi = list_n(MCA_ROI))<0) {
list_init MCA_ROI
nroi = 0
}
clscreen()
tty_move(0, 1, "\[md\]<MCA ROI Definition>\[me\]")
mstr[3] = sprintf("Counter | MCA | From | To | | | ROI |")
mstr[4] = sprintf("mnemonic| # | chan | chan | Eini | Efin | alias |")
mstr[5] = sprintf("--------|-----|-------|-------|-------|-------|--------|")
if (MCA_PAR[no]["type"] == 1) {
mstr[3] = sprintf ("%s MMAX |", mstr[3])
mstr[4] = sprintf ("%s chan |", mstr[4])
mstr[5] = sprintf ("%s------|", mstr[5])
}
for (ip = 3; ip<6; ip++) {
tty_move(0, ip, mstr[ip])
}
for (im = 0; im < MCAS; im++) {
for (ir = 1; ir <= nroi; ir++) {
if (list_getpar(MCA_ROI, ir, "device") == im) {
chmin = list_getpar(MCA_ROI, ir, "min")
chmax = list_getpar(MCA_ROI, ir, "max")
carr = sprintf("MCA_DATA%d_PARAM", im)
if (@carr[0] != 0) {
emin = _mcagetE(im, chmin)
emax = _mcagetE(im, chmax)
list_setpar(MCA_ROI, ir, "emin", emin)
list_setpar(MCA_ROI, ir, "emax", emax)
} else {
emin = list_getpar(MCA_ROI, ir, "emin")
emax = list_getpar(MCA_ROI, ir, "emax")
}
alias = list_getpar(MCA_ROI, ir, "alias")
mmax_ch = list_getpar(MCA_ROI, ir, "mmax_ch")
if (mmax_ch == -1)
mmax_ch = " "
str = sprintf("%-8s| %-2d | %-5d | %-5d | %-5d | %-5d | %-7s|", \
list_item(MCA_ROI, ir), list_getpar(MCA_ROI, ir, "device"), \
chmin, chmax, emin, emax, alias)
if (@carr[0] != 0)
str = sprintf("%-8s| %-2d | %-5d | %-5d | %-5.2f | %-5.2f | %-7s|", \
list_item(MCA_ROI, ir), list_getpar(MCA_ROI, ir, "device"), \
chmin, chmax, emin, emax, alias)
if (MCA_PAR[no]["type"] == 1)
str = sprintf ("%s %-2s |", str, mmax_ch)
tty_move(0, ip++, str)
}
}
}
ip++
return (ip)
}'
#%IU% (dev, cnt, min, max, alias)
#%MDESC% Add roi in the list
#
def _mcaroiadd(cnt, dev, min, max, alias, mmax_ch) '{
local emin emax type
global _MCA_ROI_ADD
if (list_n(MCA_ROI)<0) {
list_init MCA_ROI
}
list_add(MCA_ROI, cnt)
list_setpar(MCA_ROI, cnt, "device", dev)
list_setpar(MCA_ROI, cnt, "min", min)
list_setpar(MCA_ROI, cnt, "max", max)
emin = _mcagetE(dev, min)
emax = _mcagetE(dev, max)
list_setpar(MCA_ROI, cnt, "emin", emin)
list_setpar(MCA_ROI, cnt, "emax", emax)
if (alias){
list_setpar(MCA_ROI, cnt, "alias", alias)
}
else{
list_setpar(MCA_ROI, cnt, "alias", cnt)
}
type = MCA_PAR[dev]["type"]
if (type == 1) {
if ((emin <= 30) && (emin > 0) && (emax > 0) && (emax <= 30)){
if (mmax_ch == 0)
mmax_ch = 1
nb = list_getpar(MCA_ROI, cnt, "elem_nb")
if (nb == -1)
nb = 11
_mcammaxroiadd(dev, emin, emax, alias, mmax_ch, nb)
list_setpar(MCA_ROI, cnt, "mmax_ch", mmax_ch)
}
}
list_setpar(MCA_ROI, cnt, "cntconf", cnt_num(cnt))
_MCA_ROI_ADD = cnt
mca_user_roi_add
}'
def _mcammaxroiadd(dev, emin, emax, alias, mmax_ch, nb) '{
global cmd
cmd = sprintf("%d %d %s %d %d", mmax_ch, nb, alias, \
int(emin*1000), int(emax*1000))
p cmd
#return(esrf_io(dev, "DevMcaSetROI", cmd))
}'
#%IU% (nb, ch)
#%MDESC% Return the energy [keV] as function of the channel %B%ch%B% for the MCA number %B%nb%B%
def _mcagetE(nb, ch) '{
local carr
carr = sprintf("MCA_DATA%d_PARAM", nb)
return(@carr[0] + @carr[1] * ch + @carr[2] * pow(ch, 2))
}'
#%IU% (nb, en)
#%MDESC% Return the channel as function of the energy %B%en%B% [keV] for the MCA number %B%nb%B%
def _mcagetch(nb, en) '{
local carr
carr = sprintf("MCA_DATA%d_PARAM", nb)
if (@carr[2] == 0) {
if (@carr[1] != 0)
return(int((en - @carr[0])/@carr[1]))
else
return(0)
}
if (@carr[1] > 0)
return (int((-@carr[1]+sqrt(pow(@carr[1], 2)-4*(@carr[0]-en)*@carr[2]))/(2*@carr[2])))
if (@carr[1] < 0)
return (int((-@carr[1]-sqrt(pow(@carr[1], 2)-4*(@carr[0]-en)*@carr[2]))/(2*@carr[2])))
}'
#%IU% (cnt)
#%MDESC% Delete roi from the list
def _mcaroidel(cnt) '{
global _MCA_ROI_DEL
_MCA_ROI_DEL = cnt
mca_user_roi_delete
list_remove(MCA_ROI, cnt)
}'
def _mcareadroi(no) '{
local i cnt
if (MCA_ON[no]) {
for (i = 1; i <= MCA_ROI[0]; i++) {
cnt = MCA_ROI[i]
if (MCA_ROI[cnt]["device"] == no)
_mcaroicounts(MCA_ROI[i])
}
}
}'
#%IU% (cnt)
#%MDESC% Hook macro to update roi counter's value
def _mcaroicounts(cnt) '{
local idev mne darr min max num
num = cnt_num(cnt)
if (num == -1)
return(-1)
mne = cnt_mne(num)
if (counter_par(mne, "disable") != 0)
return(-1)
darr = sprintf("MCA_DATA%d", list_getpar(MCA_ROI, mne, "device"))
min = list_getpar(MCA_ROI, mne, "min")
max = list_getpar(MCA_ROI, mne, "max")
S[num] = array_op("sum", @darr[min:max][1])
}'
#%UU% [<filename>]
#%MDESC% Save current rois definition to file
#%BR% If no <filename> is specified, use default one.
#%BR% Default filename is BLISSADM/local/spec/userconf/mcaroi.def.USER
#
def mcaroisave '{
local roi mne filename
if ($# == 1) {
filename = "$1"
} else {
filename = sprintf("%s/local/spec/userconf/mcaroi.def.%s", BLISSADM, USER)
}
unix(sprintf("/bin/rm -f %s", filename))
if (on(filename) == -1) {
_mcamsg("all", sprintf("Cannot open file %s", filename))
} else {
offt
for (roi = 1; roi <= list_n(MCA_ROI); roi++) {
mne = list_item(MCA_ROI, roi)
printf("%s %2d %5d %5d %5.2f %5.2f %s\n", mne, \
list_getpar(MCA_ROI, mne, "device"), list_getpar(MCA_ROI, mne, "min"), \
list_getpar(MCA_ROI, mne, "max"), list_getpar(MCA_ROI, mne, "emin"), \
list_getpar(MCA_ROI, mne, "emax"), list_getpar(MCA_ROI, mne, "alias"))
}
ont; close(filename)
_mcamsg("all", sprintf("ROI saved to %s", filename))
}
}'
#%UU% [<filename>]
#%MDESC% Load rois definition from file. This overrides current rois definition.
#%BR% If no <filename> is specified, use default one.
#%BR% Default filename is BLISSADM/local/spec/userconf/mcaroi.def.USER
#
def mcaroiload '{
local file ir line pars[]
local alias
if ($# == 1) {
file = "$1"
} else {
file = sprintf("%s/local/spec/userconf/mcaroi.def.%s", BLISSADM, USER)
}
if (unix(sprintf("test -r %s", file))) {
_mcamsg("all", sprintf("Cannot find roi file %s", file))
} else {
for (ir = 1; ir <= list_n(MCA_ROI); ir++)
_mcaroidel(list_item(MCA_ROI, ir))
list_init MCA_ROI
for (line = getline(file);line != -1;line = getline(file)) {
if (split(line, pars) >= 4) {
alias = substr(pars[6], 1, length(pars[6]))
_mcaroiadd(pars[0], int(pars[1]), int(pars[2]), int(pars[3]), alias)
}
}
getline(file, "close")
_mcamsg("all", sprintf("%d rois have been loaded from %s", \
list_n(MCA_ROI), file))
}
}'
# ---------------------------------------------------------
# PLOTTING
# ---------------------------------------------------------
#%UU% [<no>]
#%MDESC% Set GUI ON for all mca device or just device <no>
#%BR% If not already opened, open gui if device is active
def mcaguion '{
local ii
if ($#) {
MCA_PAR[$1]["gui"] = $2
_mcaguion($1)
} else for (ii = 0; ii < MCAS; ii++) {
_mcaguion(ii)
}
}'
#%IU% (no)
#%MDESC% Set GUI ON for device <no>
def _mcaguion(no) '{
if (MCA_ACTIVE[no]) _mcaguiopen(no)
else _mcaguiclose(no)
}'
#%IU% [<no>]
#%MDESC% Set GUI OFF for all device or just device <no>
#%BR% Close gui if opened.
def mcaguioff '{
local ii
if ($#) _mcaguioff($1)
else for (ii = 0; ii < MCAS; ii++)
_mcaguiclose(ii)
}'
#%IU% (no)
#%MDESC% Set GUI OFF for device <no>
def _mcaguioff(no) '{
MCA_PAR[no]["gui"]= 0
_mcaguiclose(no)
}'
#%UU% [<device_no>]
#%MDESC% Open GUI for <device_no>, or for all active device if <device_no> not specified
def mcaguiopen '{
local ii
if ($#) _mcaguiopen($1)
else for (ii = 0; ii < MCAS; ii++)
if (MCA_ACTIVE[ii]&&MCA_PAR[ii]["gui"]) _mcaguiopen(ii)
}'
def _mcaguiopen(no) '{
if (MCA_PAR[no]["gui"]) {
if (MCA_PAR[no]["guiconf"] != MCA_PAR[no]["gui"]) {
MCA_PAR[no]["guiconf"] = MCA_PAR[no]["gui"]
_mcaguiclose(no)
MCA_PAR[no]["gui"] = MCA_PAR[no]["guiconf"]
} else
MCA_PAR[no]["guiconf"] = MCA_PAR[no]["gui"]
} else
MCA_PAR[no]["gui"] = MCA_PAR[no]["guiconf"]
if (!MCA_PID[no] || unix(sprintf("kill -0 %d 2>/dev/null", MCA_PID[no])))
MCA_PID[no]= _mcaguistart(no)
}'
#%UU% [<device_no>]
#%MDESC% Close GUI for <device_no>, or for all devices if <device_no> not specified
def mcaguiclose '{
local ii
if ($#) _mcaguiclose($1)
else for (ii = 0; ii<MCAS; ii++)
_mcaguiclose(ii)
}'
def _mcaguiclose(no) '{
if (MCA_PID[no])
unix(sprintf("kill -9 %d 2>/dev/null", MCA_PID[no]))
MCA_PID[no]= 0
MCA_PAR[no]["gui"] = 0
}'
def _mcaguistart(no) '{
local mystr
local pid file guicmd larr
__MultiMCA_debug "### starting _mcaguistart"
if (MCA_PAR[no]["gui"] == 1) {
file = sprintf("/tmp/mcagui_%d_%s_%s.pid", no, SPEC, USER)
larr = sprintf("MCA_DATA%d", no)
guicmd = sprintf("mcatcl -ver %s -shm %s", SPEC, larr)
} else if (MCA_PAR[no]["gui"] == 2) {
file = sprintf("/tmp/mcagui_%d_%s_%s.pid", no, SPEC, USER)
larr = sprintf("MCA_DATA%d", no)
guicmd = sprintf("pymca --spec=%s --shm=%s", SPEC, larr)
__MultiMCA_debug "### guicmd: " guicmd
} else if (MCA_PAR[no]["gui"] == 3) {
larr = sprintf("MCA_DATA%d_PARAM", no)
mystr = sprintf ("%g:%g:%g", @larr[0], @larr[1], @larr[2])
larr = sprintf("MCA_DATA%d_ENV", no)
shared string array @larr [50][50]
SPS_PutEnv(@larr, "calibration", mystr)
file = sprintf("/tmp/mcagui_%d_%s_%s.pid", no, SPEC, USER)
larr = sprintf("MCA_DATA%d", no)
guicmd = sprintf("newplot -s %s --shm=%s", SPEC, larr)
}
if (!unix(sprintf("test -r %s", file))) {
pid = getline(file)
getline(file, "close")
if (pid && !unix(sprintf("kill -0 %d 2>/dev/null", pid))) {
return(pid)
}
}
unix(sprintf("%s >/dev/null 2>&1 & echo \$! > %s", guicmd, file))
pid = getline(file)
getline(file, "close")
return (pid)
}'
# ---------------------------------------------------------
# FILE SAVING
# ---------------------------------------------------------
#%IU%<device_no>
#%MDESC% Save MCA specific header during a scan
def mcasavescanheader '{
local ii
if ((MCA_ON[$1]) && (MCA_SAVE[$1]["scan"]) && (MCA_SAVE[$1]["std"])) {
savemultimcaheader(DATAFILE, $1, 0)
}
}'
#%IU%<device_no>
#%MDESC% Save MCA data during a scan
def mcasavescandata '{
local ii
if (MCA_ON[$1] && (MCA_SAVE[$1]["scan"])) {
if (MCA_SAVE[$1]["std"]) {
savemultimcadata(DATAFILE, $1)
} else {
mcasaveprivate($1, 1)
}
}
}'
#%IU%
#%MDESC% Save mca header and data after a ct
def mcasavect '{
local ii nbstd nbpriv
local std[] priv[]
nbstd = 0
nbpriv = 0
for (ii = 0; ii < MCAS; ii++) {
if (MCA_ON[ii] && MCA_SAVE[ii]["acq"]) {
if (MCA_SAVE[ii]["std"]) {
std[nbstd]= ii
nbstd++
} else {
priv[nbpriv]= ii
nbpriv++
}
}
}
if (nbpriv||nbstd) {
HEADING = sprintf("ct %s", COUNT_TIME)
DATE = date()
if (nbpriv) {
for (ii = 0; ii<nbpriv; ii++)
mcasaveprivate(priv[ii], 0)
MCA_N++
}
if (nbstd)
mcasavestandard(nbstd, std, 1)
}
}'
#%IU%
#%MDESC% Save mca header and data after a mcaacq
def mcasaveacq '{
local ii nbstd nbpriv
local std[]
nbstd = 0
nbpriv = 0
for (ii = 0; ii<MCAS; ii++) {
if (MCA_ACTIVE[ii] && MCA_SAVE[ii]["acq"]) {
if (MCA_SAVE[ii]["std"]) {
std[nbstd]= ii
nbstd++
} else {
mcasaveprivate(ii, 0)
nbpriv++
}
}
}
if (nbpriv) MCA_N++
if (nbstd) mcasavestandard(nbstd, std, 0)
}'
#%UU%
#%MDESC% Save last acquisition for all active devices
#%BR% Do not consider saving options: save all in mca files
def mcasavelast '{
local ii
MCA_N++
for (ii = 0; ii<MCAS; ii++) {
if (MCA_ACTIVE[ii]) mcasaveprivate(ii, 0)
}
}'
#%IU%
#%MDESC% Save mca header and data in standard spec datafile
def mcasavestandard(nb, std, inct) '{
if (!_mcasavestandard(nb, std, inct)) {
_mcamsg("all", "ERROR saving spectrum to standard file")
}
}'
#%IU% (nb, std, inct)
def _mcasavestandard(nb, std, inct) '{
local ii
SCAN_N = savestdheader(DATAFILE, 3, SCAN_N)
if (SCAN_N<0) {
SCAN_N = -SCAN_N
return (0)
}
for (ii = 0; ii < nb; ii++)
if (!savemultimcaheader(DATAFILE, std[ii])) return (0)
if (inct) {
FPRNT = ""
if (savecntheader(DATAFILE)<0) return (0)
if (savecounters(DATAFILE)<0) return (0)
}
for (ii = 0; ii < nb; ii++)
if (!savemultimcadata(DATAFILE, std[ii])) return (0)
return (1)
}'
#%IU% (no)
#%MDESC% Save MCA header and data in a private file
#%BR% Return 1 on success, 0 otherwise
#
def mcasaveprivate(no, inscan) '{
local filename ret
filename = mcafilename(no, inscan)
if (!filename) return (0)
ret = 1
if (savefileheader(filename) < 0) { ret = 0 }
if (ret && savestdheader(filename, 3, 0) == -1) { ret = 0 }
if (ret) ret = savemultimcaheader(filename, no, inscan?0:1)
if (!inscan) {
FPRNT = ""
if (ret) ret = (savecntheader(filename) >= 0)
if (ret) ret = (savecounters(filename) >= 0)
}
if (ret) ret = savemultimcadata(filename, no)
if (!ret) _mcamsg(no, sprintf("Failed to save spectrum in %s", filename))
else if (!inscan) _mcamsg(no, sprintf("Saved spectrum to %s", filename))
close(filename)
}'
#%IU% (no, inscan)
#%MDESC% Create filename for specific mca files
#
def mcafilename(no, inscan) '{
local prefix fname
prefix = MCA_SAVE[no]["prefix"]
if ((prefix == "/dev/null")||(prefix == "/dev/tty")) return prefix
if ((prefix == "")||(prefix == "0")) return 0
if (!MCA_SAVE[no]["onefile"])
fname = sprintf("%s%s", prefix, MCA_SUFFIX)
else {
if (inscan) {
fname = sprintf("%s_%d_%03d_%03d%s", prefix, no, SCAN_N, NPTS, MCA_SUFFIX)
} else {
fname = sprintf("%s_%d_%03d%s", prefix, no, MCA_N, MCA_SUFFIX)
}
}
return (fname)
}'
#%IU% (file, no, withtime)
#%MDESC% Save MCA specific header for device <no>
#%BR% If <withtime>!= 0, save counting, live and real times
#%BR% Return 1 on sucess, 0 otherwise
#
def savemultimcaheader(file, no, withtime) '{
local cmin cmax npts
local carr
local nroi
if (open(file)) return (0)
fprintf(file, "#@MCADEV %d\n", no)
fprintf(file, "#@MCA %s\n", MCA_SAVE[no]["fmt"])
cmin = MCA_SAVE[no]["cmin"]
cmax = MCA_SAVE[no]["cmax"]
#cmax = MCA_MEM[no]["size"]-1
npts = int(cmax/MCA_SAVE[no]["red"]) - int(cmin/MCA_SAVE[no]["red"]) +1
npts = npts<0?0:npts
fprintf(file, "#@CHANN %g %g %g %g\n", npts, cmin, cmax, MCA_SAVE[no]["red"])
if (withtime) {
fprintf(file, "#@CTIME %g %g %g\n", COUNT_TIME, \
MCA_TIMES[no]["live"], MCA_TIMES[no]["real"])
}
carr = sprintf("MCA_DATA%d_PARAM", no)
fprintf(file, "#@CALIB %g %g %g\n", @carr[0], @carr[1], @carr[2])
nroi = list_n(MCA_ROI)
for (ir = 1; ir <= nroi; ir++) {
dev = list_getpar(MCA_ROI, ir, "device")
if (dev == no) {
fprintf(file, "#@ROI %s %g %g\n", list_item(MCA_ROI, ir), \
list_getpar(MCA_ROI, ir, "min"), list_getpar(MCA_ROI, ir, "max"))
}
}
return (1)
}'
#%IU% (file, no)
#%MDESC% Save MCA spectrum data for device <no>
#%BR% Return 1 on sucess, 0 otherwise
#
def savemultimcadata(file, no) '{
local darr chan[]
if (open(file)) return (0)
if (MCA_SAVE[no]["red"]>1) {
_mcadatareduction(no)
darr = sprintf("MCA_DATARED%d", no)
chan[0] = int(MCA_SAVE[no]["cmin"]/MCA_SAVE[no]["red"])
chan[1] = int(MCA_SAVE[no]["cmax"]/MCA_SAVE[no]["red"])
} else {
darr = sprintf("MCA_DATA%d", no)
chan[0] = MCA_SAVE[no]["cmin"]
chan[1] = MCA_SAVE[no]["cmax"]
}
fprintf(file, "@A ")
on(file);offt
data_dump(@darr[chan[0]:chan[1]][1], MCA_SAVE[no]["fmt"])
ont; off(file)
return (1)
}'
#%IU% (no)
#%MDESC% Computes reduction on %B%MCA_DATA<no>%B%. Results are stored in %B%MCA_DATARED<no>%B%
#
def _mcadatareduction(no) '{
local darr rarr
darr = sprintf("MCA_DATA%d", no)
rarr = sprintf("MCA_DATARED%d", no)
@rarr[][1]= MCA_SAVE[no]["red"]*array_op("contract", @darr[][1], MCA_SAVE[no]["red"])
}'
# ---------------------------------------------
# Copy data of all MCA_DATAn arrays in MCA_DATA
# ---------------------------------------------
#%UU%
#%MDESC% Read data from all mca ON (arrays MCA_DATAn) and save data in array MCA_DATA
#%BR% Data are written in MCA_DATA in the same order as in spec configuration
def mcalineupon '{
local size
size = _mcalineupsize()
if (size>0) {
ulong array MCA_DATA[size][2]
array_op("fill", MCA_DATA[][0])
cdef("user_prepcount", "_mcalineupclear\n", "_lpmca", 0x20)
cdef("user_getcounts", "_mcalineupdata\n", "_lpmca", 0x20)
cdef("mca_user_read", "_mcalineupdata\n", "_lpmca", 0x20)
}
}'
#%IU% ()
#%MDESC% Computes size needed for MCA_DATA to store all MCA_DATAn arrays
def _mcalineupsize() '{
local size ii
size = 0
for (ii = 0; ii < MCAS; ii++) {
if (MCA_ON[ii]) { size += MCA_MEM[ii]["size"] }
}
return (size)
}'
#%IU%
#%MDESC% Macro used in all read hooks to fillup MCA_DATA
def _mcalineupdata '{
local ii size darr beg
beg = 0
for (ii = 0; ii < MCAS; ii++) {
if (MCA_ON[ii]) {
size = MCA_MEM[ii]["size"]-1
darr = sprintf("MCA_DATA%d", ii)
MCA_DATA[beg:beg+size][1]= @darr[0:size][1]
beg = beg+size+1
}
}
}'
#%IU%
#%MDESC% Clear MCA_DATA
def _mcalineupclear '{
MCA_DATA[][1]= 0
}'
#%UU%
#%MDESC% Set lineup facility off. MCA_DATA is not updated anymore
def mcalineupoff '{
cdef("", "", "_lpmca", "delete")
}'
def mcatype '{
local i pars[] nb
nb = split("$*", pars)
if (nb == 0) {
for (i = 0; i<MCAS; i++)
_mcatype(i)
} else if ((nb %2) == 0) {
for (i = 0; i < nb; i += 2)
_mcatype(pars[i], pars[i+1], 1)
} else {
if ((pars[0] >= MCAS) || (pars[0] < 0))
eprintf ("MCA #%d not configured\n", pars[0])
else
_mcatype(pars[0])
}
}'
def _mcatype(no, type, flag) '{
local str
if (flag)
MCA_PAR[no]["type"] = type
else
type = MCA_PAR[no]["type"]
printf("MCA #%d controller type: ", no)
type == 0 ? (str = "AIM/MAX") : type == 1 ? (str = "MMAX"): \
type == 2 ? (str = "MUSST") : (str = "????")
tty_cntl("md")
printf("<%s>\n", str)
tty_cntl("me")
}'
# ----------------------------------------
# user hook macros
# ----------------------------------------
if (!(whatis("mca_user_waitcounts")&2)) {
rdef mca_user_waitcounts \'\'
}
if (!(whatis("mca_user_key")&2)) {
rdef mca_user_key \'\'
}
if (!(whatis("mca_user_read")&2)) {
rdef mca_user_read \'\'
}
cdef("mca_user_roi_add", "", "multimca")
cdef("mca_user_roi_delete", "", "multimca")
cdef("end_mac", "mcaguiclose;", "mca")
#%MACROS%
#%IMACROS%
#%DEPENDENCIES% %B%saveload.mac%B% %B%sps.mac%B%
#%AUTHOR%
# MC.Lagier, E.Papillon, A.Beteva %BR%
# $Revision: 1.45 $ / $Date: 2022/12/05 16:00:36 $
#%TOC%
|