Handel supports (since v0.3.3) the ability to set and acquire Single-Channel Analyzer (SCA) data from supported XIA hardware. The aim of the document is to show how to use these new features in Handel. Note that Regions Of Interest (ROIs) are equivalent to the SCA regions discussed below.

Supported Hardware and Firmware

As of this writing, only the xMap, Mercury, Saturn, and certain versions of microDxp hardware support SCA operations. The standard firmware version supports the definition of up to 16 SCA regions. In the standard firmware, the number of events in each SCA is determined at the end of the run and a stored in a special SCA data buffer. In addition, several special timing versions of the DXP DSP code support SCA processing; in all cases, the SCA limits are defined in the same manner (described below). The output data produced by the timing versions are defined in a separate document.

Setting the SCAs

The first step is to define the number of SCAs for each channel using xiaSetAcquisitionValues():


1:
2:
3:
4:
5:
6:
7:
8:
int status;
double nSCAs = 4.0;

status = xiaSetAcquisitionValues(0, "number_of_scas", (void *)&nSCAs);

if (status != XIA_SUCCESS) {
       /* Error */
}

The previous example sets the number of SCAs for detChan 0 to “4”. If you are running a multichannel system, e.g. xMap, and you would like to use the same number of SCAs for each channel you may reduce the number of calls to Handel by substituting the following code:


status = xiaSetAcquisitionValues(-1, "number_of_scas", (void *)&nSCA);

The “-1” indicates that Handel will set the number of SCAs on all channels to “nSCA”.

Once the number of SCAs has been set you may proceed to set the limits for each SCA:

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
int status;

double scaLo = 500.0;
double scaHi = 700.0

status = xiaSetAcquisitionValues(0, "sca0_lo", (void *)&scaLo);

if (status != XIA_SUCCESS) {
       /* Error */
}

status = xiaSetAcquisitionValues(0, "sca0_hi", (void *)&scaHi);

if (status != XIA_SUCCESS) {
       /* Error */
}

As with the number of SCAs, if each channel is going to be using the same limits a detChan of “-1” should be used. The individual SCA limits are set using xiaSetAcquisitionValues() with the name parameter set to “sca[n]_[lo|hi]”, where n is the SCA to set the limit for (starting from 0) and lo/hi indicates if the low or high limit is being set. For example, to set the lower limit for SCA 3, the string “sca3_lo” should be passed to xiaSetAcquisitionValues(). See Notes for some suggestions on how to reduce the number of calls to xiaSetAcquisitionValues() when setting the limits on SCAs.

Reading the SCA Buffer

Once all of the SCA limits are defined, the next step is to acquire some data and read out the SCAs. In the standard firmware, the SCA totals are stored in the SCA data buffer as two 16-bit words per SCA. Handel provides the routine xiaGetRunData() to read out the SCA buffer. xiaGetRunData() takes 3 arguments: the detChan, the name of the data type to read out and the data buffer to read the data into. The data buffer needs to have its memory allocated prior to calling xiaGetRunData(). However, if the number of SCAs is known at compile time it is sufficient to declare the SCA data buffer as a fixed-size array (see Complete Example for an example of this technique).

Complete Example

The following is a sample program that illustrates how to set the SCAs for a system with a Saturn module and how to read out the SCAs after a short run:


1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
int status;
unsigned short i;
double nSCAs = 2.0;

double scaLowLimits[]  = {10.0, 500.0};
double scaHighLimits[] = {20.0, 700.0};

unsigned long SCAs[2];
char scaStr[80];

/* Do initial system configuration and startup */

/* Configure SCAs */
status = xiaSetAcquisitionValues(0, "number_of_scas", (void *)&nSCAs);

if (status != XIA_SUCCESS) {
       /* Error */
}

for (i = 0; i < (unsigned short)nSCAs; i++) {
    sprintf(scaStr, "sca%u_lo", i);
    status = xiaSetAcquisitionValues(0, scaStr, (void *)&(scaLowLimits[i]));
    if (status != XIA_SUCCESS) {
              /* Error */
    }

     sprintf(scaStr, "sca%u_hi", i);
      status = xiaSetAcquisitionValues(0, scaStr, (void *)&(scaHighLimits[i]));
      if (status != XIA_SUCCESS) {
                  /* Error */
       }     
}

/* Start the run */
status = xiaStartRun(0, 0);

if (status != XIA_SUCCESS) {
       /* Error */
}

/* Wait */

/* Stop the run */
status = xiaStopRun(0);
 

if (status != XIA_SUCCESS) {
       /* Error */
}


/* Read out the SCAs */
status = xiaGetRunData(0, "sca", (void *)SCAs);

if (status != XIA_SUCCESS) {
       /* Error */
}

/* Display SCA values */
for (i = 0; i < (unsigned short)nSCAs; i++) {
       printf("SCA %u = %lu\n", i, SCAs[i]);
}

Notes

Currently, Handel does not preserve the SCA limit data when the “number_of_scas” is changed dynamically. For instance, if you create 3 SCAs and then change “number_of_scas” to 4 later in the session, the original limits on SCAs 0...2 will be lost.

Support

Please direct support requests to: support@xia.com