Skip to content

Commit 9726160

Browse files
committed
TPC: avoid having a direct dependency on RDataFrame
1 parent 91c2ccd commit 9726160

6 files changed

Lines changed: 1093 additions & 960 deletions

File tree

Detectors/TPC/reconstruction/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ o2_add_test_root_macro(macro/createTPCSpaceChargeCorrection.C
142142
O2::CommonConstants
143143
O2::CommonUtils
144144
O2::TPCSpaceCharge
145+
O2::TPCSpaceChargeIO
145146
LABELS tpc)
146147

147148
o2_add_test_root_macro(macro/findKrBoxCluster.C

Detectors/TPC/simulation/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ o2_add_library(TPCSimulation
2222
src/SAMPAProcessing.cxx
2323
src/IDCSim.cxx
2424
PUBLIC_LINK_LIBRARIES O2::DetectorsBase O2::SimulationDataFormat
25-
O2::TPCBase O2::TPCSpaceCharge O2::TPCCalibration
25+
O2::TPCBase O2::TPCSpaceCharge O2::TPCSpaceChargeIO O2::TPCCalibration
2626
ROOT::Physics)
2727

2828
o2_target_root_dictionary(TPCSimulation

Detectors/TPC/spacecharge/CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ o2_add_library(TPCSpaceCharge
1919
O2::Field
2020
Vc::Vc
2121
ROOT::Core
22-
ROOT::ROOTDataFrame
2322
O2::DataFormatsParameters)
2423

24+
o2_add_library(TPCSpaceChargeIO
25+
SOURCES src/SpaceChargeIO.cxx
26+
PUBLIC_LINK_LIBRARIES O2::TPCSpaceCharge
27+
ROOT::ROOTDataFrame)
28+
2529

2630
o2_target_root_dictionary(TPCSpaceCharge
2731
HEADERS include/TPCSpaceCharge/PoissonSolver.h
@@ -38,10 +42,12 @@ o2_target_root_dictionary(TPCSpaceCharge
3842

3943
o2_add_test_root_macro(macro/calculateDistortionsCorrections.C
4044
PUBLIC_LINK_LIBRARIES O2::TPCSpaceCharge
45+
O2::TPCSpaceChargeIO
4146
LABELS tpc COMPILE_ONLY)
4247

4348
o2_add_test_root_macro(macro/createResidualDistortionObject.C
4449
PUBLIC_LINK_LIBRARIES O2::TPCSpaceCharge
50+
O2::TPCSpaceChargeIO
4551
O2::CommonUtils
4652
LABELS tpc)
4753

@@ -51,6 +57,7 @@ install(FILES macro/createSCHistosFromHits.C
5157

5258
o2_add_test_root_macro(macro/createSCHistosFromHits.C
5359
PUBLIC_LINK_LIBRARIES O2::TPCSpaceCharge
60+
O2::TPCSpaceChargeIO
5461
O2::CommonUtils
5562
O2::TPCBase
5663
O2::TPCSimulation

Detectors/TPC/spacecharge/src/DataContainer3D.cxx

Lines changed: 0 additions & 267 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include "TPCBase/Mapper.h"
1717
#include "Framework/Logger.h"
1818
#include "TFile.h"
19-
#include "ROOT/RDataFrame.hxx"
2019
#include "TStopwatch.h"
2120
#include "TTree.h"
2221

@@ -42,98 +41,7 @@ int DataContainer3D<DataT>::writeToFile(TFile& outf, const char* name) const
4241
return 0;
4342
}
4443

45-
template <typename DataT>
46-
int DataContainer3D<DataT>::writeToFile(std::string_view file, std::string_view option, std::string_view name, const int nthreads) const
47-
{
48-
// max number of floats per Entry
49-
const size_t maxvalues = sizeof(float) * 1024 * 1024;
50-
51-
// total number of values to be stored
52-
const size_t nsize = getNDataPoints();
53-
54-
// calculate number of entries in the tree and restrict if the number of values per threads exceeds max size
55-
size_t entries = ((nsize / nthreads) > maxvalues) ? (nsize / maxvalues) : nthreads;
56-
57-
if (entries > nsize) {
58-
entries = nsize;
59-
}
60-
61-
// calculate numbers to store per entry
62-
const size_t values_per_entry = nsize / entries;
6344

64-
// in case of remainder add additonal entry
65-
const size_t values_lastEntry = nsize % entries;
66-
if (values_lastEntry) {
67-
entries += 1;
68-
}
69-
70-
// in case EnableImplicitMT was already called with different number of threads, perform reset
71-
if (ROOT::IsImplicitMTEnabled() && (ROOT::GetThreadPoolSize() != nthreads)) {
72-
ROOT::DisableImplicitMT();
73-
}
74-
ROOT::EnableImplicitMT(nthreads);
75-
76-
// define dataframe which will be stored in the TTree
77-
ROOT::RDataFrame dFrame(entries);
78-
79-
// define function which is used to fill the data frame
80-
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); });
81-
dfStore = dfStore.Define("nz", [mZVertices = mZVertices]() { return mZVertices; });
82-
dfStore = dfStore.Define("nr", [mRVertices = mRVertices]() { return mRVertices; });
83-
dfStore = dfStore.Define("nphi", [mPhiVertices = mPhiVertices]() { return mPhiVertices; });
84-
85-
// define options of TFile
86-
ROOT::RDF::RSnapshotOptions opt;
87-
opt.fMode = option;
88-
opt.fOverwriteIfExists = true; // overwrite if already exists
89-
90-
TStopwatch timer;
91-
// note: first call has some overhead (~2s)
92-
dfStore.Snapshot(name, file, {name.data(), "nz", "nr", "nphi"}, opt);
93-
timer.Print("u");
94-
return 0;
95-
}
96-
97-
template <typename DataT>
98-
bool DataContainer3D<DataT>::initFromFile(std::string_view file, std::string_view name, const int nthreads)
99-
{
100-
// in case EnableImplicitMT was already called with different number of threads, perform reset
101-
if (ROOT::IsImplicitMTEnabled() && (ROOT::GetThreadPoolSize() != nthreads)) {
102-
ROOT::DisableImplicitMT();
103-
}
104-
ROOT::EnableImplicitMT(nthreads);
105-
106-
// compare first the meta data (is the number of vertices the same)
107-
// define data frame from imput file
108-
ROOT::RDataFrame dFrame(name, file);
109-
110-
// compare vertices
111-
auto comp = [mZVertices = mZVertices, mRVertices = mRVertices, mPhiVertices = mPhiVertices](const unsigned short nz, const unsigned short nr, const unsigned short nphi) {
112-
if ((nz == mZVertices) && (nr == mRVertices) && (nphi == mPhiVertices)) {
113-
return false;
114-
}
115-
return true;
116-
};
117-
118-
auto count = dFrame.Filter(comp, {"nz", "nr", "nphi"}).Count();
119-
if (*count != 0) {
120-
LOGP(error, "Data from input file has different number of vertices! Found {} same vertices", *count);
121-
return false;
122-
}
123-
124-
// define lambda function which is used to copy the data
125-
auto readData = [&mData = mData](const std::pair<long, std::vector<float>>& data) {
126-
std::copy(data.second.begin(), data.second.end(), mData.begin() + data.first);
127-
};
128-
129-
LOGP(info, "Reading {} from file {}", name, file);
130-
131-
// fill data from RDataFrame
132-
TStopwatch timer;
133-
dFrame.Foreach(readData, {name.data()});
134-
timer.Print("u");
135-
return true;
136-
}
13745

13846
/// set values from file
13947
template <typename DataT>
@@ -215,18 +123,6 @@ void DataContainer3D<DataT>::print() const
215123
LOGP(info, "{} \n \n", stream.str());
216124
}
217125

218-
template <typename DataT>
219-
auto DataContainer3D<DataT>::getDataSlice(const std::vector<DataT>& data, size_t entries, const size_t values_per_entry, ULong64_t entry)
220-
{
221-
const long indStart = entry * values_per_entry;
222-
if (entry < (entries - 1)) {
223-
return std::pair(indStart, std::vector<float>(data.begin() + indStart, data.begin() + indStart + values_per_entry));
224-
} else if (entry == (entries - 1)) {
225-
// last entry might have different number of values. just copy the rest...
226-
return std::pair(indStart, std::vector<float>(data.begin() + indStart, data.end()));
227-
}
228-
return std::pair(indStart, std::vector<float>());
229-
};
230126

231127
template <typename DataT>
232128
DataContainer3D<DataT>& DataContainer3D<DataT>::operator*=(const DataT value)
@@ -321,82 +217,6 @@ void DataContainer3D<DataT>::setGrid(unsigned short nZ, unsigned short nR, unsig
321217
}
322218
}
323219

324-
template <typename DataT>
325-
void 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)
326-
{
327-
if (ROOT::IsImplicitMTEnabled() && (ROOT::GetThreadPoolSize() != nthreads)) {
328-
ROOT::DisableImplicitMT();
329-
}
330-
ROOT::EnableImplicitMT(nthreads);
331-
ROOT::RDataFrame dFrame(treename, fileIn);
332-
333-
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) {
334-
std::vector<size_t> ir;
335-
std::vector<size_t> iphi;
336-
std::vector<size_t> iz;
337-
std::vector<float> r;
338-
std::vector<float> phi;
339-
std::vector<float> z;
340-
std::vector<float> vals;
341-
std::vector<size_t> globalIdx;
342-
std::vector<LocalPosition3D> lPos;
343-
const auto nvalues = values.second.size();
344-
ir.reserve(nvalues);
345-
iphi.reserve(nvalues);
346-
iz.reserve(nvalues);
347-
r.reserve(nvalues);
348-
phi.reserve(nvalues);
349-
z.reserve(nvalues);
350-
vals.reserve(nvalues);
351-
lPos.reserve(nvalues);
352-
globalIdx.reserve(nvalues);
353-
for (size_t i = 0; i < nvalues; ++i) {
354-
const size_t idx = values.first + i;
355-
const auto iZTmp = o2::tpc::DataContainer3D<float>::getIndexZ(idx, nz, nr, nphi);
356-
if ((rangeiZ.first < rangeiZ.second) && ((iZTmp < rangeiZ.first) || (iZTmp > rangeiZ.second))) {
357-
continue;
358-
}
359-
360-
const auto iRTmp = o2::tpc::DataContainer3D<float>::getIndexR(idx, nz, nr, nphi);
361-
if ((rangeiR.first < rangeiR.second) && ((iRTmp < rangeiR.first) || (iRTmp > rangeiR.second))) {
362-
continue;
363-
}
364-
365-
const auto iPhiTmp = o2::tpc::DataContainer3D<float>::getIndexPhi(idx, nz, nr, nphi);
366-
if ((rangeiPhi.first < rangeiPhi.second) && ((iPhiTmp < rangeiPhi.first) || (iPhiTmp > rangeiPhi.second))) {
367-
continue;
368-
}
369-
370-
const float rTmp = o2::tpc::GridProperties<float>::getRMin() + o2::tpc::GridProperties<float>::getGridSpacingR(nr) * iRTmp;
371-
const float zTmp = o2::tpc::GridProperties<float>::getZMin() + o2::tpc::GridProperties<float>::getGridSpacingZ(nz) * iZTmp;
372-
const float phiTmp = o2::tpc::GridProperties<float>::getPhiMin() + o2::tpc::GridProperties<float>::getGridSpacingPhi(nphi) * (MGParameters::normalizeGridToNSector / double(SECTORSPERSIDE)) * iPhiTmp;
373-
374-
const float x = rTmp * std::cos(phiTmp);
375-
const float y = rTmp * std::sin(phiTmp);
376-
const LocalPosition3D pos(x, y, zTmp);
377-
unsigned char secNum = std::floor(phiTmp / SECPHIWIDTH);
378-
Sector sector(secNum + (pos.Z() < 0) * SECTORSPERSIDE);
379-
LocalPosition3D lPosTmp = Mapper::GlobalToLocal(pos, sector);
380-
381-
lPos.emplace_back(lPosTmp);
382-
ir.emplace_back(iRTmp);
383-
iphi.emplace_back(iPhiTmp);
384-
iz.emplace_back(iZTmp);
385-
r.emplace_back(rTmp);
386-
phi.emplace_back(phiTmp);
387-
z.emplace_back(zTmp);
388-
vals.emplace_back(values.second[i]);
389-
globalIdx.emplace_back(idx);
390-
}
391-
return std::make_tuple(vals, iz, ir, iphi, z, r, phi, lPos, globalIdx);
392-
},
393-
{treename.data(), "nz", "nr", "nphi"});
394-
395-
// define options of TFile
396-
ROOT::RDF::RSnapshotOptions opt;
397-
opt.fMode = option;
398-
df.Snapshot(treename, fileOut, {"slice"}, opt);
399-
}
400220

401221
template <typename DataT>
402222
DataT DataContainer3D<DataT>::interpolate(const DataT z, const DataT r, const DataT phi, const o2::tpc::RegularGrid3D<DataT>& grid) const
@@ -405,93 +225,6 @@ DataT DataContainer3D<DataT>::interpolate(const DataT z, const DataT r, const Da
405225
return interpolator(z, r, phi);
406226
}
407227

408-
template <typename DataT>
409-
void 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)
410-
{
411-
if (ROOT::IsImplicitMTEnabled() && (ROOT::GetThreadPoolSize() != nthreads)) {
412-
ROOT::DisableImplicitMT();
413-
}
414-
ROOT::EnableImplicitMT(nthreads);
415-
ROOT::RDataFrame dFrame(nPhi);
416-
417-
// get vertices for input TTree which is needed to define the grid for interpolation
418-
unsigned short nr, nz, nphi;
419-
if (!getVertices(treename, fileIn, nr, nz, nphi)) {
420-
return;
421-
}
422-
423-
// load data from input TTree
424-
DataContainer3D<DataT> data;
425-
data.setGrid(nz, nr, nphi, true);
426-
data.initFromFile(fileIn, treename, nthreads);
427-
428-
// define grid for interpolation
429-
using GridProp = GridProperties<DataT>;
430-
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});
431-
432-
auto interpolate = [&mGrid3D = std::as_const(mGrid3D), &data = std::as_const(data), rangeR, rangeZ, rangePhi, nR, nZ, nPhi](unsigned int, ULong64_t iPhi) {
433-
std::vector<size_t> ir;
434-
std::vector<size_t> iphi;
435-
std::vector<size_t> iz;
436-
std::vector<float> r;
437-
std::vector<float> phi;
438-
std::vector<float> z;
439-
std::vector<float> vals;
440-
std::vector<size_t> globalIdx;
441-
std::vector<LocalPosition3D> lPos;
442-
const auto nvalues = nR * nZ;
443-
ir.reserve(nvalues);
444-
iphi.reserve(nvalues);
445-
iz.reserve(nvalues);
446-
r.reserve(nvalues);
447-
phi.reserve(nvalues);
448-
z.reserve(nvalues);
449-
vals.reserve(nvalues);
450-
lPos.reserve(nvalues);
451-
globalIdx.reserve(nvalues);
452-
453-
const float rSpacing = (rangeR.second - rangeR.first) / (nR - 1);
454-
const float zSpacing = (rangeZ.second - rangeZ.first) / (nZ - 1);
455-
const float phiSpacing = (rangePhi.second - rangePhi.first) / (nPhi - 1);
456-
const DataT phiPos = rangePhi.first + iPhi * phiSpacing;
457-
// loop over grid and interpolate values
458-
for (int iR = 0; iR < nR; ++iR) {
459-
const DataT rPos = rangeR.first + iR * rSpacing;
460-
for (int iZ = 0; iZ < nZ; ++iZ) {
461-
const size_t idx = (iZ + nZ * (iR + iPhi * nR)); // unique index to Build index with other friend TTrees
462-
const DataT zPos = rangeZ.first + iZ * zSpacing;
463-
ir.emplace_back(iR);
464-
iphi.emplace_back(iPhi);
465-
iz.emplace_back(iZ);
466-
r.emplace_back(rPos);
467-
phi.emplace_back(phiPos);
468-
z.emplace_back(zPos);
469-
vals.emplace_back(data.interpolate(zPos, rPos, phiPos, mGrid3D)); // interpolated values
470-
globalIdx.emplace_back(idx);
471-
const float x = rPos * std::cos(phiPos);
472-
const float y = rPos * std::sin(phiPos);
473-
const LocalPosition3D pos(x, y, zPos);
474-
unsigned char secNum = std::floor(phiPos / SECPHIWIDTH); // TODO CHECK THIS
475-
Sector sector(secNum + (pos.Z() < 0) * SECTORSPERSIDE);
476-
LocalPosition3D lPosTmp = Mapper::GlobalToLocal(pos, sector);
477-
lPos.emplace_back(lPosTmp);
478-
}
479-
}
480-
return std::make_tuple(vals, iz, ir, iphi, z, r, phi, lPos, globalIdx);
481-
};
482-
483-
// define RDataFrame entry
484-
auto dfStore = dFrame.DefineSlotEntry(treename, interpolate);
485-
486-
// define options of TFile
487-
ROOT::RDF::RSnapshotOptions opt;
488-
opt.fMode = option;
489-
490-
TStopwatch timer;
491-
// note: first call has some overhead (~2s)
492-
dfStore.Snapshot(treename, fileOut, {treename.data()}, opt);
493-
timer.Print("u");
494-
}
495228

496229
template <typename DataT>
497230
bool DataContainer3D<DataT>::getVertices(std::string_view treename, std::string_view fileIn, unsigned short& nR, unsigned short& nZ, unsigned short& nPhi)

0 commit comments

Comments
 (0)