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