changes
Highlights for spec release 6.14
April 21, 2026 - RELEASE 6.14.01
IMPROVEMENTS
The array_read() Code Rewritten With New Features
The array_read() function now recognizes backlash-continued data lines, such as those produced with the "%#C" argument of array_dump(). Any line of the ASCII file ending with a backslash followed by a newline (or a backslash followed by a carriage return and a newline) will be joined to the preceding line prior to scanning for data.
The array_read() function can now be called repeatedly for the same file to read successive arrays contained in that file. The file name and position is shared with the getline() function. That allows one to use getline() to locate the position of an array in the file, then use array_read() to read in the array data. A new optional "open" argument to array_read() returns zero or nonzero, depending on whether the file can be opened, and also resets the position to the beginning of the file. The positioning options of getline() can also be used to set the file position. The previous behavior, where each array_read() returns the first data in the file, is still available if array_read() is not called with the "open" option, and the file isn't referenced using getline().
array_read() now respects the "wise"-ness value of its array argument. For a row-wise array, each row of the file fills one row of the array. For a column-wise array, each row of the file fills one column of the array. Note, the standard spec macros for plotting and data handling use row-wise arrays only.
See array_read() in the arrays help file and getline() in the functions help file.
Improved Simulate-Mode Server-Mode Motor-Position Synchronization
When a spec server moves a motor in simulate mode, it will now send the final simulated position at the end of the move. When a spec server leaves simulate mode, it will now update clients with the current real position of a motor if position events had been sent for the motor while the server was in simulate mode.
Auto Save State Now Defaults To Sixty Seconds
The automatic savstate feature implemented in spec release 6.11.02 with a default value of zero now defaults to sixty seconds. That is, the session's state file will be updated automatically, but no more frequently than once every sixty seconds. The action takes place before the main spec prompt. See "auto_savstate" in the spec_par help file for details.
Updates To spec Code Base For C23
The source code for spec release 5.08.02-1 was updated from traditional (or K&R) C to ANSI/ISO Standard C seventeen years ago (January 2009). That update involved changes to many thousands of lines of code. Over the years, the spec code has included minor updates to remain compatible with successive C standards (C99, C11, C17). This spec release supports the C23 standard which is now the base standard for versions 15 of the C compilers Clang and gcc. The biggest change needed in the code base was to modify all empty function prototypes to include parameters. Like the 2009 update, these changes affected many thousands of lines of code, mainly in the hardware support.
The spec code uses a structure of function pointers to call hardware related functions. Previously the functions were declared with no parameters. The function calls to the hardware dependent code would be made with different parameter lists, depending on the hardware type. For example, a call to read MCA data would include a first and last column, while a call to read image data, would include first and last of both columns and rows. The same function pointer would also be used to read motor controllers and counters, each again with different arguments. Now, the functions are called with a pointer to a structure that contains entries for all the argument combinations previously used.
All the hardware support code was touched in the modifications for this release. The quality control staff has carefully reviewed the changes and tested what code it could. However, most supported hardware is not available at CSS HQ for testing. If you note any anomalous behavior with this spec release or subsequent releases, be sure to promptly notify CSS.
The whatis() Function Now Works With Unset Associative Array Elements
The whatis() function has been updated to properly handle unset associative array element arguments. Previously, an unset element would generate the message, "Not an element of an array".
FIXES
Fix For eval() Return Of Data Array Within Macro Function
A rather obscure and very old bug (since the dawn of the eval() function in spec release 5) is fixed. Previously, if an eval() return value was a data array and the eval() was used wihtin a macro function, the macro function would treat the eval() as a return. The remaining code in the macro function would not get executed.
MACROS
Clearer Behavior For DATA_DIR, DATAFILE_TEMPLATE and DATAFILE
The macros dealing with the naming of the data file have been adjusted to be more consistent and clear.
DATA_DIR is an optional directory in which to stick the data. Otherwise the current directory is used.
DATAFILE_TEMPLATE is the name of the data file, without DATA_DIR. The template may include special sequences that are converted to time-related strings or spec variable-related strings. The template may also include slashes for directories, where the directory names may include special sequences. If the template begins with "/" or "./", DATA_DIR is not used.
DATAFILE is the complete name of the data file including DATA_DIR, if used, and has the expanded special sequences.
With no arguments, the newfile macro will now prompt for DATA_DIR in addition to DATAFILE_TEMPLATE. Also, DATA_DIR will be created by the macros if it doesn't exist. See the newfile help file.
New %H* Data File Template Sequence For HOSTNAME
The data file template feature introduced in spec release 6.12.01 now recognizes the additional sequence %H*. The value of the HOSTNAME global variable is substituted. If the value contains a dotted name, only the portion prior to the first dot is substituted. See the newfile help file for more information.
Revised # Tags For MCA and Image Data For Consistency
The # tags written to the spec data file by the new acquisition macros have been revised slightly for consistency and to include more information that should help with programs that parse the data file content. See the acq and newfile help files for details.
New Acquisition Macro Functionality
The MCA and image device acquisition macros now configure array saving options separately for each device. For example, MCA spectra can be saved in the main spec data file, while image data can be saved in separate files. A prefix for device-dependent macros for collecting and saving array data can be configured. The new support for the Eiger detector uses this feature. A new acq_tail hook is included in the standard _tail macro to accommodate a device-dependent macro action to be performed at the end of scans. See the acq help file.
Better Check For Active Status In read_acqdev()
The code to ensure the MCA and images devices are only read at the end of an updated counting interval if the "read during updated counting" option is disabled has been improved to include a wait(0x22) call in addition to the xxx_par(unit, "active") call. Previously, such devices were sometimes read twice.
More Options For Distributing Array Data In Files
The acquisition macros now include options to distribute MCA and image array data to one file per detector and one file per detector per scan. See the acq help file.
Mesh Scans Now Allow Any Number of Motors
The mesh and dmesh scans now work with any number of motor arguments, where each motor argument consists of a motor mnemonic, starting position, ending position and number of intervals. The first motor specified does the innermost loop. The last motor specified does the outermost loop.
cscan and cdscan Now Allow Any Number of Motors
The continuous scan macros, cscan and cdscan, can now take any number of motor arguments, where each argument consists of a motor mnemonic, starting position and ending position. All motors are moved continuously at a speed derived from the scan time argument. Previously, c2scan, c3scan and c4scan (and similarly for delta scans) specified multiple motors. Those macros are still available, but cscan and cdscan can now be used with 2, 3, 4 or more motors. See the cscan help file.
3D Continuous Mesh Scans Implemented
New cmesh3d and cdmesh3d continuous scans are available. At each point of a two dimensional grid, the on-the-fly motor will perform a continuous scan, that is, a scan where the counter is read while the motor is moving, with counter and position readings being taken continuously during the move. The first motor argument set is for the on-the-fly motor. The second and third motor argument sets specify the grid motors. See the cscan help file.
The ca and cal Macros Give Limit Warnings
The ca and cal macros, which calculate geometry motor positions for a given HKL reciprocal space position, now also show whether any of the motors would require a move beyond their configured limits.
New user_preconfig Hook In the config Macro
The standard config macro used to edit the hardware configuration file associated with the current spec instance now includes an additional user hook macro called user_preconfig. That macro will be invoked prior to running the edconf utility. The existing user_config hook macro remains and is called after reconfig re-reads the possibly modified config file. Use the cdef() chained macro to add or remove commands from both user_preconfig and user_config.
Fix For scan_data() Incorrect HKL Values
An issue where the scan_data() macro function called within the scan loops to assign values to the SCAN_D data array assigned incorrect values to H, K or L columns when those parameters had an integral value has been fixed. Note, correct values were always written to the data file.
HARDWARE
Preliminary Support For Aerotech Ensemble Motor Controllers
This spec release includes preliminary support for the Aerotech legacy Ensemble drive-based motion controllers. See the aerotech help file for more information.
Preliminary and Limited Support For STOE StadiVari Instrument
This spec release includes preliminary support for the motors associated with the four-circle STOE StadiVari diffractometer. spec only has limited access to the instrument functionality. The StadiVari software must be used to home (synchronize) the motor positions, to recover from a violation of limits and to resolve other errors. See the stadivari help file.
Preliminary Support For Dectris Pilatus Detectors
A new pilatus.mac file is included that supports the Dectris Pilatus 100K, 200K, 300K and 1M detector models that use the camserver interface. The support uses spec's macro hardware image device support along with the recently added acq acquisition macros. See the pilatus help file for details.
PYTHON
Dectris Eiger Support Updates
The Python eiger_server code includes updates and fixes. The region-of-interest calculations have been fixed. A problem where eiger_server would start a new data reading thread when there was already an active thread has been fixed. That solves an issue where data was sometimes not being read correctly. New options to rotate the image by 90, 180 or 270 degrees and/or flip the image horizontally or vertically are available. These options are set on the server command line and remain fixed as long as the server is running. Issues with accumulation mode have been fixed. See the eiger help file for details.
The eiger.mac macros have been substantially revised. Use of the Eiger is now integrated with the standard acquisition and region-of-interest macros. Use the eiger_setup macro to configure Eiger-specific parameters. Use the acq_setup macro to configure collection-related parameters, including regions of interest. See the acq and eiger help files.
The revised macros do not currently support "collection" mode. The previous macro set and help file are included in the distribution in eiger_old.mac and eiger_old.rst. Note, the old macros do not work well with the new acquisition macros.
Fix For splot Coordinate Display
An issue with recent versions of the Python splot utility where the values displayed for coordinate values and with cut lines on 2D plots had the y axis origin at the top, while the data had its origin at the bottom, has been fixed.
