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
int32_t lastRow
float & yMax
char error[CURL_ERROR_SIZE]
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
double radius
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
math_utils::Point2D< float > LocalPosition2D
Definition Defs.h:109
unsigned short GlobalPadNumber
global pad number
Definition Defs.h:114
math_utils::Point2D< float > GlobalPosition2D
Definition Defs.h:108
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