Belle II Software development
TOPDQMModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8
9#include <top/modules/TOPDQM/TOPDQMModule.h>
10#include <top/geometry/TOPGeometryPar.h>
11#include <tracking/dataobjects/ExtHit.h>
12#include <framework/gearbox/Unit.h>
13#include <framework/gearbox/Const.h>
14#include <framework/logging/Logger.h>
15#include "TDirectory.h"
16#include <boost/format.hpp>
17#include <algorithm>
18#include <cmath>
19
20using namespace std;
21using boost::format;
22
23namespace Belle2 {
28
29 using namespace TOP;
30
31 //-----------------------------------------------------------------
33 //-----------------------------------------------------------------
34
35 REG_MODULE(TOPDQM);
36
37 //-----------------------------------------------------------------
38 // Implementation
39 //-----------------------------------------------------------------
40
42 {
43 // set module description (e.g. insert text)
44 setDescription("TOP DQM histogrammer");
46
47 // Add parameters
48 addParam("histogramDirectoryName", m_histogramDirectoryName,
49 "histogram directory in ROOT file", string("TOP"));
50 addParam("momentumCut", m_momentumCut,
51 "momentum cut used to histogram number of photons per track", 0.5);
52 }
53
54
58
60 {
61 // Create a separate histogram directory and cd into it.
62
63 TDirectory* oldDir = gDirectory;
64 oldDir->mkdir(m_histogramDirectoryName.c_str())->cd();
65
66 // Variables needed for booking
67
68 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
69 m_numModules = geo->getNumModules();
70 m_bunchTimeSep = geo->getNominalTDC().getSyncTimeBase() / 24;
71
72 // Histograms
73
74 m_BoolEvtMonitor = new TH1D("BoolEvtMonitor", "Event synchronization", 2, -0.5, 1.5);
75 m_BoolEvtMonitor->GetYaxis()->SetTitle("number of digits");
76 m_BoolEvtMonitor->GetXaxis()->SetBinLabel(1, "synchronized");
77 m_BoolEvtMonitor->GetXaxis()->SetBinLabel(2, "de-synchronized");
78 m_BoolEvtMonitor->GetXaxis()->SetLabelSize(0.05);
79 m_BoolEvtMonitor->GetXaxis()->SetAlphanumeric();
80 m_BoolEvtMonitor->SetMinimum(0);
81
82 m_window_vs_slot = new TH2F("window_vs_slot", "Asic windows", 16, 0.5, 16.5, 512, 0, 512);
83 m_window_vs_slot->SetXTitle("slot number");
84 m_window_vs_slot->SetYTitle("window number w.r.t reference window");
85 m_window_vs_slot->SetStats(kFALSE);
86 m_window_vs_slot->SetMinimum(0);
87 m_window_vs_slot->GetXaxis()->SetNdivisions(16);
88
89 int nbinsT0 = 75;
90 double rangeT0 = nbinsT0 * m_bunchTimeSep;
91 m_eventT0 = new TH1F("eventT0", "Event T0; event T0 [ns]; events per bin", nbinsT0, -rangeT0 / 2, rangeT0 / 2);
92
93 m_bunchOffset = new TH1F("bunchOffset", "Bunch offset", 100, -m_bunchTimeSep / 2, m_bunchTimeSep / 2);
94 m_bunchOffset->SetXTitle("offset [ns]");
95 m_bunchOffset->SetYTitle("events per bin");
96 m_bunchOffset->SetMinimum(0);
97
98 m_time = new TH1F("goodHitTimes", "Time distribution of good hits", 1000, -20, 80);
99 m_time->SetXTitle("time [ns]");
100 m_time->SetYTitle("hits per bin");
101
102 m_timeBG = new TH1F("goodHitTimesBG", "Time distribution of good hits (background)", 1000, -20, 80);
103 m_timeBG->SetXTitle("time [ns]");
104 m_timeBG->SetYTitle("hits per bin");
105
106 m_signalHits = new TProfile("signalHits", "Number of good hits per track in [0, 50] ns", 16, 0.5, 16.5, 0, 1000);
107 m_signalHits->SetXTitle("slot number");
108 m_signalHits->SetYTitle("hits per track");
109 m_signalHits->SetMinimum(0);
110 m_signalHits->GetXaxis()->SetNdivisions(16);
111
112 m_backgroundHits = new TProfile("backgroundHits", "Number of good hits pet track in [-50, 0] ns", 16, 0.5, 16.5, 0, 1000);
113 m_backgroundHits->SetXTitle("slot number");
114 m_backgroundHits->SetYTitle("hits per track");
115 m_backgroundHits->SetMinimum(0);
116 m_backgroundHits->GetXaxis()->SetNdivisions(16);
117
118 m_trackHits = new TH2F("trackHits", "Number of events w/ and w/o track in the slot", 16, 0.5, 16.5, 2, 0, 2);
119 m_trackHits->SetXTitle("slot number");
120 m_trackHits->SetYTitle("numTracks > 0");
121
122 int nbinsHits = 1000;
123 double xmaxHits = 10000;
124 m_goodHitsPerEventAll = new TH1F("goodHitsPerEventAll", "Number of good hits per event", nbinsHits, 0, xmaxHits);
125 m_goodHitsPerEventAll->GetXaxis()->SetTitle("hits per event");
126 m_goodHitsPerEventAll->GetYaxis()->SetTitle("entries per bin");
127
128 m_badHitsPerEventAll = new TH1F("badHitsPerEventAll", "Number of junk hits per event", nbinsHits, 0, xmaxHits);
129 m_badHitsPerEventAll->GetXaxis()->SetTitle("hits per event");
130 m_badHitsPerEventAll->GetYaxis()->SetTitle("entries per bin");
131
132 int nbinsTDC = 400;
133 double xminTDC = -100;
134 double xmaxTDC = 700;
135 m_goodTDCAll = new TH1F("goodTDCAll", "Raw time distribution of good hits", nbinsTDC, xminTDC, xmaxTDC);
136 m_goodTDCAll->SetXTitle("raw time [samples]");
137 m_goodTDCAll->SetYTitle("hits per sample");
138
139 m_badTDCAll = new TH1F("badTDCAll", "Raw time distribution of junk hits", nbinsTDC, xminTDC, xmaxTDC);
140 m_badTDCAll->SetXTitle("raw time [samples]");
141 m_badTDCAll->SetYTitle("hits per sample");
142
143 m_TOPOccAfterInjLER = new TH1F("TOPOccInjLER", "TOPOccInjLER/Time;Time in #mus;Nhits/Time (#mus bins)", 4000, 0, 20000);
144 m_TOPOccAfterInjHER = new TH1F("TOPOccInjHER", "TOPOccInjHER/Time;Time in #mus;Nhits/Time (#mus bins)", 4000, 0, 20000);
145 m_TOPEOccAfterInjLER = new TH1F("TOPEOccInjLER", "TOPEOccInjLER/Time;Time in #mus;Triggers/Time (#mus bins)", 4000, 0, 20000);
146 m_TOPEOccAfterInjHER = new TH1F("TOPEOccInjHER", "TOPEOccInjHER/Time;Time in #mus;Triggers/Time (#mus bins)", 4000, 0, 20000);
147
148 m_nhitInjLER = new TProfile2D("nhitInjLER",
149 "LER: average Nhits; "
150 "time since injection [msec]; time within beam cycle [syst. clk]; Nhits average",
151 160, 0, 80, 256, 0, 1280, 0, 100000);
152 m_nhitInjHER = new TProfile2D("nhitInjHER",
153 "HER: average Nhits; "
154 "time since injection [msec]; time within beam cycle [syst. clk]; Nhits average",
155 160, 0, 80, 256, 0, 1280, 0, 100000);
156 m_nhitInjLERcut = new TProfile2D("nhitInjLERcut",
157 "LER: average Nhits (Nhits>1000); "
158 "time since injection [msec]; time within beam cycle [syst. clk]; Nhits average",
159 160, 0, 80, 256, 0, 1280, 0, 100000);
160 m_nhitInjHERcut = new TProfile2D("nhitInjHERcut",
161 "HER: average Nhits (Nhits>1000); "
162 "time since injection [msec]; time within beam cycle [syst. clk]; Nhits average",
163 160, 0, 80, 256, 0, 1280, 0, 100000);
164 m_eventInjLER = new TH2F("eventInjLER",
165 "LER: event distribution; "
166 "time since injection [msec]; time within beam cycle [syst. clk]; events per bin",
167 160, 0, 80, 256, 0, 1280);
168 m_eventInjHER = new TH2F("eventInjHER",
169 "HER: event distribution; "
170 "time since injection [msec]; time within beam cycle [syst. clk]; events per bin",
171 160, 0, 80, 256, 0, 1280);
172 m_eventInjLERcut = new TH2F("eventInjLERcut",
173 "LER: event distribution (Nhits>1000); "
174 "time since injection [msec]; time within beam cycle [syst. clk]; events per bin",
175 160, 0, 80, 256, 0, 1280);
176 m_eventInjHERcut = new TH2F("eventInjHERcut",
177 "HER: event distribution (Nhits>1000); "
178 "time since injection [msec]; time within beam cycle [syst. clk]; events per bin",
179 160, 0, 80, 256, 0, 1280);
180
181 for (int i = 0; i < m_numModules; i++) {
182 int module = i + 1;
183 string name, title;
184 TH1F* h1 = 0;
185 TH2F* h2 = 0;
186
187 name = str(format("window_vs_asic_%1%") % (module));
188 title = str(format("Asic windows for slot #%1%") % (module));
189 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0, 64, 512, 0, 512);
190 h2->SetStats(kFALSE);
191 h2->SetXTitle("ASIC number");
192 h2->SetYTitle("window number w.r.t reference window");
193 h2->SetMinimum(0);
194 m_window_vs_asic.push_back(h2);
195
196 name = str(format("good_hits_xy_%1%") % (module));
197 title = str(format("Distribution of good hits for slot #%1%") % (module));
198 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0.5, 64.5, 8, 0.5, 8.5);
199 h2->SetStats(kFALSE);
200 h2->GetXaxis()->SetTitle("pixel column");
201 h2->GetYaxis()->SetTitle("pixel row");
202 h2->SetMinimum(0);
203 m_goodHitsXY.push_back(h2);
204
205 name = str(format("bad_hits_xy_%1%") % (module));
206 title = str(format("Distribution of junk hits for slot #%1%") % (module));
207 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0.5, 64.5, 8, 0.5, 8.5);
208 h2->SetStats(kFALSE);
209 h2->GetXaxis()->SetTitle("pixel column");
210 h2->GetYaxis()->SetTitle("pixel row");
211 h2->SetMinimum(0);
212 m_badHitsXY.push_back(h2);
213
214 name = str(format("good_hits_asics_%1%") % (module));
215 title = str(format("Distribution of good hits for slot #%1%") % (module));
216 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0, 64, 8, 0, 8);
217 h2->SetStats(kFALSE);
218 h2->GetXaxis()->SetTitle("ASIC number");
219 h2->GetYaxis()->SetTitle("ASIC channel");
220 h2->SetMinimum(0);
221 m_goodHitsAsics.push_back(h2);
222
223 name = str(format("bad_hits_asics_%1%") % (module));
224 title = str(format("Distribution of junk hits for slot #%1%") % (module));
225 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0, 64, 8, 0, 8);
226 h2->SetStats(kFALSE);
227 h2->GetXaxis()->SetTitle("ASIC number");
228 h2->GetYaxis()->SetTitle("ASIC channel");
229 h2->SetMinimum(0);
230 m_badHitsAsics.push_back(h2);
231
232 name = str(format("good_TDC_%1%") % (module));
233 title = str(format("Raw time distribution of good hits for slot #%1%") % (module));
234 h1 = new TH1F(name.c_str(), title.c_str(), nbinsTDC, xminTDC, xmaxTDC);
235 h1->GetXaxis()->SetTitle("raw time [samples]");
236 h1->GetYaxis()->SetTitle("hits per sample");
237 m_goodTDC.push_back(h1);
238
239 name = str(format("bad_TDC_%1%") % (module));
240 title = str(format("Raw time distribution of junk hits for slot #%1%") % (module));
241 h1 = new TH1F(name.c_str(), title.c_str(), nbinsTDC, xminTDC, xmaxTDC);
242 h1->GetXaxis()->SetTitle("raw time [samples]");
243 h1->GetYaxis()->SetTitle("hits per sample");
244 m_badTDC.push_back(h1);
245
246 name = str(format("good_timing_%1%") % (module));
247 title = str(format("Time distribution of good hits for slot #%1%") % (module));
248 h1 = new TH1F(name.c_str(), title.c_str(), 200, -20, 80);
249 h1->GetXaxis()->SetTitle("time [ns]");
250 h1->GetYaxis()->SetTitle("hits per time bin");
251 m_goodTiming.push_back(h1);
252
253 name = str(format("good_timing_%1%BG") % (module));
254 title = str(format("Time distribution of good hits (background) for slot #%1%") % (module));
255 h1 = new TH1F(name.c_str(), title.c_str(), 200, -20, 80);
256 h1->GetXaxis()->SetTitle("time [ns]");
257 h1->GetYaxis()->SetTitle("hits per time bin");
258 m_goodTimingBG.push_back(h1);
259
260 name = str(format("good_channel_hits_%1%") % (module));
261 title = str(format("Distribution of good hits for slot #%1%") % (module));
262 int numPixels = geo->getModule(i + 1).getPMTArray().getNumPixels();
263 h1 = new TH1F(name.c_str(), title.c_str(), numPixels, 0, numPixels);
264 h1->GetXaxis()->SetTitle("channel number");
265 h1->GetYaxis()->SetTitle("hits per channel");
266 h1->SetMinimum(0);
267 m_goodChannelHits.push_back(h1);
268
269 name = str(format("bad_channel_hits_%1%") % (module));
270 title = str(format("Distribution of junk hits for slot #%1%") % (module));
271 h1 = new TH1F(name.c_str(), title.c_str(), numPixels, 0, numPixels);
272 h1->GetXaxis()->SetTitle("channel number");
273 h1->GetYaxis()->SetTitle("hits per channel");
274 h1->SetMinimum(0);
275 m_badChannelHits.push_back(h1);
276
277 name = str(format("pulseHeights_%1%") % (module));
278 title = str(format("Average pulse heights for slot #%1%") % (module));
279 auto* prof = new TProfile(name.c_str(), title.c_str(), 32, 0.5, 32.5, 0, 2000);
280 prof->GetXaxis()->SetTitle("PMT number");
281 prof->GetYaxis()->SetTitle("pulse height [ADC counts]");
282 prof->SetMarkerStyle(20);
283 prof->SetMinimum(0);
284 m_pulseHeights.push_back(prof);
285 }
286
287 m_skipProcFlag = new TH2F("skipProcFlag", "Skip processing flag; slot number; flag value", 64, 0.5, 16.5, 2, -0.5, 1.5);
288 m_skipProcFlag->GetXaxis()->SetNdivisions(16);
289 m_skipProcFlag->GetYaxis()->SetNdivisions(2);
290 m_skipProcFlag->SetMinimum(0);
291
292 m_injVetoFlag = new TH2F("injVetoFlag", "Injection veto flag; slot number; flag value", 64, 0.5, 16.5, 2, -0.5, 1.5);
293 m_injVetoFlag->GetXaxis()->SetNdivisions(16);
294 m_injVetoFlag->GetYaxis()->SetNdivisions(2);
295 m_injVetoFlag->SetMinimum(0);
296
297 m_injVetoFlagDiff = new TH1F("injVetoFlagDiff", "Injection veto flags check; ; fraction of events", 2, -0.5, 1.5);
298 m_injVetoFlagDiff->GetXaxis()->SetNdivisions(2);
299 m_injVetoFlagDiff->GetXaxis()->SetBinLabel(1, "flags the same");
300 m_injVetoFlagDiff->GetXaxis()->SetBinLabel(2, "flags differ");
301 m_injVetoFlagDiff->GetXaxis()->SetLabelSize(0.05);
302 m_injVetoFlagDiff->GetXaxis()->SetAlphanumeric();
303 m_injVetoFlagDiff->SetMinimum(0);
304
305 m_PSBypassMode = new TH2F("PSBypassMode", "PS-bypass mode; slot number; mode", 64, 0.5, 16.5, 8, -0.5, 7.5);
306 m_PSBypassMode->GetXaxis()->SetNdivisions(16);
307 m_PSBypassMode->GetYaxis()->SetNdivisions(8);
308 m_PSBypassMode->SetMinimum(0);
309
310 // cd back to root directory
311 oldDir->cd();
312 }
313
315 {
316 // Register histograms (calls back defineHisto)
317
318 REG_HISTOGRAM;
319
320 // register dataobjects
321
322 m_rawFTSWs.isOptional();
323 m_productionEventDebugs.isOptional(); // not in sim
324 m_digits.isRequired();
325 m_recBunch.isOptional();
326 m_timeZeros.isOptional();
327 m_tracks.isOptional();
328 }
329
331 {
332 m_BoolEvtMonitor->Reset();
333 m_window_vs_slot->Reset();
334 m_eventT0->Reset();
335 m_bunchOffset->Reset();
336 m_time->Reset();
337 m_timeBG->Reset();
338 m_signalHits->Reset();
339 m_backgroundHits->Reset();
340 m_trackHits->Reset();
341 m_goodTDCAll->Reset();
342 m_badTDCAll->Reset();
343 m_goodHitsPerEventAll->Reset();
344 m_badHitsPerEventAll->Reset();
345 m_TOPOccAfterInjLER->Reset();
346 m_TOPOccAfterInjHER->Reset();
347 m_TOPEOccAfterInjLER->Reset();
348 m_TOPEOccAfterInjHER->Reset();
349 m_nhitInjLER->Reset();
350 m_nhitInjHER->Reset();
351 m_nhitInjLERcut->Reset();
352 m_nhitInjHERcut->Reset();
353 m_eventInjLER->Reset();
354 m_eventInjHER->Reset();
355 m_eventInjLERcut->Reset();
356 m_eventInjHERcut->Reset();
357
358 for (int i = 0; i < m_numModules; i++) {
359 m_window_vs_asic[i]->Reset();
360 m_goodHitsXY[i]->Reset();
361 m_badHitsXY[i]->Reset();
362 m_goodHitsAsics[i]->Reset();
363 m_badHitsAsics[i]->Reset();
364 m_goodTDC[i]->Reset();
365 m_badTDC[i]->Reset();
366 m_goodTiming[i]->Reset();
367 m_goodTimingBG[i]->Reset();
368 m_goodChannelHits[i]->Reset();
369 m_badChannelHits[i]->Reset();
370 m_pulseHeights[i]->Reset();
371 }
372
373 m_skipProcFlag->Reset();
374 m_injVetoFlag->Reset();
375 m_injVetoFlagDiff->Reset();
376 m_PSBypassMode->Reset();
377 }
378
380 {
381
382 // check if event time is reconstructed; distinguish collision data and cosmics
383
384 bool recBunchValid = false;
385 bool cosmics = false;
386 if (m_recBunch.isValid()) { // collision data
387 recBunchValid = m_recBunch->isReconstructed(); // event time is reconstructed
388 } else if (m_timeZeros.getEntries() == 1) { // cosmics w/ reconstructed event time
389 cosmics = true;
390 m_eventT0->Fill(m_timeZeros[0]->getTime());
391 }
392
393 // fill bunch offset
394
395 if (recBunchValid) {
396 double t0 = m_commonT0->isRoughlyCalibrated() ? m_commonT0->getT0() : 0;
397 double offset = m_recBunch->getCurrentOffset() - t0;
398 offset -= m_bunchTimeSep * lround(offset / m_bunchTimeSep); // wrap around
399 m_bunchOffset->Fill(offset);
400 m_eventT0->Fill(m_recBunch->getTime());
401 }
402
403 // fill event desynchronization
404
405 if (m_digits.getEntries() > 0) {
406 for (const auto& digit : m_digits) {
407 int x = digit.getFirstWindow() != m_digits[0]->getFirstWindow() ? 1 : 0 ;
408 m_BoolEvtMonitor->Fill(x);
409 }
410 }
411
412 // count tracks in the modules and store the momenta
413
414 std::vector<int> numTracks(m_numModules, 0);
415 std::vector<double> trackMomenta(m_numModules, 0);
416 for (const auto& track : m_tracks) {
417 const auto* fitResult = track.getTrackFitResultWithClosestMass(Const::pion);
418 if (not fitResult) continue;
419 int slot = getModuleID(track);
420 if (slot == 0) continue;
421 numTracks[slot - 1]++;
422 trackMomenta[slot - 1] = std::max(trackMomenta[slot - 1], fitResult->getMomentum().R());
423 }
424
425 // count events w/ and w/o track in the slot
426
427 if (recBunchValid or cosmics) {
428 for (size_t i = 0; i < numTracks.size(); i++) {
429 bool hit = numTracks[i] > 0;
430 m_trackHits->Fill(i + 1, hit);
431 }
432 }
433
434 // select modules for counting hits in signal and background time windows
435
436 std::vector<bool> selectedSlots(m_numModules, false);
437 for (size_t i = 0; i < selectedSlots.size(); i++) {
438 selectedSlots[i] = (recBunchValid or cosmics) and numTracks[i] == 1 and trackMomenta[i] > m_momentumCut;
439 }
440
441 // prepare counters
442
443 int nHits_good = 0;
444 int nHits_bad = 0;
445 std::vector<int> numSignalHits(m_numModules, 0);
446 std::vector<int> numBackgroundHits(m_numModules, 0);
447
448 // loop over digits, fill histograms and increment counters
449
450 for (const auto& digit : m_digits) {
451 int slot = digit.getModuleID();
452 if (slot < 1 or slot > m_numModules) {
453 B2ERROR("Invalid slot ID found in TOPDigits: ID = " << slot);
454 continue;
455 }
456 int asic_no = digit.getChannel() / 8;
457 int asic_ch = digit.getChannel() % 8;
458
459 m_window_vs_slot->Fill(digit.getModuleID(), digit.getRawTime() / 64 + 220);
460 m_window_vs_asic[slot - 1]->Fill(asic_no, digit.getRawTime() / 64 + 220);
461
462 if (digit.getHitQuality() != TOPDigit::c_Junk) { // good hits
463 m_goodHitsXY[slot - 1]->Fill(digit.getPixelCol(), digit.getPixelRow());
464 m_goodHitsAsics[slot - 1]->Fill(asic_no, asic_ch);
465 m_goodTDC[slot - 1]->Fill(digit.getRawTime());
466 m_goodTDCAll->Fill(digit.getRawTime());
467 m_goodChannelHits[slot - 1]->Fill(digit.getChannel());
468 m_pulseHeights[slot - 1]->Fill(digit.getPMTNumber(), digit.getPulseHeight());
469 nHits_good++;
470 if (digit.hasStatus(TOPDigit::c_EventT0Subtracted)) {
471 double time = digit.getTime();
472 if (cosmics) time += 10; // move for 10 ns in order to get the complete signal at positive times
473 if (numTracks[slot - 1] > 0) {
474 m_goodTiming[slot - 1]->Fill(time);
475 m_time->Fill(time);
476 } else {
477 m_goodTimingBG[slot - 1]->Fill(time);
478 m_timeBG->Fill(time);
479 }
480 if (selectedSlots[slot - 1] and abs(time) < 50) {
481 if (time > 0) numSignalHits[slot - 1]++;
482 else numBackgroundHits[slot - 1]++;
483 }
484 }
485 } else { // bad hits: FE not valid, pedestal jump, too short or too wide pulses
486 m_badHitsXY[slot - 1]->Fill(digit.getPixelCol(), digit.getPixelRow());
487 m_badHitsAsics[slot - 1]->Fill(asic_no, asic_ch);
488 m_badTDC[slot - 1]->Fill(digit.getRawTime());
489 m_badTDCAll->Fill(digit.getRawTime());
490 m_badChannelHits[slot - 1]->Fill(digit.getChannel());
491 nHits_bad++;
492 }
493 }
494
495 // histogram counters
496
497 m_goodHitsPerEventAll->Fill(nHits_good);
498 m_badHitsPerEventAll->Fill(nHits_bad);
499 for (int slot = 1; slot <= m_numModules; slot++) {
500 if (selectedSlots[slot - 1]) {
501 m_signalHits->Fill(slot, numSignalHits[slot - 1]);
502 m_backgroundHits->Fill(slot, numBackgroundHits[slot - 1]);
503 }
504 }
505
506 // fill injection histograms
507
508 for (auto& it : m_rawFTSWs) {
509 B2DEBUG(29, "TTD FTSW : " << hex << it.GetTTUtime(0) << " " << it.GetTTCtime(0) << " EvtNr " << it.GetEveNo(0) << " Type " <<
510 (it.GetTTCtimeTRGType(0) & 0xF) << " TimeSincePrev " << it.GetTimeSincePrevTrigger(0) << " TimeSinceInj " <<
511 it.GetTimeSinceLastInjection(0) << " IsHER " << it.GetIsHER(0) << " Bunch " << it.GetBunchNumber(0));
512 auto time_clk = it.GetTimeSinceLastInjection(0); // expressed in system clock
513 if (time_clk != 0x7FFFFFFF) {
514 unsigned int nentries = m_digits.getEntries();
515 double time_us = time_clk / 127.0; // 127MHz clock ticks to us, inexact rounding
516 double time_ms = time_us / 1000;
517 double time_1280 = time_clk % 1280; // within beam cycle, expressed in system clock
518 if (it.GetIsHER(0)) {
519 m_TOPOccAfterInjHER->Fill(time_us, nentries);
520 m_TOPEOccAfterInjHER->Fill(time_us);
521 m_nhitInjHER->Fill(time_ms, time_1280, nHits_good);
522 m_eventInjHER->Fill(time_ms, time_1280);
523 if (nHits_good > 1000) {
524 m_nhitInjHERcut->Fill(time_ms, time_1280, nHits_good);
525 m_eventInjHERcut->Fill(time_ms, time_1280);
526 }
527 } else {
528 m_TOPOccAfterInjLER->Fill(time_us, nentries);
529 m_TOPEOccAfterInjLER->Fill(time_us);
530 m_nhitInjLER->Fill(time_ms, time_1280, nHits_good);
531 m_eventInjLER->Fill(time_ms, time_1280);
532 if (nHits_good > 1000) {
533 m_nhitInjLERcut->Fill(time_ms, time_1280, nHits_good);
534 m_eventInjLERcut->Fill(time_ms, time_1280);
535 }
536 }
537 }
538 }
539
540 // fill raw data header histograms
541
542 const auto& feMapper = TOPGeometryPar::Instance()->getFrontEndMapper();
543 double differ = 0;
544 for (const auto& dbg : m_productionEventDebugs) {
545 auto scrodID = dbg.getScrodID();
546 const auto* femap = feMapper.getMap(scrodID);
547 if (not femap) {
548 B2ERROR("No front-end map available for scrodID " << scrodID);
549 continue;
550 }
551 auto slot = femap->getModuleID();
552 auto bs = femap->getBoardstackNumber();
553 double x = slot + bs / 4. - 0.5;
554 m_skipProcFlag->Fill(x, dbg.getSkipProcessingFlag());
555 m_injVetoFlag->Fill(x, dbg.getInjectionVetoFlag());
556 m_PSBypassMode->Fill(x, dbg.getPSBypassMode());
557 if (dbg.getInjectionVetoFlag() != m_productionEventDebugs[0]->getInjectionVetoFlag()) differ = 1;
558 }
559 m_injVetoFlagDiff->Fill(differ);
560
561 }
562
563
564 int TOPDQMModule::getModuleID(const Track& track) const
565 {
566 Const::EDetector myDetID = Const::EDetector::TOP;
567 int pdgCode = std::abs(Const::pion.getPDGCode());
568
569 RelationVector<ExtHit> extHits = track.getRelationsWith<ExtHit>();
570 for (const auto& extHit : extHits) {
571 if (std::abs(extHit.getPdgCode()) != pdgCode) continue;
572 if (extHit.getDetectorID() != myDetID) continue;
573 if (extHit.getCopyID() < 1 or extHit.getCopyID() > m_numModules) continue;
574 return extHit.getCopyID();
575 }
576
577 return 0;
578 }
579
580
582} // end Belle2 namespace
583
EDetector
Enum for identifying the detector components (detector and subdetector).
Definition Const.h:42
static const ChargedStable pion
charged pion particle
Definition Const.h:661
Store one Ext hit as a ROOT object.
Definition ExtHit.h:31
HistoModule()
Constructor.
Definition HistoModule.h:32
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition Module.h:80
Class for type safe access to objects that are referred to in relations.
std::vector< TH2F * > m_window_vs_asic
Histograms window w.r.t reference vs.
std::vector< TH1F * > m_badChannelHits
Histograms for bad channel hits.
int m_numModules
number of TOP modules
std::vector< TH2F * > m_goodHitsXY
Histograms (2D) for good hits in pixels.
std::vector< TH2F * > m_goodHitsAsics
Histograms (2D) for good hits in asic channels.
StoreObjPtr< TOPRecBunch > m_recBunch
reconstructed bunch and event T0
TH2F * m_eventInjHER
event distribution (HER injection)
DBObjPtr< TOPCalCommonT0 > m_commonT0
common T0 calibration constants
double m_momentumCut
momentum cut
TH2F * m_injVetoFlag
injection veto flag vs.
std::vector< TH2F * > m_badHitsXY
Histograms (2D) for bad hits in pixels.
TH1F * m_bunchOffset
reconstructed bunch: current offset
TProfile2D * m_nhitInjLER
average number of good digits (LER injection)
TProfile * m_backgroundHits
number of hits in the background time window vs.
StoreArray< TOPProductionEventDebug > m_productionEventDebugs
collection of event debug data
std::vector< TH1F * > m_badTDC
Histograms for TDC distribution of bad hits.
std::vector< TH1F * > m_goodChannelHits
Histograms for good channel hits.
TH1F * m_eventT0
reconstructed event T0
TH2F * m_eventInjLERcut
event distribution after cut (LER injection)
TH2F * m_window_vs_slot
Histogram window w.r.t reference vs.
TH1F * m_injVetoFlagDiff
check if injection veto flags differ in the event
std::vector< TH1F * > m_goodTDC
Histograms for TDC distribution of good hits.
std::vector< TH1F * > m_goodTimingBG
Histograms for timing distribution of good hits (background)
TH1F * m_timeBG
time distribution of good hits (background)
TH2F * m_eventInjLER
event distribution (LER injection)
StoreArray< RawFTSW > m_rawFTSWs
Input array for DAQ Status.
TH1F * m_TOPEOccAfterInjHER
Histogram for Nr Entries (=Triggrs) for normalization after HER injection.
std::string m_histogramDirectoryName
histogram directory in ROOT file
TProfile2D * m_nhitInjLERcut
average number of good digits after cut (LER injection)
StoreArray< Track > m_tracks
collection of tracks
TH1F * m_badHitsPerEventAll
Number of bad hits per event (all slots)
TH1F * m_TOPEOccAfterInjLER
Histogram for Nr Entries (=Triggrs) for normalization after LER injection.
std::vector< TH1F * > m_goodTiming
Histograms for timing distribution of good hits.
TH1F * m_time
time distribution of good hits
TH1F * m_goodTDCAll
TDC distribution of good hits (all slots)
TProfile2D * m_nhitInjHER
average number of good digits (HER injection)
TH1F * m_TOPOccAfterInjLER
Histogram Ndigits after LER injection.
StoreArray< TOPDigit > m_digits
collection of digits
std::vector< TProfile * > m_pulseHeights
Pulse heights of good hits.
TH2F * m_eventInjHERcut
event distribution after cut (HER injection)
StoreArray< TOPTimeZero > m_timeZeros
reconstructed event T0 in case of cosmics
TProfile * m_signalHits
number of hits in the signal time window vs.
TH2F * m_trackHits
counting events w/ and w/o track in the slot vs.
TH2F * m_PSBypassMode
PS-bypass mode vs.
double m_bunchTimeSep
bunch separation time
TH1D * m_BoolEvtMonitor
Event desynchronization monitoring.
TProfile2D * m_nhitInjHERcut
average number of good digits after cut (HER injection)
std::vector< TH2F * > m_badHitsAsics
Histograms (2D) for bad hits in asic channels.
TH1F * m_TOPOccAfterInjHER
Histogram Ndigits after HER injection.
TH1F * m_badTDCAll
TDC distribution of bad hits (all slots)
TH1F * m_goodHitsPerEventAll
Number of good hits per event (all slots)
TH2F * m_skipProcFlag
skip processing flag vs.
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
static TOPGeometryPar * Instance()
Static method to obtain the pointer to its instance.
const FrontEndMapper & getFrontEndMapper() const
Returns front-end mapper (mapping of SCROD's to positions within TOP modules)
Class that bundles various TrackFitResults.
Definition Track.h:25
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
TOPDQMModule()
Constructor.
virtual void initialize() override
Initialize the Module.
virtual void event() override
Event processor.
virtual ~TOPDQMModule()
Destructor.
virtual void beginRun() override
Called when entering a new run.
int getModuleID(const Track &track) const
Returns slot ID of the module that is hit by the track.
virtual void defineHisto() override
Histogram definitions such as TH1(), TH2(), TNtuple(), TTree()....
Abstract base class for different kinds of events.
STL namespace.