Handel Programmer’s Guide - FalconXn


Intended Audience

This document is intended for those users who would like to interface to the XIA FalconXn hardware using the Handel driver library. Users of the Handel driver library should be reasonably familiar with the C programming language and this document assumes the same.

This document assumes you have a FalconX1, FalconX4, or FalconX8 set up and configured on your local network. For information on setting up your hardware and configuring it with ProSpect, please reference FalconX1/X4/X8 Quick Start Guide.


Each Handel API that is discussed is linked to the Handel API Manual. Follow the link to view the function prototype and documentation of the API’s use.

CHECK_ERROR is a placeholder for user-defined error handling.

Sample Code

This guide includes inline code examples to illustrate how specific features are used. In addition to the inline code examples, sample applications are included with the Handel source distribution. Precompiled versions of the applications (for Windows) are also included.

Each application requires a file called falconxn.ini be present in the same directory as the application. A sample file is included in the distribution.


This application walks through all of the steps required to acquire a single MCA histogram with 5 seconds worth of data. This is the simplest example and shows how to use basic Handel from start to finish.

Understanding Handel

Header Files

Before introducing the details of programming with the Handel API, it is important to discuss the relevant header files and other external details related to Handel. All code intending to call a routine in Handel needs to include the file inc/handel.h as a header. To gain access to the constants used to define the various logging levels, the file inc/md_generic.h must be included; additional constants (preset run types, mapping mode controls, etc.) are located in inc/handel_constants.h. The last header that should be included is inc/handel_errors.h, which contains all of the error codes returned by Handel.

Error Handling

A good programming practice with Handel is to compare the returned status value with XIA_SUCCESS – defined in handel_errors.h – and then process any returned errors before proceeding. All Handel routines (except for some of the debugging routines) return an integer value indicating success or failure. While not discussed in great detail in this document, Handel does provide a comprehensive logging and error reporting mechanism that allows an error to be traced back to a specific line of code in Handel.

Thread Safety

Handel uses background threads to serialize IO processing, but the APIs are not thread-safe. It is the responsibility of any application making Handel calls to ensure that only one thread is allowed to access Handel at a time.

INI Files

The last required file external to the Handel source code is an initialization, or “.ini” file. The .ini file defines the setup of your system by breaking the configuration down into the following categories: detector, firmware, hardware, and acquisition values.

XIA’s general recommendation is to use ProSpect to optimize your system and save an .ini file for use in your application. However, by referring to an existing Handel .ini file and the specifications in the reference section INI Format, you can also edit .ini files by hand or generate them in your application.

XIA provides sample .ini files in the ProSpect SDK folder. We plan to support automatically generating .ini files with a Configuration Wizard in a future version.


Most routines in Handel accept a detChan integer as the first argument. As discussed in [module definitions], channel{n}_alias, each channel in the system must be assigned a unique ID. Handel .ini files generated by ProSpect follow the convention of assigning 0 to the first channel in the first module and N - 1, where N is the total number of channels in the system, to the last channel in the last module. If you know the number of channels in the system, you can treat the detChan parameter as a 0-based index. For more information on robustly querying the system, see Enumerating Modules and Channels in the Handel API Manual.

Some routines in Handel – mostly routines that set a value – allow the special detChan -1 to be passed as an argument. This special value represents all of the detChans in the system. When calling routines like xiaSetAcquisitionValues() the -1 detChan is a convenient shortcut that eliminates the need to loop over all channels.

Other tasks, such as run control and reading module statistics, only need to be called on one channel per module. In these cases enumerating the modules is an appropriate technique.

The following table lists various acquisition tasks and indicates how each may be addressed.

Task Per channel Per module System (detChan -1)
xiaSetAcquisitionValues, all values X X X
xiaDoSpecialRun adc_trace X
xiaStartRun/xiaStopRun X X
xiaGetRunData mca X
xiaGetRunData module_statistics_21 X X
xiaBoardOperation, all mapping-related operations X
xiaGetRunData, all mapping-related data X

MCA Data Acquisition

Setting up Logging

Handel provides a comprehensive logging and error reporting mechanism that allows an error to be traced back to a specific line of code in Handel. To utilize the logging system, a log file needs to be designated, preferably at the beginning of the application:


See xiaSetLogLevel() and xiaSetLogOutput().

Initializing Handel

Before acquiring data with Handel it is necessary to initialize the library using an .ini file.

This section of the guide assumes you have set up your instrument and configured it with ProSpect. If you have not done this, you may follow the information in FalconX1/X4/X8 Quick Start Guide. Be sure to characterize the signal in the Pulse Characterization tab and verify the spectrum before continuing. Once you have configured the instrument, save the .ini file in ProSpect and copy it to the example working directory. See INI Files for details on the .ini file format. 2

Once you have an .ini file, you can use it to initialize Handel with xiaInit().


Once the initialization is complete, the next step is to call xiaStartSystem(). This is the first time that Handel attempts to communicate with the hardware specified in the .ini file. xiaInit()’s job is to prepare Handel for data acquisition, while xiaStartSystem()’s is to prepare the hardware.


Once xiaStartSystem() returns with the success status, Handel is ready to perform data acquisition tasks. xiaStartSystem() only needs to be called once after an .ini file is loaded.

Configuring Data Acquisition

After xiaStartSystem() has run, the FalconXn system is ready to be configured for data acquisition. If the .ini file that was loaded with xiaInit() contains a [default definitions] section, then the hardware will be configured using those values. If the default definitions section is missing, then Handel uses a nominal set of default values. Default settings are sufficient for many acquisition values, but most systems will require optimization of at least the analog settings to obtain a good spectrum.

Handel provides a comprehensive set of acquisition values for controlling the settings the FalconXn. See the Acquisition Values section for the complete list.

Most MCA data acquisition setups will only need to set the handful of values described below. Once a working set of acquisition values has been created, they can be saved to an .ini file using the function xiaSaveSystem().

The Handel routines to control acquisition values are xiaSetAcquisitionValues() and xiaGetAcquisitionValues().

The basic setup of a FalconXn system involves optimizing the following acquisition values for your system.

double detection_threshold = 0.010;
CHECK_ERROR(xiaSetAcquisitionValues(0, "detection_threshold", &detection_threshold));

double min_pulse_pair_separation = 25.0;
CHECK_ERROR(xiaSetAcquisitionValues(0, "min_pulse_pair_separation",

double detection_filter = XIA_FILTER_MID_RATE;
CHECK_ERROR(xiaSetAcquisitionValues(0, "detection_filter", &detection_filter));

double scale_factor = 2.0;
CHECK_ERROR(xiaSetAcquisitionValues(0, "scale_factor", &scale_factor));


Handel for FalconXn does not require the “apply” step you may be used to with other XIA products. Acquisition values are applied immediately. However, you may call the apply operation to check internal consistency of parameters on the board.


To support coordinating MCA data collection with other systems, events are collected only when the GATE input is high or low, depending on polarity. With no GATE input connected and the default settings input_logic_polarity=XIA_GATE_ACTIVE_HI and gate_ignore=1, data is collected continuously. If you have a GATE input connected but wish to veto data collection, set gate_ignore=0.

The following example configures the system to collect events only when the GATE is high.

#include "handel_constants.h"

double input_logic_polarity = XIA_GATE_COLLECT_HI;
double gate_ignore = 0.0;
CHECK_ERROR(xiaSetAcquisitionValues(-1, "input_logic_polarity", &input_logic_polarity));
CHECK_ERROR(xiaSetAcquisitionValues(-1, "gate_ignore", &gate_ignore));

Run Control

At this point, the hardware is properly configured and ready to acquire data. In this section we are interested in starting and stopping a normal MCA run and reading out the spectrum data. The routines xiaStartRun() and xiaStopRun() control the run. The run only needs to be started and stopped once per module on the FalconXn.

The MCA can be read either while the run is active or after it has been stopped. The MCA histogram is returned as an array of uint32_t integers via a call to xiaGetRunData()3.

xiaGetRunData() expects an array equal to (or larger) than the requested MCA length. The MCA length is set using the “number_mca_channels” acquisition value and can be read as an unsigned long by passing the name “mca_length” to xiaGetRunData() or as a double from xiaGetAcquisitionValues(). With this in mind, a simple data acquisition session has the following basic footprint:

#include <stdlib.h>

uint32_t *mca = NULL;

unsigned long mca_length = 0;

CHECK_ERROR(xiaGetRunData(0, "mca_length", &mca_length));

mca = malloc(mca_length * sizeof(uint32_t));

if (!mca) {
  /* Unable to allocate enough memory. */

CHECK_ERROR(xiaStartRun(-1, 0));
/* Collect as much data as you want. */

CHECK_ERROR(xiaGetRunData(0, "mca", mca));
/* Do something with the MCA histogram. */


Preset Runs

A common data acquisition technique is to do a “preset” run with a fixed metric of either time or events. A normal MCA run is both started and stopped by the host software; a preset MCA run is started by the host and stopped by the hardware. Allowing the hardware to end the run lets the host application repeatedly acquire data with similar characteristics.

The FalconXn supports three distinct preset run types: realtime, events and triggers. The constants used to define these run types are in handel_constants.h. The realtime (XIA_PRESET_FIXED_REAL) preset run instructs the hardware to run until the specified realtime has elapsed. This time is specified in seconds.

The output events (XIA_PRESET_FIXED_EVENTS) and input events (XIA_PRESET_FIXED_TRIGGERS) preset runs complete when the specified number of input or output events have been collected.

double preset_realtime = 20.0;
double preset_type = XIA_PRESET_FIXED_REAL;

int ignored = 0;
int n_channels_done;

unsigned long run_active;

CHECK_ERROR(xiaSetAcquisitionValues(-1, "preset_type", &preset_type));
CHECK_ERROR(xiaSetAcquisitionValues(-1, "preset_value", &preset_realtime));

CHECK_ERROR(xiaStartRun(-1, 0));

do {
    int i;

    n_channels_done = 0;
    for (i = 0; i < TOTAL_CHANNELS_IN_SYSTEM; i++) {
        CHECK_ERROR(xiaGetRunData(i, "run_active", &run_active));
        if ((run_active & 0x1) == 0) {

} while (n_channels_done != TOTAL_CHANNELS_IN_SYSTEM);


/* Read out data here. */

SCA Settings

The number of SCA regions for a given channel can be set via the acquisition value number_of_scas, after which limits for each region can be set with acquisition values in the format “sca{n}_[lo|hi]”, e.g. sca0_lo, sca0_hi, sca1_lo, sca1_hi. The maximum number of regions per channel varies with the hardware channel count and should be checked by reading the run data max_sca_length.

SCA counters are output via the FalconXn’s digital output lines. Cumulative hardware counters cannot be read out via Handel, but run data “sca” is implemented for compatibility with programs that use this API with other products. In the case of the FalconXn, the run data simply returns the counters by summing the bins from the current run’s MCA readout. There is no IO performance benefit to be gained by reading only the SCA data in place of the full MCA; the full spectrum is transferred over the network at regular intervals regardless of whether MCA is accessed in user programs.

See FalconX1/X4/X8 Quick Start Guide for information on the digital lines and configuring SCA regions in ProSpect.

The following sample demonstrates configuring the SCAs. This code should be executed along with other data acquisition configuration, after starting the system and before starting the run.

unsigned short maxsize;
double nSCAs = 2.0;
char scaStr[80];

double scaLowLimits[]  = {0.0, 1024.0};
double scaHighLimits[] = {1023.0, 2047.0};

double SCAs[2];

/* Check the maximum number of SCAs. */
status = xiaGetRunData(0, "max_sca_length", &maxsize);

ASSERT(nSCAs <= (double)maxsize);

/* Set the number of SCAs. */
printf("-- Set SCAs\n");
status = xiaSetAcquisitionValues(-1, "number_of_scas", (void *)&nSCAs);

/* Set the individual SCA limits. */
for (i = 0; i < (int)nSCAs; i++) {
    sprintf(scaStr, "sca%d_lo", i);
    status = xiaSetAcquisitionValues(-1, scaStr, (void *)&(scaLowLimits[i]));

    sprintf(scaStr, "sca%d_hi", i);
    status = xiaSetAcquisitionValues(-1, scaStr, (void *)&(scaHighLimits[i]));

/* Read out the SCAs during or after a run as follows.
 * If you change the number of SCAs dynamically, check run
 * data "sca_length" and reallocate SCAs accordingly.
status = xiaGetRunData(0, "sca", SCAs);

for (int i = 0; i < (int)nSCAs; i++) {
    printf(" SCA%d = %0.0f\n", i, SCAs[i]);


The last operation that any Handel application must do is call xiaExit() to release all hardware and OS resources used by the library.

printf("Cleaning up Handel.\n");

Once xiaExit() is called a new system must be loaded with xiaInit() if you want to use Handel again.

Mapping Mode

The FalconXn supports high-speed mapping operations. The current packaged release can store full spectra for each mapping pixel (MCA mode). The hardware also supports time-stamped events (List-mode); this will be supported in Handel in a later version. In general, the controls are the same for each mapping mode variant though different strategies may be required for performance reasons.

The FalconXn hardware streams mapping data to the host computer continuously. Handel controls data readout to the client application via an a/b buffering system consistent with the APIs used to control the XMAP. The system allows for continuous mapping data acquisition by organizing memory into two independent banks called buffer ‘a’ and buffer ‘b’. A single buffer can be read out by the client while the other is filled during data acquisition. Each buffer consists of a series of 16-bit header words followed by 32-bit spectra or list mode events (see FalconXn Mapping Buffer Specification for details). Handel limits the buffers to 1024 pixels per buffer and 2^32 pixels per run.

For continuous mapping, the host computer must be able to read out and clear an entire buffer for all of the modules in the system in less time then it takes to fill one buffer. The minimum pixel dwell time for continuous mapping operation is defined by the readout speed, the buffer clear time, the number of pixels that can be stored in one buffer and the size of the system. XIA targets a minimum pixel dwell time around 1 ms / pixel; some tuning of the system parameters and a dedicated network is required to achieve this performance.

Pixel Advance Modes

The FalconXn supports GATE pixel advance and host control.


The primary method for advancing the pixel is to use the GATE input as a pixel clock, where the pixel number advances on a defined edge transition of the input signal. The default setting is to use the high-to-low transition to trigger the pixel advance. “input_logic_polarity” can be set to 1.0 if the low-to-high transition is desired instead. Since the GATE signal requires transitions from high-to-low (or low-to-high), there is necessarily a transition time between states where data acquisition is inhibited. The default setting, controlled with the “gate_ignore” acquisition value, is to ignore the data during the transition period. However if “gate_ignore” is set to 1.0, data acquisition will remain active during the transition.

Host Control

It is possible to advance the pixel directly in Handel using the board operation “mapping_pixel_next”. Manually advancing the pixel is slower and does not provide good real-time control and, as such, is suitable only for debugging and evaluation purposes.

Using Mapping Mode: A Walkthrough

Mapping mode and detChans

Mapping operations such as pixel advance, buffer monitoring, and buffer readout must be performed on each channel in the system. This is a departure from the model of other XIA products such as XMAP, in which many such tasks operate at a module level and only require calls for one channel per module.

Acquisition values may always be applied to the entire system, so the walkthrough that follows passes detChan=-1 to those calls.

Where detChan=0 is passed, a production application should loop over all the modules and channels and perform the operation for each channel. See Enumerating Modules and Channels for code examples demonstrating how to identify the detChans to pass to the calls.

Enable mapping mode

Setting the acquisition value “mapping_mode” while data acquisition is stopped switches the system between the various modes. Handel for FalconXn supports MCA mapping mode (1.0). To switch back to normal MCA data acquisition, set “mapping_mode” to 0.0.

double mode = 1.0;
CHECK_ERROR(xiaSetAcquisitionValues(-1, "mapping_mode", &mode));

Set the number of bins in the spectrum

The number of bins in the spectrum affects the overall size of the buffer for a given number of pixels and the overall performance of the system in terms of pixels per second network throughput.

double nBins = 4096.0;
CHECK_ERROR(xiaSetAcquisitionValues(-1, "number_mca_channels", &nBins));

Set the total number of pixels to be acquired in this run

Handel limits the total number of pixels to 2^32. This value can also be set to 0.0 if data acquisition should continue indefinitely.

double nMapPixels = 100.0;
CHECK_ERROR(xiaSetAcquisitionValues(-1, "num_map_pixels", &nMapPixels));

Set the number of pixels per buffer

The number of pixels in a single buffer may be set between 1 and 1024. 4 If the number of mapping pixels per buffer is set larger then the maximum amount the buffer can hold, it will be truncated to the maximum value. Passing -1.0 or 0 instructs Handel to use the maximum size.

double nMapPixelsPerBuffer = -1.0;
CHECK_ERROR(xiaSetAcquisitionValues(-1, "num_map_pixels_per_buffer",

Configure pixel control

At the beginning of the run, the pixel number starts at 0 and is advanced using one of the techniques discussed in the section Pixel Advance Modes.


#include "handel_constants.h"

double pixelMode = XIA_MAPPING_CTL_GATE;
CHECK_ERROR(xiaSetAcquisitionValues(-1, "pixel_advance_mode", &pixelMode));


Manual pixel advance from the host is always available and does not need to be explicitly configured. To advance the pixel, use the following code:

int ignored = 0;
CHECK_ERROR(xiaBoardOperation(0, "mapping_pixel_next", &ignored));

As mentioned in the note at the beginning of this walkthrough, mapping data acquisition tasks such as pixel advance and all tasks demonstrated here passing detChan=0 need to be call once for each channel in the system.

Get the buffer length

After all of the settings are applied, Handel can be queried for the size of a returned buffer. This value can then be used to allocate the appropriate amount of memory.

unsigned long bufferLength = 0;
uint32_t *buffer = NULL;
CHECK_ERROR(xiaGetRunData(0, "buffer_len", &bufferLength));

buffer = malloc(bufferLength * sizeof(uint32_t));
if (!buffer) {
    /* Out-of-memory */

Start the run

CHECK_ERROR(xiaStartRun(-1, 0));

Monitor the buffer status

Once the run is started, pixels are added to the first buffer (‘a’) until it is full. To see if the buffer is full, use the following code:

int isFull = 0;

while (isFull == 0) {
    CHECK_ERROR(xiaGetRunData(0, "buffer_full_a", &isFull));

    /* Sleep for a short time here using a routine like Sleep() on win32
     * or usleep() on linux.

Each channel in the system should be polled to determine when all of the channels are ready to be read.

Read full buffer

/* Assumes that buffer was previously allocated. */
CHECK_ERROR(xiaGetRunData(0, "buffer_a", buffer));

Signal that the read has completed

Once a buffer is read, it is important to let Handel know that it is available to be filled again. Failure to do this in a timely manner can potentially cause overrun errors.

char currentBuffer = 'a';

CHECK_ERROR(xiaBoardOperation(0, "buffer_done", &currentBuffer));

Wait for buffer ‘b’ to fill

With buffer ‘a’ read and signaled as done, the next step is to wait for buffer ‘b’.

int isFull = 0;

while (isFull == 0) {
    CHECK_ERROR(xiaGetRunData(0, "buffer_full_b", &isFull));

    /* Sleep for a short time here using a routine like Sleep() on win32
     * or usleep() on linux.

Then signal “buffer_done” using the same board operation call as for the ‘a’ buffer.

Repeat until all the pixels are collected

Continue reading, signaling complete and polling while switching between buffers ‘a’ and ‘b’. You may monitor the for run completion by manually checking the pixel number:

unsigned long nMapPixels; /* As set above. */
unsigned long currentPixel;
CHECK_ERROR(xiaGetRunData(0, "current_pixel", &currentPixel));

if (currentPixel >= nMapPixels) {
    /* The run is complete. Break the monitoring loop and continue. */

Or simply monitor the run status as in normal MCA data acquisition:

unsigned long runActive;
CHECK_ERROR(xiaGetRunData(0, "run_active", &runActive));

if (!runActive) {
    /* The run is complete. Break the monitoring loop and continue. */

Stop the run

Once all of the pixels have been collected, the run must be stopped as usual.


Mapping Tips

This section describes (and reiterates) various tips and techniques to make sure that your mapping application runs smoothly.

  1. Enabling mapping mode updates all parameters

    When “mapping_mode” is enabled, all of the relevant acquisition values are applied to the hardware. There is no need to set these values each time you enable mapping mode. You may set them before or after actually setting “mapping_mode”.

  2. Set acquisition values for the system

    Acquisition values related to mapping mode do not vary by channel (as, for example, gain or threshold settings may), so for convenience set values such as “num_map_pixels” once using detChan -1.

  3. Perform mapping operations once per detChan

    Mapping operations during data acquisition, such as checking if a buffer is full, reading a buffer, and signaling a buffer is done, must be performed once for each detChan in the system. In the XMAP all of these operations were module-wide, but Handel for FalconXn tracks buffers at the channel level.

  4. Cache the mapping buffer length

    For all modes except for list-mode, the mapping buffer length, retrieved by passing “buffer_len” to xiaGetRunData(), only needs to be read once before the mapping run starts; it will not change once the run is active.

  5. Check for buffer overruns

    If the per-pixel dwell time is too short for the FalconXn to keep up pushing the data across the network or for the client application to read out and process the buffers, it is possible to overrun a buffer. To signal that the buffer is overrun the value of the run data “buffer_overrun” will be set to 1.0.

    XIA recommends treating the buffer overrun condition as an indication that the system requires additional tuning to run with the dwell time that caused the overrun.

Acquisition Values

This section lists the allowed names for use with xiaGetAcquisitionValues() and xiaSetAcquisitionValues().

Analog Section

Acquisition values controlling the analog front end.

Acts as as a gain multiplier on the analog front end. Range: [1,16].
Sets the offset on the analog front end. Range: [-2048, 2047].

The input signal polarity, specified as 1 for positive or 0 for negative. Setting to 0 effectively inverts the signal.

This value is a copy of the channel{n}_polarity setting in the [detector definitions] section of the INI file. On startup, the detector definition takes precedence over the acquisition value, so if you are customizing an INI file by hand, you must edit the detector definition or both values, not only the acquisition value. To modify the value in your application at runtime, however, you must set the acquisition value using xiaSetAcquisitionValues(); the value will be synced to the detector definition to preserve the change when the system is saved.


Input termination impedance. 0=1kohm, 1=50ohm. Default: 0.

Note that newer versions of FalconXn hardware don’t support 50ohm termination. The support can be verified by checking bit BOARD_SUPPORTS_TERMINATAION_50OHM returned from xiaBoardOperation() get_board_features


Input attenuation. 0=0dB, 1=-6dB, 2=ground. Default: 0.

Note that newer versions of FalconXn hardware don’t support ‘ground’ attenuation, instead the values are mapped to: 0=0dB, 1=-6dB, 2=-12dB. The support can be verified by checking bit BOARD_SUPPORTS_ATTENUATION_GROUND returned from xiaBoardOperation() get_board_features

AC or DC coupling. 0=AC, 1=DC. Default: 0.

This setting applies to AC coupling mode. Default: 0.

Digital DC offset. Range: [-1, 1]
Enables reset blanking. 1 = enabled, 0 = disabled. Default: enabled.
The threshold for reset blanking, in arbitrary units. Range: [-0.99999, 1.0]. Default: -0.05.
Number of samples before reset detection to blank. Range: [4, 125]. Default: 50.
Number of samples after reset detection to blank. Range: [4, 1000]. Default: 50.
Read-only value to get the sample rate in MHz.
Read-only value indicating adc_trace run data sample period as a multiple of the actual ADC rate. To determine the period for data returned in adc_trace, invert clock_speed and multiply by adc_trace_decimation. For example, if clock_speed=250MHz and adc_trace_decimation=2, the ADC sample period is 1 / (250 * 1,000,000) = 4ns. The adc_trace is returned in 4ns * 2 = 8ns samples.

Pulse Detection

Acquisition values controlling pulse detection.

Minimum height for a pulse to be detected. Range: [0, 0.999]. Default: 0.05.
Minimum number of samples between pulses. This setting controls the balance of throughput and resolution. Range: [0, 1023]. Default: 50.
Advanced tuning of throughput and resolution for detectors with slow or varying rise times, specified in nanoseconds. A default is chosen based on the detection filter. The value is optimized by the characterization process, so manual tuning should be applied after characterizing the signal. Increase to improve resolution, decrease to improve throughput. Range: [0 - 4000], typically in the lower end of [40 - 100] for fast SDDs. Added in Handel 1.1.18, requires SiToro 0.9.0.

detection_filter Default: XIA_FILTER_MID_RATE.

Scale factor for bin scaling and spectrum calibration. Range: [0.5, 200.0]. Default: 2.0.

MCA Data Acquisition

Acquisition values controlling MCA data acquisition.

The number of bins in the MCA spectrum, specified in bins. This applies to both MCA mode and fast mapping mode. Narrowing the range may improve network performance in fast mapping applications. Range: [128, 4096]. Default: 4096.
Whether to return the accepted spectrum in mca. The accepted spectrum is the standard MCA histogram and so must be enabled in any typical spectroscopy application.
Whether to return the rejected spectrum in mca. The rejected spectrum consists of pulses that triggered but were rejected due to the detection threshold or other pulse processing criteria. It is available for diagnostics purposes only, and, if enabled, is appended on the end of the mca buffer readout. If both the accepted and rejected spectra are enabled, the application must allocate a buffer that is twice the length of number_mca_channels.
The lowest bin number in the range of MCA bins to return. This may be used in conjunction with number_mca_channels number_mca_channels to narrow the range the range of bins and improve network performance but is not needed in typical applications. Default: 0.
MCA refresh period in seconds. This controls how often MCA updates are sent from the FalconXn to the client machine. Default: 0.1.
MCA bin width in eV/bin. This value is not used to configure the FalconXn but may serve as convenient storage for a multiplier value for scaling graphical axes in user programs.

Criteria to stop the run. Include handel_constants.h to access constants for the allowed values:

Preset run criteria specified in counts or seconds. Required when preset_type is anything other than XIA_PRESET_NONE.

SCA Data Acquisition


Include handel_constants.h to access constants for the allowed values:

Duration of the emitted SCA pulses in ns, will be rounded to multiple of 4ns. Range: [4, 262140]. Default: 400.0.
Number of SCA regions to configure for the channel. The upper limit varies by hardware setup. Read the run data max_sca_length for the maximum number of SCA regions supported per channel.
SCA limits are defined by pairs of acquisition values with names of the format sca{n}_[lo|hi], where n refers to the 0-indexed SCA number. For example: sca0_lo, sca0_hi, sca1_lo, and sca1_hi.

Mapping Mode


Toggles between the various mapping modes. Supported values are as follows:

Total number of pixels to acquire in the next mapping mode run. If set to 0.0, then the mapping run will continue indefinitely.
The number of pixels stored in each buffer during a mapping mode run. If the value specified is larger then the maximum number of pixels the buffer can hold, it will be rounded down to the maximum. Setting this to -1.0 or 0.0 will automatically set the value to the maximum allowed per buffer.

Sets the pixel advance mode for mapping mode. The supported types are listed in handel_constants.h. Manual pixel advance using xiaBoardOperation() is always available; use XIA_MAPPING_CTL_USER is the default and can be used to explicitly disable GATE processing on the FalconXn.


When running in mapping mode and pixel_advance_mode is set to use the GATE signal, this acquisition value determines which logic transition stops data acquisition and clears the spectrum for the next pixel.

In MCA mode, this setting determines the polarity of the GATE veto with the same collect high or collect low semantics.

Determines if data acquisition should continue or be halted during pixel advance while GATE is asserted. Set to 1.0 to keep data acquisition active during the transition or 0.0 to halt acquisition while the GATE is asserted. Default: 1.0 (continuous data collection). In MCA mode, set to 1.0 to disable GATE veto and enable continuous data collection or 0.0 to use the GATE signal to veto data collection.
Sets the number of SYNC pulses to use for each pixel. Once “sync_count” pulses have been detected, the pixel is advanced.

Run Data

This section lists the allowed names for use with xiaGetRunData().

The italicized type that follows each name is the type of the argument passed into the value parameter of xiaGetRunData(). For scalar values, you will need to pass a pointer to the specified type. For array values, a pointer is specified and the address of the first element should be passed. See xiaGetRunData() for usage examples.


run_active (unsigned long)
The current run status for the specified channel. If the value is non-zero then a run is currently active on the channel.

MCA Data

mca_length (unsigned long)
The current size of the MCA data buffer for the specified channel.
mca (uint32_t *)
The MCA data array for the specified channel. The caller is expected to allocate an array of length mca_length and pass that in as the value parameter when retrieving the MCA data.
module_statistics_2 (double *)

Returns an array containing statistics for the module. The caller is responsible for allocating enough memory for at least 9*n elements (where n is the number of channels in the module) and passing it in as the value parameter. The returned data is stored in the array as follows:

  1. channel 0 realtime
  2. channel 0 trigger livetime
  3. reserved
  4. channel 0 triggers
  5. channel 0 MCA events
  6. channel 0 input count rate
  7. channel 0 output count rate
  8. reserved
  9. reserved

[repeat for channels 1-7]

SCA Data

max_sca_length (unsigned short)

The maximum number of SCA elements supported by the system per channel. Twenty-four digital output lines are divided among channels according to the size of the module in available channels, which is the module size you purchased, or, if changed via the FalconX web interface Config tab, the number set there. Board operation get_channel_count reports the available channels.

Available channels Max SCAs per channel
1 24
2-4 6
5-8 3

Devices with earlier firmware releases (SiToro 0.8.3) configured only 16 digital outputs while incorrectly reporting a max_sca_length as though 24 total outputs were available. With such devices the application may work around the incorrect max by self-limiting the max SCAs per channel to 16/n. This limitation is corrected in SiToro 0.8.4 and later; if only up-to-date devices are used, the application should simply check max_sca_length.

sca_length (unsigned short)
The number of elements in the SCA data buffer.
sca (double *)
The SCA data buffer. The caller is expected to allocate an array of length “sca_length” and pass that in as the value parameter when retrieving the SCA data. The FalconX only outputs SCA pulses on the digital output lines and does not support readout from the electronics. Therefore this SCA data is emulated by summing MCA bins.

Mapping Mode

Note to customers porting XMAP or Mercury code: The FalconXn driver promotes the type of the boolean mapping mode run data values such as buffer_full_a from unsigned short to int. To support both Handel versions with the same client code, XIA recommends using int for the flags and checking whether the value is greater than zero, rather than checking a literal value.

buffer_len (unsigned long)
The size of a mapping buffer. For a given mapping run, this value will remain constant and, therefore, only needs to read once at the start of the run.
buffer_full_a (int)
The current status of buffer ‘a’. If the value is non-zero then the buffer is full.
buffer_full_b (int)
The current status of buffer ‘b’. If the value is non-zero then the buffer is full.
buffer_a (uint32_t *)
The data in buffer ‘a’. The caller is expected to allocate an array of length “buffer_len” and pass that in as the value parameter when retrieving the buffer data.
buffer_b (uint32_t *)
The data in buffer ‘b’. The caller is expected to allocate an array of length “buffer_len” and pass that in as the value parameter when retrieving the buffer data.
current_pixel (unsigned long)
The current pixel number. The number is reset to 0 at the start of each new mapping run.
buffer_overrun (int)
If non-zero, indicates the the current buffer has overflowed.

Special Runs

This section lists the allowed names for use with xiaDoSpecialRun(). Data types are specified as in Run Data. See xiaDoSpecialRun() for usage examples.

adc_trace (double)

Configures an ADC trace. The argument info is the number of samples to collect. The allowed range of values is 0 - FALCONXN_MAX_ADC_SAMPLES. If an out-of-range value is provided, it is coerced into the allowed range, so users should check it after xiaDoSpecialRun() returns successfully. To size the array passed to xiaGetSpecialRunData(), use the value returned in info or get the run data adc_trace_length.

The trace is triggered and read to the host when xiaGetSpecialRunData() is called.

Special Run Data

This section lists the allowed names for use with xiaGetSpecialRunData(). Data types are specified as in Run Data. See xiaGetSpecialRunData() for usage examples.

adc_trace (unsigned int *)
Reads out an array of ADC trace samples. The caller is responsible to allocate an array as long as the length value passed back from xiaDoSpecialRun() (or by subsequently reading run data adc_trace_length).
adc_trace_length (unsigned long)
Gets the length set by the last call to xiaDoSpecialRun(), for use in sizing the array passed to get special run data adc_trace.

Board Operations

This section lists the allowed names for use with xiaBoardOperation(). Data types are specified as in Run Data. See xiaBoardOperation() for usage examples.

Settings and Capabilities

apply (none)5
Acquisition values are applied immediately by xiaSetAcquisitionValues(). The apply operation may be called as a debugging step to check internal consistency of the parameters on the board.
get_connected (int)
Pings the FalconXn and returns greater than zero if it is connected. This is provided for diagnostics purposes but may not be needed in typical applications, as the other Handel APIs will return errors if the connection has been lost.
get_channel_count (int)
Returns the number of channels supported by the connected FalconXn. This is provided for diagnostics purposes only. number_of_channels as specified in the Handel .ini file is the official number of channels initialized for use in the APIs.
get_serial_number (char *)
Returns the serial number as a string. The caller is responsible for allocating value of length at least 32.
get_firmware_version (char *)
Returns the firmware version as a string. The caller is responsible for allocating value of length at least 32.
get_board_features (unsigned long)

Returns an unsigned long value storing a list of supported features, represented by bitmasks defined in handel_constants.h.

Mapping Mode

buffer_done (char)
Signal that the specified buffer (‘a’ or ‘b’) has been read and may be used for mapping acquisition again.
mapping_pixel_next (none)
Advance to the next pixel in a mapping data acquisition run. This is generally used only for evaluation and debugging purposes, as production applications should rely on the GATE signal for pixel advance.

INI Format

Each category in the .ini file contains a series of blocks, surrounded by a set of START / END delimiters. Each block represents one instance of the logical type associated with the category. For instance, each block in [detector definitions] represents a physical detector with some number of elements. Within each block is a series of key-value pairs used to define the configuration.

[detector definitions]

Each block in this section is used to define one physical detector made up of 1..N channels.

Human-readable string naming this detector. Other sections, such as [module definitions], that need to reference the detector will do so using this string.
An integer describing the number of elements in your detector. If this value is set to N, the strings {alias}:{0} through {alias}:{N - 1} will be available to map detector elements to hardware channels in the [module definitions] section.
The detector type. This field remains in the format for backward compatibility but is not used for the FalconXn. Supported values are the strings reset and rc_feedback.
For reset detectors, a double defining the reset delay time of the preamplifier(s) in microseconds. For rc_feedback detectors, a double defining the RC decay constant in microseconds.
The preamplifier gain, as a double, for detector element n specified in mV/keV.
A string defining the polarity of detector element n. Allowed values are “+” or “pos” for a preamplifier whose pulses are positive and “-” or “neg” for one with negative pulses.

[firmware definitions]

This section is not used for the FalconXn. An earlier version of Handel defined each block in this section as a reference to a single .bin file, a text file containing pulse characterization information used to optimize spectroscopic performance for a particular detector and configuration. As of v1.1.17 this information is now upgraded in place and saved in the .ini file itself.


FalconXn differs from other XIA products and their use of this configuration section in that it does not require firmware to be loaded during system startup (firmware resides on the card).

Human-readable string naming this characterization file. Other sections, such as [module definitions], that need to reference the detector will do so using this string.
Path to the .bin file. The path must be an absolute path or relative to the process working directory.6

[default definitions]

All of the acquisition values7 for each channel are stored in this section. Handel auto-generates this section and the user is not expected to modify it.

[module definitions]

Each FalconXn module in a system gets a separate block in this section. The blocks map each FalconXn channel to firmware, acquisition values, and a detector channel, and specify the hardware configuration for each module.

Human-readable string naming this module.
Always set to falconxn.
Set to 1-8, depending on the number of channels supported by your FalconXn and how many of them you would like to use.
Always set to inet.
TCP address of the FalconXn.
TCP port of the data acquisition server on FalconXn. Typically set to 8756.
TCP timeout in milliseconds. 100 milliseconds should suffice on a fast network, which is desirable for reliable data acquisition, but if timeout errors are returned from Handel APIs you can increase this number.
Specifies a global, unique index for channel n, where n is 0 .. N-1. This could be This value is referenced throughout Handel as the detChan.
Associates channel n, where n is 0 .. N-1, with a specific detector element. The detector element is referenced as {alias}:{m} where alias is a valid detector alias and m is a valid channel for alias.
Assigns a .bin file to module channel n, where n is 0..N-1. The .bin file is specified as a firmware alias.


Copyright 2005-2016 XIA LLC

All rights reserved

All trademarks and brands are property of their respective owners.



Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:



Redistribution and use in source (Markdown) and ‘compiled’ forms (HTML, PDF, LaTeX and so forth) with or without modification, are permitted provided that the following conditions are met:



Information furnished by XIA LLC is believed to be accurate and reliable. However, XIA assumes no responsibility for its use, nor any infringements of patents or other rights of third parties, which may result from its use. No license is granted by implication or otherwise under any patent or patent rights of XIA. XIA reserves the right to change specifications at any time without notice. Patents have been applied for to cover various aspects of the design of the DXP Digital X-ray Processor.


Patent Notice

  1. module_statistics_2 may successfully be retrieved for each channel, but each call returns the statistics for the whole module.

  2. An earlier version of Handel saved pulse characterization data in a separate .bin file per channel specified in a firmware definition in addition to the .ini file. The information in the .bin files is now saved in the .ini file itself. Existing .ini files are upgraded in place during initialization. Corresponding .bin files may be discarded after saving the system.

  3. See the Run Data section for a complete list of FalconXn run data names and data types.

  4. The maximum, which is limited in the XMAP by hardware memory, is an arbitrary software-imposed constraint for FalconXn, limited only by host process memory, the spectrum size, and the number of channels in the system. 1024 provides a safe general limit in practice, requiring up to approximately 32 MB host memory per channel for full 4096 bin spectra (ignoring buffer and pixel headers: 1024 pixels * 4096 bins * 4 bytes * 2 buffers = 33,554,432 bytes).

  5. The italicized type that follows the name is the type of the argument passed as the value parameter to xiaBoardOperation(). The special type “none” indicates that the board operation does not require nor return any data via value. A non-null pointer of any type should be passed in; its value will be ignored.

  6. We plan to encode support paths relative to the INI file in a future release.

  7. The original name for acquisition values was “defaults”.