ATLAS Offline Software
Loading...
Searching...
No Matches
ColumnarToolArray.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7//
8// includes
9//
10
12
17
18//
19// method implementations
20//
21
22namespace columnar
23{
24 ColumnarToolArray ::
25 ColumnarToolArray (ColumnarToolArray* val_parent)
26 {
27 if (val_parent == nullptr)
28 {
29 m_data = std::make_shared<ColumnarToolDataArray> ();
30 m_data->mainTool = this;
31 m_data->sharedTools.push_back (this);
32
34
35 // this name matches the ContainerId::eventInfo::idName, make sure
36 // to keep them in sync. the reason for hard-coding this in two
37 // places is because ContainerId::eventInfo is defined in a separate
38 // package
39 setContainerUserName ("eventInfo", numberOfEventsName);
40 m_eventsData = std::make_unique<ColumnAccessorDataArray> (&m_eventsIndex, &m_eventsData, &typeid (ColumnarOffsetType), ColumnAccessMode::input);
41 addColumn (std::string (ContainerId::eventContext::idName), m_eventsData.get(), {.isOffset = true});
42 } else
43 {
44 m_data = val_parent->m_data;
45 m_data->sharedTools.push_back (this);
46
47 m_eventsData = std::make_unique<ColumnAccessorDataArray> (&m_eventsIndex, &m_eventsData, &typeid (ColumnarOffsetType), ColumnAccessMode::input);
48 addColumn (std::string (ContainerId::eventContext::idName), m_eventsData.get(), {.isOffset = true});
49 }
50 }
51
52
53
54 ColumnarToolArray ::
55 ~ColumnarToolArray ()
56 {
57 if (m_data->mainTool == this)
58 m_data->mainTool = nullptr;
59
60 auto iter = std::find (m_data->sharedTools.begin(), m_data->sharedTools.end(), this);
61 if (iter != m_data->sharedTools.end())
62 m_data->sharedTools.erase (iter);
63 }
64
65
66
67 void ColumnarToolArray ::
68 addSubtool (ColumnarToolArray& subtool)
69 {
70 // make a copy of the shared data for the subtool, so that I don't
71 // accidentally release it when resetting the shared data pointer on
72 // the subtool
73 auto subtoolData = subtool.m_data;
74
75 if (m_data == subtoolData)
76 return;
77
78 if (subtoolData->mainTool != &subtool)
79 throw std::runtime_error ("subtool already has a different parent tool");
80
81 for (auto& containerName : subtoolData->containerInternalToUserNames)
82 {
83 auto [iter,success] = m_data->containerInternalToUserNames.emplace (containerName.first, containerName.second);
84 if (!success && iter->second != containerName.second)
85 throw std::runtime_error ("container assigned different name in subtool: " + iter->second + " vs " + containerName.second);
86 if (success)
87 m_data->containerUserToInternalNames[containerName.second].push_back (containerName.first);
88 }
89 for (auto& columnName : subtoolData->columnInternalToUserNames)
90 {
91 auto [iter,success] = m_data->columnInternalToUserNames.emplace (columnName.first, columnName.second);
92 if (!success && iter->second != columnName.second)
93 throw std::runtime_error ("column assigned different name in subtool: " + iter->second + " vs " + columnName.second);
94 if (success)
95 m_data->columnUserToInternalNames[columnName.second].push_back (columnName.first);
96 }
97
98 for (auto& column : subtoolData->columns)
99 {
100 auto [iter,success] = m_data->columns.try_emplace (column.first, std::move (column.second));
101 if (!success)
102 iter->second.mergeData (column.first, std::move (column.second));
103 }
104
105 m_data->sharedTools.insert (m_data->sharedTools.end(), subtoolData->sharedTools.begin(), subtoolData->sharedTools.end());
106 for (auto& tool : subtoolData->sharedTools)
107 tool->m_data = m_data;
108 }
109
110
111
112 StatusCode ColumnarToolArray ::
113 initializeColumns ()
114 {
115 return StatusCode::SUCCESS;
116 }
117
118
119
120 std::vector<ColumnInfo> ColumnarToolArray ::
121 getColumnInfo () const
122 {
123 std::vector<std::pair<std::string,std::string>> names;
124 names.reserve (m_data->columns.size());
125 for (auto& [name, column] : m_data->columns)
126 {
127 if (!column.empty())
128 names.emplace_back (name, m_data->convertInternalToUserName (name));
129 }
130 std::sort (names.begin(), names.end(), [] (const auto& a, const auto& b) { return a.second < b.second; });
131
132 std::vector<ColumnInfo> result;
133 result.reserve (names.size());
134 for (auto& name : names)
135 {
136 auto& column = m_data->columns.at (name.first);
137 auto info = column.info();
138 info.name = name.second;
139 info.offsetName = m_data->convertInternalToUserName (info.offsetName);
140 info.replacesColumn = m_data->convertInternalToUserName (info.replacesColumn);
141 for (auto& targetName : info.linkTargetNames)
142 targetName = m_data->convertInternalToUserName (targetName);
143 info.variantLinkKeyColumn = m_data->convertInternalToUserName (info.variantLinkKeyColumn);
144 if (result.empty() || result.back().name != info.name)
145 result.push_back (std::move(info));
146 else
147 mergeColumnInfo (result.back(), info);
148 }
149 return result;
150 }
151
152
153
154 void ColumnarToolArray ::
155 renameColumn (const std::string& from, const std::string& to)
156 {
157 if (auto iter = m_data->columnUserToInternalNames.find (from);
158 iter != m_data->columnUserToInternalNames.end())
159 {
160 for (auto& internalName : iter->second)
161 m_data->columnInternalToUserNames[internalName] = to;
162 auto internalNames = iter->second;
163 m_data->columnUserToInternalNames.erase (iter);
164 m_data->columnUserToInternalNames[to].insert (m_data->columnUserToInternalNames[to].end(), internalNames.begin(), internalNames.end());
165 return;
166 }
167
168 auto internalNames = m_data->convertUserToInternalNames (from);
169 m_data->columnUserToInternalNames[to].insert (m_data->columnUserToInternalNames[to].end(), internalNames.begin(), internalNames.end());
170 for (auto& internalName : internalNames)
171 m_data->columnInternalToUserNames[internalName] = to;
172 }
173
174
175
176 void ColumnarToolArray ::
177 setColumnIndex (const std::string& name, std::size_t index)
178 {
179 auto internalNames = m_data->convertUserToInternalNames (name);
180 bool wasSet = false;
181 for (auto& internalName : internalNames)
182 {
183 if (auto column = m_data->columns.find (internalName);
184 column != m_data->columns.end())
185 {
186 column->second.setIndex (index);
187 wasSet = true;
188 }
189 }
190 if (!wasSet)
191 throw std::runtime_error ("column not found: " + name);
192 }
193
194
195
196 void ColumnarToolArray ::
197 setContainerUserName (std::string_view container, const std::string& name)
198 {
199 auto [iter, success] = m_data->containerInternalToUserNames.emplace (container, name);
200 if (!success && iter->second != name)
201 throw std::runtime_error ("container already registered with different name: " + name + " vs " + iter->second);
202 m_data->containerUserToInternalNames[name].emplace_back (container);
203 }
204
205
206
207 void ColumnarToolArray ::
208 addColumn (const std::string& name, ColumnAccessorDataArray *accessorData, ColumnInfo&& info)
209 {
210 info.type = accessorData->type;
211 info.accessMode = accessorData->accessMode;
212
213 m_data->columns[name].addAccessor (name, info, accessorData);
214 }
215
216
217
218 ColumnDataArray ::
219 ColumnDataArray (ColumnDataArray&& other) noexcept
220 : m_info (std::move (other.m_info))
221 , m_accessors (std::move (other.m_accessors))
222 {
223 for (auto *ptr : m_accessors)
224 {
225 if (ptr->dataRef == &other)
226 ptr->dataRef = this;
227 }
228 }
229
230
231
232 ColumnDataArray ::
233 ~ColumnDataArray () noexcept
234 {
235 for (auto *ptr : m_accessors)
236 {
237 if (ptr->dataRef == this)
238 ptr->dataRef = nullptr;
239 }
240 }
241
242
243
244 bool ColumnDataArray ::
245 empty () const noexcept
246 {
247 return m_accessors.empty();
248 }
249
250
251
252 const ColumnInfo& ColumnDataArray ::
253 info () const noexcept
254 {
255 return m_info;
256 }
257
258
259
260 void ColumnDataArray ::
261 addAccessor (const std::string& name, const ColumnInfo& val_info, ColumnAccessorDataArray* val_accessorData)
262 {
263 if (m_accessors.empty())
264 {
265 m_info = val_info;
266
267 // ensure that any index is not zero. zero is reserved for a
268 // nullptr, so that if an index has never been initialized, we
269 // get a segfault on access.
270 m_info.index = 0;
271 } else
272 {
273 if (val_info.type != m_info.type)
274 throw std::runtime_error ("multiple types for column: " + name);
276 m_info.accessMode = ColumnAccessMode::update;
277 else if (m_info.accessMode == ColumnAccessMode::output || val_info.accessMode == ColumnAccessMode::output)
278 m_info.accessMode = ColumnAccessMode::output;
279 if (!val_info.isOptional)
280 m_info.isOptional = false;
281 if (val_info.offsetName != m_info.offsetName)
282 throw std::runtime_error ("inconsistent offset map for column: " + name);
283 }
284
285 if (val_accessorData)
286 {
287 m_accessors.push_back (val_accessorData);
288 val_accessorData->dataRef = this;
289 }
290 }
291
292
293
294 void ColumnDataArray ::
295 removeAccessor (ColumnAccessorDataArray& val_accessorData)
296 {
297 auto iter = std::find (m_accessors.begin(), m_accessors.end(), &val_accessorData);
298 if (iter == m_accessors.end())
299 return;
300 m_accessors.erase (iter);
301 val_accessorData.dataRef = nullptr;
302 }
303
304
305
306 void ColumnDataArray ::
307 mergeData (const std::string& name, ColumnDataArray&& other)
308 {
309 mergeColumnInfo (m_info, other.m_info);
310 addAccessor (name, other.m_info, nullptr);
311 m_accessors.insert (m_accessors.end(), other.m_accessors.begin(), other.m_accessors.end());
312 for (auto *ptr : other.m_accessors)
313 ptr->dataRef = this;
314 other.m_accessors.clear();
315 }
316
317
318
319 void ColumnDataArray ::
320 setIndex (unsigned index) noexcept
321 {
322 m_info.index = index;
323 for (auto *ptr : m_accessors)
324 *ptr->dataIndexPtr = index;
325 }
326
327
328
329 std::string ColumnarToolDataArray ::
330 convertInternalToUserName (std::string_view name) const
331 {
332 if (name.empty())
333 return std::string{};
334 if (auto iter = columnInternalToUserNames.find (name);
335 iter != columnInternalToUserNames.end())
336 return iter->second;
337 auto split = name.find ('.');
338 if (split == std::string::npos)
339 split = name.size();
340 auto containerName = name.substr (0, split);
341 auto iter = containerInternalToUserNames.find (containerName);
342 if (iter == containerInternalToUserNames.end())
343 return std::string (name);
344 return iter->second + std::string (name.substr (split));
345 }
346
347
348
349 std::vector<std::string> ColumnarToolDataArray ::
350 convertUserToInternalNames (std::string_view name) const
351 {
352 if (auto iter = columnUserToInternalNames.find (name);
353 iter != columnUserToInternalNames.end())
354 return iter->second;
355 auto split = name.find ('.');
356 if (split == std::string::npos)
357 split = name.size();
358 auto containerName = name.substr (0, split);
359 auto iter = containerUserToInternalNames.find (containerName);
360 if (iter == containerUserToInternalNames.end())
361 return {std::string (name)};
362 std::vector<std::string> result;
363 for (auto& internalContainerName : iter->second)
364 result.push_back (internalContainerName + std::string (name.substr (split)));
365 if (result.empty())
366 result.push_back (std::string (name));
367 return result;
368 }
369}
static Double_t a
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
CONT to(RANGE &&r)
Definition ranges.h:39
::StatusCode StatusCode
StatusCode definition for legacy code.
void mergeColumnInfo(ColumnInfo &target, const ColumnInfo &source)
const std::string numberOfEventsName
the name used for the column containing the number of events
@ update
an updateable column
Definition ColumnInfo.h:27
@ output
an output column
Definition ColumnInfo.h:24
@ input
an input column
Definition ColumnInfo.h:21
std::size_t ColumnarOffsetType
the type used for the size and offsets in the columnar data
Definition index.py:1
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
all the data about a column accessor that the ColumnarTool needs to know about
ColumnDataArray * dataRef
the ColumnDataArray object that holds us
ColumnDataArray() noexcept=default
standard constructor
std::vector< ColumnAccessorDataArray * > m_accessors
the data on all accessors for this column
ColumnInfo m_info
the column info
void addAccessor(const std::string &name, const ColumnInfo &val_info, ColumnAccessorDataArray *val_accessorData)
add an info to the column
a struct that contains meta-information about each column that's needed to interface the column with ...
Definition ColumnInfo.h:35
std::string offsetName
the name of the offset column used for this column (or empty string for none)
Definition ColumnInfo.h:74
bool isOptional
whether this column is optional
Definition ColumnInfo.h:121
ColumnAccessMode accessMode
the access mode for the column
Definition ColumnInfo.h:58
const std::type_info * type
the type of the individual entries in the column
Definition ColumnInfo.h:54
std::unordered_map< std::string, std::string, StringHash, std::equal_to<> > containerInternalToUserNames
the names associated with all container ids
std::unordered_map< std::string, std::vector< std::string >, StringHash, std::equal_to<> > columnUserToInternalNames
std::unordered_map< std::string, std::vector< std::string >, StringHash, std::equal_to<> > containerUserToInternalNames
std::unordered_map< std::string, std::string, StringHash, std::equal_to<> > columnInternalToUserNames
an extra map, for mapping individual column names
static constexpr std::string_view idName