Project
Loading...
Searching...
No Matches
SpaceChargeIO.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
15
21#include "TPCBase/Mapper.h"
22#include "Field/MagneticField.h"
26#include "MathUtils/Utils.h"
27#include "Framework/Logger.h"
28#include "fmt/core.h"
29#include "TFile.h"
30#include "TTree.h"
31#include "TStopwatch.h"
32#include "ROOT/RDataFrame.hxx"
33#include <numeric>
34#include <memory>
35#include <algorithm>
36#include <random>
37#include <vector>
38
39using namespace o2::tpc;
40
41template <typename DataT>
42auto DataContainer3D<DataT>::getDataSlice(const std::vector<DataT>& data, size_t entries, const size_t values_per_entry, ULong64_t entry)
43{
44 const long indStart = entry * values_per_entry;
45 if (entry < (entries - 1)) {
46 return std::pair(indStart, std::vector<float>(data.begin() + indStart, data.begin() + indStart + values_per_entry));
47 } else if (entry == (entries - 1)) {
48 // last entry might have different number of values. just copy the rest...
49 return std::pair(indStart, std::vector<float>(data.begin() + indStart, data.end()));
50 }
51 return std::pair(indStart, std::vector<float>());
52};
53
54template <typename DataT>
55int DataContainer3D<DataT>::writeToFile(std::string_view file, std::string_view option, std::string_view name, const int nthreads) const
56{
57 // max number of floats per Entry
58 const size_t maxvalues = sizeof(float) * 1024 * 1024;
59
60 // total number of values to be stored
61 const size_t nsize = getNDataPoints();
62
63 // calculate number of entries in the tree and restrict if the number of values per threads exceeds max size
64 size_t entries = ((nsize / nthreads) > maxvalues) ? (nsize / maxvalues) : nthreads;
65
66 if (entries > nsize) {
67 entries = nsize;
68 }
69
70 // calculate numbers to store per entry
71 const size_t values_per_entry = nsize / entries;
72
73 // in case of remainder add additonal entry
74 const size_t values_lastEntry = nsize % entries;
75 if (values_lastEntry) {
76 entries += 1;
77 }
78
79 // in case EnableImplicitMT was already called with different number of threads, perform reset
80 if (ROOT::IsImplicitMTEnabled() && (ROOT::GetThreadPoolSize() != nthreads)) {
81 ROOT::DisableImplicitMT();
82 }
83 ROOT::EnableImplicitMT(nthreads);
84
85 // define dataframe which will be stored in the TTree
86 ROOT::RDataFrame dFrame(entries);
87
88 // define function which is used to fill the data frame
89 auto dfStore = dFrame.DefineSlotEntry(name, [&data = std::as_const(mData), entries, values_per_entry](unsigned int, ULong64_t entry) { return DataContainer3D<DataT>::getDataSlice(data, entries, values_per_entry, entry); });
90 dfStore = dfStore.Define("nz", [mZVertices = mZVertices]() { return mZVertices; });
91 dfStore = dfStore.Define("nr", [mRVertices = mRVertices]() { return mRVertices; });
92 dfStore = dfStore.Define("nphi", [mPhiVertices = mPhiVertices]() { return mPhiVertices; });
93
94 // define options of TFile
95 ROOT::RDF::RSnapshotOptions opt;
96 opt.fMode = option;
97 opt.fOverwriteIfExists = true; // overwrite if already exists
98
99 TStopwatch timer;
100 // note: first call has some overhead (~2s)
101 dfStore.Snapshot(name, file, {name.data(), "nz", "nr", "nphi"}, opt);
102 timer.Print("u");
103 return 0;
104}
105
106template <typename DataT>
107bool DataContainer3D<DataT>::initFromFile(std::string_view file, std::string_view name, const int nthreads)
108{
109 // in case EnableImplicitMT was already called with different number of threads, perform reset
110 if (ROOT::IsImplicitMTEnabled() && (ROOT::GetThreadPoolSize() != nthreads)) {
111 ROOT::DisableImplicitMT();
112 }
113 ROOT::EnableImplicitMT(nthreads);
114
115 // compare first the meta data (is the number of vertices the same)
116 // define data frame from imput file
117 ROOT::RDataFrame dFrame(name, file);
118
119 // compare vertices
120 auto comp = [mZVertices = mZVertices, mRVertices = mRVertices, mPhiVertices = mPhiVertices](const unsigned short nz, const unsigned short nr, const unsigned short nphi) {
121 if ((nz == mZVertices) && (nr == mRVertices) && (nphi == mPhiVertices)) {
122 return false;
123 }
124 return true;
125 };
126
127 auto count = dFrame.Filter(comp, {"nz", "nr", "nphi"}).Count();
128 if (*count != 0) {
129 LOGP(error, "Data from input file has different number of vertices! Found {} same vertices", *count);
130 return false;
131 }
132
133 // define lambda function which is used to copy the data
134 auto readData = [&mData = mData](const std::pair<long, std::vector<float>>& data) {
135 std::copy(data.second.begin(), data.second.end(), mData.begin() + data.first);
136 };
137
138 LOGP(info, "Reading {} from file {}", name, file);
139
140 // fill data from RDataFrame
141 TStopwatch timer;
142 dFrame.Foreach(readData, {name.data()});
143 timer.Print("u");
144 return true;
145}
146
147template <typename DataT>
148void DataContainer3D<DataT>::dumpSlice(std::string_view treename, std::string_view fileIn, std::string_view fileOut, std::string_view option, std::pair<unsigned short, unsigned short> rangeiR, std::pair<unsigned short, unsigned short> rangeiZ, std::pair<unsigned short, unsigned short> rangeiPhi, const int nthreads)
150 if (ROOT::IsImplicitMTEnabled() && (ROOT::GetThreadPoolSize() != nthreads)) {
151 ROOT::DisableImplicitMT();
152 }
153 ROOT::EnableImplicitMT(nthreads);
154 ROOT::RDataFrame dFrame(treename, fileIn);
155
156 auto df = dFrame.Define("slice", [rangeiZ, rangeiR, rangeiPhi](const std::pair<long, std::vector<float>>& values, unsigned short nz, unsigned short nr, unsigned short nphi) {
157 std::vector<size_t> ir;
158 std::vector<size_t> iphi;
159 std::vector<size_t> iz;
160 std::vector<float> r;
161 std::vector<float> phi;
162 std::vector<float> z;
163 std::vector<float> vals;
164 std::vector<size_t> globalIdx;
165 std::vector<LocalPosition3D> lPos;
166 const auto nvalues = values.second.size();
167 ir.reserve(nvalues);
168 iphi.reserve(nvalues);
169 iz.reserve(nvalues);
170 r.reserve(nvalues);
171 phi.reserve(nvalues);
172 z.reserve(nvalues);
173 vals.reserve(nvalues);
174 lPos.reserve(nvalues);
175 globalIdx.reserve(nvalues);
176 for (size_t i = 0; i < nvalues; ++i) {
177 const size_t idx = values.first + i;
178 const auto iZTmp = o2::tpc::DataContainer3D<float>::getIndexZ(idx, nz, nr, nphi);
179 if ((rangeiZ.first < rangeiZ.second) && ((iZTmp < rangeiZ.first) || (iZTmp > rangeiZ.second))) {
180 continue;
181 }
182
183 const auto iRTmp = o2::tpc::DataContainer3D<float>::getIndexR(idx, nz, nr, nphi);
184 if ((rangeiR.first < rangeiR.second) && ((iRTmp < rangeiR.first) || (iRTmp > rangeiR.second))) {
185 continue;
186 }
187
188 const auto iPhiTmp = o2::tpc::DataContainer3D<float>::getIndexPhi(idx, nz, nr, nphi);
189 if ((rangeiPhi.first < rangeiPhi.second) && ((iPhiTmp < rangeiPhi.first) || (iPhiTmp > rangeiPhi.second))) {
190 continue;
191 }
192
196
197 const float x = rTmp * std::cos(phiTmp);
198 const float y = rTmp * std::sin(phiTmp);
199 const LocalPosition3D pos(x, y, zTmp);
200 unsigned char secNum = std::floor(phiTmp / SECPHIWIDTH);
201 Sector sector(secNum + (pos.Z() < 0) * SECTORSPERSIDE);
202 LocalPosition3D lPosTmp = Mapper::GlobalToLocal(pos, sector);
203
204 lPos.emplace_back(lPosTmp);
205 ir.emplace_back(iRTmp);
206 iphi.emplace_back(iPhiTmp);
207 iz.emplace_back(iZTmp);
208 r.emplace_back(rTmp);
209 phi.emplace_back(phiTmp);
210 z.emplace_back(zTmp);
211 vals.emplace_back(values.second[i]);
212 globalIdx.emplace_back(idx);
213 }
214 return std::make_tuple(vals, iz, ir, iphi, z, r, phi, lPos, globalIdx);
215 },
216 {treename.data(), "nz", "nr", "nphi"});
217
218 // define options of TFile
219 ROOT::RDF::RSnapshotOptions opt;
220 opt.fMode = option;
221 df.Snapshot(treename, fileOut, {"slice"}, opt);
222}
223
224template <typename DataT>
225void DataContainer3D<DataT>::dumpInterpolation(std::string_view treename, std::string_view fileIn, std::string_view fileOut, std::string_view option, std::pair<float, float> rangeR, std::pair<float, float> rangeZ, std::pair<float, float> rangePhi, const int nR, const int nZ, const int nPhi, const int nthreads)
226{
227 if (ROOT::IsImplicitMTEnabled() && (ROOT::GetThreadPoolSize() != nthreads)) {
228 ROOT::DisableImplicitMT();
229 }
230 ROOT::EnableImplicitMT(nthreads);
231 ROOT::RDataFrame dFrame(nPhi);
232
233 // get vertices for input TTree which is needed to define the grid for interpolation
234 unsigned short nr, nz, nphi;
235 if (!getVertices(treename, fileIn, nr, nz, nphi)) {
236 return;
237 }
238
239 // load data from input TTree
241 data.setGrid(nz, nr, nphi, true);
242 data.initFromFile(fileIn, treename, nthreads);
243
244 // define grid for interpolation
245 using GridProp = GridProperties<DataT>;
246 const RegularGrid3D<DataT> mGrid3D(GridProp::ZMIN, GridProp::RMIN, GridProp::PHIMIN, GridProp::getGridSpacingZ(nz), GridProp::getGridSpacingR(nr), o2::tpc::GridProperties<float>::getGridSpacingPhi(nphi) * (MGParameters::normalizeGridToNSector / double(SECTORSPERSIDE)), ParamSpaceCharge{nr, nz, nphi});
247
248 auto interpolate = [&mGrid3D = std::as_const(mGrid3D), &data = std::as_const(data), rangeR, rangeZ, rangePhi, nR, nZ, nPhi](unsigned int, ULong64_t iPhi) {
249 std::vector<size_t> ir;
250 std::vector<size_t> iphi;
251 std::vector<size_t> iz;
252 std::vector<float> r;
253 std::vector<float> phi;
254 std::vector<float> z;
255 std::vector<float> vals;
256 std::vector<size_t> globalIdx;
257 std::vector<LocalPosition3D> lPos;
258 const auto nvalues = nR * nZ;
259 ir.reserve(nvalues);
260 iphi.reserve(nvalues);
261 iz.reserve(nvalues);
262 r.reserve(nvalues);
263 phi.reserve(nvalues);
264 z.reserve(nvalues);
265 vals.reserve(nvalues);
266 lPos.reserve(nvalues);
267 globalIdx.reserve(nvalues);
268
269 const float rSpacing = (rangeR.second - rangeR.first) / (nR - 1);
270 const float zSpacing = (rangeZ.second - rangeZ.first) / (nZ - 1);
271 const float phiSpacing = (rangePhi.second - rangePhi.first) / (nPhi - 1);
272 const DataT phiPos = rangePhi.first + iPhi * phiSpacing;
273 // loop over grid and interpolate values
274 for (int iR = 0; iR < nR; ++iR) {
275 const DataT rPos = rangeR.first + iR * rSpacing;
276 for (int iZ = 0; iZ < nZ; ++iZ) {
277 const size_t idx = (iZ + nZ * (iR + iPhi * nR)); // unique index to Build index with other friend TTrees
278 const DataT zPos = rangeZ.first + iZ * zSpacing;
279 ir.emplace_back(iR);
280 iphi.emplace_back(iPhi);
281 iz.emplace_back(iZ);
282 r.emplace_back(rPos);
283 phi.emplace_back(phiPos);
284 z.emplace_back(zPos);
285 vals.emplace_back(data.interpolate(zPos, rPos, phiPos, mGrid3D)); // interpolated values
286 globalIdx.emplace_back(idx);
287 const float x = rPos * std::cos(phiPos);
288 const float y = rPos * std::sin(phiPos);
289 const LocalPosition3D pos(x, y, zPos);
290 unsigned char secNum = std::floor(phiPos / SECPHIWIDTH); // TODO CHECK THIS
291 Sector sector(secNum + (pos.Z() < 0) * SECTORSPERSIDE);
292 LocalPosition3D lPosTmp = Mapper::GlobalToLocal(pos, sector);
293 lPos.emplace_back(lPosTmp);
294 }
295 }
296 return std::make_tuple(vals, iz, ir, iphi, z, r, phi, lPos, globalIdx);
297 };
298
299 // define RDataFrame entry
300 auto dfStore = dFrame.DefineSlotEntry(treename, interpolate);
301
302 // define options of TFile
303 ROOT::RDF::RSnapshotOptions opt;
304 opt.fMode = option;
305
306 TStopwatch timer;
307 // note: first call has some overhead (~2s)
308 dfStore.Snapshot(treename, fileOut, {treename.data()}, opt);
309 timer.Print("u");
310}
311
312template <typename DataT>
313void SpaceCharge<DataT>::dumpToTree(const char* outFileName, const Side side, const int nZPoints, const int nRPoints, const int nPhiPoints, const bool randomize) const
314{
315 const DataT phiSpacing = GridProp::getGridSpacingPhi(nPhiPoints) * (MGParameters::normalizeGridToNSector / double(SECTORSPERSIDE));
316 const DataT rSpacing = GridProp::getGridSpacingR(nRPoints);
317 const DataT zSpacing = side == Side::A ? GridProp::getGridSpacingZ(nZPoints) : -GridProp::getGridSpacingZ(nZPoints);
318
319 std::uniform_real_distribution<DataT> uniR(-rSpacing / 2, rSpacing / 2);
320 std::uniform_real_distribution<DataT> uniPhi(-phiSpacing / 2, phiSpacing / 2);
321
322 std::vector<std::vector<float>> phiPosOut(nPhiPoints);
323 std::vector<std::vector<float>> rPosOut(nPhiPoints);
324 std::vector<std::vector<float>> zPosOut(nPhiPoints);
325 std::vector<std::vector<int>> iPhiOut(nPhiPoints);
326 std::vector<std::vector<int>> iROut(nPhiPoints);
327 std::vector<std::vector<int>> iZOut(nPhiPoints);
328 std::vector<std::vector<float>> densityOut(nPhiPoints);
329 std::vector<std::vector<float>> potentialOut(nPhiPoints);
330 std::vector<std::vector<float>> eZOut(nPhiPoints);
331 std::vector<std::vector<float>> eROut(nPhiPoints);
332 std::vector<std::vector<float>> ePhiOut(nPhiPoints);
333 std::vector<std::vector<float>> distZOut(nPhiPoints);
334 std::vector<std::vector<float>> distROut(nPhiPoints);
335 std::vector<std::vector<float>> distRPhiOut(nPhiPoints);
336 std::vector<std::vector<float>> corrZOut(nPhiPoints);
337 std::vector<std::vector<float>> corrROut(nPhiPoints);
338 std::vector<std::vector<float>> corrRPhiOut(nPhiPoints);
339 std::vector<std::vector<float>> lcorrZOut(nPhiPoints);
340 std::vector<std::vector<float>> lcorrROut(nPhiPoints);
341 std::vector<std::vector<float>> lcorrRPhiOut(nPhiPoints);
342 std::vector<std::vector<float>> ldistZOut(nPhiPoints);
343 std::vector<std::vector<float>> ldistROut(nPhiPoints);
344 std::vector<std::vector<float>> ldistRPhiOut(nPhiPoints);
345 std::vector<std::vector<float>> xOut(nPhiPoints);
346 std::vector<std::vector<float>> yOut(nPhiPoints);
347 std::vector<std::vector<float>> bROut(nPhiPoints);
348 std::vector<std::vector<float>> bZOut(nPhiPoints);
349 std::vector<std::vector<float>> bPhiOut(nPhiPoints);
350 std::vector<std::vector<LocalPosition3D>> lPosOut(nPhiPoints);
351 std::vector<std::vector<int>> sectorOut(nPhiPoints);
352 std::vector<std::vector<size_t>> globalIdxOut(nPhiPoints);
353 std::vector<std::vector<bool>> isOnPadPlane(nPhiPoints);
354
355#pragma omp parallel for num_threads(sNThreads)
356 for (int iPhi = 0; iPhi < nPhiPoints; ++iPhi) {
357 const int nPoints = nZPoints * nRPoints;
358 phiPosOut[iPhi].reserve(nPoints);
359 rPosOut[iPhi].reserve(nPoints);
360 zPosOut[iPhi].reserve(nPoints);
361 iPhiOut[iPhi].reserve(nPoints);
362 iROut[iPhi].reserve(nPoints);
363 iZOut[iPhi].reserve(nPoints);
364 densityOut[iPhi].reserve(nPoints);
365 potentialOut[iPhi].reserve(nPoints);
366 eZOut[iPhi].reserve(nPoints);
367 eROut[iPhi].reserve(nPoints);
368 ePhiOut[iPhi].reserve(nPoints);
369 distZOut[iPhi].reserve(nPoints);
370 distROut[iPhi].reserve(nPoints);
371 distRPhiOut[iPhi].reserve(nPoints);
372 corrZOut[iPhi].reserve(nPoints);
373 corrROut[iPhi].reserve(nPoints);
374 corrRPhiOut[iPhi].reserve(nPoints);
375 lcorrZOut[iPhi].reserve(nPoints);
376 lcorrROut[iPhi].reserve(nPoints);
377 lcorrRPhiOut[iPhi].reserve(nPoints);
378 ldistZOut[iPhi].reserve(nPoints);
379 ldistROut[iPhi].reserve(nPoints);
380 ldistRPhiOut[iPhi].reserve(nPoints);
381 xOut[iPhi].reserve(nPoints);
382 yOut[iPhi].reserve(nPoints);
383 bROut[iPhi].reserve(nPoints);
384 bZOut[iPhi].reserve(nPoints);
385 bPhiOut[iPhi].reserve(nPoints);
386 lPosOut[iPhi].reserve(nPoints);
387 sectorOut[iPhi].reserve(nPoints);
388 globalIdxOut[iPhi].reserve(nPoints);
389 isOnPadPlane[iPhi].reserve(nPoints);
390
391 std::mt19937 rng(std::random_device{}());
392 DataT phiPos = iPhi * phiSpacing;
393 for (int iR = 0; iR < nRPoints; ++iR) {
394 DataT rPos = getRMin(side) + iR * rSpacing;
395 for (int iZ = 0; iZ < nZPoints; ++iZ) {
396 DataT zPos = getZMin(side) + iZ * zSpacing;
397 if (randomize) {
398 phiPos += uniPhi(rng);
399 o2::math_utils::detail::bringTo02PiGen<DataT>(phiPos);
400 rPos += uniR(rng);
401 }
402
403 DataT density = getDensityCyl(zPos, rPos, phiPos, side);
404 DataT potential = getPotentialCyl(zPos, rPos, phiPos, side);
405
406 DataT distZ{};
407 DataT distR{};
408 DataT distRPhi{};
409 getDistortionsCyl(zPos, rPos, phiPos, side, distZ, distR, distRPhi);
410
411 DataT ldistZ{};
412 DataT ldistR{};
413 DataT ldistRPhi{};
414 getLocalDistortionsCyl(zPos, rPos, phiPos, side, ldistZ, ldistR, ldistRPhi);
415
416 // get average distortions
417 DataT corrZ{};
418 DataT corrR{};
419 DataT corrRPhi{};
420 // getCorrectionsCyl(zPos, rPos, phiPos, side, corrZ, corrR, corrRPhi);
421
422 const DataT zDistorted = zPos + distZ;
423 const DataT radiusDistorted = rPos + distR;
424 const DataT phiDistorted = regulatePhi(phiPos + distRPhi / rPos, side);
425 getCorrectionsCyl(zDistorted, radiusDistorted, phiDistorted, side, corrZ, corrR, corrRPhi);
426 corrRPhi *= rPos / radiusDistorted;
427
428 DataT lcorrZ{};
429 DataT lcorrR{};
430 DataT lcorrRPhi{};
431 getLocalCorrectionsCyl(zPos, rPos, phiPos, side, lcorrZ, lcorrR, lcorrRPhi);
432
433 // get average distortions
434 DataT eZ{};
435 DataT eR{};
436 DataT ePhi{};
437 getElectricFieldsCyl(zPos, rPos, phiPos, side, eZ, eR, ePhi);
438
439 // global coordinates
440 const float x = getXFromPolar(rPos, phiPos);
441 const float y = getYFromPolar(rPos, phiPos);
442
443 // b field
444 const float bR = mBField.evalFieldR(zPos, rPos, phiPos);
445 const float bZ = mBField.evalFieldZ(zPos, rPos, phiPos);
446 const float bPhi = mBField.evalFieldPhi(zPos, rPos, phiPos);
447
448 const LocalPosition3D pos(x, y, zPos);
449 unsigned char secNum = std::floor(phiPos / SECPHIWIDTH);
450 Sector sector(secNum + (pos.Z() < 0) * SECTORSPERSIDE);
452
453 phiPosOut[iPhi].emplace_back(phiPos);
454 rPosOut[iPhi].emplace_back(rPos);
455 zPosOut[iPhi].emplace_back(zPos);
456 iPhiOut[iPhi].emplace_back(iPhi);
457 iROut[iPhi].emplace_back(iR);
458 iZOut[iPhi].emplace_back(iZ);
459 if (mDensity[side].getNDataPoints()) {
460 densityOut[iPhi].emplace_back(density);
461 }
462 if (mPotential[side].getNDataPoints()) {
463 potentialOut[iPhi].emplace_back(potential);
464 }
465 if (mElectricFieldEr[side].getNDataPoints()) {
466 eZOut[iPhi].emplace_back(eZ);
467 eROut[iPhi].emplace_back(eR);
468 ePhiOut[iPhi].emplace_back(ePhi);
469 }
470 if (mGlobalDistdR[side].getNDataPoints()) {
471 distZOut[iPhi].emplace_back(distZ);
472 distROut[iPhi].emplace_back(distR);
473 distRPhiOut[iPhi].emplace_back(distRPhi);
474 }
475 if (mGlobalCorrdR[side].getNDataPoints()) {
476 corrZOut[iPhi].emplace_back(corrZ);
477 corrROut[iPhi].emplace_back(corrR);
478 corrRPhiOut[iPhi].emplace_back(corrRPhi);
479 }
480 if (mLocalCorrdR[side].getNDataPoints()) {
481 lcorrZOut[iPhi].emplace_back(lcorrZ);
482 lcorrROut[iPhi].emplace_back(lcorrR);
483 lcorrRPhiOut[iPhi].emplace_back(lcorrRPhi);
484 }
485 if (mLocalDistdR[side].getNDataPoints()) {
486 ldistZOut[iPhi].emplace_back(ldistZ);
487 ldistROut[iPhi].emplace_back(ldistR);
488 ldistRPhiOut[iPhi].emplace_back(ldistRPhi);
489 }
490 xOut[iPhi].emplace_back(x);
491 yOut[iPhi].emplace_back(y);
492 bROut[iPhi].emplace_back(bR);
493 bZOut[iPhi].emplace_back(bZ);
494 bPhiOut[iPhi].emplace_back(bPhi);
495 lPosOut[iPhi].emplace_back(lPos);
496 sectorOut[iPhi].emplace_back(sector);
497 const size_t idx = (iZ + nZPoints * (iR + iPhi * nRPoints));
498 globalIdxOut[iPhi].emplace_back(idx);
499
500 const float xDist = getXFromPolar(radiusDistorted, phiDistorted);
501 const float yDist = getYFromPolar(radiusDistorted, phiDistorted);
502 GlobalPosition3D posTmp(xDist, yDist, zPos);
504 isOnPadPlane[iPhi].emplace_back(digiPadPos.isValid());
505 }
506 }
507 }
508
509 if (ROOT::IsImplicitMTEnabled() && (ROOT::GetThreadPoolSize() != sNThreads)) {
510 ROOT::DisableImplicitMT();
511 }
512 ROOT::EnableImplicitMT(sNThreads);
513 ROOT::RDataFrame dFrame(nPhiPoints);
514
515 TStopwatch timer;
516 auto dfStore = dFrame.DefineSlotEntry("x", [&xOut = xOut](unsigned int, ULong64_t entry) { return xOut[entry]; });
517 dfStore = dfStore.DefineSlotEntry("y", [&yOut = yOut](unsigned int, ULong64_t entry) { return yOut[entry]; });
518 dfStore = dfStore.DefineSlotEntry("phi", [&phiPosOut = phiPosOut](unsigned int, ULong64_t entry) { return phiPosOut[entry]; });
519 dfStore = dfStore.DefineSlotEntry("r", [&rPosOut = rPosOut](unsigned int, ULong64_t entry) { return rPosOut[entry]; });
520 dfStore = dfStore.DefineSlotEntry("z", [&zPosOut = zPosOut](unsigned int, ULong64_t entry) { return zPosOut[entry]; });
521 dfStore = dfStore.DefineSlotEntry("iPhi", [&iPhiOut = iPhiOut](unsigned int, ULong64_t entry) { return iPhiOut[entry]; });
522 dfStore = dfStore.DefineSlotEntry("iR", [&iROut = iROut](unsigned int, ULong64_t entry) { return iROut[entry]; });
523 dfStore = dfStore.DefineSlotEntry("iZ", [&iZOut = iZOut](unsigned int, ULong64_t entry) { return iZOut[entry]; });
524 dfStore = dfStore.DefineSlotEntry("lPos", [&lPosOut = lPosOut](unsigned int, ULong64_t entry) { return lPosOut[entry]; });
525 dfStore = dfStore.DefineSlotEntry("sector", [&sectorOut = sectorOut](unsigned int, ULong64_t entry) { return sectorOut[entry]; });
526 dfStore = dfStore.DefineSlotEntry("scdensity", [&densityOut = densityOut](unsigned int, ULong64_t entry) { return densityOut[entry]; });
527 dfStore = dfStore.DefineSlotEntry("potential", [&potentialOut = potentialOut](unsigned int, ULong64_t entry) { return potentialOut[entry]; });
528 dfStore = dfStore.DefineSlotEntry("eZ", [&eZOut = eZOut](unsigned int, ULong64_t entry) { return eZOut[entry]; });
529 dfStore = dfStore.DefineSlotEntry("eR", [&eROut = eROut](unsigned int, ULong64_t entry) { return eROut[entry]; });
530 dfStore = dfStore.DefineSlotEntry("ePhi", [&ePhiOut = ePhiOut](unsigned int, ULong64_t entry) { return ePhiOut[entry]; });
531 dfStore = dfStore.DefineSlotEntry("distZ", [&distZOut = distZOut](unsigned int, ULong64_t entry) { return distZOut[entry]; });
532 dfStore = dfStore.DefineSlotEntry("distR", [&distROut = distROut](unsigned int, ULong64_t entry) { return distROut[entry]; });
533 dfStore = dfStore.DefineSlotEntry("distRPhi", [&distRPhiOut = distRPhiOut](unsigned int, ULong64_t entry) { return distRPhiOut[entry]; });
534 dfStore = dfStore.DefineSlotEntry("corrZ", [&corrZOut = corrZOut](unsigned int, ULong64_t entry) { return corrZOut[entry]; });
535 dfStore = dfStore.DefineSlotEntry("corrR", [&corrROut = corrROut](unsigned int, ULong64_t entry) { return corrROut[entry]; });
536 dfStore = dfStore.DefineSlotEntry("corrRPhi", [&corrRPhiOut = corrRPhiOut](unsigned int, ULong64_t entry) { return corrRPhiOut[entry]; });
537 dfStore = dfStore.DefineSlotEntry("lcorrZ", [&lcorrZOut = lcorrZOut](unsigned int, ULong64_t entry) { return lcorrZOut[entry]; });
538 dfStore = dfStore.DefineSlotEntry("lcorrR", [&lcorrROut = lcorrROut](unsigned int, ULong64_t entry) { return lcorrROut[entry]; });
539 dfStore = dfStore.DefineSlotEntry("lcorrRPhi", [&lcorrRPhiOut = lcorrRPhiOut](unsigned int, ULong64_t entry) { return lcorrRPhiOut[entry]; });
540 dfStore = dfStore.DefineSlotEntry("ldistZ", [&ldistZOut = ldistZOut](unsigned int, ULong64_t entry) { return ldistZOut[entry]; });
541 dfStore = dfStore.DefineSlotEntry("ldistR", [&ldistROut = ldistROut](unsigned int, ULong64_t entry) { return ldistROut[entry]; });
542 dfStore = dfStore.DefineSlotEntry("ldistRPhi", [&ldistRPhiOut = ldistRPhiOut](unsigned int, ULong64_t entry) { return ldistRPhiOut[entry]; });
543 dfStore = dfStore.DefineSlotEntry("bR", [&bROut = bROut](unsigned int, ULong64_t entry) { return bROut[entry]; });
544 dfStore = dfStore.DefineSlotEntry("bZ", [&bZOut = bZOut](unsigned int, ULong64_t entry) { return bZOut[entry]; });
545 dfStore = dfStore.DefineSlotEntry("bPhi", [&bPhiOut = bPhiOut](unsigned int, ULong64_t entry) { return bPhiOut[entry]; });
546 dfStore = dfStore.DefineSlotEntry("globalIndex", [&globalIdxOut = globalIdxOut](unsigned int, ULong64_t entry) { return globalIdxOut[entry]; });
547 dfStore = dfStore.DefineSlotEntry("isOnPadPlane", [&isOnPadPlane = isOnPadPlane](unsigned int, ULong64_t entry) { return isOnPadPlane[entry]; });
548 dfStore.Snapshot("tree", outFileName);
549 timer.Print("u");
550}
551
552template <typename DataT>
553void SpaceCharge<DataT>::dumpToTree(const char* outFileName, const Sector& sector, const int nZPoints) const
554{
555 const Side side = sector.side();
556 const DataT zSpacing = (side == Side::A) ? GridProp::getGridSpacingZ(nZPoints) : -GridProp::getGridSpacingZ(nZPoints);
557 const Mapper& mapper = Mapper::instance();
558
559 const int nPads = Mapper::getPadsInSector();
560 std::vector<std::vector<float>> phiPosOut(nZPoints);
561 std::vector<std::vector<float>> rPosOut(nZPoints);
562 std::vector<std::vector<float>> zPosOut(nZPoints);
563 std::vector<std::vector<int>> rowOut(nZPoints);
564 std::vector<std::vector<float>> lxOut(nZPoints);
565 std::vector<std::vector<float>> lyOut(nZPoints);
566 std::vector<std::vector<float>> xOut(nZPoints);
567 std::vector<std::vector<float>> yOut(nZPoints);
568 std::vector<std::vector<float>> corrZOut(nZPoints);
569 std::vector<std::vector<float>> corrROut(nZPoints);
570 std::vector<std::vector<float>> corrRPhiOut(nZPoints);
571 std::vector<std::vector<float>> erOut(nZPoints);
572 std::vector<std::vector<float>> ezOut(nZPoints);
573 std::vector<std::vector<float>> ephiOut(nZPoints);
574 std::vector<std::vector<float>> potentialOut(nZPoints);
575 std::vector<std::vector<int>> izOut(nZPoints);
576 std::vector<std::vector<size_t>> globalIdxOut(nZPoints);
577
578#pragma omp parallel for num_threads(sNThreads)
579 for (int iZ = 0; iZ < nZPoints; ++iZ) {
580 phiPosOut[iZ].reserve(nPads);
581 rPosOut[iZ].reserve(nPads);
582 zPosOut[iZ].reserve(nPads);
583 corrZOut[iZ].reserve(nPads);
584 corrROut[iZ].reserve(nPads);
585 corrRPhiOut[iZ].reserve(nPads);
586 rowOut[iZ].reserve(nPads);
587 lxOut[iZ].reserve(nPads);
588 lyOut[iZ].reserve(nPads);
589 xOut[iZ].reserve(nPads);
590 yOut[iZ].reserve(nPads);
591 erOut[iZ].reserve(nPads);
592 ezOut[iZ].reserve(nPads);
593 ephiOut[iZ].reserve(nPads);
594 izOut[iZ].reserve(nPads);
595 potentialOut[iZ].reserve(nPads);
596 globalIdxOut[iZ].reserve(nPads);
597
598 DataT zPos = getZMin(side) + iZ * zSpacing;
599 for (unsigned int region = 0; region < Mapper::NREGIONS; ++region) {
600 for (unsigned int irow = 0; irow < Mapper::ROWSPERREGION[region]; ++irow) {
601 for (unsigned int ipad = 0; ipad < Mapper::PADSPERROW[region][irow]; ++ipad) {
602 GlobalPadNumber globalpad = Mapper::getGlobalPadNumber(irow, ipad, region);
603 const PadCentre& padcentre = mapper.padCentre(globalpad);
604 auto lx = padcentre.X();
605 auto ly = padcentre.Y();
606 // local to global
607 auto globalPos = Mapper::LocalToGlobal(padcentre, sector);
608 auto x = globalPos.X();
609 auto y = globalPos.Y();
610
611 auto r = getRadiusFromCartesian(x, y);
612 auto phi = getPhiFromCartesian(x, y);
613 DataT corrZ{};
614 DataT corrR{};
615 DataT corrRPhi{};
616 getCorrectionsCyl(zPos, r, phi, side, corrZ, corrR, corrRPhi);
617
618 DataT eZ{};
619 DataT eR{};
620 DataT ePhi{};
621 getElectricFieldsCyl(zPos, r, phi, side, eZ, eR, ePhi);
622
623 potentialOut[iZ].emplace_back(getPotentialCyl(zPos, r, phi, side));
624 erOut[iZ].emplace_back(eR);
625 ezOut[iZ].emplace_back(eZ);
626 ephiOut[iZ].emplace_back(ePhi);
627 phiPosOut[iZ].emplace_back(phi);
628 rPosOut[iZ].emplace_back(r);
629 zPosOut[iZ].emplace_back(zPos);
630 corrZOut[iZ].emplace_back(corrZ);
631 corrROut[iZ].emplace_back(corrR);
632 corrRPhiOut[iZ].emplace_back(corrRPhi);
633 rowOut[iZ].emplace_back(irow + Mapper::ROWOFFSET[region]);
634 lxOut[iZ].emplace_back(lx);
635 lyOut[iZ].emplace_back(ly);
636 xOut[iZ].emplace_back(x);
637 yOut[iZ].emplace_back(y);
638 izOut[iZ].emplace_back(iZ);
639 const size_t idx = globalpad + Mapper::getPadsInSector() * iZ;
640 globalIdxOut[iZ].emplace_back(idx);
641 }
642 }
643 }
645
646 if (ROOT::IsImplicitMTEnabled() && (ROOT::GetThreadPoolSize() != sNThreads)) {
647 ROOT::DisableImplicitMT();
649 ROOT::EnableImplicitMT(sNThreads);
650 ROOT::RDataFrame dFrame(nZPoints);
651
652 TStopwatch timer;
653 auto dfStore = dFrame.DefineSlotEntry("phi", [&phiPosOut = phiPosOut](unsigned int, ULong64_t entry) { return phiPosOut[entry]; });
654 dfStore = dfStore.DefineSlotEntry("r", [&rPosOut = rPosOut](unsigned int, ULong64_t entry) { return rPosOut[entry]; });
655 dfStore = dfStore.DefineSlotEntry("z", [&zPosOut = zPosOut](unsigned int, ULong64_t entry) { return zPosOut[entry]; });
656 dfStore = dfStore.DefineSlotEntry("iz", [&izOut = izOut](unsigned int, ULong64_t entry) { return izOut[entry]; });
657 dfStore = dfStore.DefineSlotEntry("corrZ", [&corrZOut = corrZOut](unsigned int, ULong64_t entry) { return corrZOut[entry]; });
658 dfStore = dfStore.DefineSlotEntry("corrR", [&corrROut = corrROut](unsigned int, ULong64_t entry) { return corrROut[entry]; });
659 dfStore = dfStore.DefineSlotEntry("corrRPhi", [&corrRPhiOut = corrRPhiOut](unsigned int, ULong64_t entry) { return corrRPhiOut[entry]; });
660 dfStore = dfStore.DefineSlotEntry("row", [&rowOut = rowOut](unsigned int, ULong64_t entry) { return rowOut[entry]; });
661 dfStore = dfStore.DefineSlotEntry("lx", [&lxOut = lxOut](unsigned int, ULong64_t entry) { return lxOut[entry]; });
662 dfStore = dfStore.DefineSlotEntry("ly", [&lyOut = lyOut](unsigned int, ULong64_t entry) { return lyOut[entry]; });
663 dfStore = dfStore.DefineSlotEntry("x", [&xOut = xOut](unsigned int, ULong64_t entry) { return xOut[entry]; });
664 dfStore = dfStore.DefineSlotEntry("y", [&yOut = yOut](unsigned int, ULong64_t entry) { return yOut[entry]; });
665 dfStore = dfStore.DefineSlotEntry("er", [&erOut = erOut](unsigned int, ULong64_t entry) { return erOut[entry]; });
666 dfStore = dfStore.DefineSlotEntry("ez", [&ezOut = ezOut](unsigned int, ULong64_t entry) { return ezOut[entry]; });
667 dfStore = dfStore.DefineSlotEntry("ephi", [&ephiOut = ephiOut](unsigned int, ULong64_t entry) { return ephiOut[entry]; });
668 dfStore = dfStore.DefineSlotEntry("potential", [&potentialOut = potentialOut](unsigned int, ULong64_t entry) { return potentialOut[entry]; });
669 dfStore = dfStore.DefineSlotEntry("globalIndex", [&globalIdxOut = globalIdxOut](unsigned int, ULong64_t entry) { return globalIdxOut[entry]; });
670 dfStore.Snapshot("tree", outFileName);
671 timer.Print("u");
672}
673
674template <typename DataT>
675int SpaceCharge<DataT>::dumpElectricFields(std::string_view file, const Side side, std::string_view option) const
676{
677 if (!mElectricFieldEr[side].getNDataPoints()) {
678 LOGP(info, "============== E-Fields are not set! returning ==============");
679 return 0;
680 }
681 const std::string sideName = getSideName(side);
682 const int er = mElectricFieldEr[side].writeToFile(file, option, fmt::format("fieldEr_side{}", sideName), sNThreads);
683 const int ez = mElectricFieldEz[side].writeToFile(file, "UPDATE", fmt::format("fieldEz_side{}", sideName), sNThreads);
684 const int ephi = mElectricFieldEphi[side].writeToFile(file, "UPDATE", fmt::format("fieldEphi_side{}", sideName), sNThreads);
685 dumpMetaData(file, "UPDATE", false);
686 return er + ez + ephi;
687}
688
689template <typename DataT>
691{
692 const std::string sideName = getSideName(side);
693 std::string_view treeEr{fmt::format("fieldEr_side{}", sideName)};
694 if (!checkGridFromFile(file, treeEr)) {
695 return;
696 }
697 initContainer(mElectricFieldEr[side], true);
698 initContainer(mElectricFieldEz[side], true);
699 initContainer(mElectricFieldEphi[side], true);
700 mElectricFieldEr[side].initFromFile(file, treeEr, sNThreads);
701 mElectricFieldEz[side].initFromFile(file, fmt::format("fieldEz_side{}", sideName), sNThreads);
702 mElectricFieldEphi[side].initFromFile(file, fmt::format("fieldEphi_side{}", sideName), sNThreads);
703 readMetaData(file);
704}
705
706template <typename DataT>
707int SpaceCharge<DataT>::dumpGlobalDistortions(std::string_view file, const Side side, std::string_view option) const
708{
709 if (!mGlobalDistdR[side].getNDataPoints()) {
710 LOGP(info, "============== global distortions are not set! returning ==============");
711 return 0;
712 }
713 const std::string sideName = getSideName(side);
714 const int er = mGlobalDistdR[side].writeToFile(file, option, fmt::format("distR_side{}", sideName), sNThreads);
715 const int ez = mGlobalDistdZ[side].writeToFile(file, "UPDATE", fmt::format("distZ_side{}", sideName), sNThreads);
716 const int ephi = mGlobalDistdRPhi[side].writeToFile(file, "UPDATE", fmt::format("distRphi_side{}", sideName), sNThreads);
717 dumpMetaData(file, "UPDATE", false);
718 return er + ez + ephi;
719}
720
721template <typename DataT>
723{
724 const std::string sideName = getSideName(side);
725 std::string_view tree{fmt::format("distR_side{}", sideName)};
726 if (!checkGridFromFile(file, tree)) {
727 return;
728 }
729 initContainer(mGlobalDistdR[side], true);
730 initContainer(mGlobalDistdZ[side], true);
731 initContainer(mGlobalDistdRPhi[side], true);
732 mGlobalDistdR[side].initFromFile(file, tree, sNThreads);
733 mGlobalDistdZ[side].initFromFile(file, fmt::format("distZ_side{}", sideName), sNThreads);
734 mGlobalDistdRPhi[side].initFromFile(file, fmt::format("distRphi_side{}", sideName), sNThreads);
735 readMetaData(file);
736}
737
738template <typename DataT>
739int SpaceCharge<DataT>::dumpGlobalCorrections(std::string_view file, const Side side, std::string_view option) const
740{
741 if (!mGlobalCorrdR[side].getNDataPoints()) {
742 LOGP(info, "============== global corrections are not set! returning ==============");
743 return 0;
744 }
745 const std::string sideName = getSideName(side);
746 const int er = mGlobalCorrdR[side].writeToFile(file, option, fmt::format("corrR_side{}", sideName), sNThreads);
747 const int ez = mGlobalCorrdZ[side].writeToFile(file, "UPDATE", fmt::format("corrZ_side{}", sideName), sNThreads);
748 const int ephi = mGlobalCorrdRPhi[side].writeToFile(file, "UPDATE", fmt::format("corrRPhi_side{}", sideName), sNThreads);
749 dumpMetaData(file, "UPDATE", false);
750 return er + ez + ephi;
751}
752
753template <typename DataT>
755{
756 const std::string sideName = getSideName(side);
757 const std::string_view treename{fmt::format("corrR_side{}", getSideName(side))};
758 if (!checkGridFromFile(file, treename)) {
759 return;
760 }
761
762 initContainer(mGlobalCorrdR[side], true);
763 initContainer(mGlobalCorrdZ[side], true);
764 initContainer(mGlobalCorrdRPhi[side], true);
765 mGlobalCorrdR[side].initFromFile(file, treename, sNThreads);
766 mGlobalCorrdZ[side].initFromFile(file, fmt::format("corrZ_side{}", sideName), sNThreads);
767 mGlobalCorrdRPhi[side].initFromFile(file, fmt::format("corrRPhi_side{}", sideName), sNThreads);
768 readMetaData(file);
769}
770
771template <typename DataT>
772int SpaceCharge<DataT>::dumpLocalCorrections(std::string_view file, const Side side, std::string_view option) const
773{
774 if (!mLocalCorrdR[side].getNDataPoints()) {
775 LOGP(info, "============== local corrections are not set! returning ==============");
776 return 0;
777 }
778 const std::string sideName = getSideName(side);
779 const int lCorrdR = mLocalCorrdR[side].writeToFile(file, option, fmt::format("lcorrR_side{}", sideName), sNThreads);
780 const int lCorrdZ = mLocalCorrdZ[side].writeToFile(file, "UPDATE", fmt::format("lcorrZ_side{}", sideName), sNThreads);
781 const int lCorrdRPhi = mLocalCorrdRPhi[side].writeToFile(file, "UPDATE", fmt::format("lcorrRPhi_side{}", sideName), sNThreads);
782 dumpMetaData(file, "UPDATE", false);
783 return lCorrdR + lCorrdZ + lCorrdRPhi;
784}
785
786template <typename DataT>
788{
789 const std::string sideName = getSideName(side);
790 const std::string_view treename{fmt::format("lcorrR_side{}", getSideName(side))};
791 if (!checkGridFromFile(file, treename)) {
792 return;
793 }
794 initContainer(mLocalCorrdR[side], true);
795 initContainer(mLocalCorrdZ[side], true);
796 initContainer(mLocalCorrdRPhi[side], true);
797 const bool lCorrdR = mLocalCorrdR[side].initFromFile(file, treename, sNThreads);
798 const bool lCorrdZ = mLocalCorrdZ[side].initFromFile(file, fmt::format("lcorrZ_side{}", sideName), sNThreads);
799 const bool lCorrdRPhi = mLocalCorrdRPhi[side].initFromFile(file, fmt::format("lcorrRPhi_side{}", sideName), sNThreads);
800 readMetaData(file);
801}
802
803template <typename DataT>
804int SpaceCharge<DataT>::dumpLocalDistortions(std::string_view file, const Side side, std::string_view option) const
805{
806 if (!mLocalDistdR[side].getNDataPoints()) {
807 LOGP(info, "============== local distortions are not set! returning ==============");
808 return 0;
809 }
810 const std::string sideName = getSideName(side);
811 const int lDistdR = mLocalDistdR[side].writeToFile(file, option, fmt::format("ldistR_side{}", sideName), sNThreads);
812 const int lDistdZ = mLocalDistdZ[side].writeToFile(file, "UPDATE", fmt::format("ldistZ_side{}", sideName), sNThreads);
813 const int lDistdRPhi = mLocalDistdRPhi[side].writeToFile(file, "UPDATE", fmt::format("ldistRPhi_side{}", sideName), sNThreads);
814 dumpMetaData(file, "UPDATE", false);
815 return lDistdR + lDistdZ + lDistdRPhi;
816}
817
818template <typename DataT>
819int SpaceCharge<DataT>::dumpLocalDistCorrVectors(std::string_view file, const Side side, std::string_view option) const
820{
821 if (!mLocalVecDistdR[side].getNDataPoints()) {
822 LOGP(info, "============== local distortion vectors are not set! returning ==============");
823 return 0;
824 }
825 const std::string sideName = getSideName(side);
826 const int lVecDistdR = mLocalVecDistdR[side].writeToFile(file, option, fmt::format("lvecdistR_side{}", sideName), sNThreads);
827 const int lVecDistdZ = mLocalVecDistdZ[side].writeToFile(file, "UPDATE", fmt::format("lvecdistZ_side{}", sideName), sNThreads);
828 const int lVecDistdRPhi = mLocalVecDistdRPhi[side].writeToFile(file, "UPDATE", fmt::format("lvecdistRPhi_side{}", sideName), sNThreads);
829 dumpMetaData(file, "UPDATE", false);
830 return lVecDistdR + lVecDistdZ + lVecDistdRPhi;
831}
832
833template <typename DataT>
835{
836 const std::string sideName = getSideName(side);
837 const std::string_view treename{fmt::format("ldistR_side{}", getSideName(side))};
838 if (!checkGridFromFile(file, treename)) {
839 return;
840 }
841 initContainer(mLocalDistdR[side], true);
842 initContainer(mLocalDistdZ[side], true);
843 initContainer(mLocalDistdRPhi[side], true);
844 const bool lDistdR = mLocalDistdR[side].initFromFile(file, treename, sNThreads);
845 const bool lDistdZ = mLocalDistdZ[side].initFromFile(file, fmt::format("ldistZ_side{}", sideName), sNThreads);
846 const bool lDistdRPhi = mLocalDistdRPhi[side].initFromFile(file, fmt::format("ldistRPhi_side{}", sideName), sNThreads);
847 readMetaData(file);
848}
849
850template <typename DataT>
852{
853 const std::string sideName = getSideName(side);
854 const std::string_view treename{fmt::format("lvecdistR_side{}", getSideName(side))};
855 if (!checkGridFromFile(file, treename)) {
856 return;
857 }
858 initContainer(mLocalVecDistdR[side], true);
859 initContainer(mLocalVecDistdZ[side], true);
860 initContainer(mLocalVecDistdRPhi[side], true);
861 const bool lVecDistdR = mLocalVecDistdR[side].initFromFile(file, treename, sNThreads);
862 const bool lVecDistdZ = mLocalVecDistdZ[side].initFromFile(file, fmt::format("lvecdistZ_side{}", sideName), sNThreads);
863 const bool lVecDistdRPhi = mLocalVecDistdRPhi[side].initFromFile(file, fmt::format("lvecdistRPhi_side{}", sideName), sNThreads);
864 readMetaData(file);
865}
866
867template <typename DataT>
868int SpaceCharge<DataT>::dumpPotential(std::string_view file, const Side side, std::string_view option) const
869{
870 if (!mPotential[side].getNDataPoints()) {
871 LOGP(info, "============== potential not set! returning ==============");
872 return 0;
873 }
874 int status = mPotential[side].writeToFile(file, option, fmt::format("potential_side{}", getSideName(side)), sNThreads);
875 dumpMetaData(file, "UPDATE", false);
876 return status;
877}
878
879template <typename DataT>
880void SpaceCharge<DataT>::setPotentialFromFile(std::string_view file, const Side side)
881{
882 const std::string_view treename{fmt::format("potential_side{}", getSideName(side))};
883 if (!checkGridFromFile(file, treename)) {
884 return;
885 }
886 initContainer(mPotential[side], true);
887 mPotential[side].initFromFile(file, treename, sNThreads);
888 readMetaData(file);
889}
890
891template <typename DataT>
892int SpaceCharge<DataT>::dumpDensity(std::string_view file, const Side side, std::string_view option) const
893{
894 if (!mDensity[side].getNDataPoints()) {
895 LOGP(info, "============== space charge density are not set! returning ==============");
896 return 0;
897 }
898 int status = mDensity[side].writeToFile(file, option, fmt::format("density_side{}", getSideName(side)), sNThreads);
899 dumpMetaData(file, "UPDATE", false);
900 return status;
901}
902
903template <typename DataT>
904void SpaceCharge<DataT>::setDensityFromFile(std::string_view file, const Side side)
905{
906 const std::string_view treename{fmt::format("density_side{}", getSideName(side))};
907 if (!checkGridFromFile(file, treename)) {
908 return;
909 }
910 initContainer(mDensity[side], true);
911 mDensity[side].initFromFile(file, treename, sNThreads);
912 readMetaData(file);
913}
914
915template <typename DataT>
916void SpaceCharge<DataT>::dumpToFile(std::string_view file, const Side side, std::string_view option) const
917{
918 if (option == "RECREATE") {
919 // delete the file
920 gSystem->Unlink(file.data());
921 }
922 dumpElectricFields(file, side, "UPDATE");
923 dumpPotential(file, side, "UPDATE");
924 dumpDensity(file, side, "UPDATE");
925 dumpGlobalDistortions(file, side, "UPDATE");
926 dumpGlobalCorrections(file, side, "UPDATE");
927 dumpLocalCorrections(file, side, "UPDATE");
928 dumpLocalDistortions(file, side, "UPDATE");
929 dumpLocalDistCorrVectors(file, side, "UPDATE");
930}
931
932template <typename DataT>
933void SpaceCharge<DataT>::dumpToFile(std::string_view file) const
934{
935 dumpToFile(file, Side::A, "RECREATE");
936 dumpToFile(file, Side::C, "UPDATE");
937}
938
939template <typename DataT>
940void SpaceCharge<DataT>::dumpMetaData(std::string_view file, std::string_view option, const bool overwriteExisting) const
941{
942 TFile f(file.data(), option.data());
943 if (!overwriteExisting && f.GetListOfKeys()->Contains("meta")) {
944 return;
945 }
946 f.Close();
947
948 // create meta objects
949 std::vector<float> params{static_cast<float>(mC0), static_cast<float>(mC1), static_cast<float>(mC2)};
950 auto helperA = mGrid3D[Side::A].getHelper();
951 auto helperC = mGrid3D[Side::C].getHelper();
953 // define dataframe
954 ROOT::RDataFrame dFrame(1);
955 auto dfStore = dFrame.DefineSlotEntry("paramsC", [&params = params](unsigned int, ULong64_t entry) { return params; });
956 dfStore = dfStore.DefineSlotEntry("grid_A", [&helperA = helperA](unsigned int, ULong64_t entry) { return helperA; });
957 dfStore = dfStore.DefineSlotEntry("grid_C", [&helperC = helperC](unsigned int, ULong64_t entry) { return helperC; });
958 dfStore = dfStore.DefineSlotEntry("BField", [field = mBField.getBField()](unsigned int, ULong64_t entry) { return field; });
959 dfStore = dfStore.DefineSlotEntry("metaInf", [meta = mMeta](unsigned int, ULong64_t entry) { return meta; });
960
961 // write to TTree
962 ROOT::RDF::RSnapshotOptions opt;
963 opt.fMode = option;
964 opt.fOverwriteIfExists = true; // overwrite if already exists
965 dfStore.Snapshot("meta", file, {"paramsC", "grid_A", "grid_C", "BField", "metaInf"}, opt);
967
968template <typename DataT>
969void SpaceCharge<DataT>::readMetaData(std::string_view file)
970{
971 if (mReadMetaData) {
972 return;
973 }
974
975 // check if TTree exists
976 TFile f(file.data(), "READ");
977 if (!f.GetListOfKeys()->Contains("meta")) {
978 return;
979 }
980 f.Close();
981
982 auto readMeta = [&mC0 = mC0, &mC1 = mC1, &mC2 = mC2, &mGrid3D = mGrid3D, &mBField = mBField](const std::vector<float>& paramsC, const RegularGridHelper<double>& gridA, const RegularGridHelper<double>& gridC, int field) {
983 mC0 = paramsC[0];
984 mC1 = paramsC[1];
985 mC2 = paramsC[2];
986 mGrid3D[Side::A] = RegularGrid3D<DataT>(gridA.zmin, gridA.rmin, gridA.phimin, gridA.spacingZ, gridA.spacingR, gridA.spacingPhi, gridA.params);
987 mGrid3D[Side::C] = RegularGrid3D<DataT>(gridC.zmin, gridC.rmin, gridC.phimin, gridC.spacingZ, gridC.spacingR, gridC.spacingPhi, gridC.params);
988 mBField.setBField(field);
989 };
990
991 ROOT::RDataFrame dFrame("meta", file);
992 dFrame.Foreach(readMeta, {"paramsC", "grid_A", "grid_C", "BField"});
993
994 const auto& cols = dFrame.GetColumnNames();
995 if (std::find(cols.begin(), cols.end(), "metaInf") != cols.end()) {
996 auto readMetaInf = [&mMeta = mMeta](const SCMetaData& meta) {
997 mMeta = meta;
998 };
999 dFrame.Foreach(readMetaInf, {"metaInf"});
1000 }
1001
1002 LOGP(info, "Setting meta data: mC0={} mC1={} mC2={}", mC0, mC1, mC2);
1003 mReadMetaData = true;
1004}
1005
1006template <typename DataT>
1007void SpaceCharge<DataT>::setFromFile(std::string_view file, const Side side)
1009 setDensityFromFile(file, side);
1010 setPotentialFromFile(file, side);
1011 setElectricFieldsFromFile(file, side);
1012 setLocalDistortionsFromFile(file, side);
1013 setLocalCorrectionsFromFile(file, side);
1014 setGlobalDistortionsFromFile(file, side);
1015 setGlobalCorrectionsFromFile(file, side);
1016 setLocalDistCorrVectorsFromFile(file, side);
1017}
1018
1019template <typename DataT>
1020void SpaceCharge<DataT>::setFromFile(std::string_view file)
1021{
1022 setFromFile(file, Side::A);
1023 setFromFile(file, Side::C);
1024}
1025
1026
1027// explicit template instantiations of the moved members
1028template int o2::tpc::DataContainer3D<float>::writeToFile(std::string_view, std::string_view, std::string_view, const int) const;
1029template bool o2::tpc::DataContainer3D<float>::initFromFile(std::string_view, std::string_view, const int);
1030template void o2::tpc::DataContainer3D<float>::dumpSlice(std::string_view, std::string_view, std::string_view, std::string_view, std::pair<unsigned short, unsigned short>, std::pair<unsigned short, unsigned short>, std::pair<unsigned short, unsigned short>, const int);
1031template void o2::tpc::DataContainer3D<float>::dumpInterpolation(std::string_view, std::string_view, std::string_view, std::string_view, std::pair<float, float>, std::pair<float, float>, std::pair<float, float>, const int, const int, const int, const int);
1032template void o2::tpc::SpaceCharge<float>::dumpToTree(const char*, const o2::tpc::Side, const int, const int, const int, const bool) const;
1033template void o2::tpc::SpaceCharge<float>::dumpToTree(const char*, const o2::tpc::Sector&, const int) const;
1034template int o2::tpc::SpaceCharge<float>::dumpElectricFields(std::string_view, const o2::tpc::Side, std::string_view) const;
1035template void o2::tpc::SpaceCharge<float>::setElectricFieldsFromFile(std::string_view, const o2::tpc::Side);
1036template int o2::tpc::SpaceCharge<float>::dumpGlobalDistortions(std::string_view, const o2::tpc::Side, std::string_view) const;
1038template int o2::tpc::SpaceCharge<float>::dumpGlobalCorrections(std::string_view, const o2::tpc::Side, std::string_view) const;
1040template int o2::tpc::SpaceCharge<float>::dumpLocalCorrections(std::string_view, const o2::tpc::Side, std::string_view) const;
1041template void o2::tpc::SpaceCharge<float>::setLocalCorrectionsFromFile(std::string_view, const o2::tpc::Side);
1042template int o2::tpc::SpaceCharge<float>::dumpLocalDistortions(std::string_view, const o2::tpc::Side, std::string_view) const;
1043template int o2::tpc::SpaceCharge<float>::dumpLocalDistCorrVectors(std::string_view, const o2::tpc::Side, std::string_view) const;
1044template void o2::tpc::SpaceCharge<float>::setLocalDistortionsFromFile(std::string_view, const o2::tpc::Side);
1046template int o2::tpc::SpaceCharge<float>::dumpPotential(std::string_view, const o2::tpc::Side, std::string_view) const;
1047template void o2::tpc::SpaceCharge<float>::setPotentialFromFile(std::string_view, const o2::tpc::Side);
1048template int o2::tpc::SpaceCharge<float>::dumpDensity(std::string_view, const o2::tpc::Side, std::string_view) const;
1050template void o2::tpc::SpaceCharge<float>::dumpToFile(std::string_view, const o2::tpc::Side, std::string_view) const;
1051template void o2::tpc::SpaceCharge<float>::dumpToFile(std::string_view) const;
1052template void o2::tpc::SpaceCharge<float>::dumpMetaData(std::string_view, std::string_view, const bool) const;
1053template void o2::tpc::SpaceCharge<float>::readMetaData(std::string_view);
1054template void o2::tpc::SpaceCharge<float>::setFromFile(std::string_view, const o2::tpc::Side);
1055template void o2::tpc::SpaceCharge<float>::setFromFile(std::string_view);
1056template int o2::tpc::DataContainer3D<double>::writeToFile(std::string_view, std::string_view, std::string_view, const int) const;
1057template bool o2::tpc::DataContainer3D<double>::initFromFile(std::string_view, std::string_view, const int);
1058template void o2::tpc::DataContainer3D<double>::dumpSlice(std::string_view, std::string_view, std::string_view, std::string_view, std::pair<unsigned short, unsigned short>, std::pair<unsigned short, unsigned short>, std::pair<unsigned short, unsigned short>, const int);
1059template void o2::tpc::DataContainer3D<double>::dumpInterpolation(std::string_view, std::string_view, std::string_view, std::string_view, std::pair<float, float>, std::pair<float, float>, std::pair<float, float>, const int, const int, const int, const int);
1060template void o2::tpc::SpaceCharge<double>::dumpToTree(const char*, const o2::tpc::Side, const int, const int, const int, const bool) const;
1061template void o2::tpc::SpaceCharge<double>::dumpToTree(const char*, const o2::tpc::Sector&, const int) const;
1062template int o2::tpc::SpaceCharge<double>::dumpElectricFields(std::string_view, const o2::tpc::Side, std::string_view) const;
1063template void o2::tpc::SpaceCharge<double>::setElectricFieldsFromFile(std::string_view, const o2::tpc::Side);
1064template int o2::tpc::SpaceCharge<double>::dumpGlobalDistortions(std::string_view, const o2::tpc::Side, std::string_view) const;
1066template int o2::tpc::SpaceCharge<double>::dumpGlobalCorrections(std::string_view, const o2::tpc::Side, std::string_view) const;
1068template int o2::tpc::SpaceCharge<double>::dumpLocalCorrections(std::string_view, const o2::tpc::Side, std::string_view) const;
1070template int o2::tpc::SpaceCharge<double>::dumpLocalDistortions(std::string_view, const o2::tpc::Side, std::string_view) const;
1071template int o2::tpc::SpaceCharge<double>::dumpLocalDistCorrVectors(std::string_view, const o2::tpc::Side, std::string_view) const;
1074template int o2::tpc::SpaceCharge<double>::dumpPotential(std::string_view, const o2::tpc::Side, std::string_view) const;
1075template void o2::tpc::SpaceCharge<double>::setPotentialFromFile(std::string_view, const o2::tpc::Side);
1076template int o2::tpc::SpaceCharge<double>::dumpDensity(std::string_view, const o2::tpc::Side, std::string_view) const;
1077template void o2::tpc::SpaceCharge<double>::setDensityFromFile(std::string_view, const o2::tpc::Side);
1078template void o2::tpc::SpaceCharge<double>::dumpToFile(std::string_view, const o2::tpc::Side, std::string_view) const;
1079template void o2::tpc::SpaceCharge<double>::dumpToFile(std::string_view) const;
1080template void o2::tpc::SpaceCharge<double>::dumpMetaData(std::string_view, std::string_view, const bool) const;
1081template void o2::tpc::SpaceCharge<double>::readMetaData(std::string_view);
1082template void o2::tpc::SpaceCharge<double>::setFromFile(std::string_view, const o2::tpc::Side);
1083template void o2::tpc::SpaceCharge<double>::setFromFile(std::string_view);
void dumpToFile(std::string fileName, const CathodeSegmentation &seg, const std::vector< Point > &points)
General auxilliary methods.
This class provides a simple method to store values on a large 3-Dim grid with ROOT io functionality.
int32_t i
Header of the General Run Parameters object for B field values.
Header to collect LHC related constants.
Definition of the MagF class.
uint16_t pos
Definition RawData.h:3
uint32_t side
Definition RawData.h:0
Definition of RegularGrid3D class.
This class contains the algorithms for calculation the distortions and corrections.
Definition of TriCubic class.
uint32_t cols
bool isValid() const
Definition DigitPos.h:38
static constexpr unsigned int ROWOFFSET[NREGIONS]
offset to calculate local row from global row
Definition Mapper.h:533
static GlobalPadNumber getGlobalPadNumber(const unsigned int lrow, const unsigned int pad, const unsigned int region)
Definition Mapper.h:64
const DigitPos findDigitPosFromGlobalPosition(const GlobalPosition3D &pos) const
Definition Mapper.h:716
static const std::vector< unsigned int > PADSPERROW[NREGIONS]
number of pads per row in region
Definition Mapper.h:567
static Mapper & instance(const std::string mappingDir="")
Definition Mapper.h:44
static LocalPosition3D GlobalToLocal(const GlobalPosition3D &pos, const double alpha)
Definition Mapper.h:468
static constexpr unsigned int ROWSPERREGION[NREGIONS]
number of pad rows for region
Definition Mapper.h:532
static constexpr unsigned int NREGIONS
total number of regions in one sector
Definition Mapper.h:527
static constexpr unsigned short getPadsInSector()
Definition Mapper.h:414
const PadCentre & padCentre(GlobalPadNumber padNumber) const
Definition Mapper.h:51
static GlobalPosition3D LocalToGlobal(const LocalPosition3D &pos, const double alpha)
Definition Mapper.h:461
Side side() const
Definition Sector.h:96
int dumpPotential(std::string_view file, const Side side, std::string_view option) const
void setFromFile(std::string_view file, const Side side)
void setPotentialFromFile(std::string_view file, const Side side)
void dumpToFile(std::string_view file, const Side side, std::string_view option) const
void setElectricFieldsFromFile(std::string_view file, const Side side)
int dumpLocalDistortions(std::string_view file, const Side side, std::string_view option) const
int dumpGlobalCorrections(std::string_view file, const Side side, std::string_view option) const
void setLocalCorrectionsFromFile(std::string_view file, const Side side)
void setGlobalDistortionsFromFile(std::string_view file, const Side side)
int dumpGlobalDistortions(std::string_view file, const Side side, std::string_view option) const
int dumpLocalDistCorrVectors(std::string_view file, const Side side, std::string_view option) const
void readMetaData(std::string_view file)
void dumpMetaData(std::string_view file, std::string_view option, const bool overwriteExisting=false) const
void setDensityFromFile(std::string_view file, const Side side)
void setLocalDistCorrVectorsFromFile(std::string_view file, const Side side)
void setLocalDistortionsFromFile(std::string_view file, const Side side)
int dumpDensity(std::string_view file, const Side side, std::string_view option) const
int dumpElectricFields(std::string_view file, const Side side, std::string_view option) const
void dumpToTree(const char *outFileName, const Side side, const int nZPoints=50, const int nRPoints=150, const int nPhiPoints=180, const bool randomize=false) const
int dumpLocalCorrections(std::string_view file, const Side side, std::string_view option) const
void setGlobalCorrectionsFromFile(std::string_view file, const Side side)
GLint GLenum GLint x
Definition glcorearb.h:403
GLint GLsizei count
Definition glcorearb.h:399
GLuint entry
Definition glcorearb.h:5735
GLuint const GLchar * name
Definition glcorearb.h:781
GLdouble f
Definition glcorearb.h:310
GLenum const GLfloat * params
Definition glcorearb.h:272
GLenum GLsizei GLsizei GLint * values
Definition glcorearb.h:1576
GLboolean * data
Definition glcorearb.h:298
GLboolean r
Definition glcorearb.h:1233
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
Global TPC definitions and constants.
Definition SimTraits.h:168
constexpr double SECPHIWIDTH
Definition Defs.h:45
constexpr unsigned char SECTORSPERSIDE
Definition Defs.h:40
@ Count
sentinel - keep last
Side
TPC readout sidE.
Definition Defs.h:35
unsigned short GlobalPadNumber
global pad number
Definition Defs.h:112
void readData(o2::tpc::GBTFrameContainer &container, std::vector< std::ofstream * > &outfiles, int &run, int &done)
static size_t getIndexR(size_t index, const int nz, const int nr, const int nphi)
bool initFromFile(TFile &inpf, const char *name="data")
set values from file
int writeToFile(TFile &outf, const char *name="data") const
void setGrid(unsigned short nZ, unsigned short nR, unsigned short nPhi, const bool resize)
set the grid points
static size_t getIndexZ(size_t index, const int nz, const int nr, const int nphi)
static size_t getIndexPhi(size_t index, const int nz, const int nr, const int nphi)
static void dumpInterpolation(std::string_view treename, std::string_view fileIn, std::string_view fileOut, std::string_view option, std::pair< float, float > rangeR, std::pair< float, float > rangeZ, std::pair< float, float > rangePhi, const int nR, const int nZ, const int nPhi, const int nthreads=1)
static void dumpSlice(std::string_view treename, std::string_view fileIn, std::string_view fileOut, std::string_view option, std::pair< unsigned short, unsigned short > rangeiR, std::pair< unsigned short, unsigned short > rangeiZ, std::pair< unsigned short, unsigned short > rangeiPhi, const int nthreads=1)
static constexpr DataT getRMin()
static constexpr DataT getZMin()
static constexpr DataT getGridSpacingR(const unsigned int nR)
static constexpr DataT getPhiMin()
static constexpr DataT getGridSpacingZ(const unsigned int nZ)
static constexpr DataT getGridSpacingPhi(const unsigned int nPhi)
static int normalizeGridToNSector
the grid in phi direction is squashed from 2 Pi to (2 Pi / SECTORSPERSIDE). This can used to get the ...
helper struct to store and set RegularGrid3D
o2::InteractionRecord ir(0, 0)
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))