ATLAS Offline Software
Loading...
Searching...
No Matches
ColumnReaderRNTuple.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7//
8// includes
9//
10
12
16
17#include <ROOT/RNTupleReader.hxx>
18#include <ROOT/RNTupleInspector.hxx>
19
20//
21// method implementations
22//
23
24namespace columnar
25{
26 namespace TestUtils
27 {
28 template <typename T>
29 class RNTFieldReader final
30 {
31 std::string m_FieldName;
32 std::unique_ptr<ROOT::RNTupleView<T>> m_view;
33 ROOT::Experimental::RNTupleInspector* m_inspector = nullptr;
34 ROOT::RNTupleReader* m_reader = nullptr;
35 const T* m_data = nullptr;
36
37 public:
38 RNTFieldReader(const std::string& val_fieldName)
39 : m_FieldName(val_fieldName)
40 {}
41
42 ~RNTFieldReader() noexcept {}
45
46 [[nodiscard]] const std::string& fieldName() const
47 {
48 return m_FieldName;
49 }
50
51 [[nodiscard]] std::string columnName() const
52 {
53 std::string columnName = m_FieldName;
54 if (auto index = columnName.find("AuxDyn:"); index != std::string::npos)
55 columnName.replace(index, 6, "");
56 else if (auto index = columnName.find("Aux:."); index != std::string::npos)
57 columnName.replace(index, 4, "");
58 else if (auto index = columnName.find("Aux:"); index != std::string::npos)
59 columnName.replace(index, 3, "");
60 else if (columnName.find(":") != std::string::npos)
61 throw std::runtime_error("field name does not contain AuxDyn or Aux: " + m_FieldName);
62 std::replace(columnName.begin(), columnName.end(), ':', '.');
63
64 return columnName;
65 }
66
67 [[nodiscard]] std::string containerName() const
68 {
69 if (auto index = m_FieldName.find("AuxDyn:"); index != std::string::npos)
70 return m_FieldName.substr(0, index);
71 else if (auto index = m_FieldName.find("Aux:"); index != std::string::npos)
72 return m_FieldName.substr(0, index);
73 else if (m_FieldName.find(":") == std::string::npos)
74 return m_FieldName;
75 else
76 throw std::runtime_error("field name does not contain AuxDyn or Aux: " + m_FieldName);
77 }
78
79 void connectRNTuple(ROOT::RNTupleReader* reader,
80 ROOT::Experimental::RNTupleInspector* inspector)
81 {
82 m_inspector = inspector;
83 m_reader = reader;
84 m_view = std::make_unique<ROOT::RNTupleView<T>>(reader->GetView<T>(m_FieldName));
85
86 if (!m_view)
87 throw std::runtime_error("failed to get field: " + m_FieldName);
88 }
89
90 void connectTree(const Backend& b)
91 {
92 auto* rntbackend = std::get<RNTupleBackend*>(b); // throws if wrong backend
93
94 if (!rntbackend->reader || !rntbackend->inspector)
95 throw std::runtime_error("RNTuple backend not properly initialized");
96 connectRNTuple(rntbackend->reader, rntbackend->inspector);
97 }
98
99
100 const T& getEntry(Long64_t entry)
101 {
102 if (!m_view)
103 throw std::runtime_error("field not connected: " + m_FieldName);
104
105 m_data = &((*m_view)(static_cast<ROOT::NTupleSize_t>(entry)));
106
107 if (m_data == nullptr)
108 throw std::runtime_error("got nullptr reading data for field: " + m_FieldName);
109 return *m_data;
110 }
111
112 const T& getCachedEntry() const
113 {
114 return *m_data;
115 }
116
117 std::optional<float> entrySize() const
118 {
119
120 const ROOT::Experimental::RNTupleInspector::RFieldTreeInspector& fieldTreeInspector = m_inspector->GetFieldTreeInspector(m_FieldName);
121 return static_cast<float>(fieldTreeInspector.GetCompressedSize()) /
122 m_inspector->GetDescriptor().GetNEntries();
123 }
124
125 std::optional<float> uncompressedSize() const
126 {
127
128 const ROOT::Experimental::RNTupleInspector::RFieldTreeInspector& fieldTreeInspector = m_inspector->GetFieldTreeInspector(m_FieldName);
129
130 return static_cast<float>(fieldTreeInspector.GetUncompressedSize()) /
131 m_inspector->GetDescriptor().GetNEntries();
132 }
133
134 std::optional<unsigned> numBaskets()
135 {
136 // placeholder
137 return std::nullopt;
138 }
139 };
140
141 void makeRNTupleColumnReaders (std::vector<std::shared_ptr<TestUtils::ColumnReader>>& knownColumns, RNTupleBackend* rntbackend)
142 {
143 std::unordered_map<std::string, ROOT::DescriptorId_t> fields;
144 {
145 const auto& desc = rntbackend->reader->GetDescriptor();
146
147 for (const auto& field : desc.GetTopLevelFields())
148 {
149 fields.emplace(desc.GetQualifiedFieldName(field.GetId()), field.GetId());
150
151 std::vector<ROOT::DescriptorId_t> subFieldIds{field.GetId()};
152 while (!subFieldIds.empty())
153 {
154 const auto parentId = subFieldIds.back();
155 auto parentname=desc.GetQualifiedFieldName(parentId);
156 subFieldIds.pop_back();
157
158 for (const auto& subField : desc.GetFieldIterable(parentId))
159 {
160 auto subFieldName = desc.GetQualifiedFieldName(subField.GetId());
161
162 fields.emplace(desc.GetQualifiedFieldName(subField.GetId()), subField.GetId());
163
164 subFieldIds.push_back(subField.GetId());
165 }
166 }
167 }
168 }
169
170 const auto& desc = rntbackend->reader->GetDescriptor();
171 for (const auto& [name, fieldId] : fields)
172 {
173 auto fieldName = desc.GetQualifiedFieldName(fieldId);
174
175 if (name.find("AuxDyn:") != std::string::npos ||
176 name.find("Aux:") != std::string::npos)
177 {
178
179 const auto& fieldDesc = desc.GetFieldDescriptor(fieldId);
180 const std::string typeName = desc.GetTypeNameForComparison(fieldDesc);
181 if (typeName == "std::int32_t" || typeName == "int")
182 {
183 knownColumns.push_back(std::make_shared<ColumnReaderScalar<std::int32_t, RNTFieldReader>>(name));
184 } else if (typeName == "std::uint32_t" || typeName == "unsigned int")
185 {
186 knownColumns.push_back(std::make_shared<ColumnReaderScalar<std::uint32_t, RNTFieldReader>>(name));
187 } else if (typeName == "std::uint64_t" || typeName == "unsigned long" || typeName == "unsigned long long")
188 {
189 knownColumns.push_back(std::make_shared<ColumnReaderScalar<std::uint64_t, RNTFieldReader>>(name));
190 } else if (typeName == "float")
191 {
192 knownColumns.push_back(std::make_shared<ColumnReaderScalar<float, RNTFieldReader>>(name));
193 } else if (typeName == "std::vector<float>")
194 {
195 knownColumns.push_back(std::make_shared<ColumnReaderVector<float, RNTFieldReader>>(name));
196 } else if (typeName == "std::vector<char>")
197 {
198 knownColumns.push_back(std::make_shared<ColumnReaderVector<char, RNTFieldReader>>(name));
199 } else if (typeName == "std::vector<std::int8_t>")
200 {
201 knownColumns.push_back(std::make_shared<ColumnReaderVector<std::int8_t, RNTFieldReader>>(name));
202 } else if (typeName == "std::vector<std::uint8_t>")
203 {
204 knownColumns.push_back(std::make_shared<ColumnReaderVector<std::uint8_t, RNTFieldReader>>(name));
205 } else if (typeName == "std::vector<std::int16_t>")
206 {
207 knownColumns.push_back(std::make_shared<ColumnReaderVector<std::int16_t, RNTFieldReader>>(name));
208 } else if (typeName == "std::vector<std::uint16_t>")
209 {
210 knownColumns.push_back(std::make_shared<ColumnReaderVector<std::uint16_t, RNTFieldReader>>(name));
211 } else if (typeName == "std::vector<std::int32_t>")
212 {
213 knownColumns.push_back(std::make_shared<ColumnReaderVector<std::int32_t, RNTFieldReader>>(name));
214 } else if (typeName == "std::vector<std::uint32_t>")
215 {
216 knownColumns.push_back(std::make_shared<ColumnReaderVector<std::uint32_t, RNTFieldReader>>(name));
217 } else if (typeName == "std::vector<std::int64_t>")
218 {
219 knownColumns.push_back(std::make_shared<ColumnReaderVector<std::int64_t, RNTFieldReader>>(name));
220 } else if (typeName == "std::vector<std::uint64_t>")
221 {
222 knownColumns.push_back(std::make_shared<ColumnReaderVector<std::uint64_t, RNTFieldReader>>(name));
223 } else if (typeName == "std::vector<std::vector<float>>")
224 {
225 knownColumns.push_back(std::make_shared<ColumnReaderVectorVector<float, RNTFieldReader>>(name));
226 } else if (typeName == "std::vector<std::vector<std::int32_t>>")
227 {
228 knownColumns.push_back(std::make_shared<ColumnReaderVectorVector<std::int32_t, RNTFieldReader>>(name));
229 } else if (typeName == "std::vector<std::vector<std::uint64_t>>")
230 {
231 knownColumns.push_back(std::make_shared<ColumnReaderVectorVector<std::uint64_t, RNTFieldReader>>(name));
232 } else if (typeName =="std::vector<std::vector<std::vector<std::size_t>>>")
233 {
234 knownColumns.push_back(std::make_shared<ColumnReaderVectorVectorVector<std::size_t, RNTFieldReader>>(name));
235 }else if (typeName =="std::vector<std::vector<std::vector<std::uint64_t>>>")
236 {
237 knownColumns.push_back(std::make_shared<ColumnReaderVectorVectorVector<std::uint64_t, RNTFieldReader>>(name));
238 }else if (typeName =="std::vector<std::vector<std::vector<std::uint8_t>>>")
239 {
240 knownColumns.push_back(std::make_shared<ColumnReaderVectorVectorVector<std::uint8_t, RNTFieldReader>>(name));
241 } else if (typeName =="std::vector<std::vector<std::vector<unsigned char>>>")
242 {
243 knownColumns.push_back(std::make_shared<ColumnReaderVectorVectorVector<unsigned char, RNTFieldReader>>(name));
244 } else if (typeName == "std::vector<std::string>")
245 {
246 knownColumns.push_back(std::make_shared<ColumnReaderMetNames<RNTFieldReader>>(name));
247 }
248 }
249 }
250 knownColumns.push_back(std::make_shared<ColumnReaderSamplingPattern<RNTFieldReader>>("egammaClusters"));
251
252 knownColumns.push_back(std::make_shared<ColumnReaderVectorVectorLink<xAOD::CaloClusterContainer,RNTFieldReader>>("AnalysisElectronsAuxDyn:caloClusterLinks"));
253 knownColumns.push_back(std::make_shared<ColumnReaderVectorVectorLink<xAOD::TrackParticleContainer, RNTFieldReader>>("AnalysisElectronsAuxDyn:trackParticleLinks"));
254 knownColumns.push_back(std::make_shared<ColumnReaderVectorVectorLink<xAOD::CaloClusterContainer,RNTFieldReader>>("AnalysisPhotonsAuxDyn:caloClusterLinks"));
255 knownColumns.push_back(std::make_shared<ColumnReaderVectorVectorLink<xAOD::VertexContainer, RNTFieldReader>>("AnalysisPhotonsAuxDyn:vertexLinks"));
256 knownColumns.push_back(std::make_shared<ColumnReaderVectorRLink<xAOD::TrackParticleContainer,RNTFieldReader>>("AnalysisMuonsAuxDyn:inDetTrackParticleLink"));
257 knownColumns.push_back(std::make_shared<ColumnReaderVectorRLink<xAOD::TrackParticleContainer,RNTFieldReader>>("AnalysisMuonsAuxDyn:combinedTrackParticleLink"));
258 knownColumns.push_back(std::make_shared<ColumnReaderVectorRLink< xAOD::TrackParticleContainer, RNTFieldReader>>("AnalysisMuonsAuxDyn:extrapolatedMuonSpectrometerTrackParticleLink"));
259 knownColumns.push_back(std::make_shared<ColumnReaderVectorVectorLink<xAOD::TrackParticleContainer, RNTFieldReader>>("GSFConversionVerticesAuxDyn:trackParticleLinks"));
260 knownColumns.push_back(std::make_shared<ColumnReaderVectorRLink<xAOD::TrackParticleContainer,RNTFieldReader>>("GSFTrackParticlesAuxDyn:originalTrackParticle"));
261 knownColumns.push_back(std::make_shared<ColumnReaderVectorVectorVariantLink<xAOD::IParticleContainer, RNTFieldReader>>("AnalysisJetsAuxDyn:GhostTrack"));
262 knownColumns.push_back(std::make_shared<ColumnReaderVectorLink<xAOD::JetContainer, RNTFieldReader>>("METAssoc_AnalysisMETAux:.jetLink"));
263 knownColumns.push_back(std::make_shared<ColumnReaderVectorVectorVariantLink<xAOD::IParticleContainer, RNTFieldReader>>("METAssoc_AnalysisMETAux:.objectLinks"));
264 }
265 }
266}
RNTFieldReader(const RNTFieldReader &)=delete
ROOT::Experimental::RNTupleInspector * m_inspector
void connectRNTuple(ROOT::RNTupleReader *reader, ROOT::Experimental::RNTupleInspector *inspector)
std::optional< float > entrySize() const
const std::string & fieldName() const
std::optional< float > uncompressedSize() const
RNTFieldReader & operator=(const RNTFieldReader &)=delete
std::unique_ptr< ROOT::RNTupleView< T > > m_view
RNTFieldReader(const std::string &val_fieldName)
std::variant< TTree *, RNTupleBackend * > Backend
void makeRNTupleColumnReaders(std::vector< std::shared_ptr< TestUtils::ColumnReader > > &knownColumns, RNTupleBackend *rntbackend)
Definition index.py:1