Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
ColumnarToolWrapper.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 //
9 // includes
10 //
11 
13 
17 #include <algorithm>
18 #include <cstdint>
19 #include <stdexcept>
20 #include <typeindex>
21 
22 //
23 // method implementations
24 //
25 
26 namespace columnar
27 {
30  : m_tool (val_tool)
31  {
32  constexpr unsigned numpySigned = 0;
33  constexpr unsigned numpyUnsigned = 1;
34  constexpr unsigned numpyFloat = 2;
35  std::unordered_map<std::type_index, std::pair<int,unsigned>> numpyTypes;
36  numpyTypes[typeid (float)] = { numpyFloat, sizeof (float) * 8 };
37  numpyTypes[typeid (char)] = { std::is_signed_v<char> ? numpySigned : numpyUnsigned, sizeof (char) * 8 };
38  numpyTypes[typeid (int)] = { numpySigned, sizeof (int) * 8 };
39  numpyTypes[typeid (std::uint8_t)] = { numpyUnsigned, sizeof (std::uint8_t) * 8 };
40  numpyTypes[typeid (std::uint16_t)] = { numpyUnsigned, sizeof (std::uint16_t) * 8 };
41  numpyTypes[typeid (std::uint32_t)] = { numpyUnsigned, sizeof (std::uint32_t) * 8 };
42  numpyTypes[typeid (std::uint64_t)] = { numpyUnsigned, sizeof (std::uint64_t) * 8 };
43 
44 
45  auto toolColumns = m_tool->getColumnInfo();
46  unsigned nextIndex = 1u;
47  for (auto& column : toolColumns)
48  {
49  MyColumnInfo myinfo;
50  myinfo.index = nextIndex++;
51  val_tool->setColumnIndex (column.name, myinfo.index);
52  myinfo.type = column.type;
53  switch (column.accessMode)
54  {
56  myinfo.isConst = true;
57  break;
59  myinfo.isConst = false;
60  break;
62  myinfo.isConst = false;
63  break;
64  }
65  for (unsigned dim : column.fixedDimensions)
66  myinfo.fixedDimensions *= dim;
67  myinfo.isOffset = column.isOffset;
68  myinfo.isOptional = column.isOptional;
69 
70  if (auto iter = numpyTypes.find (*column.type); iter != numpyTypes.end())
71  {
72  myinfo.numpyType = iter->second.first;
73  myinfo.numpyBits = iter->second.second;
74  }
75  const auto infoIdx = myinfo.index;
76  auto [iter, success] = m_columns.emplace (column.name, std::move (myinfo));
77  if (!success)
78  throw std::runtime_error ("column name already registered: " + column.name);
79 
80  if (m_numColumns <= infoIdx)
81  m_numColumns = infoIdx + 1;
82  }
83 
84  for (auto& column : toolColumns)
85  {
86  if (!column.offsetName.empty())
87  {
88  auto offsetIter = m_columns.find (column.offsetName);
89  if (offsetIter == m_columns.end())
90  throw std::runtime_error ("offset column name not found: " + column.offsetName);
91  if (*offsetIter->second.type != typeid (ColumnarOffsetType))
92  throw std::runtime_error ("offset column has wrong type: " + column.offsetName);
93  if (!offsetIter->second.isOffset)
94  throw std::runtime_error ("offset column is not registered as offset: " + column.offsetName);
95  m_columns.at (column.name).offsets = &*offsetIter;
96  }
97  }
98  }
99 
100 
101 
103  ColumnarToolWrapper (std::shared_ptr<IColumnarTool> val_tool)
104  : ColumnarToolWrapper (val_tool.get())
105  {
106  m_toolOwn = std::move (val_tool);
107  }
108 
109 
110 
112  ColumnarToolWrapperData (const ColumnarToolWrapper *val_wrapper) noexcept
113  : m_wrapper (val_wrapper),
114  m_data (m_wrapper->m_numColumns, nullptr),
115  m_dataSize (m_wrapper->m_numColumns, 0u),
116  m_columnIsChecked (m_wrapper->m_numColumns, false),
117  m_columnIsFilled (m_wrapper->m_numColumns, false)
118  {}
119 
120 
121 
123  setColumnVoid (const std::string& name, std::size_t size, const void *dataPtr, const std::type_info& type, bool isConst)
124  {
125  auto column = m_wrapper->m_columns.find (name);
126  if (column == m_wrapper->m_columns.end())
127  throw std::runtime_error ("unknown column name: " + name);
128 
129  if (type != *column->second.type)
130  throw std::runtime_error ("invalid type for column: " + name);
131  if (isConst && !column->second.isConst)
132  throw std::runtime_error ("assigning const vector to a non-const column: " + name);
133  if (column->second.index == 0)
134  throw std::runtime_error ("column has no index assigned: " + name);
135  if (m_columnIsFilled[column->second.index])
136  throw std::runtime_error ("column filled multiple times: " + name);
137  m_columnIsFilled[column->second.index] = true;
138  auto *castDataPtr ATLAS_THREAD_SAFE = const_cast<void*>(dataPtr);
139  m_data[column->second.index] = castDataPtr;
140  m_dataSize[column->second.index] = size;
141  }
142 
143 
144 
146  setColumnNumpy (const std::string& name, std::size_t size, const void *dataPtr, int type, unsigned bits, bool isConst)
147  {
148  auto column = m_wrapper->m_columns.find (name);
149  if (column == m_wrapper->m_columns.end())
150  throw std::runtime_error ("unknown column name: " + name);
151 
152  if (type != column->second.numpyType || bits != column->second.numpyBits)
153  throw std::runtime_error ("invalid type for column: " + name + " (expected " + std::to_string (column->second.numpyType) + "/" + std::to_string (column->second.numpyBits) + " but got " + std::to_string (type) + "/" + std::to_string (bits) + ")");
154  if (isConst && !column->second.isConst)
155  throw std::runtime_error ("assigning const vector to a non-const column: " + name);
156  if (column->second.index == 0)
157  throw std::runtime_error ("column has no index assigned: " + name);
158  if (m_columnIsFilled[column->second.index])
159  throw std::runtime_error ("column filled multiple times: " + name);
160  m_columnIsFilled[column->second.index] = true;
161  auto *castDataPtr ATLAS_THREAD_SAFE = const_cast<void*>(dataPtr);
162  m_data[column->second.index] = castDataPtr;
163  m_dataSize[column->second.index] = size;
164  }
165 
166 
167 
168  std::pair<std::size_t,const void*> ColumnarToolWrapperData ::
169  getColumnVoid (const std::string& name, const std::type_info *type, bool isConst)
170  {
171  auto column = m_wrapper->m_columns.find (name);
172  if (column == m_wrapper->m_columns.end())
173  throw std::runtime_error ("unknown column name: " + name);
174 
175  if (*type != *column->second.type)
176  throw std::runtime_error ("invalid type for column: " + name);
177  if (!isConst && column->second.isConst)
178  throw std::runtime_error ("retrieving non-const vector from a const column: " + name);
179  if (m_data[column->second.index] != nullptr)
180  return std::make_pair (m_dataSize[column->second.index],
181  m_data[column->second.index]);
182  else
183  return std::make_pair (0u, nullptr);
184  }
185 
186 
187 
190  {
191  for (auto& column : m_wrapper->m_columns)
193  }
194 
195 
196 
198  call ()
199  {
201  m_wrapper->m_tool->callVoid (m_data.data());
202  }
203 
204 
205 
207  checkColumn (const std::pair<const std::string,ColumnarToolWrapper::MyColumnInfo>& column)
208  {
209  if (m_columnIsChecked.at(column.second.index))
210  return;
211  if (!m_columnIsFilled.at(column.second.index))
212  {
213  if (!column.second.isOptional)
214  throw std::runtime_error ("column not filled: " + column.first);
215  m_columnIsChecked[column.second.index] = true;
216  return;
217  }
218 
219  ColumnarOffsetType expectedSize = 1u;
220  if (column.second.offsets)
221  {
222  checkColumn (*column.second.offsets);
223  if (m_data[column.second.offsets->second.index] == nullptr)
224  throw std::runtime_error ("offset column not filled: " + column.second.offsets->first);
225  const auto offsetIndex = column.second.offsets->second.index;
226  auto *offsetsPtr = static_cast<const ColumnarOffsetType*>(m_data[offsetIndex]);
227  expectedSize = offsetsPtr[m_dataSize[offsetIndex]-1];
228  }
229  expectedSize *= column.second.fixedDimensions;
230 
231  if (column.second.isOffset)
232  expectedSize += 1u;
233 
234  if (m_dataSize[column.second.index] != expectedSize)
235  throw std::runtime_error ("column size doesn't match expected size: " + column.first + ", found " + std::to_string (m_dataSize[column.second.index]) + " vs " + std::to_string (expectedSize));
236 
237  if (column.second.isOffset)
238  {
239  auto *dataPtr = static_cast<const ColumnarOffsetType*>(m_data[column.second.index]);
240  if (dataPtr[0] != 0)
241  throw std::runtime_error ("offset column doesn't start with 0: " + column.first);
242  }
243 
244  m_columnIsChecked[column.second.index] = true;
245  }
246 
247 
248 
249  std::vector<std::string> ColumnarToolWrapper ::
250  getColumnNames () const
251  {
252  std::vector<std::string> result;
253  for (auto& column : m_columns)
254  result.push_back (column.first);
255  std::sort (result.begin(), result.end());
256  return result;
257  }
258 
259 
260 
261  [[nodiscard]] std::vector<ColumnInfo> ColumnarToolWrapper ::
262  getColumnInfo () const
263  {
264  return m_tool->getColumnInfo();
265  }
266 }
columnar::ColumnarToolWrapperData::m_wrapper
const ColumnarToolWrapper * m_wrapper
Definition: ColumnarToolWrapper.h:211
columnar::IColumnarTool::callVoid
virtual void callVoid(void **data) const =0
run the tool on the data vector
columnar::IColumnarTool::setColumnIndex
virtual void setColumnIndex(const std::string &name, std::size_t index)=0
set the index for the column
columnar::IColumnarTool
an interface for tools that operate on columnar data
Definition: IColumnarTool.h:214
columnar::ColumnAccessMode::input
@ input
an input column
yodamerge_tmp.dim
dim
Definition: yodamerge_tmp.py:239
get_generator_info.result
result
Definition: get_generator_info.py:21
columnar::ColumnarToolWrapperData::getColumnVoid
std::pair< std::size_t, const void * > getColumnVoid(const std::string &name, const std::type_info *type, bool isConst)
get the data for the given column in a type-erased manner
Definition: ColumnarToolWrapper.cxx:169
columnar::ColumnarToolWrapper::MyColumnInfo::index
unsigned index
Definition: ColumnarToolWrapper.h:91
columnar::ColumnarToolWrapper::MyColumnInfo::isOffset
bool isOffset
Definition: ColumnarToolWrapper.h:95
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:557
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
columnar::ColumnarToolWrapper::m_toolOwn
std::shared_ptr< const IColumnarTool > m_toolOwn
the owning pointer to the tool
Definition: ColumnarToolWrapper.h:81
m_data
std::vector< T > m_data
Definition: TrackTruthMatchingBaseAlg.cxx:660
columnar::ColumnarToolWrapperData::checkColumnsValid
void checkColumnsValid()
check that all columns are valid
Definition: ColumnarToolWrapper.cxx:189
columnar::ColumnarToolWrapper::MyColumnInfo::isOptional
bool isOptional
Definition: ColumnarToolWrapper.h:97
xAOD::char
char
Definition: TrigDecision_v1.cxx:38
columnar::ColumnarToolWrapper::getColumnNames
std::vector< std::string > getColumnNames() const
get information on all defined columns
Definition: ColumnarToolWrapper.cxx:250
DeMoUpdate.column
dictionary column
Definition: DeMoUpdate.py:1110
columnar::ColumnarToolWrapperData::m_data
std::vector< void * > m_data
Definition: ColumnarToolWrapper.h:213
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:77
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
columnar::ColumnarToolWrapper::MyColumnInfo::type
const std::type_info * type
Definition: ColumnarToolWrapper.h:87
columnar::ColumnAccessMode::output
@ output
an output column
columnar::ColumnarToolWrapperData::checkColumn
void checkColumn(const std::pair< const std::string, ColumnarToolWrapper::MyColumnInfo > &column)
Definition: ColumnarToolWrapper.cxx:207
columnar::ColumnarToolWrapper::MyColumnInfo::numpyType
int numpyType
Definition: ColumnarToolWrapper.h:99
columnar::ColumnarToolWrapperData::setColumnNumpy
void setColumnNumpy(const std::string &name, std::size_t size, const void *dataPtr, int type, unsigned bits, bool isConst)
set the data for the given column with the user passing in the type information from numpy
Definition: ColumnarToolWrapper.cxx:146
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:93
IColumnarTool.h
columnar::ColumnarToolWrapperData::setColumnVoid
void setColumnVoid(const std::string &name, std::size_t size, const void *dataPtr, const std::type_info &type, bool isConst)
set the data for the given column with the user passing in the type
Definition: ColumnarToolWrapper.cxx:123
columnar::IColumnarTool::getColumnInfo
virtual std::vector< ColumnInfo > getColumnInfo() const =0
the meta-information for the columns
columnar::ColumnarToolWrapperData::m_dataSize
std::vector< std::size_t > m_dataSize
Definition: ColumnarToolWrapper.h:214
columnar::ColumnarToolWrapperData::m_columnIsChecked
std::vector< bool > m_columnIsChecked
Definition: ColumnarToolWrapper.h:215
python.LArMinBiasAlgConfig.int
int
Definition: LArMinBiasAlgConfig.py:59
columnar::ColumnarToolWrapper::ColumnarToolWrapper
ColumnarToolWrapper(IColumnarTool *val_tool)
constructor: wrap the given tool (non-owning)
Definition: ColumnarToolWrapper.cxx:29
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
columnar::size
std::size_t size() const noexcept
Definition: ObjectRange.h:132
columnar::ColumnAccessMode::update
@ update
an updateable column
ColumnarToolWrapper.h
columnar::ColumnarToolWrapperData::m_columnIsFilled
std::vector< bool > m_columnIsFilled
Definition: ColumnarToolWrapper.h:216
columnar::ColumnarToolWrapper::getColumnInfo
std::vector< ColumnInfo > getColumnInfo() const
Definition: ColumnarToolWrapper.cxx:262
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
columnar::ColumnarToolWrapper::MyColumnInfo::numpyBits
unsigned numpyBits
Definition: ColumnarToolWrapper.h:101
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
columnar::ColumnarToolWrapper
a class that wraps an IColumnarTool for use in Python
Definition: ColumnarToolWrapper.h:36
columnar::ColumnarToolWrapper::m_tool
const IColumnarTool * m_tool
the wrapped tool
Definition: ColumnarToolWrapper.h:78
columnar::ColumnarToolWrapper::MyColumnInfo::fixedDimensions
unsigned fixedDimensions
Definition: ColumnarToolWrapper.h:93
columnar::ColumnarToolWrapperData::ColumnarToolWrapperData
ColumnarToolWrapperData(const ColumnarToolWrapper *val_wrapper) noexcept
constructor: wrap the given tool
Definition: ColumnarToolWrapper.cxx:112
columnar::ColumnarToolWrapper::m_columns
std::unordered_map< std::string, MyColumnInfo > m_columns
Definition: ColumnarToolWrapper.h:105
columnar::ColumnarToolWrapper::m_numColumns
unsigned m_numColumns
the number of columns that the tool expects (equal to the greatest column index + 1)
Definition: ColumnarToolWrapper.h:110
columnar
Definition: ClusterDef.h:16
columnar::ColumnarToolWrapper::MyColumnInfo::isConst
bool isConst
Definition: ColumnarToolWrapper.h:89
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
ColumnInfo.h
checker_macros.h
Define macros for attributes used to control the static checker.
columnar::ColumnarOffsetType
std::size_t ColumnarOffsetType
the type used for the size and offsets in the columnar data
Definition: IColumnarTool.h:20
columnar::ColumnarToolWrapper::MyColumnInfo
my cached information for the various columns needed
Definition: ColumnarToolWrapper.h:86
columnar::ColumnarToolWrapperData::call
void call()
call the tool
Definition: ColumnarToolWrapper.cxx:198
python.LArMinBiasAlgConfig.float
float
Definition: LArMinBiasAlgConfig.py:65