An EPICS areaDetector driver for Dectris Mythen strip detector.
- Overview
- Installation
- Configuration
- Driver Parameters
- Operation
- User Interface
- Examples
- Troubleshooting
- Technical Reference
- Appendices
ADMythen is an EPICS areaDetector driver that provides control and data acquisition capabilities for Dectris Mythen strip detectors. The Mythen is a one-dimensional silicon strip detector designed for X-ray diffraction and spectroscopy applications.
- TCP/IP Communication: Communicates with the detector over TCP/IP (UDP or TCP protocols)
- Multiple Module Support: Supports up to 2 detector modules, each with 1280 channels
- Flexible Acquisition Modes: Single image, multiple images, and continuous acquisition
- Trigger Modes: None (software), Single (external), and Continuous (external)
- Data Corrections:
- Flat field correction
- Count rate correction with configurable deadtime constant
- Bad channel interpolation
- Configurable Bit Depths: 4, 8, 16, or 24 bits per channel
- Read Modes: Raw (uncorrected) or Corrected data
- Energy Settings: Predefined settings for common X-ray sources (Cu, Mo, Ag, Cr) or custom energy values
- Gate Mode: Support for gated acquisitions
- Firmware Compatibility: Works with multiple firmware versions
ADMythen inherits from the ADDriver base class, which provides standard areaDetector functionality. The driver uses:
- asynPort: For TCP/IP communication with the detector
- NDArray: Standard areaDetector data format
- EPICS Channel Access: For control and monitoring
The driver supports all standard areaDetector plugins including NDStdArrays, NDPluginFile, NDPluginStats, etc.
- Original Development: Based on asyn driver from LNLS
- areaDetector Integration: Modified by Joe Sullivan (ANL-APS/XSD/BCDA) to work with areaDetector
- Enhancements:
- M. Moore (ANL-APS/XSD/DET): Firmware compatibility updates, ReadMode support, trigger timeout handling, ImageMode improvements
- Documentation: Comprehensive documentation created by K. Gofron (ORNL, Oak Ridge National Laboratory, December 6, 2025)
For detailed release notes, see RELEASE.md.
- EPICS Base: Version 3.14.12 or later (or EPICS 7.x)
- areaDetector Modules:
- ADCore: R3-3 or later
- ADSupport: Compatible version
- asyn: R4-26 or later
- Operating System: Linux or Windows
- Network: TCP/IP connectivity to the Mythen detector
- Compiler:
- Linux: GCC 4.8 or later
- Windows: Visual Studio 2015 or later
- Build Tools: GNU Make
The ADMythen source code should be placed in the areaDetector support directory structure:
/epics/support/areaDetector/
├── ADCore/
├── ADSupport/
├── ADMythen/ <-- Place ADMythen here
└── ...
Clone or download the repository:
cd /epics/support/areaDetector
git clone <repository-url> ADMythenEdit configure/RELEASE to point to your EPICS modules:
# Location of external products
EPICS_BASE=/epics/base-3.15.5
ADCORE=$(AREA_DETECTOR)/ADCore
ADSUPPORT=$(AREA_DETECTOR)/ADSupport
ASYN=$(AREA_DETECTOR)/asynFrom the ADMythen top-level directory:
makeThis will build:
- The driver library (
mythenApp) - The IOC application (
iocs/mythenIOC)
make installLinux:
- Standard build process as described above
- Supports both little-endian and big-endian architectures
Windows:
- Use Visual Studio solution files if provided
- Ensure proper path configuration for EPICS modules
Big-Endian Support:
- The driver includes automatic byte-swapping for big-endian systems
- No special configuration required
To verify the installation:
-
Check that the libraries were built:
ls -la lib/linux-x86_64/
-
Check that the IOC was built:
ls -la iocs/mythenIOC/bin/linux-x86_64/
-
Start a test IOC (see Configuration section for details)
The IOC is located in iocs/mythenIOC/. The main startup script is iocBoot/iocMythen/st.cmd.
iocs/mythenIOC/
├── configure/
│ ├── RELEASE # EPICS module paths
│ └── ...
├── iocBoot/
│ └── iocMythen/
│ ├── st.cmd # IOC startup script
│ └── auto_settings.req
└── mythenApp/
└── src/
└── mythenAppMain.cpp
The driver communicates with the Mythen detector over TCP/IP. Configure the network connection in st.cmd:
# Configure asyn IP port
# Format: drvAsynIPPortConfigure("portName", "IP:Port Protocol", priority, noAutoConnect, noProcessEos)
drvAsynIPPortConfigure("IP_M1K", "192.168.0.90:1030 UDP", 0, 0, 1)Parameters:
- portName: Name for the asyn port (e.g., "IP_M1K")
- IP:Port: Detector IP address and port (default port is 1030)
- Protocol: "UDP" or "TCP" (UDP is typical)
- priority: Thread priority (0 = default)
- noAutoConnect: 0 = auto-connect, 1 = manual connect
- noProcessEos: 1 = don't process end-of-string
End-of-String Configuration:
# Set output end-of-string (carriage return)
asynOctetSetOutputEos("IP_M1K", 0, "\r")Tracing (for debugging):
# Enable I/O tracing (mask 6 = read/write)
asynSetTraceIOMask("IP_M1K", 0, 6)
# Enable general tracing (mask 3 = traceIO, traceError, traceWarning)
asynSetTraceMask("IP_M1K", 0, 3)Configure the Mythen driver using the mythenConfig function:
# mythenConfig(portName, IPPortName, maxBuffers, maxMemory, priority, stackSize)
mythenConfig("SD1", "IP_M1K", -1, -1)Parameters:
- portName: Name for the driver port (e.g., "SD1")
- IPPortName: Name of the asyn IP port (e.g., "IP_M1K")
- maxBuffers: Maximum NDArray buffers (-1 = unlimited)
- maxMemory: Maximum memory in bytes (-1 = unlimited)
- priority: Thread priority (optional, default from ADDriver)
- stackSize: Thread stack size (optional, default from ADDriver)
Example with limits:
mythenConfig("SD1", "IP_M1K", 100, 100000000) # 100 buffers, 100MB memoryLoad the database template with appropriate macros:
# Set environment variables
epicsEnvSet("PREFIX", "dp_mythen1K:")
epicsEnvSet("PORT", "SD1")
epicsEnvSet("ADDR", "0")
epicsEnvSet("TIMEOUT", "1")
# Load database template
dbLoadRecords("$(ADMYTHEN)/mythenApp/Db/mythen.template",
"P=$(PREFIX),R=cam1:,PORT=$(PORT),ADDR=0,TIMEOUT=1")Macro Substitutions:
- P: EPICS prefix (e.g., "dp_mythen1K:")
- R: Record name prefix (e.g., "cam1:")
- PORT: Driver port name (e.g., "SD1")
- ADDR: asyn address (typically 0)
- TIMEOUT: Timeout in seconds
Array Size Configuration:
epicsEnvSet("EPICS_CA_MAX_ARRAY_BYTES", "64008") # For 1280 channels * 4 bytes
epicsEnvSet("XSIZE", "1280") # Number of channels
epicsEnvSet("YSIZE", "1") # Always 1 for strip detector
epicsEnvSet("NCHANS", "1280") # Total channelsConfigure the standard arrays plugin to make data available via Channel Access:
NDStdArraysConfigure("Image1", 3, 0, "$(PORT)", 0, 0)
dbLoadRecords("$(ADCORE)/db/NDStdArrays.template",
"P=$(PREFIX),R=image1:,PORT=Image1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT),NDARRAY_ADDR=0,TYPE=Float64,FTVL=DOUBLE,NELEMENTS=$(NCHANS)")Load additional plugins using the common plugins script:
< $(ADCORE)/iocBoot/commonPlugins.cmdThis loads standard plugins like:
- NDPluginFile (file saving)
- NDPluginStats (statistics)
- NDPluginROI (regions of interest)
- NDPluginColorConvert
- NDPluginOverlay
- NDPluginTransform
- NDPluginCircularBuff
- NDPluginAttribute
- NDPluginFFT
Configure autosave to restore detector settings:
set_requestfile_path("$(TOP)/mythenApp/Db")
create_monitor_set("auto_settings.req", 30, "P=$(PREFIX),D=cam1:")This saves detector settings every 30 seconds and restores them on IOC startup.
< envPaths
# Set array size for Channel Access
epicsEnvSet EPICS_CA_MAX_ARRAY_BYTES 64008
# Load database definitions
dbLoadDatabase("$(TOP)/dbd/mythenApp.dbd")
mythenApp_registerRecordDeviceDriver(pdbbase)
# Configure network connection
drvAsynIPPortConfigure("IP_M1K", "192.168.0.90:1030 UDP", 0, 0, 1)
asynOctetSetOutputEos("IP_M1K", 0, "\r")
# Set environment variables
epicsEnvSet("PREFIX", "dp_mythen1K:")
epicsEnvSet("PORT", "SD1")
epicsEnvSet("XSIZE", "1280")
epicsEnvSet("YSIZE", "1")
epicsEnvSet("NCHANS", "1280")
# Configure driver
mythenConfig("SD1", "IP_M1K", -1, -1)
# Load database
dbLoadRecords("$(ADMYTHEN)/mythenApp/Db/mythen.template",
"P=$(PREFIX),R=cam1:,PORT=$(PORT),ADDR=0,TIMEOUT=1")
# Configure plugins
NDStdArraysConfigure("Image1", 3, 0, "$(PORT)", 0, 0)
dbLoadRecords("$(ADCORE)/db/NDStdArrays.template",
"P=$(PREFIX),R=image1:,PORT=Image1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT),NDARRAY_ADDR=0,TYPE=Float64,FTVL=DOUBLE,NELEMENTS=$(NCHANS)")
< $(ADCORE)/iocBoot/commonPlugins.cmd
# Configure autosave
set_requestfile_path("$(TOP)/mythenApp/Db")
create_monitor_set("auto_settings.req", 30, "P=$(PREFIX),D=cam1:")
# Initialize IOC
iocInit()ADMythen inherits all standard parameters from ADDriver. Key parameters include:
| Parameter | Type | Description |
|---|---|---|
Acquire |
bo | Start/stop acquisition (0=Stop, 1=Start) |
AcquireTime |
ao | Exposure time per frame (seconds) |
AcquirePeriod |
ao | Time between frames (seconds) |
ImageMode |
mbbo | Single, Multiple, Continuous, or Stream |
NumImages |
longout | Number of images to acquire |
NumImagesCounter |
longin | Current image number |
ArraySizeX |
longin | Array size in X (channels) |
ArraySizeY |
longin | Array size in Y (always 1) |
DataType |
mbbo | Data type (NDInt32) |
Status |
mbbi | Detector status |
StatusMessage |
stringin | Status message |
See ADCore documentation for complete list of standard parameters.
SD_SETTING (mbbo/mbbi)
- Description: Detector setting for predefined X-ray source configurations
- Values:
- 0 = Cu (Copper)
- 1 = Mo (Molybdenum)
- 2 = Ag (Silver)
- 3 = Cr (Chromium)
- Access: Read/Write
- EPICS Records:
$(P)$(R)Setting,$(P)$(R)Setting_RBV
SD_FIRMWARE_VERSION (stringin)
- Description: Detector firmware version (read-only)
- Access: Read-only
- EPICS Record:
$(P)$(R)FirmwareVersion
SD_DELAY_TIME (ao/ai)
- Description: Delay after trigger before acquisition starts
- Units: seconds
- Range: 0.0 to 655.35 seconds (in 100ns steps)
- Default: 0.1 seconds
- Access: Read/Write
- EPICS Records:
$(P)$(R)DelayTime,$(P)$(R)DelayTime_RBV
SD_NUM_FRAMES (longout/longin)
- Description: Number of frames to acquire in one acquisition sequence
- Range: 1 to 500
- Default: 1
- Access: Read/Write
- EPICS Records:
$(P)$(R)NumFrames,$(P)$(R)NumFrames_RBV - Note: In Single image mode, this is automatically set to 1
SD_TRIGGER (mbbo/mbbi)
- Description: Trigger mode
- Values:
- 0 = None (software trigger only)
- 1 = Single (external trigger for single frame)
- 2 = Continuous (continuous acquisition on external triggers)
- Default: 0 (None)
- Access: Read/Write
- EPICS Records:
$(P)$(R)TriggerMode,$(P)$(R)TriggerMode_RBV
SD_READ_MODE (mbbo/mbbi)
- Description: Data readout mode
- Values:
- 0 = Raw (uncorrected data from detector)
- 1 = Corrected (data with corrections applied)
- Default: 0 (Raw)
- Access: Read/Write
- EPICS Records:
$(P)$(R)ReadMode,$(P)$(R)ReadMode_RBV
SD_THRESHOLD (ao/ai)
- Description: Energy threshold for photon counting
- Units: keV
- Range: 0.0 to 50.0 keV (typical)
- Default: 8.05 keV
- Access: Read/Write
- EPICS Records:
$(P)$(R)ThresholdEnergy,$(P)$(R)ThresholdEnergy_RBV
SD_ENERGY (ao/ai)
- Description: Beam energy (used for corrections)
- Units: keV
- Range: 0.0 to 50.0 keV (typical)
- Default: 8.1 keV
- Access: Read/Write
- EPICS Records:
$(P)$(R)BeamEnergy,$(P)$(R)BeamEnergy_RBV - Note: Only available in firmware version 3.0 or later
SD_USE_FLATFIELD (bo/bi)
- Description: Enable/disable flat field correction
- Values: 0 = Disable, 1 = Enable
- Default: 1 (Enabled)
- Access: Read/Write
- EPICS Records:
$(P)$(R)UseFlatField,$(P)$(R)UseFlatField_RBV
SD_USE_COUNTRATE (bo/bi)
- Description: Enable/disable count rate correction
- Values: 0 = Disable, 1 = Enable
- Default: 1 (Enabled)
- Access: Read/Write
- EPICS Records:
$(P)$(R)UseCountRate,$(P)$(R)UseCountRate_RBV
SD_TAU (ao/ai)
- Description: Deadtime constant for count rate correction
- Units: nanoseconds
- Range: -1.0 (use detector default) or > 0
- Default: -1.0
- Access: Read/Write
- EPICS Records:
$(P)$(R)Tau,$(P)$(R)Tau_RBV - Note: Set to -1 to use detector's default value
SD_USE_BADCHANNEL_INTRPL (bo/bi)
- Description: Enable/disable bad channel interpolation
- Values: 0 = Disable, 1 = Enable
- Default: 1 (Enabled)
- Access: Read/Write
- EPICS Records:
$(P)$(R)UseBadChanIntrpl,$(P)$(R)UseBadChanIntrpl_RBV
SD_BIT_DEPTH (mbbo/longin)
- Description: Bit depth for data readout
- Values:
- 0 = 24 bits
- 1 = 16 bits
- 2 = 8 bits
- 3 = 4 bits
- Default: 0 (24 bits)
- Access: Read/Write
- EPICS Records:
$(P)$(R)BitDepth,$(P)$(R)BitDepth_RBV - Note: Lower bit depths reduce data size but also reduce dynamic range
SD_USE_GATES (bo/bi)
- Description: Enable/disable gate mode
- Values: 0 = Disable, 1 = Enable
- Default: 0 (Disabled)
- Access: Read/Write
- EPICS Records:
$(P)$(R)UseGates,$(P)$(R)UseGates_RBV
SD_NUM_GATES (longout/longin)
- Description: Number of gates per frame
- Range: 1 to maximum supported by detector
- Default: 1
- Access: Read/Write
- EPICS Records:
$(P)$(R)NumGates,$(P)$(R)NumGates_RBV - Note: Only used when gate mode is enabled
SD_NMODULES (longin)
- Description: Number of detector modules (read-only)
- Range: 1 to 2
- Access: Read-only
- EPICS Record:
$(P)$(R)NumModules_RBV
SD_RESET (bo)
- Description: Reset detector (write-only)
- Access: Write-only
- EPICS Record:
$(P)$(R)Reset - Note: Writing 1 to this record resets the detector
| Parameter Name | EPICS Type | Data Type | Units | Range/Values | Access | Description |
|---|---|---|---|---|---|---|
| SD_SETTING | mbbo/mbbi | Int32 | - | 0-3 (Cu/Mo/Ag/Cr) | R/W | Detector setting |
| SD_DELAY_TIME | ao/ai | Float64 | s | 0.0-655.35 | R/W | Delay after trigger |
| SD_THRESHOLD | ao/ai | Float64 | keV | 0.0-50.0 | R/W | Energy threshold |
| SD_ENERGY | ao/ai | Float64 | keV | 0.0-50.0 | R/W | Beam energy |
| SD_USE_FLATFIELD | bo/bi | Int32 | - | 0/1 | R/W | Enable flat field |
| SD_USE_COUNTRATE | bo/bi | Int32 | - | 0/1 | R/W | Enable count rate correction |
| SD_TAU | ao/ai | Float64 | ns | -1.0 or >0 | R/W | Deadtime constant |
| SD_USE_BADCHANNEL_INTRPL | bo/bi | Int32 | - | 0/1 | R/W | Enable bad channel interpolation |
| SD_BIT_DEPTH | mbbo/longin | Int32 | - | 0-3 (24/16/8/4 bits) | R/W | Bit depth |
| SD_USE_GATES | bo/bi | Int32 | - | 0/1 | R/W | Enable gates |
| SD_NUM_GATES | longout/longin | Int32 | - | 1-max | R/W | Number of gates |
| SD_NUM_FRAMES | longout/longin | Int32 | - | 1-500 | R/W | Number of frames |
| SD_TRIGGER | mbbo/mbbi | Int32 | - | 0-2 (None/Single/Continuous) | R/W | Trigger mode |
| SD_READ_MODE | mbbo/mbbi | Int32 | - | 0-1 (Raw/Corrected) | R/W | Read mode |
| SD_NMODULES | longin | Int32 | - | 1-2 | R | Number of modules |
| SD_FIRMWARE_VERSION | stringin | String | - | - | R | Firmware version |
| SD_RESET | bo | Int32 | - | 0/1 | W | Reset detector |
-
Navigate to IOC directory:
cd /epics/support/areaDetector/ADMythen/iocs/mythenIOC/iocBoot/iocMythen -
Edit st.cmd to configure detector IP address and other settings
-
Start the IOC:
./st.cmd
Or use the run script:
./run
-
Verify startup:
- Check for error messages
- Verify detector connection
- Check that records are loaded
-
Set exposure time:
caput dp_mythen1K:cam1:AcquireTime 1.0 # 1 second exposure -
Set image mode to Single:
caput dp_mythen1K:cam1:ImageMode 0 # Single -
Start acquisition:
caput dp_mythen1K:cam1:Acquire 1
-
Monitor status:
caget dp_mythen1K:cam1:Acquire caget dp_mythen1K:cam1:Status
-
Read data (via NDStdArrays plugin):
caget dp_mythen1K:image1:ArrayData
-
Set number of frames:
caput dp_mythen1K:cam1:NumFrames 10
-
Set image mode to Multiple:
caput dp_mythen1K:cam1:ImageMode 1 # Multiple -
Set acquire period (time between frames):
caput dp_mythen1K:cam1:AcquirePeriod 2.0 # 2 seconds between frames -
Start acquisition:
caput dp_mythen1K:cam1:Acquire 1
-
Monitor progress:
caget dp_mythen1K:cam1:NumImagesCounter
Default mode. Acquisition is started by software only:
caput dp_mythen1K:cam1:TriggerMode 0 # None
caput dp_mythen1K:cam1:Acquire 1 # Start acquisitionOne frame per external trigger:
caput dp_mythen1K:cam1:TriggerMode 1 # Single
caput dp_mythen1K:cam1:Acquire 1 # Arm detector
# Detector waits for external triggerContinuous acquisition on external triggers:
caput dp_mythen1K:cam1:TriggerMode 2 # Continuous
caput dp_mythen1K:cam1:ImageMode 2 # Continuous
caput dp_mythen1K:cam1:Acquire 1 # Start continuous mode
# Each external trigger acquires one frameFlat field correction compensates for channel-to-channel variations:
# Enable flat field correction
caput dp_mythen1K:cam1:UseFlatField 1
# Disable flat field correction
caput dp_mythen1K:cam1:UseFlatField 0Note: Flat field calibration must be performed on the detector before use.
Count rate correction compensates for deadtime effects at high count rates:
# Enable count rate correction
caput dp_mythen1K:cam1:UseCountRate 1
# Set deadtime constant (nanoseconds)
# Use -1 for detector default, or set specific value
caput dp_mythen1K:cam1:Tau 1000.0 # 1000 ns deadtimeWhen to use: At high count rates (>100 kHz per channel typically)
Interpolates values for known bad channels:
# Enable bad channel interpolation
caput dp_mythen1K:cam1:UseBadChanIntrpl 1
# Disable (use raw values for bad channels)
caput dp_mythen1K:cam1:UseBadChanIntrpl 0Uncorrected data directly from detector:
caput dp_mythen1K:cam1:ReadMode 0 # RawUse when:
- You want to apply your own corrections
- Debugging detector issues
- Maximum data fidelity needed
Data with detector corrections applied:
caput dp_mythen1K:cam1:ReadMode 1 # CorrectedUse when:
- Standard operation
- Corrections are properly calibrated
- Simplified data processing
Use predefined settings for common X-ray sources:
# Copper K-alpha (8.05 keV)
caput dp_mythen1K:cam1:Setting 0 # Cu
# Molybdenum K-alpha (17.48 keV)
caput dp_mythen1K:cam1:Setting 1 # Mo
# Silver K-alpha (22.16 keV)
caput dp_mythen1K:cam1:Setting 2 # Ag
# Chromium K-alpha (5.41 keV)
caput dp_mythen1K:cam1:Setting 3 # CrSet custom energy values:
# Set threshold energy
caput dp_mythen1K:cam1:ThresholdEnergy 10.0 # 10 keV
# Set beam energy (firmware 3.0+)
caput dp_mythen1K:cam1:BeamEnergy 10.5 # 10.5 keVGate mode allows time-resolved measurements:
# Enable gate mode
caput dp_mythen1K:cam1:UseGates 1
# Set number of gates per frame
caput dp_mythen1K:cam1:NumGates 4 # 4 gates per frame
# Start acquisition
caput dp_mythen1K:cam1:Acquire 1Use cases:
- Time-resolved experiments
- Pump-probe measurements
- Synchronized with external events
Choose bit depth based on dynamic range needs:
# 24 bits (maximum dynamic range)
caput dp_mythen1K:cam1:BitDepth 0
# 16 bits (reduced data size)
caput dp_mythen1K:cam1:BitDepth 1
# 8 bits (minimal data size)
caput dp_mythen1K:cam1:BitDepth 2
# 4 bits (very limited dynamic range)
caput dp_mythen1K:cam1:BitDepth 3Trade-offs:
- Higher bit depth = larger data files, more dynamic range
- Lower bit depth = smaller files, less dynamic range
The driver includes MEDM (Motif Editor and Display Manager) screens:
Main Control Screen: mythenApp/op/adl/mythen.adl
To launch:
medm -x -macro "P=dp_mythen1K:,R=cam1:" mythenApp/op/adl/mythen.adlOr use the provided script:
./start_medm_mythenThe screen includes:
- Acquisition controls
- Detector settings
- Energy and threshold controls
- Correction enable/disable
- Status display
- Data display
The driver includes screens in multiple formats:
- EDM:
mythenApp/op/edl/autoconvert/mythen.edl - CSS/Bob:
mythenApp/op/bob/autoconvert/mythen.bob - OPI:
mythenApp/op/opi/autoconvert/mythen.opi - UI:
mythenApp/op/ui/autoconvert/mythen.ui
Use EPICS Channel Access command-line tools:
Get parameter values:
caget dp_mythen1K:cam1:AcquireTime
caget dp_mythen1K:cam1:Status
caget dp_mythen1K:cam1:FirmwareVersionSet parameter values:
caput dp_mythen1K:cam1:AcquireTime 2.0
caput dp_mythen1K:cam1:TriggerMode 1Monitor parameters:
camonitor dp_mythen1K:cam1:Status
camonitor dp_mythen1K:cam1:NumImagesCounterGet array data:
caget dp_mythen1K:image1:ArrayDataComplete IOC configuration for basic operation:
st.cmd:
< envPaths
epicsEnvSet EPICS_CA_MAX_ARRAY_BYTES 64008
dbLoadDatabase("$(TOP)/dbd/mythenApp.dbd")
mythenApp_registerRecordDeviceDriver(pdbbase)
drvAsynIPPortConfigure("IP_M1K", "192.168.0.90:1030 UDP", 0, 0, 1)
asynOctetSetOutputEos("IP_M1K", 0, "\r")
epicsEnvSet("PREFIX", "mythen:")
epicsEnvSet("PORT", "SD1")
epicsEnvSet("NCHANS", "1280")
mythenConfig("SD1", "IP_M1K", -1, -1)
dbLoadRecords("$(ADMYTHEN)/mythenApp/Db/mythen.template",
"P=$(PREFIX),R=cam1:,PORT=$(PORT),ADDR=0,TIMEOUT=1")
NDStdArraysConfigure("Image1", 3, 0, "$(PORT)", 0, 0)
dbLoadRecords("$(ADCORE)/db/NDStdArrays.template",
"P=$(PREFIX),R=image1:,PORT=Image1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT),NDARRAY_ADDR=0,TYPE=Float64,FTVL=DOUBLE,NELEMENTS=$(NCHANS)")
iocInit()Acquisition sequence:
# Set 1 second exposure
caput mythen:cam1:AcquireTime 1.0
# Single image mode
caput mythen:cam1:ImageMode 0
# Start acquisition
caput mythen:cam1:Acquire 1
# Wait for completion, then read data
caget mythen:image1:ArrayDataConfiguration for triggered multi-frame acquisition:
# Set trigger mode to Single
caput mythen:cam1:TriggerMode 1
# Set number of frames
caput mythen:cam1:NumFrames 10
# Set image mode to Multiple
caput mythen:cam1:ImageMode 1
# Set exposure time
caput mythen:cam1:AcquireTime 0.5
# Set delay after trigger
caput mythen:cam1:DelayTime 0.1
# Arm detector (waits for triggers)
caput mythen:cam1:Acquire 1
# Monitor progress
camonitor mythen:cam1:NumImagesCounterConfiguration for continuous acquisition with all corrections enabled:
# Enable all corrections
caput mythen:cam1:UseFlatField 1
caput mythen:cam1:UseCountRate 1
caput mythen:cam1:UseBadChanIntrpl 1
# Set count rate correction parameters
caput mythen:cam1:Tau 1000.0
# Use corrected read mode
caput mythen:cam1:ReadMode 1
# Set energy for Cu K-alpha
caput mythen:cam1:Setting 0 # Cu
# Continuous mode
caput mythen:cam1:ImageMode 2
caput mythen:cam1:TriggerMode 2 # Continuous trigger
# Start continuous acquisition
caput mythen:cam1:Acquire 1Save data automatically using NDPluginFile:
# In st.cmd, load file plugin:
NDFileHDF5Configure("HDF1", 50, 0, "$(PORT)", 0, 0, 0)
dbLoadRecords("$(ADCORE)/db/NDFileHDF5.template",
"P=$(PREFIX),R=HDF1:,PORT=HDF1,ADDR=0,TIMEOUT=1,NDARRAY_PORT=$(PORT),NDARRAY_ADDR=0")
# Enable file saving
caput mythen:HDF1:EnableCallbacks 1
caput mythen:HDF1:FileWriteMode 2 # Stream mode
# Set file path and name
caput mythen:HDF1:FilePath "/data/mythen"
caput mythen:HDF1:FileName "scan_001"
caput mythen:HDF1:AutoIncrement 1
caput mythen:HDF1:AutoSave 1
# Start acquisition (files saved automatically)
caput mythen:cam1:Acquire 1Problem: Cannot connect to detector
Solutions:
-
Verify network connectivity:
ping 192.168.0.90
-
Check IP address and port in st.cmd:
drvAsynIPPortConfigure("IP_M1K", "192.168.0.90:1030 UDP", 0, 0, 1)
-
Verify detector is powered on and network configured
-
Check firewall settings (port 1030 UDP should be open)
-
Enable asyn tracing:
asynSetTraceIOMask("IP_M1K", 0, 6) # Trace I/O asynSetTraceMask("IP_M1K", 0, 3) # Trace errors
Problem: Connection timeout
Solutions:
- Increase timeout in database template
- Check network latency
- Verify detector firmware is compatible
Problem: Acquisition times out
Solutions:
-
Check exposure time:
caget mythen:cam1:AcquireTime
Timeout is automatically set to
M1K_TIMEOUT + AcquireTime -
Verify trigger mode (if using external trigger):
caget mythen:cam1:TriggerMode
-
Check detector status:
caget mythen:cam1:Status
-
Increase timeout if needed (modify
M1K_TIMEOUTin source code)
Problem: No data received
Solutions:
-
Check read mode:
caget mythen:cam1:ReadMode
-
Verify number of modules:
caget mythen:cam1:NumModules_RBV
-
Check array size configuration:
caget mythen:cam1:ArraySizeX
-
Enable I/O tracing to see communication
Problem: Wrong data values
Solutions:
-
Check bit depth setting:
caget mythen:cam1:BitDepth
-
Verify corrections are appropriate:
caget mythen:cam1:UseFlatField caget mythen:cam1:UseCountRate
-
Check energy/threshold settings
Problem: Records not loading
Solutions:
-
Verify database path:
dbLoadRecords("$(ADMYTHEN)/mythenApp/Db/mythen.template", ...) -
Check macro substitutions:
epicsEnvSet("PREFIX", "mythen:") epicsEnvSet("PORT", "SD1")
-
Verify ADCore path in RELEASE file
Problem: Plugin not working
Solutions:
-
Check plugin configuration:
NDStdArraysConfigure("Image1", 3, 0, "$(PORT)", 0, 0)
-
Verify NDARRAY_PORT in plugin database:
NDARRAY_PORT=$(PORT) -
Check EPICS_CA_MAX_ARRAY_BYTES:
epicsEnvSet EPICS_CA_MAX_ARRAY_BYTES 64008
Enable detailed I/O tracing:
# In st.cmd or iocsh:
asynSetTraceIOMask("IP_M1K", 0, 0xFFFF) # Trace all I/O
asynSetTraceMask("IP_M1K", 0, 0xFFFF) # Trace all messagesTrace masks:
- I/O Mask: 1=read, 2=write, 4=flush, 8=connect/disconnect
- General Mask: 1=traceIO, 2=traceError, 4=traceWarning, 8=traceInfo, 16=traceFlow
Monitor status:
camonitor mythen:cam1:Status
camonitor mythen:cam1:AcquireGet all parameters:
caget mythen:cam1:*Check detector settings:
caget mythen:cam1:FirmwareVersion
caget mythen:cam1:NumModules_RBV
caget mythen:cam1:Setting_RBVTest network connection:
# Test UDP connection
nc -u 192.168.0.90 1030
# Check if port is open
nmap -sU -p 1030 192.168.0.90- ADStatusIdle (0): Detector idle, ready for acquisition
- ADStatusAcquire (1): Acquiring data
- ADStatusReadout (2): Reading out data
- ADStatusError (3): Error occurred
The driver checks firmware version on startup. Some features (like SD_ENERGY) require firmware 3.0 or later.
Check firmware:
caget mythen:cam1:FirmwareVersionConfigure buffer limits based on available memory:
# Limit to 100 buffers, 100MB
mythenConfig("SD1", "IP_M1K", 100, 100000000)- Use UDP for lower latency (default)
- Ensure low network latency (< 1 ms typical)
- Avoid network congestion
Adjust thread priorities if needed (advanced):
mythenConfig("SD1", "IP_M1K", -1, -1, 50, 200000)
# priority=50, stackSize=200000The driver communicates with the Mythen detector using a text-based command protocol over TCP/IP.
Commands are sent as ASCII strings terminated with carriage return (\r):
-command [arguments]\r
Responses are binary data:
- Integer responses: 4-byte signed integer (big-endian or little-endian)
- Float responses: 4-byte float (for tau command)
- String responses: ASCII string (for version command)
- Data readout: Binary array of integers
| Command | Description | Response |
|---|---|---|
-start |
Start acquisition | Int32 (0=success) |
-stop |
Stop acquisition | Int32 (0=success) |
-time <hns> |
Set exposure time (100ns units) | Int32 |
-delafter <hns> |
Set delay after trigger (100ns units) | Int32 |
-frames <n> |
Set number of frames | Int32 |
-trigen <0|1> |
Enable/disable single trigger | Int32 |
-conttrigen <0|1> |
Enable/disable continuous trigger | Int32 |
-readout |
Read corrected data | Binary array |
-readoutraw |
Read raw data | Binary array |
-kthresh <keV> |
Set threshold energy | Int32 |
-energy <keV> |
Set beam energy (firmware 3.0+) | Int32 |
-tau <ns> |
Set deadtime constant | Float32 |
-flatfieldcorrection <0|1> |
Enable/disable flat field | Int32 |
-ratecorrection <0|1> |
Enable/disable rate correction | Int32 |
-badchannelinterpolation <0|1> |
Enable/disable bad channel interpolation | Int32 |
-gateen <0|1> |
Enable/disable gates | Int32 |
-gates <n> |
Set number of gates | Int32 |
-module <n> |
Select module (0 or 1) | Int32 |
-get nmodules |
Get number of modules | Int32 |
-get version |
Get firmware version | String |
-get tau |
Get tau value | Float32 |
-setting <0|1|2|3> |
Set predefined setting (Cu/Mo/Ag/Cr) | Int32 |
-bitdepth <0|1|2|3> |
Set bit depth (24/16/8/4 bits) | Int32 |
The driver automatically handles byte order:
- Detector uses big-endian format
- Driver swaps bytes on little-endian systems
- Handled transparently by
swap4()andswap8()functions
- Data Type:
NDInt32(32-bit signed integers) - Dimensions: 1D array (1280 channels × number of modules)
- Color Mode: Monochrome (
NDColorModeMono) - Array Size:
- Single module: 1280 channels
- Two modules: 2560 channels
- Raw Mode: Data encoded according to bit depth setting
- Corrected Mode: 24-bit data with corrections applied
- Byte Order: Native endianness (swapped if needed)
Each NDArray includes standard attributes:
ColorMode: Color mode (monochrome)UniqueId: Unique frame identifierTimeStamp: Acquisition timestamp- Standard areaDetector attributes
- Firmware 2.x: Basic functionality
- Firmware 3.0+: Full functionality including energy command
Firmware version is read on driver initialization:
-get versionStored in SD_FIRMWARE_VERSION parameter.
- Energy command: Requires firmware 3.0 or later
- Read mode: Available in all versions
- Corrections: Available in all versions
- Maximum modules: 2 modules
- Channels per module: 1280 channels
- Maximum frames: 500 frames per acquisition
- Bit depth: 4, 8, 16, or 24 bits
- Timeout: 5.0 seconds base timeout (
M1K_TIMEOUT) - Maximum trigger timeout count: 50 retries
- Array size: Fixed at 1280 × number of modules
- Windows: Full support
- Linux: Full support (little-endian and big-endian)
- Other platforms: May require porting
Configure the Mythen driver:
int mythenConfig(const char *portName,
const char *IPPortName,
int maxBuffers,
int maxMemory,
int priority = 0,
int stackSize = 0)Parameters:
portName: Driver port nameIPPortName: asyn IP port namemaxBuffers: Maximum NDArray buffers (-1 = unlimited)maxMemory: Maximum memory in bytes (-1 = unlimited)priority: Thread priority (optional)stackSize: Thread stack size (optional)
Returns: 0 on success
Key methods in the mythen class:
setAcquire(): Start/stop acquisitionsetExposureTime(): Set exposure timesetTrigger(): Set trigger modesetFrames(): Set number of framesdataCallback(): Process acquired dataacquisitionTask(): Acquisition threadpollTask(): Status polling thread
ADMythen/
├── configure/ # Build configuration
│ ├── RELEASE # EPICS module paths
│ ├── CONFIG # Build configuration
│ └── ...
├── iocs/ # IOC applications
│ └── mythenIOC/
│ ├── configure/ # IOC configuration
│ ├── iocBoot/ # IOC startup scripts
│ │ └── iocMythen/
│ │ ├── st.cmd # Main startup script
│ │ └── auto_settings.req # Autosave request file
│ └── mythenApp/
│ └── src/
│ └── mythenAppMain.cpp # IOC main
├── mythenApp/ # Driver application
│ ├── Db/ # Database templates
│ │ ├── mythen.template # Main database template
│ │ └── mythen_settings.req # Autosave settings
│ ├── op/ # Operator interface files
│ │ ├── adl/ # MEDM screens
│ │ │ └── mythen.adl
│ │ ├── edl/ # EDM screens
│ │ ├── bob/ # CSS/Bob screens
│ │ ├── opi/ # OPI screens
│ │ └── ui/ # UI screens
│ └── src/ # Source code
│ ├── mythen.cpp # Main driver implementation
│ └── mythenSupport.dbd # Database definitions
├── LICENSE # License file
├── README.md # This file
└── RELEASE.md # Release notes
The main database template is mythenApp/Db/mythen.template. It includes:
- Standard ADBase records (from
ADBase.template) - Mythen-specific records for all driver parameters
- Readback records (RBV) for all writable parameters
Key Records:
| Record Name | Type | Description |
|---|---|---|
$(P)$(R)Setting |
mbbo | Detector setting |
$(P)$(R)DelayTime |
ao | Delay after trigger |
$(P)$(R)ThresholdEnergy |
ao | Energy threshold |
$(P)$(R)BeamEnergy |
ao | Beam energy |
$(P)$(R)UseFlatField |
bo | Enable flat field |
$(P)$(R)UseCountRate |
bo | Enable count rate correction |
$(P)$(R)Tau |
ao | Deadtime constant |
$(P)$(R)UseBadChanIntrpl |
bo | Enable bad channel interpolation |
$(P)$(R)BitDepth |
mbbo | Bit depth |
$(P)$(R)UseGates |
bo | Enable gates |
$(P)$(R)NumGates |
longout | Number of gates |
$(P)$(R)NumFrames |
longout | Number of frames |
$(P)$(R)TriggerMode |
mbbo | Trigger mode |
$(P)$(R)ReadMode |
mbbo | Read mode |
$(P)$(R)NumModules_RBV |
longin | Number of modules (read-only) |
$(P)$(R)FirmwareVersion |
stringin | Firmware version (read-only) |
All writable records have corresponding _RBV readback records.
The build system uses EPICS standard Makefiles:
- Top-level Makefile: Builds driver and IOC
- mythenApp/Makefile: Builds driver library
- iocs/mythenIOC/Makefile: Builds IOC application
make # Build everything
make install # Install libraries and binaries
make clean # Clean build files
make uninstall # Remove installed files- configure/RELEASE: EPICS module paths
- configure/CONFIG: Build configuration
- configure/CONFIG_SITE: Site-specific configuration
- ADDriver: areaDetector base driver class
- asyn: EPICS asynchronous I/O library
- EPICS: Experimental Physics and Industrial Control System
- IOC: Input/Output Controller (EPICS server)
- NDArray: areaDetector data array format
- NDPlugin: areaDetector plugin for data processing
- PV: Process Variable (EPICS record)
- RBV: Readback Value (read-only copy of parameter)
- Strip Detector: One-dimensional detector with linear array of pixels
- Dectris Website
- Mythen detector user manual (contact Dectris)
See RELEASE.md for detailed release notes and version history.
- Updated for areaDetector R3-3 compatibility
- Minor debugging improvements
- Windows compilation support
- Big-endian machine support
- Fixed error in writeFloat64
- Updated medm screen for ADCore R3-0
- Initial release
- Based on LNLS asyn driver
- areaDetector integration by Joe Sullivan (ANL-APS)
- Check this documentation first
- Review troubleshooting section
- Check areaDetector mailing list
- Contact detector manufacturer (Dectris) for hardware issues
Report issues via:
- GitHub issues (if repository is on GitHub)
- areaDetector mailing list
- Contact maintainers
Contributions are welcome! Please:
- Follow EPICS coding standards
- Test on multiple platforms
- Update documentation
- Submit pull requests or patches
Last Updated: Based on ADMythen R2-1
Maintainers:
- Original: Joe Sullivan (ANL-APS/XSD/BCDA)
- Contributors: M. Moore (ANL-APS/XSD/DET)
Documentation:
- Created by K. Gofron (ORNL, Oak Ridge National Laboratory, December 6, 2025)