Commit 06372886 authored by Jens Kroeger's avatar Jens Kroeger
Browse files

resolved merge-conflicts regarding DUTAssociation.cpp/.h and edited README.md

parents 38bf7f1d 9afc59ec
......@@ -48,9 +48,12 @@ Corryvreckan has been developed and is maintained by
The following authors, in alphabetical order, have contributed to Corryvreckan:
* Matthew Daniel Buckland, University of Liverpool, @mbucklan
* Dominik Dannheim, CERN, @dannheim
* Adrian Fiergolski, CERN, @afiergol
* Jens Kroeger, University of Heidelberg/CERN, @jekroege
* Andreas Matthias Nürnberg, CERN, @nurnberg
* Florian Pitters, CERN, @fpipper
* Tomas Vanat, CERN, @tvanat
## Contributing
All types of contributions, being it minor and major, are very welcome. Please refer to our [contribution guidelines](CONTRIBUTING.md) for a description on how to get started.
......
......@@ -106,6 +106,9 @@ void Analysis::load() {
void Analysis::load_detectors() {
// Flag for the reference detector
bool found_reference = false;
std::vector<std::string> detectors_files = global_config.getPathArray("detectors_file");
for(auto& detectors_file : detectors_files) {
......@@ -127,11 +130,24 @@ void Analysis::load_detectors() {
LOG(INFO) << "Detector: " << name;
Detector* det_parm = new Detector(detector);
// Check if we already found a reference plane:
if(found_reference && det_parm->role() == DetectorRole::REFERENCE) {
throw InvalidValueError(global_config, "detectors_file", "Found more than one reference detector");
}
// Switch flag if we found the reference plane:
found_reference |= (det_parm->role() == DetectorRole::REFERENCE);
// Add the new detector to the global list:
detectors.push_back(det_parm);
}
}
// Check that exactly one detector is marked as reference:
if(!found_reference) {
throw InvalidValueError(global_config, "detectors_file", "Found no detector marked as reference");
}
LOG(STATUS) << "Loaded " << detectors.size() << " detectors";
// Finally, sort the list of detectors by z position (from lowest to highest)
......
......@@ -9,7 +9,7 @@
*/
#ifndef CORRYVRECKAN_CLIPBOARD_EXCEPTIONS_H
#define CORRYVRECKAN_CLIPOARD_EXCEPTIONS_H
#define CORRYVRECKAN_CLIPBOARD_EXCEPTIONS_H
#include <string>
......
......@@ -22,10 +22,27 @@ using namespace ROOT::Math;
using namespace corryvreckan;
Detector::Detector(const Configuration& config) {
// Get information from the conditions file:
// Role of this detector:
auto role = config.get<std::string>("role", "none");
std::transform(role.begin(), role.end(), role.begin(), ::tolower);
if(role == "none") {
m_role = DetectorRole::NONE;
} else if(role == "reference") {
m_role = DetectorRole::REFERENCE;
} else if(role == "dut") {
m_role = DetectorRole::DUT;
} else {
throw InvalidValueError(config, "role", "Detector role does not exist.");
}
// Detector position and orientation
m_displacement = config.get<ROOT::Math::XYZPoint>("position", ROOT::Math::XYZPoint());
m_orientation = config.get<ROOT::Math::XYZVector>("orientation", ROOT::Math::XYZVector());
m_orientation_mode = config.get<std::string>("orientation_mode", "xyz");
if(m_orientation_mode != "xyz" && m_orientation_mode != "zyx") {
throw InvalidValueError(config, "orientation_mode", "Invalid detector orientation mode");
}
// Number of pixels
auto npixels = config.get<ROOT::Math::DisplacementVector2D<Cartesian2D<int>>>("number_of_pixels");
......@@ -39,9 +56,8 @@ Detector::Detector(const Configuration& config) {
if(Units::convert(m_pitch.X(), "mm") >= 1 or Units::convert(m_pitch.Y(), "mm") >= 1 or
Units::convert(m_pitch.X(), "um") <= 1 or Units::convert(m_pitch.Y(), "um") <= 1) {
LOG(WARNING) << "Pixel pitch unphysical for detector " << m_detectorName << ".";
LOG(WARNING) << "Pitch X = " << Units::display(m_pitch.X(), {"nm", "um", "mm"})
<< " ; Pitch Y = " << Units::display(m_pitch.Y(), {"nm", "um", "mm"});
LOG(WARNING) << "Pixel pitch unphysical for detector " << m_detectorName << ": " << std::endl
<< Units::display(m_pitch, {"nm", "um", "mm"});
}
m_detectorType = config.get<std::string>("type");
......@@ -69,6 +85,14 @@ Detector::Detector(const Configuration& config) {
}
}
bool Detector::isReference() {
return m_role == DetectorRole::REFERENCE;
}
bool Detector::isDUT() {
return m_role == DetectorRole::DUT;
}
// Functions to set and check channel masking
void Detector::setMaskFile(std::string file) {
m_maskfile = file;
......@@ -133,8 +157,6 @@ void Detector::initialise() {
ROOT::Math::RotationX(m_orientation.X()));
} else if(m_orientation_mode == "zyx") {
rotations = Rotation3D(ROOT::Math::RotationZYX(m_orientation.x(), m_orientation.y(), m_orientation.x()));
} else {
throw RuntimeError("Invalid detector orientation mode: " + m_orientation_mode);
}
m_localToGlobal = Transform3D(rotations, translations);
......@@ -160,6 +182,13 @@ Configuration Detector::getConfiguration() {
Configuration config(name());
config.set("type", m_detectorType);
// Store the role of the detector
if(m_role == DetectorRole::REFERENCE) {
config.set("role", "reference");
} else if(m_role == DetectorRole::DUT) {
config.set("role", "dut");
}
config.set("position", m_displacement, {"um", "mm"});
config.set("orientation_mode", m_orientation_mode);
config.set("orientation", m_orientation, {"deg"});
......
......@@ -27,7 +27,21 @@
using namespace ROOT::Math;
namespace corryvreckan {
// Class containing just the detector parameters
/**
* @brief Role of the detector
*/
enum class DetectorRole {
NONE = 0, ///< No specific detector role
REFERENCE, ///< Reference detector
DUT, ///< Detector used as device under test
};
/**
* @brief Detector representation in the reconstruction chain
*
* Contains the detector with all its properties such as type, name, position and orientation, pitch, resolution etc.
*/
class Detector {
public:
// Constructors and desctructors
......@@ -39,6 +53,11 @@ namespace corryvreckan {
std::string type() { return m_detectorType; }
std::string name() { return m_detectorName; }
// Detector role and helper functions
DetectorRole role() { return m_role; }
bool isReference();
bool isDUT();
Configuration getConfiguration();
ROOT::Math::XYVector size() { return ROOT::Math::XYVector(m_pitch.X() * m_nPixelsX, m_pitch.Y() * m_nPixelsY); }
......@@ -108,7 +127,8 @@ namespace corryvreckan {
bool isWithinROI(Cluster* cluster);
private:
// Member variables
DetectorRole m_role;
// Detector information
std::string m_detectorType;
std::string m_detectorName;
......
......@@ -34,6 +34,20 @@ Detector* Module::get_detector(std::string name) {
return (*it);
}
Detector* Module::get_reference() {
auto it = find_if(m_detectors.begin(), m_detectors.end(), [](Detector* obj) { return obj->isReference(); });
return (*it);
}
Detector* Module::get_dut() {
auto it = find_if(m_detectors.begin(), m_detectors.end(), [](Detector* obj) { return obj->isDUT(); });
if(it == m_detectors.end()) {
return nullptr;
}
return (*it);
}
bool Module::has_detector(std::string name) {
auto it = find_if(m_detectors.begin(), m_detectors.end(), [&name](Detector* obj) { return obj->name() == name; });
if(it == m_detectors.end()) {
......
......@@ -134,6 +134,19 @@ namespace corryvreckan {
*/
Detector* get_detector(std::string name);
/**
* @brief Get the reference detector for this setup
* @return Pointer to the reference detector
*/
Detector* get_reference();
/**
* @brief Get the device under test
* @return Pointer to the DUT detector. A nullptr is returned if no DUT is found.
* FIXME This should allow retrieval of a vector of DUTs
*/
Detector* get_dut();
/**
* @brief Check if this module should act on a given detector
* @param name Name of the detector to check
......
......@@ -31,6 +31,11 @@ namespace corryvreckan {
void finalise();
private:
/*
* @brief Converts gray encoded data to binary number
*/
uint32_t gray_decode(uint32_t gray);
/*
* @brief Read data in the format written by the Karlsruhe readout system
*/
......@@ -45,12 +50,15 @@ namespace corryvreckan {
int m_eventNumber;
unsigned long long int m_oldtoa;
unsigned long long int m_overflowcounter;
std::string detectorID;
std::string m_filename;
std::ifstream m_file;
// Resuming in next event:
std::streampos oldpos;
unsigned long long old_readout_ts;
unsigned long long old_fpga_ts;
// int ts1Range;
int ts2Range;
TH2F* hHitMap;
TH1F* hPixelToT;
......@@ -67,11 +75,14 @@ namespace corryvreckan {
double m_eventLength;
double m_startTime;
bool m_toaMode;
std::string m_detectorID;
bool m_legacyFormat;
double m_clockCycle;
// int m_clkdivendM;
int m_clkdivend2M;
std::map<std::string, int> m_identifiers;
unsigned int data_pixel_{}, data_header_{};
};
} // namespace corryvreckan
#endif // ATLASpixEventLoader_H
# ATLASpixEventLoader
**Maintainer**: Simon Spannagel (<simon.spannagel@cern.ch>)
**Status**: Functional
**Status**: Functional
### Description
This module reads in data for the ATLASpix device from an input file created by the CaRIBou readout system.
This module reads in data for the ATLASpix device from an input file created by the CaRIBou readout system. It supports binary output format.
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.
The module opens and reads one data file named `data.bin` in the specified input directory. For each hit it, stores the detectorID, row, column, and ToT.
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. The ATLASpix device is assumed to be the `DUT`.
* `inputDirectory`: Path to the directory containing the `data.bin` 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 `6.25ns`.
* `DUT`: Name of the DUT plane.
* `clkdivend2`: Value of clkdivend2 register in ATLASPix specifying the speed of TS2 counter. Default is `0`.
### Plots produced
* 2D Hit map
......@@ -25,4 +26,3 @@ This module requires either another event loader of another detector type before
DUT = "W0005_H03"
inputDirectory = /user/data/directory
```
Parameters to be used in multiple modules can also be defined globally at the top of the configuration file. This is highly encouraged for parameters such as `DUT` and `reference`.
......@@ -36,7 +36,7 @@ Alignment::Alignment(Configuration config, std::vector<Detector*> detectors)
if(m_config.has("detectorToAlign")) {
detectorToAlign = m_config.get<std::string>("detectorToAlign");
} else {
detectorToAlign = m_config.get<std::string>("DUT");
detectorToAlign = get_dut()->name();
}
LOG(INFO) << "Aligning detector \"" << detectorToAlign << "\"";
} else {
......@@ -399,8 +399,7 @@ void Alignment::finalise() {
string detectorID = detector->name();
// Do not align the reference plane
if(detectorID == m_config.get<std::string>("reference") ||
(m_config.has("DUT") && detectorID == m_config.get<std::string>("DUT"))) {
if(detector->isReference() || detector->isDUT()) {
continue;
}
......@@ -493,8 +492,7 @@ void Alignment::finalise() {
// Now list the new alignment parameters
for(auto& detector : get_detectors()) {
// Do not align the reference plane
if(detector->name() == m_config.get<std::string>("reference") ||
(m_config.has("DUT") && detector->name() == m_config.get<std::string>("DUT"))) {
if(detector->isReference() || detector->isDUT()) {
continue;
}
......
......@@ -55,4 +55,3 @@ alignmentMethod = 0
number_of_tracks = 1000000
log_level = INFO
```
Parameters to be used in multiple modules can also be defined globally at the top of the configuration file. This is highly encouraged for parameters such as `DUT` and `reference`.
......@@ -12,9 +12,7 @@ BasicTracking::BasicTracking(Configuration config, std::vector<Detector*> detect
timingCut = m_config.get<double>("timingCut", Units::convert(200, "ns"));
spatialCut = m_config.get<double>("spatialCut", Units::convert(0.2, "mm"));
minHitsOnTrack = m_config.get<int>("minHitsOnTrack", 6);
// checking if DUT parameter is in the configuration file, if so then check if the the DUT should be excluded, if not
// then set exclude the DUT
excludeDUT = (m_config.has("DUT") ? m_config.get<bool>("excludeDUT", true) : true);
excludeDUT = m_config.get<bool>("excludeDUT", true);
}
void BasicTracking::initialise() {
......@@ -58,9 +56,6 @@ StatusCode BasicTracking::run(Clipboard* clipboard) {
vector<string> detectors;
Clusters* referenceClusters = nullptr;
// Output track container
Tracks* tracks = new Tracks();
// Loop over all planes and get clusters
bool firstDetector = true;
std::string seedPlane;
......@@ -74,7 +69,7 @@ StatusCode BasicTracking::run(Clipboard* clipboard) {
} else {
// Store them
LOG(DEBUG) << "Picked up " << tempClusters->size() << " clusters from " << detectorID;
if(firstDetector && (!m_config.has("DUT") || detectorID != m_config.get<std::string>("DUT"))) {
if(firstDetector && !detector->isDUT()) {
referenceClusters = tempClusters;
seedPlane = detector->name();
LOG(DEBUG) << "Seed plane is " << seedPlane;
......@@ -89,13 +84,14 @@ StatusCode BasicTracking::run(Clipboard* clipboard) {
}
// If there are no detectors then stop trying to track
if(detectors.size() == 0)
if(detectors.size() == 0 || referenceClusters == nullptr) {
return Success;
}
// Output track container
Tracks* tracks = new Tracks();
// Loop over all clusters
if(referenceClusters == nullptr)
return Success;
int nSeedClusters = referenceClusters->size();
map<Cluster*, bool> used;
for(auto& cluster : (*referenceClusters)) {
......@@ -107,14 +103,14 @@ StatusCode BasicTracking::run(Clipboard* clipboard) {
track->addCluster(cluster);
track->setTimestamp(cluster->timestamp());
used[cluster] = true;
// Get the cluster time
long long int timestamp = cluster->timestamp();
// Loop over each subsequent plane and look for a cluster within the timing cuts
for(auto& detectorID : detectors) {
// Get the detector
auto det = get_detector(detectorID);
// Check if the DUT should be excluded and obey:
if(m_config.has("DUT") && excludeDUT && detectorID == m_config.get<std::string>("DUT")) {
if(excludeDUT && det->isDUT()) {
LOG(DEBUG) << "Skipping DUT plane.";
continue;
}
......@@ -138,8 +134,6 @@ StatusCode BasicTracking::run(Clipboard* clipboard) {
if(track->nClusters() > 1) {
track->fit();
// Get the detector
auto det = get_detector(detectorID);
PositionVector3D<Cartesian3D<double>> interceptPoint = det->getIntercept(track);
interceptX = interceptPoint.X();
interceptY = interceptPoint.Y();
......@@ -244,5 +238,3 @@ Cluster* BasicTracking::getNearestCluster(long long int timestamp, Clusters clus
return bestCluster;
}
void BasicTracking::finalise() {}
......@@ -23,7 +23,6 @@ namespace corryvreckan {
// Functions
void initialise();
StatusCode run(Clipboard* clipboard);
void finalise();
private:
// Cluster* getNearestCluster(Cluster*, map<Cluster*, bool>, Clusters*);
......@@ -52,8 +51,6 @@ namespace corryvreckan {
double spatialCut;
int minHitsOnTrack;
bool excludeDUT;
int associatedClusters;
};
} // namespace corryvreckan
#endif // BASICTRACKING_H
......@@ -42,4 +42,3 @@ DUT = "W13_01"
timingCut = 200ns
excludeDUT = true
```
Parameters to be used in multiple modules can also be defined globally at the top of the configuration file. This is highly encouraged for parameters such as `DUT` and `reference`.
......@@ -8,7 +8,6 @@ using namespace corryvreckan;
CLICpix2Analysis::CLICpix2Analysis(Configuration config, std::vector<Detector*> detectors)
: Module(std::move(config), std::move(detectors)) {
m_DUT = m_config.get<std::string>("DUT");
m_timeCutFrameEdge = m_config.get<double>("timeCutFrameEdge", Units::convert(20, "ns"));
......@@ -19,7 +18,7 @@ CLICpix2Analysis::CLICpix2Analysis(Configuration config, std::vector<Detector*>
void CLICpix2Analysis::initialise() {
// Get DUT detector:
auto det = get_detector(m_DUT);
auto det = get_dut();
hClusterMapAssoc = new TH2F(
"clusterMapAssoc", "clusterMapAssoc", det->nPixelsX(), 0, det->nPixelsX(), det->nPixelsY(), 0, det->nPixelsY());
......@@ -162,7 +161,7 @@ StatusCode CLICpix2Analysis::run(Clipboard* clipboard) {
}
// Get the DUT detector:
auto detector = get_detector(m_DUT);
auto detector = get_dut();
// Loop over all tracks
for(auto& track : (*tracks)) {
......@@ -218,7 +217,7 @@ StatusCode CLICpix2Analysis::run(Clipboard* clipboard) {
double ymod = Units::convert(detector->inPixelY(localIntercept), "um");
// Get the DUT clusters from the clipboard
Clusters* clusters = (Clusters*)clipboard->get(m_DUT, "clusters");
Clusters* clusters = (Clusters*)clipboard->get(get_dut()->name(), "clusters");
if(clusters == NULL) {
LOG(DEBUG) << " - no DUT clusters";
} else {
......
......@@ -59,7 +59,6 @@ namespace corryvreckan {
TH2F* hUnassociatedTracksGlobalPosition;
// Member variables
std::string m_DUT;
double spatialCut, m_timeCutFrameEdge;
double chi2ndofCut;
};
......
......@@ -36,4 +36,3 @@ Analysis module for CLICpix2 prototypes. This module is still work in progress,
timeCutFrameEdge = 50ns
```
Parameters to be used in multiple algorithms can also be defined globally at the top of the configuration file. This is highly encouraged for parameters such as `DUT` and `reference`.
......@@ -9,8 +9,6 @@ CLICpixEventLoader::CLICpixEventLoader(Configuration config, std::vector<Detecto
}
void CLICpixEventLoader::initialise() {
// Assume that the CLICpix is the DUT (if running this algorithm
detectorID = m_config.get<std::string>("DUT");
// File structure is RunX/CLICpix/RunX.dat
// Take input directory from global parameters
......@@ -50,7 +48,8 @@ void CLICpixEventLoader::initialise() {
StatusCode CLICpixEventLoader::run(Clipboard* clipboard) {
// LOG(TRACE) <<"Running"
// Assume that the CLICpix is the DUT (if running this algorithm
auto detector = get_dut();
// If have reached the end of file, close it and exit program running
if(m_file.eof()) {
......@@ -62,7 +61,7 @@ StatusCode CLICpixEventLoader::run(Clipboard* clipboard) {
// Pixel container, shutter information
Pixels* pixels = new Pixels();
long double shutterStartTime, shutterStopTime;
long double shutterStartTime = 0, shutterStopTime = 0;
string data;
int npixels = 0;
......@@ -109,9 +108,9 @@ StatusCode CLICpixEventLoader::run(Clipboard* clipboard) {
LOG(TRACE) << "New pixel: " << col << "," << row << " with tot " << tot;
// If this pixel is masked, do not save it
if(get_detector(detectorID)->masked(col, row))
if(detector->masked(col, row))
continue;
Pixel* pixel = new Pixel(detectorID, row, col, tot, 0);
Pixel* pixel = new Pixel(detector->name(), row, col, tot, 0);
pixels->push_back(pixel);
npixels++;
hHitMap->Fill(col, row);
......@@ -126,7 +125,7 @@ StatusCode CLICpixEventLoader::run(Clipboard* clipboard) {
LOG(TRACE) << "Loaded " << npixels << " pixels";
// Put the data on the clipboard
if(pixels->size() > 0)
clipboard->put(detectorID, "pixels", (Objects*)pixels);
clipboard->put(detector->name(), "pixels", (Objects*)pixels);
// Fill histograms
hPixelsPerFrame->Fill(npixels);
......
......@@ -32,7 +32,6 @@ namespace corryvreckan {
// Member variables
int m_eventNumber;
std::string m_filename;
std::string detectorID;
std::ifstream m_file;
TH2F* hHitMap;
......
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