Skip to content

Commit 19b763d

Browse files
authored
Streamlining definition and reading of tables (#4369)
1 parent 840bbbb commit 19b763d

File tree

10 files changed

+180
-200
lines changed

10 files changed

+180
-200
lines changed

Framework/Core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ o2_add_library(Framework
2828
src/ASoA.cxx
2929
${GUI_SOURCES}
3030
src/AnalysisHelpers.cxx
31+
src/AnalysisDataModelHelpers.cxx
3132
src/BoostOptionsRetriever.cxx
3233
src/ChannelConfigurationPolicy.cxx
3334
src/ChannelMatching.cxx

Framework/Core/include/Framework/AnalysisDataModel.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ DECLARE_SOA_DYNAMIC_COLUMN(TPCFractionSharedCls, tpcFractionSharedCls, [](uint8_
205205
});
206206
} // namespace track
207207

208-
DECLARE_SOA_TABLE_FULL(StoredTracks, "Tracks", "AOD", "TRACKPAR",
208+
DECLARE_SOA_TABLE_FULL(StoredTracks, "Tracks", "AOD", "TRACK:PAR",
209209
o2::soa::Index<>, track::CollisionId, track::TrackType,
210210
track::X, track::Alpha,
211211
track::Y, track::Z, track::Snp, track::Tgl,
@@ -216,18 +216,18 @@ DECLARE_SOA_TABLE_FULL(StoredTracks, "Tracks", "AOD", "TRACKPAR",
216216
track::Pz<track::Signed1Pt, track::Tgl>,
217217
track::Charge<track::Signed1Pt>);
218218

219-
DECLARE_SOA_EXTENDED_TABLE(Tracks, StoredTracks, "TRACKPAR",
219+
DECLARE_SOA_EXTENDED_TABLE(Tracks, StoredTracks, "TRACK:PAR",
220220
aod::track::Pt,
221221
aod::track::P,
222222
aod::track::Eta,
223223
aod::track::RawPhi);
224224

225-
DECLARE_SOA_TABLE_FULL(StoredTracksCov, "TracksCov", "AOD", "TRACKPARCOV",
225+
DECLARE_SOA_TABLE_FULL(StoredTracksCov, "TracksCov", "AOD", "TRACK:PARCOV",
226226
track::SigmaY, track::SigmaZ, track::SigmaSnp, track::SigmaTgl, track::Sigma1Pt,
227227
track::RhoZY, track::RhoSnpY, track::RhoSnpZ, track::RhoTglY, track::RhoTglZ,
228228
track::RhoTglSnp, track::Rho1PtY, track::Rho1PtZ, track::Rho1PtSnp, track::Rho1PtTgl);
229229

230-
DECLARE_SOA_EXTENDED_TABLE(TracksCov, StoredTracksCov, "TRACKPARCOV",
230+
DECLARE_SOA_EXTENDED_TABLE(TracksCov, StoredTracksCov, "TRACK:PARCOV",
231231
aod::track::CYY,
232232
aod::track::CZY,
233233
aod::track::CZZ,
@@ -244,7 +244,7 @@ DECLARE_SOA_EXTENDED_TABLE(TracksCov, StoredTracksCov, "TRACKPARCOV",
244244
aod::track::C1PtTgl,
245245
aod::track::C1Pt21Pt2);
246246

247-
DECLARE_SOA_TABLE(TracksExtra, "AOD", "TRACKEXTRA",
247+
DECLARE_SOA_TABLE(TracksExtra, "AOD", "TRACK:EXTRA",
248248
track::TPCInnerParam, track::Flags, track::ITSClusterMap,
249249
track::TPCNClsFindable, track::TPCNClsFindableMinusFound, track::TPCNClsFindableMinusCrossedRows,
250250
track::TPCNClsShared, track::TRDPattern, track::ITSChi2NCl,
@@ -468,7 +468,7 @@ DECLARE_SOA_INDEX_COLUMN_FULL(NegTrack, negTrack, int, FullTracks, "fNegTrackID"
468468
DECLARE_SOA_INDEX_COLUMN(Collision, collision);
469469
} // namespace v0
470470

471-
DECLARE_SOA_TABLE(StoredV0s, "AOD", "O2v0", o2::soa::Index<>, v0::PosTrackId, v0::NegTrackId);
471+
DECLARE_SOA_TABLE(StoredV0s, "AOD", "V0", o2::soa::Index<>, v0::PosTrackId, v0::NegTrackId);
472472
DECLARE_SOA_TABLE(TransientV0s, "AOD", "V0INDEX", v0::CollisionId);
473473

474474
using V0s = soa::Join<TransientV0s, StoredV0s>;
@@ -481,7 +481,7 @@ DECLARE_SOA_INDEX_COLUMN_FULL(Bachelor, bachelor, int, FullTracks, "fTracksID");
481481
DECLARE_SOA_INDEX_COLUMN(Collision, collision);
482482
} // namespace cascade
483483

484-
DECLARE_SOA_TABLE(StoredCascades, "AOD", "O2cascade", o2::soa::Index<>, cascade::V0Id, cascade::BachelorId);
484+
DECLARE_SOA_TABLE(StoredCascades, "AOD", "CASCADE", o2::soa::Index<>, cascade::V0Id, cascade::BachelorId);
485485
DECLARE_SOA_TABLE(TransientCascades, "AOD", "CASCADEINDEX", cascade::CollisionId);
486486

487487
using Cascades = soa::Join<TransientCascades, StoredCascades>;
@@ -503,7 +503,7 @@ DECLARE_SOA_COLUMN(BBFlag, bbFlag, uint64_t);
503503
DECLARE_SOA_COLUMN(BGFlag, bgFlag, uint64_t);
504504
} // namespace run2v0
505505

506-
DECLARE_SOA_TABLE(Run2V0s, "AOD", "RUN2V0", o2::soa::Index<>, run2v0::BCId,
506+
DECLARE_SOA_TABLE(Run2V0s, "RN2", "V0", o2::soa::Index<>, run2v0::BCId,
507507
run2v0::Adc, run2v0::Time, run2v0::Width,
508508
run2v0::MultA, run2v0::MultC,
509509
run2v0::TimeA, run2v0::TimeC,

Framework/Core/include/Framework/DataAllocator.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,6 @@ class DataAllocator
133133
void* t2tr = nullptr;
134134
call_if_defined<struct TreeToTable>([&](auto* p) {
135135
auto t2t = new std::decay_t<decltype(*p)>(args...);
136-
t2t->addAllColumns();
137136
adopt(spec, t2t);
138137
t2tr = t2t;
139138
});

Framework/Core/src/AODReaderHelpers.cxx

Lines changed: 29 additions & 163 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#include "Framework/TableTreeHelpers.h"
1212
#include "Framework/AODReaderHelpers.h"
13-
#include "Framework/AnalysisDataModel.h"
13+
#include "AnalysisDataModelHelpers.h"
1414
#include "DataProcessingHelpers.h"
1515
#include "ExpressionHelpers.h"
1616
#include "Framework/RootTableBuilderHelpers.h"
@@ -41,105 +41,6 @@
4141

4242
namespace o2::framework::readers
4343
{
44-
enum AODTypeMask : uint64_t {
45-
None = 0,
46-
Track = 1 << 0,
47-
TrackCov = 1 << 1,
48-
TrackExtra = 1 << 2,
49-
Calo = 1 << 3,
50-
CaloTrigger = 1 << 4,
51-
Muon = 1 << 5,
52-
MuonCluster = 1 << 6,
53-
Zdc = 1 << 7,
54-
BC = 1 << 8,
55-
Collision = 1 << 9,
56-
FT0 = 1 << 10,
57-
FV0 = 1 << 11,
58-
FDD = 1 << 12,
59-
UnassignedTrack = 1 << 13,
60-
Run2V0 = 1 << 14,
61-
McCollision = 1 << 15,
62-
McTrackLabel = 1 << 16,
63-
McCaloLabel = 1 << 17,
64-
McCollisionLabel = 1 << 18,
65-
McParticle = 1 << 19,
66-
Unknown = 1 << 20
67-
};
68-
69-
uint64_t getMask(header::DataDescription description)
70-
{
71-
72-
if (description == header::DataDescription{"TRACKPAR"}) {
73-
return AODTypeMask::Track;
74-
} else if (description == header::DataDescription{"TRACKPARCOV"}) {
75-
return AODTypeMask::TrackCov;
76-
} else if (description == header::DataDescription{"TRACKEXTRA"}) {
77-
return AODTypeMask::TrackExtra;
78-
} else if (description == header::DataDescription{"CALO"}) {
79-
return AODTypeMask::Calo;
80-
} else if (description == header::DataDescription{"CALOTRIGGER"}) {
81-
return AODTypeMask::CaloTrigger;
82-
} else if (description == header::DataDescription{"MUON"}) {
83-
return AODTypeMask::Muon;
84-
} else if (description == header::DataDescription{"MUONCLUSTER"}) {
85-
return AODTypeMask::MuonCluster;
86-
} else if (description == header::DataDescription{"ZDC"}) {
87-
return AODTypeMask::Zdc;
88-
} else if (description == header::DataDescription{"BC"}) {
89-
return AODTypeMask::BC;
90-
} else if (description == header::DataDescription{"COLLISION"}) {
91-
return AODTypeMask::Collision;
92-
} else if (description == header::DataDescription{"FT0"}) {
93-
return AODTypeMask::FT0;
94-
} else if (description == header::DataDescription{"FV0"}) {
95-
return AODTypeMask::FV0;
96-
} else if (description == header::DataDescription{"FDD"}) {
97-
return AODTypeMask::FDD;
98-
} else if (description == header::DataDescription{"UNASSIGNEDTRACK"}) {
99-
return AODTypeMask::UnassignedTrack;
100-
} else if (description == header::DataDescription{"RUN2V0"}) {
101-
return AODTypeMask::Run2V0;
102-
} else if (description == header::DataDescription{"MCCOLLISION"}) {
103-
return AODTypeMask::McCollision;
104-
} else if (description == header::DataDescription{"MCTRACKLABEL"}) {
105-
return AODTypeMask::McTrackLabel;
106-
} else if (description == header::DataDescription{"MCCALOLABEL"}) {
107-
return AODTypeMask::McCaloLabel;
108-
} else if (description == header::DataDescription{"MCCOLLISLABEL"}) {
109-
return AODTypeMask::McCollisionLabel;
110-
} else if (description == header::DataDescription{"MCPARTICLE"}) {
111-
return AODTypeMask::McParticle;
112-
} else {
113-
LOG(DEBUG) << "This is a tree of unknown type! " << description.str;
114-
return AODTypeMask::Unknown;
115-
}
116-
}
117-
118-
uint64_t calculateReadMask(std::vector<OutputRoute> const& routes, header::DataOrigin const&)
119-
{
120-
uint64_t readMask = None;
121-
for (auto& route : routes) {
122-
auto concrete = DataSpecUtils::asConcreteDataTypeMatcher(route.matcher);
123-
auto description = concrete.description;
124-
125-
readMask |= getMask(description);
126-
}
127-
return readMask;
128-
}
129-
130-
std::vector<OutputRoute> getListOfUnknown(std::vector<OutputRoute> const& routes)
131-
{
132-
133-
std::vector<OutputRoute> unknows;
134-
for (auto& route : routes) {
135-
auto concrete = DataSpecUtils::asConcreteDataTypeMatcher(route.matcher);
136-
137-
if (getMask(concrete.description) == AODTypeMask::Unknown)
138-
unknows.push_back(route);
139-
}
140-
return unknows;
141-
}
142-
14344
AlgorithmSpec AODReaderHelpers::aodSpawnerCallback(std::vector<InputSpec> requested)
14445
{
14546
return AlgorithmSpec::InitCallback{[requested](InitContext& ic) {
@@ -174,9 +75,9 @@ AlgorithmSpec AODReaderHelpers::aodSpawnerCallback(std::vector<InputSpec> reques
17475
return o2::soa::spawner(expressions{}, original_table.get());
17576
};
17677

177-
if (description == header::DataDescription{"TRACKPAR"}) {
78+
if (description == header::DataDescription{"TRACK:PAR"}) {
17879
outputs.adopt(Output{origin, description}, maker(o2::aod::TracksExtensionMetadata{}));
179-
} else if (description == header::DataDescription{"TRACKPARCOV"}) {
80+
} else if (description == header::DataDescription{"TRACK:PARCOV"}) {
18081
outputs.adopt(Output{origin, description}, maker(o2::aod::TracksCovExtensionMetadata{}));
18182
} else if (description == header::DataDescription{"MUON"}) {
18283
outputs.adopt(Output{origin, description}, maker(o2::aod::MuonsExtensionMetadata{}));
@@ -206,16 +107,11 @@ AlgorithmSpec AODReaderHelpers::rootFileReaderCallback()
206107
// get the run time watchdog
207108
auto* watchdog = new RuntimeWatchdog(options.get<int64_t>("time-limit"));
208109

209-
// analyze type of requested tables
210-
uint64_t readMask = calculateReadMask(spec.outputs, header::DataOrigin{"AOD"});
211-
std::vector<OutputRoute> unknowns;
212-
if (readMask & AODTypeMask::Unknown) {
213-
unknowns = getListOfUnknown(spec.outputs);
214-
}
110+
// create list of requested tables
111+
std::vector<OutputRoute> requestedTables(spec.outputs);
215112

216113
auto counter = std::make_shared<int>(0);
217-
return adaptStateless([readMask,
218-
unknowns,
114+
return adaptStateless([requestedTables,
219115
watchdog,
220116
didir](DataAllocator& outputs, ControlService& control, DeviceSpec const& device) {
221117
// check if RuntimeLimit is reached
@@ -242,66 +138,36 @@ AlgorithmSpec AODReaderHelpers::rootFileReaderCallback()
242138
return;
243139
}
244140

245-
auto tableMaker = [&readMask, &outputs, fi, didir](auto metadata, AODTypeMask mask, char const* treeName) {
246-
if (readMask & mask) {
141+
// loop over requested tables
142+
for (auto route : requestedTables) {
247143

248-
auto dh = header::DataHeader(decltype(metadata)::description(), decltype(metadata)::origin(), 0);
249-
auto reader = didir->getTreeReader(dh, fi, treeName);
144+
// create a TreeToTable object
145+
auto concrete = DataSpecUtils::asConcreteDataMatcher(route.matcher);
146+
auto dh = header::DataHeader(concrete.description, concrete.origin, concrete.subSpec);
250147

251-
using table_t = typename decltype(metadata)::table_t;
252-
if (!reader || (reader->IsInvalid())) {
253-
LOGP(ERROR, "Requested \"{}\" tree not found in input file \"{}\"", treeName, didir->getInputFilename(dh, fi));
254-
} else {
255-
auto& builder = outputs.make<TableBuilder>(Output{decltype(metadata)::origin(), decltype(metadata)::description()});
256-
RootTableBuilderHelpers::convertASoA<table_t>(builder, *reader);
257-
}
148+
auto tr = didir->getDataTree(dh, fi);
149+
if (!tr) {
150+
char* table;
151+
sprintf(table, "%s/%s/%" PRIu32, concrete.origin.str, concrete.description.str, concrete.subSpec);
152+
LOGP(ERROR, "Error while retrieving the tree for \"{}\"!", table);
153+
return;
258154
}
259-
};
260-
tableMaker(o2::aod::CollisionsMetadata{}, AODTypeMask::Collision, "O2collision");
261-
tableMaker(o2::aod::StoredTracksMetadata{}, AODTypeMask::Track, "O2track");
262-
tableMaker(o2::aod::StoredTracksCovMetadata{}, AODTypeMask::TrackCov, "O2track");
263-
tableMaker(o2::aod::TracksExtraMetadata{}, AODTypeMask::TrackExtra, "O2track");
264-
tableMaker(o2::aod::CalosMetadata{}, AODTypeMask::Calo, "O2calo");
265-
tableMaker(o2::aod::CaloTriggersMetadata{}, AODTypeMask::CaloTrigger, "O2calotrigger");
266-
tableMaker(o2::aod::StoredMuonsMetadata{}, AODTypeMask::Muon, "O2muon");
267-
tableMaker(o2::aod::MuonClustersMetadata{}, AODTypeMask::Muon, "O2muoncluster");
268-
tableMaker(o2::aod::ZdcsMetadata{}, AODTypeMask::Zdc, "O2zdc");
269-
tableMaker(o2::aod::BCsMetadata{}, AODTypeMask::BC, "O2bc");
270-
tableMaker(o2::aod::FT0sMetadata{}, AODTypeMask::FT0, "O2ft0");
271-
tableMaker(o2::aod::FV0sMetadata{}, AODTypeMask::FV0, "O2fv0");
272-
tableMaker(o2::aod::FDDsMetadata{}, AODTypeMask::FDD, "O2fdd");
273-
tableMaker(o2::aod::UnassignedTracksMetadata{}, AODTypeMask::UnassignedTrack, "O2unassignedtrack");
274-
tableMaker(o2::aod::Run2V0sMetadata{}, AODTypeMask::Run2V0, "Run2v0");
275-
tableMaker(o2::aod::McCollisionsMetadata{}, AODTypeMask::McCollision, "O2mccollision");
276-
tableMaker(o2::aod::McTrackLabelsMetadata{}, AODTypeMask::McTrackLabel, "O2mctracklabel");
277-
tableMaker(o2::aod::McCaloLabelsMetadata{}, AODTypeMask::McCaloLabel, "O2mccalolabel");
278-
tableMaker(o2::aod::McCollisionLabelsMetadata{}, AODTypeMask::McCollisionLabel, "O2mccollisionlabel");
279-
tableMaker(o2::aod::McParticlesMetadata{}, AODTypeMask::McParticle, "O2mcparticle");
280-
281-
// tables not included in the DataModel
282-
if (readMask & AODTypeMask::Unknown) {
283155

284-
// loop over unknowns
285-
for (auto route : unknowns) {
156+
auto o = Output(dh);
157+
auto& t2t = outputs.make<TreeToTable>(o, tr);
286158

287-
// create a TreeToTable object
288-
auto concrete = DataSpecUtils::asConcreteDataMatcher(route.matcher);
289-
auto dh = header::DataHeader(concrete.description, concrete.origin, concrete.subSpec);
290-
291-
auto tr = didir->getDataTree(dh, fi);
292-
if (!tr) {
293-
char* table;
294-
sprintf(table, "%s/%s/%" PRIu32, concrete.origin.str, concrete.description.str, concrete.subSpec);
295-
LOGP(ERROR, "Error while retrieving the tree for \"{}\"!", table);
296-
return;
159+
// add branches to read
160+
auto colnames = aod::datamodel::getColumnNames(dh);
161+
if (colnames.size() == 0) {
162+
t2t.addAllColumns();
163+
} else {
164+
for (auto colname : colnames) {
165+
t2t.addColumn(colname.c_str());
297166
}
298-
299-
auto o = Output(dh);
300-
auto& t2t = outputs.make<TreeToTable>(o, tr);
301-
302-
// fill the table
303-
t2t.fill();
304167
}
168+
169+
// fill the table
170+
t2t.fill();
305171
}
306172
});
307173
})};
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
#include "AnalysisDataModelHelpers.h"
12+
#include "Framework/AnalysisDataModel.h"
13+
#include "Framework/StringHelpers.h"
14+
#include "Framework/Logger.h"
15+
#include <boost/algorithm/string.hpp>
16+
17+
namespace o2::aod::datamodel
18+
{
19+
std::string getTreeName(header::DataHeader dh)
20+
{
21+
std::string description = std::string(dh.dataDescription.str);
22+
std::string origin = std::string(dh.dataOrigin.str);
23+
24+
// lower case of first part of description
25+
auto found = description.find_first_of(":");
26+
std::string treeName = boost::algorithm::to_lower_copy(description).substr(0, found);
27+
28+
// add prefix according to origin
29+
if (origin == "AOD") {
30+
treeName = "O2" + treeName;
31+
} else if (origin == "RN2") {
32+
treeName = "Run2" + treeName;
33+
}
34+
35+
// exceptions from this
36+
if (origin == "AOD" && description == "MCCOLLISLABEL") {
37+
treeName = "O2mccollisionlabel";
38+
}
39+
40+
return treeName;
41+
}
42+
43+
template <typename... C>
44+
static constexpr auto columnNamesTrait(framework::pack<C...>)
45+
{
46+
return std::vector<std::string>{C::columnLabel()...};
47+
}
48+
49+
std::vector<std::string> getColumnNames(header::DataHeader dh)
50+
{
51+
auto description = std::string(dh.dataDescription.str);
52+
auto origin = std::string(dh.dataOrigin.str);
53+
54+
// get column names
55+
// AOD / RN2
56+
if (origin == "AOD") {
57+
if (description == "TRACK:PAR") {
58+
return columnNamesTrait(typename StoredTracksMetadata::table_t::persistent_columns_t{});
59+
} else if (description == "TRACK:PARCOV") {
60+
return columnNamesTrait(typename StoredTracksCovMetadata::table_t::persistent_columns_t{});
61+
} else if (description == "TRACK:EXTRA") {
62+
return columnNamesTrait(typename TracksExtraMetadata::table_t::persistent_columns_t{});
63+
}
64+
}
65+
66+
// default: column names = {}
67+
return std::vector<std::string>({});
68+
}
69+
70+
} // namespace o2::aod::datamodel

0 commit comments

Comments
 (0)