Project
Loading...
Searching...
No Matches
Painter.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 <string>
13#include <algorithm>
14#include <fmt/core.h>
15#include <fmt/format.h>
16#include <cmath>
17
18#include "TAxis.h"
19#include "TMultiGraph.h"
20#include "TGraphErrors.h"
21#include "TTree.h"
22#include "TH1.h"
23#include "TH2.h"
24#include "TH3.h"
25#include "TH2Poly.h"
26#include "TProfile2D.h"
27#include "TCanvas.h"
28#include "TLine.h"
29#include "TLatex.h"
30#include "TStyle.h"
31#include "TPaveText.h"
32#include "TPaletteAxis.h"
33#include "TObjArray.h"
34
36#include "DataFormatsTPC/Defs.h"
37#include "TPCBase/ROC.h"
38#include "TPCBase/Sector.h"
39#include "TPCBase/Mapper.h"
40#include "TPCBase/CalDet.h"
41#include "TPCBase/CalArray.h"
42#include "TPCBase/Painter.h"
43#include "TPCBase/Utils.h"
45
46// for conversion CalDet to TH3
47#include <deque>
48#include <boost/geometry.hpp>
49#include <boost/geometry/geometries/point_xy.hpp>
50#include <boost/geometry/geometries/polygon.hpp>
51#include <string_view>
52#include "MathUtils/Utils.h"
53
54using namespace o2::tpc;
55
56std::array<int, 6> painter::colors = {EColor::kBlack, EColor::kRed + 1, EColor::kOrange + 2, EColor::kGreen + 2, EColor::kBlue + 1, EColor::kMagenta + 1};
57std::array<int, 10> painter::markers = {20, 21, 33, 34, 47, 24, 25, 27, 28, 46};
58
59std::vector<painter::PadCoordinates> painter::getPadCoordinatesSector()
60{
61 std::vector<painter::PadCoordinates> padCoords;
62
63 const auto& regInf = Mapper::instance().getMapPadRegionInfo();
64
65 for (const auto& padReg : regInf) {
66 const auto npr = padReg.getNumberOfPadRows();
67 const auto ro = padReg.getRowOffset();
68 const auto xm = padReg.getXhelper();
69 const auto ph = padReg.getPadHeight();
70 const auto pw = padReg.getPadWidth();
71 const auto yro = padReg.getRadiusFirstRow();
72 const auto ks = ph / pw * std::tan(1.74532925199432948e-01);
73
74 for (int irow = 0; irow < npr; ++irow) {
75 const auto npads = std::floor(ks * (irow + ro) + xm);
76 for (int ipad = -npads; ipad < npads; ++ipad) {
77 const auto xPadBottomRight = yro + ph * irow;
78 const auto xPadTopRight = yro + ph * (irow + 1);
79 const auto ri = xPadBottomRight;
80 const auto yPadBottomRight = pw * ipad * xPadBottomRight / (ri + ph / 2);
81 const auto yPadTopRight = pw * ipad * xPadTopRight / (ri + ph / 2);
82 const auto yPadBottomLeft = pw * (ipad + 1) * xPadBottomRight / (ri + ph / 2);
83 const auto yPadTopLeft = pw * (ipad + 1) * xPadTopRight / (ri + ph / 2);
84 auto& padCoord = padCoords.emplace_back();
85 padCoord.xVals = {xPadBottomRight, xPadTopRight, xPadTopRight, xPadBottomRight};
86 padCoord.yVals = {yPadBottomRight, yPadTopRight, yPadTopLeft, yPadBottomLeft};
87 }
88 }
89 }
90
91 return padCoords;
92}
93
94std::vector<painter::PadCoordinates> painter::getStackCoordinatesSector()
95{
96 std::vector<painter::PadCoordinates> padCoords;
97 const auto& regInf = Mapper::instance().getMapPadRegionInfo();
98
99 std::vector<GEMstack> stacks;
100 stacks.reserve(CRU::CRUperSector);
101 for (int cru = 0; cru < CRU::CRUperSector; ++cru) {
102 stacks.emplace_back(CRU(cru).gemStack());
103 }
104
105 for (int stack = 0; stack < GEMSTACKSPERSECTOR; ++stack) {
106 auto& padCoord = padCoords.emplace_back();
107 padCoord.xVals.resize(0);
108 padCoord.yVals.resize(0);
109
110 const GEMstack currentStack = static_cast<GEMstack>(stack);
111 const auto first = std::find(stacks.cbegin(), stacks.cend(), currentStack);
112 const auto last = std::find(stacks.crbegin(), stacks.crend(), currentStack);
113 const int firstRegion = std::distance(stacks.cbegin(), first);
114 const int lastRegion = (stacks.size() - std::distance(stacks.crbegin(), last) - 1);
115
116 for (int region = firstRegion; region <= lastRegion; ++region) {
117 const auto& padReg = regInf[region];
118 const auto npr = padReg.getNumberOfPadRows();
119 const auto ro = padReg.getRowOffset();
120 const auto xm = padReg.getXhelper();
121 const auto ph = padReg.getPadHeight();
122 const auto pw = padReg.getPadWidth();
123 const auto yro = padReg.getRadiusFirstRow();
124 const auto ks = ph / pw * std::tan(1.74532925199432948e-01);
125
126 for (int irow = 0; irow < npr; ++irow) {
127 const auto npads = std::floor(ks * (irow + ro) + xm);
128 const int ipad = -npads;
129 const auto xPadBottomRight = yro + ph * irow;
130 const auto xPadTopRight = yro + ph * (irow + 1);
131 const auto ri = xPadBottomRight;
132 const auto yPadBottomRight = pw * ipad * xPadBottomRight / (ri + ph / 2);
133 const auto yPadTopRight = pw * ipad * xPadTopRight / (ri + ph / 2);
134 const auto yPadBottomLeft = pw * (ipad + 1) * xPadBottomRight / (ri + ph / 2);
135 const auto yPadTopLeft = pw * (ipad + 1) * xPadTopRight / (ri + ph / 2);
136 padCoord.xVals.emplace_back(xPadBottomRight);
137 padCoord.yVals.emplace_back(yPadBottomRight);
138 padCoord.xVals.emplace_back(xPadTopRight);
139 padCoord.yVals.emplace_back(yPadTopRight);
140 }
141 }
142 // mirror coordinates
143 for (int i = padCoord.xVals.size() - 1; i >= 0; i--) {
144 padCoord.xVals.emplace_back(padCoord.xVals[i]);
145 padCoord.yVals.emplace_back(std::abs(padCoord.yVals[i]));
146 }
147 }
148 return padCoords;
149}
150
151std::vector<painter::PadCoordinates> painter::getFECCoordinatesSector()
152{
153 std::vector<painter::PadCoordinates> padCoords;
154 const Mapper& mapper = Mapper::instance();
155 const auto& regInf = mapper.getMapPadRegionInfo();
156
157 for (int stack = 0; stack < 5; ++stack) {
158 const int regionStart = 2 * stack;
159 const int regionEnd = regionStart + 2;
160
161 struct fecInf {
162 void addPad(int pad, int row) { pad_map[row].emplace_back(pad); }
163 const std::vector<int>& getPads(const int row) { return pad_map[row]; }
164 std::unordered_map<int, std::vector<int>> pad_map;
165 };
166
167 std::unordered_map<size_t, std::array<fecInf, 2>> fecs;
168 for (int region = regionStart; region < regionEnd; ++region) {
169 for (unsigned int lrow = 0; lrow < Mapper::ROWSPERREGION[region]; ++lrow) {
170 for (unsigned int pad = 0; pad < Mapper::PADSPERROW[region][lrow]; ++pad) {
171 const FECInfo& fec = mapper.fecInfo(Mapper::getGlobalPadNumber(lrow, pad, region));
172 const size_t fecIndex = fec.getIndex();
173 fecs[fecIndex][region - regionStart].addPad(pad, lrow);
174 }
175 }
176 }
177
178 for (auto& fec : fecs) {
179 auto& padCoord = padCoords.emplace_back();
180 padCoord.xVals.resize(0);
181 padCoord.yVals.resize(0);
182 for (int j = 0; j < 2; ++j) {
183 for (int regionTmp = regionStart; regionTmp < regionEnd; ++regionTmp) {
184 const int region = (j == 0) ? regionTmp : (regionStart + regionEnd - regionTmp - 1);
185 const auto& padReg = regInf[region];
186 const auto npr = padReg.getNumberOfPadRows();
187 const auto ro = padReg.getRowOffset();
188 const auto xm = padReg.getXhelper();
189 const auto ph = padReg.getPadHeight();
190 const auto pw = padReg.getPadWidth();
191 const auto yro = padReg.getRadiusFirstRow();
192 const auto ks = ph / pw * std::tan(1.74532925199432948e-01);
193
194 for (int irowTmp = 0; irowTmp < npr; ++irowTmp) {
195 const int irow = (j == 0) ? irowTmp : (npr - irowTmp - 1);
196 const auto npads = std::floor(ks * (irow + ro) + xm);
197 const std::vector<int>& padsFEC = fec.second[region - regionStart].getPads(irow);
198 const int padOff = (j == 0) ? padsFEC.front() : (padsFEC.back() + 1);
199 const int ipad = -npads + padOff;
200 const auto xPadBottomRight = yro + ph * irow;
201 const auto xPadTopRight = yro + ph * (irow + 1);
202 const auto ri = xPadBottomRight;
203 const auto yPadBottomRight = pw * ipad * xPadBottomRight / (ri + ph / 2);
204 const auto yPadTopRight = pw * ipad * xPadTopRight / (ri + ph / 2);
205 const auto yPadBottomLeft = pw * (ipad + 1) * xPadBottomRight / (ri + ph / 2);
206 const auto yPadTopLeft = pw * (ipad + 1) * xPadTopRight / (ri + ph / 2);
207 if (j == 0) {
208 padCoord.xVals.emplace_back(xPadBottomRight);
209 padCoord.yVals.emplace_back(yPadBottomRight);
210 padCoord.xVals.emplace_back(xPadTopRight);
211 padCoord.yVals.emplace_back(yPadTopRight);
212 } else {
213 padCoord.yVals.emplace_back(yPadTopRight);
214 padCoord.xVals.emplace_back(xPadTopRight);
215 padCoord.yVals.emplace_back(yPadBottomRight);
216 padCoord.xVals.emplace_back(xPadBottomRight);
217 }
218 }
219 }
220 }
221 }
222 }
223 return padCoords;
224}
225
226std::vector<o2::tpc::painter::PadCoordinates> painter::getCoordinates(const Type type)
227{
228 if (type == Type::Pad) {
230 } else if (type == Type::Stack) {
232 } else if (type == Type::FEC) {
234 } else {
235 LOGP(warning, "Wrong Type provided!");
236 return std::vector<o2::tpc::painter::PadCoordinates>();
237 }
238}
239
240std::vector<double> painter::getRowBinningCM(uint32_t roc)
241{
242 const Mapper& mapper = Mapper::instance();
243
244 int firstRegion = 0, lastRegion = 10;
245 if (roc < 36) {
246 firstRegion = 0;
247 lastRegion = 4;
248 } else if (roc < 72) {
249 firstRegion = 4;
250 lastRegion = 10;
251 }
252
253 std::vector<double> binning;
254
255 float lastPadHeight = mapper.getPadRegionInfo(firstRegion).getPadHeight();
256 float localX = mapper.getPadRegionInfo(firstRegion).getRadiusFirstRow();
257 binning.emplace_back(localX - 3);
258 binning.emplace_back(localX);
259 for (int iregion = firstRegion; iregion < lastRegion; ++iregion) {
260 const auto& regionInfo = mapper.getPadRegionInfo(iregion);
261 const auto padHeight = regionInfo.getPadHeight();
262
263 if (std::abs(padHeight - lastPadHeight) > 1e-5) {
264 lastPadHeight = padHeight;
265 localX = regionInfo.getRadiusFirstRow();
266 binning.emplace_back(localX);
267 }
268
269 for (int irow = 0; irow < regionInfo.getNumberOfPadRows(); ++irow) {
270 localX += lastPadHeight;
271 binning.emplace_back(localX);
272 }
273 }
274 binning.emplace_back(localX + 3);
275
276 return binning;
277}
278
279std::string painter::getROCTitle(const int rocNumber)
280{
281 const std::string_view type = (rocNumber < 36) ? "IROC" : "OROC";
282 const std::string_view side = ((rocNumber % 36) < 18) ? "A" : "C";
283 return fmt::format("{} {}{:02}", type, side, rocNumber % 18);
284}
285
286template <class T>
287TCanvas* painter::draw(const CalDet<T>& calDet, int nbins1D, float xMin1D, float xMax1D, TCanvas* outputCanvas)
288{
289 using DetType = CalDet<T>;
290 using CalType = CalArray<T>;
291
292 const Mapper& mapper = Mapper::instance();
293
294 // ===| name and title |======================================================
295 std::string title = calDet.getName();
296 std::string name = calDet.getName();
297 std::replace(name.begin(), name.end(), ' ', '_');
298 std::replace(title.begin(), title.end(), '_', ' ');
299
300 // ===| define histograms |===================================================
301 // TODO: auto scaling of ranges based on mean and variance?
302 // for the moment use roots auto scaling
303
304 // set buffer size such that autoscaling uses the full range. This is about 2MB per histogram!
305 const int bufferSize = TH1::GetDefaultBufferSize();
306 TH1::SetDefaultBufferSize(Sector::MAXSECTOR * mapper.getPadsInSector());
307
308 auto hAside1D = new TH1F(fmt::format("h_Aside_1D_{}", name).data(), fmt::format("{0} (A-Side);{0}", title).data(),
309 nbins1D, xMin1D, xMax1D); // TODO: modify ranges
310
311 auto hCside1D = new TH1F(fmt::format("h_Cside_1D_{}", name).data(), fmt::format("{0} (C-Side);{0}", title).data(),
312 nbins1D, xMin1D, xMax1D); // TODO: modify ranges
313
314 auto hAside2D = new TH2F(fmt::format("h_Aside_2D_{}", name).data(), fmt::format("{0} (A-Side);#it{{x}} (cm);#it{{y}} (cm);{0}", title).data(),
315 330, -270, 270, 330, -270, 270);
316
317 auto hCside2D = new TH2F(fmt::format("h_Cside_2D_{}", name).data(), fmt::format("{0} (C-Side);#it{{x}} (cm);#it{{y}} (cm);{0}", title).data(),
318 330, -270, 270, 330, -270, 270);
319
320 for (ROC roc; !roc.looped(); ++roc) {
321
322 auto hist2D = hAside2D;
323 auto hist1D = hAside1D;
324 if (roc.side() == Side::C) {
325 hist2D = hCside2D;
326 hist1D = hCside1D;
327 }
328
329 const int nrows = mapper.getNumberOfRowsROC(roc);
330 for (int irow = 0; irow < nrows; ++irow) {
331 const int npads = mapper.getNumberOfPadsInRowROC(roc, irow);
332 for (int ipad = 0; ipad < npads; ++ipad) {
333 const auto val = calDet.getValue(roc, irow, ipad);
334 const GlobalPosition2D pos = mapper.getPadCentre(PadROCPos(roc, irow, ipad));
335 const int bin = hist2D->FindBin(pos.X(), pos.Y());
336 if (!hist2D->GetBinContent(bin)) {
337 hist2D->SetBinContent(bin, double(val));
338 }
339 hist1D->Fill(double(val));
340 }
341 }
342 }
343
344 if (xMax1D > xMin1D) {
345 hAside2D->SetMinimum(xMin1D);
346 hAside2D->SetMaximum(xMax1D);
347 hCside2D->SetMinimum(xMin1D);
348 hCside2D->SetMaximum(xMax1D);
349 }
350
351 // ===| Draw histograms |=====================================================
352 gStyle->SetOptStat("mr");
353 auto c = outputCanvas;
354 if (!c) {
355 c = new TCanvas(fmt::format("c_{}", name).data(), title.data(), 1000, 1000);
356 }
357 gStyle->SetStatX(1. - gPad->GetRightMargin());
358 gStyle->SetStatY(1. - gPad->GetTopMargin());
359
360 c->Clear();
361 c->Divide(2, 2);
362
363 c->cd(1);
364 hAside2D->Draw("colz");
365 hAside2D->SetStats(0);
366 hAside2D->SetTitleOffset(1.05, "XY");
367 hAside2D->SetTitleSize(0.05, "XY");
368 adjustPalette(hAside2D, 0.92);
370
371 c->cd(2);
372 hCside2D->Draw("colz");
373 hCside2D->SetStats(0);
374 hCside2D->SetTitleOffset(1.05, "XY");
375 hCside2D->SetTitleSize(0.05, "XY");
376 adjustPalette(hCside2D, 0.92);
378
379 c->cd(3);
380 hAside1D->Draw();
381
382 c->cd(4);
383 hCside1D->Draw();
384
385 // reset the buffer size
386 TH1::SetDefaultBufferSize(bufferSize);
387
388 // associate histograms to canvas
389 hAside1D->SetBit(TObject::kCanDelete);
390 hCside1D->SetBit(TObject::kCanDelete);
391 hAside2D->SetBit(TObject::kCanDelete);
392 hCside2D->SetBit(TObject::kCanDelete);
393
394 return c;
395}
396
397//______________________________________________________________________________
398template <class T>
399TCanvas* painter::draw(const CalArray<T>& calArray)
400{
401 auto hist = getHistogram2D(calArray);
402 std::string name = hist->GetName();
403 name[0] = 'c';
404 auto c = new TCanvas(fmt::format("c_{}", name).data(), hist->GetTitle());
405
406 hist->Draw("colz");
407
408 // associate histograms to canvas
409 hist->SetBit(TObject::kCanDelete);
410
411 return c;
412}
413
414//______________________________________________________________________________
415template <class T>
416void painter::fillHistogram2D(TH2& h2D, const CalDet<T>& calDet, Side side)
417{
418 const Mapper& mapper = Mapper::instance();
419
420 for (ROC roc; !roc.looped(); ++roc) {
421 if (roc.side() != side) {
422 continue;
423 }
424
425 const int nrows = mapper.getNumberOfRowsROC(roc);
426 for (int irow = 0; irow < nrows; ++irow) {
427 const int npads = mapper.getNumberOfPadsInRowROC(roc, irow);
428 for (int ipad = 0; ipad < npads; ++ipad) {
429 const auto val = calDet.getValue(roc, irow, ipad);
430 const GlobalPosition2D pos = mapper.getPadCentre(PadROCPos(roc, irow, ipad));
431 const int bin = h2D.FindBin(pos.X(), pos.Y());
432 if (!h2D.GetBinContent(bin)) {
433 h2D.SetBinContent(bin, double(val));
434 }
435 }
436 }
437 }
438}
439
440//______________________________________________________________________________
441template <class T>
442void painter::fillHistogram2D(TH2& h2D, const CalArray<T>& calArray)
443{
444 const Mapper& mapper = Mapper::instance();
445
446 const size_t position = calArray.getPadSubsetNumber();
447 const PadSubset padSubset = calArray.getPadSubset();
448 const int nrows = mapper.getNumberOfPadRows(padSubset, position);
449
450 // ===| fill hist |===========================================================
451 for (int irow = 0; irow < nrows; ++irow) {
452 const int padsInRow = mapper.getNumberOfPadsInRow(padSubset, position, irow);
453 for (int ipad = 0; ipad < padsInRow; ++ipad) {
454 const GlobalPadNumber pad = mapper.getPadNumber(padSubset, position, irow, ipad);
455 const auto val = calArray.getValue(pad);
456 const int cpad = ipad - padsInRow / 2;
457 h2D.Fill(irow, cpad, double(val));
458 }
459 }
460}
461
462//______________________________________________________________________________
463template <class T>
464TH2* painter::getHistogram2D(const CalDet<T>& calDet, Side side)
465{
466 std::string title = calDet.getName();
467 std::string name = calDet.getName();
468 std::replace(name.begin(), name.end(), ' ', '_');
469 std::replace(title.begin(), title.end(), '_', ' ');
470 const char side_name = (side == Side::A) ? 'A' : 'C';
471
472 auto h2D = new TH2F(fmt::format("h_{}side_2D_{}", side_name, name).data(),
473 fmt::format("{} ({}-Side);x (cm);y (cm)", title, side_name).data(),
474 300, -300, 300, 300, -300, 300);
475
476 fillHistogram2D(*h2D, calDet, side);
477
478 return h2D;
479}
480
481//______________________________________________________________________________
482template <class T>
483TH2* painter::getHistogram2D(const CalArray<T>& calArray)
484{
485 const Mapper& mapper = Mapper::instance();
486
487 const size_t position = calArray.getPadSubsetNumber();
488 const PadSubset padSubset = calArray.getPadSubset();
489
490 // ===| maximum number of rows and pads |=====================================
491 const int nrows = mapper.getNumberOfPadRows(padSubset, position);
492 const int npads = mapper.getNumberOfPadsInRow(padSubset, position, nrows - 1) + 6;
493
494 // ===| create histogram |====================================================
495 std::string title = calArray.getName();
496 std::string name = calArray.getName();
497 std::replace(title.begin(), title.end(), '_', ' ');
498 std::replace(name.begin(), name.end(), ' ', '_');
499
500 if (padSubset == PadSubset::ROC) {
501 title += fmt::format(" ({})", getROCTitle(position));
502 }
503
504 auto hist = new TH2F(fmt::format("h_{}", name).data(),
505 fmt::format("{};pad row;pad", title).data(),
506 nrows, 0., nrows,
507 npads, -npads / 2., npads / 2.);
508
509 fillHistogram2D(*hist, calArray);
510
511 return hist;
512}
513
514template <typename T>
515std::enable_if_t<std::is_signed<T>::value, bool> hasData(const CalArray<T>& cal)
516{
517 return std::abs(cal.getSum()) > T{0};
518}
519
520template <typename T>
521std::enable_if_t<std::is_unsigned<T>::value, bool> hasData(const CalArray<T>& cal)
522{
523 return cal.getSum() > T{0};
524}
525
526template <typename T>
527std::enable_if_t<std::is_enum<T>::value, bool> hasData(const CalArray<T>& cal)
528{
529 for (const auto v : cal.getData()) {
530 if (int(v) > 0) {
531 return true;
532 }
533 }
534 return false;
535}
536
537template <class T>
538std::vector<TCanvas*> painter::makeSummaryCanvases(const CalDet<T>& calDet, int nbins1D, float xMin1D, float xMax1D, bool onlyFilled, std::vector<TCanvas*>* outputCanvases)
539{
540
541 std::vector<TCanvas*> vecCanvases;
542
543 auto nROCs = calDet.getData().size();
544
545 if (onlyFilled) {
546 nROCs = 0;
547 for (size_t iroc = 0; iroc < calDet.getData().size(); ++iroc) {
548 const auto& roc = calDet.getCalArray(iroc);
549
550 if (hasData(roc)) {
551 ++nROCs;
552 }
553 }
554
555 if (!nROCs) {
556 return vecCanvases;
557 }
558 }
559
560 // ===| set up canvases |===
561 TCanvas* cSides = nullptr;
562 TCanvas* cROCs1D = nullptr;
563 TCanvas* cROCs2D = nullptr;
564 const std::string_view calName = calDet.getName();
565
566 if (outputCanvases) {
567 if (outputCanvases->size() < 3) {
568 LOGP(error, "At least 3 canvases are needed to fill the output, only {} given", outputCanvases->size());
569 return vecCanvases;
570 }
571
572 cSides = outputCanvases->at(0);
573 cROCs1D = outputCanvases->at(1);
574 cROCs2D = outputCanvases->at(2);
575 cSides->Clear();
576 cROCs1D->Clear();
577 cROCs2D->Clear();
578 } else {
579
580 cROCs1D = new TCanvas(fmt::format("c_ROCs_{}_1D", calName).data(), fmt::format("{} values for each ROC", calName).data(), 1400, 1000);
581 cROCs2D = new TCanvas(fmt::format("c_ROCs_{}_2D", calName).data(), fmt::format("{} values for each ROC", calName).data(), 1400, 1000);
582 }
583 cSides = draw(calDet, nbins1D, xMin1D, xMax1D, cSides);
584 cROCs1D->DivideSquare(nROCs);
585 cROCs2D->DivideSquare(nROCs);
586
587 vecCanvases.emplace_back(cSides);
588 vecCanvases.emplace_back(cROCs1D);
589 vecCanvases.emplace_back(cROCs2D);
590
591 // ===| produce plots for each ROC |===
592 size_t pad = 1;
593 for (size_t iroc = 0; iroc < calDet.getData().size(); ++iroc) {
594 const auto& roc = calDet.getCalArray(iroc);
595
596 if (onlyFilled && !hasData(roc)) {
597 continue;
598 }
599
600 // ===| 1D histogram |===
601 auto h1D = new TH1F(fmt::format("h1_{}_{:02d}", calName, iroc).data(), fmt::format("{} distribution ROC {:02d} ({});ADC value", calName, iroc, getROCTitle(iroc)).data(), nbins1D, xMin1D, xMax1D);
602 for (const auto& val : roc.getData()) {
603 h1D->Fill(double(val));
604 }
605
606 // ===| 2D histogram |===
607 auto h2D = painter::getHistogram2D(roc);
608 h2D->SetStats(0);
609 if (xMax1D > xMin1D) {
610 h2D->SetMinimum(xMin1D);
611 h2D->SetMaximum(xMax1D);
612 }
613 h2D->SetUniqueID(iroc);
614
615 cROCs1D->cd(pad);
616 h1D->Draw();
617
618 cROCs2D->cd(pad);
619 h2D->Draw("colz");
620
621 ++pad;
622
623 // associate histograms to canvas
624 h1D->SetBit(TObject::kCanDelete);
625 h2D->SetBit(TObject::kCanDelete);
626 }
627
628 return vecCanvases;
629}
630
631std::vector<TCanvas*> o2::tpc::painter::makeSummaryCanvases(TTree& tree, const std::string_view draw, std::string_view cut, int nbins1D, float xMin1D, float xMax1D)
632{
633 const Mapper& mapper = Mapper::instance();
634
635 std::vector<TCanvas*> vecCanvases;
636
637 // ===| name and title |======================================================
638 std::string title = draw.data();
639 std::string name = title;
640 std::replace(name.begin(), name.end(), ' ', '_');
641 std::replace(name.begin(), name.end(), '/', '_');
642 const std::string_view calName = name;
643
644 // ===| Per ROC histograms |===
645 if (nbins1D > 0) {
646 const size_t nROCs = 72;
647 auto cROCs1D = new TCanvas(fmt::format("c_ROCs_{}_1D", calName).data(), fmt::format("{} values for each ROC", calName).data(), 1400, 1000);
648 auto cROCs2D = new TCanvas(fmt::format("c_ROCs_{}_2D", calName).data(), fmt::format("{} values for each ROC", calName).data(), 1400, 1000);
649
650 cROCs1D->DivideSquare(nROCs);
651 cROCs2D->DivideSquare(nROCs);
652
653 vecCanvases.emplace_back(cROCs1D);
654 vecCanvases.emplace_back(cROCs2D);
655
656 // ===| produce plots for each ROC |===
657 size_t pad = 1;
658 for (size_t iroc = 0; iroc < nROCs; ++iroc) {
659
660 // ===| 1D histogram |===
661 auto h1D = new TH1F(fmt::format("h1_{}_{:02d}", calName, iroc).data(), fmt::format("{} distribution ROC {:02d} ({});{}", calName, iroc, getROCTitle(iroc), draw).data(), nbins1D, xMin1D, xMax1D);
662 tree.Draw(fmt::format("{} >> {}", draw, h1D->GetName()).data(), fmt::format("(roc == {}) && ({})", iroc, cut).data(), "goff");
663
664 // ===| 2D histogram |===
665 const int nrows = mapper.getNumberOfPadRows(PadSubset::ROC, iroc);
666 const int npads = mapper.getNumberOfPadsInRow(PadSubset::ROC, iroc, nrows - 1) + 6;
667
668 // ===| create histogram |====================================================
669
670 const std::string rocTitle = title + fmt::format(" ({})", getROCTitle(iroc));
671
672 auto h2D = new TProfile2D(fmt::format("h_{}_ROC{}", name, iroc).data(),
673 fmt::format("{};pad row;pad;{}", rocTitle, draw).data(),
674 nrows, 0., nrows,
675 npads, -npads / 2., npads / 2.);
676 tree.Draw(fmt::format("{} : cpad : row >> {}", draw, h2D->GetName()).data(), fmt::format("(roc == {}) && ({})", iroc, cut).data(), "profcolzgoff");
677
678 h2D->SetStats(0);
679 if (xMax1D > xMin1D) {
680 h2D->SetMinimum(xMin1D);
681 h2D->SetMaximum(xMax1D);
682 }
683 h2D->SetUniqueID(iroc);
684
685 cROCs1D->cd(pad);
686 h1D->Draw();
687
688 cROCs2D->cd(pad);
689 h2D->Draw("colz");
690
691 ++pad;
692
693 // associate histograms to canvas
694 h1D->SetBit(TObject::kCanDelete);
695 h2D->SetBit(TObject::kCanDelete);
696 }
697 }
698
699 // ===| Side histograms |=====================================================
700
701 // ---| define histograms |---------------------------------------------------
702 // TODO: auto scaling of ranges based on mean and variance?
703 // for the moment use roots auto scaling
704
705 // set buffer size such that autoscaling uses the full range. This is about 2MB per histogram!
706 const int bufferSize = TH1::GetDefaultBufferSize();
707 TH1::SetDefaultBufferSize(Sector::MAXSECTOR * mapper.getPadsInSector());
708
709 auto hAside1D = new TH1F(fmt::format("h_Aside_1D_{}", name).data(), fmt::format("{0} (A-Side);{0}", title).data(),
710 std::abs(nbins1D), xMin1D, xMax1D); // TODO: modify ranges
711
712 auto hCside1D = new TH1F(fmt::format("h_Cside_1D_{}", name).data(), fmt::format("{0} (C-Side);{0}", title).data(),
713 std::abs(nbins1D), xMin1D, xMax1D); // TODO: modify ranges
714
715 auto hAside2D = new TProfile2D(fmt::format("h_Aside_2D_{}", name).data(), fmt::format("{} (A-Side);#it{{x}} (cm);#it{{y}} (cm);{}", title, draw).data(),
716 330, -270, 270, 330, -270, 270);
717
718 auto hCside2D = new TProfile2D(fmt::format("h_Cside_2D_{}", name).data(), fmt::format("{} (C-Side);#it{{x}} (cm);#it{{y}} (cm);{}", title, draw).data(),
719 330, -270, 270, 330, -270, 270);
720
721 tree.Draw(fmt::format("{} >> {}", draw, hAside1D->GetName()).data(), fmt::format("(A_Side) && ({})", cut).data(), "goff");
722 tree.Draw(fmt::format("{} >> {}", draw, hCside1D->GetName()).data(), fmt::format("(C_Side) && ({})", cut).data(), "goff");
723 tree.Draw(fmt::format("{} : gy : gx >> {}", draw, hAside2D->GetName()).data(), fmt::format("(A_Side) && ({})", cut).data(), "profcolzgoff");
724 tree.Draw(fmt::format("{} : gy : gx >> {}", draw, hCside2D->GetName()).data(), fmt::format("(C_Side) && ({})", cut).data(), "profcolzgoff");
725
726 if (xMax1D > xMin1D) {
727 hAside2D->SetMinimum(xMin1D);
728 hAside2D->SetMaximum(xMax1D);
729 hCside2D->SetMinimum(xMin1D);
730 hCside2D->SetMaximum(xMax1D);
731 }
732
733 // ===| Draw histograms |=====================================================
734 gStyle->SetOptStat("mr");
735 auto cSides = new TCanvas(fmt::format("c_{}", name).data(), title.data(), 1000, 1000);
736 vecCanvases.emplace_back(cSides);
737
738 gStyle->SetStatX(1. - gPad->GetRightMargin());
739 gStyle->SetStatY(1. - gPad->GetTopMargin());
740
741 cSides->Clear();
742 cSides->Divide(2, 2);
743
744 cSides->cd(1);
745 hAside2D->Draw("colz");
746 hAside2D->SetStats(0);
747 hAside2D->SetTitleOffset(1.05, "XY");
748 hAside2D->SetTitleSize(0.05, "XY");
749 adjustPalette(hAside2D, 0.92);
750 drawSectorsXY(Side::A);
751
752 cSides->cd(2);
753 hCside2D->Draw("colz");
754 hCside2D->SetStats(0);
755 hCside2D->SetTitleOffset(1.05, "XY");
756 hCside2D->SetTitleSize(0.05, "XY");
757 adjustPalette(hCside2D, 0.92);
758 drawSectorsXY(Side::C);
759
760 cSides->cd(3);
761 hAside1D->Draw();
762
763 cSides->cd(4);
764 hCside1D->Draw();
765
766 // reset the buffer size
767 TH1::SetDefaultBufferSize(bufferSize);
768
769 // associate histograms to canvas
770 hAside1D->SetBit(TObject::kCanDelete);
771 hCside1D->SetBit(TObject::kCanDelete);
772 hAside2D->SetBit(TObject::kCanDelete);
773 hCside2D->SetBit(TObject::kCanDelete);
774
775 return vecCanvases;
776}
777
778//______________________________________________________________________________
779std::vector<TCanvas*> painter::makeSummaryCanvases(const std::string_view fileName, const std::string_view calPadNames, int nbins1D, float xMin1D, float xMax1D, bool onlyFilled)
780{
781 using namespace o2::tpc;
782
783 const auto calPads = utils::readCalPads(fileName, calPadNames);
784
785 std::vector<TCanvas*> vecCanvases;
786
787 for (const auto calPad : calPads) {
788 auto canvases = makeSummaryCanvases(*calPad, nbins1D, xMin1D, xMax1D, onlyFilled);
789 for (auto c : canvases) {
790 vecCanvases.emplace_back(c);
791 }
792 }
793
794 return vecCanvases;
795}
796
797//______________________________________________________________________________
798TH2Poly* painter::makeSectorHist(const std::string_view name, const std::string_view title, const float xMin, const float xMax, const float yMin, const float yMax, const Type type)
799{
800 auto poly = new TH2Poly(name.data(), title.data(), xMin, xMax, yMin, yMax);
801
803 for (const auto& coord : coords) {
804 poly->AddBin(coord.xVals.size(), coord.xVals.data(), coord.yVals.data());
805 }
806
807 return poly;
808}
809
810//______________________________________________________________________________
811TH2Poly* painter::makeSideHist(Side side, const Type type)
812{
813 const auto s = (side == Side::A) ? "A" : "C";
814 auto poly = new TH2Poly(fmt::format("hSide_{}", s).data(), fmt::format("{}-Side;#it{{x}} (cm);#it{{y}} (cm)", s).data(), -270., 270., -270., 270.);
815
817 for (int isec = 0; isec < 18; ++isec) {
818 const float angDeg = 10.f + isec * 20;
819 for (auto coord : coords) {
820 coord.rotate(angDeg);
821 poly->AddBin(coord.xVals.size(), coord.xVals.data(), coord.yVals.data());
822 }
823 }
824
825 return poly;
826}
827
828//______________________________________________________________________________
829template <class T>
830void painter::fillPoly2D(TH2Poly& h2D, const CalDet<T>& calDet, Side side)
831{
832 const Mapper& mapper = Mapper::instance();
833
834 int bin = 1;
835 for (const auto& calROC : calDet.getData()) {
836 ROC roc(calROC.getPadSubsetNumber());
837 if (roc.side() != side) {
838 continue;
839 }
840
841 const int nrows = mapper.getNumberOfRowsROC(roc);
842 for (int irow = 0; irow < nrows; ++irow) {
843 const int padMax = mapper.getNumberOfPadsInRowROC(roc, irow) - 1;
844 for (int ipad = 0; ipad <= padMax; ++ipad) {
845 const auto pos = mapper.getPadCentre(PadROCPos(calROC.getPadSubsetNumber(), irow, ipad));
846 const auto val = calDet.getValue(roc, irow, ipad);
847 h2D.Fill(pos.X(), pos.Y(), val);
848 }
849 }
850 }
851}
852
853//______________________________________________________________________________
854void painter::drawSectorsXY(Side side, int sectorLineColor, int sectorTextColor)
855{
856 TLine l;
857 l.SetLineColor(std::abs(sectorLineColor));
858
859 TLatex latSide;
860 latSide.SetTextColor(sectorTextColor);
861 latSide.SetTextAlign(22);
862 latSide.SetTextSize(0.08);
863 if (sectorTextColor >= 0) {
864 latSide.DrawLatex(0, 0, (side == Side::C) ? "C" : "A");
865 }
866
867 TLatex lat;
868 lat.SetTextAlign(22);
869 lat.SetTextSize(0.03);
870 lat.SetTextColor(std::abs(sectorLineColor));
871
872 constexpr float phiWidth = float(SECPHIWIDTH);
873 const float rFactor = std::cos(phiWidth / 2.);
874 const float rLow = 83.65 / rFactor;
875 const float rIROCup = 133.3 / rFactor;
876 const float rOROClow = 133.5 / rFactor;
877 const float rOROC12 = 169.75 / rFactor;
878 const float rOROC23 = 207.85 / rFactor;
879 const float rOut = 247.7 / rFactor;
880 const float rText = rLow * rFactor * 3. / 4.;
881
882 for (Int_t isector = 0; isector < 18; ++isector) {
883 const float sinR = std::sin(phiWidth * isector);
884 const float cosR = std::cos(phiWidth * isector);
885
886 const float sinL = std::sin(phiWidth * ((isector + 1) % 18));
887 const float cosL = std::cos(phiWidth * ((isector + 1) % 18));
888
889 const float sinText = std::sin(phiWidth * (isector + 0.5));
890 const float cosText = std::cos(phiWidth * (isector + 0.5));
891
892 const float xR1 = rLow * cosR;
893 const float yR1 = rLow * sinR;
894 const float xR2 = rOut * cosR;
895 const float yR2 = rOut * sinR;
896
897 const float xL1 = rLow * cosL;
898 const float yL1 = rLow * sinL;
899 const float xL2 = rOut * cosL;
900 const float yL2 = rOut * sinL;
901
902 const float xOROCmup1 = rOROClow * cosR;
903 const float yOROCmup1 = rOROClow * sinR;
904 const float xOROCmup2 = rOROClow * cosL;
905 const float yOROCmup2 = rOROClow * sinL;
906
907 const float xIROCmup1 = rIROCup * cosR;
908 const float yIROCmup1 = rIROCup * sinR;
909 const float xIROCmup2 = rIROCup * cosL;
910 const float yIROCmup2 = rIROCup * sinL;
911
912 const float xO121 = rOROC12 * cosR;
913 const float yO121 = rOROC12 * sinR;
914 const float xO122 = rOROC12 * cosL;
915 const float yO122 = rOROC12 * sinL;
916
917 const float xO231 = rOROC23 * cosR;
918 const float yO231 = rOROC23 * sinR;
919 const float xO232 = rOROC23 * cosL;
920 const float yO232 = rOROC23 * sinL;
921
922 const float xText = rText * cosText;
923 const float yText = rText * sinText;
924
925 // left side line
926 l.DrawLine(xR1, yR1, xR2, yR2);
927
928 // IROC inner line
929 l.DrawLine(xR1, yR1, xL1, yL1);
930
931 // IROC end line
932 l.DrawLine(xIROCmup1, yIROCmup1, xIROCmup2, yIROCmup2);
933
934 // OROC start line
935 l.DrawLine(xOROCmup1, yOROCmup1, xOROCmup2, yOROCmup2);
936
937 // OROC1 - OROC2 line
938 l.DrawLine(xO121, yO121, xO122, yO122);
939
940 // OROC2 - OROC3 line
941 l.DrawLine(xO231, yO231, xO232, yO232);
942
943 // IROC inner line
944 l.DrawLine(xR2, yR2, xL2, yL2);
945
946 // sector numbers
947 if (sectorLineColor >= 0) {
948 lat.DrawLatex(xText, yText, fmt::format("{}", isector).data());
949 }
950 }
951}
952
953void painter::drawSectorLocalPadNumberPoly(short padTextColor, float lineScalePS)
954{
955 const Mapper& mapper = Mapper::instance();
956 const auto coords = getPadCoordinatesSector();
957 TLatex lat;
958 lat.SetTextAlign(12);
959 lat.SetTextSize(0.002f);
960 lat.SetTextColor(padTextColor);
961 gStyle->SetLineScalePS(lineScalePS);
962
963 for (unsigned int iregion = 0; iregion < Mapper::NREGIONS; ++iregion) {
964 const auto padInf = mapper.getPadRegionInfo(iregion);
965 for (unsigned int irow = 0; irow < Mapper::ROWSPERREGION[iregion]; ++irow) {
966 for (unsigned int ipad = 0; ipad < Mapper::PADSPERROW[iregion][irow]; ++ipad) {
967 const GlobalPadNumber padNum = o2::tpc::Mapper::getGlobalPadNumber(irow, ipad, iregion);
968 const auto coordinate = coords[padNum];
969 const float yPos = (coordinate.yVals[0] + coordinate.yVals[2]) / 2;
970 const float xPos = (coordinate.xVals[0] + coordinate.xVals[2]) / 2;
971 lat.DrawLatex(xPos, yPos, Form("%i", ipad));
972 }
973 }
974 }
975}
976
977void painter::drawSectorInformationPoly(short regionLineColor, short rowTextColor)
978{
979 const Mapper& mapper = Mapper::instance();
980
981 TLatex lat;
982 lat.SetTextColor(rowTextColor);
983 lat.SetTextSize(0.02f);
984 lat.SetTextAlign(12);
985
986 TLine line;
987 line.SetLineColor(regionLineColor);
988
989 std::vector<float> radii(Mapper::NREGIONS + 1);
990 radii.back() = 247;
991 for (unsigned int ireg = 0; ireg < Mapper::NREGIONS; ++ireg) {
992 const auto reg = mapper.getPadRegionInfo(ireg);
993 const float rad = reg.getRadiusFirstRow();
994 radii[ireg] = rad;
995 line.DrawLine(rad, -43, rad, 43);
996 }
997
998 // draw top region information
999 for (unsigned int ireg = 0; ireg < Mapper::NREGIONS; ++ireg) {
1000 lat.DrawLatex((radii[ireg] + radii[ireg + 1]) / 2, 45, Form("%i", ireg));
1001 }
1002
1003 lat.SetTextSize(0.002f);
1004 lat.SetTextAlign(13);
1005 // draw local and global rows
1006 const std::array<float, Mapper::NREGIONS> posRow{16.2f, 18.2f, 20.2f, 22.3f, 26.f, 29.f, 33.f, 35.f, 39.f, 42.5f};
1007 int globalRow = 0;
1008 for (unsigned int ireg = 0; ireg < Mapper::NREGIONS; ++ireg) {
1009 const auto reg = mapper.getPadRegionInfo(ireg);
1010 const float nRows = reg.getNumberOfPadRows();
1011 for (int i = 0; i < nRows; ++i) {
1012 const float padHeight = reg.getPadHeight();
1013 const float radiusFirstRow = reg.getRadiusFirstRow();
1014 const float xPos = radiusFirstRow + (i + 0.5f) * padHeight;
1015 const float yPos = posRow[ireg];
1016 // row in region
1017 lat.DrawLatex(xPos, yPos, Form("%i", i));
1018 lat.DrawLatex(xPos, -yPos, Form("%i", i));
1019 // row in sector
1020 const float offs = 0.5f;
1021 lat.DrawLatex(xPos, yPos + offs, Form("%i", globalRow));
1022 lat.DrawLatex(xPos, -yPos - offs, Form("%i", globalRow++));
1023 }
1024 }
1025}
1026
1027template <typename DataT>
1028TH3F painter::convertCalDetToTH3(const std::vector<CalDet<DataT>>& calDet, const bool norm, const int nRBins, const float rMin, const float rMax, const int nPhiBins, const float zMax)
1029{
1030 const int nZBins = calDet.size();
1031 TH3F histConvSum("hisCalDet", "hisCalDet", nPhiBins, 0, o2::constants::math::TwoPI, nRBins, rMin, rMax, 2 * nZBins, -zMax, zMax); // final converted histogram
1032 TH3F histConvWeight("histConvWeight", "histConvWeight", nPhiBins, 0, o2::constants::math::TwoPI, nRBins, rMin, rMax, 2 * nZBins, -zMax, zMax);
1033
1034 typedef boost::geometry::model::polygon<boost::geometry::model::d2::point_xy<float>> polygon;
1035 const auto coords = o2::tpc::painter::getPadCoordinatesSector(); // coordinates of the pads in one sector
1036
1037 // create polygons per pad of the input histogram
1038 std::vector<polygon> geoBin;
1039 const int nGeoBins = nPhiBins * nRBins;
1040 geoBin.reserve(nGeoBins);
1041 for (int iphi = 1; iphi <= nPhiBins; ++iphi) {
1042 const double phiLow = histConvSum.GetXaxis()->GetBinLowEdge(iphi);
1043 const double phiUp = histConvSum.GetXaxis()->GetBinUpEdge(iphi);
1044 for (int ir = 1; ir <= nRBins; ++ir) {
1045 const double rLow = histConvSum.GetYaxis()->GetBinLowEdge(ir);
1046 const double rUp = histConvSum.GetYaxis()->GetBinUpEdge(ir);
1047 const double xPos1 = rLow * std::cos(phiLow);
1048 const double yPos1 = rLow * std::sin(phiLow);
1049 const double xPos2 = rLow * std::cos(phiUp);
1050 const double yPos2 = rLow * std::sin(phiUp);
1051 const double xPos4 = rUp * std::cos(phiLow);
1052 const double yPos4 = rUp * std::sin(phiLow);
1053 const double xPos3 = rUp * std::cos(phiUp);
1054 const double yPos3 = rUp * std::sin(phiUp);
1055 // round the values due to problems in intersection in boost with polygons close to each other
1056 boost::geometry::read_wkt(Form("POLYGON((%.4f %.4f, %.4f %.4f, %.4f %.4f, %.4f %.4f, %.4f %.4f))", xPos1, yPos1, xPos2, yPos2, xPos3, yPos3, xPos4, yPos4, xPos1, yPos1), geoBin.emplace_back());
1057 boost::geometry::correct(geoBin.back());
1058 }
1059 }
1060
1061 for (unsigned int sector = 0; sector < Mapper::NSECTORS / 2; ++sector) {
1062 for (unsigned int region = 0; region < Mapper::NREGIONS; ++region) {
1063 const unsigned int rowsRegion = o2::tpc::Mapper::ROWSPERREGION[region];
1064 for (unsigned int iRow = 0; iRow < rowsRegion; ++iRow) {
1065 const unsigned int padsInRow = o2::tpc::Mapper::PADSPERROW[region][iRow] - 1;
1066 for (unsigned int iPad = 0; iPad <= padsInRow; ++iPad) {
1067 const GlobalPadNumber padNum = Mapper::getGlobalPadNumber(iRow, iPad, region);
1068
1069 const float angDeg = 10.f + sector * 20;
1070 auto coordinate = coords[padNum];
1071 coordinate.rotate(angDeg);
1072
1073 const std::array<double, 2> radiusPadCoord{
1074 std::sqrt(coordinate.xVals[0] * coordinate.xVals[0] + coordinate.yVals[0] * coordinate.yVals[0]),
1075 std::sqrt(coordinate.xVals[2] * coordinate.xVals[2] + coordinate.yVals[2] * coordinate.yVals[2]),
1076 };
1077
1078 std::array<float, 4> phiPadCoord{
1079 static_cast<float>(std::atan2(coordinate.yVals[0], coordinate.xVals[0])),
1080 static_cast<float>(std::atan2(coordinate.yVals[1], coordinate.xVals[1])),
1081 static_cast<float>(std::atan2(coordinate.yVals[2], coordinate.xVals[2])),
1082 static_cast<float>(std::atan2(coordinate.yVals[3], coordinate.xVals[3]))};
1083
1084 for (auto& phi : phiPadCoord) {
1086 }
1087
1088 // bins of the histogram of the edges of the pad
1089 const int binRBottomStart = std::clamp(histConvSum.GetYaxis()->FindBin(radiusPadCoord[0]) - 1, 1, nRBins);
1090 const int binRTopEnd = std::clamp(histConvSum.GetYaxis()->FindBin(radiusPadCoord[1]) + 1, 1, nRBins);
1091 int binPhiStart = std::min(histConvSum.GetXaxis()->FindBin(phiPadCoord[0]), histConvSum.GetXaxis()->FindBin(phiPadCoord[1]));
1092 int binPhiEnd = std::max(histConvSum.GetXaxis()->FindBin(phiPadCoord[2]), histConvSum.GetXaxis()->FindBin(phiPadCoord[3]));
1093
1094 // define boost geoemtry object
1095 polygon geoPad;
1096 boost::geometry::read_wkt(Form("POLYGON((%f %f, %f %f, %f %f, %f %f, %f %f))", coordinate.xVals[0], coordinate.yVals[0], coordinate.xVals[1], coordinate.yVals[1], coordinate.xVals[2], coordinate.yVals[2], coordinate.xVals[3], coordinate.yVals[3], coordinate.xVals[0], coordinate.yVals[0]), geoPad);
1097 boost::geometry::correct(geoPad);
1098
1099 for (int binR = binRBottomStart; binR <= binRTopEnd; ++binR) {
1100 for (int binPhi = binPhiStart; binPhi <= binPhiEnd; ++binPhi) {
1101 const int ind = (binPhi - 1) * nRBins + binR - 1;
1102
1103 std::deque<polygon> output;
1104 boost::geometry::intersection(geoPad, geoBin[ind], output);
1105 if (output.empty()) {
1106 continue;
1107 }
1108 const double area = boost::geometry::area(output.front());
1109 const double fac = area * Mapper::INVPADAREA[region];
1110
1111 for (int iSide = 0; iSide < 2; ++iSide) {
1112 const Side side = iSide == 0 ? Side::C : Side::A;
1113 const unsigned int iCRU = side == Side::A ? (sector * Mapper::NREGIONS + region) : ((sector + Mapper::NSECTORS / 2) * Mapper::NREGIONS + region);
1114 const CRU cru(iCRU);
1115
1116 for (int iz = 0; iz < nZBins; ++iz) {
1117 const auto val = calDet[iz].getValue(cru, iRow, (side == Side::A) ? iPad : padsInRow - iPad);
1118 const int zBin = side == Side::A ? (nZBins + iz + 1) : (nZBins - iz);
1119 const auto globBin = histConvSum.GetBin(binPhi, binR, zBin);
1120 histConvSum.AddBinContent(globBin, val * fac);
1121 if (norm) {
1122 histConvWeight.AddBinContent(globBin, fac);
1123 }
1124 }
1125 }
1126 }
1127 }
1128 }
1129 }
1130 }
1131 }
1132
1133 if (norm) {
1134 histConvSum.Divide(&histConvWeight);
1135 }
1136
1137 return histConvSum;
1138}
1139
1140std::vector<TCanvas*> painter::makeSummaryCanvases(const LtrCalibData& ltr, std::vector<TCanvas*>* outputCanvases)
1141{
1142 std::vector<TCanvas*> vecCanvases;
1143
1144 // ===| set up canvases |===
1145 TCanvas* cLtrCoverage = nullptr;
1146 TCanvas* cLtrdEdx = nullptr;
1147 TCanvas* cCalibValues = nullptr;
1148
1149 const auto size = 1400;
1150 if (outputCanvases) {
1151 if (outputCanvases->size() < 3) {
1152 LOGP(error, "At least 3 canvases are needed to fill the output, only {} given", outputCanvases->size());
1153 return vecCanvases;
1154 }
1155
1156 cLtrCoverage = outputCanvases->at(0);
1157 cCalibValues = outputCanvases->at(1);
1158 cLtrdEdx = outputCanvases->at(2);
1159 cLtrCoverage->Clear();
1160 cCalibValues->Clear();
1161 cLtrdEdx->Clear();
1162 cLtrCoverage->SetCanvasSize(size, 2. * size * 7 / 24 * 1.1);
1163 cCalibValues->SetCanvasSize(size, 2. * size * 7 / 24 * 1.1);
1164 cLtrdEdx->SetCanvasSize(size, 2. * size * 7 / 24 * 1.1);
1165 } else {
1166 cLtrCoverage = new TCanvas("cLtrCoverage", "laser track coverage", size, 2. * size * 7 / 24 * 1.1);
1167 cLtrdEdx = new TCanvas("cLtrdEdx", "laser track average dEdx", size, 2. * size * 7 / 24 * 1.1);
1168 cCalibValues = new TCanvas("cCalibValues", "calibration values", size, 2. * size * 7 / 24 * 1.1);
1169
1170 // TODO: add cCalibValues
1171 }
1172
1173 auto getLtrStatHist = [](Side side, std::string_view type = "Coverage") -> TH2F* {
1174 auto sideName = (side == Side::A) ? "A" : "C";
1175 auto hltr = new TH2F(fmt::format("hltr{}_{}", type, sideName).data(), ";Bundle ID;Track in bundle", 24, 0, 24, 7, 0, 7);
1176 hltr->SetBit(TObject::kCanDelete);
1177 hltr->SetStats(0);
1178 hltr->GetXaxis()->SetNdivisions(406, false);
1179 hltr->GetYaxis()->SetNdivisions(107, false);
1180 hltr->SetLabelSize(0.05, "XY");
1181 hltr->SetTitleSize(0.06, "X");
1182 hltr->SetTitleSize(0.07, "Y");
1183 hltr->SetTitleOffset(0.8, "X");
1184 hltr->SetTitleOffset(0.4, "Y");
1185 return hltr;
1186 };
1187
1188 auto drawNames = [](Side side) {
1189 const std::array<const std::string_view, 6> namesA{"A01/02", "A04/05", "A07/08", "A10/11", "A13/14", "A16/17"};
1190 const std::array<const std::string_view, 6> namesC{"C00/01", "C03/04", "C06/07", "C09/10", "C12/13", "C15/16"};
1191 const auto& names = (side == Side::A) ? namesA : namesC;
1192
1193 TLatex lat;
1194 lat.SetTextAlign(22);
1195 lat.SetTextSize(0.06);
1196
1197 TLine line;
1198 for (int i = 0; i < 6; ++i) {
1199 lat.DrawLatex(2.f + i * 4.f, 7.5, names[i].data());
1200 if (i < 5) {
1201 line.DrawLine(4.f + i * 4.f, 0, 4.f + i * 4.f, 8);
1202 }
1203 }
1204 };
1205
1206 auto hltrCoverageA = getLtrStatHist(Side::A);
1207 auto hltrCoverageC = getLtrStatHist(Side::C);
1208
1209 auto hltrdEdxA = getLtrStatHist(Side::A, "dEdx");
1210 auto hltrdEdxC = getLtrStatHist(Side::C, "dEdx");
1211
1212 float dEdxSumA = 0.f;
1213 float dEdxSumC = 0.f;
1214 int nTrackA = 0;
1215 int nTrackC = 0;
1216
1217 for (size_t itrack = 0; itrack < ltr.matchedLtrIDs.size(); ++itrack) {
1218 const auto id = ltr.matchedLtrIDs.at(itrack);
1219 const auto dEdx = ltr.dEdx.at(itrack);
1220 const auto trackID = id % LaserTrack::TracksPerBundle;
1222 const auto sideA = id < (LaserTrack::NumberOfTracks / 2);
1223
1224 auto hltrCoverage = (sideA) ? hltrCoverageA : hltrCoverageC;
1225 auto hltrdEdx = (sideA) ? hltrdEdxA : hltrdEdxC;
1226
1227 hltrCoverage->Fill(bundleID, trackID);
1228 hltrdEdx->Fill(bundleID, trackID, dEdx);
1229
1230 if (sideA) {
1231 dEdxSumA += dEdx;
1232 ++nTrackA;
1233 } else {
1234 dEdxSumC += dEdx;
1235 ++nTrackC;
1236 }
1237 }
1238 // hltrCoverage->Scale(1.f/float(ltr->processedTFs));
1239
1240 if (nTrackA > 1) {
1241 dEdxSumA /= nTrackA;
1242 }
1243
1244 if (nTrackC > 1) {
1245 dEdxSumC /= nTrackC;
1246 }
1247
1248 // ===| coverage canvases |===
1249 cLtrCoverage->Divide(1, 2);
1250
1251 // A-Side
1252 cLtrCoverage->cd(1);
1253 gPad->SetGridx(1);
1254 gPad->SetGridy(1);
1255 gPad->SetRightMargin(0.01);
1256 hltrCoverageA->Draw("col text");
1257 drawNames(Side::A);
1258
1259 // C-Side
1260 cLtrCoverage->cd(2);
1261 gPad->SetGridx(1);
1262 gPad->SetGridy(1);
1263 gPad->SetRightMargin(0.01);
1264 hltrCoverageC->Draw("col text");
1265 drawNames(Side::C);
1266
1267 // ===| dEdx canvases |===
1268 cLtrdEdx->Divide(1, 2);
1269
1270 // A-Side
1271 cLtrdEdx->cd(1);
1272 gPad->SetGridx(1);
1273 gPad->SetGridy(1);
1274 gPad->SetRightMargin(0.01);
1275 hltrdEdxA->Divide(hltrCoverageA);
1276 hltrdEdxA->Draw("col text");
1277 drawNames(Side::A);
1278
1279 // C-Side
1280 cLtrdEdx->cd(2);
1281 gPad->SetGridx(1);
1282 gPad->SetGridy(1);
1283 gPad->SetRightMargin(0.01);
1284 hltrdEdxC->Divide(hltrCoverageC);
1285 hltrdEdxC->Draw("col text");
1286 drawNames(Side::C);
1287
1288 // ===| calibration value canvas |===
1289 // TODO: Implement
1290 auto calibValMsg = new TPaveText(0.1, 0.1, 0.9, 0.9, "NDC");
1291 calibValMsg->SetFillColor(0);
1292 calibValMsg->SetBorderSize(0);
1293 calibValMsg->AddText(fmt::format("processedTFs: {}", ltr.processedTFs).data());
1294 calibValMsg->AddText(fmt::format("dvCorrectionA: {}", ltr.dvCorrectionA).data());
1295 calibValMsg->AddText(fmt::format("dvCorrectionC: {}", ltr.dvCorrectionC).data());
1296 calibValMsg->AddText(fmt::format("dvCorrection: {}", ltr.getDriftVCorrection()).data());
1297 calibValMsg->AddText(fmt::format("dvAbsolute: {}", ltr.refVDrift / ltr.getDriftVCorrection()).data());
1298 calibValMsg->AddText(fmt::format("dvOffsetA: {}", ltr.dvOffsetA).data());
1299 calibValMsg->AddText(fmt::format("dvOffsetC: {}", ltr.dvOffsetC).data());
1300 calibValMsg->AddText(fmt::format("t0A: {}", ltr.getT0A()).data());
1301 calibValMsg->AddText(fmt::format("t0C: {}", ltr.getT0C()).data());
1302 calibValMsg->AddText(fmt::format("nTracksA: {}", ltr.nTracksA).data());
1303 calibValMsg->AddText(fmt::format("nTracksC: {}", ltr.nTracksC).data());
1304 calibValMsg->AddText(fmt::format("#LTdEdx A#GT: {}", dEdxSumA).data());
1305 calibValMsg->AddText(fmt::format("#LTdEdx C#GT: {}", dEdxSumC).data());
1306
1307 cCalibValues->cd();
1308 calibValMsg->Draw();
1309
1310 vecCanvases.emplace_back(cLtrCoverage);
1311 vecCanvases.emplace_back(cCalibValues);
1312 vecCanvases.emplace_back(cLtrdEdx);
1313 return vecCanvases;
1314}
1315
1316TCanvas* painter::makeJunkDetectionCanvas(const TObjArray* data, TCanvas* outputCanvas)
1317{
1318 auto c = outputCanvas;
1319 if (!c) {
1320 c = new TCanvas("junk_detection", "Junk Detection", 1000, 1000);
1321 }
1322
1323 c->Clear();
1324
1325 auto strA = (TH2F*)data->At(4);
1326 auto strB = (TH2F*)data->At(5);
1327
1328 double statsA[7];
1329 double statsB[7];
1330
1331 strA->GetStats(statsA);
1332 strB->GetStats(statsB);
1333
1334 auto junkDetectionMsg = new TPaveText(0.1, 0.1, 0.9, 0.9, "NDC");
1335 junkDetectionMsg->SetFillColor(0);
1336 junkDetectionMsg->SetBorderSize(0);
1337 junkDetectionMsg->AddText("Removal Strategy A");
1338 junkDetectionMsg->AddText(fmt::format("Number of Clusters before Removal: {}", statsA[2]).data());
1339 junkDetectionMsg->AddText(fmt::format("Removed Fraction: {:.2f}%", statsA[4]).data());
1340 junkDetectionMsg->AddLine(.0, .5, 1., .5);
1341 junkDetectionMsg->AddText("Removal Strategy B");
1342 junkDetectionMsg->AddText(fmt::format("Number of Clusters before Removal: {}", statsB[2]).data());
1343 junkDetectionMsg->AddText(fmt::format("Removed Fraction: {:.2f}%", statsB[4]).data());
1344
1345 c->cd();
1346 junkDetectionMsg->Draw();
1347
1348 return c;
1349}
1350
1351void painter::adjustPalette(TH1* h, float x2ndc, float tickLength)
1352{
1353 gPad->Modified();
1354 gPad->Update();
1355 auto palette = (TPaletteAxis*)h->GetListOfFunctions()->FindObject("palette");
1356 if (!palette) {
1357 return;
1358 }
1359 palette->SetX2NDC(x2ndc);
1360 auto ax = h->GetZaxis();
1361 ax->SetTickLength(tickLength);
1362}
1363
1364TMultiGraph* painter::makeMultiGraph(TTree& tree, std::string_view varX, std::string_view varsY, std::string_view errVarsY, std::string_view cut, bool makeSparse)
1365{
1366 bool hasErrors = errVarsY.size() > 0 && (std::count(varsY.begin(), varsY.end(), ':') == std::count(errVarsY.begin(), errVarsY.end(), ':'));
1367
1368 tree.Draw(fmt::format("{} : {} {} {}", varX, varsY, hasErrors ? " : " : "", hasErrors ? errVarsY : "").data(), cut.data(), "goff");
1369 const auto nRows = tree.GetSelectedRows();
1370
1371 // get sort index
1372 std::vector<size_t> idx(tree.GetSelectedRows());
1373 std::iota(idx.begin(), idx.end(), static_cast<size_t>(0));
1374 std::sort(idx.begin(), idx.end(), [&tree](auto a, auto b) { return tree.GetVal(0)[a] < tree.GetVal(0)[b]; });
1375
1376 auto mgr = new TMultiGraph();
1377 const auto params = o2::utils::Str::tokenize(varsY.data(), ':');
1378
1379 for (size_t ivarY = 0; ivarY < params.size(); ++ivarY) {
1380 auto gr = new TGraphErrors(nRows);
1381 gr->SetMarkerSize(1);
1382 gr->SetMarkerStyle(markers[ivarY % markers.size()]);
1383 gr->SetMarkerColor(colors[ivarY % colors.size()]);
1384 gr->SetLineColor(colors[ivarY % colors.size()]);
1385 gr->SetNameTitle(params[ivarY].data(), params[ivarY].data());
1386 for (Long64_t iEntry = 0; iEntry < nRows; ++iEntry) {
1387 if (makeSparse) {
1388 gr->SetPoint(iEntry, iEntry + 0.5, tree.GetVal(ivarY + 1)[idx[iEntry]]);
1389 } else {
1390 gr->SetPoint(iEntry, tree.GetVal(0)[idx[iEntry]], tree.GetVal(ivarY + 1)[idx[iEntry]]);
1391 }
1392 if (hasErrors) {
1393 gr->SetPointError(iEntry, 0, tree.GetVal(ivarY + 1 + params.size())[idx[iEntry]]);
1394 }
1395 }
1396
1397 mgr->Add(gr, "lp");
1398 }
1399
1400 if (makeSparse) {
1401 auto xax = mgr->GetXaxis();
1402 xax->Set(nRows, 0., static_cast<Double_t>(nRows));
1403 for (Long64_t iEntry = 0; iEntry < nRows; ++iEntry) {
1404 xax->SetBinLabel(iEntry + 1, fmt::format("{}", tree.GetVal(0)[idx[iEntry]]).data());
1405 }
1406 xax->LabelsOption("v");
1407 }
1408
1409 return mgr;
1410}
1411
1412// ===| explicit instantiations |===============================================
1413// this is required to force the compiler to create instances with the types
1414// we usually would like to deal with
1415template TCanvas* painter::draw<float>(const CalDet<float>& calDet, int, float, float, TCanvas*);
1416template std::vector<TCanvas*> painter::makeSummaryCanvases<float>(const CalDet<float>& calDet, int, float, float, bool, std::vector<TCanvas*>*);
1417template TCanvas* painter::draw<float>(const CalArray<float>& calArray);
1418template void painter::fillHistogram2D<float>(TH2& h2D, const CalDet<float>& calDet, Side side);
1419template void painter::fillPoly2D<float>(TH2Poly& h2D, const CalDet<float>& calDet, Side side);
1420template void painter::fillHistogram2D<float>(TH2& h2D, const CalArray<float>& calArray);
1421template TH2* painter::getHistogram2D<float>(const CalDet<float>& calDet, Side side);
1422template TH2* painter::getHistogram2D<float>(const CalArray<float>& calArray);
1423
1424template TCanvas* painter::draw<double>(const CalDet<double>& calDet, int, float, float, TCanvas*);
1425template std::vector<TCanvas*> painter::makeSummaryCanvases<double>(const CalDet<double>& calDet, int, float, float, bool, std::vector<TCanvas*>*);
1426template TCanvas* painter::draw<double>(const CalArray<double>& calArray);
1427template TH2* painter::getHistogram2D<double>(const CalDet<double>& calDet, Side side);
1428template TH2* painter::getHistogram2D<double>(const CalArray<double>& calArray);
1429
1430template TCanvas* painter::draw<int>(const CalDet<int>& calDet, int, float, float, TCanvas*);
1431template std::vector<TCanvas*> painter::makeSummaryCanvases<int>(const CalDet<int>& calDet, int, float, float, bool, std::vector<TCanvas*>*);
1432template TCanvas* painter::draw<int>(const CalArray<int>& calArray);
1433template TH2* painter::getHistogram2D<int>(const CalDet<int>& calDet, Side side);
1434template TH2* painter::getHistogram2D<int>(const CalArray<int>& calArray);
1435
1436template TCanvas* painter::draw<short>(const CalDet<short>& calDet, int, float, float, TCanvas*);
1437template std::vector<TCanvas*> painter::makeSummaryCanvases<short>(const CalDet<short>& calDet, int, float, float, bool, std::vector<TCanvas*>*);
1438template TCanvas* painter::draw<short>(const CalArray<short>& calArray);
1439template TH2* painter::getHistogram2D<short>(const CalDet<short>& calDet, Side side);
1440template TH2* painter::getHistogram2D<short>(const CalArray<short>& calArray);
1441
1442template TCanvas* painter::draw<PadFlags>(const CalDet<PadFlags>& calDet, int, float, float, TCanvas*);
1443template std::vector<TCanvas*> painter::makeSummaryCanvases<PadFlags>(const CalDet<PadFlags>& calDet, int, float, float, bool, std::vector<TCanvas*>*);
1444template TCanvas* painter::draw<PadFlags>(const CalArray<PadFlags>& calArray);
1445template TH2* painter::getHistogram2D<PadFlags>(const CalDet<PadFlags>& calDet, Side side);
1446template TH2* painter::getHistogram2D<PadFlags>(const CalArray<PadFlags>& calArray);
1447
1448template TCanvas* painter::draw<bool>(const CalDet<bool>& calDet, int, float, float, TCanvas*);
1449template std::vector<TCanvas*> painter::makeSummaryCanvases<bool>(const CalDet<bool>& calDet, int, float, float, bool, std::vector<TCanvas*>*);
1450template TCanvas* painter::draw<bool>(const CalArray<bool>& calArray);
1451template TH2* painter::getHistogram2D<bool>(const CalDet<bool>& calDet, Side side);
1452template TH2* painter::getHistogram2D<bool>(const CalArray<bool>& calArray);
1453
1454template TH3F painter::convertCalDetToTH3<float>(const std::vector<CalDet<float>>&, const bool, const int, const float, const float, const int, const float);
General auxilliary methods.
int32_t i
float float float & zMax
float & yMax
void output(const std::map< std::string, ChannelStat > &channels)
Definition rawdump.cxx:197
std::enable_if_t< std::is_signed< T >::value, bool > hasData(const CalArray< T > &cal)
Definition Painter.cxx:515
uint16_t pos
Definition RawData.h:3
uint32_t roc
Definition RawData.h:3
uint32_t j
Definition RawData.h:0
uint32_t side
Definition RawData.h:0
uint32_t c
Definition RawData.h:2
uint32_t stack
Definition RawData.h:1
const auto & getData()
Class for time synchronization of RawReader instances.
@ CRUperSector
Definition CRU.h:30
const U getSum() const
calculate the sum of all elements
Definition CalArray.h:109
const std::string & getName() const
Definition CalArray.h:102
PadSubset getPadSubset() const
Definition CalArray.h:89
const std::vector< T > & getData() const
Definition CalArray.h:104
int getPadSubsetNumber() const
Definition CalArray.h:93
const T getValue(const size_t channel) const
Definition CalArray.h:96
const CalType & getCalArray(size_t position) const
Definition CalDet.h:63
const T getValue(const int sec, const int globalPadInSector) const
Definition CalDet.h:154
const std::vector< CalType > & getData() const
Definition CalDet.h:58
const std::string & getName() const
Definition CalDet.h:85
unsigned char getIndex() const
Definition FECInfo.h:41
static constexpr int RodsPerSide
Number of laser rods per side.
Definition LaserTrack.h:30
static constexpr int BundlesPerRod
number of micro-mirror bundle per laser rod
Definition LaserTrack.h:31
static constexpr int NumberOfTracks
Total number of laser tracks.
Definition LaserTrack.h:29
static constexpr int TracksPerBundle
number of micro-mirrors per bundle
Definition LaserTrack.h:32
const std::array< PadRegionInfo, 10 > & getMapPadRegionInfo() const
Definition Mapper.h:386
static GlobalPadNumber getGlobalPadNumber(const unsigned int lrow, const unsigned int pad, const unsigned int region)
Definition Mapper.h:64
static const std::vector< unsigned int > PADSPERROW[NREGIONS]
number of pads per row in region
Definition Mapper.h:567
const FECInfo & fecInfo(GlobalPadNumber padNumber) const
Definition Mapper.h:52
int getNumberOfRowsROC(ROC roc) const
Definition Mapper.h:305
int getNumberOfPadsInRow(PadSubset padSubset, int position, int row) const
Definition Mapper.h:354
int getNumberOfPadsInRowROC(int roc, int row) const
Definition Mapper.h:342
static constexpr float INVPADAREA[NREGIONS]
inverse size of the pad area padwidth*padLength
Definition Mapper.h:536
static Mapper & instance(const std::string mappingDir="")
Definition Mapper.h:44
GlobalPadNumber getPadNumber(const PadSubset padSubset, const size_t padSubsetNumber, const int row, const int pad) const
Definition Mapper.h:134
static constexpr unsigned int ROWSPERREGION[NREGIONS]
number of pad rows for region
Definition Mapper.h:532
static constexpr unsigned int NSECTORS
total number of sectors in the TPC
Definition Mapper.h:526
const PadRegionInfo & getPadRegionInfo(const unsigned char region) const
Definition Mapper.h:385
static constexpr unsigned int NREGIONS
total number of regions in one sector
Definition Mapper.h:527
static constexpr unsigned short getPadsInSector()
Definition Mapper.h:414
int getNumberOfPadRows(PadSubset padSubset, int position) const
Definition Mapper.h:321
GlobalPosition2D getPadCentre(const PadSecPos &padSec) const
Definition Mapper.h:163
Pad and row inside a ROC.
Definition PadROCPos.h:37
float getRadiusFirstRow() const
float getPadHeight() const
bool looped() const
if increment operator went above MaxROC
Definition ROC.h:108
static constexpr int MAXSECTOR
Definition Sector.h:44
GLsizeiptr size
Definition glcorearb.h:659
const GLdouble * v
Definition glcorearb.h:832
GLenum coord
Definition glcorearb.h:4109
GLsizei const GLubyte GLsizei GLenum const void * coords
Definition glcorearb.h:5468
GLuint const GLchar * name
Definition glcorearb.h:781
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLint GLint GLsizei GLint GLenum GLenum type
Definition glcorearb.h:275
GLenum const GLfloat * params
Definition glcorearb.h:272
GLboolean * data
Definition glcorearb.h:298
GLuint GLfloat * val
Definition glcorearb.h:1582
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
constexpr float TwoPI
constexpr std::array< float, nLayers > radii
Definition SpecsV2.h:116
void bringTo02PiGen(float &phi)
Definition Utils.h:80
std::vector< CalPad * > readCalPads(const std::string_view fileName, const std::vector< std::string > &calPadNames)
Definition Utils.cxx:190
Global TPC definitions and constants.
Definition SimTraits.h:167
GEMstack
TPC GEM stack types.
Definition Defs.h:53
constexpr double SECPHIWIDTH
Definition Defs.h:45
PadSubset
Definition of the different pad subsets.
Definition Defs.h:63
@ ROC
ROCs (up to 72)
Side
TPC readout sidE.
Definition Defs.h:35
@ A
Definition Defs.h:35
@ C
Definition Defs.h:36
unsigned short GlobalPadNumber
global pad number
Definition Defs.h:129
constexpr unsigned short GEMSTACKSPERSECTOR
Definition Defs.h:57
const int iz
Definition TrackUtils.h:69
float getDriftVCorrection() const
float dvCorrectionA
drift velocity correction factor A-Side (inverse multiplicative)
float dvOffsetC
drift velocity trigger offset C-Side
float dvOffsetA
drift velocity trigger offset A-Side
float dvCorrectionC
drift velocity correction factor C-Side (inverse multiplicative)
std::vector< uint16_t > matchedLtrIDs
matched laser track IDs
std::vector< float > dEdx
dE/dx of each track
size_t processedTFs
number of processed TFs with laser track candidates
uint16_t nTracksC
number of tracks used for C-Side fit
uint16_t nTracksA
number of tracks used for A-Side fit
float refVDrift
reference vdrift for which factor was extracted
static std::vector< double > getRowBinningCM(uint32_t roc=72)
static std::array< int, 6 > colors
Definition Painter.h:59
static TH3F convertCalDetToTH3(const std::vector< CalDet< DataT > > &calDet, const bool norm=true, const int nRBins=150, const float rMin=83.5, const float rMax=254.5, const int nPhiBins=720, const float zMax=1)
static std::vector< PadCoordinates > getStackCoordinatesSector()
create a vector of stack corner coordinate for one full sector
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 std::array< int, 10 > markers
Definition Painter.h:60
static void fillHistogram2D(TH2 &h2D, const CalDet< T > &calDet, Side side)
static std::vector< o2::tpc::painter::PadCoordinates > getCoordinates(const Type type)
static TMultiGraph * makeMultiGraph(TTree &tree, std::string_view varX, std::string_view varsY, std::string_view errVarsY="", std::string_view cut="", bool makeSparse=true)
static std::string getROCTitle(const int rocNumber)
ROC title from ROC number.
static std::vector< PadCoordinates > getFECCoordinatesSector()
create a vector of FEC corner coordinates for one full sector
static void drawSectorLocalPadNumberPoly(short padTextColor=kBlack, float lineScalePS=1)
static void adjustPalette(TH1 *h, float x2ndc, float tickLength=0.015)
static void fillPoly2D(TH2Poly &h2D, const CalDet< T > &calDet, Side side)
@ FEC
drawing of FECs
@ Stack
drawing stacks
static TH2 * getHistogram2D(const CalDet< T > &calDet, Side side)
static TH2Poly * makeSideHist(Side side, const Type type=Type::Pad)
static void drawSectorInformationPoly(short regionLineColor=kRed, short rowTextColor=kRed)
static void drawSectorsXY(Side side, int sectorLineColor=920, int sectorTextColor=1)
draw sector boundaris, side name and sector numbers
static std::vector< PadCoordinates > getPadCoordinatesSector()
create a vector of pad corner coordinate for one full sector
static TCanvas * makeJunkDetectionCanvas(const TObjArray *data, TCanvas *outputCanvas=nullptr)
make a canvas for junk detection data
static TCanvas * draw(const CalDet< T > &calDet, int nbins1D=300, float xMin1D=0, float xMax1D=0, TCanvas *outputCanvas=nullptr)
static std::vector< TCanvas * > makeSummaryCanvases(const CalDet< T > &calDet, int nbins1D=300, float xMin1D=0, float xMax1D=0, bool onlyFilled=true, std::vector< TCanvas * > *outputCanvases=nullptr)
static std::vector< std::string > tokenize(const std::string &src, char delim, bool trimToken=true, bool skipEmpty=true)
o2::InteractionRecord ir(0, 0)
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))
std::vector< int > row