Skip to content

NSLS2/A1Soft-IOC

Repository files navigation

A1Soft-IOC

Caproto IOC to control A1Soft spectrum analyzer from MB Scientific AB https://www.mbscientific.se/ through the provided TCP Server.

Note

Much of the behavior described below was deduced through trial & error. There are a significant amount of unknowns that we still need to discover through this process.

GenAcqTE TCP Server

The "General Acquisition Tango-EPICS" VI when specified to use the "EPICS" Instance Name, runs a TCP server which exports some data and controls over socket connections.

TCP Sockets

There are three TCP socket connections.

Usage Description
Data For images accessed via the GET_IMAGE Action.
Commands For commands sent from a client and responses to that client (in JSON format)
Live plots For live data monitoring

Commands Types

Here are a list of the types of commands able to be processed by the TCP server. It is currently unknown what the "DATA" command type does.

Type Description
GET Get the current value of a Parameter
SET Set the value of a non-read-only Parameter
ACTION Perform one of the Actions

Parameters

Note

For the acqMode parameter, we manually changed the LabView TypeDef to include FixedTrigd, which was not included by default.

Name Type Description Read-Only?
state enum The state of the acquisition. Options are: RUNNING, MOVING, STANDBY Y
endX int Y
startY int Y
numSlice int Y
endY int Y
startX int Y
frames int The number of frames to capture N
numSteps int N
passEnergy enum Options are PE001, PE002, PE005, PE010, PE020, PE050 N
lensMode enum Options are L4Ang0d6, L4Ang0d8, L4Ang1d6, L4Ang3d9, L4MSpat5, L4Spat5 N
numScans int The number of scans to take N
regNum int Y
totSteps int Y
addFms int Y
actScans int The number of actual scans taken Y
dithSteps int N
startKe float The starting kinetic energy of the scan N
stepSize float The energy step size of the scan N
endKe float The ending kinetic energy of the scan N
spinOffs float N
width float N
centreKe float The center kinetic energy N
firstEnergy float N
deflX float N
deflY float N
dbl10 float Y
acqMode enum Options are Fixed, FixedTrigd, Swept, Dither N
dateNumber bool Y
locDet bool Y
xtab bool N
spin bool ?
regName str Y
nameString str Y
generatedName str Y
comment1 str N
startTime str N
discr int Y
adcMask int Y
adcOffset int Y
pCntType int Y
pcMask int Y
softBinX int N
softBinY int N
EScaleMult float N
EScaleMax float Y
EScaleMin float Y
YScaleMult float Y
YScaleMax float Y
YScaleMin float Y
YScaleName str Y
XScaleMult float Y
XScaleMax float Y
XScaleMin float Y
XScaleName str Y
PsuMode str Y
OverRArr str Y
OverRange int Y

Actions

Name Description
START Starts the acquisition
STOP Stops the acquisition
DET_OFF Turns the detector off
GET_IMAGE Requests an image on the data socket
GET_ACQ_STATS Gets the acquisition state and index

Data Socket

You will only receive data on this socket after sending a GET_IMAGE Action over the JSON socket. The schema is

Name Byte offset Description
Header 0 - 40 Contains the header data
Marker 0 - 4
Index 4 - 8 The current frame number requested since acquisition start
State 8 - 12
Reserved 12 - 16
Width 16 - 20 The width of the first channel image
Height 20 - 24 The height of the first channel image
Length 24 - 28 The length of the first channel image in bytes
Current width 28 - 32 The width of the second channel image
Current height 32 - 36 The height of the second channel image
Current length 36 - 40 The length of the second channel image in bytes
First channel image 40 - (40 + Length) The uint32 byte array for the first channel image, representing the current image being displayed
Second channel image (40 + length) - (40 + length + current length) The uint32 byte array for the second channel image, representing the sum of the first channel images in the acquisition so far

In Fixed acquisition mode, you can only capture data at a maximum of ~12.5 frames per second. The A1Soft latency between receiving a GET_IMAGE action and putting all of this data into the data socket is greater than the rate at which images are produced. This means that the IOC will never be able to keep up and will drop frames!

Live Socket

There is also a live data socket for streaming data from the detector. This is only available while acquiring.

The "Live Data" must be configured to be on and the monitor must be enabled. There is no way to control this from the TCP server, so you must manually configure this in LabView. You can control the rate at which the TCP server adds live data by configuring it in the parameters.ini file that should have come with the server.

Note

There were some bugs in the dataTransferLoop.vi that was causing data to be added to the live socket every 5ms! This overloaded the socket and caused many issues. You have to fix this by either increasing the 5ms to 1000ms or moving the error wire after the socket connection heartbeat. We did both to make it work.

The schema is

Name Byte offset Description
Marker 0 - 4 Message start marker (delimits frames)
Index 4 - 8 The current frame number requested since acquisition start
Width 8 - 12 The width of the image
Height 12 - 16 The height of the image
Length 16 - 20 The length of the image in bytes
Image 20 - (20 + Length) The uint32 byte array for the first channel image, representing the current image being displayed

Process Variables (PVs)

Here are the tables of EPICS PVs that are hosted by the Caproto server. They are roughly grouped into categories.

$(P) corresponds to the specified prefix set via the command-line argument.

Acquisition Control

PV Name Description
$(P)ACQUIRE Starts acquiring when set to 1. Stops when set to 0. Does not do anything if already running.
$(P)ACQ:STATUS Status of the acquisition started via EPICS
$(P)LIVE:MONITORING Enable/disable live data monitoring from live_port
$(P)LIVE:MAX_COUNT Current maximum pixel count from live data stream
$(P)LIVE:LAST_UPDATE Timestamp of last live data update
$(P)LIVE:MAX_COUNT_THRESH Threshold for the maximum value of a single pixel of the detector
$(P)LIVE:MAX_COUNT_EXCEEDED Indicates if the maximum count has exceeded the threshold
$(P)LIVE:MAX_COUNT_AVG_N Window size for averaging the max count (i.e. average over the last n max counts)

Detector Control

PV Name Description
$(P)DET:OFF Perform Action DET_OFF

System Control

PV Name Description
$(P)SYS:CONNECTED Connection status of the client to the TCP Server, true if all ports are connected.
$(P)SYS:LAST_SYNC Timestamp of the last time the parameters from A1Soft were synced with the PVs
$(P)SYS:SYNC Enable/Disable syncing Detector Parameters. Set polling frequency via .SCAN record

File Writing

The IOC will open a NeXus file for writing when you turn on $(P)FILE:CAPTURE. The file only remains open when there is data available to write. Within a single acquisition, it will continually update the frame every time actScans increases by 1. Once actScans is equal to numScans, it will commit this frame to the file. Subsequent acquisitions will append a new frame to the same dataset. This way if you stop a single acquisition in the middle, there will be partial frame data available.

The number of full acquisitions that complete will be equal to the number of frames committed to the file. So if I call caput $(P)ACQUIRE 1 5 separate times (waiting for each acquisition to complete in between calls), there will be 5 frames in the file.

PV Name Description
$(P)FILE:CAPTURE Enable/disable file capture
$(P)FILE:NAME File name for captured data
$(P)FILE:PATH File path for captured data
$(P)FILE:NUM_CAPTURED Number of images captured while file capture is on
$(P)FILE:NUM_PROCESSED Number of scans processed during a single acquisition

Detector Parameters

When synchronization is active, these parameters will be updated, by default every second, to match what the parameter values are in LabView. This way, when someone changes one of these parameters in LabView, it gets reflected in the PV values.

PV Name Description
$(P)STATE Sets and gets state
$(P)ENDX Sets and gets endX
$(P)STARTY Sets and gets startY
$(P)NUM_SLICE Sets and gets numSlice
$(P)ENDY Sets and gets endY
$(P)STARTX Sets and gets startX
$(P)FRAMES Sets and gets frames
$(P)NUM_STEPS Sets and gets numSteps
$(P)PASS_ENERGY Sets and gets passEnergy
$(P)LENS_MODE Sets and gets lensMode
$(P)NUM_SCANS Sets and gets numScans
$(P)REG_NUM Sets and gets regNum
$(P)TOT_STEPS Sets and gets totSteps
$(P)ADD_FMS Sets and gets addFms
$(P)ACT_SCANS Sets and gets actScans
$(P)DITH_STEPS Sets and gets dithSteps
$(P)START_KE Sets and gets startKe
$(P)STEP_SIZE Sets and gets stepSize
$(P)END_KE Sets and gets endKe
$(P)SPIN_OFFS Sets and gets spinOffs
$(P)WIDTH Sets and gets width
$(P)CENTER_KE Sets and gets centreKe
$(P)FIRST_ENERGY Sets and gets firstEnergy
$(P)DEFLX Sets and gets deflX
$(P)DEFLY Sets and gets deflY
$(P)DBL10 Sets and gets dbl10
$(P)ACQ_MODE Sets and gets acqMode
$(P)DATE_NUMBER Sets and gets dateNumber
$(P)LOC_DET Sets and gets locDet
$(P)XTAB Sets and gets xtab
$(P)SPIN Sets and gets spin
$(P)REG_NAME Sets and gets regName
$(P)NAME_STRING Sets and gets nameString
$(P)GENERATED_NAME Sets and gets generatedName
$(P)COMMENT1 Sets and gets comment1
$(P)START_TIME Sets and gets startTime
$(P)DISCR Sets and gets discr
$(P)ADC_MASK Sets and gets adcMask
$(P)ADC_OFFSET Sets and gets adcOffset
$(P)P_CNT_TYPE Sets and gets pCntType
$(P)PC_MASK Sets and gets pcMask
$(P)SOFT_BIN_X Sets and gets softBinX
$(P)SOFT_BIN_Y Sets and gets softBinY
$(P)ESCALE_MULT Sets and gets EScaleMult
$(P)ESCALE_MAX Sets and gets EScaleMax
$(P)ESCALE_MIN Sets and gets EScaleMin
$(P)YSCALE_MULT Sets and gets YScaleMult
$(P)YSCALE_MAX Sets and gets YScaleMax
$(P)YSCALE_MIN Sets and gets YScaleMin
$(P)YSCALE_NAME Sets and gets YScaleName
$(P)XSCALE_MULT Sets and gets XScaleMult
$(P)XSCALE_MAX Sets and gets XScaleMax
$(P)XSCALE_MIN Sets and gets XScaleMin
$(P)XSCALE_NAME Sets and gets XScaleName
$(P)PSU_MODE Sets and gets PsuMode
$(P)OVER_R_ARR Sets and gets OverRArr
$(P)OVER_RANGE Sets and gets OverRange

Installation

To install the package:

pip install .

Or for editable install:

pip install -e .

Usage

To launch the Caproto server:

python -m a1soft.ioc --list-pvs --interfaces=127.0.0.1

To use the Ophyd device in scripts:

from a1soft.ophyd import SpectrumAnalyzer

# Example usage
device = SpectrumAnalyzer('PREFIX:', name='sa')

About

Caproto IOC to control A1Soft spectrum analyzer from MB Scientific AB https://www.mbscientific.se/

Resources

Stars

Watchers

Forks

Packages

No packages published