SINQDAQ Epics Module
A Stream and Asyn based driver for configuring the Data Acquisition Systems at SINQ.
This supports the older 4 and 8 channel EL737 models and the new 10CH 2nd generation systems.
How to Use
Unless a custom database is needed, a device can be configure simply by setting the required environment variables when calling the correct DAQ interface script.
Required Variables
Environment Variable | Purpose |
---|---|
INSTR | Prefix of all device specific PVs |
NAME | First field in all PVs after Prefix |
DAQ_IP | Network IP of device |
DAQ_PORT | Network Port of device |
All PVs take the form
$(INSTR)$(NAME):*
Available device startup scripts
- scripts/daq_4ch.cmd
- scripts/daq_8ch.cmd
- scripts/daq_2nd_gen.cmd
A device can be configured using one of the startup scripts as follows
epicsEnvSet("INSTR", "SQ:INSTRUMENT:") # can also be set in runScript call
runScript "$(sinqDAQ_DIR)daq_2nd_gen.cmd" "NAME=DAQ, DAQ_IP=TestInst-DAQ1, DAQ_PORT=2000"
PVs of Interest
PV | Description |
---|---|
$(INSTR)$(NAME):MsgTxt | Contains unexpected response to executed command |
$(INSTR)$(NAME):STATUS | 0: Idle, 1: Counting, 2: Low rate, 3: Paused, 4: Error |
$(INSTR)$(NAME):MONITOR-CHANNEL | Channel that PRESET-COUNT monitors (has RBV, only v2 can be changed) |
$(INSTR)$(NAME):PRESET-COUNT | Run count until specified pv value reached |
$(INSTR)$(NAME):PRESET-TIME | Run count until specified pv value in seconds reached |
$(INSTR)$(NAME):THRESHOLD | Minimum rate for counting to preceed. (has RBV) |
$(INSTR)$(NAME):THRESHOLD-MONITOR | Channel monitored for minimum rate (has RBV) |
$(INSTR)$(NAME):ELAPSED-TIME | Time DAQ has been measuring for |
$(INSTR)$(NAME):M_ | Current count on channel. (1-10 depending on DAQ system) |
$(INSTR)$(NAME):CHANNELS | Number of available channels (4, 8 or 10) |
$(INSTR)$(NAME):GATE-_ | Configuration for Gating in newer hardware |
Generating Test Signals
The 2nd generation systems have two test channels that can be used to output signals at a variable rate. These can be used to ensure the other channels are working and to check the IOC - Nicos integration. These can be loaded at runtime via the following
epicsEnvSet("LOAD_TEST_PVS","")
runScript "$(sinqDAQ_DIR)daq_2nd_gen.cmd" "NAME=DAQ, DAQ_IP=TestInst-DAQ1, DAQ_PORT=2000"
See the file daq_2nd_gen_test.db
Nicos Interface
A set of Nicos devices have been developed which allow control of the Detector Hardware via this Epics Driver. The corresponding code can be found in sinqdaq.py.
Full Example
Include the following snippet in your IOC
# st.cmd at SINQTEST
epicsEnvSet("STREAM_PROTOCOL_PATH","./db")
epicsEnvSet("INSTR","SQ:SINQTEST:")
require sinqDAQ
runScript "$(sinqDAQ_DIR)daq_2nd_gen.cmd" "NAME=DAQ, DAQ_IP=TestInst-DAQ1, DAQ_PORT=2000"
What follows is an example Nicos setup file. The "channels" are created in the loop at the bottom.
# DAQDetector.py
description = 'Devices for the detectors'
countprefix = 'SQ:SINQTEST:DAQ'
devices = dict(
ElapsedTime = device(
'nicos_sinq.devices.epics.sinqdaq.DAQTime',
daqpvprefix = countprefix,
),
DAQPreset = device(
'nicos_sinq.devices.epics.sinqdaq.DAQPreset',
description = '2nd Generation Data Acquisition',
daqpvprefix = countprefix,
channels = [],
time_channel = ['ElapsedTime'],
),
DAQV2 = device(
'nicos_sinq.devices.epics.sinqdaq.SinqDetector',
description = 'Detector Interface',
timers = ['ElapsedTime'],
counters = [],
monitors = ['DAQPreset'],
images = [],
others = [],
liveinterval = 2,
saveintervals = [2]
),
ThresholdChannel = device(
'nicos_sinq.devices.epics.sinqdaq.DAQMinThresholdChannel',
daqpvprefix = countprefix,
channels = [],
visibility = {'metadata', 'namespace'},
),
Threshold = device(
'nicos_sinq.devices.epics.sinqdaq.DAQMinThreshold',
daqpvprefix = countprefix,
min_rate_channel = 'ThresholdChannel',
visibility = {'metadata', 'namespace'},
),
Gate1 = device(
'nicos_sinq.devices.epics.sinqdaq.DAQGate',
daqpvprefix = countprefix,
channel = 1,
visibility = {'metadata', 'namespace'},
),
Gate2 = device(
'nicos_sinq.devices.epics.sinqdaq.DAQGate',
daqpvprefix = countprefix,
channel = 2,
visibility = {'metadata', 'namespace'},
),
TestGen = device('nicos_sinq.devices.epics.sinqdaq.DAQTestGen',
daqpvprefix = countprefix,
visibility = {'metadata', 'namespace'},
),
)
for i in range(10):
devices[f'monitor{i+1}'] = device(
'nicos_sinq.devices.epics.sinqdaq.DAQChannel',
description = f'Monitor {i + 1}',
daqpvprefix = countprefix,
channel = i + 1,
type = 'monitor',
)
devices['DAQPreset'][1]['channels'].append(f'monitor{i+1}')
devices['ThresholdChannel'][1]['channels'].append(f'monitor{i+1}')
devices['DAQV2'][1]['monitors'].append(f'monitor{i+1}')
startupcode = '''
SetDetectors(DAQV2)
'''
Simulation
Simulation of the Hardware can be toggled on as follows:
epicsEnvSet("SET_SIM_MODE","") # run DAQ simulation instead of connecting to actual system
runScript "$(sinqDAQ_DIR)daq_2nd_gen.cmd" "NAME=CB_TEST, DAQ_IP=localhost, DAQ_PORT=2000"
In such a case, the provided DAQ_IP
is ignored, and a python program
simulating the hardware is started in the background, listening at the
specified DAQ_PORT
. So, if you have multiple devices listening on the same
port, you might have to change this port value of one of the devices when
simulating hardware. You can then interact with the PVs as with the normal
hardware. Keep in mind, however, that not all functionality has been
implemented.
See sim/daq_sim.py.
Testing
An IOC with the 2nd generation DAQ started in simulation mode can be started via the test/ioc.sh script.
There is also a simple automated test that can be run for a simple check of functionality and that the PVs load test/test.py.
Both require that the module has been built and installed as is normal in the require based module system.
You might have to change the specified version in the test/st.cmd file to the version you compiled and want to test.