ATLAS Offline Software
ColumnarMemoryTest.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 
18 
19 //
20 // method implementations
21 //
22 
23 namespace columnar
24 {
27  {
28  }
29 
30 
31 
34  {
35  static std::atomic<unsigned> index = 0;
36  return "UniqueMemoryTestTool" + std::to_string(++index);
37  }
38 
39 
40 
42  checkMode ()
43  {
44  return std::is_same_v<ColumnarModeDefault,ColumnarModeArray>;
45  }
46 
47 
48 
49  namespace TestUtils
50  {
53  {
54  m_tool = dynamic_cast<IColumnarTool*> (&val_tool);
55  if (m_tool == nullptr)
56  throw std::runtime_error ("tool does not implement IColumnarTool");
57  m_systTool = dynamic_cast<CP::ISystematicsTool*> (m_tool);
58  }
59 
60 
61 
63  renameContainers (const std::vector<std::pair<std::string,std::string>>& renames)
64  {
66  if (m_toolWrapper)
67  {
68  m_columnHeader = std::make_shared<ColumnVectorHeader> ();
69  m_toolWrapper = std::make_shared<ToolColumnVectorMap> (*m_columnHeader, *m_tool);
70  }
71  }
72 
73 
74 
76  initialize ()
77  {
78  m_columnHeader = std::make_shared<ColumnVectorHeader> ();
79  m_toolWrapper = std::make_shared<ToolColumnVectorMap> (*m_columnHeader, *m_tool);
80  }
81 
82 
83 
85  applySystematicVariation (const std::string& sysName)
86  {
87  // by convention setting a systematic on a non-systematics tool
88  // will do nothing
89  if (m_systTool == nullptr)
90  return;
92  throw std::runtime_error ("failed to apply systematic variation");
93  }
94 
95 
96 
97  [[nodiscard]] std::vector<ColumnInfo> ColumnarTestToolHandle ::
98  getColumnInfo () const
99  {
100  if (!m_toolWrapper)
101  throw std::runtime_error ("tool not initialized");
102  return m_tool->getColumnInfo ();
103  }
104 
105 
106 
107  std::vector<std::string> ColumnarTestToolHandle ::
108  getColumnNames () const
109  {
110  if (!m_toolWrapper)
111  throw std::runtime_error ("tool not initialized");
112  return m_toolWrapper->getColumnNames ();
113  }
114 
115 
116 
117  std::vector<std::string> ColumnarTestToolHandle ::
119  {
120  if (!m_systTool)
121  return {""};
122  std::vector<std::string> result;
124  result.push_back (sys.name());
125  return result;
126  }
127 
128 
129 
132  {
133  if (!m_toolWrapper)
134  throw std::runtime_error ("tool not initialized");
135  return *m_toolWrapper;
136  }
137 
138 
139 
141  getToolWrapper () const
142  {
143  if (!m_toolWrapper)
144  throw std::runtime_error ("tool not initialized");
145  return *m_toolWrapper;
146  }
147 
148 
149 
151  getTool ()
152  {
153  return m_tool;
154  }
155 
156 
157 
159  ColumnMapType (ColumnarTestToolHandle& val_toolHandle)
160  : m_toolHandle (&val_toolHandle), m_columnData (std::make_unique<ColumnVectorData> (&val_toolHandle.getColumnHeader()))
161  {
162  for (auto& column : m_toolHandle->getColumnInfo())
163  {
164  auto& userColumn = m_userColumns[column.name];
165  if (userColumn.info.has_value())
166  throw std::runtime_error ("column already exists: " + column.name);
167  userColumn.info = column;
168  }
169  }
170 
171 
172 
174  addColumn (const std::string& name, std::vector<std::any> data)
175  {
176  auto& userColumn = m_userColumns[name];
177  if (userColumn.input.has_value())
178  throw std::runtime_error ("column added twice: " + name);
179  ManualColumnData manualData {std::move (data)};
180  userColumn.input = std::move (manualData);
181  }
182 
183 
184 
186  setExpectation (const std::string& name, std::vector<std::any> values)
187  {
188  auto& userColumn = m_userColumns[name];
189  if (userColumn.expectation.has_value())
190  throw std::runtime_error ("column added twice: " + name);
191  ManualColumnData manualData {std::move (values)};
192  userColumn.expectation = std::move (manualData);
193  }
194 
195 
196 
197  std::size_t ColumnMapType ::
198  columnSize (const std::string& name)
199  {
200  auto iter = m_userColumns.find (name);
201  if (iter == m_userColumns.end() || !iter->second.input.has_value())
202  throw std::runtime_error ("column not found: " + name);
203  return iter->second.input.value().columnSize ();
204  }
205 
206 
207 
210  {
211  std::vector<std::string> missingColumns;
212  for (auto& [name, userColumn] : m_userColumns)
213  {
214  if (!userColumn.info.has_value())
215  {
216  // report missing column to gtest, but continue
217  ADD_FAILURE() << "provided a column not requested by tool: " << name;
218  continue;
219  }
220  auto& columnInfo = userColumn.info.value();
221  if (!userColumn.input.has_value())
222  {
223  if (!columnInfo.isOptional)
224  {
225  // for missing non-optional inputs we need to throw, because
226  // the tool will fail otherwise. potentially we could try to
227  // fill dummy input values, but that is more complicated.
228  missingColumns.push_back (name);
229  }
230  continue;
231  }
232  auto& input = userColumn.input.value();
233  switch (columnInfo.accessMode)
234  {
238  {
239  const bool isConst = columnInfo.accessMode == ColumnAccessMode::input;
240  input.configureType (name, *columnInfo.type);
241  m_toolHandle->getToolWrapper().setColumnVoid (*m_columnData, name, input.columnSize(), input.columnVoidData(), *columnInfo.type, isConst);
242  }
243  break;
244  default:
245  throw std::runtime_error ("column mode unknown: " + columnInfo.name);
246  }
247  }
248  if (!missingColumns.empty())
249  {
250  std::string message = "missing input columns:";
251  for (auto& column : missingColumns)
252  message += " " + column;
253  throw std::runtime_error (message);
254  }
255  }
256 
257 
258 
260  call ()
261  {
262  m_columnData->checkData ();
263  m_columnData->callNoCheck (*m_toolHandle->getTool());
264  }
265 
266 
267 
270  {
271  for (auto& [columnName, userColumn] : m_userColumns)
272  {
273  if (!userColumn.info.has_value())
274  continue;
275  auto& info = userColumn.info.value();
276  if (info.accessMode == ColumnAccessMode::input)
277  {
278  if (userColumn.expectation.has_value())
279  ADD_FAILURE() << "expectation provided for input-only column: " << columnName;
280  continue;
281  }
282  if (!userColumn.input.has_value())
283  {
284  if (info.isOptional)
285  {
286  if (userColumn.expectation.has_value())
287  ADD_FAILURE() << "expectation provided for omitted column: " << columnName;
288  continue;
289  }
290  throw std::logic_error ("output column does not exist: " + columnName);
291  }
292  auto& output = userColumn.input.value();
293 
294  if (!userColumn.expectation.has_value())
295  {
296  ADD_FAILURE() << "no expectation provided for output column: " << columnName;
297  } else
298  {
299  auto& expectation = userColumn.expectation.value();
300  expectation.configureType (columnName, *info.type);
301  TestUtils::checkExpectation (columnName, *output.type(), output.columnSize(), output.columnVoidData(), *expectation.type(), expectation.columnSize(), expectation.columnVoidData());
302  }
303  TestUtils::printExpectedOutput (columnName, *output.type(), output.columnSize(), output.columnVoidData());
304  }
305  }
306  }
307 }
CaloCondBlobAlgs_fillNoiseFromASCII.sysName
sysName
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:92
columnar::TestUtils::ColumnMapType::setExpectation
void setExpectation(const std::string &name, std::vector< std::any > values)
Definition: ColumnarMemoryTest.cxx:186
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
createLinkingScheme.iter
iter
Definition: createLinkingScheme.py:62
asg::AsgTool
Base class for the dual-use tool implementation classes.
Definition: AsgTool.h:47
columnar::IColumnarTool
an interface for tools that operate on columnar data
Definition: IColumnarTool.h:214
columnar::ColumnAccessMode::input
@ input
an input column
get_generator_info.result
result
Definition: get_generator_info.py:21
CP::make_systematics_vector
std::vector< CP::SystematicSet > make_systematics_vector(const SystematicSet &systematics)
utility functions for working with systematics
Definition: SystematicsUtil.cxx:25
index
Definition: index.py:1
columnar::TestUtils::ColumnMapType::addColumn
void addColumn(const std::string &name, std::vector< std::any > data)
Definition: ColumnarMemoryTest.cxx:174
TestUtils
Definition: TestUtils.py:1
CP::SystematicSet
Class to wrap a set of SystematicVariations.
Definition: SystematicSet.h:31
columnar::TestUtils::ColumnarTestToolHandle::applySystematicVariation
void applySystematicVariation(const std::string &sysName)
set the tool to apply the given systematic variation
Definition: ColumnarMemoryTest.cxx:85
columnar::TestUtils::ColumnarTestToolHandle::renameContainers
void renameContainers(const std::vector< std::pair< std::string, std::string >> &renames)
rename the columns the tool uses
Definition: ColumnarMemoryTest.cxx:63
DeMoUpdate.column
dictionary column
Definition: DeMoUpdate.py:1110
columnar::TestUtils::ColumnarTestToolHandle::getToolWrapper
ToolColumnVectorMap & getToolWrapper()
get the tool wrapper
Definition: ColumnarMemoryTest.cxx:131
columnar::ToolColumnVectorMap
a class that interfaces an IColumnarTool to a ColumnVectorHeader
Definition: ToolColumnVectorMap.h:30
MuonR4::to_string
std::string to_string(const SectorProjector proj)
Definition: MsTrackSeeder.cxx:66
columnar::TestUtils::ColumnarTestToolHandle::initialize
void initialize()
initialize the tool
Definition: ColumnarMemoryTest.cxx:76
ReweightUtils.message
message
Definition: ReweightUtils.py:15
mapkey::sys
@ sys
Definition: TElectronEfficiencyCorrectionTool.cxx:42
columnar::ColumnAccessMode::output
@ output
an output column
columnar::TestUtils::ColumnMapType::call
void call()
Definition: ColumnarMemoryTest.cxx:260
python.Bindings.values
values
Definition: Control/AthenaPython/python/Bindings.py:808
columnar::ToolColumnVectorMap::setColumnVoid
void setColumnVoid(ColumnVectorData &columnData, const std::string &name, std::size_t size, const void *dataPtr, const std::type_info &type, bool isConst) const
set the data for the given column with the user passing in the type
Definition: ToolColumnVectorMap.h:85
columnar::TestUtils::ColumnarTestToolHandle
a handle to a columnar tool for running tests
Definition: ColumnarMemoryTest.h:55
columnar::IColumnarTool::getColumnInfo
virtual std::vector< ColumnInfo > getColumnInfo() const =0
the meta-information for the columns
columnar::TestUtils::ColumnarTestToolHandle::m_toolWrapper
std::shared_ptr< ToolColumnVectorMap > m_toolWrapper
Definition: ColumnarMemoryTest.h:103
columnar::TestUtils::ColumnarTestToolHandle::getColumnInfo
std::vector< ColumnInfo > getColumnInfo() const
get the expected column info
Definition: ColumnarMemoryTest.cxx:98
columnar::TestUtils::ColumnMapType::columnSize
std::size_t columnSize(const std::string &name)
Definition: ColumnarMemoryTest.cxx:198
columnar::ColumnarMemoryTest::makeUniqueName
std::string makeUniqueName()
make a unique tool name to be used in unit tests
Definition: ColumnarMemoryTest.cxx:33
columnar::TestUtils::ColumnarTestToolHandle::m_tool
IColumnarTool * m_tool
Definition: ColumnarMemoryTest.h:99
ColumnarDef.h
columnar::renameContainers
void renameContainers(IColumnarTool &tool, const std::vector< std::pair< std::string, std::string >> &renames)
rename containers in the columnar tool
Definition: ColumnarToolHelpers.cxx:23
columnar::ColumnarMemoryTest::ColumnarMemoryTest
ColumnarMemoryTest()
Definition: ColumnarMemoryTest.cxx:26
columnar::ColumnAccessMode::update
@ update
an updateable column
columnar::TestUtils::ColumnMapType::m_columnData
std::unique_ptr< ColumnVectorData > m_columnData
Definition: ColumnarMemoryTest.h:134
columnar::TestUtils::checkExpectation
void checkExpectation(const std::string &columnName, const std::type_info &outputType, std::size_t outputSize, const void *outputData, const std::type_info &expectationType, std::size_t expectationSize, const void *expectationData)
Definition: ExpectationCompare.cxx:46
columnar::TestUtils::ColumnarTestToolHandle::getColumnNames
std::vector< std::string > getColumnNames() const
get the expected column names
Definition: ColumnarMemoryTest.cxx:108
columnar::TestUtils::ColumnMapType::m_userColumns
std::unordered_map< std::string, MyColumnData > m_userColumns
Definition: ColumnarMemoryTest.h:142
CP::IReentrantSystematicsTool::recommendedSystematics
virtual SystematicSet recommendedSystematics() const =0
the list of all systematics this tool recommends to use
columnar::TestUtils::ColumnarTestToolHandle::m_columnHeader
std::shared_ptr< ColumnVectorHeader > m_columnHeader
Definition: ColumnarMemoryTest.h:102
columnar::TestUtils::ColumnarTestToolHandle::ColumnarTestToolHandle
ColumnarTestToolHandle(asg::AsgTool &val_tool)
Definition: ColumnarMemoryTest.cxx:52
columnar::TestUtils::ColumnarTestToolHandle::getTool
IColumnarTool * getTool()
get the contained tool
Definition: ColumnarMemoryTest.cxx:151
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
ExpectationCompare.h
columnar::TestUtils::ColumnarTestToolHandle::getRecommendedSystematics
std::vector< std::string > getRecommendedSystematics() const
get the recommended systematics
Definition: ColumnarMemoryTest.cxx:118
CP::ISystematicsTool
Interface for all CP tools supporting systematic variations.
Definition: ISystematicsTool.h:32
columnar::ColumnVectorData
a class that holds the columnar data for a single call
Definition: ColumnVectorWrapper.h:158
columnar::TestUtils::ManualColumnData
a class that holds manually specified column data
Definition: ManualColumnData.h:39
ColumnarMemoryTest.h
columnar::TestUtils::ColumnarTestToolHandle::m_systTool
CP::ISystematicsTool * m_systTool
Definition: ColumnarMemoryTest.h:100
columnar
Definition: ClusterDef.h:16
columnar::TestUtils::ColumnMapType::m_toolHandle
ColumnarTestToolHandle * m_toolHandle
Definition: ColumnarMemoryTest.h:132
ColumnarToolHelpers.h
columnar::TestUtils::ColumnMapType::connectColumnsToTool
void connectColumnsToTool()
add the columns we have to the tool
Definition: ColumnarMemoryTest.cxx:209
columnar::TestUtils::ColumnMapType::checkExpectations
void checkExpectations()
Definition: ColumnarMemoryTest.cxx:269
columnar::ColumnarMemoryTest::checkMode
static bool checkMode()
check whether we have the right mode
Definition: ColumnarMemoryTest.cxx:42
CP::ISystematicsTool::applySystematicVariation
virtual StatusCode applySystematicVariation(const SystematicSet &systConfig)=0
effects: configure this tool for the given list of systematic variations.
python.difftuple.renames
dictionary renames
Definition: difftuple.py:22
columnar::TestUtils::ColumnMapType::ColumnMapType
ColumnMapType(ColumnarTestToolHandle &val_toolHandle)
Definition: ColumnarMemoryTest.cxx:159
python.ParticleTypeUtil.info
def info
Definition: ParticleTypeUtil.py:87
columnar::TestUtils::printExpectedOutput
void printExpectedOutput(const std::string &columnName, const std::type_info &outputType, std::size_t outputSize, const void *outputData)
Definition: ExpectationCompare.cxx:93
SystematicsUtil.h