spec

Software for Diffraction

acq

MCA/Image Acquisition and Region of Interest Configuration

DESCRIPTION

The MCA/Image acquisition macros create dynamic region of interest (ROI) counters for 1D (MCA-type) or 2D (image-type) hardware controllers and configure whether data from these devices is read and saved during scans.

The acqsetup macro presents an interactive menu that selects which acquisition devices to read and is used to configure ROI counters for each device. The ROI counters behave identically to counters created via the hardware configuration file but are dynamic, in that they are created at run time and only exist during the current session.

For each MCA and image device, acqsetup configures a number of options in addition to the ROI configuration:

  • Whether to program the device with the count time. If not so programmed the device will be started and stopped either by hardware gating, if so connected, or software gating.
  • Whether to read the device (even if no ROI counters). One might want to read the device for a real-time display, but not save the data.
  • Whether to save the obtained spectrum to a data file.
  • For MCA devices, whether to plot the data using spec's X11 plotting after reading.
  • Whether to read the device during updated counting. If reading is slow, one might prefer to read once at the end of the count interval.

For each device, ROI counters can be defined. An ROI defines a region on the detector where pixel values are combined to form a single value. The current macros support the operations sum, average value, minimum value and maximum value. The default operation is to return the sum of the pixels.

For an MCA-type detector, the ROI is defined by a beginning and ending channel. For an image detector, the ROI is defined by beginning and ending row and column numbers. For both, if no region is specified, the entire pixel range will be used for the operation.

The ROI configuration information is stored in the ROI_info[][] global associative array. The first index identifies the controller using the string "mca" or "img" with the unit number appended. The second index is the counter mnemonic. The value of each array element is a string with five components separated by colons. The components are described in description of roiconf below.

The acqsetup macro also configures how to save acquired spectra to a data file. By default, spectra are included in the standard spec data file. The menu provides option to store spectra in a different file. There can be one file for all spectra, one file per scan, one file per data point or one file per spectra. One can choose automatic file name generation, where the spectra are stored in file names beginning with the value of DATAFILE, with scan number, point number and array name appended, as appropriate. The files will have the extension .arr. Alternatively, a filename template can be entered that can include items such as the main data file name, the scan number, the point number and the array name as part of the file name. See the newfile help file for information on templates.

Currently the only option is to use ASCII format in the separate files. Binary format support in the macros is coming.

If using X11 plotting, a configuration option turns on automatic X11 plotting after each read of MCA data. X11 "filters" numbered one through nine are available for plotting. One or more may be dedicated to scaler counters selected via the counters or plotselect macros. The acquisition macros select an unused filter for each MCA to be plotted. If no more filters are available, the MCA data will not be plotted. Note, the MCA X11 plots will be created if this configuration option is enabled even if X11 plotting is disabled in setplot.

If using Python splot plotting, both MCA and image data can be automatically plotted by splot whenever the data is updated as the data is put into shared-data arrays. To configure splot plots for MCA or image data, choose SPEC->Display Variable in the splot menu, and select the desired shared-data array in the pop-up window. The newly created splot tab can be detached by dragging.

Flags associated with configuration options as to how to read the MCA or image device are stored in the ACQ_flags[] global associative array as bit flags. The array index is the string "mca" or "img" with the controller unit number appended. Bits are associated with the configuration options described above.

Some MCA and image controllers allow multiple modules to be associated with a single unit. For these, spec supports a unit plus module addressing syntax. The functions mca_spar(), mca_sget(), mca_sput(), image_par(), image_get() and image_put() recognize the syntax. If U is the unit number and M is the module number, unit plus module can be specified as U.M "U.M" or "U:M". That is, the functions treat the first argument as a string, even if in the case of using the decimal point, the quotation marks are missing. If there are multiple modules, the unit numbers used as the array indexes in ROI_info[][] and ACQ_flags[] have a ".M" appended.

Some MCA and image hardware controllers may return ROI values directly, indicated by the return value of the "hdw_roi?" mca_par()/mca_spar()/image_par() call. If such a feature is implemented, the macros don't read the spectra or create the data array solely to obtain ROI values.

When a controller is disabled or turned "OFF" in the spec hardware configuration file, the associated configuration in ROI_info and ACQ_flags is preserved, but the associated counters are not created.

Note, the ROI region can be selected directly when displaying 1D or 2D data from the Data menu in the Python splot utility.

MACRO DESCRIPTIONS

acqsetup (also roisetup, acq_setup and roi_setup)
Presents an interactive menu to enter acquisition device configuration parameters. MCA and image devices can be configured to collect region-of-interest counter values and/or to collect spectra or images to save. Use q to save and quit, ^C to discard changes and quit.
_roi_mne_check()
Called from the spec_menu() function to validate whether a chosen counter mnemonic is allowed. A counter_par() "add" call will produce an error if the choice is not allowed. The error will be displayed in the menu. A "delete" call removes the mnemonic. The choices will be properly added when acqsetup finishes.
roiconf controller mne name [op [range]]

A one-line alternative to the acqsetup menu to create and/or reconfigure a single ROI counter. Parameters are:

controller
Selects the controller type and unit. The format is mca# or img#, where # is the unit number of the controller in the spec hardware config file. If the controller unit has multiple modules, use #.M after mca or img, where M is the module number. Modules numbers start from zero.
mne
Counter mnemonic to be added, up to seven characters. Must not conflict with other mnemonics, macro names or global variables.
name
Counter name, up to 15 characters. If spaces are included, surround argument with quotes.
op
Operation to be applied over the region of interest to obtain the counter value. Must be one of sum, ave, max or min, where sum is the summation of all points in the ROI, ave is the sum divided by the number of points, max is the highest value in the ROI and min is the lowest value. An unrecognized or missing argument will default to sum.
range
Range of the region of interest. If this field is left blank, the operation will be applied over the entire range. Otherwise, the range is specified using a comma separated list of values (no spaces). Negative values count from the end. The entire range for an MCA, for example, would be covered by 0,-1. For an image device, four values are required in the order: first row, last row, first column, last column.
roi_parse_conf()

Parses the ROI configuration string argument, checking for errors. If none are found, creates the ROI counter (if it doesn't yet exist) using counter_par() and assigns the configuration string to ROI_info[]. The single argument contains the arguments to roiconf in one string separated by colons, as in "controller:mne:name:op:range".

The ROI counters are created using the "add" option to counter_par(). That counter_par() call also associates the macro named roi_counts() with the counter. The macro is called to get the value of the ROI when the spec getcounts command is run. The roi_counts() macro will call the read_acqdev() macro that creates arrays for the the MCA or image device as necessary.

The macro will also delete an existing ROI_info entry for the specified counter mnemonic if the associated controller is no longer in the hardware config file. Entries associated with turned "OFF" controllers will remain in ROI_info, but no ROI counter will be created.

roi_reconf()
Reconfigures the ROI counters based on the contents of ROI_info. Assigned to config_mac to restore ROI counters after reading the spec hardware configuration file. Also called by the disable and enable macros via acq_chk_enable to ensure the associated ROI counters are appropriately disabled or enabled.
config_mac
A built-in macro called after reading the hardware configuration. Here we add a segment to the config_mac chained definition to reconfigure the ROI counters. The 0x20 flag puts the segment at the end of the macro. That is so that the ROI reconfiguration will take into account the enabled/disabled status of controllers, set by config_mac segment associated with the enable/disable macros, used to restore that state after reading the hardware configuration. The ROI configuration macros leaves the configuration choices in ROI_info[] for disabled controllers, but doesn't create the counters for those controllers.
roidel mne [mne2 ...]
Removes the ROI counters with the specified mnemonics.
roi_counters()
Used by the Python splot utility to find which ROI counters are associated with particular shared data arrays of the form MCA_DATA_# or IMG_DATA_#.
roi_devices()
Used by the Python splot utility to find out which MCA and image controllers are available for potential ROI creation.
roi_counts()

Associated with each of the ROI counters via the counter_par(mne, "add", "roi_counts") command. The macro function is called by the spec code associated with the getcounts command. The argument is the counter number. The macro initiates a read of the associated device, storing the data into a data array.

If more than one ROI is associated with a controller, the global ACQ_is_read[] is used to make sure the controller is only read once per count interval.

If mcs_spar() or image_par() for "hdw_roi?" is true, the controller implements the ROI functionality, and the "hdw_roi" command is used to retrieve ROI values.

_roi_cent()
A utility macro used by roishow to pad a string to center it within a given width.
roishow
Displays the current ROI counter configuration. Called automatically when acqsetup exits.
read_acqdev(type, unit)

The first argument is either "mca" or "img". The second argument is the unit number of the MCA or image device. Called from roi_counts() if ROIs are configured. Also called from the count macro (via get_acqdev) at each point of a scan.

The ACQ_is_read[] array keeps track of whether the particular device has been read for each scan point, so that devices are only read once per point, even if multiple operations are done with the data, such as calculating one or more ROI counter values or reading in order to save the spectrum or image to a file.

Unusable or disabled devices are skipped.

The macro creates (or resizes) an array (if not already existing) to read the MCA or image device. The arrays are named MCA_DATA_# and IMG_DATA_# with size and data type to match the underlying controller. Here # is the unit number of the controller, where unit numbers start at zero. For devices with multiple modules, a _M is appended to the array name, where M is the module number. By default (determined by the value of the constant ACQ_shared), the arrays are shared data in order that the Python splot utility (or any concurrent data display or analysis program) can access them.

_acq_mca_plot(id, arr)
Called after mca_sget() in read_acqdev() to plot MCA data if so configured in acq_setup. id is a string beginning with "mca" and ending with the MCA number. arr is a string containing the name of the associated data array. To work with existing plotting macros, finds unused X11 windows and plots in those. The PWIN[]["using"] array keeps track of which windows are in use. A value of 1 means used for plotting scan scalar data. Assigned the value id if being used for MCA data. The first time through after PWIN is changed in the counters macro, unused open plot windows are closed.
_acq_precount()
Assigned to acq_precount when MCA or image devices are configured. Called by count_em, the lowest level macro that starts counters. Calls mca_spar() or image_par(), as appropriate with settings for "auto_run" and "soft_preset".
_get_acqdev()
Assigned to get_acqdev when MCA or image devices are configured. get_acqdev is called from the standard get_counts macro, which is the lowest level macro that reads counters. Calls read_acqdev() for all appropriately configured devices.
_acq_head

Writes scan header information for MCA- and image-type acquisition devices to the data file. The header information looks like:

#@IMG 0 IMG_DATA_1 1024 512 long SERVER_IMG localhost:5001
#@MCA 1 MCA_DATA_12 1 256 ulong DP5 /dev/ttyS0

The second argument is an ID number to match subsequent entries in the data file that precede each saved spectrum. Following the ID is the name of the data array, the number of rows and columns, the data type, the controller type and, if available, the device ID.

_save_acqdev

Writes the data arrays containing MCA or image data to the data file or to a separate file, if that option has been configured. When saving to the standard data file, each array is prefixed with a line such as:

#IMG 0

or:

#MCA 1

where the number corresponds to the associated ID number in the header. For historical compatibility, the data values begin with @A if written to the standard data file.

When writing to a separate file, the save_spectra() macro is called which writes one line to the data file that includes the name of the separate file for each array.

The format "%32C" for MCA spectra writes up to 32 values per line and appends a backslash to continued lines. Image spectra are written one complete row per line.

save_spectra(kind, unit, arr_name, arr)

Saves MCA or image array to file. Parameters are:

kind
Either "mca" or "img".
unit
Unit number of MCA or image device.
arr_name
Name of array as a string.
arr
The array containing the data.

The local how parameter is taken from the global ACQ_save_how and determines how to distribute the data to a file as follows:

0 - all data to one file, separate from DATAFILE
1 - a new file for each scan
2 - a new file for each data point
3 - a new file for each spectra

If using automatic file name generation, the file name begins using the value of DATAFILE and ends with the extension ".arr". If there is a separate file per scan, the scan number is appended to the base name. If there is one file per data point, the data point number is also appended. Finally, if there is one file per spectrum, the array name is additionally appended.

If user-defined, the variable ACQ_template contains the template. It is expanded in the macro file_from_template(). See the newfile help file for more on templates. Be sure the template includes enough conversion sequences to be unique for each file. For example, if creating a new file for each scan point, the template should include a "%S*" for the scan number and a "%N*" for the point number. To include the array name in the file name, use "%3A*" in the template as the file_from_template() function is called with the array name as the third argument of the macro function.

For example:

ACQ_template = "%D*-%S*-%N*-%3A*.dat"

would produce files such as

/tmp/data_2023-08-09-003-001-MCA_DATA_12.dat

where the expansions are:

%D* = /tmp/data_2023-08-09
%S* = 003
%N* = 001
%3A* = MCA_DATA_12

Here

DATA_DIR = "/tmp"
DATAFILE_TEMPLATE = "data_%F.dat"

After expansion:

DATAFILE = "/tmp/data_2023-08-09.dat"

Each spectrum saved to the file is preceded by a control line of the sort:

#mca 0 MCA_DATA_12 scan 12 point 5

The first piece is #mca or #img. Next is the ID number for this array from the standard data file. (Each MCA and each image device is assigned an index number in the data file's scan header.) The index number if followed by the array name, the word scan followed by the scan number, then the word point followed by the point number.

chk_acq_using

Cleans up ROI_info and ACQ_flags and defines acquisition macros if 1D/2D devices are in the config file and needed by acqsetup configuration.

If no MCA or image devices are being used for ROI counters or for automatic reading and saving, the hook macros acq_precount, acq_chk_enable, acq_head, get_acqdev and save_acqdev are defined as empty strings. That avoids unnecessary overhead when the macros are not relevant. The above macros that actually perform the functions are assigned if there are MCA or image devices in use. ROI counters only require acq_precount and acq_chk_enable. Read and save requires all of the macros.

GLOBALS

ROI_info[] - 2D array contains ROI counter configuration

ACQ_flags[] - 1D array contains acquisition flags as bits

ACQ_template - Filename template if using separate files

ACQ_save_how - Bits indicate how to save MCA/image data

ACQ_save_fmt - Currently unimplemented

ACQ_is_read[] - Tracks if controller has been read at each count

ACQ_shared - Set to "shared" for shared data for Python splot (and others)

ROI_info_orig - To restore ROI_info if interrupted

MACROS

roisetup

roi_setup

acq_setup

acqsetup

_roi_mne_check(mne)

roiconf

roi_parse_conf(s)

roi_reconf()

roidel

roi_counters(arg)

roi_devices()

roi_counts(num)

_roi_cent(s, w)

roishow

read_acqdev(type, unit)

_acq_mca_plot(id, arr)

_acq_precount()

_get_acqdev()

_acq_head()

_save_acqdev()

save_spectra(kind, unit, arr_name, arr)

chk_acq_using