42 {
44
45
47 ATH_MSG_ERROR(
"excludeChargedElectronFE and includeChargedMuonFE are mutually exclusive!");
48 return StatusCode::FAILURE;
49 }
50
52 ATH_MSG_ERROR(
"excludeChargedElectronFE and includeChargedElectronFE are mutually exclusive!");
53 return StatusCode::FAILURE;
54 }
55
57 if (! ChargedPFlowObjects.isValid()){
59 return StatusCode::FAILURE;
60 }
61
63 if (! NeutralPFlowObjects.isValid()){
65 return StatusCode::FAILURE;
66 }
67
68 SG::ReadDecorHandle<xAOD::FlowElementContainer, std::vector< ElementLink<xAOD::ElectronContainer> > > chargedFE_ElectronLinks(
m_chargedFEElectronsReadDecorKey,ctx);
69 if (!chargedFE_ElectronLinks.isValid()){
70 ATH_MSG_ERROR(
"Can't retrieve input decoration " << chargedFE_ElectronLinks.key());
71 return StatusCode::FAILURE;
72 }
73
74 SG::ReadDecorHandle<xAOD::FlowElementContainer, std::vector< ElementLink<xAOD::MuonContainer> > > chargedFE_MuonLinks(
m_chargedFEMuonsReadDecorKey,ctx);
75 if (!chargedFE_MuonLinks.isValid()){
76 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< chargedFE_MuonLinks.key());
77 return StatusCode::FAILURE;
78 }
79
80 SG::ReadDecorHandle<xAOD::FlowElementContainer, std::vector< ElementLink<xAOD::ElectronContainer> > > neutralFE_ElectronLinks(
m_neutralFEElectronsReadDecorKey,ctx);
81 if (!neutralFE_ElectronLinks.isValid()){
82 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< neutralFE_ElectronLinks.key());
83 return StatusCode::FAILURE;
84 }
85
86 SG::ReadDecorHandle<xAOD::FlowElementContainer, std::vector< ElementLink<xAOD::MuonContainer> > > neutralFE_MuonLinks(
m_neutralFEMuonsReadDecorKey,ctx);
87 if (!neutralFE_MuonLinks.isValid()){
88 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< neutralFE_MuonLinks.key());
89 return StatusCode::FAILURE;
90 }
91
92 auto selectedChargedPFlowObjects = std::make_unique<xAOD::FlowElementContainer>();
93 auto selectedChargedPFlowObjectsAux = std::make_unique<xAOD::FlowElementAuxContainer>();
94 selectedChargedPFlowObjects->setStore(selectedChargedPFlowObjectsAux.get());
95
96 auto selectedNeutralPFlowObjects = std::make_unique<xAOD::FlowElementContainer>();
97 auto selectedNeutralPFlowObjectsAux = std::make_unique<xAOD::FlowElementAuxContainer>();
98 selectedNeutralPFlowObjects->setStore(selectedNeutralPFlowObjectsAux.get());
99
100
101 std::vector< const xAOD::FlowElement* > ChargedPFlowObjects_matched;
102
103 FEMuonHelper muonHelper;
104 FEElectronHelper electronHelper;
105
106
108
109 bool isMuonToExclude;
110 bool isMuonToInclude;
112 isMuonToExclude = false;
113 isMuonToInclude = false;
114 } else {
117 }
120
121 bool excludeChargedFE = false;
122
123
126
127
128
129
130
133
136
137
138 if ( !excludeChargedFE) {
140 selectedChargedPFlowObjects->push_back(selectedFE);
141 *selectedFE = *fe;
142 }
143 else {
144 ChargedPFlowObjects_matched.push_back(fe);
145 }
146
147 }
148
149
151
152 bool isMuonToExclude;
153 bool isMuonToInclude;
155 isMuonToExclude = false;
156 isMuonToInclude = false;
157 } else {
160 }
163
164
165
166
168 bool vetoElectron_IncludeMode = false;
171 if (vetoElectron_IncludeMode) continue;
172
174 selectedNeutralPFlowObjects->push_back(selectedFE);
175 *selectedFE = *fe;
176
177 bool excludeNeutralMuon = false;
178
179
181
182
183
184
187
188 if (excludeNeutralMuon) {
189
190
193 }
194
195 }
196
197
198
200
201
202 std::vector<std::pair<const xAOD::IParticle*,float> > theOtherPairs_charged = chargedFE->otherObjectsAndWeights();
203 std::vector<ElementLink<xAOD::IParticleContainer>> theOtherLinks_charged = chargedFE->otherObjectLinks();
204
205
206 for (unsigned int iCluster = 0; iCluster < chargedFE->nOtherObjects(); ++iCluster){
207
208 bool thisCluster_matched = false;
209
210 std::pair<const xAOD::IParticle*,float> theOtherPair_charged = theOtherPairs_charged[iCluster];
211 const xAOD::IParticle* theCluster_charged = theOtherPair_charged.first;
212 float theClusterWeight_charged = theOtherPair_charged.second;
213
214
216 if (thisCluster_matched) continue;
217
218
219 std::vector<std::pair<const xAOD::IParticle*,float> > theOtherPairs_neutral = neutralFE->otherObjectsAndWeights();
220 for (auto& [theCluster_neutral, theClusterWeight_neutral] : theOtherPairs_neutral){
221
222
223 if (theCluster_charged == theCluster_neutral){
224
225
226 float newEnergy = neutralFE->e() + theClusterWeight_charged;
227 neutralFE->setP4(newEnergy/cosh(neutralFE->eta()),
228 neutralFE->eta(),
229 neutralFE->phi(),
230 neutralFE->m());
231
232 ATH_MSG_DEBUG(
"Updated neutral FlowElement with E, pt, eta and phi: "
233 << neutralFE->e() << ", " << neutralFE->pt() << ", "
234 << neutralFE->eta() << " and " << neutralFE->phi());
235
236 thisCluster_matched = true;
237 }
238
239 }
240 }
241
242
243
244 if ( !thisCluster_matched && theCluster_charged ){
245
246
247 bool belongsToElectron = false;
249
250
251 unsigned int chargedClusterIndex = theCluster_charged->index();
252
254 if (!electronReadHandle.isValid()){
256 return StatusCode::FAILURE;
257 }
258
259 for (auto thisElectron : *electronReadHandle){
261 for (auto thisElectronTopoCluster : electronTopoClusters){
262 if (thisElectronTopoCluster->index() == chargedClusterIndex){
263 belongsToElectron = true;
264 break;
265 }
266 }
267 }
268 }
269
270 if (belongsToElectron) continue;
271
272 double muonCaloEnergy = 0.0;
275 std::vector<double> muonCaloEnergies = chargedFE_energy_match_muonReadHandle(*chargedFE);
276 muonCaloEnergy = muonCaloEnergies[iCluster];
277 }
278
280 selectedNeutralPFlowObjects->push_back(newFE);
281
282 newFE->
setP4((theClusterWeight_charged - muonCaloEnergy) / cosh(theCluster_charged->
eta()),
283 theCluster_charged->
eta(),
284 theCluster_charged->
phi(),
285 theCluster_charged->
m());
288
289 ATH_MSG_DEBUG(
"Created neutral FlowElement with E, pt, eta and phi: "
290 << newFE->
e() <<
", " << newFE->
pt() <<
", "
291 << newFE->
eta() <<
" and " << newFE->
phi());
292
293 std::vector<ElementLink<xAOD::IParticleContainer>> theClusters;
294 ElementLink< xAOD::IParticleContainer > theIParticleLink;
295 theIParticleLink.
resetWithKeyAndIndex(theOtherLinks_charged[iCluster].persKey(), theOtherLinks_charged[iCluster].persIndex());
296
297 theClusters.push_back(theIParticleLink);
299
300
301 FEHelpers::FillNeutralFlowElements FEFiller;
305
306 float layerEnergy_TileBar0 = castCluster_charged->
eSample(xAOD::CaloCluster::CaloSample::TileBar0);
307 float layerEnergy_TileExt0 = castCluster_charged->
eSample(xAOD::CaloCluster::CaloSample::TileExt0);
308 const static SG::AuxElement::Accessor<float> accFloatTIle0E("LAYERENERGY_TILE0");
309 accFloatTIle0E(*newFE) = layerEnergy_TileBar0 + layerEnergy_TileExt0;
310
311 const static SG::AuxElement::Accessor<float> accFloatTiming("TIMING");
312 accFloatTiming(*newFE) = castCluster_charged->
time();
313 }
314
315 }
316 }
317
318
320 if (!handle_ChargedPFlow_out.record(std::move(selectedChargedPFlowObjects), std::move(selectedChargedPFlowObjectsAux)) ){
322 return StatusCode::FAILURE;
323 }
324
326 if (!handle_NeutralPFlow_out.record(std::move(selectedNeutralPFlowObjects), std::move(selectedNeutralPFlowObjectsAux)) ){
328 return StatusCode::FAILURE;
329 }
330
331 return StatusCode::SUCCESS;
332}
void resetWithKeyAndIndex(const ID_type &key, index_type index, xAOD::TVirtualEvent *event=0)
Reset with storable key and element index (fast).
bool checkElectronLinks(const std::vector< ElementLink< xAOD::ElectronContainer > > &FE_ElectronLinks, const std::string &qualityString) const
void addStandardSamplingEnergies(xAOD::FlowElement &theFE, const xAOD::CaloCluster &theCluster)
void addStandardMoments(xAOD::FlowElement &theFE, const xAOD::CaloCluster &theCluster)
bool checkMuonLinks(const std::vector< ElementLink< xAOD::MuonContainer > > &FE_MuonLinks, const std::string &qualityString) const
Verify if at least one combined muon in a list passes the relevant quality criteria Details of muon w...
TLorentzVector adjustNeutralCaloEnergy(const std::vector< double > &clusterMuonEnergyFracs, const xAOD::FlowElement &theFE) const
SG::WriteHandleKey< xAOD::FlowElementContainer > m_outputNeutralPFlowHandleKey
SG::ReadDecorHandleKey< xAOD::FlowElementContainer > m_neutralFEElectronsReadDecorKey
SG::ReadHandleKey< xAOD::ElectronContainer > m_electronContainerKey
SG::ReadHandleKey< xAOD::FlowElementContainer > m_ChargedPFlowContainerKey
Gaudi::Property< std::string > m_electronIDToInclude
Gaudi::Property< std::string > m_muonIDToInclude
Gaudi::Property< bool > m_includeChargedElectronFE
Gaudi::Property< bool > m_excludeNeutralMuonFE
SG::ReadDecorHandleKey< xAOD::FlowElementContainer > m_chargedFEMuonsReadDecorKey
Gaudi::Property< bool > m_excludeNeutralElectronFE
SG::ReadDecorHandleKey< xAOD::FlowElementContainer > m_neutralFEMuonsReadDecorKey
Gaudi::Property< bool > m_includeChargedMuonFE
Gaudi::Property< bool > m_includeNeutralMuonFE
SG::ReadDecorHandleKey< xAOD::FlowElementContainer > m_chargedFE_energy_match_muonReadHandleKey
Gaudi::Property< std::string > m_muonIDToExclude
Gaudi::Property< bool > m_excludeChargedElectronFE
Gaudi::Property< bool > m_excludeChargedMuonFE
SG::ReadDecorHandleKey< xAOD::FlowElementContainer > m_neutralFEMuons_efrac_match_DecorKey
Gaudi::Property< bool > m_isEgammaPEB
Gaudi::Property< bool > m_includeNeutralElectronFE
SG::ReadHandleKey< xAOD::FlowElementContainer > m_NeutralPFlowContainerKey
Gaudi::Property< std::string > m_electronIDToExclude
SG::WriteHandleKey< xAOD::FlowElementContainer > m_outputChargedPFlowHandleKey
SG::ReadDecorHandleKey< xAOD::FlowElementContainer > m_chargedFEElectronsReadDecorKey
flt_t time() const
Access cluster time.
float eSample(const CaloSample sampling) const
virtual double pt() const override
void setP4(float pt, float eta, float phi, float m)
virtual double phi() const override
The azimuthal angle ( ) of the particle.
virtual double eta() const override
The pseudorapidity ( ) of the particle.
void setSignalType(signal_t t)
void setOtherObjectLinks(const std::vector< ElementLink< IParticleContainer > > &elV)
virtual double e() const override
The total energy of the particle.
virtual double eta() const =0
The pseudorapidity ( ) of the particle.
virtual double m() const =0
The invariant mass of the particle.
virtual double phi() const =0
The azimuthal angle ( ) of the particle.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
std::vector< const xAOD::CaloCluster * > getAssociatedTopoClusters(const xAOD::CaloCluster *cluster)
Return a vector of all the topo clusters associated with the egamma cluster.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
FlowElement_v1 FlowElement
Definition of the current "pfo version".