Commit 291bbd2b authored by Simon Spannagel's avatar Simon Spannagel
Browse files

Merge branch 'master' into clicpix2-analysis

parents 7d8ecbd4 6890bf4d
......@@ -47,7 +47,7 @@ Corryvreckan has been developed and is maintained by
The following authors, in alphabetical order, have contributed to Corryvreckan:
* Matthew Daniel Buckland, University of Glasgow, @mbucklan
* Matthew Daniel Buckland, University of Liverpool, @mbucklan
* Adrian Fiergolski, CERN, @afiergol
* Andreas Matthias Nürnberg, CERN, @nurnberg
* Florian Pitters, CERN, @fpipper
......
......@@ -42,13 +42,17 @@
% Command to add all modules
\newcommand{\includemodulesmd}{\def\temp{@CORRYVRECKAN_MODULE_FILES@}\ifx\temp\empty
\textit{Module documentation not added because Markdown to LaTex conversion was not possible}
\textit{Module documentation not added because Markdown to \LaTeX~conversion was not possible. Pandoc is required for the conversion.}
\else
\foreach \n in @CORRYVRECKAN_MODULE_FILES@ {\input{\n}}
\fi}
% Command to add a single converted markdown file
\newcommand{\inputmd}[1]{\input{md/#1}}
\newcommand{\inputmd}[1]{\def\temp{@other_tex_files@}\ifx\temp\empty
\textit{This section is missing Markdown to \LaTeX~conversion was not possible. Pandoc is required for the conversion.}
\else
\input{md/#1}
\fi}
% Set bibliography
\addbibresource{usermanual/references.bib}
......
......@@ -11,7 +11,13 @@ ATLASpixEventLoader::ATLASpixEventLoader(Configuration config, std::vector<Detec
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");
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"));
// Allow reading of legacy data format using the Karlsruhe readout system:
m_legacyFormat = m_config.get<bool>("legacyFormat", false);
m_startTime = m_config.get<double>("startTime", 0.);
m_toaMode = m_config.get<bool>("toaMode", false);
......@@ -22,7 +28,7 @@ void ATLASpixEventLoader::initialise() {
// File structure is RunX/ATLASpix/data.dat
// Assume that the ATLASpix is the DUT (if running this algorithm
string detectorID = m_config.get<std::string>("DUT");
m_detectorID = m_config.get<std::string>("DUT");
// Open the root directory
DIR* directory = opendir(m_inputDirectory.c_str());
......@@ -43,8 +49,11 @@ void ATLASpixEventLoader::initialise() {
}
// If no data was loaded, give a warning
if(m_filename.length() == 0)
if(m_filename.length() == 0) {
LOG(WARNING) << "No data file was found for ATLASpix in " << m_inputDirectory;
} else {
LOG(STATUS) << "Opened data file for ATLASpix: " << m_filename;
}
// Open the data file for later
m_file.open(m_filename.c_str());
......@@ -54,27 +63,31 @@ void ATLASpixEventLoader::initialise() {
std::getline(m_file, headerline);
// Make histograms for debugging
hHitMap = new TH2F("hitMap", "hitMap", 128, 0, 128, 400, 0, 400);
auto det = get_detector(m_detectorID);
hHitMap = new TH2F("hitMap", "hitMap", det->nPixelsX(), 0, det->nPixelsX(), det->nPixelsY(), 0, det->nPixelsY());
hPixelToT = new TH1F("pixelToT", "pixelToT", 100, 0, 100);
hPixelToTCal = new TH1F("pixelToTCal", "pixelToT", 100, 0, 100);
hPixelToA = new TH1F("pixelToA", "pixelToA", 100, 0, 100);
hPixelsPerFrame = new TH1F("pixelsPerFrame", "pixelsPerFrame", 200, 0, 200);
hPixelsOverTime = new TH1F("pixelsOverTime", "pixelsOverTime", 2e6, 0, 2e6);
// Read calibration:
m_calibrationFactors.resize(25 * 400, 1.0);
std::ifstream calibration(m_calibrationFile);
std::string line;
std::getline(calibration, line);
int col, row;
double calibfactor;
while(getline(calibration, line)) {
std::istringstream(line) >> col >> row >> calibfactor;
m_calibrationFactors.at(row * 25 + col) = calibfactor;
m_calibrationFactors.resize(det->nPixelsX() * det->nPixelsY(), 1.0);
if(!m_calibrationFile.empty()) {
std::ifstream calibration(m_calibrationFile);
std::string line;
std::getline(calibration, line);
int col, row;
double calibfactor;
while(getline(calibration, line)) {
std::istringstream(line) >> col >> row >> calibfactor;
m_calibrationFactors.at(row * 25 + col) = calibfactor;
}
calibration.close();
}
calibration.close();
LOG(INFO) << "Timewalk corrtion factors: ";
LOG(INFO) << "Timewalk correction factors: ";
for(auto& ts : m_timewalkCorrectionFactors) {
LOG(INFO) << ts;
}
......@@ -96,6 +109,106 @@ StatusCode ATLASpixEventLoader::run(Clipboard* clipboard) {
return Failure;
}
double current_time = clipboard->get_persistent("currentTime");
// Read pixel data
Pixels* pixels = (m_legacyFormat ? read_legacy_data(current_time) : read_caribou_data(current_time));
for(auto px : (*pixels)) {
hHitMap->Fill(px->column(), px->row());
hPixelToT->Fill(px->tot());
hPixelToTCal->Fill(px->charge());
hPixelToA->Fill(px->timestamp());
// Pixels per 100us:
hPixelsOverTime->Fill(Units::convert(px->timestamp(), "ms"));
}
// Put the data on the clipboard
if(!pixels->empty()) {
clipboard->put(m_detectorID, "pixels", (Objects*)pixels);
}
// 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) {
// Pixel container
Pixels* pixels = new Pixels();
// Detector we're looking at:
auto detector = get_detector(m_detectorID);
// 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);
std::string identifier;
line >> identifier;
m_identifiers[identifier]++;
if(identifier == "WEIRD_DATA") {
continue;
} else if(identifier == "TRIGGER") {
int id, cnt;
line >> id >> cnt;
LOG(DEBUG) << "Trigger at " << cnt;
} else if(identifier == "HIT") {
// Read columns form file
std::string scol, srow, sts1, sts2, stot, sfpga_ts, str_cnt, sbin_cnt;
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);
// 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)) {
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"}) << ")";
// Rewind to previous position:
m_file.seekg(oldpos);
break;
}
// If this pixel is masked, do not save it
if(detector->masked(col, row)) {
continue;
}
Pixel* pixel = new Pixel(m_detectorID, row, col, tot, timestamp);
LOG(DEBUG) << *pixel;
pixels->push_back(pixel);
} else {
LOG(DEBUG) << "Unknown identifier \"" << identifier << "\"";
}
// Store this position in the file in case we need to rewind:
oldpos = m_file.tellg();
}
return pixels;
}
Pixels* ATLASpixEventLoader::read_legacy_data(double) {
// Pixel container
Pixels* pixels = new Pixels();
......@@ -107,7 +220,7 @@ StatusCode ATLASpixEventLoader::run(Clipboard* clipboard) {
m_file >> col >> row >> ts >> tot >> dummy >> dummy >> bincounter >> TriggerDebugTS;
auto detector = get_detector(detectorID);
auto detector = get_detector(m_detectorID);
// If this pixel is masked, do not save it
if(detector->masked(col, row)) {
continue;
......@@ -160,26 +273,19 @@ StatusCode ATLASpixEventLoader::run(Clipboard* clipboard) {
// Convert TOA to nanoseconds:
toa /= (4096. * 0.04);
Pixel* pixel = new Pixel(detectorID, row, col, cal_tot, toa);
Pixel* pixel = new Pixel(m_detectorID, row, col, cal_tot, toa);
pixel->setCharge(cal_tot);
pixels->push_back(pixel);
hHitMap->Fill(col, row);
hPixelToT->Fill(tot);
hPixelToTCal->Fill(cal_tot);
hPixelToA->Fill(toa);
}
// Put the data on the clipboard
if(pixels->size() > 0)
clipboard->put(detectorID, "pixels", (Objects*)pixels);
// Fill histograms
hPixelsPerFrame->Fill(pixels->size());
// Return value telling analysis to keep running
return Success;
return pixels;
}
void ATLASpixEventLoader::finalise() {
LOG(DEBUG) << "Analysed " << m_eventNumber << " events";
LOG(INFO) << "Identifier distribution:";
for(auto id : m_identifiers) {
LOG(INFO) << "\t" << id.first << ": " << id.second;
}
}
......@@ -30,11 +30,16 @@ namespace corryvreckan {
StatusCode run(Clipboard* clipboard);
void finalise();
// Histograms for several devices
std::map<std::string, TH2F*> plotPerDevice;
private:
/*
* @brief Read data in the format written by the Karlsruhe readout system
*/
Pixels* read_legacy_data(double current_time);
// Single histograms
TH1F* singlePlot;
/*
* @brief Read data in the format written by the Caribou readout system
*/
Pixels* read_caribou_data(double current_time);
// Member variables
int m_eventNumber;
......@@ -50,6 +55,7 @@ namespace corryvreckan {
TH1F* hPixelToTCal;
TH1F* hPixelToA;
TH1F* hPixelsPerFrame;
TH1F* hPixelsOverTime;
// Parameters:
std::vector<double> m_timewalkCorrectionFactors;
......@@ -60,6 +66,11 @@ namespace corryvreckan {
double m_eventLength;
double m_startTime;
bool m_toaMode;
std::string m_detectorID;
bool m_legacyFormat;
int m_clockCycle;
std::map<std::string, int> m_identifiers;
};
} // namespace corryvreckan
#endif // ATLASpixEventLoader_H
......@@ -100,6 +100,7 @@ void FileReader::initialise() {
}
}
LOG(STATUS) << "Successfully opened data file \"" << m_fileName << "\"";
// Initialise member variables
m_eventNumber = 0;
}
......
......@@ -27,7 +27,6 @@ ROOT_GENERATE_DICTIONARY(CorryvreckanObjectsDictionary
LINKDEF
${CMAKE_CURRENT_SOURCE_DIR}/Linkdef.h
OPTIONS
-Wno-inconsistent-missing-override
-inlineInputHeader
-I${CMAKE_CURRENT_SOURCE_DIR}
MODULE
......@@ -50,6 +49,7 @@ ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/CorryvreckanObjectsDiction
# Define the library adding the object file created above
ADD_LIBRARY(CorryvreckanObjects SHARED
Object.cpp
Pixel.cpp
${CMAKE_CURRENT_BINARY_DIR}/CorryvreckanObjectsDictionary.cxx.o
)
......
// local
#include "Object.hpp"
#include "Cluster.h"
#include "MCParticle.h"
......@@ -38,3 +37,8 @@ Object* Object::Factory(std::string detectorType, std::string objectType, Object
return new Object();
}
std::ostream& corryvreckan::operator<<(std::ostream& out, const Object& obj) {
obj.print(out);
return out;
}
......@@ -15,6 +15,7 @@
#ifndef CORRYVRECKAN_OBJECT_H
#define CORRYVRECKAN_OBJECT_H
#include <iostream>
#include <string>
#include <vector>
#include "TObject.h"
......@@ -31,18 +32,26 @@ namespace corryvreckan {
class Object : public TObject {
public:
// Constructors and destructors
friend std::ostream& operator<<(std::ostream& out, const corryvreckan::Object& obj);
/**
* @brief Required default constructor
*/
Object();
explicit Object(std::string detectorID);
explicit Object(double timestamp);
Object(std::string detectorID, double timestamp);
/**
* @brief Required virtual destructor
*/
~Object() override;
// Methods to get member variables
std::string getDetectorID() { return m_detectorID; }
std::string getDetectorID() const { return m_detectorID; }
std::string detectorID() { return getDetectorID(); }
double timestamp() { return m_timestamp; }
double timestamp() const { return m_timestamp; }
void timestamp(double time) { m_timestamp = time; }
void setTimestamp(double time) { timestamp(time); }
......@@ -53,15 +62,40 @@ namespace corryvreckan {
static Object* Factory(std::string, Object* object = NULL);
static Object* Factory(std::string, std::string, Object* object = NULL);
/**
* @brief ROOT class definition
*/
ClassDefOverride(Object, 3);
protected:
// Member variables
std::string m_detectorID;
double m_timestamp{0};
// ROOT I/O class definition - update version number when you change this class!
ClassDefOverride(Object, 2)
/**
* @brief Print an ASCII representation of this Object to the given stream
* @param out Stream to print to
*/
virtual void print(std::ostream& out) const { out << "<unknown object>"; };
/**
* @brief Override function to implement ROOT Print()
* @warning Should not be used inside the framework but might assist in inspecting ROOT files with these objects.
*/
void Print(Option_t*) const override {
print(std::cout);
std::cout << std::endl;
}
};
/**
* @brief Overloaded ostream operator for printing of object data
* @param out Stream to write output to
* @param obj Object to print to stream
* @return Stream where output was written to
*/
std::ostream& operator<<(std::ostream& out, const corryvreckan::Object& obj);
// Vector type declaration
using Objects = std::vector<Object*>;
} // namespace corryvreckan
......
#include "Pixel.h"
using namespace corryvreckan;
void Pixel::print(std::ostream& out) const {
out << "Pixel " << this->column() << ", " << this->row() << ", " << this->adc() << ", " << this->timestamp();
}
......@@ -15,14 +15,25 @@ namespace corryvreckan {
Pixel(std::string detectorID, int row, int col, int tot, double timestamp)
: Object(detectorID, timestamp), m_row(row), m_column(col), m_adc(tot), m_charge(tot) {}
int row() { return m_row; }
int column() { return m_column; }
int row() const { return m_row; }
int column() const { return m_column; }
int adc() { return m_adc; }
int tot() { return adc(); }
int adc() const { return m_adc; }
int tot() const { return adc(); }
double charge() const { return m_charge; }
void setCharge(double charge) { m_charge = charge; }
double charge() { return m_charge; }
/**
* @brief Print an ASCII representation of Pixel to the given stream
* @param out Stream to print to
*/
void print(std::ostream& out) const override;
/**
* @brief ROOT class definition
*/
ClassDefOverride(Pixel, 3);
private:
// Member variables
......@@ -31,9 +42,6 @@ namespace corryvreckan {
int m_adc;
double m_charge;
// ROOT I/O class definition - update version number when you change this class!
ClassDef(Pixel, 3)
};
// Vector type declaration
......
Supports Markdown
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