60 TDirectory* oldDir = gDirectory;
71 m_BoolEvtMonitor =
new TH2D(
"BoolEvtMonitor",
"Event synchronization", 64, 1, 17, 2, 0, 2);
84 m_window_vs_slot =
new TH2F(
"window_vs_slot",
"Asic windows", 64, 1, 17, 512, 0, 512);
93 m_eventT0 =
new TH1F(
"eventT0",
"Event T0; event T0 [ns]; events per bin", nbinsT0, -rangeT0 / 2, rangeT0 / 2);
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");
104 m_timeBG =
new TH1F(
"goodHitTimesBG",
"Time distribution of good hits (background)", 1000, -20, 80);
106 m_timeBG->SetYTitle(
"hits per bin");
108 m_signalHits =
new TProfile(
"signalHits",
"Number of good hits per track in [0, 50] ns", 16, 0.5, 16.5, 0, 1000);
114 m_backgroundHits =
new TProfile(
"backgroundHits",
"Number of good hits pet track in [-50, 0] ns", 16, 0.5, 16.5, 0, 1000);
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);
124 int nbinsHits = 1000;
125 double xmaxHits = 10000;
126 m_goodHitsPerEventAll =
new TH1F(
"goodHitsPerEventAll",
"Number of good hits per event", nbinsHits, 0, xmaxHits);
130 m_badHitsPerEventAll =
new TH1F(
"badHitsPerEventAll",
"Number of junk hits per event", nbinsHits, 0, xmaxHits);
135 double xminTDC = -100;
136 double xmaxTDC = 700;
137 m_goodTDCAll =
new TH1F(
"goodTDCAll",
"Raw time distribution of good hits", nbinsTDC, xminTDC, xmaxTDC);
141 m_badTDCAll =
new TH1F(
"badTDCAll",
"Raw time distribution of junk hits", nbinsTDC, xminTDC, xmaxTDC);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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");
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);
289 m_skipProcFlag =
new TH2F(
"skipProcFlag",
"Skip processing flag; slot number; flag value", 64, 1, 17, 2, 0, 2);
299 m_injVetoFlag =
new TH2F(
"injVetoFlag",
"Injection veto flag; slot number; flag value", 64, 1, 17, 2, 0, 2);
309 m_injVetoFlagDiff =
new TH1F(
"injVetoFlagDiff",
"Injection veto flags check; ; fraction of events", 2, -0.5, 1.5);
317 m_PSBypassMode =
new TH2F(
"PSBypassMode",
"PS-bypass mode; slot number; mode", 64, 1, 17, 8, 0, 8);
324 m_unpackErr =
new TProfile(
"unpackErr",
"Unpacker errors (per boardstack); slot number; fraction of events", 64, 1, 17, 0, 2);
408 bool recBunchValid =
false;
409 bool cosmics =
false;
411 recBunchValid =
m_recBunch->isReconstructed();
421 double offset =
m_recBunch->getCurrentOffset() - t0;
432 std::map<unsigned, unsigned> firstWindows;
433 for (
const auto& digit :
m_digits) {
434 firstWindows[digit.getFirstWindow()] += 1;
436 auto it0 = firstWindows.begin();
437 for (
auto it = firstWindows.begin(); it != firstWindows.end(); ++it) {
438 if (it->second > it0->second) it0 = it;
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 ;
455 for (
const auto& track :
m_tracks) {
456 const auto* fitResult = track.getTrackFitResultWithClosestMass(
Const::pion);
457 if (not fitResult)
continue;
459 if (slot == 0)
continue;
460 numTracks[slot - 1]++;
461 trackMomenta[slot - 1] = std::max(trackMomenta[slot - 1], fitResult->getMomentum().R());
466 if (recBunchValid or cosmics) {
467 for (
size_t i = 0; i < numTracks.size(); i++) {
468 bool hit = numTracks[i] > 0;
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;
489 for (
const auto& digit :
m_digits) {
490 int slot = digit.getModuleID();
492 B2ERROR(
"Invalid slot ID found in TOPDigits: ID = " << slot);
495 int asic_no = digit.getChannel() / 8;
496 int asic_ch = digit.getChannel() % 8;
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);
503 if (digit.getHitQuality() != TOPDigit::c_Junk) {
504 m_goodHitsXY[slot - 1]->Fill(digit.getPixelCol(), digit.getPixelRow());
506 m_goodTDC[slot - 1]->Fill(digit.getRawTime());
509 m_pulseHeights[slot - 1]->Fill(digit.getPMTNumber(), digit.getPulseHeight());
511 if (digit.hasStatus(TOPDigit::c_EventT0Subtracted)) {
512 double time = digit.getTime();
513 if (cosmics) time += 10;
514 if (numTracks[slot - 1] > 0) {
521 if (selectedSlots[slot - 1] and abs(time) < 50) {
522 if (time > 0) numSignalHits[slot - 1]++;
523 else numBackgroundHits[slot - 1]++;
527 m_badHitsXY[slot - 1]->Fill(digit.getPixelCol(), digit.getPixelRow());
529 m_badTDC[slot - 1]->Fill(digit.getRawTime());
541 if (selectedSlots[slot - 1]) {
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);
554 if (time_clk != 0x7FFFFFFF) {
555 unsigned int nentries =
m_digits.getEntries();
556 double time_us = time_clk / 127.0;
557 double time_ms = time_us / 1000;
558 double time_1280 = time_clk % 1280;
559 if (it.GetIsHER(0)) {
564 if (nHits_good > 1000) {
573 if (nHits_good > 1000) {
586 auto scrodID = dbg.getScrodID();
587 const auto* femap = feMapper.getMap(scrodID);
589 B2ERROR(
"No front-end map available for scrodID " << scrodID);
592 auto slot = femap->getModuleID();
593 auto bs = femap->getBoardstackNumber();
594 double x = slot + bs / 4.0;
604 for (
size_t bit = 0; bit < flags.size(); bit++) {
605 int slot = bit / 4 + 1;
607 double x = slot + bs / 4.0;