Pixelator publishes messages based on various types of events. Some events are periodic, others depend on scanning and others are prompted by ZMQ requests. Messages are always structured as a list, with the first element being a string that identifies the type of message.
'beamShutterMode'
Example:
['beamShutterMode', 'Auto']
'beamShutterStatus'
Example:
['beamShutterStatus', 'red']
'filename'
Indicates where scan data will be saved during the measurement. Follows after a 'scanStarted' message. Depending on the scan archive status pf the scan type, the scan data file may be moved out of the "discard" subdirectory after the scan has finished.
['filename', 'Sample_Image_2026-06-10_034.hdf5', '/home/control/LocalData/2026-06-10/discard']
'focalStatus'
Provides the maximum OSA gap (distance between sample and OSA) that would fit the current FZP focal length and OSA diameter.
Examples:
['focalStatus', {'maxDOsa': nan}]
['focalStatus', {'maxDOsa': 422.446144433878}]
'focusType'
Example:
['focusType', 'Static']
'recordedChannels'
Example:
[recordedChannels', []]
'scanFinished'
These messages are published to indicate that a scan has completed and no further 'scanLineData' will be coming. The data provides info on where the data file was saved/moved to and a flag that indicates why the scan finished. Scan data is typically saved in the 'neXusDiscardSubDirectory' during the scan and then may be moved (depending on the archive status of the scan type) out of this subdirectory.
| Flag Value | Condition |
|---|---|
| 0 | Successful completion |
| 1 | Abort requested (by user) |
| 2 | Aborted due to error |
Flag values coded with the scanFinishedFlag variable in ScanController.cc
Example:
['scanFinished', {'filename': '/home/control/LocalData/2026-06-10/Sample_Image_2026-06-10_034.hdf5', 'flag': 1, 'neXusBaseDirectory': '/home/control/LocalData', 'neXusDiscardSubDirectory': 'discard', 'neXusLocalBaseDirectory': '/home/control/LocalData'}]
'scanLineData'
These messages are published during a scan so that the live data can be plotted in the GUI. Detector data is published in chunks that typically correspond to a scanned line. The data elements are:
- Indices:
- Polarisation index
- Outer region index
- Inner region index (but more complicated than you'd expect)
- Channel index (i.e. detector index)
- Chunk start (relative to current tile/inner region)
- y position
- x position
- Chunk size
- y size
- x size
- Data values
The "inner region index" does not refer to the "innerRegions" described in the scan definition, which correspond to the spatial regions that the user selected for imaging. Instead, those regions are broken up into "tiles" (even when "tiling mode" is not selected for the scan). The size and shape of these tiles are not transmitted and plotting code needs to figure out such details on the fly. The order of the tiles is consistent:
- start at lowest index position (i.e. (0,0) in the lower left corner)
- next tile will be neighbour in the fast-axis direction (to the right normally, or above if "y-axis fast" is selected for the scan)
- after filling the spatial region in the fast-axis direction, the fast-axis will rewind and the second-axis increments (up one and left-most normally, or rightwards one and bottom-most if "y-axis fast")
By keeping track of the size and positions of the tiles/inner regions, one will eventually get to a chunk that completes a spatial region (whose size can be calculated from the scanStarted published message) - the next "inner region index" will start the next spatial region.
Data values must be provided as floats (the Intens GUI will crash if values are not floats). Note that it is possible for the data values to include "NaN" (not a number) values, and for the number of values provided to be less than indicated by the chunk size provided (particularly for asynchronous detectors).
Image Examples:
['scanLineData', '0 0 15 0 ', '17 0 ', '1 20 ', '[589.0,286.0,341.0,911.0,250.0,617.0,226.0,756.0,808.0,972.0,894.0,434.0,157.0,659.0,199.0,940.0,NaN,NaN,NaN,NaN]']
['scanLineData', '0 0 0 0 ', '35 0 ', '1 100 ', '[770.0,708.0,357.0,425.0,844.0,102.0,185.0,710.0,342.0,880.0,792.0,890.0,898.0,704.0,32.0,454.0,105.0,94.0,296.0,373.0,339.0,285.0,406.0,122.0,343.0,487.0,973.0,152.0,62.0,481.0,713.0,880.0,338.0,149.0,385.0,596.0,531.0,79.0,952.0,491.0,225.0,2.0,361.0,200.0,279.0,278.0,356.0,913.0,396.0,101.0,107.0,399.0,616.0,810.0,809.0,252.0,330.0,17.0,464.0,87.0,367.0,370.0,975.0,874.0,864.0,385.0,331.0,935.0,278.0,16.0,287.0,668.0,515.0,836.0,184.0,542.0,838.0,426.0,925.0,25.0,181.0,204.0,140.0,607.0,118.0,131.0,250.0,159.0,225.0,562.0,609.0,86.0,714.0,117.0,521.0,791.0,664.0,471.0,500.0,676.0]']
Linescan and Pointscan Examples:
['scanLineData', '0 9 1 0 ', '0 ', '10 ', '[716.0,589.0,95.0,729.0,311.0,220.0,153.0,613.0,788.0,696.0]']
'scanStarted'
This message is published when a scan is started. The data is a copy of the scan definition. A plotting routine should use this info to calculate the size and shape of the data to be measured. Note that the sets of innerRegions and outerRegions should be truncated to the sizes given by 'nInnerRegions' and 'nOuterRegions'.
Following this message should be:
- 'filename'
- 'scanTypeArchive'
- 'scanLineData'
- 'scanStatus' (periodically, and not coordinated with 'scanLineData' messages)
- 'scanAborted' (maybe)
- 'scanFinished'
Example:
['scanStarted', {'accelerationDistance': 1.0, 'displayedAxes': {'x': {'index': 1, 'region': 'inner'}, 'y': {'index': 0, 'region': 'inner'}}, 'innerRegions': [{'axes': [{'nPoints': 100, 'trajectories': [{'center': -1.0, 'positionerName': 'CoarseY', 'range': 50.0, 'step': 0.5}]}, {'nPoints': 100, 'trajectories': [{'center': 1.0, 'positionerName': 'CoarseX', 'range': 50.0, 'step': 0.5}]}]}], 'lineDelay': 0.001, 'lineMode': 'Point by Point', 'lineRepetition': 1, 'meander': 1, 'nInnerRegions': 1, 'nOuterRegions': 1, 'outerRegions': [{'axes': [{'nPoints': 11, 'trajectories': [{'end': 310.0, 'positionerName': 'Energy', 'range': 10.0, 'start': 300.0, 'step': 1.0}]}], 'dwellTime': 0.0001}], 'pointDelay': 0.0, 'scanType': 'Sample', 'singleOuterRegionValue': True, 'spatialType': 'Image', 'tileDelay': 0.01, 'tiling': 1, 'yAxisFast': 0}]
'scanStatus'
['scanStatus', {'current': {'innerRegion': 1, 'line': 5, 'lineRepetition': 1, 'outerRegion': 1, 'point': 51, 'polarization': 1, 'remainingTime': '00h 00m 32s', 'time': '00h 00m 00s'}, 'scanType': 'Sample Scan', 'status': 'running', 'total': {'innerRegion': 1, 'line': 100, 'lineRepetition': 1, 'outerRegion': 1, 'point': 100, 'polarization': 1, 'time': '00h 00m 43s'}}]
'scanTypeArchive'
Example:
['scanTypeArchive', {'attrActual': 'archive', 'attrNew': 'locked'}]
'topupMode'
Example:
['topupMode', 'On']
'topupStatus'
Example:
['topupStatus', 'green']
'userStatus'
Example:
['userStatus', {'saveLocal': 'on', 'username': 'stxm'}]