Commit 61e08957 authored by Simon Spannagel's avatar Simon Spannagel
Browse files

Make Timepix3EventLoader use Metronome

parent f6d69b65
## Timepix3EventLoader
**Maintainer**: Daniel Hynds (<>)
**Status**: Outdated
**Maintainer**: Daniel Hynds (<>), Simon Spannagel (<>)
**Status**: Functional
#### Description
This module loads raw data from a Timepix3 device and adds it to the clipboard. The input file must have extension `.dat` and are sorted into time order via the data file serial numbers. This code also identifies `trimdac` files and applies this mask to the pixels.
......@@ -9,11 +9,12 @@ The data can be split into events using an event length in time, or using a maxi
The hit timestamps are derived from the 40 MHz TOA counter and the fast on-pixel oscillator, which is measuring the precise hit arrival phase within to the global 40 MHz clock. In Timepix3, the phase of the 40 MHz clock can be shifted from one double column to the next by 22.5 degree by the clock generator in order to minimize the instant digital power supply due to the pixel matrix clock tree. This mode is used in the CLICdp telescope, and thus, the column-to-column phase shift is taken into account when calculating the hit arrival times. See also, Timepix3 Manual v1.9, section 3.2.1 and/or EP-ESE seminar,The Timepix3 chip, X. Llopart,, slides 25 and 48.
When running in time mode (`number_of_pixelhits` not set), this module requires either another event loader of another detector type before which defines the event start and end times (variables `eventStart` and `eventEnd` on the clipboard) or an instance of the Metronome module which provides this information.
#### Parameters
* `inputDirectory`: Path to the directory above the data directory for each device. The device name is added to the path during the module.
* `minNumberOfPlanes`: Minimum number of planes with loaded data required for each event to be stored. Default value is `1`.
* `eventLength`: Length in time for each event. Default value is `0.0`. Event length is only used if this parameter is present in the configuration file, otherwise the data is split into events using the `number_of_pixelhits` parameter.
* `number_of_pixelhits`: Maximum number of pixel hits on each detector per event. Default value is `2000`. This is only used if `eventLength` is not present in the configuration file, otherwise the data is split into events using the `eventLength` parameter.
* `number_of_pixelhits`: Maximum number of pixel hits on each detector per event. Default value is `2000`. This is only used if this parameter is present in the configuration file, otherwise the data is split into events using the event length information from the clipboard.
* `calibrationPath`: Path to the calibration directory. If this parameter is set, calibration will be applied to the DUT. Assumed folder structure is `"[calibrationPath]/[detector name]/cal_thr_[thr dac]_ik_[ikrum dac]/[detector name]_cal_[tot/toa].txt"`. The assumed file structure is `[col | row | val1 | val2 | etc.]`.
* `DUT`: Name of the DUT plane.
......@@ -14,8 +14,8 @@ using namespace corryvreckan;
using namespace std;
Timepix3EventLoader::Timepix3EventLoader(Configuration config, std::vector<Detector*> detectors)
: Module(std::move(config), std::move(detectors)), temporalSplit(false), m_currentTime(0), m_currentEvent(0),
m_prevTime(0), m_shutterOpen(false) {
: Module(std::move(config), std::move(detectors)), temporalSplit(false), m_currentEvent(0), m_prevTime(0),
m_shutterOpen(false) {
// Take input directory from global parameters
m_inputDirectory = m_config.get<std::string>("inputDirectory");
......@@ -23,7 +23,6 @@ Timepix3EventLoader::Timepix3EventLoader(Configuration config, std::vector<Detec
m_minNumberOfPlanes = m_config.get<int>("minNumerOfPlanes", 1);
// Check whether event length or pixel count should be used to separate events:
m_eventLength = m_config.get<double>("eventLength", Units::convert(0.0, "ns"));
m_numberPixelHits = m_config.get<int>("number_of_pixelhits", 2000);
// Calibration parameters
......@@ -33,12 +32,12 @@ Timepix3EventLoader::Timepix3EventLoader(Configuration config, std::vector<Detec
void Timepix3EventLoader::initialise() {
if(m_config.has("eventLength")) {
LOG(INFO) << "Event length set, splitting events by time.";
temporalSplit = true;
} else {
if(m_config.has("number_of_pixelhits")) {
LOG(INFO) << "Splitting events by number of pixel hits on detector plane.";
temporalSplit = false;
} else {
LOG(INFO) << "Event length set, splitting events by time.";
temporalSplit = true;
// File structure is RunX/ChipID/files.dat
......@@ -248,12 +247,6 @@ StatusCode Timepix3EventLoader::run(Clipboard* clipboard) {
// be done in one of two ways: by taking all data in the time interval (t,t+delta), or by
// loading a fixed number of pixels (ie. 2000 at a time)
// If event length is stored on clipboard, prefer that one:
if(clipboard->get_persistent("eventLength") > 0.1) {
m_eventLength = clipboard->get_persistent("eventLength");
LOG(DEBUG) << "Using event length from clipboard: " << Units::display(m_eventLength, {"s", "us", "ns"});
LOG(TRACE) << "== New event";
int loadedData = 0;
......@@ -293,14 +286,11 @@ StatusCode Timepix3EventLoader::run(Clipboard* clipboard) {
clipboard->put(detectorID, "SpidrSignals", (Objects*)spidrData);
// Increment the event time
clipboard->put_persistent("currentTime", clipboard->get_persistent("currentTime") + m_eventLength);
// Otherwise tell event loop to keep running
if(temporalSplit) {
LOG_PROGRESS(INFO, "tpx3_loader")
<< "Current time: " << Units::display(clipboard->get_persistent("currentTime"), {"s", "ms", "us", "ns"});
<< "Current time: " << Units::display(clipboard->get_persistent("eventStart"), {"s", "ms", "us", "ns"});
} else {
LOG_PROGRESS(INFO, "tpx3_loader") << "Current event: " << m_currentEvent;
......@@ -490,7 +480,7 @@ bool Timepix3EventLoader::loadData(Clipboard* clipboard, Detector* detector, Pix
// (and rewind the file
// reader so that we start with this signal next event)
if(temporalSplit) {
if(timestamp > (clipboard->get_persistent("currentTime") + m_eventLength)) {
if(timestamp > clipboard->get_persistent("eventEnd")) {
(*m_file_iterator[detectorID])->seekg(-1 * sizeof(pixdata), std::ios_base::cur);
LOG(TRACE) << "Signal has a time beyond the current event: " << Units::display(timestamp, "ns");
......@@ -624,20 +614,19 @@ bool Timepix3EventLoader::loadData(Clipboard* clipboard, Detector* detector, Pix
// time is within this window
// Ignore pixel data if it is before the "currentTime" read from the clipboard storage:
if(temporalSplit && (timestamp < clipboard->get_persistent("currentTime"))) {
if(temporalSplit && (timestamp < clipboard->get_persistent("eventStart"))) {
LOG(TRACE) << "Skipping pixel, is before event window (" << Units::display(timestamp, {"s", "us", "ns"})
<< " < " << Units::display(clipboard->get_persistent("currentTime"), {"s", "us", "ns"}) << ")";
<< " < " << Units::display(clipboard->get_persistent("eventStart"), {"s", "us", "ns"}) << ")";
// Stop looking at data if the pixel is after the current event window
// (and rewind the file reader so that we start with this pixel next event)
if(temporalSplit && (timestamp > (clipboard->get_persistent("currentTime") + m_eventLength))) {
if(temporalSplit && (timestamp > clipboard->get_persistent("eventEnd"))) {
LOG(DEBUG) << "Stopping processing event, pixel is after "
"event window ("
<< Units::display(timestamp, {"s", "us", "ns"}) << " > "
<< Units::display(clipboard->get_persistent("currentTime") + m_eventLength, {"s", "us", "ns"})
<< ")";
<< Units::display(clipboard->get_persistent("eventEnd"), {"s", "us", "ns"}) << ")";
(*m_file_iterator[detectorID])->seekg(-1 * sizeof(pixdata), std::ios_base::cur);
......@@ -47,7 +47,6 @@ namespace corryvreckan {
int m_minNumberOfPlanes;
bool temporalSplit;
double m_eventLength;
int m_numberPixelHits;
bool applyCalibration;
......@@ -66,7 +65,6 @@ namespace corryvreckan {
std::map<std::string, long long int> m_syncTimeTDC;
std::map<std::string, int> m_TDCoverflowCounter;
long long int m_currentTime;
long long int m_currentEvent;
long long int m_prevTime;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment