ATLAS Offline Software
Loading...
Searching...
No Matches
TrigEgammaPrecisionElectronHypoAlg.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
11
12namespace TCU = TrigCompositeUtils;
13
14TrigEgammaPrecisionElectronHypoAlg::TrigEgammaPrecisionElectronHypoAlg( const std::string& name, ISvcLocator* pSvcLocator ) :
15 ::HypoBase( name, pSvcLocator ) {}
16
17
19{
20
21 ATH_MSG_DEBUG ( "Initializing " << name() << "..." );
22
23 ATH_CHECK( m_hypoTools.retrieve() );
24
25 ATH_MSG_DEBUG( "Retrieving egammaElectronCBTool..." );
27
28 // Now we try to retrieve the ElectronPhotonSelectorTools that we will use to apply the electron Identification. This is a *must*
29 ATH_MSG_DEBUG( "Retrieving egammaElectronLHTool..." );
31 ATH_MSG_DEBUG( "Retrieving egammaElectronDNNTool..." );
33
34 // Retrieving Luminosity info
35 ATH_MSG_DEBUG( "Retrieving luminosityCondData..." );
36 ATH_CHECK( m_avgMuKey.initialize() );
37 ATH_CHECK( m_electronsKey.initialize() );
38 renounce( m_electronsKey );// electrons are made in views, so they are not in the EvtStore: hide them
39
43 ATH_CHECK( m_decorD0Key.initialize() );
44 ATH_CHECK( m_decorClEtaKey.initialize() );
45 ATH_CHECK( m_decorClPhiKey.initialize() );
46
47 if (! m_monTool.empty() ) ATH_CHECK( m_monTool.retrieve() );
48 return StatusCode::SUCCESS;
49}
50
51
52StatusCode TrigEgammaPrecisionElectronHypoAlg::execute( const EventContext& context ) const
53{
54
55 ATH_MSG_DEBUG ( "Executing " << name() << "..." );
56
57 auto timer = Monitored::Timer("TIME_exec");
58 auto timer_lh = Monitored::Timer("TIME_LH_exec");
59 auto timer_dnn = Monitored::Timer("TIME_DNN_exec");
60 auto monitoring = Monitored::Group( m_monTool, timer, timer_lh, timer_dnn);
61
62
63 timer.start();
64
65
66 auto previousDecisionsHandle = SG::makeHandle( decisionInput(), context );
67 ATH_CHECK( previousDecisionsHandle.isValid() );
68 ATH_MSG_DEBUG( "Running in precisionElectron step with "<< previousDecisionsHandle->size() <<" previous decisions");
69
70
71 // new decisions
72 // new output decisions
74 auto decisions = outputHandle.ptr();
75
76 // input for decision
77 std::vector<ITrigEgammaPrecisionElectronHypoTool::ElectronInfo> toolInput;
78
79 // loop over previous decisions
80 size_t counter=0;
81 for ( auto previousDecision: *previousDecisionsHandle ) {
82
83 //get updated RoI
84 auto roiELInfo = TCU::findLink<TrigRoiDescriptorCollection>( previousDecision, TCU::roiString() );
85
86 ATH_CHECK( roiELInfo.isValid() );
87 const TrigRoiDescriptor* roi = *(roiELInfo.link);
88 const auto viewEL = previousDecision->objectLink<ViewContainer>( TCU::viewString() );
89 ATH_CHECK( viewEL.isValid() );
90 auto electronHandle = ViewHelper::makeHandle( *viewEL, m_electronsKey, context);
91 ATH_CHECK( electronHandle.isValid() );
92 ATH_MSG_DEBUG ( "Precision Electron handle size: " << electronHandle->size() << "..." );
93
94 // Make decorators to output track d0 and cluster eta/phi
95 auto decor_d0 = ViewHelper::makeHandle<float> (*viewEL, m_decorD0Key, context);
96 auto decor_clEta = ViewHelper::makeHandle<float> (*viewEL, m_decorClEtaKey, context);
97 auto decor_clPhi = ViewHelper::makeHandle<float> (*viewEL, m_decorClPhiKey, context);
98
99 // This algorithm adds a few decorations to the input electrons.
100 // But sometimes we can be given views on which another instance of this
101 // algorithm has already run. We need to avoid redoing the decorations
102 // in that case, or we'll crash.
103 // We can even be given a mixture of views, some of which have
104 // the decorations already done and some not, so we can't really
105 // configure this statically.
106 // Test if the decoration is there, and trust that the overall
107 // configuration ensures that two threads won't try to write the
108 // same decoration at the same time.
109 bool hasDecor = decor_d0.isAvailable();
110
111 // Used for checking earlier decorations.
112 static const SG::ConstAccessor<float> acc_d0 (SG::decorKeyFromKey (m_decorD0Key.key()));
113 static const SG::ConstAccessor<float> acc_clEta (SG::decorKeyFromKey (m_decorClEtaKey.key()));
114 static const SG::ConstAccessor<float> acc_clPhi (SG::decorKeyFromKey (m_decorClPhiKey.key()));
115
116 // Loop over the electronHandles
117 size_t validelectrons=0;
118 for (const xAOD::Electron* ele : *electronHandle) {
119
120 {
121 auto el = ViewHelper::makeLink( *viewEL, electronHandle, ele->index() );
122 ATH_MSG_DEBUG ( "Checking el.isValid()...");
123 if( !el.isValid() ) {
124 ATH_MSG_DEBUG ( "Precision ElectronHandle in position " << ele->index() << " -> invalid ElemntLink!. Skipping...");
125 }
126
127 ATH_CHECK(el.isValid());
128 ATH_MSG_DEBUG ( "Precision ElectronHandle in position " << ele->index() << " processing...");
129 auto d = TCU::newDecisionIn( decisions, TCU::hypoAlgNodeName() );
130 d->setObjectLink( TCU::featureString(), el );
131 TCU::linkToPrevious( d, decisionInput().key(), counter );
132
133 // create the info
134 ITrigEgammaPrecisionElectronHypoTool::ElectronInfo info(d, roi, ele, previousDecision);
135
136 // Retrieve avgmu value from event info
138
139 if(eventInfoDecor.isPresent()){
140 float avg_mu = eventInfoDecor(0);
141 ATH_MSG_DEBUG("Average mu " << avg_mu);
142 info.valueDecorator["avgmu"] = avg_mu;
143 }
144
145 // Decorate the info with all CB decisions
146 for (std::size_t i = 0; i < m_cbNames.size(); ++i) {
147 auto const& pidname = m_cbNames[i];
148 info.pidDecorator[pidname] = (bool)m_egammaElectronCBTools[i]->accept(context, ele);
149 }
150
151 // Decorate the info with all LH decisions
152 ATH_MSG_DEBUG ("Using LH Tool..");
153 int idx=0;
154 for ( auto &pidname : m_lhNames ){
155 timer_lh.start();
156 if(eventInfoDecor.isPresent()) {
157 float avg_mu = eventInfoDecor(0);
158 float lhvalue = m_egammaElectronLHTools[idx]->calculate(context, ele,avg_mu);
159 info.valueDecorator[pidname+"LHValue"] = lhvalue;
160 info.pidDecorator[pidname] = (bool)m_egammaElectronLHTools[idx]->accept(context, ele,avg_mu);
161 }else{
162 float lhvalue = m_egammaElectronLHTools[idx]->calculate(context, ele);
163 info.valueDecorator[pidname+"LHValue"] = lhvalue;
164 ATH_MSG_WARNING("EventInfo decoration not available!");
165 info.pidDecorator[pidname] = (bool)m_egammaElectronLHTools[idx]->accept(context, ele);
166 }
167 timer_lh.stop();
168
169 idx++;
170 }
171
172 // Decorate the info with DNN decision
173 ATH_MSG_DEBUG ("Using DNN Tool..");
174 idx = 0;
175 for ( auto &pidname : m_dnnNames ){
176 ATH_MSG_DEBUG("pidname: "<<pidname);
177 timer_dnn.start();
178 if(eventInfoDecor.isPresent()) {
179 float avg_mu = eventInfoDecor(0);
180 info.pidDecorator[pidname] = (bool)m_egammaElectronDNNTools[idx]->accept(context, ele,avg_mu);
181 ATH_MSG_DEBUG("info.pidDecorator[pidname]: "<<info.pidDecorator[pidname]);
182 }else{
183 ATH_MSG_WARNING("EventInfo decoration not available!");
184 info.pidDecorator[pidname] = (bool)m_egammaElectronDNNTools[idx]->accept(context, ele);
185 ATH_MSG_DEBUG("info.pidDecorator[pidname]: "<<info.pidDecorator[pidname]);
186 }
187 timer_dnn.stop();
188 idx++;
189 }
190
191 // Add track d0 and cluster eta/phi decorations for output electrons
192 if (hasDecor) {
193 // If the decorations are already there, verify that they
194 // match what we would write.
195 if (acc_d0(*ele) != ele->trackParticle()->d0() ||
196 acc_clEta(*ele) != ele->caloCluster()->etaBE(2) ||
197 acc_clPhi(*ele) != ele->caloCluster()->phiBE(2))
198 {
199 ATH_MSG_ERROR( "Decoration mismatch: "
200 << acc_d0(*ele) << "<->" << ele->trackParticle()->d0()
201 << acc_clEta(*ele) << "<->" << ele->caloCluster()->etaBE(2)
202 << acc_clPhi(*ele) << "<->" << ele->caloCluster()->phiBE(2) );
203 }
204 }
205 else {
206 decor_d0(*ele) = ele->trackParticle()->d0();
207 decor_clEta(*ele) = ele->caloCluster()->etaBE(2);
208 decor_clPhi(*ele) = ele->caloCluster()->phiBE(2);
209 }
210
211 toolInput.push_back( info );
212 validelectrons++;
213 }
214 }
215
216 ATH_MSG_DEBUG( "Electrons with valid links: " << validelectrons );
217 ATH_MSG_DEBUG( "roi, electron, previous decision to new decision " << counter << " for roi " );
218 counter++;
219 }
220
221
222 ATH_MSG_DEBUG( "Found "<<toolInput.size()<<" inputs to tools");
223 for ( auto& tool: m_hypoTools ) {
224 ATH_CHECK( tool->decide( toolInput ) );
225 }
226
227 ATH_CHECK( hypoBaseOutputProcessing(outputHandle) );
228 return StatusCode::SUCCESS;
229}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Header file to be included by clients of the Monitored infrastructure.
DataVector< SG::View > ViewContainer
View container for recording in StoreGate.
Definition View.h:290
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)
const SG::ReadHandleKey< TrigCompositeUtils::DecisionContainer > & decisionInput() const
methods for derived classes to access handles of the base class input other read/write handles may be...
Definition HypoBase.cxx:18
const SG::WriteHandleKey< TrigCompositeUtils::DecisionContainer > & decisionOutput() const
methods for derived classes to access handles of the base class output other read/write handles may b...
Definition HypoBase.cxx:22
StatusCode hypoBaseOutputProcessing(SG::WriteHandle< TrigCompositeUtils::DecisionContainer > &outputHandle, MSG::Level lvl=MSG::DEBUG) const
Base class function to be called once slice specific code has finished. Handles debug printing and va...
Definition HypoBase.cxx:35
HypoBase(const std::string &name, ISvcLocator *pSvcLocator)
constructor, to be called by sub-class constructors
Definition HypoBase.cxx:12
Group of local monitoring quantities and retain correlation when filling histograms
A monitored timer.
Helper class to provide constant type-safe access to aux data.
Handle class for reading a decoration on an object.
bool isPresent() const
Is the referenced container present in SG?
pointer_type ptr()
Dereference the pointer.
virtual StatusCode execute(const EventContext &context) const override
SG::WriteDecorHandleKey< xAOD::ElectronContainer > m_decorD0Key
SG::ReadHandleKey< xAOD::ElectronContainer > m_electronsKey
PublicToolHandleArray< IAsgElectronIsEMSelector > m_egammaElectronCBTools
Gaudi::Property< std::vector< std::string > > m_dnnNames
Gaudi::Property< std::vector< std::string > > m_lhNames
ToolHandle< GenericMonitoringTool > m_monTool
PublicToolHandleArray< IAsgElectronLikelihoodTool > m_egammaElectronDNNTools
ToolHandleArray< ITrigEgammaPrecisionElectronHypoTool > m_hypoTools
SG::WriteDecorHandleKey< xAOD::ElectronContainer > m_decorClPhiKey
PublicToolHandleArray< IAsgElectronLikelihoodTool > m_egammaElectronLHTools
Gaudi::Property< std::vector< std::string > > m_cbNames
SG::ReadDecorHandleKey< xAOD::EventInfo > m_avgMuKey
SG::WriteDecorHandleKey< xAOD::ElectronContainer > m_decorClEtaKey
nope - should be used for standalone also, perhaps need to protect the class def bits ifndef XAOD_ANA...
std::string decorKeyFromKey(const std::string &key, const std::string &deflt)
Extract the decoration part of key.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
const std::string & viewString()
const std::string & roiString()
Decision * newDecisionIn(DecisionContainer *dc, const std::string &name)
Helper method to create a Decision object, place it in the container and return a pointer to it.
const std::string & featureString()
SG::WriteHandle< DecisionContainer > createAndStore(const SG::WriteHandleKey< DecisionContainer > &key, const EventContext &ctx)
Creates and right away records the DecisionContainer with the key.
const std::string & hypoAlgNodeName()
void linkToPrevious(Decision *d, const std::string &previousCollectionKey, size_t previousIndex)
Links to the previous object, location of previous 'seed' decision supplied by hand.
LinkInfo< T > findLink(const Decision *start, const std::string &linkName, const bool suppressMultipleLinksWarning=false)
Perform a recursive search for ElementLinks of type T and name 'linkName', starting from Decision obj...
ElementLink< T > makeLink(const SG::View *view, const SG::ReadHandle< T > &handle, size_t index)
Create EL to a collection in view.
Definition ViewHelper.h:309
auto makeHandle(const SG::View *view, const KEY &key, const EventContext &ctx)
Create a view handle from a handle key.
Definition ViewHelper.h:273
Electron_v1 Electron
Definition of the current "egamma version".