Project
Loading...
Searching...
No Matches
SimpleEventDisplayGUI.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#include <fmt/format.h>
13#include <iostream>
14#include <fstream>
15#include <memory>
16#include <unistd.h>
17#include <string_view>
18#include <filesystem>
19
20#include "TGFrame.h"
21#include "TGTextEntry.h"
22#include "TGLabel.h"
23#include "TGButton.h"
24#include "TGNumberEntry.h"
25#include "TGButtonGroup.h"
26#include "TQObject.h"
27#include "TH2Poly.h"
28#include "TPolyMarker.h"
29#include "TLine.h"
30
31#include "TH1F.h"
32#include "TH2F.h"
33#include "TFile.h"
34#include "TSystem.h"
35#include "TStyle.h"
36#include "TCanvas.h"
37#include "TObjArray.h"
38#include "TROOT.h"
39#include "TMath.h"
40#include "TApplication.h"
41
42#include <fairlogger/Logger.h>
43
44#include "GPUTPCGeometry.h"
45#include "TPCBase/Mapper.h"
46#include "TPCBase/CalDet.h"
47#include "TPCBase/CalArray.h"
48#include "TPCBase/Painter.h"
50
52
53using namespace o2::tpc;
54namespace fs = std::filesystem;
55
56//__________________________________________________________________________
58{
59 float xsize = 160;
60 float ysize = 25;
61 float yoffset = 10;
62 float ysize_dist = 2;
63 float mainx = xsize + 2 * 10;
64 float mainy = 335;
65 int ycount = 0;
66 float currentY = yoffset + ycount * (ysize_dist + ysize);
67
68 auto nextY = [&ycount, &currentY, yoffset, ysize, ysize_dist]() {
69 ++ycount;
70 currentY = yoffset + ycount * (ysize_dist + ysize);
71 };
72
73 TGMainFrame* mFrameMain = new TGMainFrame(gClient->GetRoot(), mainx, mainy, kMainFrame | kVerticalFrame);
74 mFrameMain->SetLayoutBroken(kTRUE);
75 mFrameMain->SetCleanup(kDeepCleanup);
76
77 TGCompositeFrame* mContRight = new TGCompositeFrame(mFrameMain, xsize + 5, mainy, kVerticalFrame | kFixedWidth | kFitHeight);
78 mFrameMain->AddFrame(mContRight, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandY | kLHintsExpandX, 3, 5, 3, 3));
79
80 //---------------------------
81 TGTextButton* mFrameNextEvent = new TGTextButton(mContRight, "&Next Event");
82 mContRight->AddFrame(mFrameNextEvent, new TGLayoutHints(kLHintsExpandX));
83
84 mFrameNextEvent->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "next(=-1)");
85 mFrameNextEvent->SetTextColor(200);
86 mFrameNextEvent->SetToolTipText("Go to next event");
87 mFrameNextEvent->MoveResize(10, currentY, xsize, (unsigned int)ysize);
88 nextY();
89
90 //---------------------------
91 TGTextButton* mFramePreviousEvent = new TGTextButton(mContRight, "&Previous Event");
92 mContRight->AddFrame(mFramePreviousEvent, new TGLayoutHints(kLHintsExpandX));
93 if (mRunMode == RunMode::Online) {
94 mFramePreviousEvent->SetState(kButtonDisabled);
95 }
96
97 mFramePreviousEvent->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "next(=-2)");
98 mFramePreviousEvent->SetTextColor(200);
99 mFramePreviousEvent->SetToolTipText("Go to previous event");
100 mFramePreviousEvent->MoveResize(10, currentY, xsize, (unsigned int)ysize);
101 nextY();
102
103 //---------------------------
104
105 TGTextButton* mGoToEvent = new TGTextButton(mContRight, "&Go to event");
106 mContRight->AddFrame(mGoToEvent, new TGLayoutHints(kLHintsNormal));
107
108 mGoToEvent->SetTextColor(200);
109 mGoToEvent->SetToolTipText("Go to event");
110 mGoToEvent->MoveResize(10, currentY, 0.65 * xsize, (unsigned int)ysize);
111 mGoToEvent->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "callEventNumber()");
112
113 //
114 auto* ftbuf = new TGTextBuffer(10);
115 ftbuf->AddText(0, "0");
116 mEventNumber = new TGTextEntry(mContRight, ftbuf);
117 mContRight->AddFrame(mEventNumber, new TGLayoutHints(kFitHeight));
118 mEventNumber->MoveResize(0.7 * xsize, currentY, 0.3 * xsize, (unsigned int)ysize);
119 mEventNumber->SetAlignment(kTextRight);
120 nextY();
121
122 //---------------------------
123 TGTextButton* mApplySignalThreshold = new TGTextButton(mContRight, "&Apply Threshold");
124 mContRight->AddFrame(mApplySignalThreshold, new TGLayoutHints(kLHintsNormal));
125
126 mApplySignalThreshold->SetTextColor(200);
127 mApplySignalThreshold->SetToolTipText("Apply Threshold");
128 mApplySignalThreshold->MoveResize(10, currentY, 0.65 * xsize, (unsigned int)ysize);
129 mApplySignalThreshold->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "applySignalThreshold()");
130
131 auto* signalThresholdBuf = new TGTextBuffer(10);
132 signalThresholdBuf->AddText(0, "0");
133 mSignalThresholdValue = new TGTextEntry(mContRight, signalThresholdBuf);
134 mSignalThresholdValue->MoveResize(0.7 * xsize, currentY, 0.3 * xsize, (unsigned int)ysize);
135 mSignalThresholdValue->SetAlignment(kTextRight);
136 mSignalThresholdValue->Connect("ReturnPressed()", "o2::tpc::SimpleEventDisplayGUI", this, "applySignalThreshold()");
137 nextY();
138
139 //---------------------------
140 mCheckSingleTB = new TGCheckButton(mContRight, "One TB");
141 mContRight->AddFrame(mCheckSingleTB, new TGLayoutHints(kLHintsExpandX));
142
143 mCheckSingleTB->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "toggleSingleTimeBin()");
144 mCheckSingleTB->SetTextColor(200);
145 mCheckSingleTB->SetToolTipText("Show single time bin");
146 mCheckSingleTB->MoveResize(10, currentY, 0.5 * xsize, (unsigned int)ysize);
147 mCheckSingleTB->SetDown(0);
148
149 mSelTimeBin = new TGNumberEntry(mContRight, mEvDisp.getFirstTimeBin(), 6, 999, TGNumberFormat::kNESInteger,
150 TGNumberFormat::kNEAPositive,
151 TGNumberFormat::kNELLimitMinMax,
152 mEvDisp.getFirstTimeBin(), mEvDisp.getLastTimeBin());
153
154 mSelTimeBin->MoveResize(0.55 * xsize, currentY, 0.45 * xsize, (unsigned int)ysize);
155 mSelTimeBin->Connect("ValueSet(Long_t)", "o2::tpc::SimpleEventDisplayGUI", this, "selectTimeBin()");
156 (mSelTimeBin->GetNumberEntry())->Connect("ReturnPressed()", "o2::tpc::SimpleEventDisplayGUI", this, "selectTimeBin()");
157 nextY();
158
159 //---------------------------
160 mCheckFFT = new TGCheckButton(mContRight, "Show FFT");
161 mContRight->AddFrame(mCheckFFT, new TGLayoutHints(kLHintsExpandX));
162
163 mCheckFFT->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "toggleFFT()");
164 mCheckFFT->SetTextColor(200);
165 mCheckFFT->SetToolTipText("Switch on FFT calculation");
166 mCheckFFT->MoveResize(10, currentY, xsize, (unsigned int)ysize);
167 mCheckFFT->SetDown(0);
168 toggleFFT();
169 nextY();
170
171 //---------------------------
172 mCheckOccupancy = new TGCheckButton(mContRight, "Show Occupancy");
173 mContRight->AddFrame(mCheckOccupancy, new TGLayoutHints(kLHintsExpandX));
174
175 mCheckOccupancy->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "toggleOccupancy()");
176 mCheckOccupancy->SetTextColor(200);
177 mCheckOccupancy->SetToolTipText("Switch on Occupancy calculation");
178 mCheckOccupancy->MoveResize(10, currentY, xsize, (unsigned int)ysize);
179 mCheckOccupancy->SetDown(0);
181 nextY();
182
183 //---------------------------
184 mCheckPadTime = new TGCheckButton(mContRight, "Show PadTime");
185 mContRight->AddFrame(mCheckPadTime, new TGLayoutHints(kLHintsExpandX));
186
187 mCheckPadTime->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "togglePadTime()");
188 mCheckPadTime->SetTextColor(200);
189 mCheckPadTime->SetToolTipText("Switch on PadTime calculation");
190 mCheckPadTime->MoveResize(10, currentY, xsize, (unsigned int)ysize);
191 mCheckPadTime->SetDown(0);
192 nextY();
193
194 //---------------------------
195 mCheckShowClusters = new TGCheckButton(mContRight, "Overlay clusters");
196 mContRight->AddFrame(mCheckShowClusters, new TGLayoutHints(kLHintsExpandX));
197
198 mCheckShowClusters->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "toggleClusters()");
199 mCheckShowClusters->SetTextColor(200);
200 mCheckShowClusters->SetToolTipText("Switch on ShowClusters calculation");
201 mCheckShowClusters->MoveResize(10, currentY, xsize, (unsigned int)ysize);
202 mCheckShowClusters->SetDown(0);
203 mCheckShowClusters->SetEnabled(kFALSE);
204
205 nextY();
206
207 //---------------------------
208 mFlagGroup = new TGVButtonGroup(mContRight, "Cl Flags");
209 auto hframe = new TGHorizontalFrame(mFlagGroup);
210 const std::string flagTips[NCheckClFlags] = {"Golden", "Split Pad", "Split Time", "Edge", "Single Pad and/or Time"};
211 for (int iCheck = 0; iCheck < NCheckClFlags; ++iCheck) {
212 mCheckClFlags[iCheck] = new TGCheckButton(hframe, "", 10000 + iCheck);
213 mCheckClFlags[iCheck]->SetToolTipText(flagTips[iCheck].data());
214 mCheckClFlags[iCheck]->SetDown(1);
215 mCheckClFlags[iCheck]->SetEnabled(kFALSE);
216 mCheckClFlags[iCheck]->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "showClusters(=-1,-1)");
217 hframe->AddFrame(mCheckClFlags[iCheck], new TGLayoutHints(kLHintsExpandX));
218 }
219 mFlagGroup->AddFrame(hframe, new TGLayoutHints(kLHintsExpandX));
220 mFlagGroup->Show();
221 mFlagGroup->MoveResize(10, currentY, xsize, (unsigned int)2 * ysize);
222 mContRight->AddFrame(mFlagGroup, new TGLayoutHints(kLHintsExpandX));
223 mFlagGroup->SetState(kFALSE);
224 nextY();
225 nextY();
226
227 //---------------------------
228 TGTextButton* mFrameExit = new TGTextButton(mContRight, "Exit ROOT");
229 mContRight->AddFrame(mFrameExit, new TGLayoutHints(kLHintsExpandX));
230
231 mFrameExit->Connect("Clicked()", "o2::tpc::SimpleEventDisplayGUI", this, "exitRoot()");
232 mFrameExit->SetTextColor(200);
233 mFrameExit->SetToolTipText("Exit the ROOT process");
234 mFrameExit->MoveResize(10, currentY, xsize, (unsigned int)ysize);
235 nextY();
236
237 //---------------------------
238 mFrameMain->MapSubwindows();
239 mFrameMain->MapWindow();
240 mFrameMain->SetWindowName("OM");
241 mFrameMain->MoveResize(50, 50, (unsigned int)mainx, (unsigned int)currentY + 20);
242 mFrameMain->Move(4 * 400 + 10, 10);
243}
244
245//__________________________________________________________________________
247{
248 if (mCheckFFT->IsDown()) {
249 if (gROOT->GetListOfCanvases()->FindObject("SigIFFT")) {
250 return;
251 }
252 // FFT canvas
253 const int w = 400;
254 const int h = 400;
255 const int hOff = 60;
256 const int vOff = 2;
257 new TCanvas("SigIFFT", "SigIFFT", -3 * (w + vOff), 0 * h, w, h);
258 new TCanvas("SigOFFT", "SigOFFT", -3 * (w + vOff), 1 * h + hOff, w, h);
259 } else {
260 delete gROOT->GetListOfCanvases()->FindObject("SigIFFT");
261 delete gROOT->GetListOfCanvases()->FindObject("SigOFFT");
262 delete mHFFTI;
263 delete mHFFTO;
264 mHFFTI = mHFFTO = nullptr;
265 }
266}
267
268//______________________________________________________________________________
269void SimpleEventDisplayGUI::initOccupancyHists()
270{
271 const int w = 400;
272 const int h = 400;
273 const int hOff = 60;
274 const int vOff = 2;
275 TCanvas* c = nullptr;
276
277 if (mShowSides) {
278 // histograms and canvases for occupancy values A-Side
279 c = new TCanvas("OccupancyValsA", "OccupancyValsA", 0 * w - 1, 0 * h, w, h);
280
281 c->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
282 "o2::tpc::SimpleEventDisplayGUI", this,
283 "selectSectorExec(int,int,int,TObject*)");
284
285 mHOccupancyA = new TH2F("hOccupancyValsA", "Occupancy Values Side A;x (cm);y (cm)", 330, -250, 250, 330, -250, 250);
286 mHOccupancyA->SetStats(kFALSE);
287 mHOccupancyA->SetUniqueID(0); // A-Side
288 mHOccupancyA->Draw("colz");
290
291 // histograms and canvases for occupancy values C-Side
292 c = new TCanvas("OccupancyValsC", "OccupancyValsC", 0 * w - 1, 1 * h + hOff, w, h);
293
294 c->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
295 "o2::tpc::SimpleEventDisplayGUI", this,
296 "selectSectorExec(int,int,int,TObject*)");
297 mHOccupancyC = new TH2F("hOccupancyValsC", "Occupancy Values Side C;x (cm);y (cm)", 330, -250, 250, 330, -250, 250);
298 mHOccupancyC->SetStats(kFALSE);
299 mHOccupancyC->SetUniqueID(1); // C-Side
300 mHOccupancyC->Draw("colz");
302 }
303
304 // histograms and canvases for occupancy values IROC
305 c = new TCanvas("OccupancyValsI", "OccupancyValsI", -1 * (w + vOff), 0 * h, w, h);
306
307 c->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
308 "o2::tpc::SimpleEventDisplayGUI", this,
309 "drawPadSignal(int,int,int,TObject*)");
310 mHOccupancyIROC = new TH2F("hOccupancyValsIROC", "Occupancy Values IROC;row;pad", 63, 0, 63, 108, -54, 54);
311 mHOccupancyIROC->SetDirectory(nullptr);
312 mHOccupancyIROC->SetStats(kFALSE);
313 mHOccupancyIROC->Draw("colz");
314
315 // histograms and canvases for occupancy values OROC
316 c = new TCanvas("OccupancyValsO", "OccupancyValsO", -1 * (w + vOff), 1 * h + hOff, w, h);
317
318 c->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
319 "o2::tpc::SimpleEventDisplayGUI", this,
320 "drawPadSignal(int,int,int,TObject*)");
321 mHOccupancyOROC = new TH2F("hOccupancyValsOROC", "Occupancy Values OROC;row;pad", 89, 0, 89, 140, -70, 70);
322 mHOccupancyOROC->SetDirectory(nullptr);
323 mHOccupancyOROC->SetStats(kFALSE);
324 mHOccupancyOROC->Draw("colz");
325
327}
328
329void SimpleEventDisplayGUI::deleteOccupancyHists()
330{
331 delete gROOT->GetListOfCanvases()->FindObject("OccupancyValsA");
332 delete mHOccupancyA;
333 mHOccupancyA = nullptr;
334
335 delete gROOT->GetListOfCanvases()->FindObject("OccupancyValsC");
336 delete mHOccupancyC;
337 mHOccupancyC = nullptr;
338
339 delete gROOT->GetListOfCanvases()->FindObject("OccupancyValsO");
340 delete mHOccupancyOROC;
341 mHOccupancyOROC = nullptr;
342
343 delete gROOT->GetListOfCanvases()->FindObject("OccupancyValsI");
344 delete mHOccupancyIROC;
345 mHOccupancyIROC = nullptr;
346
347 delete gROOT->GetListOfCanvases()->FindObject("hOccupancyValsA");
348 delete gROOT->GetListOfCanvases()->FindObject("hOccupancyValsC");
349 delete gROOT->GetListOfCanvases()->FindObject("hOccupancyValsIROC");
350 delete gROOT->GetListOfCanvases()->FindObject("hOccupancyValsOROC");
351}
352
353void SimpleEventDisplayGUI::initPadTimeHists()
354{
355 // histograms and canvases for pad vs. time values IROC
356 const int w = 400;
357 const int h = 400;
358 const int hOff = 60;
359 const int vOff = 4;
360 TCanvas* c = nullptr;
361
362 const Int_t firstTimeBin = mEvDisp.getFirstTimeBin();
363 const Int_t lastTimeBin = mEvDisp.getLastTimeBin();
364 const Int_t nTimeBins = mEvDisp.getLastTimeBin() - mEvDisp.getFirstTimeBin();
365
366 c = new TCanvas("PadTimeValsI", "PadTimeValsI", -3 * (w + vOff), 0 * h, w, h);
367
368 c->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
369 "o2::tpc::SimpleEventDisplayGUI", this,
370 "drawPadSignal(int,int,int,TObject*)");
371 mHPadTimeIROC = new TH2F("hPadTimeValsI", "PadTime Values IROC;time bin;pad", nTimeBins, firstTimeBin, lastTimeBin, 108, -54, 54);
372 // mHPadTimeIROC->SetDirectory(nullptr);
373 mHPadTimeIROC->SetStats(kFALSE);
374 mHPadTimeIROC->Draw("colz");
375 if (!mClustersIROC) {
376 mClustersIROC = new TPolyMarker;
377 mClustersIROC->SetMarkerSize(1);
378 mClustersIROC->SetMarkerStyle(29);
379 mClustersIROC->SetMarkerColor(kMagenta);
380 mClustersIROC->Draw();
381 }
382
383 // histograms and canvases for pad vs. time values OROC
384 c = new TCanvas("PadTimeValsO", "PadTimeValsO", -3 * (w + vOff), 1 * h + hOff, w, h);
385
386 c->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
387 "o2::tpc::SimpleEventDisplayGUI", this,
388 "drawPadSignal(int,int,int,TObject*)");
389 mHPadTimeOROC = new TH2F("hPadTimeValsO", "PadTime Values OROC;time bin;pad", nTimeBins, firstTimeBin, lastTimeBin, 140, -70, 70);
390 // mHPadTimeOROC->SetDirectory(nullptr);
391 mHPadTimeOROC->SetStats(kFALSE);
392 mHPadTimeOROC->Draw("colz");
393 if (!mClustersOROC) {
394 mClustersOROC = new TPolyMarker;
395 mClustersOROC->SetMarkerSize(1);
396 mClustersOROC->SetMarkerStyle(29);
397 mClustersOROC->SetMarkerColor(kMagenta);
398 mClustersOROC->Draw();
399 }
400}
401
402void SimpleEventDisplayGUI::deletePadTimeHists()
403{
404 delete gROOT->GetListOfCanvases()->FindObject("PadTimeValsO");
405 delete mHPadTimeOROC;
406 mHPadTimeOROC = nullptr;
407
408 delete gROOT->GetListOfCanvases()->FindObject("PadTimeValsI");
409 delete mHPadTimeIROC;
410 mHPadTimeIROC = nullptr;
411
412 delete gROOT->GetListOfCanvases()->FindObject("hPadTimeValsIROC");
413 delete gROOT->GetListOfCanvases()->FindObject("hPadTimeValsOROC");
414}
415
416void SimpleEventDisplayGUI::initSingleTBHists()
417{
418 // histograms and canvases for pad vs. time values IROC
419 const int w = 400;
420 const int h = 400;
421 const int hOff = 60;
422 const int vOff = 4;
423 TCanvas* c = nullptr;
424
425 const Int_t firstTimeBin = mEvDisp.getFirstTimeBin();
426 const Int_t lastTimeBin = mEvDisp.getLastTimeBin();
427 const Int_t nTimeBins = mEvDisp.getLastTimeBin() - mEvDisp.getFirstTimeBin();
428
429 c = new TCanvas("SingleTB", "SingleTB", -3 * (w + vOff), 1 * h + hOff, 1.8 * w, h);
430
431 c->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
432 "o2::tpc::SimpleEventDisplayGUI", this,
433 "drawPadSignal(int,int,int,TObject*)");
434 mSectorPolyTimeBin = painter::makeSectorHist("hSingleTB");
435 // mHPadTimeIROC->SetDirectory(nullptr);
436 mSectorPolyTimeBin->SetStats(kFALSE);
437 mSectorPolyTimeBin->Draw("colz");
438
439 if (!mClustersRowPad) {
440 mClustersRowPad = new TPolyMarker;
441 mClustersRowPad->SetMarkerSize(1);
442 mClustersRowPad->SetMarkerStyle(29);
443 mClustersRowPad->SetMarkerColor(kMagenta);
444 }
445 mClustersRowPad->Draw();
446}
447
448void SimpleEventDisplayGUI::deleteSingleTBHists()
449{
450 delete gROOT->GetListOfCanvases()->FindObject("SingleTB");
451 delete mSectorPolyTimeBin;
452 mSectorPolyTimeBin = nullptr;
453}
454
455//__________________________________________________________________________
457{
458 if (mCheckPadTime->IsDown()) {
459 initPadTimeHists();
460 mCheckShowClusters->SetEnabled(kTRUE);
461 } else {
462 deletePadTimeHists();
463 mCheckShowClusters->SetEnabled(kFALSE);
464 }
465}
466
467//__________________________________________________________________________
469{
470 if (mCheckOccupancy->IsDown()) {
471 initOccupancyHists();
472 } else {
473 deleteOccupancyHists();
474 }
475}
476
477//__________________________________________________________________________
479{
480 if (mCheckSingleTB->IsDown()) {
481 initSingleTBHists();
483 } else {
484 deleteSingleTBHists();
485 if (mClustersRowPad) {
486 mClustersRowPad->SetPolyMarker(0);
487 }
488 }
489}
490
491//______________________________________________________________________________
493{
494 if (mCheckShowClusters->IsDown()) {
495 if (mTPCclusterReader.getTreeSize() > 0) {
496 return;
497 }
498 fs::path p{mInputFileInfo};
499 std::string clusterFile = fmt::format("{}/tpc-native-clusters.root", p.parent_path().c_str());
500 if (!fs::exists(clusterFile)) {
501 LOGP(warn, "Clusters file '{}' does not exist, trying local 'tpc-native-clusters.root'", clusterFile);
502 clusterFile = "tpc-native-clusters.root";
503 if (!fs::exists(clusterFile)) {
504 LOGP(error, "Clusters file '{}' does not exist, can't load clusters", clusterFile);
505 return;
506 }
507 }
508 LOGP(info, "loading clusters from file '{}'", clusterFile);
509 mTPCclusterReader.init(clusterFile.data());
510 gROOT->cd();
511 const auto presentEventNumber = mEvDisp.getPresentEventNumber();
512 fillClusters(presentEventNumber);
513 mFlagGroup->SetState(kTRUE);
514 for (int iCheck = 0; iCheck < NCheckClFlags; ++iCheck) {
515 mCheckClFlags[iCheck]->SetEnabled(kTRUE);
516 }
517 } else {
518 if (mClustersIROC) {
519 mClustersIROC->SetPolyMarker(0);
520 mClustersOROC->SetPolyMarker(0);
521 }
522 mFlagGroup->SetState(kFALSE);
523 for (int iCheck = 0; iCheck < NCheckClFlags; ++iCheck) {
524 mCheckClFlags[iCheck]->SetEnabled(kFALSE);
525 }
526 }
527}
528
529//__________________________________________________________________________
531{
532 mStop = true;
533 gApplication->Terminate();
534}
535
536//__________________________________________________________________________
538{
539 std::unique_ptr<TObjArray> arr(clist.Tokenize(";"));
540 for (auto o : *arr) {
541 auto c = (TCanvas*)gROOT->GetListOfCanvases()->FindObject(o->GetName());
542 if (c) {
543 c->Modified();
544 c->Update();
545 }
546 }
547}
548
549//__________________________________________________________________________
551{
552 if (!type) {
553 switch (histogramType) {
554 case MaxValues:
555 if (mHMaxA) {
556 mHMaxA->Reset();
557 }
558 if (mHMaxC) {
559 mHMaxC->Reset();
560 }
561 break;
562 case Occupancy:
563 if (mHOccupancyA) {
564 mHOccupancyA->Reset();
565 }
566 if (mHOccupancyC) {
567 mHOccupancyC->Reset();
568 }
569 break;
570 default:
571 break;
572 }
573 }
574 switch (histogramType) {
575 case MaxValues:
576 if (mHMaxIROC) {
577 mHMaxIROC->Reset();
578 }
579 if (mHMaxOROC) {
580 mHMaxOROC->Reset();
581 }
582 break;
583 case Occupancy:
584 if (mHOccupancyIROC) {
585 mHOccupancyIROC->Reset();
586 }
587 if (mHOccupancyOROC) {
588 mHOccupancyOROC->Reset();
589 }
590 break;
591 default:
592 break;
593 }
594}
595
596//__________________________________________________________________________
597TH1* SimpleEventDisplayGUI::getBinInfoXY(int& binx, int& biny, float& bincx, float& bincy)
598{
599 auto pad = (TPad*)gTQSender;
600 TObject* select = pad->GetSelected();
601
602 if (!select) {
603 return nullptr;
604 }
605
606 if (!select->InheritsFrom("TH2")) {
607 pad->SetUniqueID(0);
608 return nullptr;
609 }
610
611 TH1* h = (TH1*)select;
612 pad->GetCanvas()->FeedbackMode(kTRUE);
613
614 const int px = pad->GetEventX();
615 const int py = pad->GetEventY();
616 const float xx = pad->AbsPixeltoX(px);
617 const float x = pad->PadtoX(xx);
618 const float yy = pad->AbsPixeltoY(py);
619 const float y = pad->PadtoX(yy);
620
621 if (h->InheritsFrom(TH2Poly::Class())) {
622 auto hPoly = (TH2Poly*)h;
623 binx = hPoly->GetXaxis()->FindBin(x);
624 biny = hPoly->GetYaxis()->FindBin(y);
625 bincx = hPoly->GetXaxis()->GetBinCenter(binx);
626 bincy = hPoly->GetYaxis()->GetBinCenter(biny);
627 binx = biny = hPoly->FindBin(x, y);
628 } else {
629 binx = h->GetXaxis()->FindBin(x);
630 biny = h->GetYaxis()->FindBin(y);
631 bincx = h->GetXaxis()->GetBinCenter(binx);
632 bincy = h->GetYaxis()->GetBinCenter(biny);
633 }
634
635 return h;
636}
637
638//__________________________________________________________________________
640{
641 //
642 // type: name of canvas
643 //
644
645 // fmt::print("o: {}, type: {}, name: {}\n", (void*)o, o ? o->IsA()->GetName() : "", o ? o->GetName() : "");
646 if (!o) {
647 return;
648 }
649
650 // check if an event was alreay loaded
651 if (!mEvDisp.getNumberOfProcessedEvents()) {
652 return;
653 }
654
655 // return if mouse is pressed to allow looking at one pad
656 if (event != 51) {
657 return;
658 }
659
660 int binx, biny;
661 float bincx, bincy;
662 TH1* h = getBinInfoXY(binx, biny, bincx, bincy);
663 if (!h) {
664 return;
665 }
666 // fmt::print("binx {}, biny {}, cx {}, cy {}\n", binx, biny, bincx, bincy);
667
668 const auto& mapper = Mapper::instance();
669 // int roc = h->GetUniqueID();
670 int roc = mSelectedSector;
671 TString type;
672 const std::string_view objectName(o->GetName());
673
674 // for standard row vs cpad histo, is overwritte in case of TH2Poly sector histo below
675 int row = int(TMath::Floor(bincx));
676
677 // find pad and channel
678 int pad = -1;
679
680 if (objectName == "hMaxValsIROC" || objectName == "hOccupancyValsIROC") {
681 type = "SigI";
682 } else if (objectName == "hMaxValsOROC" || objectName == "hOccupancyValsOROC") {
683 type = "SigO";
684 roc += 36;
685 } else if (objectName == "hPadTimeValsI") {
686 type = "SigI";
687 row = h->GetUniqueID();
688 } else if (objectName == "hPadTimeValsO") {
689 type = "SigO";
690 row = h->GetUniqueID();
691 roc += 36;
692 } else if (objectName == "hSingleTB") {
693 type = "SigI";
694 const auto padPosSec = mapper.padPos(binx - 1);
695 pad = padPosSec.getPad();
696 row = padPosSec.getRow();
697 if (bincx > 133) {
698 type = "SigO";
699 roc += 36;
700 row -= mapper.getNumberOfRowsROC(0);
701 }
702 // fmt::print("roc {}, row {}, pad {}\n", roc, row, pad);
703 } else {
704 return;
705 }
706 const int nPads = mapper.getNumberOfPadsInRowROC(roc, row);
707 if (pad == -1) {
708 const int cpad = int(TMath::Floor(bincy));
709 pad = cpad + nPads / 2;
710 }
711
712 if (pad < 0 || pad >= (int)nPads) {
713 return;
714 }
715 if (row < 0 || row >= (int)mapper.getNumberOfRowsROC(roc)) {
716 return;
717 }
718 if (roc < 0 || roc >= (int)ROC::MaxROC) {
719 return;
720 }
721 const TString rocType = (roc < 36) ? "I" : "O";
722
723 // draw requested pad signal
724
725 TH1*& hFFT = (roc < 36) ? mHFFTI : mHFFTO;
726
727 TCanvas* c = (TCanvas*)gROOT->GetListOfCanvases()->FindObject(type);
728 TCanvas* cFFT = (TCanvas*)gROOT->GetListOfCanvases()->FindObject(Form("%sFFT", type.Data()));
729 if (c) {
730 c->Clear();
731 c->cd();
732 TH1D* h2 = mEvDisp.makePadSignals(roc, row, pad);
733 if (h2) {
734 h2->Draw();
735 h2->SetStats(0);
736
737 if (cFFT) {
738 const bool init = (hFFT == nullptr);
739 const double maxTime = h2->GetNbinsX() * 200.e-6;
740 hFFT = h2->FFT(hFFT, "MAG M");
741 if (hFFT) {
742 hFFT->SetStats(0);
743 const auto nbinsx = hFFT->GetNbinsX();
744 auto xax = hFFT->GetXaxis();
745 xax->SetRange(2, nbinsx / 2);
746 if (init) {
747 xax->Set(nbinsx, xax->GetXmin() / maxTime, xax->GetXmax() / maxTime);
748 hFFT->SetNameTitle(Form("hFFT_%sROC", rocType.Data()), "FFT magnitude;frequency (kHz);amplitude");
749 }
750 hFFT->Scale(2. / (nbinsx - 1));
751 cFFT->cd();
752 hFFT->Draw();
753 }
754 }
755 }
756 if (mCheckSingleTB) {
757 TLine l;
758 l.SetLineColor(kRed);
759 const auto timeBin = mSelTimeBin->GetNumberEntry()->GetIntNumber();
760 h = (TH1D*)gROOT->FindObject(fmt::format("PadSignals_{}ROC", rocType.Data()).data());
761 if (h) {
762 l.DrawLine(timeBin + 0.5, h->GetMinimum(), timeBin + 0.5, h->GetMaximum());
763 }
764 }
765 if (mCheckPadTime && objectName.find("hPadTimeVals") == 0) {
766 TLine l;
767 l.SetLineColor(kMagenta);
768 const auto timeBin = bincx;
769 h = (TH1D*)gROOT->FindObject(fmt::format("PadSignals_{}ROC", rocType.Data()).data());
770 if (h) {
771 l.DrawLine(timeBin + 0.5, h->GetMinimum(), timeBin, h->GetMaximum());
772 }
773 }
774 if (mCheckShowClusters->IsDown()) {
776 }
777 const auto padTimeValsName = fmt::format("PadTimeVals{}", type[type.Length() - 1]);
778 TCanvas* cPadTimeVals = (TCanvas*)gROOT->GetListOfCanvases()->FindObject(padTimeValsName.data());
779 if (cPadTimeVals) {
780 h = (TH1D*)gROOT->FindObject(("h" + padTimeValsName).data());
781 if (h) {
782 cPadTimeVals->cd();
783 delete cPadTimeVals->GetListOfPrimitives()->FindObject("TLine");
784 TLine l;
785 l.SetLineColor(kRed);
786 const auto timeBin = mSelTimeBin->GetNumberEntry()->GetIntNumber();
787 l.DrawLine(timeBin + 0.5, h->GetYaxis()->GetXmin(), timeBin + 0.5, h->GetYaxis()->GetXmax());
788 }
789 }
790 update(Form("%s;%sFFT;PadTimeVals%s;SingleTB", type.Data(), type.Data(), rocType.Data()));
791 }
792 // printf("bin=%03d.%03d(%03d)[%05d], name=%s, ROC=%02d content=%.1f, ev: %d\n",row,pad,cpad,chn,h->GetName(), roc, h->GetBinContent(binx,biny), event);
793}
794
795//__________________________________________________________________________
797{
798 //
799 // type: 0 fill side and sector, 1: fill sector only
800 //
801 const auto& mapper = Mapper::instance();
802
803 float kEpsilon = 0.000000000001;
804 CalPad* pad = histogramType == MaxValues ? mEvDisp.getCalPadMax() : mEvDisp.getCalPadOccupancy();
805 TH2F* hSide = nullptr;
806 TH2F* hROC = nullptr;
807 resetHists(type, histogramType);
808 const int runNumber = TString(gSystem->Getenv("RUN_NUMBER")).Atoi();
809 // const int eventNumber = mEvDisp.getNumberOfProcessedEvents() - 1;
810 const int eventNumber = mEvDisp.getPresentEventNumber();
811 const bool eventComplete = mEvDisp.isPresentEventComplete();
812
813 for (int iROC = 0; iROC < 72; iROC++) {
814 hROC = histogramType == MaxValues ? mHMaxOROC : mHOccupancyOROC;
815 hSide = histogramType == MaxValues ? mHMaxC : mHOccupancyC;
816 if (iROC < 36) {
817 hROC = histogramType == MaxValues ? mHMaxIROC : mHOccupancyIROC;
818 }
819 if ((iROC % 36) < 18) {
820 hSide = histogramType == MaxValues ? mHMaxA : mHOccupancyA;
821 }
822 if ((iROC % 36) == (mSelectedSector % 36)) {
823 TString title = Form("%s Values %cROC %c%02d (%02d) TF %s%d%s", histogramType == MaxValues ? "Max" : "Occupancy", (iROC < 36) ? 'I' : 'O', (iROC % 36 < 18) ? 'A' : 'C', iROC % 18, iROC, eventComplete ? "" : "(", eventNumber, eventComplete ? "" : ")");
824 // TString title = Form("Max Values Run %d Event %d", runNumber, eventNumber);
825 if (hROC) {
826 hROC->SetTitle(title.Data());
827 }
828 }
829 auto& calRoc = pad->getCalArray(iROC);
830 const int nRows = mapper.getNumberOfRowsROC(iROC);
831 for (int irow = 0; irow < nRows; irow++) {
832 const int nPads = mapper.getNumberOfPadsInRowROC(iROC, irow);
833 for (int ipad = 0; ipad < nPads; ipad++) {
834 float value = calRoc.getValue(irow, ipad);
835 // printf("iROC: %02d, sel: %02d, row %02d, pad: %02d, value: %.5f\n", iROC, mSelectedSector, irow, ipad, value);
836 if (TMath::Abs(value) > kEpsilon) {
837 if (!type && hSide) {
838 const GlobalPosition2D global2D = mapper.getPadCentre(PadSecPos(Sector(iROC % 36), PadPos(irow + (iROC >= 36) * mapper.getNumberOfRowsROC(0), ipad)));
839 int binx = 1 + TMath::Nint((global2D.X() + 250.) * hSide->GetNbinsX() / 500.);
840 int biny = 1 + TMath::Nint((global2D.Y() + 250.) * hSide->GetNbinsY() / 500.);
841 hSide->SetBinContent(binx, biny, value);
842 }
843 const int nPads = mapper.getNumberOfPadsInRowROC(iROC, irow);
844 const int cpad = ipad - nPads / 2;
845 if ((iROC % 36 == mSelectedSector % 36) && hROC) {
846 // printf(" ->>> Fill: iROC: %02d, sel: %02d, row %02d, pad: %02d, value: %.5f\n", iROC, mSelectedSector, irow, ipad, value);
847 hROC->Fill(irow, cpad, value);
848 }
849 }
850 if ((iROC % 36 == mSelectedSector % 36) && hROC) {
851 hROC->SetUniqueID(iROC);
852 }
853 }
854 }
855 }
856 if (!type) {
857 update(histogramType == MaxValues ? "MaxValsA;MaxValsC" : "OccupancyValsA;OccupancyValsC");
858 }
859
860 update(histogramType == MaxValues ? "MaxValsI;MaxValsO" : "OccupancyValsI;OccupancyValsO");
861}
862
863//__________________________________________________________________________
865{
866 mSelectedSector = sector % 36;
867 mEvDisp.setSelectedSector(mSelectedSector);
869 if (mCheckOccupancy->IsDown()) {
871 }
872 mEvDisp.updateSectorHists();
874}
875
876//__________________________________________________________________________
877int SimpleEventDisplayGUI::FindROCFromXY(const float x, const float y, const int side)
878{
879 //
880 //
881 //
882
883 const auto& mapper = Mapper::instance();
884 float r = TMath::Sqrt(x * x + y * y);
885 static const float innerWall = mapper.getPadCentre(PadPos(0, 0)).X() - 5.;
886 static const float outerWall = mapper.getPadCentre(PadPos(151, 0)).X() + 5.;
887 static const float outerIROC = mapper.getPadCentre(PadPos(62, 0)).X();
888 static const float innerOROC = mapper.getPadCentre(PadPos(63, 0)).X();
889 static const float betweenROC = (outerIROC + innerOROC) / 2.;
890
891 // check radial boundary
892 if (r < innerWall || r > outerWall) {
893 return -1;
894 }
895
896 // check for IROC or OROC
897 int type = 0;
898
899 if (r > betweenROC) {
900 type = 1;
901 }
902
903 int alpha = TMath::Nint(TMath::ATan2(y, x) / TMath::Pi() * 180);
904 // printf("%6.3f %6.3f %03d\n",x, y, alpha);
905 if (alpha < 0) {
906 alpha += 360;
907 }
908 const int roc = alpha / 20 + side * 18 + type * 36;
909 return roc;
910}
911
912//__________________________________________________________________________
914{
915
916 int binx, biny;
917 float bincx, bincy;
918 TH1* h = getBinInfoXY(binx, biny, bincx, bincy);
919
920 if (!h) {
921 return;
922 }
923
924 const int side = h->GetUniqueID();
925 const int roc = FindROCFromXY(bincx, bincy, side);
926
927 if (roc < 0) {
928 return;
929 }
930
931 const int sector = roc % 36;
932
933 std::string title("Max Values");
934 std::string_view name(h->GetTitle());
935 if (name.find("Occupancy") != std::string::npos) {
936 title = "Occupancy Values";
937 }
938 h->SetTitle(fmt::format("{} {}{:02d}", title, (sector < 18) ? 'A' : 'C', sector % 18).data());
939
940 if (sector != mOldHooverdSector) {
941 auto pad = (TPad*)gTQSender;
942 pad->Modified();
943 pad->Update();
944 mOldHooverdSector = sector;
945 }
946
947 if (event != 11) {
948 return;
949 }
950 // printf("selectSector: %d.%02d.%d = %02d\n", side, sector, roc < 36, roc);
951 selectSector(sector);
952}
953
954//__________________________________________________________________________
956{
957 const int w = 400;
958 const int h = 400;
959 const int hOff = 60;
960 const int vOff = 2;
961 TCanvas* c = nullptr;
962
963 if (mShowSides) {
964 // histograms and canvases for max values A-Side
965 c = new TCanvas("MaxValsA", "MaxValsA", 0 * w - 1, 0 * h, w, h);
966
967 c->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
968 "o2::tpc::SimpleEventDisplayGUI", this,
969 "selectSectorExec(int,int,int,TObject*)");
970
971 mHMaxA = new TH2F("hMaxValsA", "Max Values Side A;x (cm);y (cm)", 330, -250, 250, 330, -250, 250);
972 mHMaxA->SetStats(kFALSE);
973 mHMaxA->SetUniqueID(0); // A-Side
974 mHMaxA->Draw("colz");
976
977 // histograms and canvases for max values C-Side
978 c = new TCanvas("MaxValsC", "MaxValsC", 0 * w - 1, 1 * h + hOff, w, h);
979
980 c->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
981 "o2::tpc::SimpleEventDisplayGUI", this,
982 "selectSectorExec(int,int,int,TObject*)");
983 mHMaxC = new TH2F("hMaxValsC", "Max Values Side C;x (cm);y (cm)", 330, -250, 250, 330, -250, 250);
984 mHMaxC->SetStats(kFALSE);
985 mHMaxC->SetUniqueID(1); // C-Side
986 mHMaxC->Draw("colz");
988 }
989
990 // histograms and canvases for max values IROC
991 c = new TCanvas("MaxValsI", "MaxValsI", -1 * (w + vOff), 0 * h, w, h);
992
993 c->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
994 "o2::tpc::SimpleEventDisplayGUI", this,
995 "drawPadSignal(int,int,int,TObject*)");
996 mHMaxIROC = new TH2F("hMaxValsIROC", "Max Values IROC;row;pad", 63, 0, 63, 108, -54, 54);
997 mHMaxIROC->SetDirectory(nullptr);
998 mHMaxIROC->SetStats(kFALSE);
999 mHMaxIROC->Draw("colz");
1000
1001 // histograms and canvases for max values OROC
1002 c = new TCanvas("MaxValsO", "MaxValsO", -1 * (w + vOff), 1 * h + hOff, w, h);
1003
1004 c->Connect("ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
1005 "o2::tpc::SimpleEventDisplayGUI", this,
1006 "drawPadSignal(int,int,int,TObject*)");
1007 mHMaxOROC = new TH2F("hMaxValsOROC", "Max Values OROC;row;pad", 89, 0, 89, 140, -70, 70);
1008 mHMaxOROC->SetDirectory(nullptr);
1009 mHMaxOROC->SetStats(kFALSE);
1010 mHMaxOROC->Draw("colz");
1011
1012 // canvases for pad signals
1013 new TCanvas("SigI", "SigI", -2 * (w + vOff), 0 * h, w, h);
1014 new TCanvas("SigO", "SigO", -2 * (w + vOff), 1 * h + hOff, w, h);
1015}
1016
1017//__________________________________________________________________________
1018void SimpleEventDisplayGUI::next(int eventNumber)
1019{
1020 if (mRunMode == RunMode::Online) {
1021
1022 if (!mDataAvailable) {
1023 return;
1024 }
1025
1026 mUpdatingDigits = true;
1027 usleep(1000);
1028 mNextEvent = true;
1029
1030 while (mUpdatingDigits) {
1031 usleep(1000);
1032 }
1033 mProcessingEvent = true;
1034 }
1035
1037 Status status = mEvDisp.processEvent(eventNumber);
1038
1039 const int timeBins = mEvDisp.getNumberOfProcessedTimeBins();
1040
1041 const int presentEventNumber = mEvDisp.getPresentEventNumber();
1042 mEventNumber->SetText(Form("%d", presentEventNumber));
1043
1044 switch (status) {
1045 case Status::Ok: {
1046 std::cout << "Read in full event with " << timeBins << " time bins\n";
1047 break;
1048 }
1049 case Status::Truncated: {
1050 std::cout << "Event is truncated and contains less than " << timeBins << " time bins\n";
1051 break;
1052 }
1053 case Status::NoMoreData: {
1054 std::cout << "No more data to be read\n";
1055 // return;
1056 break;
1057 }
1058 case Status::NoReaders: {
1059 std::cout << "No raw readers configured\n";
1060 return;
1061 break;
1062 }
1063 default:
1064 // Do nothing for non-listed values of Status enum
1065 break;
1066 }
1067 // bool res=mEvDisp.processEvent();
1068 // printf("Next: %d, %d (%d - %d), %d\n",res, ((AliRawReaderGEMDate*)mRawReader)->mEventInFile,((AliRawReaderGEMDate*)mRawReader)->GetCamacData(0),mRawReader->GetEventFromTag(), mRawReader->GetDataSize());
1069 // printf("Next Event: %d\n",mRawReader->GetEventFromTag());
1070
1071 fillHists(0, MaxValues);
1072 if (mCheckOccupancy->IsDown()) {
1073 fillHists(0, Occupancy);
1074 }
1075
1076 if (mRunMode == RunMode::Online) {
1077 mProcessingEvent = false;
1078 }
1079
1080 fillClusters(presentEventNumber);
1081}
1082
1083//__________________________________________________________________________
1085{
1086 const int event = TString(mEventNumber->GetText()).Atoi();
1087 next(event);
1088}
1089
1090//__________________________________________________________________________
1091void SimpleEventDisplayGUI::runSimpleEventDisplay(std::string_view fileInfo, std::string_view pedestalFile, int firstTimeBin, int lastTimeBin, int nTimeBinsPerCall, uint32_t verbosity, uint32_t debugLevel, int selectedSector, bool showSides)
1092{
1093 fair::Logger::SetVerbosity("LOW");
1094 fair::Logger::SetConsoleSeverity("DEBUG");
1095 gStyle->SetNumberContours(255);
1096 if (pedestalFile.size()) {
1097 TFile f(pedestalFile.data());
1098 if (f.IsOpen()) {
1099 CalDet<float>* pedestal = nullptr;
1100 f.GetObject("Pedestals", pedestal);
1101 mEvDisp.setPedstals(pedestal);
1102 }
1103 }
1104
1105 mSelectedSector = selectedSector;
1106 mShowSides = showSides;
1107
1108 mEvDisp.setupContainers(fileInfo.data(), verbosity, debugLevel);
1109 mEvDisp.setSkipIncompleteEvents(false); // in case of the online monitor do not skip incomplete events
1110 mEvDisp.setSelectedSector(mSelectedSector);
1111 mEvDisp.setLastSelSector(mSelectedSector);
1112 mEvDisp.setTimeBinsPerCall(nTimeBinsPerCall);
1113 mEvDisp.setTimeBinRange(firstTimeBin, lastTimeBin);
1114
1115 initGUI();
1116 monitorGui();
1117
1118 next(0);
1119
1120 mInputFileInfo = fileInfo;
1121
1122 memset(&mClusterIndex, 0, sizeof(mClusterIndex));
1123}
1124
1125//_____________________________________________________________________________
1127{
1128 mRunMode = RunMode::Online;
1129
1130 TApplication evDisp("TPC raw data monitor", nullptr, nullptr);
1131
1132 mEvDisp.setSkipIncompleteEvents(false); // in case of the online monitor do not skip incomplete events
1133 mEvDisp.setSelectedSector(mSelectedSector);
1134 mEvDisp.setLastSelSector(mSelectedSector);
1135 mEvDisp.setTimeBinsPerCall(maxTimeBins);
1136 mEvDisp.setTimeBinRange(0, maxTimeBins);
1137
1138 initGUI();
1139 monitorGui();
1140
1141 evDisp.Run(true);
1142}
1143
1144//_____________________________________________________________________________
1146{
1147 UInt_t signalThreshold = TString(mSignalThresholdValue->GetText()).Atoi();
1148 mEvDisp.setSignalThreshold(signalThreshold);
1150}
1151
1152//______________________________________________________________________________
1154{
1155 if (!mCheckSingleTB->IsDown()) {
1156 return;
1157 }
1158 const auto timeBin = mSelTimeBin->GetNumberEntry()->GetIntNumber();
1159 mEvDisp.fillSectorHistSingleTimeBin(mSectorPolyTimeBin, timeBin);
1160 mSectorPolyTimeBin->SetTitle(fmt::format("Sector {:02}, time bin {:6}", mSelectedSector, timeBin).data());
1161 showClusters(-1, -1);
1162 update("SingleTB");
1163}
1164
1165//______________________________________________________________________________
1167{
1168 static int lastRow = -1;
1169 static int lastROC = -1;
1170 static int lastTimeBin = -1;
1171 const auto timeBin = mSelTimeBin->GetNumberEntry()->GetIntNumber();
1172 bool forceUpdate = false;
1173 // fmt::print("roc {}, row {}, lastROC {}, lastRow {}\n", roc, row, lastROC, lastRow);
1174 if (roc == -1) {
1175 roc = lastROC;
1176 forceUpdate = true;
1177 }
1178 if ((mTPCclusterReader.getTreeSize() == 0) || (lastRow == row) || (roc == -1)) {
1179 return;
1180 }
1181 if (row == -1) {
1182 if (lastRow == -1) {
1183 return;
1184 }
1185 row = lastRow;
1186 }
1187 lastRow = row;
1188 lastROC = roc;
1189
1190 const auto& mapper = Mapper::instance();
1191 const int sector = roc % 36;
1192 TPolyMarker* marker = mClustersIROC;
1193 const int nPads = mapper.getNumberOfPadsInRowROC(roc, row);
1194
1195 if (roc >= 36) {
1196 marker = mClustersOROC;
1197 row += mapper.getNumberOfRowsROC(0); // cluster access is using the global row in sector
1198 }
1199
1200 marker->SetPolyMarker(0);
1201 if (mClustersRowPad) {
1202 mClustersRowPad->SetPolyMarker(0);
1203 }
1204 size_t iSelClusters = 0;
1205 int selFlags = 0;
1206 bool golden = mCheckClFlags[0]->IsDown();
1207 for (int iFlag = 1; iFlag < NCheckClFlags; ++iFlag) {
1208 selFlags += mCheckClFlags[iFlag]->IsDown() << (iFlag - 1);
1209 }
1210 const bool fillSingleTB = mCheckSingleTB->IsDown();
1211 const o2::gpu::GPUTPCGeometry gpuGeom;
1212
1213 const int rowMin = fillSingleTB ? 0 : row;
1214 const int rowMax = fillSingleTB ? constants::MAXGLOBALPADROW : row + 1;
1215
1216 for (int irow = rowMin; irow < rowMax; ++irow) {
1217 const auto nClusters = mClusterIndex.nClusters[sector][irow];
1218 for (size_t icl = 0; icl < nClusters; ++icl) {
1219 const auto& cl = mClusterIndex.clusters[sector][irow][icl];
1220 const auto flags = cl.getFlags();
1221 // fmt::print("flags: {}, selFlags: {}, selGolden: {}, ", flags, selFlags, golden);
1222 if (((flags == 0) && golden) || (flags & selFlags)) {
1223 // fmt::print("sel");
1224 if (row == irow) {
1225 marker->SetPoint(iSelClusters, cl.getTime() + 0.5, cl.getPad() + 0.5 - nPads / 2.);
1226 ++iSelClusters;
1227 }
1228 if (fillSingleTB && std::abs(cl.getTime() - timeBin) < 2) {
1229 const auto ly = gpuGeom.LinearPad2Y(sector, irow, cl.getPad() + 0.5);
1230 mClustersRowPad->SetNextPoint(gpuGeom.Row2X(irow), (sector >= GPUCA_NSECTORS / 2) ? -ly : ly);
1231 }
1232 }
1233 // fmt::print("\n");
1234 }
1235 }
1236 // marker->SetPolyMarker(iSelClusters);
1237
1238 if (forceUpdate) {
1239 update(Form("PadTimeVals%s;SingleTB", (roc < 36) ? "I" : "O"));
1240 }
1241}
1242
1243//______________________________________________________________________________
1244void SimpleEventDisplayGUI::fillClusters(Long64_t entry)
1245{
1246 if (mTPCclusterReader.getTreeSize() > 0) {
1247 mTPCclusterReader.read(entry);
1248 mTPCclusterReader.fillIndex(mClusterIndex, mClusterBuffer, mClusterMCBuffer);
1249 LOGP(info, "Loaded cluster tree entry {} with {} clusters", entry, mClusterIndex.nClustersTotal);
1250 }
1251}
#define verbosity
bool o
#define GPUCA_NSECTORS
uint32_t roc
Definition RawData.h:3
uint32_t side
Definition RawData.h:0
uint32_t c
Definition RawData.h:2
GUI for raw data event display.
int nClusters
Class for time synchronization of RawReader instances.
const CalType & getCalArray(size_t position) const
Definition CalDet.h:63
size_t getPresentEventNumber() const
get present event number
void setTimeBinsPerCall(Int_t nTimeBins)
set number of time bins to process in one call to processEvent
ProcessStatus processEvent(int eventNumber=-1)
void setupContainers(TString fileInfo, uint32_t verbosity=0, uint32_t debugLevel=0)
bool isPresentEventComplete() const
check if present event is complete
void setSkipIncompleteEvents(bool skip)
set skipping of incomplete events
size_t getNumberOfProcessedEvents() const
number of processed events
size_t getNumberOfProcessedTimeBins() const
number of processed time bins in last event
int fillIndex(ClusterNativeAccess &clusterIndex, std::unique_ptr< ClusterNative[]> &clusterBuffer, ConstMCLabelContainerViewWithBuffer &mcBuffer)
void init(const char *filename, const char *treename=nullptr)
static Mapper & instance(const std::string mappingDir="")
Definition Mapper.h:44
@ MaxROC
Definition ROC.h:47
void fillHists(int type=0, HistogramType histogramType=MaxValues)
@ Online
run online from decoded digits
void resetHists(int type, HistogramType histogramType)
void runSimpleEventDisplay(std::string_view fileInfo, std::string_view pedestalFile="", int firstTimeBin=0, int lastTimeBin=500, int nTimeBinsPerCall=500, uint32_t verbosity=0, uint32_t debugLevel=0, int selectedSector=0, bool showSides=1)
void drawPadSignal(int event, int x, int y, TObject *o)
int FindROCFromXY(const float x, const float y, const int side)
void startGUI(int maxTimeBins=114048)
void selectSectorExec(int event, int x, int y, TObject *o)
TH1D * makePadSignals(Int_t roc, Int_t row, Int_t pad)
void setSelectedSector(Int_t selectedSector)
Set currently selected sector.
void setTimeBinRange(int firstBin, int lastBin)
set time bin range
void setSignalThreshold(Int_t signalThreshold)
void setPedstals(CalPad *pedestals)
void fillSectorHistSingleTimeBin(TH2Poly *h, Int_t timeBin)
void setLastSelSector(Int_t lastSelSector)
Set last selected sector.
struct _cl_event * event
Definition glcorearb.h:2982
GLfloat GLfloat GLfloat alpha
Definition glcorearb.h:279
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint entry
Definition glcorearb.h:5735
GLuint const GLchar * name
Definition glcorearb.h:781
GLdouble f
Definition glcorearb.h:310
GLint GLint GLint yoffset
Definition glcorearb.h:406
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLboolean * data
Definition glcorearb.h:298
GLbitfield flags
Definition glcorearb.h:1570
GLboolean r
Definition glcorearb.h:1233
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
std::vector< InputSpec > select(char const *matcher="")
constexpr int MAXGLOBALPADROW
Definition Constants.h:34
Global TPC definitions and constants.
Definition SimTraits.h:167
void fillClusters(CompressedClustersROOT &clusters, ClustersData &data)
@ A
Definition Defs.h:35
@ C
Definition Defs.h:36
unsigned int nClusters[constants::MAXSECTOR][constants::MAXGLOBALPADROW]
const ClusterNative * clusters[constants::MAXSECTOR][constants::MAXGLOBALPADROW]
static TH2Poly * makeSectorHist(const std::string_view name="hSector", const std::string_view title="Sector;local #it{x} (cm);local #it{y} (cm)", const float xMin=83.65f, const float xMax=247.7f, const float yMin=-43.7f, const float yMax=43.7f, const Type type=Type::Pad)
static void drawSectorsXY(Side side, int sectorLineColor=920, int sectorTextColor=1)
draw sector boundaris, side name and sector numbers
std::vector< int > row