ATLAS Offline Software
Loading...
Searching...
No Matches
ColumnReaderImp.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#include <xAODBase/ObjectType.h>
18
19//
20// method implementations
21//
22
23namespace columnar
24{
25 namespace TestUtils
26 {
28 {
29 std::array<ColumnarOffsetType, 2> data = {0, 0};
30
32 {
33 outputColumns.push_back ({.name = eventRangeColumnName, .isOffset = true});
34 }
35
36 virtual bool connect(Backend /*source*/, std::unordered_map<std::string,const std::vector<ColumnarOffsetType>*>& /*offsetColumns*/,std::unordered_map<std::string, ColumnInfo>& requestedColumns) override
37 {
38 if (requestedColumns.contains(outputColumns.at(0).name))
39 {
40 requestedColumns.erase(outputColumns.at(0).name);
41 outputColumns.at(0).enabled = true;
42 return true;
43 }
44 return false;
45 }
46 virtual void clearColumns () override
47 {
48 data[0] = 0;
49 data[1] = 0;
50 }
51
52 virtual void getEntry (Long64_t /*entry*/) override
53 {
54 data[1] += 1;
55 }
56
57 virtual void setData (ColumnVectorData& columnData) override
58 {
59 if (outputColumns.at(0).columnIndex != ColumnVectorHeader::nullIndex)
60 columnData.setColumn (outputColumns.at(0).columnIndex, data.size(), data.data());
61 }
62
63 [[nodiscard]] virtual BranchPerfData getPerfData (float /*emptyTime*/) override
64 {
65 BranchPerfData result;
66 result.name = "EventCount(auto)";
67 return result;
68 }
69
70 virtual void collectColumnData () override
71 {}
72 };
73
74 template <typename T>
76 {
78 const std::vector<ColumnarOffsetType>* offsetColumn = nullptr;
79 std::vector<T> outData;
80 unsigned entries = 0;
81
82 ColumnReaderOutVector (const std::string& val_columnName, const T& val_defaultValue)
83 : defaultValue (val_defaultValue)
84 {
85 outputColumns.push_back ({.name = val_columnName});
86 }
87
88 virtual bool connect(Backend /*source*/, std::unordered_map<std::string, const std::vector<ColumnarOffsetType>*>& offsetColumns, std::unordered_map<std::string, ColumnInfo>& requestedColumns) override
89 {
90 auto iter = requestedColumns.find (outputColumns.at(0).name);
91 if (iter == requestedColumns.end())
92 return false;
93 outputColumns.at(0).enabled = true;
94
95 const auto & offsetName = iter->second.offsetName;
96 if (offsetName.empty())
97 throw std::runtime_error ("missing offset column for: " + outputColumns.at(0).name);
98
99 if (auto offsetIter = offsetColumns.find (offsetName); offsetIter != offsetColumns.end())
100 offsetColumn = offsetIter->second;
101 else
102 throw std::runtime_error ("missing offset column for: " + outputColumns.at(0).name + " (offset column: " + offsetName + ")");
103
104 // IMPORTANT: This has to be erased at the end of the function,
105 // since erasing it earlier would invalidate the offsetName
106 // reference.
107 requestedColumns.erase (iter);
108 return true;
109 }
110
111 virtual void clearColumns () override
112 {
113 outData.clear ();
114 }
115
116 virtual void getEntry (Long64_t /*entry*/) override
117 {
118 outData.resize (offsetColumn->back(), defaultValue);
119 }
120
121 virtual void setData (ColumnVectorData& columnData) override
122 {
123 if (outputColumns.at(0).columnIndex != ColumnVectorHeader::nullIndex)
124 columnData.setColumn (outputColumns.at(0).columnIndex, outData.size(), outData.data());
125 }
126
127 [[nodiscard]] virtual BranchPerfData getPerfData (float /*emptyTime*/) override
128 {
129 BranchPerfData result;
130 result.name = outputColumns.at(0).name + "(out)";
131 result.entries = entries;
132 return result;
133 }
134
135 virtual void collectColumnData () override
136 {
137 entries += outData.size();
138 }
139 };
140
142 {
143 std::vector<std::string> termNames;
144 const std::vector<ColumnarOffsetType>* offsetColumns = nullptr;
145 std::vector<ColumnarOffsetType> offsets = {0};
146 std::vector<ColumnarOffsetType> namesOffsets = {0};
147 std::vector<char> namesData;
148 std::vector<std::size_t> namesHash;
149
150 ColumnReaderOutputMet (const std::string& val_columnName, std::vector<std::string> val_termNames)
151 : termNames (std::move (val_termNames))
152 {
153 outputColumns.push_back ({.name = val_columnName, .isOffset = true});
154 outputColumns.push_back ({.name = val_columnName + ".name.data"});
155 outputColumns.push_back ({.name = val_columnName + ".name.offset", .isOffset = true});
156 outputColumns.push_back ({.name = val_columnName + ".nameHash"});
157 }
158
159 virtual bool connect([[maybe_unused]]Backend source, std::unordered_map<std::string, const std::vector<ColumnarOffsetType>*>& offsetColumns, std::unordered_map<std::string, ColumnInfo>& requestedColumns) override
160 {
161 if (auto iter = requestedColumns.find (outputColumns.at(0).name);
162 iter != requestedColumns.end())
163 requestedColumns.erase (iter);
164 else
165 return false;
166 outputColumns.at(0).enabled = true;
167
168 if (auto iter = requestedColumns.find (outputColumns.at(1).name);
169 iter != requestedColumns.end())
170 {
171 outputColumns.at(1).enabled = true;
172 requestedColumns.erase (iter);
173 }
174
175 if (auto iter = requestedColumns.find (outputColumns.at(2).name);
176 iter != requestedColumns.end())
177 {
178 outputColumns.at(2).enabled = true;
179 requestedColumns.erase (iter);
180 }
181
182 if (auto iter = requestedColumns.find (outputColumns.at(3).name);
183 iter != requestedColumns.end())
184 {
185 outputColumns.at(3).enabled = true;
186 requestedColumns.erase (iter);
187 }
188
189 // For multi-tool support, skip if offset column already registered
190 if (auto offsetIter = offsetColumns.find (outputColumns.at(0).name); offsetIter == offsetColumns.end())
191 offsetColumns.emplace (outputColumns.at(0).name, &offsets);
192
193 return true;
194 }
195
196 virtual void clearColumns () override
197 {
198 offsets.clear ();
199 offsets.push_back (0);
200 namesData.clear ();
201 namesOffsets.clear ();
202 namesOffsets.push_back (0);
203 namesHash.clear ();
204 }
205
206 virtual void getEntry (Long64_t /*entry*/) override
207 {
208 for (const auto& termName : termNames)
209 {
210 namesData.insert (namesData.end(), termName.begin(), termName.end());
211 namesOffsets.push_back (namesData.size());
212 namesHash.push_back (std::hash<std::string> () (termName));
213 }
214 offsets.push_back (namesHash.size());
215 }
216
217 virtual void setData (ColumnVectorData& colData) override
218 {
219 if (outputColumns.at(0).columnIndex != ColumnVectorHeader::nullIndex)
220 colData.setColumn (outputColumns.at(0).columnIndex, offsets.size(), offsets.data());
221 if (outputColumns.at(1).columnIndex != ColumnVectorHeader::nullIndex)
222 colData.setColumn (outputColumns.at(1).columnIndex, namesData.size(), namesData.data());
223 if (outputColumns.at(2).columnIndex != ColumnVectorHeader::nullIndex)
224 colData.setColumn (outputColumns.at(2).columnIndex, namesOffsets.size(), namesOffsets.data());
225 if (outputColumns.at(3).columnIndex != ColumnVectorHeader::nullIndex)
226 colData.setColumn (outputColumns.at(3).columnIndex, namesHash.size(), namesHash.data());
227 }
228
229 [[nodiscard]] virtual BranchPerfData getPerfData (float /*emptyTime*/) override
230 {
231 BranchPerfData result;
232 result.name = outputColumns.at(0).name + "(met-out)";
233 return result;
234 }
235
236 virtual void collectColumnData () override
237 {}
238 };
239
240
241
242 void makeCommonColumnReaders (std::vector<std::shared_ptr<TestUtils::ColumnReader>>& knownColumns)
243 {
244 knownColumns.push_back (std::make_shared<ColumnReaderEventCount> ());
245 }
246
247 void makeCommonLateColumnReaders (std::vector<std::shared_ptr<TestUtils::ColumnReader>>& knownColumns, const std::vector<std::string>& allMetTermNames)
248 {
249 if (!allMetTermNames.empty())
250 knownColumns.push_back(std::make_shared<ColumnReaderOutputMet>("OutputMET",allMetTermNames));
251
252 // For METMaker we need various extra columns to run. This may need
253 // some work to avoid, but would likey be worth it.
254 knownColumns.push_back(std::make_shared<ColumnReaderOutVector<std::uint16_t>>("AnalysisMuons.objectType", xAOD::Type::Muon));
255 knownColumns.push_back(std::make_shared<ColumnReaderOutVector<float>>("AnalysisMuons.m", ParticleConstants::muonMassInMeV));
256 knownColumns.push_back(std::make_shared<ColumnReaderOutVector<std::uint16_t>>("AnalysisJets.objectType", xAOD::Type::Jet));
257
258 // These are columns that represent variables that are normally held
259 // by METAssociationHelper, or alternatively are decorated on the
260 // MET terms (even though they are per object).
261 knownColumns.push_back(std::make_shared<ColumnReaderOutVector<float>>("AnalysisMuons.MetObjectWeight", 0));
262 knownColumns.push_back(std::make_shared<ColumnReaderOutVector<float>>("AnalysisJets.MetObjectWeight", 0));
263 knownColumns.push_back(std::make_shared<ColumnReaderOutVector<float>>("AnalysisJets.MetObjectWeightSoft", 0));
264 knownColumns.push_back(std::make_shared<ColumnReaderOutVector<MissingETBase::Types::bitmask_t>>("METAssoc_AnalysisMET.useObjectFlags", 0));
265 }
266
267 void makeOutputColumnReaders (std::vector<std::shared_ptr<TestUtils::ColumnReader>>& knownColumns, const ColumnVectorHeader& columnHeader)
268 {
269 using namespace asg::msgUserCode;
270
271 // Get all column info directly from the header (all tools have already
272 // registered their columns via ToolColumnVectorMap)
273 auto requestedColumns = columnHeader.getAllColumnInfo();
274
275 for (auto& [name, info] : requestedColumns)
276 {
277 if (info.accessMode != ColumnAccessMode::output || !info.fixedDimensions.empty())
278 continue;
279 auto offsetIter = requestedColumns.find(info.offsetName);
280 if (offsetIter == requestedColumns.end() || offsetIter->second.offsetName != eventRangeColumnName)
281 {
282 ANA_MSG_WARNING ("skipping column {} as it is not a scalar decoration on a global container", name);
283 continue;
284 }
285 std::shared_ptr<TestUtils::ColumnReader> myColumn;
286 if (*info.type == typeid(float))
287 myColumn = std::make_shared<TestUtils::ColumnReaderOutVector<float>>(info.name, 0);
288 else if (*info.type == typeid(char))
289 myColumn = std::make_shared<TestUtils::ColumnReaderOutVector<char>>(info.name, 0);
290 else if (*info.type == typeid(std::uint16_t))
291 myColumn = std::make_shared<TestUtils::ColumnReaderOutVector<std::uint16_t>>(info.name, 0);
292 else if (*info.type == typeid(std::uint64_t))
293 myColumn = std::make_shared<TestUtils::ColumnReaderOutVector<std::uint64_t>>(info.name, 0);
294 else
295 {
296 ANA_MSG_WARNING("unhandled column type: " << info.name << " "<< info.type->name());
297 continue;
298 }
299 knownColumns.push_back(myColumn);
300 }
301 }
302 }
303}
macros for messaging and checking status codes
#define ANA_MSG_WARNING(xmsg,...)
Macro printing warning messages.
A number of constexpr particle constants to avoid hardcoding them directly in various places.
a class that holds the columnar data for a single call
void setColumn(std::size_t columnIndex, std::size_t size, CT *dataPtr)
set the data for the given column
the header information for the entire columnar data vector
static constexpr std::size_t nullIndex
the index used for an invalid index (always has to be 0)
std::unordered_map< std::string, ColumnInfo > getAllColumnInfo() const
get all columns as a map of ColumnInfo for use with IColumnData::connect
std::vector< OutputColumnInfo > outputColumns
constexpr double muonMassInMeV
the mass of the muon (in MeV)
std::variant< TTree *, RNTupleBackend * > Backend
void makeCommonColumnReaders(std::vector< std::shared_ptr< TestUtils::ColumnReader > > &knownColumns)
void makeCommonLateColumnReaders(std::vector< std::shared_ptr< TestUtils::ColumnReader > > &knownColumns, const std::vector< std::string > &allMetTermNames)
void makeOutputColumnReaders(std::vector< std::shared_ptr< TestUtils::ColumnReader > > &knownColumns, const ColumnVectorHeader &columnHeader)
@ output
an output column
Definition ColumnInfo.h:25
const std::string eventRangeColumnName
the default name for the column containing the event range
STL namespace.
@ Jet
The object is a jet.
Definition ObjectType.h:40
@ Muon
The object is a muon.
Definition ObjectType.h:48
the performance data for reading a single branch/column
std::array< ColumnarOffsetType, 2 > data
virtual void setData(ColumnVectorData &columnData) override
virtual void getEntry(Long64_t) override
virtual bool connect(Backend, std::unordered_map< std::string, const std::vector< ColumnarOffsetType > * > &, std::unordered_map< std::string, ColumnInfo > &requestedColumns) override
virtual BranchPerfData getPerfData(float) override
virtual BranchPerfData getPerfData(float) override
virtual bool connect(Backend, std::unordered_map< std::string, const std::vector< ColumnarOffsetType > * > &offsetColumns, std::unordered_map< std::string, ColumnInfo > &requestedColumns) override
virtual void getEntry(Long64_t) override
virtual void setData(ColumnVectorData &columnData) override
ColumnReaderOutVector(const std::string &val_columnName, const T &val_defaultValue)
const std::vector< ColumnarOffsetType > * offsetColumn
const std::vector< ColumnarOffsetType > * offsetColumns
virtual void getEntry(Long64_t) override
virtual bool connect(Backend source, std::unordered_map< std::string, const std::vector< ColumnarOffsetType > * > &offsetColumns, std::unordered_map< std::string, ColumnInfo > &requestedColumns) override
std::vector< ColumnarOffsetType > namesOffsets
std::vector< ColumnarOffsetType > offsets
virtual BranchPerfData getPerfData(float) override
ColumnReaderOutputMet(const std::string &val_columnName, std::vector< std::string > val_termNames)
virtual void setData(ColumnVectorData &colData) override