SciSDK Library
SDK for SciCompiler projects
Loading...
Searching...
No Matches
Time of Flight Spectrum

The time of flight spectrum is an histogram used to measure the time delay between a T0 and a trigger events. The T0 is a reference event that is used to synchronize the acquisition of the data. The trigger event is the event that is used to measure the time delay. For example the T0 can be a laser digital trigger pulse and the trigger event can be a photon detected by a PMT. The laser pulse can irragiate a biological sample and the PMT observe the photons generated by the flourescence of the sample. The time of flight spectrum is used to measure the time delay between the laser trigger and the photons arriving on the detector displaying as an histogram. In another application ToF spectrum can be used for neutron ToF Spectroscopy. In this case the T0 is for example the synchrotron kicker signal or the chopper sync pulse and the trigger event is a neutron detected by a neutron detector (ie He3 tube).

The ToF component in SciCompiler has indeed two input:

  • T0: the reference event
  • IN: the trigger event

There is a minimum delay between the T0 and the first event, this can be configured with parameter start_delay. Any events before this delay are discarded. The histrogram start after the start delay In any case, at least one clock cycle between T0 and first event must be present.

dead time: the bin width, expressed in clock cycles, is configured with parameter binwidth. A bin width of 3 clock cycles must be respected to allow the internal FPGA logic to switch between each bin.

So the time base (x bin on the histogram) is given by the formula: binwidth * clock_period * index_of_the_bin

Every time a T0 is received, the ToF resets the index_of_the_bin and accumulate counts in the specific bin of the histogram. For example, if the binwidth is set to 10 and the clock of the board is 100 MHz, each bin will last 100ns. The T0 rising edge force the bin of the ToF to go back to 0 but it will not reset the histogram. The histogram will accumulate counts in the bin 0 from T0 to 100ns than it will pass to bin 1 from 100ns to 200ns and so on.

0 ....... 100n ....... 200n ....... 300n
0 1 2
*
* *
* *
* * *

When a second T0 is received, the index_of_the_bin if forced back to 0 and the histogram is restart to integrate on bin 0. The histogram will accumulate counts in the bin 0 from T0 to 100ns than it will pass to bin 1 from 100ns to 200ns and so on.

0 ....... 100n ....... 200n ....... 300n
0 1 2
*
*
* *
* *
* * *
* * *
* * *

If the histogram has (for example) 1024 bins two thinks can happen:

  • the T0 is received before the end of the last bin, in this case the histogram index_of_the_bin is forced back to 0 and integration continue on bin 0
  • the T0 is not received before the end of the last bin, in this case the histogram integrate everithing in the last bin

An TOF spectrum has the following parameters taken from the JSON file:

  • the number of bins
  • the number of bits on the y-axis

Number of bins and number of bits define the memory occupancy of the spectrum indeed they are defined at compile time by SciCompiler.

Parameters

The following parameters can be configured:

Parameter Acces Mode Description Default value
binwidth R/W set x-axis bin size in clock cycles, minimum 3 10
start_delay R/W set the start delay. Events between T0 and start_delay will be discarded 0
bins R number of bins of the histogram
max_conts R maximum number of counts y-axes on the histogram
buffer_type R type of the buffer: (always decoded)

Bin width

The bin width is the x-axis bin size in clock cycles. The minimum bin width is 3 clock cycles. The bin width is set with the parameter binwidth. The bin width is used to calculate the time base of the histogram. The time base is calculated as follow:

binwidth * clock_period * index_of_the_bin

For example, if the binwidth is set to 10 and the clock of the board is 100 MHz, each bin will last 100ns.

Start delay

The start delay is the minimum delay between the T0 and the first event. The start delay is set with the parameter start_delay. Any events before this delay are discarded. The histrogram start after the start delay. In any case, at least one clock cycle between T0 and first event must be present. The start delay is usefull to cut-off for example prompt gamma events or to compensate a delay between the T0 and the expected time of the first event in order to do not waste bins on the hisgram.

Commands

The following commands are available:

Command Description Parameter
start start the histogram integration
stop suspend the histogram integration
reset reinitialize all bins in the histogram to 0

Resets the histogram

start and stop commands do not reset the spectrum. They should be consideder as a start and pause of the spectrum. A start command after a stop command will continue the integration from the last bin value. In order to reset the spectrum it is necessary to use the reset command. The reset command reset all the bins in the histogram to 0.

Output data Format

The ToF spectrum uses the same data structures of the energy spectrum

Decoded Data

The data output structure is the following:

typedef struct {
uint32_t magic;
uint32_t *data;
uint64_t timecode;
uint32_t inttime;
struct {
uint32_t buffer_size;
uint32_t total_bins;
uint32_t valid_bins;
} info;
Spectrum decoded data.
Definition scisdk_defines.h:238

The magic field is a 32 bit value that identify the data format. The data field is a pointer to the data buffer. The data buffer is an array of 32 bit values. The number of elements in the array is defined by the total_bins field. The valid_bins field is the number of bins that contains data. The valid_bins field is always equal to total_bins field.

timecode it's the epoch of the readout PC when the data is readout from the fpga. The timecode is expressed in milliseconds.

Data in the data array are the counts of each bin. The first element of the array is the bin with the lowest time. The last element of the array is the bin with the highest time in the spectrum. Each element of the array is a 32 bit value.

Data Format
bin 0
bin 1
bin 2
...
bin n

Status

The status of the spectrum is stored in a SCISDK_SPECTRUM_STATUS structure.

typedef struct {
bool running;
bool completed;
uint32_t progress;
uint32_t peak_max;
uint32_t total_counter;
double integration_time;
Spectrum status structure.
Definition scisdk_defines.h:254

The running field is true if the spectrum is running. The completed field is always false.

The progress field is unused.

The peak_max field is the value of the bin with the highest count.

The total_counter field is the total number of counts in the histogram.

The integration_time field is the integration time of the spectrum in milliseconds.

The current version of the library do not report the peak_max, total_counter, integration_time fields. These fields are always 0.

Basic Examples

The following example shows how to use the spectrum component.

C

int res = SCISDK_AllocateBuffer("board0:/MMCComponents/TOF_0", T_BUFFER_TYPE_DECODED, (void**)&obSpectrum, _sdk);
if (res != NI_OK) {
printf("Error allocating buffer\n");
return -1;
}
SCISDK_SetParameterString("board0:/MMCComponents/TOF_0.binwidth", "100",_sdk);
SCISDK_SetParameterString("board0:/MMCComponents/TOF_0.start_delay", "0",_sdk);
SCISDK_ExecuteCommand("board0:/MMCComponents/TOF_0.reset", "", _sdk;
SCISDK_ExecuteCommand("board0:/MMCComponents/TOF_0.start", "", _sdk);
SCISDK_ReadData("board0:/MMCComponents/TOF_0", (void *)obSpectrum, _sdk);
....
SCISDK_FreeBuffer("board0:/MMCComponents/TOF_0", 1, (void**)&obSpectrum, _sdk);
#define NI_OK
Definition NIErrorCode.h:8
SCISDK_DLL_API int SCISDK_SetParameterString(char *Path, char *value, void *handle)
Set the value of a parameter for the specific SciCompiler Memory Mapped Component or route the value ...
SCISDK_DLL_API int SCISDK_ExecuteCommand(char *Path, char *value, void *handle)
Execute a command for the specific Memory Mapped Component device driver/endpoint....
SCISDK_DLL_API int SCISDK_AllocateBuffer(char *Path, T_BUFFER_TYPE buffer_type, void **buffer, void *handle)
Allocate a buffer to be used to store data from the board for the specific Memory Mapped Componet (os...
SCISDK_DLL_API int SCISDK_FreeBuffer(char *Path, int buffer_type, void **buffer, void *handle)
Release the memory allocated by SCISDK_AllocateBuffer() or SCISDK_AllocateBufferSize()
SCISDK_DLL_API int SCISDK_ReadData(char *Path, void *buffer, void *handle)
Read data from the board for the specific Memory Mapped Componet (oscilloscope, spectrum,...
@ T_BUFFER_TYPE_DECODED
Definition scisdk_defines.h:230

C++

++
int res = sdk.AllocateBuffer("board0:/MMCComponents/TOF_0", T_BUFFER_TYPE_DECODED, (void**)&obSpectrum, _sdk);
if (res != NI_OK) {
cout << "Error allocating buffer" << endl;
return -1;
}
sdk.SetParameter("board0:/MMCComponents/TOF_0.binwidth", "100",_sdk);
sdk.SetParameter("board0:/MMCComponents/TOF_0.start_delay", "0", _sdk);
sdk.ExecuteCommand("board0:/MMCComponents/TOF_0.reset", "", _sdk;
sdk.ExecuteCommand("board0:/MMCComponents/TOF_0.start", "", _sdk);
sdk.ReadData("board0:/MMCComponents/TOF_0", (void *)obSpectrum, _sdk);
....
sdk.FreeBuffer("board0:/MMCComponents/TOF_0", 1, (void**)&obSpectrum, _sdk);

Python

res, obSpectrum = sdk.AllocateBuffer("board0:/MMCComponents/TOF_0", T_BUFFER_TYPE_DECODED)
if res != 0:
print("Error allocating buffer")
return -1
sdk.SetParameter("board0:/MMCComponents/TOF_0.binwidth", "100")
sdk.SetParameter("board0:/MMCComponents/TOF_0.start_delay", "0")
sdk.ExecuteCommand("board0:/MMCComponents/TOF_0.reset", "")
sdk.ExecuteCommand("board0:/MMCComponents/TOF_0.start", "")
res, obSpectrum = sdk.ReadData("board0:/MMCComponents/TOF_0", obSpectrum)
....
sdk.FreeBuffer("board0:/MMCComponents/TOF_0", 1, obSpectrum)

C Sharp

int res = sdk.AllocateBuffer("board0:/MMCComponents/TOF_0", T_BUFFER_TYPE_DECODED, ref obSpectrum);
if (res != 0) {
Console.WriteLine("Error allocating buffer");
return -1;
}
sdk.SetParameter("board0:/MMCComponents/TOF_0.binwidth", "100");
sdk.SetParameter("board0:/MMCComponents/TOF_0.start_delay", "0");
sdk.ExecuteCommand("board0:/MMCComponents/TOF_0.reset", "");
sdk.ExecuteCommand("board0:/MMCComponents/TOF_0.start", "");
dk.ReadData("board0:/MMCComponents/TOF_0", ref obSpectrum);
....
sdk.FreeBuffer("board0:/MMCComponents/TOF_0", 1, ref obSpectrum);

VB.NET

Dim obSpectrum As SCISDK_SPECTRUM_DECODED_BUFFER
Dim res As Integer = sdk.AllocateBuffer("board0:/MMCComponents/TOF_0", T_BUFFER_TYPE_DECODED, obSpectrum)
If res <> 0 Then
Console.WriteLine("Error allocating buffer")
Return -1
End If
sdk.SetParameter("board0:/MMCComponents/TOF_0.binwidth", "100")
sdk.SetParameter("board0:/MMCComponents/TOF_0.start_delay", "0")
sdk.ExecuteCommand("board0:/MMCComponents/TOF_0.reset", "")
sdk.ExecuteCommand("board0:/MMCComponents/TOF_0.start", "")
sdk.ReadData("board0:/MMCComponents/TOF_0", obSpectrum)
....
sdk.FreeBuffer("board0:/MMCComponents/TOF_0", 1, obSpectrum)

JAVA

res = sdk.SetParameterInteger("board0:/MMCComponents/TOF_0.binwidth", 3);
sdk.SetParameterString("board0:/MMCComponents/TOF_0.start_delay", "0");
sdk.SetParameterString("board0:/MMCComponents/TOF_0.limitmode", "freerun");
sdk.SetParameterString("board0:/MMCComponents/TOF_0.limit", "100");
sdk.ExecuteCommand("board0:/MMCComponents/TOF_0.reset", "");
sdk.ExecuteCommand("board0:/MMCComponents/TOF_0.start", "");
Ref<SpectrumDecodedBuffer> buf = new Ref<>(new SpectrumDecodedBuffer());
int res = sdk.AllocateBuffer("board0:/MMCComponents/TOF_0", buf);
if(res == 0) {
res = sdk.ReadData("board0:/MMCComponents/TOF_0", buf);
....
sdk.FreeBuffer("board0:/MMCComponents/TOF_0", buf);
}

Labview

You can find the labview file for this example here

Additional Examples

Print spectrum

This example print a spectrum every second. ```c

SCISDK_SPECTRUM_DECODED_BUFFER *obSpectrum;

int res = SCISDK_AllocateBuffer("board0:/MMCComponents/TOF_0", T_BUFFER_TYPE_DECODED, (void**)&obSpectrum, _sdk);
if (res != NI_OK) {
    printf("Error allocating buffer\n");
    return -1;
}
SCISDK_SetParameterString("board0:/MMCComponents/TOF_0.binwidth", "100",_sdk);
SCISDK_SetParameterString("board0:/MMCComponents/TOF_0.start_delay", "0", _sdk);
SCISDK_ExecuteCommand("board0:/MMCComponents/TOF_0.reset", "", _sdk;
SCISDK_ExecuteCommand("board0:/MMCComponents/TOF_0.start", "", _sdk);

while (1) {
    //Just leave in your code of of two of this sleep functions
    usleep(1000*1000);  // LINUX: sleep for 1s
    Sleep(1000);        // WINDOWS: sleep for 1s 
    int res = SCISDK_ReadData("board0:/MMCComponents/TOF_0", (void *)obSpectrum, _sdk);
    if (res == NI_OK) {
        for (int i = 0; i < obSpectrum->info.valid_bins; i++) {
            printf("[%5d] -- %9d\n", i, obSpectrum->data[i]);
        }
    }
}
SCISDK_FreeBuffer("board0:/MMCComponents/TOF_0", 1, (void**)&obSpectrum, _sdk);