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#include <map>
20
21using namespace std;
22using boost::format;
23
24namespace Belle2 {
29
30 using namespace TOP;
31
32 //-----------------------------------------------------------------
34 //-----------------------------------------------------------------
35
36 REG_MODULE(TOPDQM);
37
38 //-----------------------------------------------------------------
39 // Implementation
40 //-----------------------------------------------------------------
41
43 {
44 // set module description (e.g. insert text)
45 setDescription("TOP DQM histogrammer");
47
48 // Add parameters
49 addParam("histogramDirectoryName", m_histogramDirectoryName,
50 "histogram directory in ROOT file", string("TOP"));
51 addParam("momentumCut", m_momentumCut,
52 "momentum cut used to histogram number of photons per track", 0.5);
53 }
54
55
57 {
58 // Create a separate histogram directory and cd into it.
59
60 TDirectory* oldDir = gDirectory;
61 oldDir->mkdir(m_histogramDirectoryName.c_str())->cd();
62
63 // Variables needed for booking
64
65 const auto* geo = TOPGeometryPar::Instance()->getGeometry();
66 m_numModules = geo->getNumModules();
67 m_bunchTimeSep = geo->getNominalTDC().getSyncTimeBase() / 24;
68
69 // Histograms
70
71 m_BoolEvtMonitor = new TH2D("BoolEvtMonitor", "Event synchronization", 64, 1, 17, 2, 0, 2);
72 m_BoolEvtMonitor->SetXTitle("slot number");
73 m_BoolEvtMonitor->SetYTitle(" synchonized hits | de-synchronized hits");
74 m_BoolEvtMonitor->GetXaxis()->SetNdivisions(16);
75 m_BoolEvtMonitor->GetXaxis()->CenterLabels();
76 m_BoolEvtMonitor->GetYaxis()->SetNdivisions(2);
77 m_BoolEvtMonitor->GetYaxis()->SetBinLabel(1, "0");
78 m_BoolEvtMonitor->GetYaxis()->SetBinLabel(2, "1");
79 m_BoolEvtMonitor->GetYaxis()->SetLabelSize(0.05);
80 m_BoolEvtMonitor->GetYaxis()->SetAlphanumeric();
81 m_BoolEvtMonitor->GetYaxis()->CenterTitle();
82 m_BoolEvtMonitor->SetMinimum(0);
83
84 m_window_vs_slot = new TH2F("window_vs_slot", "Asic windows", 64, 1, 17, 512, 0, 512);
85 m_window_vs_slot->SetXTitle("slot number");
86 m_window_vs_slot->SetYTitle("window number w.r.t reference window");
87 m_window_vs_slot->GetXaxis()->SetNdivisions(16);
88 m_window_vs_slot->GetXaxis()->CenterLabels();
89 m_window_vs_slot->SetMinimum(0);
90
91 int nbinsT0 = 75;
92 double rangeT0 = nbinsT0 * m_bunchTimeSep;
93 m_eventT0 = new TH1F("eventT0", "Event T0; event T0 [ns]; events per bin", nbinsT0, -rangeT0 / 2, rangeT0 / 2);
94
95 m_bunchOffset = new TH1F("bunchOffset", "Bunch offset", 100, -m_bunchTimeSep / 2, m_bunchTimeSep / 2);
96 m_bunchOffset->SetXTitle("offset [ns]");
97 m_bunchOffset->SetYTitle("events per bin");
98 m_bunchOffset->SetMinimum(0);
99
100 m_time = new TH1F("goodHitTimes", "Time distribution of good hits", 1000, -20, 80);
101 m_time->SetXTitle("time [ns]");
102 m_time->SetYTitle("hits per bin");
103
104 m_timeBG = new TH1F("goodHitTimesBG", "Time distribution of good hits (background)", 1000, -20, 80);
105 m_timeBG->SetXTitle("time [ns]");
106 m_timeBG->SetYTitle("hits per bin");
107
108 m_signalHits = new TProfile("signalHits", "Number of good hits per track in [0, 50] ns", 16, 0.5, 16.5, 0, 1000);
109 m_signalHits->SetXTitle("slot number");
110 m_signalHits->SetYTitle("hits per track");
111 m_signalHits->SetMinimum(0);
112 m_signalHits->GetXaxis()->SetNdivisions(16);
113
114 m_backgroundHits = new TProfile("backgroundHits", "Number of good hits pet track in [-50, 0] ns", 16, 0.5, 16.5, 0, 1000);
115 m_backgroundHits->SetXTitle("slot number");
116 m_backgroundHits->SetYTitle("hits per track");
117 m_backgroundHits->SetMinimum(0);
118 m_backgroundHits->GetXaxis()->SetNdivisions(16);
119
120 m_trackHits = new TH2F("trackHits", "Number of events w/ and w/o track in the slot", 16, 0.5, 16.5, 2, 0, 2);
121 m_trackHits->SetXTitle("slot number");
122 m_trackHits->SetYTitle("numTracks > 0");
123
124 int nbinsHits = 1000;
125 double xmaxHits = 10000;
126 m_goodHitsPerEventAll = new TH1F("goodHitsPerEventAll", "Number of good hits per event", nbinsHits, 0, xmaxHits);
127 m_goodHitsPerEventAll->GetXaxis()->SetTitle("hits per event");
128 m_goodHitsPerEventAll->GetYaxis()->SetTitle("entries per bin");
129
130 m_badHitsPerEventAll = new TH1F("badHitsPerEventAll", "Number of junk hits per event", nbinsHits, 0, xmaxHits);
131 m_badHitsPerEventAll->GetXaxis()->SetTitle("hits per event");
132 m_badHitsPerEventAll->GetYaxis()->SetTitle("entries per bin");
133
134 int nbinsTDC = 400;
135 double xminTDC = -100;
136 double xmaxTDC = 700;
137 m_goodTDCAll = new TH1F("goodTDCAll", "Raw time distribution of good hits", nbinsTDC, xminTDC, xmaxTDC);
138 m_goodTDCAll->SetXTitle("raw time [samples]");
139 m_goodTDCAll->SetYTitle("hits per sample");
140
141 m_badTDCAll = new TH1F("badTDCAll", "Raw time distribution of junk hits", nbinsTDC, xminTDC, xmaxTDC);
142 m_badTDCAll->SetXTitle("raw time [samples]");
143 m_badTDCAll->SetYTitle("hits per sample");
144
145 m_TOPOccAfterInjLER = new TH1F("TOPOccInjLER", "TOPOccInjLER/Time;Time in #mus;Nhits/Time (#mus bins)", 4000, 0, 20000);
146 m_TOPOccAfterInjHER = new TH1F("TOPOccInjHER", "TOPOccInjHER/Time;Time in #mus;Nhits/Time (#mus bins)", 4000, 0, 20000);
147 m_TOPEOccAfterInjLER = new TH1F("TOPEOccInjLER", "TOPEOccInjLER/Time;Time in #mus;Triggers/Time (#mus bins)", 4000, 0, 20000);
148 m_TOPEOccAfterInjHER = new TH1F("TOPEOccInjHER", "TOPEOccInjHER/Time;Time in #mus;Triggers/Time (#mus bins)", 4000, 0, 20000);
149
150 m_nhitInjLER = new TProfile2D("nhitInjLER",
151 "LER: average Nhits; "
152 "time since injection [msec]; time within beam cycle [syst. clk]; Nhits average",
153 160, 0, 80, 256, 0, 1280, 0, 100000);
154 m_nhitInjHER = new TProfile2D("nhitInjHER",
155 "HER: average Nhits; "
156 "time since injection [msec]; time within beam cycle [syst. clk]; Nhits average",
157 160, 0, 80, 256, 0, 1280, 0, 100000);
158 m_nhitInjLERcut = new TProfile2D("nhitInjLERcut",
159 "LER: average Nhits (Nhits>1000); "
160 "time since injection [msec]; time within beam cycle [syst. clk]; Nhits average",
161 160, 0, 80, 256, 0, 1280, 0, 100000);
162 m_nhitInjHERcut = new TProfile2D("nhitInjHERcut",
163 "HER: average Nhits (Nhits>1000); "
164 "time since injection [msec]; time within beam cycle [syst. clk]; Nhits average",
165 160, 0, 80, 256, 0, 1280, 0, 100000);
166 m_eventInjLER = new TH2F("eventInjLER",
167 "LER: event distribution; "
168 "time since injection [msec]; time within beam cycle [syst. clk]; events per bin",
169 160, 0, 80, 256, 0, 1280);
170 m_eventInjHER = new TH2F("eventInjHER",
171 "HER: event distribution; "
172 "time since injection [msec]; time within beam cycle [syst. clk]; events per bin",
173 160, 0, 80, 256, 0, 1280);
174 m_eventInjLERcut = new TH2F("eventInjLERcut",
175 "LER: event distribution (Nhits>1000); "
176 "time since injection [msec]; time within beam cycle [syst. clk]; events per bin",
177 160, 0, 80, 256, 0, 1280);
178 m_eventInjHERcut = new TH2F("eventInjHERcut",
179 "HER: event distribution (Nhits>1000); "
180 "time since injection [msec]; time within beam cycle [syst. clk]; events per bin",
181 160, 0, 80, 256, 0, 1280);
182
183 for (int i = 0; i < m_numModules; i++) {
184 int module = i + 1;
185 string name, title;
186 TH1F* h1 = 0;
187 TH2F* h2 = 0;
188
189 name = str(format("window_vs_asic_%1%") % (module));
190 title = str(format("Asic windows for slot #%1%") % (module));
191 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0, 64, 512, 0, 512);
192 h2->SetStats(kFALSE);
193 h2->SetXTitle("ASIC number");
194 h2->SetYTitle("window number w.r.t reference window");
195 h2->SetMinimum(0);
196 m_window_vs_asic.push_back(h2);
197
198 name = str(format("good_hits_xy_%1%") % (module));
199 title = str(format("Distribution of good hits for slot #%1%") % (module));
200 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0.5, 64.5, 8, 0.5, 8.5);
201 h2->SetStats(kFALSE);
202 h2->GetXaxis()->SetTitle("pixel column");
203 h2->GetYaxis()->SetTitle("pixel row");
204 h2->SetMinimum(0);
205 m_goodHitsXY.push_back(h2);
206
207 name = str(format("bad_hits_xy_%1%") % (module));
208 title = str(format("Distribution of junk hits for slot #%1%") % (module));
209 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0.5, 64.5, 8, 0.5, 8.5);
210 h2->SetStats(kFALSE);
211 h2->GetXaxis()->SetTitle("pixel column");
212 h2->GetYaxis()->SetTitle("pixel row");
213 h2->SetMinimum(0);
214 m_badHitsXY.push_back(h2);
215
216 name = str(format("good_hits_asics_%1%") % (module));
217 title = str(format("Distribution of good hits for slot #%1%") % (module));
218 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0, 64, 8, 0, 8);
219 h2->SetStats(kFALSE);
220 h2->GetXaxis()->SetTitle("ASIC number");
221 h2->GetYaxis()->SetTitle("ASIC channel");
222 h2->SetMinimum(0);
223 m_goodHitsAsics.push_back(h2);
224
225 name = str(format("bad_hits_asics_%1%") % (module));
226 title = str(format("Distribution of junk hits for slot #%1%") % (module));
227 h2 = new TH2F(name.c_str(), title.c_str(), 64, 0, 64, 8, 0, 8);
228 h2->SetStats(kFALSE);
229 h2->GetXaxis()->SetTitle("ASIC number");
230 h2->GetYaxis()->SetTitle("ASIC channel");
231 h2->SetMinimum(0);
232 m_badHitsAsics.push_back(h2);
233
234 name = str(format("good_TDC_%1%") % (module));
235 title = str(format("Raw time distribution of good hits for slot #%1%") % (module));
236 h1 = new TH1F(name.c_str(), title.c_str(), nbinsTDC, xminTDC, xmaxTDC);
237 h1->GetXaxis()->SetTitle("raw time [samples]");
238 h1->GetYaxis()->SetTitle("hits per sample");
239 m_goodTDC.push_back(h1);
240
241 name = str(format("bad_TDC_%1%") % (module));
242 title = str(format("Raw time distribution of junk hits for slot #%1%") % (module));
243 h1 = new TH1F(name.c_str(), title.c_str(), nbinsTDC, xminTDC, xmaxTDC);
244 h1->GetXaxis()->SetTitle("raw time [samples]");
245 h1->GetYaxis()->SetTitle("hits per sample");
246 m_badTDC.push_back(h1);
247
248 name = str(format("good_timing_%1%") % (module));
249 title = str(format("Time distribution of good hits for slot #%1%") % (module));
250 h1 = new TH1F(name.c_str(), title.c_str(), 200, -20, 80);
251 h1->GetXaxis()->SetTitle("time [ns]");
252 h1->GetYaxis()->SetTitle("hits per time bin");
253 m_goodTiming.push_back(h1);
254
255 name = str(format("good_timing_%1%BG") % (module));
256 title = str(format("Time distribution of good hits (background) for slot #%1%") % (module));
257 h1 = new TH1F(name.c_str(), title.c_str(), 200, -20, 80);
258 h1->GetXaxis()->SetTitle("time [ns]");
259 h1->GetYaxis()->SetTitle("hits per time bin");
260 m_goodTimingBG.push_back(h1);
261
262 name = str(format("good_channel_hits_%1%") % (module));
263 title = str(format("Distribution of good hits for slot #%1%") % (module));
264 int numPixels = geo->getModule(i + 1).getPMTArray().getNumPixels();
265 h1 = new TH1F(name.c_str(), title.c_str(), numPixels, 0, numPixels);
266 h1->GetXaxis()->SetTitle("channel number");
267 h1->GetYaxis()->SetTitle("hits per channel");
268 h1->SetMinimum(0);
269 m_goodChannelHits.push_back(h1);
270
271 name = str(format("bad_channel_hits_%1%") % (module));
272 title = str(format("Distribution of junk hits for slot #%1%") % (module));
273 h1 = new TH1F(name.c_str(), title.c_str(), numPixels, 0, numPixels);
274 h1->GetXaxis()->SetTitle("channel number");
275 h1->GetYaxis()->SetTitle("hits per channel");
276 h1->SetMinimum(0);
277 m_badChannelHits.push_back(h1);
278
279 name = str(format("pulseHeights_%1%") % (module));
280 title = str(format("Average pulse heights for slot #%1%") % (module));
281 auto* prof = new TProfile(name.c_str(), title.c_str(), 32, 0.5, 32.5, 0, 2000);
282 prof->GetXaxis()->SetTitle("PMT number");
283 prof->GetYaxis()->SetTitle("pulse height [ADC counts]");
284 prof->SetMarkerStyle(20);
285 prof->SetMinimum(0);
286 m_pulseHeights.push_back(prof);
287 }
288
289 m_skipProcFlag = new TH2F("skipProcFlag", "Skip processing flag; slot number; flag value", 64, 1, 17, 2, 0, 2);
290 m_skipProcFlag->GetXaxis()->SetNdivisions(16);
291 m_skipProcFlag->GetXaxis()->CenterLabels();
292 m_skipProcFlag->GetYaxis()->SetNdivisions(2);
293 m_skipProcFlag->GetYaxis()->SetBinLabel(1, "0");
294 m_skipProcFlag->GetYaxis()->SetBinLabel(2, "1");
295 m_skipProcFlag->GetYaxis()->SetLabelSize(0.05);
296 m_skipProcFlag->GetYaxis()->SetAlphanumeric();
297 m_skipProcFlag->SetMinimum(0);
298
299 m_injVetoFlag = new TH2F("injVetoFlag", "Injection veto flag; slot number; flag value", 64, 1, 17, 2, 0, 2);
300 m_injVetoFlag->GetXaxis()->SetNdivisions(16);
301 m_injVetoFlag->GetXaxis()->CenterLabels();
302 m_injVetoFlag->GetYaxis()->SetNdivisions(2);
303 m_injVetoFlag->GetYaxis()->SetBinLabel(1, "0");
304 m_injVetoFlag->GetYaxis()->SetBinLabel(2, "1");
305 m_injVetoFlag->GetYaxis()->SetLabelSize(0.05);
306 m_injVetoFlag->GetYaxis()->SetAlphanumeric();
307 m_injVetoFlag->SetMinimum(0);
308
309 m_injVetoFlagDiff = new TH1F("injVetoFlagDiff", "Injection veto flags check; ; fraction of events", 2, -0.5, 1.5);
310 m_injVetoFlagDiff->GetXaxis()->SetNdivisions(2);
311 m_injVetoFlagDiff->GetXaxis()->SetBinLabel(1, "flags the same");
312 m_injVetoFlagDiff->GetXaxis()->SetBinLabel(2, "flags differ");
313 m_injVetoFlagDiff->GetXaxis()->SetLabelSize(0.05);
314 m_injVetoFlagDiff->GetXaxis()->SetAlphanumeric();
315 m_injVetoFlagDiff->SetMinimum(0);
316
317 m_PSBypassMode = new TH2F("PSBypassMode", "PS-bypass mode; slot number; mode", 64, 1, 17, 8, 0, 8);
318 m_PSBypassMode->GetXaxis()->SetNdivisions(16);
319 m_PSBypassMode->GetYaxis()->SetNdivisions(8);
320 m_PSBypassMode->GetXaxis()->CenterLabels();
321 m_PSBypassMode->GetYaxis()->CenterLabels();
322 m_PSBypassMode->SetMinimum(0);
323
324 m_unpackErr = new TProfile("unpackErr", "Unpacker errors (per boardstack); slot number; fraction of events", 64, 1, 17, 0, 2);
325 m_unpackErr->GetXaxis()->SetNdivisions(16);
326 m_unpackErr->GetXaxis()->CenterLabels();
327 m_unpackErr->SetMinimum(0);
328 m_unpackErr->SetMarkerStyle(24);
329 m_unpackErr->SetFillColor(2);
330 m_unpackErr->SetDrawOption("hist");
331
332 // cd back to root directory
333 oldDir->cd();
334 }
335
337 {
338 // Register histograms (calls back defineHisto)
339
340 REG_HISTOGRAM;
341
342 // register dataobjects
343
344 m_rawFTSWs.isOptional();
345 m_productionEventDebugs.isOptional(); // not in sim
346 m_unpackerErrors.isOptional(); // not in sim
347 m_digits.isRequired();
348 m_recBunch.isOptional();
349 m_timeZeros.isOptional();
350 m_tracks.isOptional();
351 }
352
354 {
355 m_BoolEvtMonitor->Reset();
356 m_window_vs_slot->Reset();
357 m_eventT0->Reset();
358 m_bunchOffset->Reset();
359 m_time->Reset();
360 m_timeBG->Reset();
361 m_signalHits->Reset();
362 m_backgroundHits->Reset();
363 m_trackHits->Reset();
364 m_goodTDCAll->Reset();
365 m_badTDCAll->Reset();
366 m_goodHitsPerEventAll->Reset();
367 m_badHitsPerEventAll->Reset();
368 m_TOPOccAfterInjLER->Reset();
369 m_TOPOccAfterInjHER->Reset();
370 m_TOPEOccAfterInjLER->Reset();
371 m_TOPEOccAfterInjHER->Reset();
372 m_nhitInjLER->Reset();
373 m_nhitInjHER->Reset();
374 m_nhitInjLERcut->Reset();
375 m_nhitInjHERcut->Reset();
376 m_eventInjLER->Reset();
377 m_eventInjHER->Reset();
378 m_eventInjLERcut->Reset();
379 m_eventInjHERcut->Reset();
380
381 for (int i = 0; i < m_numModules; i++) {
382 m_window_vs_asic[i]->Reset();
383 m_goodHitsXY[i]->Reset();
384 m_badHitsXY[i]->Reset();
385 m_goodHitsAsics[i]->Reset();
386 m_badHitsAsics[i]->Reset();
387 m_goodTDC[i]->Reset();
388 m_badTDC[i]->Reset();
389 m_goodTiming[i]->Reset();
390 m_goodTimingBG[i]->Reset();
391 m_goodChannelHits[i]->Reset();
392 m_badChannelHits[i]->Reset();
393 m_pulseHeights[i]->Reset();
394 }
395
396 m_skipProcFlag->Reset();
397 m_injVetoFlag->Reset();
398 m_injVetoFlagDiff->Reset();
399 m_PSBypassMode->Reset();
400 m_unpackErr->Reset();
401 }
402
404 {
405
406 // check if event time is reconstructed; distinguish collision data and cosmics
407
408 bool recBunchValid = false;
409 bool cosmics = false;
410 if (m_recBunch.isValid()) { // collision data
411 recBunchValid = m_recBunch->isReconstructed(); // event time is reconstructed
412 } else if (m_timeZeros.getEntries() == 1) { // cosmics w/ reconstructed event time
413 cosmics = true;
414 m_eventT0->Fill(m_timeZeros[0]->getTime());
415 }
416
417 // fill bunch offset
418
419 if (recBunchValid) {
420 double t0 = m_commonT0->isRoughlyCalibrated() ? m_commonT0->getT0() : 0;
421 double offset = m_recBunch->getCurrentOffset() - t0;
422 offset -= m_bunchTimeSep * lround(offset / m_bunchTimeSep); // wrap around
423 m_bunchOffset->Fill(offset);
424 m_eventT0->Fill(m_recBunch->getTime());
425 }
426
427 // fill event desynchronization
428
429 if (m_digits.getEntries() > 0) {
430
431 // determine most common window number
432 std::map<unsigned, unsigned> firstWindows;
433 for (const auto& digit : m_digits) {
434 firstWindows[digit.getFirstWindow()] += 1;
435 }
436 auto it0 = firstWindows.begin();
437 for (auto it = firstWindows.begin(); it != firstWindows.end(); ++it) {
438 if (it->second > it0->second) it0 = it;
439 }
440
441 // fill histogram
442 for (const auto& digit : m_digits) {
443 int slot = digit.getModuleID();
444 int bs = digit.getBoardstackNumber();
445 double x = slot + bs / 4.0;
446 double y = digit.getFirstWindow() != it0->first ? 1 : 0 ;
447 m_BoolEvtMonitor->Fill(x, y);
448 }
449 }
450
451 // count tracks in the modules and store the momenta
452
453 std::vector<int> numTracks(m_numModules, 0);
454 std::vector<double> trackMomenta(m_numModules, 0);
455 for (const auto& track : m_tracks) {
456 const auto* fitResult = track.getTrackFitResultWithClosestMass(Const::pion);
457 if (not fitResult) continue;
458 int slot = getModuleID(track);
459 if (slot == 0) continue;
460 numTracks[slot - 1]++;
461 trackMomenta[slot - 1] = std::max(trackMomenta[slot - 1], fitResult->getMomentum().R());
462 }
463
464 // count events w/ and w/o track in the slot
465
466 if (recBunchValid or cosmics) {
467 for (size_t i = 0; i < numTracks.size(); i++) {
468 bool hit = numTracks[i] > 0;
469 m_trackHits->Fill(i + 1, hit);
470 }
471 }
472
473 // select modules for counting hits in signal and background time windows
474
475 std::vector<bool> selectedSlots(m_numModules, false);
476 for (size_t i = 0; i < selectedSlots.size(); i++) {
477 selectedSlots[i] = (recBunchValid or cosmics) and numTracks[i] == 1 and trackMomenta[i] > m_momentumCut;
478 }
479
480 // prepare counters
481
482 int nHits_good = 0;
483 int nHits_bad = 0;
484 std::vector<int> numSignalHits(m_numModules, 0);
485 std::vector<int> numBackgroundHits(m_numModules, 0);
486
487 // loop over digits, fill histograms and increment counters
488
489 for (const auto& digit : m_digits) {
490 int slot = digit.getModuleID();
491 if (slot < 1 or slot > m_numModules) {
492 B2ERROR("Invalid slot ID found in TOPDigits: ID = " << slot);
493 continue;
494 }
495 int asic_no = digit.getChannel() / 8;
496 int asic_ch = digit.getChannel() % 8;
497
498 double window = digit.getRawTime() / 64 + 220;
499 if (window < 0) window += 512;
500 m_window_vs_slot->Fill(digit.getModuleID() + digit.getBoardstackNumber() / 4.0, window);
501 m_window_vs_asic[slot - 1]->Fill(asic_no, window);
502
503 if (digit.getHitQuality() != TOPDigit::c_Junk) { // good hits
504 m_goodHitsXY[slot - 1]->Fill(digit.getPixelCol(), digit.getPixelRow());
505 m_goodHitsAsics[slot - 1]->Fill(asic_no, asic_ch);
506 m_goodTDC[slot - 1]->Fill(digit.getRawTime());
507 m_goodTDCAll->Fill(digit.getRawTime());
508 m_goodChannelHits[slot - 1]->Fill(digit.getChannel());
509 m_pulseHeights[slot - 1]->Fill(digit.getPMTNumber(), digit.getPulseHeight());
510 nHits_good++;
511 if (digit.hasStatus(TOPDigit::c_EventT0Subtracted)) {
512 double time = digit.getTime();
513 if (cosmics) time += 10; // move for 10 ns in order to get the complete signal at positive times
514 if (numTracks[slot - 1] > 0) {
515 m_goodTiming[slot - 1]->Fill(time);
516 m_time->Fill(time);
517 } else {
518 m_goodTimingBG[slot - 1]->Fill(time);
519 m_timeBG->Fill(time);
520 }
521 if (selectedSlots[slot - 1] and abs(time) < 50) {
522 if (time > 0) numSignalHits[slot - 1]++;
523 else numBackgroundHits[slot - 1]++;
524 }
525 }
526 } else { // bad hits: FE not valid, pedestal jump, too short or too wide pulses
527 m_badHitsXY[slot - 1]->Fill(digit.getPixelCol(), digit.getPixelRow());
528 m_badHitsAsics[slot - 1]->Fill(asic_no, asic_ch);
529 m_badTDC[slot - 1]->Fill(digit.getRawTime());
530 m_badTDCAll->Fill(digit.getRawTime());
531 m_badChannelHits[slot - 1]->Fill(digit.getChannel());
532 nHits_bad++;
533 }
534 }
535
536 // histogram counters
537
538 m_goodHitsPerEventAll->Fill(nHits_good);
539 m_badHitsPerEventAll->Fill(nHits_bad);
540 for (int slot = 1; slot <= m_numModules; slot++) {
541 if (selectedSlots[slot - 1]) {
542 m_signalHits->Fill(slot, numSignalHits[slot - 1]);
543 m_backgroundHits->Fill(slot, numBackgroundHits[slot - 1]);
544 }
545 }
546
547 // fill injection histograms
548
549 for (auto& it : m_rawFTSWs) {
550 B2DEBUG(29, "TTD FTSW : " << hex << it.GetTTUtime(0) << " " << it.GetTTCtime(0) << " EvtNr " << it.GetEveNo(0) << " Type " <<
551 (it.GetTTCtimeTRGType(0) & 0xF) << " TimeSincePrev " << it.GetTimeSincePrevTrigger(0) << " TimeSinceInj " <<
552 it.GetTimeSinceLastInjection(0) << " IsHER " << it.GetIsHER(0) << " Bunch " << it.GetBunchNumber(0));
553 auto time_clk = it.GetTimeSinceLastInjection(0); // expressed in system clock
554 if (time_clk != 0x7FFFFFFF) {
555 unsigned int nentries = m_digits.getEntries();
556 double time_us = time_clk / 127.0; // 127MHz clock ticks to us, inexact rounding
557 double time_ms = time_us / 1000;
558 double time_1280 = time_clk % 1280; // within beam cycle, expressed in system clock
559 if (it.GetIsHER(0)) {
560 m_TOPOccAfterInjHER->Fill(time_us, nentries);
561 m_TOPEOccAfterInjHER->Fill(time_us);
562 m_nhitInjHER->Fill(time_ms, time_1280, nHits_good);
563 m_eventInjHER->Fill(time_ms, time_1280);
564 if (nHits_good > 1000) {
565 m_nhitInjHERcut->Fill(time_ms, time_1280, nHits_good);
566 m_eventInjHERcut->Fill(time_ms, time_1280);
567 }
568 } else {
569 m_TOPOccAfterInjLER->Fill(time_us, nentries);
570 m_TOPEOccAfterInjLER->Fill(time_us);
571 m_nhitInjLER->Fill(time_ms, time_1280, nHits_good);
572 m_eventInjLER->Fill(time_ms, time_1280);
573 if (nHits_good > 1000) {
574 m_nhitInjLERcut->Fill(time_ms, time_1280, nHits_good);
575 m_eventInjLERcut->Fill(time_ms, time_1280);
576 }
577 }
578 }
579 }
580
581 // fill raw data header histograms
582
583 const auto& feMapper = TOPGeometryPar::Instance()->getFrontEndMapper();
584 double differ = 0;
585 for (const auto& dbg : m_productionEventDebugs) {
586 auto scrodID = dbg.getScrodID();
587 const auto* femap = feMapper.getMap(scrodID);
588 if (not femap) {
589 B2ERROR("No front-end map available for scrodID " << scrodID);
590 continue;
591 }
592 auto slot = femap->getModuleID();
593 auto bs = femap->getBoardstackNumber();
594 double x = slot + bs / 4.0;
595 m_skipProcFlag->Fill(x, dbg.getSkipProcessingFlag());
596 m_injVetoFlag->Fill(x, dbg.getInjectionVetoFlag());
597 m_PSBypassMode->Fill(x, dbg.getPSBypassMode());
598 if (dbg.getInjectionVetoFlag() != m_productionEventDebugs[0]->getInjectionVetoFlag()) differ = 1;
599 }
600 m_injVetoFlagDiff->Fill(differ);
601
602 if (m_unpackerErrors.isValid()) {
603 const auto& flags = m_unpackerErrors->getErrorFlags();
604 for (size_t bit = 0; bit < flags.size(); bit++) {
605 int slot = bit / 4 + 1;
606 int bs = bit % 4;
607 double x = slot + bs / 4.0;
608 m_unpackErr->Fill(x, flags[bit]);
609 }
610 }
611
612 }
613
614
615 int TOPDQMModule::getModuleID(const Track& track) const
616 {
617 Const::EDetector myDetID = Const::EDetector::TOP;
618 int pdgCode = std::abs(Const::pion.getPDGCode());
619
620 RelationVector<ExtHit> extHits = track.getRelationsWith<ExtHit>();
621 for (const auto& extHit : extHits) {
622 if (std::abs(extHit.getPdgCode()) != pdgCode) continue;
623 if (extHit.getDetectorID() != myDetID) continue;
624 if (extHit.getCopyID() < 1 or extHit.getCopyID() > m_numModules) continue;
625 return extHit.getCopyID();
626 }
627
628 return 0;
629 }
630
631
633} // end Belle2 namespace
634
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
TProfile * m_unpackErr
fraction of events with boardstack unpacker errors
TProfile2D * m_nhitInjLER
average number of good digits (LER injection)
TH2D * m_BoolEvtMonitor
Event desynchronization monitoring.
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.
StoreObjPtr< TOPUnpackerErrors > m_unpackerErrors
unpacker error flags
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
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 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.