Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 
16 
17 //
18 // method implementations
19 //
20 
21 namespace columnar
22 {
23  ColumnarTool<ColumnarModeArray> ::
24  ColumnarTool ()
25  : m_data (std::make_shared<ColumnarToolDataArray> ())
26  {
27  m_data->mainTool = this;
28  m_data->sharedTools.push_back (this);
29 
31  setContainerName (ContainerId::eventInfo, numberOfEventsName);
32  m_eventsData = std::make_unique<ColumnAccessorDataArray> (&m_eventsIndex, &m_eventsData, &typeid (ColumnarOffsetType), ColumnAccessMode::input);
33  addColumn (numberOfEventsName, m_eventsData.get(), {.isOffset = true});
34  }
35 
36  ColumnarTool<ColumnarModeArray> ::
37  ColumnarTool (ColumnarTool<ColumnarModeArray>* val_parent)
38  : m_data (val_parent->m_data)
39  {
40  m_eventsData = std::make_unique<ColumnAccessorDataArray> (&m_eventsIndex, &m_eventsData, &typeid (ColumnarOffsetType), ColumnAccessMode::input);
41  addColumn (numberOfEventsName, m_eventsData.get(), {.isOffset = true});
42  }
43 
44  ColumnarTool<ColumnarModeArray> ::
45  ~ColumnarTool ()
46  {
47  if (m_data->mainTool == this)
48  m_data->mainTool = nullptr;
49 
50  auto iter = std::find (m_data->sharedTools.begin(), m_data->sharedTools.end(), this);
51  if (iter != m_data->sharedTools.end())
52  m_data->sharedTools.erase (iter);
53  }
54 
55  void ColumnarTool<ColumnarModeArray> ::
56  addSubtool (ColumnarTool<ColumnarModeArray>& subtool)
57  {
58  // make a copy of the shared data for the subtool, so that I don't
59  // accidentally release it when resetting the shared data pointer on
60  // the subtool
61  auto subtoolData = subtool.m_data;
62 
63  if (m_data == subtoolData)
64  return;
65 
66  if (subtoolData->mainTool != &subtool)
67  throw std::runtime_error ("subtool already has a different parent tool");
68 
69  for (auto& containerName : subtoolData->containerNames)
70  {
71  auto [iter,success] = m_data->containerNames.emplace (containerName.first, containerName.second);
72  if (!success && iter->second != containerName.second)
73  throw std::runtime_error ("container assigned different name in subtool: " + iter->second + " vs " + containerName.second);
74  }
75 
76  for (auto& column : subtoolData->columns)
77  {
78  auto [iter,success] = m_data->columns.try_emplace (column.first, std::move (column.second));
79  if (!success)
80  iter->second.mergeData (column.first, std::move (column.second));
81  }
82 
83  m_data->sharedTools.insert (m_data->sharedTools.end(), subtoolData->sharedTools.begin(), subtoolData->sharedTools.end());
84  for (auto& tool : subtoolData->sharedTools)
85  tool->m_data = m_data;
86  }
87 
88  StatusCode ColumnarTool<ColumnarModeArray> ::
89  initializeColumns ()
90  {
91  return StatusCode::SUCCESS;
92  }
93 
94 
95 
96  void ColumnarTool<ColumnarModeArray> ::
97  callVoid (void **data) const
98  {
99  auto eventsOffset = static_cast<const ColumnarOffsetType*> (data[m_eventsIndex]);
100  callEvents (ObjectRange<ContainerId::eventContext,ColumnarModeArray> (data, eventsOffset[0], eventsOffset[1]));
101  }
102 
103 
104 
105  std::vector<ColumnInfo> ColumnarTool<ColumnarModeArray> ::
106  getColumnInfo () const
107  {
108  std::vector<std::string> names;
109  names.reserve (m_data->columns.size());
110  for (auto& [name, column] : m_data->columns)
111  {
112  if (!column.empty())
113  names.push_back (name);
114  }
115  std::sort (names.begin(), names.end());
116 
117  std::vector<ColumnInfo> result;
118  result.reserve (names.size());
119  for (auto& name : names)
120  {
121  auto& column = m_data->columns.at (name);
122  result.push_back (column.info());
123  result.back().name = name;
124  }
125  return result;
126  }
127 
128 
129 
130  void ColumnarTool<ColumnarModeArray> ::
131  renameColumn (const std::string& from, const std::string& to)
132  {
133  // Note: This is not the most efficient way to do this, if you want
134  // to rename all columns it is at O(n^2). However, since n is
135  // supposed to be small this shouldn't be a problem. Should this
136  // become a problem I'd have to introduce back-references to
137  // offset-columns, etc. However, that also introduces a fair bit of
138  // complexity, so I'm not doing it unless I have to.
139 
140  auto from_iter = m_data->columns.find (from);
141  if (from_iter == m_data->columns.end())
142  throw std::runtime_error ("column to rename from not found: " + from);
143  auto to_iter = m_data->columns.find (to);
144  if (to_iter != m_data->columns.end())
145  {
146  to_iter->second.mergeData (to, std::move (from_iter->second));
147  m_data->columns.erase (from_iter);
148  } else
149  {
150  auto node = m_data->columns.extract (from_iter);
151  node.key() = to;
152  m_data->columns.insert (std::move (node));
153  }
154  for (auto& column : m_data->columns)
155  column.second.updateColumnRef (from, to);
156  }
157 
158 
159 
160  void ColumnarTool<ColumnarModeArray> ::
161  setColumnIndex (const std::string& name, std::size_t index)
162  {
163  if (auto column = m_data->columns.find (name);
164  column != m_data->columns.end())
165  column->second.setIndex (index);
166  }
167 
168 
169 
170  void ColumnarTool<ColumnarModeArray> ::
171  callEvents (ObjectRange<ContainerId::eventContext,ColumnarModeArray> /*events*/) const
172  {
173  throw std::runtime_error ("tool didn't implement callEvents");
174  }
175 
176 
177 
178  const std::string& ColumnarTool<ColumnarModeArray> ::
179  objectName (ContainerId objectType) const
180  {
181  auto iter = m_data->containerNames.find (objectType);
182  if (iter == m_data->containerNames.end())
183  throw std::runtime_error ("object type not registered, make sure to register object handle first: " + std::to_string (unsigned(objectType)));
184  return iter->second;
185  }
186 
187 
188 
189  void ColumnarTool<ColumnarModeArray> ::
190  setContainerName (ContainerId container, const std::string& name)
191  {
192  auto [iter, success] = m_data->containerNames.emplace (container, name);
193  if (!success && iter->second != name)
194  throw std::runtime_error ("container already registered with different name: " + name + " vs " + iter->second);
195  }
196 
197 
198 
199  void ColumnarTool<ColumnarModeArray> ::
200  addColumn (const std::string& name, ColumnAccessorDataArray *accessorData, ColumnInfo&& info)
201  {
202  info.type = accessorData->type;
203  info.accessMode = accessorData->accessMode;
204 
205  m_data->columns[name].addAccessor (name, info, accessorData);
206  }
207 
208 
209 
210  ColumnDataArray ::
211  ColumnDataArray (ColumnDataArray&& other) noexcept
212  : m_info (std::move (other.m_info))
213  , m_accessors (std::move (other.m_accessors))
214  {
215  for (auto *ptr : m_accessors)
216  {
217  if (ptr->dataRef == &other)
218  ptr->dataRef = this;
219  }
220  }
221 
222 
223 
224  ColumnDataArray ::
225  ~ColumnDataArray () noexcept
226  {
227  for (auto *ptr : m_accessors)
228  {
229  if (ptr->dataRef == this)
230  ptr->dataRef = nullptr;
231  }
232  }
233 
234 
235 
236  bool ColumnDataArray ::
237  empty () const noexcept
238  {
239  return m_accessors.empty();
240  }
241 
242 
243 
245  info () const noexcept
246  {
247  return m_info;
248  }
249 
250 
251 
252  void ColumnDataArray ::
253  addAccessor (const std::string& name, const ColumnInfo& val_info, ColumnAccessorDataArray* val_accessorData)
254  {
255  if (m_accessors.empty())
256  {
257  m_info = val_info;
258 
259  // ensure that any index is not zero. zero is reserved for a
260  // nullptr, so that if an index has never been initialized, we
261  // get a segfault on access.
262  m_info.index = 0;
263  } else
264  {
265  if (val_info.type != m_info.type)
266  throw std::runtime_error ("multiple types for column: " + name);
267  if (m_info.accessMode == ColumnAccessMode::update || val_info.accessMode == ColumnAccessMode::update)
268  m_info.accessMode = ColumnAccessMode::update;
269  else if (m_info.accessMode == ColumnAccessMode::output || val_info.accessMode == ColumnAccessMode::output)
270  m_info.accessMode = ColumnAccessMode::output;
271  if (!val_info.isOptional)
272  m_info.isOptional = false;
273  if (val_info.offsetName != m_info.offsetName)
274  throw std::runtime_error ("inconsistent offset map for column: " + name);
275  }
276 
277  if (val_accessorData)
278  {
279  m_accessors.push_back (val_accessorData);
280  val_accessorData->dataRef = this;
281  }
282  }
283 
284 
285 
286  void ColumnDataArray ::
287  removeAccessor (ColumnAccessorDataArray& val_accessorData)
288  {
289  auto iter = std::find (m_accessors.begin(), m_accessors.end(), &val_accessorData);
290  if (iter == m_accessors.end())
291  return;
292  m_accessors.erase (iter);
293  val_accessorData.dataRef = nullptr;
294  }
295 
296 
297 
298  void ColumnDataArray ::
299  mergeData (const std::string& name, ColumnDataArray&& other)
300  {
301  addAccessor (name, other.m_info, nullptr);
302  m_accessors.insert (m_accessors.end(), other.m_accessors.begin(), other.m_accessors.end());
303  for (auto *ptr : other.m_accessors)
304  ptr->dataRef = this;
305  other.m_accessors.clear();
306  }
307 
308 
309 
310  void ColumnDataArray ::
311  updateColumnRef (const std::string& from, const std::string& to)
312  {
313  auto remapName = [&] (std::string& name)
314  {
315  if (name == from)
316  name = to;
317  };
318 
319  remapName (m_info.name);
320  remapName (m_info.offsetName);
321  remapName (m_info.replacesColumn);
322  remapName (m_info.linkToName);
323  }
324 
325 
326 
327  void ColumnDataArray ::
328  setIndex (unsigned index) noexcept
329  {
330  m_info.index = index;
331  for (auto *ptr : m_accessors)
332  *ptr->dataIndexPtr = index;
333  }
334 }
grepfile.info
info
Definition: grepfile.py:38
columnar::ContainerId::eventContext
@ eventContext
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
columnar::ColumnDataArray
Definition: ColumnarToolDataArray.h:17
columnar::ColumnAccessMode::input
@ input
an input column
columnar::numberOfEventsName
const std::string numberOfEventsName
the name used for the column containing the number of events
Definition: IColumnarTool.h:38
columnar::ColumnInfo::accessMode
ColumnAccessMode accessMode
the access mode for the column
Definition: ColumnInfo.h:58
get_generator_info.result
result
Definition: get_generator_info.py:21
columnar::ColumnInfo::offsetName
std::string offsetName
the name of the offset column used for this column (or empty string for none)
Definition: ColumnInfo.h:74
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
index
Definition: index.py:1
m_data
std::vector< T > m_data
Definition: TrackTruthMatchingBaseAlg.cxx:660
DeMoUpdate.column
dictionary column
Definition: DeMoUpdate.py:1110
columnar::ColumnAccessorDataArray::dataRef
ColumnDataArray * dataRef
the ColumnDataArray object that holds us
Definition: ColumnAccessorDataArray.h:39
dbg::ptr
void * ptr(T *p)
Definition: SGImplSvc.cxx:74
const
bool const RAWDATA *ch2 const
Definition: LArRodBlockPhysicsV0.cxx:560
columnar::ColumnInfo::type
const std::type_info * type
the type of the individual entries in the column
Definition: ColumnInfo.h:54
hotSpotInTAG.objectType
objectType
Definition: hotSpotInTAG.py:107
columnar::ColumnInfo
a struct that contains meta-information about each column that's needed to interface the column with ...
Definition: ColumnInfo.h:35
ColumnarToolDataArray.h
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
python.subdetectors.mmg.names
names
Definition: mmg.py:8
columnar::ColumnInfo::isOptional
bool isOptional
whether this column is optional
Definition: ColumnInfo.h:113
ColumnAccessorDataArray.h
ColumnarTool.h
merge.output
output
Definition: merge.py:17
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
AtlCoolConsole.tool
tool
Definition: AtlCoolConsole.py:453
columnar::ContainerId::eventInfo
@ eventInfo
FlavorTagDiscriminants::str::remapName
const std::string remapName(const std::string &name, std::map< std::string, std::string > &remap, std::set< std::string > &usedRemap)
Definition: PhysicsAnalysis/JetTagging/FlavorTagDiscriminants/Root/StringUtils.cxx:8
CxxUtils::to
CONT to(RANGE &&r)
Definition: ranges.h:39
DeMoScan.index
string index
Definition: DeMoScan.py:364
InDetDD::other
@ other
Definition: InDetDD_Defs.h:16
columnar
Definition: ClusterDef.h:16
std::sort
void sort(typename std::reverse_iterator< DataModel_detail::iterator< DVL > > beg, typename std::reverse_iterator< DataModel_detail::iterator< DVL > > end, const Compare &comp)
Specialization of sort for DataVector/List.
Definition: DVL_algorithms.h:623
columnar::ColumnInfo::index
unsigned index
the index of the column in the data array
Definition: ColumnInfo.h:46
columnar::ColumnAccessorDataArray
all the data about a column accessor that the ColumnarTool needs to know about
Definition: ColumnAccessorDataArray.h:23
columnar::ContainerId
ContainerId
the id for the different "virtual" containers
Definition: ContainerId.h:71
ColumnInfo.h
columnar::ColumnarOffsetType
std::size_t ColumnarOffsetType
the type used for the size and offsets in the columnar data
Definition: IColumnarTool.h:20
WriteBchToCool.update
update
Definition: WriteBchToCool.py:67
node
Definition: node.h:21