206 lines
7.2 KiB
Markdown
206 lines
7.2 KiB
Markdown
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](./db/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](https://gitea.psi.ch/lin-instrument-computers/Nicos/src/branch/release-3.12/nicos_sinq/devices/epics/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](sim/daq_sim.py).
|
|
|
|
## Testing
|
|
|
|
An IOC with the 2nd generation DAQ started in simulation mode can be started
|
|
via the [test/ioc.sh](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](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](test/st.cmd) file to the version you compiled and want to test.
|