9 #include <top/modules/collectors/TOPPulseHeightCollectorModule.h>
31 TOPPulseHeightCollectorModule::TOPPulseHeightCollectorModule()
34 setDescription(
"A collector for channel pulse-height distributions");
35 setPropertyFlags(c_ParallelProcessingCertified);
38 addParam(
"nx", m_nx,
"number of histogram bins", 200);
39 addParam(
"xmax", m_xmax,
"histogram upper limit [ADC counts]", 2000.0);
40 addParam(
"pulseWidthWindow", m_widthWindow,
41 "lower and upper bound of pulse-width selection window [ns]. "
42 "Empty list means no selection on the pulse width. "
43 "Note: selection on pulse width will influence pulse-height distribution.",
45 addParam(
"timeWindow", m_timeWindow,
46 "lower and upper bound of time selection window [ns]. "
47 "Empty list means no selection on photon time.", m_timeWindow);
52 void TOPPulseHeightCollectorModule::prepare()
55 m_digits.isRequired();
57 auto h1a =
new TH1F(
"time",
"time distribution (all hits)", 1000, -100, 250);
58 h1a->SetXTitle(
"time [ns]");
59 registerObject<TH1F>(
"time", h1a);
61 auto h1b =
new TH1F(
"time_sel",
"time distribution (selected hits)", 1000, -100, 250);
62 h1b->SetXTitle(
"time [ns]");
63 registerObject<TH1F>(
"time_sel", h1b);
65 auto h2a =
new TH2F(
"ph_vs_width",
"pulse height vs. width (all hits)",
66 200, 0, 10, 200, 0, 2000);
67 h2a->SetXTitle(
"pulse width [ns]");
68 h2a->SetYTitle(
"pulse height [ADC counts]");
69 registerObject<TH2F>(
"ph_vs_width", h2a);
71 auto h2b =
new TH2F(
"ph_vs_width_sel",
"pulse height vs. width (selected hits)",
72 200, 0, 10, 200, 0, 2000);
73 h2b->SetXTitle(
"pulse width [ns]");
74 h2b->SetYTitle(
"pulse height [ADC counts]");
75 registerObject<TH2F>(
"ph_vs_width_sel", h2b);
77 for (
int slot = 1; slot <= 16; slot++) {
78 string name =
"ph_slot_" + to_string(slot);
79 string title =
"pulse-height vs. channel for slot " + to_string(slot);
80 auto h =
new TH2F(name.c_str(), title.c_str(), 512, 0, 512, m_nx, 0, m_xmax);
81 h->SetXTitle(
"channel number");
82 h->SetYTitle(
"pulse height [ADC counts]");
83 registerObject<TH2F>(name, h);
84 m_names.push_back(name);
90 void TOPPulseHeightCollectorModule::collect()
93 std::vector<TH2F*> slots;
94 for (
const auto& name : m_names) {
95 auto h = getObjectPtr<TH2F>(name);
99 auto h1a = getObjectPtr<TH1F>(
"time");
100 auto h1b = getObjectPtr<TH1F>(
"time_sel");
101 auto h2a = getObjectPtr<TH2F>(
"ph_vs_width");
102 auto h2b = getObjectPtr<TH2F>(
"ph_vs_width_sel");
104 for (
const auto& digit : m_digits) {
105 if (digit.getHitQuality() != TOPDigit::c_Good)
continue;
106 auto t = digit.getTime();
107 auto w = digit.getPulseWidth();
108 auto ph = digit.getPulseHeight();
111 if (m_widthWindow.size() == 2) {
112 if (w < m_widthWindow[0] or w > m_widthWindow[1])
continue;
114 if (m_timeWindow.size() == 2) {
115 if (t < m_timeWindow[0] or t > m_timeWindow[1])
continue;
119 unsigned m = digit.getModuleID() - 1;
120 if (m < slots.size()) slots[m]->Fill(digit.getChannel(), ph);
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Abstract base class for different kinds of events.