Commit 320471c9 authored by Simon Spannagel's avatar Simon Spannagel
Browse files

Merge branch 'master' into documentation

parents f2afc2f9 69c843be
Pipeline #435019 passed with stages
in 3 minutes and 53 seconds
......@@ -6,17 +6,21 @@
MESSAGE(STATUS "Looking for Peary...")
FIND_PATH(Peary_INCLUDE_DIRS NAMES "peary/device/device.hpp" PATHS "$ENV{PEARYPATH}")
FIND_PATH(Peary_INCLUDE_DIR NAMES "peary/device/device.hpp" PATHS "$ENV{PEARYPATH}")
FIND_LIBRARY(Peary_LIBRARIES NAMES "peary" HINTS "$ENV{PEARYPATH}/lib")
LIST(APPEND Peary_INCLUDE_DIRS "${Peary_INCLUDE_DIR}/peary/utils")
LIST(APPEND Peary_INCLUDE_DIRS "${Peary_INCLUDE_DIR}/devices")
IF(Peary_FIND_COMPONENTS)
FOREACH(component ${Peary_FIND_COMPONENTS})
STRING(TOLOWER "${component}" _COMP)
FIND_PATH(Peary_COMP_INCLUDE NAMES "devices/${_COMP}/${_COMP}.hpp" PATHS "$ENV{PEARYPATH}")
FIND_LIBRARY(Peary_COMP_LIB NAMES "${component}" HINTS "$ENV{PEARYPATH}/lib")
FIND_PATH(Peary_COMP_INCLUDE NAMES "devices/${component}/${component}Device.hpp" PATHS "$ENV{PEARYPATH}")
FIND_LIBRARY(Peary_COMP_LIB NAMES "PearyDevice${component}" HINTS "$ENV{PEARYPATH}/lib")
IF(Peary_COMP_INCLUDE AND Peary_COMP_LIB)
LIST(APPEND Peary_LIBRARIES "${Peary_COMP_LIB}")
LIST(APPEND Peary_INCLUDE_DIRS "${Peary_COMP_INCLUDE}/devices/${component}")
SET(Peary_${component}_FOUND TRUE)
MESSAGE(STATUS "Looking for Peary component: ${component} -- Found")
ELSE()
MESSAGE(STATUS "Looking for Peary component: ${component} -- NOTFOUND")
ENDIF()
......
......@@ -147,7 +147,7 @@ void Analysis::load_modules() {
global_config.setAlias("histogram_file", "histogramFile");
std::string histogramFile = global_config.getPath("histogram_file");
m_histogramFile = new TFile(histogramFile.c_str(), "RECREATE");
m_histogramFile = std::make_unique<TFile>(histogramFile.c_str(), "RECREATE");
m_directory = m_histogramFile->mkdir("corryvreckan");
if(m_histogramFile->IsZombie()) {
throw RuntimeError("Cannot create main ROOT file " + histogramFile);
......@@ -360,7 +360,7 @@ void Analysis::run() {
if(number_of_events > -1 && m_events >= number_of_events)
break;
if(run_time > 0.0 && (m_clipboard->get_persistent("currentTime")) >= run_time)
if(run_time > 0.0 && (m_clipboard->get_persistent("eventStart")) >= run_time)
break;
// Check if we have reached the maximum number of tracks
......@@ -418,7 +418,7 @@ void Analysis::run() {
LOG_PROGRESS(STATUS, "event_loop")
<< "Ev: +" << m_events << " \\" << skipped << " Tr: " << m_tracks << " (" << std::setprecision(3)
<< ((double)m_tracks / m_events)
<< "/ev) t = " << Units::display(m_clipboard->get_persistent("currentTime"), {"ns", "us", "s"});
<< "/ev) t = " << Units::display(m_clipboard->get_persistent("eventStart"), {"ns", "us", "ms", "s"});
}
// Clear objects from this iteration from the clipboard
......@@ -494,7 +494,9 @@ void Analysis::finaliseAll() {
// Write the output histogram file
m_directory->cd();
m_directory->Write();
m_histogramFile->Close();
LOG(STATUS) << "Wrote histogram output file to " << global_config.getPath("histogramFile");
// Write out update detectors file:
if(global_config.has("detectors_file_updated")) {
......
......@@ -66,7 +66,7 @@ namespace corryvreckan {
// Log file if specified
std::ofstream log_file_;
TFile* m_histogramFile;
std::unique_ptr<TFile> m_histogramFile;
TDirectory* m_directory;
int m_events;
int m_tracks;
......
#include "Clipboard.hpp"
#include "exceptions.h"
#include "objects/Object.hpp"
using namespace corryvreckan;
......@@ -24,7 +25,15 @@ Objects* Clipboard::get(std::string name, std::string type) {
}
double Clipboard::get_persistent(std::string name) {
return m_persistent_data[name];
try {
return m_persistent_data.at(name);
} catch(std::out_of_range&) {
throw MissingDataError("Key " + name + " not available on clipboard");
}
}
bool Clipboard::has_persistent(std::string name) {
return m_persistent_data.find(name) != m_persistent_data.end();
}
void Clipboard::clear() {
......
......@@ -75,9 +75,17 @@ namespace corryvreckan {
* @brief Retrieve variable from the persistent clipboard storage
* @param name Name of the variable
* @return Stored value from the persistent clipboard storage
* @throws MissingKeyError in case the key is not found.
*/
double get_persistent(std::string name);
/**
* @brief Check if variable exists on the persistent clipboard storage
* @param name Name of the variable
* @return True if value exists, false if it does not exist.
*/
bool has_persistent(std::string name);
/**
* @brief Clear the event storage of the clipboard
*/
......
......@@ -8,13 +8,11 @@ ATLASpixEventLoader::ATLASpixEventLoader(Configuration config, std::vector<Detec
: Module(std::move(config), std::move(detectors)) {
m_timewalkCorrectionFactors = m_config.getArray<double>("timewalkCorrectionFactors", std::vector<double>());
m_timestampPeriod = m_config.get<double>("timestampPeriod", Units::convert(25, "ns"));
m_inputDirectory = m_config.get<std::string>("inputDirectory");
m_calibrationFile = m_config.get<std::string>("calibrationFile", std::string());
m_eventLength = m_config.get<double>("eventLength", Units::convert(0.0, "ns"));
m_clockCycle = m_config.get<int>("clockCycle", Units::convert(25, "ns"));
m_clockCycle = m_config.get<double>("clockCycle", Units::convert(25, "ns"));
// Allow reading of legacy data format using the Karlsruhe readout system:
m_legacyFormat = m_config.get<bool>("legacyFormat", false);
......@@ -43,7 +41,7 @@ void ATLASpixEventLoader::initialise() {
while((entry = readdir(directory))) {
// Check for the data file
string filename = m_inputDirectory + "/" + entry->d_name;
if(filename.find(".dat") != string::npos) {
if(filename.find("data.txt") != string::npos) {
m_filename = filename;
}
}
......@@ -92,8 +90,7 @@ void ATLASpixEventLoader::initialise() {
LOG(INFO) << ts;
}
m_clockFactor = m_timestampPeriod / 25;
LOG(INFO) << "Applying clock scaling factor: " << m_clockFactor << std::endl;
LOG(INFO) << "Using clock cycle length of " << m_clockCycle << std::endl;
// Initialise member variables
m_eventNumber = 0;
......@@ -103,16 +100,22 @@ void ATLASpixEventLoader::initialise() {
StatusCode ATLASpixEventLoader::run(Clipboard* clipboard) {
// Check if event frame is defined:
if(!clipboard->has_persistent("eventStart") || !clipboard->has_persistent("eventEnd")) {
throw ModuleError("Event not defined. Add Metronome module or Event reader defining the event.");
}
// If have reached the end of file, close it and exit program running
if(m_file.eof()) {
m_file.close();
return Failure;
}
double current_time = clipboard->get_persistent("currentTime");
double start_time = clipboard->get_persistent("eventStart");
double end_time = clipboard->get_persistent("eventEnd");
// Read pixel data
Pixels* pixels = (m_legacyFormat ? read_legacy_data(current_time) : read_caribou_data(current_time));
Pixels* pixels = (m_legacyFormat ? read_legacy_data(start_time, end_time) : read_caribou_data(start_time, end_time));
for(auto px : (*pixels)) {
hHitMap->Fill(px->column(), px->row());
......@@ -124,22 +127,22 @@ StatusCode ATLASpixEventLoader::run(Clipboard* clipboard) {
hPixelsOverTime->Fill(Units::convert(px->timestamp(), "ms"));
}
// Fill histograms
hPixelsPerFrame->Fill(pixels->size());
// Put the data on the clipboard
if(!pixels->empty()) {
clipboard->put(m_detectorID, "pixels", (Objects*)pixels);
} else {
return NoData;
}
// Increment the event time
clipboard->put_persistent("currentTime", clipboard->get_persistent("currentTime") + m_eventLength);
// Fill histograms
hPixelsPerFrame->Fill(pixels->size());
// Return value telling analysis to keep running
return Success;
}
Pixels* ATLASpixEventLoader::read_caribou_data(double current_time) {
Pixels* ATLASpixEventLoader::read_caribou_data(double start_time, double end_time) {
// Pixel container
Pixels* pixels = new Pixels();
......@@ -148,7 +151,6 @@ Pixels* ATLASpixEventLoader::read_caribou_data(double current_time) {
// Read file and load data
std::string line_str;
std::streampos oldpos;
while(getline(m_file, line_str)) {
double timestamp;
std::istringstream line(line_str);
......@@ -169,25 +171,33 @@ Pixels* ATLASpixEventLoader::read_caribou_data(double current_time) {
line >> scol >> srow >> sts1 >> sts2 >> stot >> sfpga_ts >> str_cnt >> sbin_cnt;
// Only convert used numbers:
int col = std::stoi(scol);
int row = std::stoi(srow);
int fpga_ts = std::stoi(sfpga_ts);
int tot = std::stoi(stot);
long long col = std::stoll(scol);
long long row = std::stoll(srow);
long long fpga_ts = std::stoll(sfpga_ts);
long long tot = std::stoll(stot);
// Convert the timestamp to nanoseconds:
timestamp = fpga_ts * m_clockCycle;
// 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(timestamp > (current_time + m_eventLength)) {
if(timestamp > end_time) {
LOG(DEBUG) << "Stopping processing event, pixel is after event window ("
<< Units::display(timestamp, {"s", "us", "ns"}) << " > "
<< Units::display(current_time + m_eventLength, {"s", "us", "ns"}) << ")";
<< Units::display(end_time, {"s", "us", "ns"}) << ")";
// Rewind to previous position:
LOG(TRACE) << "Rewinding to file pointer : " << oldpos;
m_file.seekg(oldpos);
break;
}
if(timestamp < start_time) {
LOG(DEBUG) << "Skipping pixel hit, pixel is before event window ("
<< Units::display(timestamp, {"s", "us", "ns"}) << " < "
<< Units::display(start_time, {"s", "us", "ns"}) << ")";
continue;
}
// If this pixel is masked, do not save it
if(detector->masked(col, row)) {
continue;
......@@ -201,13 +211,14 @@ Pixels* ATLASpixEventLoader::read_caribou_data(double current_time) {
}
// Store this position in the file in case we need to rewind:
LOG(TRACE) << "Storing file pointer position: " << m_file.tellg();
oldpos = m_file.tellg();
}
return pixels;
}
Pixels* ATLASpixEventLoader::read_legacy_data(double) {
Pixels* ATLASpixEventLoader::read_legacy_data(double, double) {
// Pixel container
Pixels* pixels = new Pixels();
......
......@@ -34,12 +34,12 @@ namespace corryvreckan {
/*
* @brief Read data in the format written by the Karlsruhe readout system
*/
Pixels* read_legacy_data(double current_time);
Pixels* read_legacy_data(double start_time, double end_time);
/*
* @brief Read data in the format written by the Caribou readout system
*/
Pixels* read_caribou_data(double current_time);
Pixels* read_caribou_data(double start_time, double end_time);
// Member variables
int m_eventNumber;
......@@ -48,7 +48,9 @@ namespace corryvreckan {
std::string detectorID;
std::string m_filename;
std::ifstream m_file;
double m_clockFactor;
// Resuming in next event:
std::streampos oldpos;
TH2F* hHitMap;
TH1F* hPixelToT;
......@@ -60,7 +62,6 @@ namespace corryvreckan {
// Parameters:
std::vector<double> m_timewalkCorrectionFactors;
std::vector<double> m_calibrationFactors;
double m_timestampPeriod;
std::string m_inputDirectory;
std::string m_calibrationFile;
double m_eventLength;
......@@ -68,7 +69,7 @@ namespace corryvreckan {
bool m_toaMode;
std::string m_detectorID;
bool m_legacyFormat;
int m_clockCycle;
double m_clockCycle;
std::map<std::string, int> m_identifiers;
};
......
# ATLASpixEventLoader
**Maintainer**: Simon Spannagel (<simon.spannagel@cern.ch>)
**Status**: Outdated
**Maintainer**: Simon Spannagel (<simon.spannagel@cern.ch>)
**Status**: Functional
### Description
This module reads in data for the ATLASpix device from an input file.
This module reads in data for the ATLASpix device from an input file created by the CaRIBou readout system.
The module opens and reads one data file in the specified input directory with the ending `.dat`. For each hit it, stores the detectorID, row, column, and ToT.
Outdated as data format and decoding for this device has since changed.
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 containing the `.dat` file. This path should lead to the directory above the ALTASpix directory, as this string is added to the input directory in the module.
* `clockCycle`: Period of the clock used to count the trigger timestamps in, defaults to `25ns`
* `DUT`: Name of the DUT plane.
### Plots produced
......
......@@ -12,7 +12,6 @@ CLICpix2Analysis::CLICpix2Analysis(Configuration config, std::vector<Detector*>
m_DUT = m_config.get<std::string>("DUT");
m_timeCutFrameEdge = m_config.get<double>("timeCutFrameEdge", Units::convert(20, "ns"));
m_roi = m_config.getMatrix<int>("roi", std::vector<std::vector<int>>());
spatialCut = m_config.get<double>("spatialCut", Units::convert(50, "um"));
chi2ndofCut = m_config.get<double>("chi2ndofCut", 3.);
......
......@@ -62,7 +62,6 @@ namespace corryvreckan {
std::string m_DUT;
double spatialCut, m_timeCutFrameEdge;
double chi2ndofCut;
std::vector<std::vector<int>> m_roi;
};
} // namespace corryvreckan
......
......@@ -120,8 +120,9 @@ StatusCode CLICpixEventLoader::run(Clipboard* clipboard) {
}
// Now set the event time so that the Timepix3 data is loaded correctly
clipboard->put_persistent("currentTime", shutterStartTime);
m_config.set<double>("eventLength", (shutterStopTime - shutterStartTime));
clipboard->put_persistent("eventStart", shutterStartTime);
clipboard->put_persistent("eventEnd", shutterStopTime);
clipboard->put_persistent("eventLength", (shutterStopTime - shutterStartTime));
LOG(TRACE) << "Loaded " << npixels << " pixels";
// Put the data on the clipboard
......
......@@ -11,7 +11,7 @@ CORRYVRECKAN_MODULE_SOURCES(${MODULE_NAME}
Clicpix2EventLoader.cpp
)
TARGET_INCLUDE_DIRECTORIES(${MODULE_NAME} SYSTEM PRIVATE ${Peary_INCLUDE_DIRS}/devices/clicpix2 ${Peary_INCLUDE_DIRS}/peary/utils)
TARGET_INCLUDE_DIRECTORIES(${MODULE_NAME} SYSTEM PRIVATE ${Peary_INCLUDE_DIRS})
# Link required Peary libraries
TARGET_LINK_LIBRARIES(${MODULE_NAME} ${Peary_LIBRARIES})
......
#include "Clicpix2EventLoader.h"
#include "clicpix2_pixels.hpp"
#include "clicpix2_utilities.hpp"
#include "CLICpix2/clicpix2_pixels.hpp"
#include "CLICpix2/clicpix2_utilities.hpp"
#include "datatypes.hpp"
using namespace corryvreckan;
......@@ -266,7 +266,8 @@ StatusCode Clicpix2EventLoader::run(Clipboard* clipboard) {
// Store current frame time and the length of the event:
LOG(DEBUG) << "Event time: " << Units::display(shutterStartTime, {"ns", "us", "s"})
<< ", length: " << Units::display((shutterStopTime - shutterStartTime), {"ns", "us", "s"});
clipboard->put_persistent("currentTime", shutterStartTime);
clipboard->put_persistent("eventStart", shutterStartTime);
clipboard->put_persistent("eventEnd", shutterStopTime);
clipboard->put_persistent("eventLength", (shutterStopTime - shutterStartTime));
// Put the data on the clipboard
......
......@@ -17,8 +17,8 @@
#include "objects/Pixel.h"
#include "objects/Track.h"
#include "clicpix2_frameDecoder.hpp"
#include "clicpix2_pixels.hpp"
#include "CLICpix2/clicpix2_pixels.hpp"
#include "CLICpix2/framedecoder/clicpix2_frameDecoder.hpp"
namespace corryvreckan {
/** @ingroup Modules
......
......@@ -3,7 +3,8 @@
**Status**: Functional
### Description
This module reads in data for a CLICpix2 device from an input file. It defines the reconstruction time structure as being the CLICpix2 frame by setting the `currentTime` to the begin of the frame and the `eventLength` to the length of the readout frame. These times are stored on the persistent clipboard storage and can be picked up by other modules to allow synchronization.
This module reads in data for a CLICpix2 device from an input file. It defines the reconstruction time structure as being the CLICpix2 frame by setting the `eventStart` to the begin of the frame, the `eventEnd` to the end of the shutter and the `eventLength` to the length of the readout frame. These times are stored on the persistent clipboard storage and can be picked up by other modules to allow synchronization.
Thus, this module should not be used in conjunction with the Metronome but should be placed at the very beginning of the module chain.
The module opens and reads one data file in the specified input directory.
The input directory is searched for a data file with the file extension `.raw` and a pixel matrix configuration file required for decoding with the file extension `.cfg` and a name starting with `matrix`.
......
# Define module and return the generated name as MODULE_NAME
CORRYVRECKAN_MODULE(MODULE_NAME)
# Add source files to library
CORRYVRECKAN_MODULE_SOURCES(${MODULE_NAME}
Metronome.cpp
# ADD SOURCE FILES HERE...
)
# Provide standard install target
CORRYVRECKAN_MODULE_INSTALL(${MODULE_NAME})
#include "Metronome.h"
using namespace corryvreckan;
using namespace std;
Metronome::Metronome(Configuration config, std::vector<Detector*> detectors)
: Module(std::move(config), std::move(detectors)) {
m_eventLength = m_config.get<double>("eventLength", Units::convert(10, "us"));
}
void Metronome::initialise() {
// Set initial values for the start and stop time of the first event:
m_eventStart = 0.0;
m_eventEnd = m_eventLength;
}
StatusCode Metronome::run(Clipboard* clipboard) {
// Set up the clipboard persistent storage for the current event:
clipboard->put_persistent("eventStart", m_eventStart);
clipboard->put_persistent("eventEnd", m_eventEnd);
clipboard->put_persistent("eventLength", m_eventLength);
// Increment the current event's start and end times by the configured event length
m_eventStart = m_eventEnd;
m_eventEnd += m_eventLength;
// Return value telling analysis to keep running
return Success;
}
#ifndef Metronome_H
#define Metronome_H 1
#include <iostream>
#include "TCanvas.h"
#include "TH1F.h"
#include "TH2F.h"
#include "core/module/Module.hpp"
#include "objects/Cluster.h"
#include "objects/Pixel.h"
#include "objects/Track.h"
namespace corryvreckan {
/** @ingroup Modules
*/
class Metronome : public Module {
public:
// Constructors and destructors
Metronome(Configuration config, std::vector<Detector*> detectors);
~Metronome() {}
// Functions
void initialise();
StatusCode run(Clipboard* clipboard);
private:
double m_eventStart, m_eventEnd, m_eventLength;
};
} // namespace corryvreckan
#endif // Metronome_H
## Metronome
**Maintainer**: Simon Spannagel (<simon.spannagel@cern.ch>)
**Status**: Functional
#### Description
The `Metronome` module is can be used to slice data without strict event structure in arbitrarily long time slots, which serve as events for subsequent modules. This is done by configuring an event length and by setting the variables `eventStart` and `eventStop` on the clipboard.
Subsequent modules should read these values and adhere to them.
#### Parameters
* `eventLength`: Length of the event to be defined in physical units (not clock cycles of a specific device). Default value is `10us`.
#### Usage
```toml
[Metronome]
eventLength = 500ns
```
# Timepix3EventLoader
**Maintainer**: Daniel Hynds (<daniel.hynds@cern.ch>)
**Status**: Outdated
**Maintainer**: Daniel Hynds (<daniel.hynds@cern.ch>), Simon Spannagel (<simon.spannagel@cern.ch>)
**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.
......@@ -12,11 +12,12 @@ In Timepix3, the phase of the 40 MHz clock can be shifted from one double column
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 the Timepix3 chip manual version 1.9, section 3.2.1 and/or [@timepix3-talk], 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.
......
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