Project
Loading...
Searching...
No Matches
IDCAverageGroup.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
17#include "TPCBase/Mapper.h"
20
21// root includes
22#include "TFile.h"
23#include "TKey.h"
25#include "TH2Poly.h"
26#include "TCanvas.h"
27#include "TLatex.h"
28#include "TStyle.h"
29#include "Framework/Logger.h"
30
31#if (defined(WITH_OPENMP) || defined(_OPENMP)) && !defined(__CLING__)
32#include <omp.h>
33#else
34static inline int omp_get_thread_num() { return 0; }
35#endif
36
37template <>
39{
40 unsigned int maxValues = 0;
41 for (unsigned int i = 0; i < Mapper::NREGIONS; ++i) {
42 const unsigned int maxGroup = (this->mIDCsGrouped.getGroupRows() + this->mIDCsGrouped.getGroupLastRowsThreshold()) * (this->mIDCsGrouped.getGroupPads() + this->mIDCsGrouped.getGroupLastPadsThreshold() + Mapper::ADDITIONALPADSPERROW[i].back());
43 if (maxGroup > maxValues) {
44 maxValues = maxGroup;
45 }
46 }
47
48 for (auto& rob : this->mRobustAverage) {
49 rob.reserve(maxValues);
50 }
51
52 // init weights
53 const float sigmaEdge = 1.f;
54 this->mWeightsPad.reserve(mOverlapPads);
55 for (int i = 0; i < mOverlapPads; ++i) {
56 const float groupPadsHalf = this->mIDCsGrouped.getGroupPads() / 2.f;
57 const float sigmaPad = groupPadsHalf / sigmaEdge; // assume 3-sigma at the edge of the last pad
58 this->mWeightsPad.emplace_back(normal_dist(groupPadsHalf + i, sigmaPad));
59 }
60
61 this->mWeightsRow.reserve(mOverlapRows);
62 for (int i = 0; i < mOverlapRows; ++i) {
63 const float groupRowsHalf = this->mIDCsGrouped.getGroupRows() / 2.f;
64 const float sigmaRow = groupRowsHalf / sigmaEdge; // assume 3-sigma at the edge of the last pad
65 this->mWeightsRow.emplace_back(normal_dist(groupRowsHalf + i, sigmaRow));
66 }
67}
68
69template <>
71{
72 unsigned int maxValues = 0;
73 for (unsigned int i = 0; i < Mapper::NREGIONS; ++i) {
74 const unsigned int maxGroup = (this->mIDCGroupHelperSector.getGroupingParameter().getGroupRows(i) + this->mIDCGroupHelperSector.getGroupingParameter().getGroupLastRowsThreshold(i)) * (this->mIDCGroupHelperSector.getGroupingParameter().getGroupPads(i) + this->mIDCGroupHelperSector.getGroupingParameter().getGroupLastPadsThreshold(i) + Mapper::ADDITIONALPADSPERROW[i].back());
75 if (maxGroup > maxValues) {
76 maxValues = maxGroup;
77 }
78 }
79
80 for (auto& rob : this->mRobustAverage) {
81 rob.reserve(maxValues);
82 }
83
84 // init weights
85 for (unsigned int region = 0; region < Mapper::NREGIONS; ++region) {
86 const float sigmaEdge = 1.f;
87 this->mWeightsPad[region].reserve(mOverlapPads);
88 for (unsigned int i = 0; i < mOverlapPads; ++i) {
89 const float groupPadsHalf = this->mIDCGroupHelperSector.getGroupingParameter().getGroupPads(i) / 2.f;
90 const float sigmaPad = groupPadsHalf / sigmaEdge; // assume 3-sigma at the edge of the last pad
91 this->mWeightsPad[i].emplace_back(normal_dist(groupPadsHalf + i, sigmaPad));
92 }
93
94 this->mWeightsRow[region].reserve(mOverlapRows);
95 for (unsigned int i = 0; i < mOverlapRows; ++i) {
96 const float groupRowsHalf = this->mIDCGroupHelperSector.getGroupingParameter().getGroupRows(i) / 2.f;
97 const float sigmaRow = groupRowsHalf / sigmaEdge; // assume 3-sigma at the edge of the last pad
98 this->mWeightsRow[i].emplace_back(normal_dist(groupRowsHalf + i, sigmaRow));
99 }
100 }
101}
102
103template <class Type>
104float o2::tpc::IDCAverageGroup<Type>::normal_dist(const float x, const float sigma)
105{
106 const float fac = x / sigma;
107 return std::exp(-fac * fac / 2);
108}
109
110template <>
112{
113 std::vector<IDCAverageGroupHelper<IDCAverageGroupCRU>> idcStruct(sNThreads, IDCAverageGroupHelper<IDCAverageGroupCRU>{this->mIDCsGrouped, this->mWeightsPad, this->mWeightsRow, this->mIDCsUngrouped, this->mRobustAverage, this->getCRU()});
114#pragma omp parallel for num_threads(sNThreads)
115 for (unsigned int integrationInterval = 0; integrationInterval < this->getNIntegrationIntervals(); ++integrationInterval) {
116 const unsigned int threadNum = omp_get_thread_num();
117 idcStruct[threadNum].set(threadNum, integrationInterval);
118 loopOverGroups(idcStruct[threadNum], padStatusFlags);
120}
121
122template <>
124{
125 std::vector<IDCAverageGroupHelper<IDCAverageGroupTPC>> idcStruct(sNThreads, IDCAverageGroupHelper<IDCAverageGroupTPC>{this->mIDCsGrouped, this->mWeightsPad, this->mWeightsRow, this->mIDCsUngrouped, this->mRobustAverage, this->mIDCGroupHelperSector});
126 for (int thread = 0; thread < sNThreads; ++thread) {
127 idcStruct[thread].setThreadNum(thread);
128 }
129
130 const int cruStart = (mSide == Side::A) ? 0 : CRU::MaxCRU / 2;
131 const int cruEnd = (mSide == Side::A) ? CRU::MaxCRU / 2 : CRU::MaxCRU;
132
133#pragma omp parallel for num_threads(sNThreads)
134 for (unsigned int i = cruStart; i < cruEnd; ++i) {
135 const unsigned int threadNum = omp_get_thread_num();
136 const CRU cru(i);
137 idcStruct[threadNum].setCRU(cru);
138 for (unsigned int integrationInterval = 0; integrationInterval < this->getNIntegrationIntervals(); ++integrationInterval) {
139 idcStruct[threadNum].setIntegrationInterval(integrationInterval);
140 loopOverGroups(idcStruct[threadNum], padStatusFlags);
141 }
142 }
143}
144
145template <class Type>
147{
148 const auto& mapper = Mapper::instance();
149 const float xMin = 83.65f;
150 const float xMax = 247.7f;
151 const float yMin = -51;
152 const float yMax = 49;
153 TH2Poly* poly = o2::tpc::painter::makeSectorHist("hSector", "Sector;#it{x} (cm);#it{y} (cm)", xMin, xMax, yMin, yMax);
154 poly->GetXaxis()->SetTickLength(0.01f);
155
156 poly->SetContour(255);
157 gStyle->SetNumberContours(255);
158
159 TCanvas can("can", "can", 2000, 1400);
160 can.SetRightMargin(0.01f);
161 can.SetLeftMargin(0.06f);
162 can.SetTopMargin(0.04f);
163 can.cd();
164 poly->SetTitle(nullptr);
165 poly->GetYaxis()->SetTickSize(0.002f);
166 poly->GetYaxis()->SetTitleOffset(0.7f);
167 poly->SetStats(0);
168 poly->Draw("col");
169
170 int sumIDCs = 0;
171 for (unsigned int i = 0; i < Mapper::NREGIONS; ++i) {
172 if constexpr (std::is_same_v<Type, IDCAverageGroupCRU>) {
173 IDCAverageGroupHelper<IDCAverageGroupDraw> idcStruct(this->mIDCsGrouped.getGroupPads(), this->mIDCsGrouped.getGroupRows(), this->mIDCsGrouped.getGroupLastRowsThreshold(), this->mIDCsGrouped.getGroupLastPadsThreshold(), this->mIDCsGrouped.getGroupPadsSectorEdges(), i, Mapper::PADSPERREGION[i], mapper.getPadRegionInfo(i), *poly);
174 loopOverGroups(idcStruct);
175 const int nidcs = this->mIDCsGrouped.getNIDCsPerIntegrationInterval();
176 sumIDCs += nidcs;
177 drawGroupingInformations(i, this->mIDCsGrouped.getGroupPads(), this->mIDCsGrouped.getGroupRows(), this->mIDCsGrouped.getGroupLastRowsThreshold(), this->mIDCsGrouped.getGroupLastPadsThreshold(), mOverlapRows, mOverlapPads, nidcs, this->mIDCsGrouped.getGroupPadsSectorEdges());
178 } else {
179 IDCAverageGroupHelper<IDCAverageGroupDraw> idcStruct(this->mIDCGroupHelperSector.getGroupingParameter().getGroupPads(i), this->mIDCGroupHelperSector.getGroupingParameter().getGroupRows(i), this->mIDCGroupHelperSector.getGroupingParameter().getGroupLastRowsThreshold(i), this->mIDCGroupHelperSector.getGroupingParameter().getGroupLastPadsThreshold(i), this->mIDCGroupHelperSector.getGroupingParameter().getGroupPadsSectorEdges(), i, Mapper::PADSPERREGION[i], mapper.getPadRegionInfo(i), *poly);
180 loopOverGroups(idcStruct);
181 const int nidcs = this->mIDCGroupHelperSector.getNIDCs(i);
182 sumIDCs += nidcs;
183 drawGroupingInformations(i, this->mIDCGroupHelperSector.getGroupingParameter().getGroupPads(i), this->mIDCGroupHelperSector.getGroupingParameter().getGroupRows(i), this->mIDCGroupHelperSector.getGroupingParameter().getGroupLastRowsThreshold(i), this->mIDCGroupHelperSector.getGroupingParameter().getGroupLastPadsThreshold(i), mOverlapRows, mOverlapPads, nidcs, this->mIDCGroupHelperSector.getGroupingParameter().getGroupPadsSectorEdges());
184 }
185 }
186
187 painter::drawSectorLocalPadNumberPoly(kBlack);
188 painter::drawSectorInformationPoly(kRed, kRed);
189
190 TLatex lat;
191 lat.SetTextColor(kBlack);
192 lat.SetTextSize(0.02f);
193 lat.SetTextAlign(12);
194 const float posYInf = -44.5f;
195 const float offsx = 1;
196 lat.DrawLatex(xMin + offsx, posYInf, "nPads | nRows | nLastPads | nLastRows");
197
198 lat.SetTextColor(kGreen + 2);
199 lat.DrawLatex(mapper.getPadRegionInfo(4).getRadiusFirstRow(), posYInf, "nPadsSectorEdge | overlapRows | overlapPads");
200
201 lat.SetTextColor(kBlack);
202 lat.DrawLatex(xMin + offsx, 47.2f, "IDCs");
203
204 // ToDo add compression factor from root
205 const int dataRate = sumIDCs * Mapper::NSECTORS * sizeof(short) * 1000 / (1024 * 1024); // approximate data rate for IDCDelta: 'number of values per sector' * 'number of sectors' * 'sizeof datatype' * '1000 objects per second' / '1000000: to mega byte'
206 lat.DrawLatex(xMin + offsx, 50.5f, fmt::format("IDCDelta data rate (short): {} MB/s IDCs per sector: {}", dataRate, sumIDCs).data());
207
208 if constexpr (std::is_same_v<Type, IDCAverageGroupCRU>) {
209 const std::string outName = filename.empty() ? fmt::format("grouping_rows-{}_pads-{}_rowThr-{}_padThr-{}_ovRows-{}_ovPads-{}_edge-{}.pdf", this->mIDCsGrouped.getGroupPads(), this->mIDCsGrouped.getGroupRows(), this->mIDCsGrouped.getGroupLastRowsThreshold(), this->mIDCsGrouped.getGroupLastPadsThreshold(), mOverlapRows, mOverlapPads, this->mIDCsGrouped.getGroupPadsSectorEdges()) : filename;
210 can.SaveAs(outName.data());
211 } else {
212 std::string sgrRows = {"_"};
213 std::string sgrPads = {"_"};
214 std::string sgrRowsTh = {"_"};
215 std::string sgrPadsTh = {"_"};
216 if (filename.empty()) {
217 for (unsigned int i = 0; i < Mapper::NREGIONS; ++i) {
218 const int grRows = this->mIDCGroupHelperSector.getGroupingParameter().getGroupRows(i);
219 sgrRows += fmt::format("{}_", grRows);
220 const int grPads = this->mIDCGroupHelperSector.getGroupingParameter().getGroupPads(i);
221 sgrPads += fmt::format("{}_", grPads);
222 const int grRowsTh = this->mIDCGroupHelperSector.getGroupingParameter().getGroupLastRowsThreshold(i);
223 sgrRowsTh += fmt::format("{}_", grRowsTh);
224 const int grPadsTh = this->mIDCGroupHelperSector.getGroupingParameter().getGroupLastPadsThreshold(i);
225 sgrPadsTh += fmt::format("{}_", grPadsTh);
226 }
227 }
228 const std::string outName = filename.empty() ? fmt::format("grouping_rows{}pads{}rowThr{}padThr{}ovRows-{}_ovPads-{}_edge-{}.pdf", sgrRows, sgrPads, sgrRowsTh, sgrPadsTh, mOverlapRows, mOverlapPads, this->mIDCGroupHelperSector.getGroupingParameter().getGroupPadsSectorEdges()) : filename;
229 can.SaveAs(outName.data());
230 }
231 delete poly;
232}
233
234template <class Type>
235void o2::tpc::IDCAverageGroup<Type>::drawGroupingInformations(const int region, const int grPads, const int grRows, const int groupLastRowsThreshold, const int groupLastPadsThreshold, const int overlapRows, const int overlapPads, const int nIDCs, const int groupPadsSectorEdges) const
236{
237 const o2::tpc::Mapper& mapper = Mapper::instance();
238
239 TLatex lat;
240 lat.SetTextColor(kBlack);
241 lat.SetTextSize(0.02f);
242 lat.SetTextAlign(12);
243
244 const float radius = mapper.getPadRegionInfo(region).getRadiusFirstRow();
245
246 // draw grouping parameter
247 lat.DrawLatex(radius, -47, fmt::format("{} | {} | {} | {}", grPads, grRows, groupLastRowsThreshold, groupLastPadsThreshold).data());
248
249 lat.SetTextColor(kGreen + 2);
250 lat.DrawLatex(radius, -49, fmt::format("{} | {} | {}", groupPadsSectorEdges, overlapRows, overlapPads).data());
251
252 // draw number of grouped pads
253 lat.SetTextColor(kBlack);
254 const float radiusNext = region == 9 ? 247.f : mapper.getPadRegionInfo(region + 1).getRadiusFirstRow();
255 lat.DrawLatex((radius + radiusNext) / 2, 47.2f, Form("%i", nIDCs));
256}
257
258template <class Type>
259template <class LoopType>
260void o2::tpc::IDCAverageGroup<Type>::loopOverGroups(IDCAverageGroupHelper<LoopType>& idcStruct, const CalDet<PadFlags>* padStatusFlags)
261{
262 const unsigned int region = idcStruct.getRegion();
263 const int groupRows = idcStruct.getGroupRows();
264 const int groupPads = idcStruct.getGroupPads();
265 const int lastRow = idcStruct.getLastRow();
266 const int groupPadsSectorEdges = idcStruct.getTotalGroupPadsSectorEdges();
267 unsigned int rowGrouped = 0;
268 const bool applyWeights = mOverlapRows && mOverlapPads;
269
270 if (groupPadsSectorEdges) {
271 const auto groupingType = idcStruct.getEdgePadGroupingType();
272 const bool groupRowsEdge = groupingType == EdgePadGroupingMethod::ROWS;
273 const int groupedPads = idcStruct.getGroupedPadsSectorEdges();
274 const int endrow = groupRowsEdge ? lastRow + 1 : Mapper::ROWSPERREGION[region];
275 const int stepRow = groupRowsEdge ? groupRows : 1;
276 for (int ulrow = 0; ulrow < endrow; ulrow += stepRow) {
277 const bool bNotLastrow = ulrow != lastRow;
278
279 if constexpr (std::is_same_v<LoopType, IDCAverageGroupDraw>) {
280 idcStruct.mCol = ulrow / stepRow;
281 }
282
283 for (int iYLocalSide = 0; iYLocalSide < 2; ++iYLocalSide) {
284 int pad = 0;
285 for (int padGroup = 0; padGroup < groupedPads; ++padGroup) {
286 const int nPadsPerGroup = idcStruct.getPadsInGroupSectorEdges(padGroup);
287 for (int padInGroup = 0; padInGroup < nPadsPerGroup; ++padInGroup) {
288 const int endRow = (groupRowsEdge && (ulrow + stepRow >= Mapper::ROWSPERREGION[region] || !bNotLastrow)) ? (Mapper::ROWSPERREGION[region] - ulrow) : stepRow; // last row in this group
289 for (int iRowMerge = 0; iRowMerge < endRow; ++iRowMerge) {
290 const int irow = ulrow + iRowMerge;
291 const int ungroupedPad = !iYLocalSide ? pad : Mapper::PADSPERROW[region][irow] - pad - 1;
292 const int padInRegion = Mapper::OFFSETCRULOCAL[region][irow] + ungroupedPad;
293
294 if constexpr (std::is_same_v<LoopType, IDCAverageGroupCRU> || std::is_same_v<LoopType, IDCAverageGroupTPC>) {
295 if (padStatusFlags) {
296 const auto flag = padStatusFlags->getCalArray(idcStruct.getCRU()).getValue(padInRegion);
297 if ((flag & PadFlags::flagSkip) == PadFlags::flagSkip) {
298 continue;
299 }
300 }
301 idcStruct.addValue(padInRegion, 1);
302 } else {
303 const GlobalPadNumber padNum = o2::tpc::Mapper::getGlobalPadNumber(irow, ungroupedPad, region);
304 drawLatex(idcStruct, padNum, padInRegion, true);
305 }
306 }
307 ++pad;
308 }
309 if constexpr (std::is_same_v<LoopType, IDCAverageGroupCRU> || std::is_same_v<LoopType, IDCAverageGroupTPC>) {
310 const int ungroupedPad = !iYLocalSide ? pad - 1 : Mapper::PADSPERROW[region][ulrow] - pad;
311 idcStruct.setSectorEdgeIDC(ulrow, ungroupedPad);
312 idcStruct.clearRobustAverage();
313 } else {
314 ++idcStruct.mGroupCounter;
315 ++idcStruct.mCol;
316 }
317 }
318 }
319 }
320 }
321
322 // loop over ungrouped row
323 for (int iRow = 0; iRow <= lastRow; iRow += groupRows) {
324 const bool bNotLastrow = iRow != lastRow;
325
326 // the sectors is divide in to two parts around ylocal=0 to get the same simmetric grouping around ylocal=0
327 for (int iYLocalSide = 0; iYLocalSide < 2; ++iYLocalSide) {
328 if constexpr (std::is_same_v<LoopType, IDCAverageGroupDraw>) {
329 idcStruct.mCol = region + iRow / groupRows + iYLocalSide;
330 }
331 unsigned int padGrouped = iYLocalSide ? idcStruct.getPadsPerRow(rowGrouped) / 2 : idcStruct.getPadsPerRow(rowGrouped) / 2 - 1; // grouped pad in pad direction
332 const int nPadsStart = Mapper::PADSPERROW[region][iRow] / 2; // first ungrouped pad in pad direction
333 const int nPadsEnd = idcStruct.getLastPad(iRow) + nPadsStart; // last grouped pad in pad direction
334
335 // loop over ungrouped pads
336 for (int iPad = nPadsStart; iPad <= nPadsEnd; iPad += groupPads) {
337 if constexpr (std::is_same_v<LoopType, IDCAverageGroupCRU> || std::is_same_v<LoopType, IDCAverageGroupTPC>) {
338 idcStruct.clearRobustAverage();
339 }
340
341 const int startRow = ((iRow - mOverlapRows) < 0) ? 0 : -mOverlapRows; // first row in this group
342 const int endRow = ((iRow + groupRows + mOverlapRows) >= Mapper::ROWSPERREGION[region] || !bNotLastrow) ? (Mapper::ROWSPERREGION[region] - iRow) : (mOverlapRows + groupRows); // last row in this group
343 for (int iRowMerge = startRow; iRowMerge < endRow; ++iRowMerge) {
344 const bool bOverlapRowRight = iRowMerge >= groupRows;
345 const unsigned int ungroupedRow = iRow + iRowMerge;
346 const int offsPad = static_cast<int>(Mapper::ADDITIONALPADSPERROW[region][ungroupedRow]) - static_cast<int>(Mapper::ADDITIONALPADSPERROW[region][iRow]); // offset due to additional pads in pad direction in the current row compared to the first row in the group
347
348 const bool lastPad = iPad == nPadsEnd;
349 const int padEnd = lastPad ? (static_cast<int>(Mapper::PADSPERROW[region][ungroupedRow]) - iPad - groupPadsSectorEdges) : (groupPads + offsPad + mOverlapPads); // last ungrouped pad in pad direction
350 const int padStart = offsPad - mOverlapPads; // first ungrouped pad in pad direction
351
352 for (int ipadMerge = padStart; ipadMerge < padEnd; ++ipadMerge) {
353 const unsigned int ungroupedPad = iYLocalSide ? (iPad + ipadMerge) : Mapper::PADSPERROW[region][ungroupedRow] - (iPad + ipadMerge) - 1;
354 const unsigned int padInRegion = Mapper::OFFSETCRULOCAL[region][ungroupedRow] + ungroupedPad;
355
356 // averaging and grouping
357 if constexpr (std::is_same_v<LoopType, IDCAverageGroupCRU> || std::is_same_v<LoopType, IDCAverageGroupTPC>) {
358 // check status flag
359 if (padStatusFlags) {
360 const auto flag = padStatusFlags->getCalArray(idcStruct.getCRU()).getValue(padInRegion);
361 if ((flag & PadFlags::flagSkip) == PadFlags::flagSkip) {
362 continue;
363 }
364 }
365
366 // set weight for outer pads which are not in the main group
367 if (applyWeights) {
368 float weight = 1;
369 if (iRowMerge < 0) {
370 // everything on the left border
371 const int relPosRow = std::abs(iRowMerge);
372 if (ipadMerge < offsPad) {
373 const int relPosPad = std::abs(ipadMerge - offsPad);
374 weight = idcStruct.getWeight(relPosRow, relPosPad);
375 } else if (!lastPad && ipadMerge >= (groupPads + offsPad)) {
376 const int relPosPad = std::abs(1 + ipadMerge - (groupPads + offsPad));
377 weight = idcStruct.getWeight(relPosRow, relPosPad);
378 } else {
379 weight = idcStruct.getWeightRow(relPosRow);
380 }
381 } else if (bNotLastrow && bOverlapRowRight) {
382 const int relPosRow = std::abs(1 + iRowMerge - (groupRows));
383 if (ipadMerge < offsPad) {
384 const int relPosPad = std::abs(ipadMerge - offsPad);
385 weight = idcStruct.getWeight(relPosRow, relPosPad);
386 } else if (!lastPad && ipadMerge >= (groupPads + offsPad)) {
387 const int relPosPad = std::abs(1 + ipadMerge - (groupPads + offsPad));
388 weight = idcStruct.getWeight(relPosRow, relPosPad);
389 } else {
390 weight = idcStruct.getWeightRow(relPosRow);
391 }
392 } else if (ipadMerge < offsPad) {
393 // bottom
394 const int relPadPos = std::abs(ipadMerge - offsPad);
395 weight = idcStruct.getWeightPad(relPadPos);
396 } else if (!lastPad && ipadMerge >= (groupPads + offsPad)) {
397 const int relPadPos = std::abs(1 + ipadMerge - (groupPads + offsPad));
398 weight = idcStruct.getWeightPad(relPadPos);
399 } else {
400 }
401 idcStruct.addValue(padInRegion, weight);
402 } else {
403 idcStruct.addValue(padInRegion);
404 }
405
406 } else {
407 // drawing the grouping
408 const GlobalPadNumber padNum = o2::tpc::Mapper::getGlobalPadNumber(ungroupedRow, ungroupedPad, region);
409 const bool fillNotPoly = iRowMerge < 0 || (bNotLastrow && bOverlapRowRight) || (ipadMerge < offsPad) || (!lastPad && ipadMerge >= (groupPads + offsPad));
410 drawLatex(idcStruct, padNum, padInRegion, !fillNotPoly, idcStruct.mColors.size());
411 }
412 }
413 }
414 if constexpr (std::is_same_v<LoopType, IDCAverageGroupCRU> || std::is_same_v<LoopType, IDCAverageGroupTPC>) {
415 idcStruct.setGroupedIDC(rowGrouped, padGrouped, applyWeights);
416 } else {
417 ++idcStruct.mGroupCounter;
418 ++idcStruct.mCol;
419 }
420 iYLocalSide ? ++padGrouped : --padGrouped;
421 }
422 }
423 ++rowGrouped;
424 }
425}
426
427template <class Type>
428void o2::tpc::IDCAverageGroup<Type>::dumpToFile(const char* outFileName, const char* outName) const
429{
430 TFile fOut(outFileName, "RECREATE");
431 fOut.WriteObject(this, outName);
432 fOut.Close();
433}
434
435template <class Type>
436bool o2::tpc::IDCAverageGroup<Type>::setFromFile(const char* fileName, const char* name)
437{
438 TFile inpf(fileName, "READ");
439 using Temp = IDCAverageGroup<Type>;
440 Temp* idcAverageGroupTmp{nullptr};
441 idcAverageGroupTmp = reinterpret_cast<Temp*>(inpf.GetObjectChecked(name, Temp::Class()));
442
443 if (!idcAverageGroupTmp) {
444 LOGP(error, "Failed to load {} from {}", name, inpf.GetName());
445 return false;
446 }
447 if constexpr (std::is_same_v<Type, IDCAverageGroupCRU>) {
448 this->setIDCs(idcAverageGroupTmp->getIDCsUngrouped());
449 } else {
450 this->setIDCs(idcAverageGroupTmp->getIDCsUngrouped(), idcAverageGroupTmp->getSide());
451 }
452
453 delete idcAverageGroupTmp;
454 return true;
455}
456
457template <>
459{
460 o2::utils::TreeStreamRedirector pcstream(nameFile, "RECREATE");
461 pcstream.GetFile()->cd();
462 IDCAverageGroupHelper<IDCAverageGroupCRU> idcStruct(this->mIDCsGrouped, this->mWeightsPad, this->mWeightsRow, this->mIDCsUngrouped, this->mRobustAverage, this->getCRU());
463 for (unsigned int integrationInterval = 0; integrationInterval < this->getNIntegrationIntervals(); ++integrationInterval) {
464 idcStruct.set(0, integrationInterval);
465 createDebugTree(idcStruct, pcstream);
466 }
467 pcstream.Close();
468}
469
470template <>
472{
473 IDCAverageGroupHelper<IDCAverageGroupTPC> idcStruct(this->mIDCsGrouped, this->mWeightsPad, this->mWeightsRow, this->mIDCsUngrouped, this->mRobustAverage, this->mIDCGroupHelperSector);
474 o2::utils::TreeStreamRedirector pcstream(nameFile, "RECREATE");
475 pcstream.GetFile()->cd();
476 for (unsigned int iCRU = 0; iCRU < CRU::MaxCRU; ++iCRU) {
477 const CRU cru(iCRU);
478 idcStruct.setCRU(cru);
479 for (unsigned int integrationInterval = 0; integrationInterval < this->getNIntegrationIntervals(); ++integrationInterval) {
480 idcStruct.setIntegrationInterval(integrationInterval);
481 createDebugTree(idcStruct, pcstream);
482 }
483 }
484 pcstream.Close();
485}
486
487template <>
489{
490 o2::utils::TreeStreamRedirector pcstream(nameFile, "RECREATE");
491 pcstream.GetFile()->cd();
492 TFile fInp(filename, "READ");
493
494 for (TObject* keyAsObj : *fInp.GetListOfKeys()) {
495 const auto key = dynamic_cast<TKey*>(keyAsObj);
496 LOGP(info, "Key name: {} Type: {}", key->GetName(), key->GetClassName());
497
498 if (std::strcmp(o2::tpc::IDCAverageGroup<IDCAverageGroupCRU>::Class()->GetName(), key->GetClassName()) != 0) {
499 LOGP(info, "skipping object. wrong class.");
500 continue;
501 }
502
504 IDCAverageGroupHelper<IDCAverageGroupCRU> idcStruct(idcavg->mIDCsGrouped, idcavg->mWeightsPad, idcavg->mWeightsRow, idcavg->mIDCsUngrouped, idcavg->mRobustAverage, idcavg->getCRU());
505 for (unsigned int integrationInterval = 0; integrationInterval < idcavg->getNIntegrationIntervals(); ++integrationInterval) {
506 idcStruct.set(0, integrationInterval);
507 createDebugTree(idcStruct, pcstream);
508 }
509 delete idcavg;
510 }
511 pcstream.Close();
512}
513
514template <class Type>
516{
517 const Mapper& mapper = Mapper::instance();
518 unsigned int cru = idcStruct.getCRU();
519 const CRU cruTmp(cru);
520 unsigned int sector = cruTmp.sector();
521 unsigned int region = idcStruct.getRegion();
522 unsigned int integrationInterval = idcStruct.getIntegrationInterval();
523
524 const unsigned long padsPerCRU = Mapper::PADSPERREGION[region];
525 std::vector<unsigned int> vRow(padsPerCRU);
526 std::vector<unsigned int> vPad(padsPerCRU);
527 std::vector<float> vXPos(padsPerCRU);
528 std::vector<float> vYPos(padsPerCRU);
529 std::vector<float> vGlobalXPos(padsPerCRU);
530 std::vector<float> vGlobalYPos(padsPerCRU);
531 std::vector<float> idcsPerIntegrationInterval(padsPerCRU); // idcs for one time bin
532 std::vector<float> groupedidcsPerIntegrationInterval(padsPerCRU); // idcs for one time bin
533 std::vector<float> invPadArea(padsPerCRU);
534
535 for (unsigned int iPad = 0; iPad < padsPerCRU; ++iPad) {
536 const GlobalPadNumber globalNum = Mapper::GLOBALPADOFFSET[region] + iPad;
537 const auto& padPosLocal = mapper.padPos(globalNum);
538 vRow[iPad] = padPosLocal.getRow();
539 vPad[iPad] = padPosLocal.getPad();
540 vXPos[iPad] = mapper.getPadCentre(padPosLocal).X();
541 vYPos[iPad] = mapper.getPadCentre(padPosLocal).Y();
542 invPadArea[iPad] = Mapper::INVPADAREA[region];
543 const GlobalPosition2D globalPos = mapper.LocalToGlobal(LocalPosition2D(vXPos[iPad], vYPos[iPad]), cruTmp.sector());
544 vGlobalXPos[iPad] = globalPos.X();
545 vGlobalYPos[iPad] = globalPos.Y();
546 idcsPerIntegrationInterval[iPad] = idcStruct.getUngroupedIDCVal(iPad);
547 groupedidcsPerIntegrationInterval[iPad] = idcStruct.getGroupedIDCValGlobal(vRow[iPad], vPad[iPad]);
548 }
549
550 pcstream << "tree"
551 << "cru=" << cru
552 << "sector=" << sector
553 << "region=" << region
554 << "integrationInterval=" << integrationInterval
555 << "IDCUngrouped.=" << idcsPerIntegrationInterval
556 << "IDCGrouped.=" << groupedidcsPerIntegrationInterval
557 << "invPadArea.=" << invPadArea
558 << "pad.=" << vPad
559 << "row.=" << vRow
560 << "lx.=" << vXPos
561 << "ly.=" << vYPos
562 << "gx.=" << vGlobalXPos
563 << "gy.=" << vGlobalYPos
564 << "\n";
565}
566
567template <class Type>
568void o2::tpc::IDCAverageGroup<Type>::drawLatex(IDCAverageGroupHelper<IDCAverageGroupDraw>& idcStruct, const GlobalPadNumber padNum, const unsigned int padInRegion, const bool fillPoly, const int colOffs) const
569{
570 // drawing the grouping
572 auto coordinate = coords[padNum];
573
574 const float yPos = (coordinate.yVals[0] + coordinate.yVals[2]) / 2;
575 const float xPos = (coordinate.xVals[0] + coordinate.xVals[2]) / 2;
576 const int nCountDraw = idcStruct.mCountDraw[padInRegion]++;
577 const float offsX = (nCountDraw % 2) * 0.6f * idcStruct.mPadInf.getPadHeight();
578 const float offsY = (nCountDraw / 2) * 0.2f * idcStruct.mPadInf.getPadWidth();
579 const float xPosDraw = xPos - 0.3f * idcStruct.mPadInf.getPadHeight() + offsX;
580 const float yPosDraw = yPos - 0.4f * idcStruct.mPadInf.getPadWidth() + offsY;
581
582 TLatex latex;
583 latex.SetTextFont(63);
584 latex.SetTextSize(1);
585
586 const int col = idcStruct.mCol % idcStruct.mColors.size();
587 const char* groupText = Form("#bf{#color[%d]{%i}}", col + 1, idcStruct.mGroupCounter);
588 latex.DrawLatex(xPosDraw, yPosDraw, groupText);
589 if (fillPoly) {
590 idcStruct.mPoly.Fill(xPos, yPos, idcStruct.mColors[col] + colOffs);
591 }
592}
593
596template void o2::tpc::IDCAverageGroup<o2::tpc::IDCAverageGroupCRU>::loopOverGroups(IDCAverageGroupHelper<o2::tpc::IDCAverageGroupCRU>&, const CalDet<PadFlags>*);
597template void o2::tpc::IDCAverageGroup<o2::tpc::IDCAverageGroupTPC>::loopOverGroups(IDCAverageGroupHelper<o2::tpc::IDCAverageGroupTPC>&, const CalDet<PadFlags>*);
598template void o2::tpc::IDCAverageGroup<o2::tpc::IDCAverageGroupCRU>::loopOverGroups(IDCAverageGroupHelper<o2::tpc::IDCAverageGroupDraw>&, const CalDet<PadFlags>*);
599template void o2::tpc::IDCAverageGroup<o2::tpc::IDCAverageGroupTPC>::loopOverGroups(IDCAverageGroupHelper<o2::tpc::IDCAverageGroupDraw>&, const CalDet<PadFlags>*);
uint16_t rob
int32_t i
float & yMax
base class for averaging and grouping of IDCs
helper class for averaging and grouping of IDCs
class for averaging and grouping of IDCs
helper class for drawing IDCs per region/side
useful math constants
uint32_t col
Definition RawData.h:4
StringRef key
static void createDebugTreeForAllCRUs(const char *nameFile, const char *filename)
void createDebugTree(const char *nameFile)
void dumpToFile(const char *outFileName="IDCAverageGroup.root", const char *outName="IDCAverageGroup") const
bool setFromFile(const char *fileName="IDCAverageGroup.root", const char *name="IDCAverageGroup")
void drawGrouping(const std::string filename="")
void processIDCs(const CalDet< PadFlags > *padStatusFlags=nullptr)
static GlobalPadNumber getGlobalPadNumber(const unsigned int lrow, const unsigned int pad, const unsigned int region)
Definition Mapper.h:64
const PadPos & padPos(GlobalPadNumber padNumber) const
Definition Mapper.h:50
const PadRegionInfo & getPadRegionInfo(const unsigned char region) const
Definition Mapper.h:385
static GlobalPosition3D LocalToGlobal(const LocalPosition3D &pos, const double alpha)
Definition Mapper.h:461
GlobalPosition2D getPadCentre(const PadSecPos &padSec) const
Definition Mapper.h:163
float getRadiusFirstRow() const
GLint GLenum GLint x
Definition glcorearb.h:403
GLsizei const GLubyte GLsizei GLenum const void * coords
Definition glcorearb.h:5468
GLuint const GLchar * name
Definition glcorearb.h:781
GLuint GLuint GLfloat weight
Definition glcorearb.h:5477
GLboolean * data
Definition glcorearb.h:298
return * this
unsigned short GlobalPadNumber
global pad number
Definition Defs.h:112
std::string filename()
double getValue(DPVAL dp)
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, std::string binningStr="")
static std::vector< PadCoordinates > getPadCoordinatesSector()
create a vector of pad corner coordinate for one full sector