ATLAS Offline Software
ExpressionParserUser.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 #include "ExpressionEvaluation/SGxAODProxyLoader.h"
5 #include "ExpressionEvaluation/SGNTUPProxyLoader.h"
6 #include "ExpressionEvaluation/MultipleProxyLoader.h"
7 #include "ExpressionEvaluation/ExpressionParser.h"
8 #include "ExpressionParserUser.h"
9 #include <cassert>
10 
11 namespace ExpressionParsing {
12  template <unsigned short NUM_PARSER>
13  std::array< std::unique_ptr<ExpressionParsing::ExpressionParser>, NUM_PARSER >
14  MultiParserHelper<NUM_PARSER>::createParser(ExpressionParsing::IProxyLoader &proxy_loader, const std::vector< std::string> &selection_string, unsigned short num_parser) {
15  if (selection_string.size() != num_parser) { throw std::logic_error("Dimension mismtach between selection strings and number of parsers."); }
16  std::array< std::unique_ptr<ExpressionParsing::ExpressionParser>,NUM_PARSER > parser;
17  unsigned int idx=0;
18  for (const std::string &a_selection_string : selection_string) {
19  assert( idx < parser.size() );
20  parser[idx]=std::make_unique<ExpressionParsing::ExpressionParser>(&proxy_loader );
21  parser[idx]->loadExpression( a_selection_string );
22  ++idx;
23  }
24  return parser;
25  }
26 
27  template <unsigned short NUM_PARSER>
28  std::vector<std::string> MultiParserHelper<NUM_PARSER>::getVariables( const std::array< std::unique_ptr<ExpressionParsing::ExpressionParser>, NUM_PARSER > &parser ) {
29  std::vector<std::string> var_names;
30  for (const std::unique_ptr<ExpressionParsing::ExpressionParser> &a_parser : parser) {
31  std::vector<std::string> tmp_var_names ( a_parser->getVariables() );
32  var_names.reserve( var_names.size() + tmp_var_names.size());
33  for (const std::string &a_name : tmp_var_names ) {
34  if (std::find(var_names.begin(),var_names.end(),a_name) == var_names.end()) {
35  var_names.push_back( a_name );
36  }
37  }
38  }
39  return var_names;
40  }
41 
42  std::unique_ptr<ExpressionParsing::ExpressionParser>
43  SingleParserHelper::createParser(ExpressionParsing::IProxyLoader &proxy_loader, const std::string &selection_string, [[maybe_unused]] unsigned short num_parser) {
44  assert( num_parser == 1);
45  std::unique_ptr<ExpressionParsing::ExpressionParser>
46  parser = std::make_unique<ExpressionParsing::ExpressionParser>(&proxy_loader );
47  parser->loadExpression( selection_string );
48  return parser;
49  }
50 
51  inline std::vector<std::string> SingleParserHelper::getVariables( const std::unique_ptr<ExpressionParsing::ExpressionParser> &parser ) {
52  return parser->getVariables();
53  }
54 
55 }
56 
57 template <class T_Base, unsigned short const NUM_PARSER>
58 StatusCode ExpressionParserUserBase<T_Base,NUM_PARSER>::_initializeParser(const ExpressionParsing::SelectionArg<NUM_PARSER> &selection_string,
59  ExpressionParsing::AppendLoaderFunc pre_xaod_loader,
60  ExpressionParsing::AppendLoaderFunc post_xaod_loader)
61 {
62  std::unique_ptr<ExpressionParsing::MultipleProxyLoader> proxyLoaders = std::make_unique<ExpressionParsing::MultipleProxyLoader>();
63 
64  StatusCode sc = pre_xaod_loader(*proxyLoaders);
65  if (sc.isFailure()) return sc;
66 
67  ExpressionParsing::IProxyLoader* loader = proxyLoaders->push_back
68  (std::make_unique<ExpressionParsing::SGxAODProxyLoader>(this->evtStore(), this->msgLvl(MSG::DEBUG)));
69  m_xAODProxyLoader = static_cast<ExpressionParsing::SGxAODProxyLoader*>(loader);
70 
71  sc = post_xaod_loader(*proxyLoaders);
72  if (sc.isFailure()) return sc;
73 
74  // load the expressions
75  m_proxyLoaders = std::move(proxyLoaders);
76  m_parser = ExpressionParsing::ParserHelper<NUM_PARSER>::createParser( *m_proxyLoaders, selection_string, NUM_PARSER );
77  return sc;
78 }
79 
80 template <class T_Base, unsigned short const NUM_PARSER>
81 StatusCode ExpressionParserUserBase<T_Base, NUM_PARSER>::finalizeParser() {
82  m_parser = {};
83  return StatusCode::SUCCESS;
84 }
85 
86 template <class T_Base, unsigned short const NUM_PARSER>
87 bool ExpressionParserUserBase<T_Base,NUM_PARSER>::updateDataNeeds(const std::vector<const DataObjID*> &input_data_in,
88  const std::vector<const DataObjID*> &output_data_in,
89  std::vector<Gaudi::DataHandle *> &new_input_handles,
90  std::vector<Gaudi::DataHandle *> &new_output_handles) {
91  if (!m_xAODProxyLoader) return false;
92  std::vector<std::string> var_names = ExpressionParsing::ParserHelper<NUM_PARSER>::getVariables(m_parser);
93 
94  auto parent = ExpressionParsing::SGxAODProxyLoader::wrapParent(this);
95  return m_xAODProxyLoader->updateDataDependencies(parent,var_names, m_renounce, input_data_in, output_data_in,new_input_handles,new_output_handles);
96 }
97 
98 template <class T_Base, unsigned short const NUM_PARSER>
99 bool ExpressionParserUserBase<T_Base,NUM_PARSER>::renounceInput( const DataObjID& output_data_id) {
100  if (m_xAODProxyLoader) {
101  std::vector<std::string> var_names = ExpressionParsing::ParserHelper<NUM_PARSER>::getVariables(m_parser);
102 
103  for (const std::string &var : var_names) {
104  if (output_data_id.key().find(var) != std::string::npos) {
105  m_renounce.push_back(output_data_id.key());
106  }
107  }
108  }
109  return T_Base::renounceInput(output_data_id);
110 }
111 
112 template <class T_Base, unsigned short const NUM_PARSER>
113 StatusCode ExpressionParserUser<T_Base, NUM_PARSER>::initializeParser(const ExpressionParsing::SelectionArg<NUM_PARSER> &selection_string) {
114  return this->_initializeParser(selection_string,
115  ExpressionParsing::NoLoaderFunc,
116  [this](ExpressionParsing::MultipleProxyLoader &proxy_loaders) -> StatusCode {
117  proxy_loaders.push_back(std::make_unique<ExpressionParsing::SGNTUPProxyLoader>(this->evtStore()));
118  return StatusCode::SUCCESS;
119  });
120 }