Dante

author:Mark Rivers, University of Chicago

Table of Contents

Overview

This is an EPICS driver for the XGLab Dante digital x-ray spectroscopy system. The source code is in the dante repository in the Github epics-modules project. The Dante is available in single channel (Dante1) and 8-channel (Dante8) versions. This module is intended to work with either, though it has currently only been tested on the single-channel version. In this document NumBoards refers to the number of enabled input channels, e.g. 1 for a Dante1, up to 8 for a Dante8, and >8 for systems with more than one Dante8 daisy-chained together. If a channel is disabled then it is not counted in NumBoards.

The Dante can collect data in 3 different modes:

  • Single MCA spectrum. It acquires a single MCA spectrum on all channels.
  • MCA mapping mode. It acquires multiple spectra in rapid succession, and it often used for making an x-ray map where there is an MCA spectrum for each channel at each pixel. The advance to the next pixel can come from an internal clock or an external trigger.
  • List mapping mode. It acquires each x-ray event energy and timestamp in a list buffer.

The Dante driver is derived from the base class asynNDArrayDriver, which is part of the EPICS areaDetector package. The allows the Dante driver to use all of the areaDetector plugins for file saving in MCA mapping and list modes, and for other purposes. It also implements the mca interface from the EPICS mca module. The EPICS mca record can be used to display the spectra and control the basic operation including Regions-of-Interest (ROIs).

The Dante driver can be used on both Windows and Linux. A Windows machine with a USB interface is required to load new firmware. Otherwise the module can be used from either Linux or Windows over Ethernet. The Linux library provided can run on most Linux versions, including RHEL7/Centos7.

This document does not attempt to give an explanation of the principles of operation of the Dante, or a detailed explanation of the many configuration parameters for the digital pulse processing. The user should consult the DanteManual for this information.

System controls

These records are in the file dante.template. This database is loaded once for the Dante system. It provides control of the system-wide settings for the system.

EPICS record names Record types drvInfo string Description
CollectMode, CollectMode_RBV mbbo, mbbi DanteCollectMode Controls the data collection mode. Choices are “MCA” (0), “MCA Mapping” (1) and “List” (2).
GatingMode, GatingMode_RBV mbbo, mbbi DanteGatingMode Controls the gating mode. Choices are “Free running” (0), “Trig rising” (1), “Trig falling” (2), “Trig both” (3), “Gate high” (4), “Gate low” (5).
NumMCAChannels, NumMCAChannels_RBV mbbo, mbbi MCA_NUM_CHANNELS The number of MCA channels to use. Choices are 1024, 2048, 4096.
PollTime, PollTime_RBV ao, ai DantePollTime The time between polls when reading completion status, MCA mapping data, and list mode data from the driver. 0.01 second is a reasonable value that will provide good response and resource utilization.
PresetReal ao MCA_PRESET_REAL Sets the preset real time. Set this to 0 to count forever in MCA mode or List mode.
EraseStart bo N.A. Processing this record starts acquisition for all boards in the selected CollectMode.
StartAll bo MCA_START_ACQUIRE Processing this record starts acquisition for all boards in the selected CollectMode. This record should not be used by higher-level software, it is processed by EraseStart.
MCAAcquireBusy busy N.A. This record goes to 1 (“Collecting”) when EraseStart is processed. It goes back to 0 (“Done”)when 3 conditions are satisfied. 1) MCAAcquiring is 0; 2) All MCA records have .ACQG field=0; 3)AcquireBusy from areaDetector=0. The last condition can ensure that all plugins are done processing if WaitForPlugins is set.
MCAAcquiring bi MCA_ACQUIRING This record is 1 when the Dante driver itself is acquiring, and 0 when it is done. This record is generally not used by higher level software, use MCAAcquireBusy instead, since it indicates when all components are done.
StopAll bo MCA_STOP_ACQUIRE Processing this record stops acquisition for all boards in the selected CollectMode. This only needs to be used to terminate acquisition before it would otherwise stop because PresetReal or NumMappingPoints have been reached.
ReadAll bo N.A. Processing this record reads the MCA data and statistics for all boards. This .SCAN field of this record is typically set to periodic, i.e. “1 second”, “.1 second”, etc. to provide user feedback while acquisition is in progress. It can be set to “Passive” and the system will still read the data once when acquisition completes. This can be used to improve performance at very short PresetReal times. This record is disabled when acquisition is complete to reduce unneeded resource usage.
ReadAllOnce bo N.A. Processing this record reads the MCA data and statistics for all boards. This record is processed by ReadAll. It can be manually processed to read the data even when acquisition is complete.
ElapsedReal ai MCA_ELAPSED_REAL The elapsed real time.
ElapsedLive ai MCA_ELAPSED_LIVE The elapsed live time.
DeadTime ai DanteDeadTime The cummulative deadtime.
IDeadTime ai DanteIDeadTime The “instantaneous” deadtime since the previous readout.

Configuration parameters

These records control the configuration of the digital signal processing. The readback (_RBV) values may differ slightly from the output values because of the discrete nature of the system clocks and MCA bins.

These parameters are specific to a single board, and are contained in DanteN.template.

EPICS record names Record types drvInfo string Description
EnableBoard, EnableBoard_RBV bo, bi DanteEnableBoard Enables (1) or disables (0) a board in a Dante8. This allows using fewer than 8 channels on a Dante8.
InputMode, InputMode_RBV mbbo, mbbi DanteInputMode The analog input mode. Choices are “DC_HiImp” (0), “DC_LoImp” (1). “AC_Slow” (2), and “AC_Fast” (3).
InputPolarity, InputPolarity_RBV bo, bi DanteInvertedInput The pre-amp output polarity. Choices are “Pos.” (0) and “Neg.” (1).
MaxEnergy, MaxEnergy_RBV ao, ai DanteMaxEnergy The actual energy of the last channel. The user must provide this value based on the energy calibration. It is used to provide meaningful units for FastThreshold, EnergyThreshold, and BaselineThreshold.
AnalogOffset, AnalogOffset_RBV longout, longin DanteAnalogOffset The analog offset applied to the input signal, 0 to 255. This offset must be adjusted to keep the input signal within the range of the ADC. This should be adjusted using the ADC Trace plot with a long sampling to see the range of the input signal through a reset event.
ResetThreshold, ResetThreshold_RBV longout, longin DanteResetThreshold The reset threshold in ADC units per N 8 ns sample intervals. The Dante detects a reset the signal changes by more than this amount. The standard firmware uses N=6 and this ResetThreshold value. The high-rate firmware uses N=1 and fixes ResetThreshold=256, so this parameter has no effect.
ResetRecoveryTime, ResetRecoveryTime_RBV ao, ai DanteResetRecoveryTime The time in microseconds to wait after a reset event.
Gain, Gain_RBV ao, ai DanteGain The gain which controls the number of ADC units per MCA bin. Gains of 1.0-8.0 are typical.
FastThreshold, FastThreshold_RBV ao, ai DanteFastFilterThreshold The fast filter threshold in keV.
FastPeakingTime, FastPeakingTime_RBV ao, ai DanteEdgePeakingTime The peaking time of the fast filter in microseconds.
FastFlatTopTime, FastFlatTopTime_RBV ao, ai DanteEdgeFlatTop The flat top time of the fast filter in microseconds.
EnergyThreshold, EnergyThreshold_RBV ao, ai DanteEnergyFilterThreshold The energy filter threshold in keV.
PeakingTime, PeakingTime_RBV ao, ai DantePeakingTime The peaking time of the slow filter in microseconds.
MaxPeakingTime, MaxPeakingTime_RBV ao, ai DanteMaxPeakingTime The maximum peaking time of the slow filter in microseconds. Used only with the high-rate firmware. Must be set to 0 when using the standard firmware.
FlatTopTime, FlatTopTime_RBV ao, ai DanteFlatTop The flat top time of the slow filter in microseconds.
BaselineThreshold, BaselineThreshold_RBV ao, ai DanteEnergyBaselineThreshold The baseline filter threshold in keV.
MaxRiseTime, MaxRiseTime_RBV ao, ai DanteMaxRiseTime The maximum rise time in usec. Pulses with a longer rise time will be pileup rejected.
ZeroPeakFreq, ZeroPeakFreq_RBV ao, ai DanteZeroPeakFreq The frequency of the zero-energy peak in Hz.
BaselineSamples, BaselineSamples_RBV longout, longin DanteBaselineSamples The number of baseline samples. Typical value is 64.
TimeConstant, TimeConstant_RBV ao, ai DanteTimeConstant The time constant. Used for digital deconvolution in the case of continuous reset signals.
BaseOffset, BaseOffset_RBV longout, longin DanteBaseOffset The base offset. Used for digital deconvolution in the case of continuous reset signals.

Run-time statistics

These are the records for run-time statistics.

These parameters are specific to a single board, and are contained in DanteN.template.

EPICS record names Record types drvInfo string Description
ElapsedRealTime ai MCA_ELAPSED_REAL The elapsed real time in seconds.
ElapsedLiveTime ai MCA_ELAPSED_LIVE The elapsed live time in seconds.
InputCountRate ai DanteInputCountRate The input count rate in kHz.
OutputCountRate ai DanteOutputCountRate The output count rate in kHz.
Triggers longin DanteTriggers The number of triggers received.
Events longin DanteEvents The number of events received.
FastDeadTime longin DanteEdgeDTime The fast deadtime in clock ticks.
F1DeadTime longin DanteFilt1DT The filter 1 deadtime in clock ticks.
ZeroCounts longin DanteZeroCounts The number of zero count events.
BaselineCount longin DanteBaselinesValue The number of baseline events.
PileUp longin DantePUPValue The number of pileup events.
F1PileUp longin DantePUPF1Value The number of filter 1 pileup events.
NotF1PileUp longin DantePUPNotF1Value The number of not filter 1 pileup events.
ResetCounts longin DanteResetCounterValue The number of reset events.
LastTimeStamp ai DanteLastTimeStamp The last timestamp time in clock ticks.

medm screens

The following is the main MEDM screen dante1.adl. This screen is used with the single-channel Dante1.

_images/dante1.png

The following is the main MEDM screen dante8.adl. This screen is used with the 8-channel Dante8.

_images/dante8.png

Multi-element systems

Multi-element detector (MED) systems use an EPICS State Notation Language (SNL) program to synchronize and copy PVs.

These are the records for multi-element detector systems. They are contained in danteMED.template.

EPICS record names Record type Description
SNLConnected bi Indicates whether or not the SNL program is running.
DeadTime ai The average deadtime of all the enabled boards.
IDeadTime ai The average instantaneous deadtime of all the enabled boards.
Copy[XXX] bo Copies the setting XXX from board 0 to all other enabled boards. XXX can be any of the configuration parameters described above, for example Gain, AnalogOffset, etc. XXX can also be the definition of the ROIs for the MCA records. In this case the copy can be either by MCA channel number, or by x-ray energy, using the calibration coefficients in the MCA record.

The following is the MEDM screen dante8Parameters.adl. This screen is used with the Dante8.

_images/dante8Parameters.png

The following is the MEDM screen dante8MCA.adl. This screen is used with the Dante8.

_images/dante8MCA.png

The following is the MEDM screen dante8Statistics.adl. This screen is used with the Dante8.

_images/dante8Statistics.png

The following is the MEDM screen dante8ROI.adl. This screen is used with the Dante8. It allows copying the definition of 16 ROIs from board 0 to all boards.

_images/dante8ROI.png

MCA mode

The MCA mode collects a single MCA record at a time. It is compatible with the MCA record, and is the same as MCA operation on many other EPICS MCAs, e.g. Canberra AIM, Amptek, XIA (Saturn, Mercury, xMAP, FalconX), SIS38XX, and others.

It only supports counting for a preset real time, or counting indefinitely (PresetReal=0). It does not support PresetLive or PresetCounts which some other MCAs do.

The following is the MEDM screen mca.adl displaying the MCA spectrum as it is acquiring.

_images/dante_mca.png

The following is the IDL MCA Display program showing the MCA spectrum as it is acquiring. This GUI allows defining ROIs graphically, fitting peaks and background, and many other features.

_images/dante_idl_mca.png

MCA mapping mode

These are the records for MCA Mapping mode. They are contained in dante.template.

EPICS record names Record types drvInfo string Description
CurrentPixel longin DanteCurrentPixel In MCA Mapping mode this is the current pixel number. In List mode it is the total number of x-ray events received so far.
MappingPoints, MappingPoints_RBV longout, longin DanteMappingPoints The number of spectra to collect in MCA mapping mode.

In MCA mapping mode the GatingMode can be “Free running”, “Trig rising”, “Trig falling”, or “Trig both”. In free-running mode the Dante will begin the next spectrum when the PresetReal time has elapsed. In triggered mode the Dante will begin the next spectrum when a trigger occurs or when the PresetReal time has elapsed, whichever comes first. To advance only on trigger events set the PresetReal time to a value larger than the maximum time between triggers.

The MCA spectra are copied into NDArrays of dimensions [NumMCAChannels, NumBoards]. For a 1-channel Dante NumBoards is 1. The run-time statistics for each spectrum are copied into NDAttributes attached to each NDArray. The attribute names contain the board number, for example “RealTime_0”.

The NDArrays can be used by any of the standard areaDetector plugins. For example, they can be streamed to HDF5, netCDF, or TIFF files.

The following is the MEDM screen NDFileHDF5.adl when the Dante is saving MCA mapping data to an HDF5 file.

_images/dante_mapping_hdf5.png

List mode

These are the records for list mode. They are contained in dante.template.

EPICS record names Record types drvInfo string Description
CurrentPixel longin DanteCurrentPixel In List mode this is the total number of x-ray events received so far.
ListBufferSize, ListBufferSize_RBV longout, longin DanteListBufferSize The number of x-ray events per buffer in list mode. Once this number of events has been received the events read from the Dante stored in NDArrays, and callbacks are done to any registered plugins.

List mode events are 64-bit unsigned integers.

  • Bits 0 to 15 are the x-ray energy, i.e. ADC value.
  • Bits 16 to 17 are not used.
  • Bits 18 to 61 are the timestamp in 8 ns units.
  • Bits 62 and 63 are not used.

In list mode the x-ray events are copied into NDArrays. The data type of the NDArrays is NDUInt64, and the NDArrayDimensions are [ListBufferSize, NumBoards]. For a 1-channel Dante NumBoards is 1.

The run-time statistics for ListBufferSize events are copied into NDAttributes attached to each NDArray. The attribute names contain the board number, for example “RealTime_0”. Note that these statistics are cummulative for the entire acquisition, not just since the last time the event buffer was read. By making ListBufferSize smaller one obtains a more frequent sampling of these statistics.

These statistics also update the run-time statistics records described above, so there is feedback while the list mode acquisition is in progress.

The first NumMCAChannels events are copied to the buffer for the MCA record for each board. In this case the MCA record will not contain an x-ray spectrum, but rather will contain the x-ray energy in ADC units on the vertical axis and the event number on the horizontal axis.

The NDArrays can be used by most of the standard areaDetector plugins. For example, they can be streamed to HDF5 or TIFF files. List-mode data cannot be written to a netCDF file, because the netCDF classic format does not support 64-bit integer data types.

The following is an IDL procedure to read the List mode data from an HDF5 file into two arrays, “energy” and “time”:

pro read_dante_list_data, filename, energy, time
   data = read_nd_hdf5(filename)
   energy = uint(data and 'ffff'x)
   time = double(ishft((data and '3ffffffffffc0000'x), -18))*8e-9
end

read_nd_hdf5_ is a function that reads an HDF5 file written by the areaDetector NDFileHDF5 plugin:

function read_nd_hdf5, file, range=range, dataset=dataset
  if (n_elements(dataset) eq 0) then dataset = '/entry/data/data'
  file_id = h5f_open(file)
  dataset_id = h5d_open(file_id, dataset)
  data = h5d_read(dataset_id)
  h5d_close, dataset_id
  h5f_close, file_id
  return, data
end

The following is a plot of the energy events for the first 1 second of that data, using this IDL command:

IDL> p = plot(time, energy, xrange=[0,1], yrange=[0,20000], linestyle='none', symbol='plus')
_images/dante_idl_list_plot.png

ADC trace waveforms

The Dante can collect ADC trace waveforms, which is effectively a digital oscilloscope of the pre-amp input signal. This very useful for setting the AnalogOffset record, and for diagnosing issues with the input.

These are the records to control ADC traces. All of the records except TraceData affect all boards and are in dante.template. TraceData is specific to each board and is in danteN.template.

EPICS record names Record types drvInfo string Description
ReadTrace bo DanteReadTrace Arms the system to capture trace data on the next trigger event.
TraceTimeArray waveform DanteTraceTimeArray Waveform record containing the time values for each point in TraceData. 64-bit float data type.
TraceTime, TraceTime_RBV ao, ai DanteTraceTime Time per sample of the ADC trace data in microseconds. Allowed range is 0.016 to 0.512.
TraceLength, TraceLength_RBV longout, longin DanteTraceLength The number of samples to read in the ADC trace. This must be a multiple of 16384, and will be limited by the NELM field of the TraceData and TraceTimeArray waveform records.
TraceTriggerLevel, TraceTriggerLevel_RBV longout, longin DanteTraceTriggerLevel The trigger level in ADC units (0 to 65535).
TraceTriggerRising, TraceTriggerRising_RBV bo, bi DanteTraceTriggerRising Trigger the ADC trace as it rises through TraceTriggerLevel. Choices are “No” (0) and “Yes” (1).
TraceTriggerFalling, TraceTriggerFalling_RBV bo, bi DanteTraceTriggerFalling Trigger the ADC trace as it fals through TraceTriggerLevel. Choices are “No” (0) and “Yes” (1).
TraceTriggerInstant, TraceTriggerInstant_RBV bo, bi DanteTraceTriggerInstant Trigger the ADC trace even if a rising or falling trigger is not detected. Choices are “No” (0) and “Yes” (1).
TraceTriggerWait, TraceTriggerWait_RBV ao, ai DanteTraceTriggerWait The delay time after the trigger condition is satisfied before beginning the ADC trace.
TraceData waveform DanteTraceData Waveform record containing the ADC trace data. 32-bit integer data type.

The following are the MEDM screen danteTrace.adl displaying two ADC traces. These were done with a Vortex SDD detctor and a Cd109 source, which produces Ag K x-rays. The traces were captured with TraceTriggerRising=Yes and TraceTriggerLevel=50000. The first trace was done with TraceTime=0.512 microseconds, so the total time is 8192 microseconds. 2 resets are visible on this trace. The second trace was done with TraceTime=0.016 microseconds, so the total time is 256 microseconds. The individual 22 keV Ag x-ray steps can be seen in this trace.

_images/dante_trace1.png
_images/dante_trace2.png

The following is the MEDM screen dante8Trace.adl. This screen is used with the Dante8.

_images/dante8Trace.png

IOC startup script

The command to configure a Dante in the startup script is:

DanteConfig(portName, ipAddress, totalBoards, maxMemory)

portName is the name for the Dante port driver

ipAddress is the IP address of the Dante

totalBoards is the total number of boards in the Dante system, including those that may be disabled.

maxMemory is the maximum amount of memory the NDArrayPool is allowed to allocate. 0 means unlimited.

Performance

Dante8 free-running mapping mode

The following table shows the maximum number of pixels/s for MCA mapping mode as a function of the number of boards enabled and the number of MCA channels on the Dante8. The tests were done under the following conditions:

  • MappingPoints = 2000
  • PollTime = 0.01
  • ArrayCallbacks = Enable
  • WaitForPlugins = Yes
  • TriggerMode = FreeRunning

The PresetReal time was decreased in 1 ms steps until the mapping mode acquisition no longer collected the requested number of pixels.

The PresetReal time on the Dante is limited to multiples of 1 ms, so the pixel rate in FreeRun mode is limited to 1000, 500, 333, 250, etc.

Maximum pixel rate in Hz (spectra/board/second) for TriggerMode=FreeRunning
MCA Channels 1 board enabled 2 boards enabled 4 boards enabled 8 boards enabled
1024 1000 1000 1000 500
2048 1000 1000 500 333
4096 1000 1000 1000 1000

Dante8 externally triggered mapping mode

The following table shows the maximum number of pixels/s for MCA mapping mode as a function of the number of boards enabled and the number of MCA channels on the Dante8. The tests were done under the following conditions:

  • MappingPoints = 2000
  • PollTime = 0.01
  • ArrayCallbacks = Enable
  • WaitForPlugins = Yes
  • TriggerMode = Trig Rising
  • PresetReal = 0.1 (does not matter)

The Dante8 was triggered by an external programmable pulse generator. The pulse width was 10 microseconds. The pulse generator was programmed to output 2000 pulses.

The pulse frequency was increased until the mapping mode acquisition no longer collected the requested number of pixels.

Maximum pixel rate in Hz (spectra/board/second) for TriggerMode=Trig Rising
MCA Channels 1 board enabled 2 boards enabled 4 boards enabled 8 boards enabled
1024 6200 2300 900 350
2048 1500 750 340 150
4096 8060 8060 8060 8060

The same results as above were obtained for TriggerMode=Gate High.

In 4096 channel mode all spectra are eventually collected for trigger frequencies up to 8000 Hz. However, in 2048 and 1024 channel mode the maximum trigger frequency is much less before spectra are lost, and the EPICS IOC needs to be restarted.