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