Starting a measurement

The function sc_tdc_start_measure2() is used to start a measurement. After calling this function, the device switches into a measurement state. The library receives and processes data from the device in a separate thread, and transfers the results to the application through the data pipes that have been configured in advance. See Receiving Data for more info on how to operate data pipes.

Working with hardware-triggered measurements

By default, starting of a measurement comes with a certain variable delay, before the hardware actually enters the state of detecting and recording of data. This default behaviour corresponds to the ini file parameter ext_trigger being set to NO.

When the ini file parameter ext_trigger is set to YES, the hardware waits for an external trigger at the Sync In input each time the application calls the sc_tdc_start_measure2() function — so this function can be called in advance. As soon as the pulse on the Sync In input is received by the hardware, it starts the measurement with a duration as specified in the respective argument passed sc_tdc_start_measure2(). This is useful for precisely synchronizing the starts of measurements with external devices.

Caution: If no pulse occurs on the Sync In input, the hardware remains in a waiting state and does not start the measurement. From the software side, the device is already regarded as being in a measurement state, but the end of the measurement is never reached.

Working with external start pulses (for time-resolved measurements)

(This subsection applies to TDCs and DLDs but not to cameras). Hardware can be configured to work with external Start pulses by setting the ini file parameter Ext_Gpx_Start to YES. The start of the measurement is not influenced by this setting — by default, the hardware starts the measurement with a short delay after calling sc_tdc_start_measure2() and terminates the measurement after the specified exposure. However, for data to be recorded, at least one pulse has to be fed into the Start In hardware input. If no such pulse occurs, no data is recorded, such that histogram pipes return empty histograms and USER_CALLBACKS pipes do not deliver any DLD or TDC events.

Waiting for the end of a measurement

The sc_tdc_start_measure2() function starts a measurement in the background and control is immediately returned back to the user code, before the measurement finishes. There are two general options and two use-case specific options to wait for the end of a measurement.

General options:

  1. Polling the idle status

    The application developer can repeatedly call sc_tdc_get_status2() to ask whether the hardware is still in a measurement. This includes the internal PC-side processing of the scTDC library. The idle state is only reported when the library has finished processing the data stream of the hardware up to the end of the most recently started measurement.

    Between subsequent calls to sc_tdc_get_status2(), one typically uses sleep intervals so as to keep the CPU load low. The length of the sleep intervals is chosen as a compromise between fast reaction time and low CPU load. The more frequent you poll, the faster your reaction time for the end of the measurement is. In this sense, polling is always a somewhat inefficient pattern, but it is also easiest to implement. For better performance, read about the next option.

  2. Registering an end-of-measurement callback

    Prior to starting a measurement, the application developer can register a function of his choice that the scTDC library calls when the end of measurement is reached. This registration is done by calling sc_tdc_set_complete_callback2() and providing a function with the signature void cb(void* privateptr, int reason_code);. The proper end of measurement is indicated, when this function is called with a reason_code == 1. However, as soon as the hardware stops its exposure, even before all of its data has been transferred to the PC and processed by the library, the cb function may be called with a reason_code == 4. This code 4 comes in addition and prior to the code 1, so the application developer has to handle this case with a separate behaviour – for example ignoring code 4 and reacting to code 1. Aborted measurements are indicated by cb invocations with reason_code == 2, and reason_code == 3. The reason codes have macro definitions in File scTDC_error_codes.h (SC_TDC_INFO_MEAS_COMPLETE, SC_TDC_INFO_USER_INTERRUPT, SC_TDC_INFO_BUFFER_FULL, SC_TDC_INFO_HW_IDLE)

Use-case specific options:

  1. Reading histogram data or reading statistics data

    If your application has configured a pipe that generates histograms or the statistics pipe, you will use sc_pipe_read2() to read the respective data. This function can be called with the timeout set to something much longer than the measurement time. As soon as the end of the measurement is reached, histogram data and statistics data become available and the function returns at this moment. This can be used to trigger any actions the application should perform with the data and also to trigger the start of the next measurement.

  2. Reading event data from the USER_CALLBACKS pipe and reacting to its end_of_measure callback

    If your application reads event data via the USER_CALLBACKS pipe, one of the callback functions you can register for, notifies you when the end-of-measurement control sign is encountered by the internal hardware protocol decoder of the scTDC library. This control sign appears as the last thing of a measurement, so all measurement data and statistics data have already been processed by the library. However, some internal threads of the library may not have switched to the idle state. It is not possible to start a new measurement directly from the callback function. Instead, you can use thread synchronization mechanisms such as semaphores or condition variables to notify your main thread, that all data is available and possibly a new measurement can be started.

Running sequences of measurements

After waiting for the end of a measurement, you may decide to start the next measurement, as soon as possible, thus establishing a sequence of measurements. Depending on how you waited for the end of the measurement you may run into a SC_TDC_ERR_NOTRDY (File scTDC_error_codes.h) returned by calling sc_tdc_start_measure2(). This does not happen if you used the polling-for-idle-status mechanism, but it can happen with the other options discussed in the previous section. To make your sequence more robust, you can call sc_tdc_start_measure2() multiple times with a thread-yield (meaning your thread pauses for a minimal time until it is scheduled again by the operating system) in between until this function returns zero, indicating success, or some other error than SC_TDC_ERR_NOTRDY (in that case you should stop retrying).