Project
Loading...
Searching...
No Matches
TPCFastSpaceChargeCorrection.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
16
18#include "GPUCommonLogger.h"
19
20#include <iostream>
21#include <string>
22#include <cmath>
23#include <sstream>
24#include "Spline2DHelper.h"
25
26using namespace o2::gpu;
27
29
31 : FlatObject(),
32 mConstructionScenarios(nullptr),
33 mNumberOfScenarios(0),
34 mScenarioPtr(nullptr),
35 mTimeStamp(-1),
36 mCorrectionData{nullptr, nullptr, nullptr},
37 mSectorDataSizeBytes{0, 0, 0}
38{
39 // Default Constructor: creates an empty uninitialized object
40}
41
47
48void TPCFastSpaceChargeCorrection::releaseConstructionMemory()
49{
50 // release temporary arrays
51 delete[] mConstructionScenarios;
52 mConstructionScenarios = nullptr;
53}
54
56{
57 releaseConstructionMemory();
58 mConstructionScenarios = nullptr;
59 mNumberOfScenarios = 0;
60 mScenarioPtr = nullptr;
61 mTimeStamp = -1;
62 for (int32_t is = 0; is < 3; is++) {
63 mCorrectionData[is] = nullptr;
64 mSectorDataSizeBytes[is] = 0;
65 }
67}
68
69void TPCFastSpaceChargeCorrection::relocateBufferPointers(const char* oldBuffer, char* newBuffer)
70{
71 mScenarioPtr = FlatObject::relocatePointer(oldBuffer, newBuffer, mScenarioPtr);
72
73 for (int32_t i = 0; i < mNumberOfScenarios; i++) {
74 SplineType& sp = mScenarioPtr[i];
75 char* newSplineBuf = relocatePointer(oldBuffer, newBuffer, sp.getFlatBufferPtr());
76 sp.setActualBufferAddress(newSplineBuf);
77 }
78 mCorrectionData[0] = relocatePointer(oldBuffer, newBuffer, mCorrectionData[0]);
79 mCorrectionData[1] = relocatePointer(oldBuffer, newBuffer, mCorrectionData[1]);
80 mCorrectionData[2] = relocatePointer(oldBuffer, newBuffer, mCorrectionData[2]);
81}
82
84{
88
89 const char* oldFlatBufferPtr = obj.mFlatBufferPtr;
90
91 FlatObject::cloneFromObject(obj, newFlatBufferPtr);
92
93 releaseConstructionMemory();
94
95 mNumberOfScenarios = obj.mNumberOfScenarios;
96
97 mGeo = obj.mGeo;
98
99 mTimeStamp = obj.mTimeStamp;
100
101 mSectorDataSizeBytes[0] = obj.mSectorDataSizeBytes[0];
102 mSectorDataSizeBytes[1] = obj.mSectorDataSizeBytes[1];
103 mSectorDataSizeBytes[2] = obj.mSectorDataSizeBytes[2];
104
105 // variable-size data
106 mScenarioPtr = obj.mScenarioPtr;
107 mCorrectionData[0] = obj.mCorrectionData[0];
108 mCorrectionData[1] = obj.mCorrectionData[1];
109 mCorrectionData[2] = obj.mCorrectionData[2];
110
111 mClassVersion = obj.mClassVersion;
112
113 for (int32_t i = 0; i < TPCFastTransformGeo::getMaxNumberOfRows(); i++) {
114 mRowInfos[i] = obj.mRowInfos[i];
115 }
116
117 relocateBufferPointers(oldFlatBufferPtr, mFlatBufferPtr);
118}
119
121{
123
124 const char* oldFlatBufferPtr = mFlatBufferPtr;
125 FlatObject::moveBufferTo(newFlatBufferPtr);
126 relocateBufferPointers(oldFlatBufferPtr, mFlatBufferPtr);
127}
128
130{
132
133 if (mClassVersion == 4) {
134 FlatObject::setActualBufferAddress(actualFlatBufferPtr);
135
136 size_t scSize = sizeof(SplineType) * mNumberOfScenarios;
137
138 mScenarioPtr = reinterpret_cast<SplineType*>(mFlatBufferPtr);
139
140 size_t scBufferOffset = alignSize(scSize, SplineType::getBufferAlignmentBytes());
141 size_t scBufferSize = 0;
142
143 for (int32_t i = 0; i < mNumberOfScenarios; i++) {
144 SplineType& sp = mScenarioPtr[i];
145 sp.setActualBufferAddress(mFlatBufferPtr + scBufferOffset + scBufferSize);
146 scBufferSize = alignSize(scBufferSize + sp.getFlatBufferSize(), sp.getBufferAlignmentBytes());
147 }
148 size_t bufferSize = scBufferOffset + scBufferSize;
149 for (int32_t is = 0; is < 3; is++) {
150 bufferSize = alignSize(bufferSize, SplineType::getParameterAlignmentBytes());
151 mCorrectionData[is] = reinterpret_cast<char*>(mFlatBufferPtr + bufferSize);
152 bufferSize += mSectorDataSizeBytes[is] * mGeo.getNumberOfSectors();
153 }
154 return;
155 }
156
157 if (mClassVersion != 3) {
158 LOG(fatal) << "TPCFastSpaceChargeCorrection::setActualBufferAddress() called with class version " << mClassVersion << ". This is not supported.";
159 return;
160 }
161
162 // Class version 3
163
164 struct RowInfoVersion3 {
165 int32_t splineScenarioID{0};
166 size_t dataOffsetBytes[3]{0};
167 };
168
169 struct RowActiveAreaVersion3 {
170 float maxDriftLengthCheb[5]{0.f};
171 float vMax{0.f};
172 float cuMin{0.f};
173 float cuMax{0.f};
174 float cvMax{0.f};
175 };
176
177 struct SectorRowInfoVersion3 {
178 float gridV0{0.f};
179 float gridCorrU0{0.f};
180 float gridCorrV0{0.f};
181 float scaleCorrUtoGrid{0.f};
182 float scaleCorrVtoGrid{0.f};
183 RowActiveAreaVersion3 activeArea;
184 };
185
186 FlatObject::setActualBufferAddress(actualFlatBufferPtr);
187
188 size_t oldRowsOffset = 0;
189 size_t oldRowsSize = sizeof(RowInfoVersion3) * mGeo.getNumberOfRows();
190
191 size_t oldSectorRowsOffset = oldRowsOffset + oldRowsSize;
192 size_t oldSectorRowsSize = sizeof(SectorRowInfoVersion3) * mGeo.getNumberOfRows() * mGeo.getNumberOfSectors();
193
194 size_t oldScenariosOffset = alignSize(oldSectorRowsOffset + oldSectorRowsSize, SplineType::getClassAlignmentBytes());
195 size_t scenariosSize = sizeof(SplineType) * mNumberOfScenarios;
196
197 SplineType* oldScenarioPtr = reinterpret_cast<SplineType*>(mFlatBufferPtr + oldScenariosOffset);
198
199 { // copy old-format sector and row parameters from the buffer to the arrays
200
201 auto* oldRowInfos = reinterpret_cast<RowInfoVersion3*>(mFlatBufferPtr + oldRowsOffset);
202 auto* oldSectorRowInfos = reinterpret_cast<SectorRowInfoVersion3*>(mFlatBufferPtr + oldSectorRowsOffset);
203
204 int32_t iSector = 0;
205
206 for (int32_t iRow = 0; iRow < mGeo.getNumberOfRows(); iRow++) {
207 RowInfoVersion3& oldRowInfo = oldRowInfos[iRow];
208 SectorRowInfoVersion3& oldSectorRowInfo = oldSectorRowInfos[mGeo.getNumberOfRows() * iSector + iRow];
209
210 // the spline buffer is not yet initialised, don't try to access knot positions etc
211 const auto& spline = oldScenarioPtr[oldRowInfo.splineScenarioID];
212
213 RowInfo& newRowInfo = getRowInfo(iRow);
214
215 newRowInfo.splineScenarioID = oldRowInfo.splineScenarioID;
216 for (int32_t is = 0; is < 3; is++) {
217 newRowInfo.dataOffsetBytes[is] = oldRowInfo.dataOffsetBytes[is];
218 }
219
220 { // grid for the measured coordinates
221 float y0 = mGeo.getRowInfo(iRow).yMin;
222 float yScale = spline.getGridX1().getUmax() / mGeo.getRowInfo(iRow).getYwidth();
223 float zOut = mGeo.getTPCzLength() - oldSectorRowInfo.gridV0;
224 float z0 = -3.;
225 float zScale = spline.getGridX2().getUmax() / (zOut - z0);
226 newRowInfo.gridMeasured.set(y0, yScale, z0, zScale, zOut, mGeo.getTPCzLength());
227 }
228 newRowInfo.gridReal = newRowInfo.gridMeasured;
229 }
230 }
231
232 // move spline scenarios to the new place in the buffer
233
234 mScenarioPtr = reinterpret_cast<SplineType*>(mFlatBufferPtr);
235 memmove((void*)mScenarioPtr, (const void*)oldScenarioPtr, scenariosSize);
236
237 size_t oldScenariosBufferOffset = alignSize(oldScenariosOffset + scenariosSize, SplineType::getBufferAlignmentBytes());
238 size_t scenariosBufferOffset = alignSize(scenariosSize, SplineType::getBufferAlignmentBytes());
239
240 size_t oldScenariosBufferSize = 0;
241 size_t scenariosBufferSize = 0;
242 for (int32_t i = 0; i < mNumberOfScenarios; i++) {
243 SplineType& sp = mScenarioPtr[i];
244 char* oldAddress = mFlatBufferPtr + oldScenariosBufferOffset + oldScenariosBufferSize;
245 char* newAddress = mFlatBufferPtr + scenariosBufferOffset + scenariosBufferSize;
246 memmove(newAddress, oldAddress, sp.getFlatBufferSize());
247 sp.setActualBufferAddress(newAddress);
248 oldScenariosBufferSize = alignSize(oldScenariosBufferSize + sp.getFlatBufferSize(), sp.getBufferAlignmentBytes());
249 scenariosBufferSize = alignSize(scenariosBufferSize + sp.getFlatBufferSize(), sp.getBufferAlignmentBytes());
250 }
251
252 size_t oldBufferSize = oldScenariosBufferOffset + oldScenariosBufferSize;
253 size_t bufferSize = scenariosBufferOffset + scenariosBufferSize;
254
255 // move spline data to the new place in the buffer
256
257 for (int32_t is = 0; is < 3; is++) {
258 size_t oldCorrectionDataOffset = alignSize(oldBufferSize, SplineType::getParameterAlignmentBytes());
259 size_t correctionDataOffset = alignSize(bufferSize, SplineType::getParameterAlignmentBytes());
260 mCorrectionData[is] = reinterpret_cast<char*>(mFlatBufferPtr + correctionDataOffset);
261 memmove(mCorrectionData[is], mFlatBufferPtr + oldCorrectionDataOffset, mSectorDataSizeBytes[is] * mGeo.getNumberOfSectors());
262 oldBufferSize = oldCorrectionDataOffset + mSectorDataSizeBytes[is] * mGeo.getNumberOfSectors();
263 bufferSize = correctionDataOffset + mSectorDataSizeBytes[is] * mGeo.getNumberOfSectors();
264 }
265
266 mFlatBufferSize = bufferSize;
267
268 // now convert the spline data to the new format
269 for (int32_t iSector = 0; iSector < mGeo.getNumberOfSectors(); iSector++) {
270 bool isAside = (iSector < mGeo.getNumberOfSectorsA());
271 for (int32_t iRow = 0; iRow < mGeo.getNumberOfRows(); iRow++) {
272
273 RowInfo& rowInfo = getRowInfo(iRow);
274 const auto& spline = mScenarioPtr[rowInfo.splineScenarioID];
275
276 int nSplineDimensions[3] = {3, 1, 2};
277
278 for (int iSpline = 0; iSpline < 3; iSpline++) {
279 int nDim = nSplineDimensions[iSpline];
280 int nKnotParameters = 4 * nDim;
281 auto* data = getCorrectionData(iSector, iRow, iSpline);
282
283 // lambda to swap parameters at two knots
284 auto swapKnots = [&](int i1, int j1, int i2, int j2) {
285 auto k1 = spline.getKnotIndex(i1, j1);
286 auto k2 = spline.getKnotIndex(i2, j2);
287 for (int ipar = 0; ipar < nKnotParameters; ipar++) {
288 std::swap(data[nKnotParameters * k1 + ipar], data[nKnotParameters * k2 + ipar]);
289 }
290 };
291
292 // reorder knots for the A side U == old U, V == - old V
293 if (isAside) {
294 for (int32_t i = 0; i < spline.getGridX1().getNumberOfKnots(); i++) {
295 for (int32_t j = 0; j < spline.getGridX2().getNumberOfKnots() / 2; j++) {
296 swapKnots(i, j, i, spline.getGridX2().getNumberOfKnots() - 1 - j);
297 }
298 }
299 } else { // reorder knots for the C side U == - old U, V == - old V
300 for (int32_t i = 0; i < spline.getGridX1().getNumberOfKnots() / 2; i++) {
301 for (int32_t j = 0; j < spline.getGridX2().getNumberOfKnots(); j++) {
302 swapKnots(i, j, spline.getGridX1().getNumberOfKnots() - 1 - i, spline.getGridX2().getNumberOfKnots() - 1 - j);
303 }
304 }
305 }
306
307 // correct sign of the parameters due to the coordinate swaps
308
309 for (int32_t iKnot = 0; iKnot < spline.getNumberOfKnots(); iKnot++) {
310 // new grid directions for all corrections
311 for (int iDim = 0; iDim < nDim; iDim++) {
312 if (isAside) {
313 data[nKnotParameters * iKnot + nDim * 1 + iDim] *= -1; // invert Z derivatives on A side
314 data[nKnotParameters * iKnot + nDim * 3 + iDim] *= -1; // invert cross derivatives on A side
315 } else {
316 data[nKnotParameters * iKnot + nDim * 1 + iDim] *= -1; // invert Z derivatives on C side
317 data[nKnotParameters * iKnot + nDim * 2 + iDim] *= -1; // invert Y derivatives on C side
318 }
319 }
320 // new correction directions
321 if (iSpline == 0) { // dX,dU,dV -> dX,dY,dZ
322 if (isAside) {
323 data[nKnotParameters * iKnot + nDim * 0 + 2] *= -1; // invert correction in Z
324 data[nKnotParameters * iKnot + nDim * 1 + 2] *= -1; // invert correction in Z Z-derivative
325 data[nKnotParameters * iKnot + nDim * 2 + 2] *= -1; // invert correction in Z Y-derivative
326 data[nKnotParameters * iKnot + nDim * 3 + 2] *= -1; // invert correction in Z cross derivative
327 } else {
328 data[nKnotParameters * iKnot + nDim * 0 + 1] *= -1; // invert correction in Y
329 data[nKnotParameters * iKnot + nDim * 1 + 1] *= -1; // invert correction in Y Z-derivative
330 data[nKnotParameters * iKnot + nDim * 2 + 1] *= -1; // invert correction in Y Y-derivative
331 data[nKnotParameters * iKnot + nDim * 3 + 1] *= -1; // invert correction in Y cross derivative
332 }
333 } else if (iSpline == 2) { // dU,dV at real U,V -> dY,dZ at real Y,Z
334 if (isAside) {
335 data[nKnotParameters * iKnot + nDim * 0 + 1] *= -1; // invert correction in Z
336 data[nKnotParameters * iKnot + nDim * 1 + 1] *= -1; // invert correction in Z Z-derivative
337 data[nKnotParameters * iKnot + nDim * 2 + 1] *= -1; // invert correction in Z Y-derivative
338 data[nKnotParameters * iKnot + nDim * 3 + 1] *= -1; // invert correction in Z cross derivative
339 } else {
340 data[nKnotParameters * iKnot + nDim * 0 + 0] *= -1; // invert correction in Y
341 data[nKnotParameters * iKnot + nDim * 1 + 0] *= -1; // invert correction in Y Z-derivative
342 data[nKnotParameters * iKnot + nDim * 2 + 0] *= -1; // invert correction in Y Y-derivative
343 data[nKnotParameters * iKnot + nDim * 3 + 0] *= -1; // invert correction in Y cross derivative
344 }
345 }
346 }
347
348 } // iSpline
349 } // iRow
350 } // iSector
351
352 // set the class version to the current one
353 mClassVersion = 4;
354}
355
357{
364
365 char* oldBuffer = mFlatBufferPtr;
366 char* newBuffer = futureFlatBufferPtr;
367
368 for (int32_t i = 0; i < mNumberOfScenarios; i++) {
369 SplineType& sp = mScenarioPtr[i];
370 char* newSplineBuf = relocatePointer(oldBuffer, newBuffer, sp.getFlatBufferPtr());
371 sp.setFutureBufferAddress(newSplineBuf);
372 }
373 mScenarioPtr = relocatePointer(oldBuffer, newBuffer, mScenarioPtr);
374 mCorrectionData[0] = relocatePointer(oldBuffer, newBuffer, mCorrectionData[0]);
375 mCorrectionData[1] = relocatePointer(oldBuffer, newBuffer, mCorrectionData[1]);
376 mCorrectionData[2] = relocatePointer(oldBuffer, newBuffer, mCorrectionData[2]);
377
378 FlatObject::setFutureBufferAddress(futureFlatBufferPtr);
379}
380
382{
383 LOG(info) << " TPC Correction: ";
384 mGeo.print();
385 LOG(info) << " mNumberOfScenarios = " << mNumberOfScenarios;
386 LOG(info) << " mTimeStamp = " << mTimeStamp;
387 LOG(info) << " mSectorDataSizeBytes = " << mSectorDataSizeBytes[0] << " " << mSectorDataSizeBytes[1] << " " << mSectorDataSizeBytes[2];
388
389 if (mScenarioPtr) {
390 for (int32_t i = 0; i < mNumberOfScenarios; i++) {
391 LOG(info) << " SplineScenario " << i << ": ";
392 mScenarioPtr[i].print();
393 }
394 }
395 if (mScenarioPtr) {
396 LOG(info) << " Spline Data: ";
397 for (int32_t is = 0; is < mGeo.getNumberOfSectors(); is++) {
398 for (int32_t ir = 0; ir < mGeo.getNumberOfRows(); ir++) {
399 LOG(info) << "sector " << is << " row " << ir << ": ";
400 const SplineType& spline = getSplineForRow(ir);
401 const float* d = getCorrectionData(is, ir);
402 int32_t k = 0;
403 for (int32_t i = 0; i < spline.getGridX1().getNumberOfKnots(); i++) {
404 for (int32_t j = 0; j < spline.getGridX2().getNumberOfKnots(); j++, k++) {
405 LOG(info) << d[k] << " ";
406 }
407 LOG(info) << "";
408 }
409 }
410 // LOG(info) << "inverse correction: sector " << sector
411 // << " dx " << maxDsector[0] << " du " << maxDsector[1] << " dv " << maxDsector[2] ;
412 }
413 }
414}
415
416void TPCFastSpaceChargeCorrection::startConstruction(const TPCFastTransformGeo& geo, int32_t numberOfSplineScenarios)
417{
419
421
422 assert((geo.isConstructed()) && (numberOfSplineScenarios > 0));
423
424 mGeo = geo;
425 mNumberOfScenarios = numberOfSplineScenarios;
426
427 releaseConstructionMemory();
428
429 mConstructionScenarios = new SplineType[mNumberOfScenarios];
430
431 assert(mConstructionScenarios != nullptr);
432
433 for (int32_t i = 0; i < mGeo.getNumberOfRows(); i++) {
434 auto& row = mRowInfos[i];
436 row.gridReal = {};
437 row.gridMeasured = {};
438 row.dataOffsetBytes[0] = 0;
439 row.dataOffsetBytes[1] = 0;
440 row.dataOffsetBytes[2] = 0;
441 }
442
443 for (int32_t i = 0; i < mNumberOfScenarios; i++) {
444 mConstructionScenarios[i].destroy();
445 }
446
447 mTimeStamp = -1;
448
449 mScenarioPtr = nullptr;
450 for (int32_t s = 0; s < 3; s++) {
451 mCorrectionData[s] = nullptr;
452 mSectorDataSizeBytes[s] = 0;
453 }
454 mClassVersion = 4;
455}
456
457void TPCFastSpaceChargeCorrection::setRowScenarioID(int32_t iRow, int32_t iScenario)
458{
461 assert(iRow >= 0 && iRow < mGeo.getNumberOfRows() && iScenario >= 0 && iScenario < mNumberOfScenarios);
462 auto& row = getRowInfo(iRow);
463 row.splineScenarioID = iScenario;
464 for (int32_t s = 0; s < 3; s++) {
465 row.dataOffsetBytes[s] = 0;
466 }
467}
468
469void TPCFastSpaceChargeCorrection::setSplineScenario(int32_t scenarioIndex, const SplineType& spline)
470{
473 assert(scenarioIndex >= 0 && scenarioIndex < mNumberOfScenarios);
474 assert(spline.isConstructed());
475 SplineType& sp = mConstructionScenarios[scenarioIndex];
476 sp.cloneFromObject(spline, nullptr); // clone to internal buffer container
477}
478
480{
482
484
485 for (int32_t j = 0; j < mGeo.getNumberOfRows(); j++) {
486 [[maybe_unused]] RowInfo& row = getRowInfo(j);
487 assert(row.splineScenarioID >= 0);
488 assert(row.splineScenarioID < mNumberOfScenarios);
489 }
490
491 for (int32_t i = 0; i < mNumberOfScenarios; i++) {
492 assert(mConstructionScenarios[i].isConstructed());
493 }
494
495 // organize memory for the flat buffer and caculate its size
496
497 size_t scOffset = 0;
498 size_t scSize = sizeof(SplineType) * mNumberOfScenarios;
499
500 size_t scBufferOffsets[mNumberOfScenarios];
501
502 scBufferOffsets[0] = alignSize(scOffset + scSize, SplineType::getBufferAlignmentBytes());
503 size_t scBufferSize = 0;
504 for (int32_t i = 0; i < mNumberOfScenarios; i++) {
505 SplineType& sp = mConstructionScenarios[i];
506 scBufferOffsets[i] = scBufferOffsets[0] + scBufferSize;
507 scBufferSize = alignSize(scBufferSize + sp.getFlatBufferSize(), sp.getBufferAlignmentBytes());
508 }
509 size_t bufferSize = scBufferOffsets[0] + scBufferSize;
510 size_t correctionDataOffset[3];
511 for (int32_t is = 0; is < 3; is++) {
512 bufferSize = alignSize(bufferSize, SplineType::getParameterAlignmentBytes());
513 correctionDataOffset[is] = bufferSize;
514 mSectorDataSizeBytes[is] = 0;
515 for (int32_t j = 0; j < mGeo.getNumberOfRows(); j++) {
516 RowInfo& row = getRowInfo(j);
517 row.dataOffsetBytes[is] = mSectorDataSizeBytes[is];
518 const SplineType& spline = mConstructionScenarios[row.splineScenarioID];
519 if (is == 0) {
520 const SplineTypeXYZ& splineXYZ = reinterpret_cast<const SplineTypeXYZ&>(spline);
521 mSectorDataSizeBytes[is] += splineXYZ.getSizeOfParameters();
522 } else if (is == 1) {
523 const SplineTypeInvX& splineInvX = reinterpret_cast<const SplineTypeInvX&>(spline);
524 mSectorDataSizeBytes[is] += splineInvX.getSizeOfParameters();
525 } else if (is == 2) {
526 const SplineTypeInvYZ& splineInvYZ = reinterpret_cast<const SplineTypeInvYZ&>(spline);
527 mSectorDataSizeBytes[is] += splineInvYZ.getSizeOfParameters();
528 }
529 mSectorDataSizeBytes[is] = alignSize(mSectorDataSizeBytes[is], SplineType::getParameterAlignmentBytes());
530 }
531 bufferSize += mSectorDataSizeBytes[is] * mGeo.getNumberOfSectors();
532 }
533
535
536 mScenarioPtr = reinterpret_cast<SplineType*>(mFlatBufferPtr + scOffset);
537
538 for (int32_t i = 0; i < mNumberOfScenarios; i++) {
539 SplineType& sp0 = mConstructionScenarios[i];
540 SplineType& sp1 = mScenarioPtr[i];
541 new (&sp1) SplineType(); // first, call a constructor
542 sp1.cloneFromObject(sp0, mFlatBufferPtr + scBufferOffsets[i]);
543 }
544
545 for (int32_t is = 0; is < 3; is++) {
546 mCorrectionData[is] = reinterpret_cast<char*>(mFlatBufferPtr + correctionDataOffset[is]);
547 }
548 releaseConstructionMemory();
549
550 mTimeStamp = -1;
551
552 setNoCorrection();
553}
554
556{
557 // initialise all corrections to 0.
558
559 for (int32_t row = 0; row < mGeo.getNumberOfRows(); row++) {
560 const SplineType& spline = getSplineForRow(row);
561 RowInfo& info = getRowInfo(row);
562 float y0 = mGeo.getRowInfo(row).getYmin();
563 float yScale = spline.getGridX1().getUmax() / mGeo.getRowInfo(row).getYwidth();
564 float z0 = 0.;
565 float zScale = spline.getGridX2().getUmax() / mGeo.getTPCzLength();
566 info.gridMeasured.set(y0, yScale, z0, zScale, mGeo.getTPCzLength(), mGeo.getTPCzLength());
567 info.gridReal = info.gridMeasured;
568 } // row
569
570 for (int32_t sector = 0; sector < mGeo.getNumberOfSectors(); sector++) {
571 for (int32_t row = 0; row < mGeo.getNumberOfRows(); row++) {
572 for (int32_t is = 0; is < 3; is++) {
573 float* data = getCorrectionData(sector, row, is);
574 int32_t nPar = 0;
575 if (is == 0) {
576 nPar = getSplineForRow(row).getNumberOfParameters();
577 } else if (is == 1) {
578 nPar = getSplineInvXforRow(row).getNumberOfParameters();
579 } else if (is == 2) {
580 nPar = getSplineInvYZforRow(row).getNumberOfParameters();
581 }
582 for (int32_t i = 0; i < nPar; i++) {
583 data[i] = 0.f;
584 }
585 }
586 } // row
587 } // sector
588}
589
591{
592 const int32_t nCorrectionScenarios = 1;
593 startConstruction(geo, nCorrectionScenarios);
594 for (int32_t row = 0; row < geo.getNumberOfRows(); row++) {
596 }
597 {
599 spline.recreate(2, 2);
600 setSplineScenario(0, spline);
601 }
603 setNoCorrection();
604}
605
606double TPCFastSpaceChargeCorrection::testInverse(bool prn)
607{
608 if (prn) {
609 LOG(info) << "Test inverse transform ";
610 }
611
612 double tpcR2min = mGeo.getRowInfo(0).x - 1.;
613 tpcR2min = tpcR2min * tpcR2min;
614 double tpcR2max = mGeo.getRowInfo(mGeo.getNumberOfRows() - 1).x;
615 tpcR2max = tpcR2max / cos(2 * M_PI / mGeo.getNumberOfSectorsA() / 2) + 1.;
616 tpcR2max = tpcR2max * tpcR2max;
617
618 struct MaxValue {
619 double V{0.};
620 int Sector{-1};
621 int Row{-1};
622
623 void update(double v, int sector, int row)
624 {
625 if (fabs(v) > fabs(V)) {
626 V = v;
627 Sector = sector;
628 Row = row;
629 }
630 }
631 void update(const MaxValue& other)
632 {
633 update(other.V, other.Sector, other.Row);
634 }
635
636 std::string toString()
637 {
638 std::stringstream ss;
639 ss << V << "(" << Sector << "," << Row << ")";
640 return ss.str();
641 }
642 };
643
644 MaxValue maxDtpc[3];
645 MaxValue maxD;
646
647 for (int32_t sector = 0; sector < mGeo.getNumberOfSectors(); sector++) {
648 if (prn) {
649 LOG(info) << "check inverse transform for sector " << sector;
650 }
651
652 MaxValue maxDsector[3];
653 for (int32_t row = 0; row < mGeo.getNumberOfRows(); row++) {
654 double x = mGeo.getRowInfo(row).x;
655 auto [y0, y1] = mGeo.getRowInfo(row).getYrange();
656 auto [z0, z1] = mGeo.getZrange(sector);
657
658 double stepY = (y1 - y0) / 100.;
659 double stepZ = (z1 - z0) / 100.;
660 MaxValue maxDrow[3];
661 for (double y = y0; y < y1; y += stepY) {
662 for (double z = z0; z < z1; z += stepZ) {
663 float dx, dy, dz;
664 getCorrectionLocal(sector, row, y, z, dx, dy, dz);
665 double realX = x + dx;
666 double realY = y + dy;
667 double realZ = z + dz;
668 if (!isLocalInsideGrid(sector, row, y, z) || !isRealLocalInsideGrid(sector, row, realY, realZ)) {
669 continue;
670 }
671 double r2 = realX * realX + realY * realY;
672 if (realY < y0 || realY > y1 ||
673 realZ < z0 || realZ > z1 ||
674 r2 < tpcR2min || r2 > tpcR2max) {
675 continue;
676 }
677 float dxr = getCorrectionXatRealYZ(sector, row, realY, realZ);
678 float dyr, dzr;
679 getCorrectionYZatRealYZ(sector, row, realY, realZ, dyr, dzr);
680 double d[3] = {dxr - dx, dyr - dy, dzr - dz};
681 for (int32_t i = 0; i < 3; i++) {
682 maxDrow[i].update(d[i], sector, row);
683 }
684
685 if (0 && prn && fabs(d[0]) + fabs(d[1]) + fabs(d[2]) > 0.1) {
686 LOG(info) << dxr - dx << " " << dyr - dy << " " << dzr - dz
687 << " measured xyz " << x << ", " << y << ", " << z
688 << " dx,dy,dz from measured point " << dx << ", " << dy << ", " << dz
689 << " dx,dy,dz from real point " << dxr << ", " << dyr << ", " << dzr;
690 }
691 }
692 }
693 if (0 && prn) {
694 LOG(info) << "sector " << sector << " row " << row
695 << " dx " << maxDrow[0].V << " dy " << maxDrow[1].V << " dz " << maxDrow[2].V;
696 }
697 for (int32_t i = 0; i < 3; i++) {
698 maxDsector[i].update(maxDrow[i]);
699 maxDtpc[i].update(maxDrow[i]);
700 maxD.update(maxDrow[i]);
701 }
702 }
703 if (prn) {
704 LOG(info) << "inverse correction: sector " << sector << ". Max deviations: "
705 << " dx " << maxDsector[0].toString() << " dy " << maxDsector[1].toString() << " dz " << maxDsector[2].toString();
706 }
707 } // sector
708
709 LOG(info) << "Test inverse TPC correction. max deviations: "
710 << " dx " << maxDtpc[0].toString() << " dy " << maxDtpc[1].toString() << " dz " << maxDtpc[2].toString() << " cm";
711
712 return maxD.V;
713}
int32_t i
uint32_t iSector
uint32_t j
Definition RawData.h:0
Definition of Spline2DHelper class.
ClassImp(TPCFastSpaceChargeCorrection)
Definition of TPCFastSpaceChargeCorrection class.
std::string toString(CoderTag tag)
void setFutureBufferAddress(char *futureFlatBufferPtr)
Definition FlatObject.h:569
uint32_t mConstructionMask
mask for constructed object members, first two bytes are used by this class
Definition FlatObject.h:321
int32_t mFlatBufferSize
size of the flat buffer
Definition FlatObject.h:320
void destroy()
_______________ Utilities _______________________________________________
Definition FlatObject.h:361
bool isConstructed() const
Tells if the object is constructed.
Definition FlatObject.h:260
static T * relocatePointer(const char *oldBase, char *newBase, const T *ptr)
Relocates a pointer inside a buffer to the new buffer address.
Definition FlatObject.h:283
void setActualBufferAddress(char *actualFlatBufferPtr)
_____________ Methods for moving the class with its external buffer to another location _____________...
Definition FlatObject.h:559
void startConstruction()
_____________ Construction _________
Definition FlatObject.h:354
void moveBufferTo(char *newBufferPtr)
Definition FlatObject.h:408
void finishConstruction(int32_t flatBufferSize)
Definition FlatObject.h:370
static constexpr size_t alignSize(size_t sizeBytes, size_t alignmentBytes)
_______________ Generic utilities _______________________________________________
Definition FlatObject.h:275
void cloneFromObject(const FlatObject &obj, char *newFlatBufferPtr)
Definition FlatObject.h:385
@ InProgress
construction started: temporary memory is reserved
Definition FlatObject.h:317
Forward declaration — specializations below select ClassDefNV based on FlatBase.
Definition Spline2D.h:104
TPCFastSpaceChargeCorrection()
_____________ Constructors / destructors __________________________
void setSplineScenario(int32_t scenarioIndex, const SplineType &spline)
Sets approximation scenario.
void setRowScenarioID(int32_t iRow, int32_t iScenario)
Initializes a TPC row.
void finishConstruction()
Finishes construction: puts everything to the flat buffer, releases temporary memory.
void setFutureBufferAddress(char *futureFlatBufferPtr)
void constructWithNoCorrection(const TPCFastTransformGeo &geo)
void setActualBufferAddress(char *actualFlatBufferPtr)
Moving the class with its external buffer to another location.
void cloneFromObject(const TPCFastSpaceChargeCorrection &obj, char *newFlatBufferPtr)
Construction interface.
static constexpr int getMaxNumberOfRows()
Gives number of TPC rows.
static constexpr int32_t getNumberOfSectorsA()
Gives number of TPC sectors on the A side.
bool isConstructed() const
Is the object constructed.
void print() const
Print method.
static constexpr int32_t getNumberOfSectors()
_______________ Getters _________________________________
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint GLfloat GLfloat GLfloat GLfloat y1
Definition glcorearb.h:5034
const GLdouble * v
Definition glcorearb.h:832
GLboolean * data
Definition glcorearb.h:298
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLuint GLfloat GLfloat y0
Definition glcorearb.h:5034
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
GPUd() const expr uint32_t MultivariatePolynomialHelper< Dim
float float float float z1
Definition MathUtils.h:77
void set(float y0_, float yScale_, float z0_, float zScale_, float zOut_, float zReadout_)
GridInfo gridReal
grid info for the real coordinates
GridInfo gridMeasured
grid info for the measured coordinates
int32_t splineScenarioID
scenario index (which of Spline2D splines to use)
size_t dataOffsetBytes[3]
offset for the spline data withing a TPC sector
VectorOfTObjectPtrs other
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)
std::vector< int > row