Commit 5cd6c1a3 authored by Simon Spannagel's avatar Simon Spannagel
Browse files

Merge branch 'tlu-apx-sync' into 'master'

Bug fixes + improvements in EventLoader

See merge request !119
parents 00d47552 6de3ba3b
Pipeline #956092 failed with stages
in 60 minutes
......@@ -148,13 +148,15 @@ void EventLoaderATLASpix::initialise() {
hPixelCharge = new TH1F("pixelCharge", "pixelCharge; pixel charge [e]; # events", 100, 0, 100);
hPixelToA = new TH1F("pixelToA", "pixelToA; pixel ToA [ns]; # events", 100, 0, 100);
hPixelsPerFrame = new TH1F("pixelsPerFrame", "pixelsPerFrame; pixels per frame; # events", 200, 0, 200);
hPixelsOverTime = new TH1F("pixelsOverTime", "pixelsOverTime; time [ms]; # events", 2e6, 0, 2e6);
hPixelsOverTime = new TH1F("pixelsOverTime", "pixelsOverTime; time [ns]; # events", 3e6, 0, 3e9);
hPixelTS1 = new TH1F("pixelTS1", "pixelTS1; pixel TS1 [lsb]; # events", 2050, 0, 2050);
hPixelTS2 = new TH1F("pixelTS2", "pixelTS2; pixel TS2 [lsb]; # events", 130, 0, 130);
hPixelTS1bits = new TH1F("pixelTS1bits", "pixelTS1bits; pixel TS1 bit [lsb->msb]; # events", 12, 0, 12);
hPixelTS2bits = new TH1F("pixelTS2bits", "pixelTS2bits; pixel TS2 bit [lsb->msb]; # events", 8, 0, 8);
hTriggersPerEvent = new TH1D("hTriggersPerEvent", "hTriggersPerEvent;triggers per event;entries", 20, 0, 20);
// low ToT:
hPixelTS1_lowToT = new TH1F("pixelTS1_lowToT", "pixelTS1_lowToT; pixel TS1 [lsb]; # events", 2050, 0, 2050);
hPixelTS2_lowToT = new TH1F("pixelTS2_lowToT", "pixelTS2_lowToT; pixel TS2 [lsb]; # events", 130, 0, 130);
......@@ -171,6 +173,21 @@ void EventLoaderATLASpix::initialise() {
hPixelTS2bits_highToT =
new TH1F("pixelTS2bits_highToT", "pixelTS2bits_highToT; pixel TS2 bit [lsb->msb]; # events", 8, 0, 8);
hPixelTimeEventBeginResidual = new TH1F("hPixelTimeEventBeginResidual",
"hPixelTimeEventBeginResidual;pixel_ts - clipboard event begin [us]; # entries",
2.1e5,
-10,
200);
hPixelTimeEventBeginResidualOverTime =
new TH2F("hPixelTimeEventBeginResidualOverTime",
"hPixelTimeEventBeginResidualOverTime; pixel time [s];pixel_ts - clipboard event begin [us]",
3e3,
0,
3e3,
2.1e4,
-10,
200);
// Read calibration:
m_calibrationFactors.resize(static_cast<size_t>(m_detector->nPixels().X() * m_detector->nPixels().Y()), 1.0);
if(!m_calibrationFile.empty()) {
......@@ -217,6 +234,11 @@ StatusCode EventLoaderATLASpix::run(std::shared_ptr<Clipboard> clipboard) {
return StatusCode::DeadTime;
}
// Here fill some histograms for data quality monitoring:
auto nTriggers = event->triggerList().size();
LOG(DEBUG) << "nTriggers = " << nTriggers;
hTriggersPerEvent->Fill(static_cast<double>(nTriggers));
for(auto px : (*pixels)) {
hHitMap->Fill(px->column(), px->row());
if(px->raw() > m_highToTCut) {
......@@ -227,11 +249,34 @@ StatusCode EventLoaderATLASpix::run(std::shared_ptr<Clipboard> clipboard) {
hPixelCharge->Fill(px->charge());
hPixelToA->Fill(px->timestamp());
// Pixels per 100us:
hPixelsOverTime->Fill(static_cast<double>(Units::convert(px->timestamp(), "ms")));
hPixelTimeEventBeginResidual->Fill(static_cast<double>(Units::convert(px->timestamp() - start_time, "us")));
hPixelTimeEventBeginResidualOverTime->Fill(static_cast<double>(Units::convert(px->timestamp(), "s")),
static_cast<double>(Units::convert(px->timestamp() - start_time, "us")));
size_t iTrigger = 0;
for(auto& trigger : event->triggerList()) {
// check if histogram exists already, if not: create it
if(hPixelTriggerTimeResidual.find(iTrigger) == hPixelTriggerTimeResidual.end()) {
std::string histName = "hPixelTriggerTimeResidual_" + to_string(iTrigger);
std::string histTitle = histName + ";trigger_ts - pixel_ts [us];# entries";
hPixelTriggerTimeResidual[iTrigger] = new TH1D(histName.c_str(), histTitle.c_str(), 2e5, -100, 100);
}
if(hPixelTriggerTimeResidualOverTime.find(iTrigger) == hPixelTriggerTimeResidualOverTime.end()) {
std::string histName = "hPixelTriggerTimeResidualOverTime_" + to_string(iTrigger);
std::string histTitle = histName + ";time [us];trigger_ts - pixel_ts [us];# entries";
hPixelTriggerTimeResidualOverTime[iTrigger] =
new TH2D(histName.c_str(), histTitle.c_str(), 3e3, 0, 3e3, 1e4, -50, 50);
}
// use iTrigger, not trigger ID (=trigger.first) (which is unique and continuously incrementing over the runtime)
hPixelTriggerTimeResidual[iTrigger]->Fill(
static_cast<double>(Units::convert(px->timestamp() - trigger.second, "us")));
hPixelTriggerTimeResidualOverTime[iTrigger]->Fill(
static_cast<double>(Units::convert(px->timestamp(), "s")),
static_cast<double>(Units::convert(px->timestamp() - trigger.second, "us")));
iTrigger++;
}
hPixelsOverTime->Fill(static_cast<double>(Units::convert(px->timestamp(), "ns")));
}
// Fill histograms
hPixelsPerFrame->Fill(static_cast<double>(pixels->size()));
// Put the data on the clipboard
......
......@@ -68,6 +68,13 @@ namespace corryvreckan {
TH1F* hPixelToT_beforeCorrection;
TH1F* hPixelCharge;
TH1F* hPixelToA;
TH1F* hPixelTimeEventBeginResidual;
TH2F* hPixelTimeEventBeginResidualOverTime;
std::map<size_t, TH1D*> hPixelTriggerTimeResidual;
std::map<size_t, TH2D*> hPixelTriggerTimeResidualOverTime;
TH1D* hTriggersPerEvent;
TH1F* hPixelsPerFrame;
TH1F* hPixelsOverTime;
......
......@@ -16,12 +16,32 @@ This module requires either another event loader of another detector type before
* `clock_cycle`: Period of the clock used to count the trigger timestamps in, defaults to `6.25ns`.
* `legacy_format`: Set `true` if using legacy data format of the Karlsruhe readout system. Default is `false`, corresponding the the format of the Caribou readout system.
* `clkdivend2`: Value of clkdivend2 register in ATLASPix specifying the speed of TS2 counter. Default is `0`.
* `high_tot_cut`: "high ToT" histograms are filled if pixel ToT is larger than this cut. Default is `40`.
* `calibration_file` (optional): input file for pixel-wise calibration from ToT to charge in electrons. If not provided, the pixel charge is equivalent to pixel ToT.
### Plots produced
* 2D Hit map
* 1D Pixel ToT histogram
* 1D Pixels per frame histogram
* 2D hit map
* 2D hit map for high ToT events (ToT>high_tot_cut)
* 2D ToT-weighted hit map
* 1D pixel ToT histogram
* 1D pixel ToT histogram before timestamp overflow correction
* 1D pixels charge histogram (currently not calibrated -> equivalent to ToT)
* 1D pixel ToA histogram
* 1D pixels per frame histogram
* 1D pixels over time histogram
* 1D pixel TS1 histogram
* 1D pixel TS2 histogram
* 1D pixel TS1 bits histogram
* 1D pixel TS2 bits histogram
* 1D pixel TS1 histogram for high ToT events (ToT>high_tot_cut)
* 1D pixel TS2 histogram for high ToT events (ToT>high_tot_cut)
* 1D pixel TS1 bits histogram for high ToT events (ToT>high_tot_cut)
* 1D pixel TS2 bits histogram for high ToT events (ToT>high_tot_cut)
* 1D trigger per event histogram
* 1D pixel time minus event begin residual histogram
* 2D pixel time minus event begin residual over time histogram
* map of all available 1D pixel time minus trigger time residual histograms
* map of all available 2D pixel time minus trigger time residual over time histograms
### Usage
```toml
......
......@@ -48,7 +48,7 @@ void EventLoaderEUDAQ2::initialise() {
m_detector->nPixels().Y());
title = ";hit timestamp [ns]; # events";
hHitTimes = new TH1F("hitTimes", title.c_str(), 3e6, 0, 3e12);
hHitTimes = new TH1F("hitTimes", title.c_str(), 3e6, 0, 3e9);
title = "pixel raw values";
hPixelRawValues = new TH1F("hPixelRawValues", title.c_str(), 1024, 0, 1024);
......@@ -57,10 +57,37 @@ void EventLoaderEUDAQ2::initialise() {
hPixelsPerEvent = new TH1F("pixelsPerFrame", title.c_str(), 1000, 0, 1000);
title = ";EUDAQ event start time[ns];# entries";
hEudaqEventStart = new TH1D("eudaqEventStart", title.c_str(), 1e6, 0, 1e9);
hEudaqEventStart = new TH1D("eudaqEventStart", title.c_str(), 3e6, 0, 3e9);
title = "Corryvreckan event start times (on clipboard); Corryvreckan event start time [ns];# entries";
hClipboardEventStart = new TH1D("clipboardEventStart", title.c_str(), 1e6, 0, 1e9);
hClipboardEventStart = new TH1D("clipboardEventStart", title.c_str(), 3e6, 0, 3e9);
title = "Corryvreckan event end times (on clipboard); Corryvreckan event end time [ns];# entries";
hClipboardEventEnd = new TH1D("clipboardEventEnd", title.c_str(), 3e6, 0, 3e9);
title = "Corryvreckan event end times (on clipboard); Corryvreckan event end time [ns];# entries";
hClipboardEventDuration = new TH1D("clipboardEventDuration", title.c_str(), 3e6, 0, 3e9);
hPixelTimeEventBeginResidual = new TH1F("hPixelTimeEventBeginResidual",
"hPixelTimeEventBeginResidual;pixel_ts - clipboard event begin [us]; # entries",
2.1e5,
-10,
200);
hPixelTimeEventBeginResidualOverTime =
new TH2F("hPixelTimeEventBeginResidualOverTime",
"hPixelTimeEventBeginResidualOverTime; pixel time [s];pixel_ts - clipboard event begin [us]",
3e3,
0,
3e3,
2.1e4,
-10,
200);
hTriggersPerEvent = new TH1D("hTriggersPerEvent", "hTriggersPerEvent;triggers per event;entries", 20, 0, 20);
std::string histTitle = "hPixelTriggerTimeResidualOverTime_0;time [us];trigger_ts - pixel_ts [us];# entries";
hPixelTriggerTimeResidualOverTime =
new TH2D("hPixelTriggerTimeResidualOverTime_0", histTitle.c_str(), 3e3, 0, 3e3, 1e4, -50, 50);
// open the input file with the eudaq reader
try {
......@@ -123,7 +150,7 @@ EventLoaderEUDAQ2::EventPosition EventLoaderEUDAQ2::is_within_event(std::shared_
std::shared_ptr<eudaq::StandardEvent> evt) {
// Check if this event has timestamps available:
if(evt->GetTimeBegin() == 0) {
if(evt->GetTimeBegin() <= std::numeric_limits<double>::epsilon()) {
LOG(DEBUG) << evt->GetDescription() << ": Event has no timestamp, comparing trigger number";
// If there is no event defined yet or the trigger number is unkown, there is little we can do:
......@@ -142,19 +169,13 @@ EventLoaderEUDAQ2::EventPosition EventLoaderEUDAQ2::is_within_event(std::shared_
double event_start = evt->GetTimeBegin();
double event_end = evt->GetTimeEnd();
LOG(DEBUG) << "event_start = " << Units::display(event_start, "us")
<< ", event_end = " << Units::display(event_end, "us");
// If adjustment of event start/end is required:
const auto it = std::find_if(adjust_event_times.begin(),
adjust_event_times.end(),
[evt](const std::vector<std::string>& x) { return x.front() == evt->GetDescription(); });
if(it != adjust_event_times.end()) {
double shift_start = corryvreckan::from_string<double>(it->at(1));
double shift_end = corryvreckan::from_string<double>(it->at(2));
event_start += shift_start;
event_end += shift_end;
LOG(DEBUG) << "Adjusting " << it->at(0) << ": event_start by " << Units::display(shift_start, {"us", "ns"})
<< ", event_end by " << Units::display(event_end, {"us", "ns"});
}
// Skip if later start is requested:
if(event_start < m_skip_time) {
......@@ -163,34 +184,55 @@ EventLoaderEUDAQ2::EventPosition EventLoaderEUDAQ2::is_within_event(std::shared_
return EventPosition::BEFORE;
}
double shift_start = 0;
double shift_end = 0;
if(!clipboard->event_defined()) {
LOG(DEBUG) << "Defining Corryvreckan event: " << Units::display(event_start, {"us", "ns"}) << " - "
<< Units::display(event_end, {"us", "ns"}) << ", length "
<< Units::display(event_end - event_start, {"us", "ns"});
if(it != adjust_event_times.end()) {
shift_start = corryvreckan::from_string<double>(it->at(1));
shift_end = corryvreckan::from_string<double>(it->at(2));
event_start += shift_start;
event_end += shift_end;
LOG(DEBUG) << "Adjusting " << it->at(0) << ": event_start by " << Units::display(shift_start, {"us", "ns"})
<< ", event_end by " << Units::display(shift_end, {"us", "ns"});
}
LOG(DEBUG) << "Shifted Corryvreckan event: " << Units::display(event_start, {"us", "ns"}) << " - "
<< Units::display(event_end, {"us", "ns"}) << ", length "
<< Units::display(event_end - event_start, {"us", "ns"});
clipboard->put_event(std::make_shared<Event>(event_start, event_end));
} else {
LOG(DEBUG) << "Corryvreckan event found on clipboard.";
}
double clipboard_start = clipboard->get_event()->start();
double clipboard_end = clipboard->get_event()->end();
if(event_start < clipboard_start) {
// if(event_start < clipboard_start) { // we still need to discuss about the logic here!
if(event_end < clipboard_start) {
LOG(DEBUG) << "Event start before Corryvreckan event: " << Units::display(event_start, {"us", "ns"}) << " < "
<< Units::display(clipboard_start, {"us", "ns"});
return EventPosition::BEFORE;
} else if(clipboard_end < event_end) {
// } else if(clipboard_end < event_end) { // we still need to discuss about the logic here!
} else if(clipboard_end < event_start) {
LOG(DEBUG) << "Event end after Corryvreckan event: " << Units::display(event_end, {"us", "ns"}) << " > "
<< Units::display(clipboard_end, {"us", "ns"});
return EventPosition::AFTER;
} else {
// Store potential trigger numbers, assign to center of event:
clipboard->get_event()->addTrigger(evt->GetTriggerN(), (event_start + event_start) / 2);
LOG(DEBUG) << "Stored trigger ID " << evt->GetTriggerN() << " at "
<< Units::display((event_start + event_start) / 2, {"us", "ns"});
// check if event has valid trigger ID (flag = 0x10):
if(evt->IsFlagTrigger()) {
// Store potential trigger numbers, assign to center of event:
clipboard->get_event()->addTrigger(evt->GetTriggerN(), event_start - shift_start);
LOG(DEBUG) << "Stored trigger ID " << evt->GetTriggerN() << " at "
<< Units::display(event_start - shift_start, {"us", "ns"});
}
return EventPosition::DURING;
}
}
void EventLoaderEUDAQ2::store_data(std::shared_ptr<Clipboard> clipboard, std::shared_ptr<eudaq::StandardEvent> evt) {
Pixels* EventLoaderEUDAQ2::get_pixel_data(std::shared_ptr<eudaq::StandardEvent> evt) {
Pixels* pixels = new Pixels();
......@@ -201,14 +243,14 @@ void EventLoaderEUDAQ2::store_data(std::shared_ptr<Clipboard> clipboard, std::sh
// Concatenate plane name according to naming convention: sensor_type + "_" + int
auto plane_name = plane.Sensor() + "_" + std::to_string(plane.ID());
auto detector_name = m_detector->name();
// LOG(DEBUG) << plane_name <<", "<<detector_name;
// Convert to lower case before string comparison to avoid errors by the user:
std::transform(plane_name.begin(), plane_name.end(), plane_name.begin(), ::tolower);
std::transform(detector_name.begin(), detector_name.end(), detector_name.begin(), ::tolower);
LOG(TRACE) << plane_name << " with " << plane.HitPixels() << " hit pixels";
LOG(TRACE) << plane_name << " (" << i_plane << " out of " << evt->NumPlanes() << ") with " << plane.HitPixels()
<< " hit pixels";
if(detector_name != plane_name) {
LOG(DEBUG) << "Wrong plane: " << detector_name << "!=" << plane_name << ". Continue.";
LOG(TRACE) << "Wrong plane: " << detector_name << "!=" << plane_name << ". Continue.";
continue;
}
......@@ -222,6 +264,7 @@ void EventLoaderEUDAQ2::store_data(std::shared_ptr<Clipboard> clipboard, std::sh
LOG(DEBUG) << "Read pixel (col, row) = (" << col << ", " << row << ") from EUDAQ2 event data (before masking).";
if(m_detector->masked(col, row)) {
LOG(TRACE) << "Masked pixel (col, row) = (" << col << ", " << row << ")";
continue;
}
......@@ -231,21 +274,20 @@ void EventLoaderEUDAQ2::store_data(std::shared_ptr<Clipboard> clipboard, std::sh
hitmap->Fill(col, row);
hHitTimes->Fill(ts);
hPixelRawValues->Fill(raw);
pixels->push_back(pixel);
}
hPixelsPerEvent->Fill(static_cast<int>(pixels->size()));
LOG(DEBUG) << m_detector->name() << ": Plane contains " << pixels->size() << " pixels";
}
if(!pixels->empty()) {
LOG(DEBUG) << "Detector " << m_detector->name() << " has " << pixels->size() << " pixels";
clipboard->put(m_detector->name(), "pixels", reinterpret_cast<Objects*>(pixels));
} else {
delete pixels;
}
return pixels;
}
StatusCode EventLoaderEUDAQ2::run(std::shared_ptr<Clipboard> clipboard) {
Pixels* pixels = new Pixels();
EventPosition current_position = EventPosition::UNKNOWN;
while(1) {
// Retrieve next event from file/buffer:
......@@ -261,9 +303,11 @@ StatusCode EventLoaderEUDAQ2::run(std::shared_ptr<Clipboard> clipboard) {
current_position = is_within_event(clipboard, event_);
if(current_position == EventPosition::DURING) {
LOG(DEBUG) << "Is within current event, storing data";
LOG(DEBUG) << "Is within current Corryvreckan event, storing data";
// Store data on the clipboard
store_data(clipboard, event_);
auto new_pixels = get_pixel_data(event_);
pixels->insert(pixels->end(), new_pixels->begin(), new_pixels->end());
delete new_pixels;
}
// If this event was after the current event, stop reading:
......@@ -274,13 +318,55 @@ StatusCode EventLoaderEUDAQ2::run(std::shared_ptr<Clipboard> clipboard) {
// Do not fill if current_position == EventPosition::AFTER to avoid double-counting!
hEudaqEventStart->Fill(event_->GetTimeBegin());
if(clipboard->event_defined()) {
hClipboardEventStart->Fill(clipboard->get_event()->start());
hClipboardEventStart->Fill(static_cast<double>(Units::convert(clipboard->get_event()->start(), "ns")));
hClipboardEventEnd->Fill(static_cast<double>(Units::convert(clipboard->get_event()->end(), "ns")));
hClipboardEventDuration->Fill(
static_cast<double>(Units::convert(clipboard->get_event()->end() - clipboard->get_event()->start(), "ns")));
}
// Reset this event to get a new one:
event_.reset();
}
auto event = clipboard->get_event();
auto nTriggers = event->triggerList().size();
LOG(DEBUG) << "nTriggers = " << nTriggers;
for(auto& trigger : event->triggerList()) {
LOG(DEBUG) << "triggerID: " << trigger.first << ", trigger time: " << Units::display(trigger.second, "us");
}
hTriggersPerEvent->Fill(static_cast<double>(nTriggers));
// Loop over pixels for plotting
for(auto& pixel : (*pixels)) {
hPixelTimeEventBeginResidual->Fill(static_cast<double>(Units::convert(pixel->timestamp() - event->start(), "us")));
hPixelTimeEventBeginResidualOverTime->Fill(
static_cast<double>(Units::convert(pixel->timestamp(), "s")),
static_cast<double>(Units::convert(pixel->timestamp() - event->start(), "us")));
size_t iTrigger = 0;
for(auto& trigger : event->triggerList()) {
// check if histogram exists already, if not: create it
if(hPixelTriggerTimeResidual.find(iTrigger) == hPixelTriggerTimeResidual.end()) {
std::string histName = "hPixelTriggerTimeResidual_" + to_string(iTrigger);
std::string histTitle = histName + ";trigger_ts - pixel_ts [us];# entries";
hPixelTriggerTimeResidual[iTrigger] = new TH1D(histName.c_str(), histTitle.c_str(), 2e5, -100, 100);
}
// use iTrigger, not trigger ID (=trigger.first) (which is unique and continuously incrementing over the runtime)
hPixelTriggerTimeResidual[iTrigger]->Fill(
static_cast<double>(Units::convert(pixel->timestamp() - trigger.second, "us")));
if(iTrigger == 0) { // fill only for 0th trigger
hPixelTriggerTimeResidualOverTime->Fill(
static_cast<double>(Units::convert(pixel->timestamp(), "s")),
static_cast<double>(Units::convert(pixel->timestamp() - trigger.second, "us")));
}
iTrigger++;
}
}
// Store the full event data on the clipboard:
clipboard->put(m_detector->name(), "pixels", reinterpret_cast<Objects*>(pixels));
LOG(DEBUG) << "Finished Corryvreckan event";
return StatusCode::Success;
}
......@@ -74,10 +74,10 @@ namespace corryvreckan {
/**
* @brief Store pixel data from relevant detectors on the clipboard
* @param clipboard Shared pointer to the event clipboard
* @param evt StandardEvent to read the pixel data from
* @return Vector of pointers to pixels read from this event
*/
void store_data(std::shared_ptr<Clipboard> clipboard, std::shared_ptr<eudaq::StandardEvent> evt);
Pixels* get_pixel_data(std::shared_ptr<eudaq::StandardEvent> evt);
std::shared_ptr<Detector> m_detector;
std::string m_filename{};
......@@ -103,6 +103,15 @@ namespace corryvreckan {
TH1F* hPixelsPerEvent;
TH1D* hEudaqEventStart;
TH1D* hClipboardEventStart;
TH1D* hClipboardEventEnd;
TH1D* hClipboardEventDuration;
TH1F* hPixelTimeEventBeginResidual;
TH2F* hPixelTimeEventBeginResidualOverTime;
std::map<size_t, TH1D*> hPixelTriggerTimeResidual;
TH2D* hPixelTriggerTimeResidualOverTime;
TH1D* hTriggersPerEvent;
};
} // namespace corryvreckan
......@@ -41,6 +41,7 @@ The decoder promises to
* not return any event before a possible T0 signal in the data.
* return the smallest possible granularity of data in time either as even or as sub-events within one event.
* always return valid event time stamps. If the device does not have timestamps, it should return zero for the beginning of the event and have a valid trigger number set.
* return events in a the correct time order
### Configuring EUDAQ2 Event Converters
......@@ -57,10 +58,18 @@ Also, more complex constructs such as arrays or matrices read by the Corryvrecka
### Plots produced
* 2D hitmap
* 1D pixel raw data histogram
* 1D pixel hit times
* 1D pixel raw value histogram (corresponds to chip-specific charge equivalent measurement, e.g. ToT)
* 1D pixels per event histogram
* 1D eudaq event start histogram
* 1D clipboard event start histogram
* 1D clipboard event end histogram
* 1D clipboard event duration histogram
* 1D pixel time minus event begin residual histogram
* 2D pixel time minus event begin residual over time histogram
* map of all available 1D pixel time minus trigger time residual histograms
* 2D pixel time minus trigger time residual over time histogram for 0th trigger
* 1D triggers per event histogram
### Usage
```toml
......
......@@ -19,12 +19,20 @@ For each device the following plots are produced:
* 2D hitmap
* 2D event times histogram
* Correlation in X
* Correlation between X(reference) and Y
* Correlation in Y
* 2D correlation in X in global coordinates
* 2D correlation in Y in global coordinates
* Correlation between Y(reference) and X
* 2D correlation in X in local coordinates
* 2D correlation in Y in local coordinates
* Correlation times (nanosecond binning) histogram, range covers 2 * event length
* 2D correlation between columns
* 2D correlation between columns(reference) and rows
* 2D correlation between rows
* 2D correlation between rows(reference) and columns
* 2D correlation in X in global coordinates
* 2D correlation in Y in global coordinates
* Correlation times (nanosecond binning) histogram, range covers 2 * `timing_cut`
* 2D correlation times over time histogram
* Correlation times (on pixel level, all other histograms take clusters)
* Correlation times (integer values) histogram
### Usage
......
......@@ -27,6 +27,15 @@ void TestAlgorithm::initialise() {
m_detector->nPixels().Y(),
0,
m_detector->nPixels().Y());
title = m_detector->name() + ": hitmap of clusters;x [px];y [px];events";
hitmap_clusters = new TH2F("hitmap_clusters",
title.c_str(),
m_detector->nPixels().X(),
0,
m_detector->nPixels().X(),
m_detector->nPixels().Y(),
0,
m_detector->nPixels().Y());
if(makeCorrelations) {
// Correlation plots
......@@ -34,11 +43,29 @@ void TestAlgorithm::initialise() {
correlationX = new TH1F("correlationX", title.c_str(), 1000, -10., 10.);
title = m_detector->name() + ": correlation Y;y_{ref}-y [mm];events";
correlationY = new TH1F("correlationY", title.c_str(), 1000, -10., 10.);
title = m_detector->name() + ": correlation XY;y_{ref}-x [mm];events";
correlationXY = new TH1F("correlationXY", title.c_str(), 1000, -10., 10.);
title = m_detector->name() + ": correlation YX;x_{ref}-y [mm];events";
correlationYX = new TH1F("correlationYX", title.c_str(), 1000, -10., 10.);
// time correlation plot range should cover length of events. nanosecond binning.
title = m_detector->name() + "Reference cluster time stamp - cluster time stamp;t_{ref}-t [ns];events";
correlationTime =
new TH1F("correlationTime", title.c_str(), static_cast<int>(2. * timingCut), -1 * timingCut, timingCut);
title =
m_detector->name() + "Reference cluster time stamp - cluster time stamp over time;t [s];t_{ref}-t [ns];events";
correlationTimeOverTime = new TH2F("correlationTimeOverTime",
title.c_str(),
3e3,
0,
3e3,
static_cast<int>(2. * timingCut),
-1 * timingCut,
timingCut);
title = m_detector->name() + "Reference pixel time stamp - pixel time stamp;t_{ref}-t [ns];events";
correlationTime_px =
new TH1F("correlationTime_px", title.c_str(), static_cast<int>(2. * timingCut), -1 * timingCut, timingCut);
title = m_detector->name() + "Reference cluster time stamp - cluster time stamp;t_{ref}-t [1/40MHz];events";
correlationTimeInt = new TH1F("correlationTimeInt", title.c_str(), 8000, -40000, 40000);
......@@ -61,6 +88,42 @@ void TestAlgorithm::initialise() {
reference->nPixels().Y(),
0,
reference->nPixels().Y());
title = m_detector->name() + ": correlation col to col;col [px];col_{ref} [px];events";
correlationColCol_px = new TH2F("correlationColCol_px",
title.c_str(),
m_detector->nPixels().X(),
0,
m_detector->nPixels().X(),
reference->nPixels().X(),
0,
reference->nPixels().X());
title = m_detector->name() + ": correlation col to row;col [px];row_{ref} [px];events";
correlationColRow_px = new TH2F("correlationColRow_px",
title.c_str(),
m_detector->nPixels().X(),
0,
m_detector->nPixels().X(),
reference->nPixels().Y(),
0,
reference->nPixels().Y());
title = m_detector->name() + ": correlation row to col;row [px];col_{ref} [px];events";
correlationRowCol_px = new TH2F("correlationRowCol_px",
title.c_str(),
m_detector->nPixels().Y(),
0,
m_detector->nPixels().Y(),
reference->nPixels().X(),
0,
reference->nPixels().X());
title = m_detector->name() + ": correlation row to row;row [px];row_{ref} [px];events";
correlationRowRow_px = new TH2F("correlationRowRow_px",
title.c_str(),
m_detector->nPixels().Y(),
0,
m_detector->nPixels().Y(),
reference->nPixels().Y(),
0,
reference->nPixels().Y());