41 {
43
44
46 ATH_MSG_ERROR(
"excludeChargedElectronFE and includeChargedMuonFE are mutually exclusive!");
47 return StatusCode::FAILURE;
48 }
49
51 ATH_MSG_ERROR(
"excludeChargedElectronFE and includeChargedElectronFE are mutually exclusive!");
52 return StatusCode::FAILURE;
53 }
54
56 if (! ChargedPFlowObjects.isValid()){
58 return StatusCode::FAILURE;
59 }
60
62 if (! NeutralPFlowObjects.isValid()){
64 return StatusCode::FAILURE;
65 }
66
67 SG::ReadDecorHandle<xAOD::FlowElementContainer, std::vector< ElementLink<xAOD::ElectronContainer> > > chargedFE_ElectronLinks(
m_chargedFEElectronsReadDecorKey,ctx);
68 if (!chargedFE_ElectronLinks.isValid()){
69 ATH_MSG_ERROR(
"Can't retrieve input decoration " << chargedFE_ElectronLinks.key());
70 return StatusCode::FAILURE;
71 }
72
73 SG::ReadDecorHandle<xAOD::FlowElementContainer, std::vector< ElementLink<xAOD::MuonContainer> > > chargedFE_MuonLinks(
m_chargedFEMuonsReadDecorKey,ctx);
74 if (!chargedFE_MuonLinks.isValid()){
75 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< chargedFE_MuonLinks.key());
76 return StatusCode::FAILURE;
77 }
78
79 SG::ReadDecorHandle<xAOD::FlowElementContainer, std::vector< ElementLink<xAOD::ElectronContainer> > > neutralFE_ElectronLinks(
m_neutralFEElectronsReadDecorKey,ctx);
80 if (!neutralFE_ElectronLinks.isValid()){
81 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< neutralFE_ElectronLinks.key());
82 return StatusCode::FAILURE;
83 }
84
85 SG::ReadDecorHandle<xAOD::FlowElementContainer, std::vector< ElementLink<xAOD::MuonContainer> > > neutralFE_MuonLinks(
m_neutralFEMuonsReadDecorKey,ctx);
86 if (!neutralFE_MuonLinks.isValid()){
87 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< neutralFE_MuonLinks.key());
88 return StatusCode::FAILURE;
89 }
90
91 auto selectedChargedPFlowObjects = std::make_unique<xAOD::FlowElementContainer>();
92 auto selectedChargedPFlowObjectsAux = std::make_unique<xAOD::FlowElementAuxContainer>();
93 selectedChargedPFlowObjects->setStore(selectedChargedPFlowObjectsAux.get());
94
95 auto selectedNeutralPFlowObjects = std::make_unique<xAOD::FlowElementContainer>();
96 auto selectedNeutralPFlowObjectsAux = std::make_unique<xAOD::FlowElementAuxContainer>();
97 selectedNeutralPFlowObjects->setStore(selectedNeutralPFlowObjectsAux.get());
98
99
100 std::vector< const xAOD::FlowElement* > ChargedPFlowObjects_matched;
101
102 FEMuonHelper muonHelper;
103 FEElectronHelper electronHelper;
104
105
107
112
113 bool excludeChargedFE = false;
114
115
118
119
120
121
122
125
128
129
130 if ( !excludeChargedFE) {
132 selectedChargedPFlowObjects->push_back(selectedFE);
133 *selectedFE = *fe;
134 }
135 else {
136 ChargedPFlowObjects_matched.push_back(fe);
137 }
138
139 }
140
141
143
148
149
150
151
153 bool vetoElectron_IncludeMode = false;
156 if (vetoElectron_IncludeMode) continue;
157
159 selectedNeutralPFlowObjects->push_back(selectedFE);
160 *selectedFE = *fe;
161
162 bool excludeNeutralMuon = false;
163
164
166
167
168
169
172
173 if (excludeNeutralMuon) {
174
175
178 }
179
180 }
181
182
183
185
186
187 std::vector<std::pair<const xAOD::IParticle*,float> > theOtherPairs_charged = chargedFE->otherObjectsAndWeights();
188 std::vector<ElementLink<xAOD::IParticleContainer>> theOtherLinks_charged = chargedFE->otherObjectLinks();
189
190
191 for (unsigned int iCluster = 0; iCluster < chargedFE->nOtherObjects(); ++iCluster){
192
193 bool thisCluster_matched = false;
194
195 std::pair<const xAOD::IParticle*,float> theOtherPair_charged = theOtherPairs_charged[iCluster];
196 const xAOD::IParticle* theCluster_charged = theOtherPair_charged.first;
197 float theClusterWeight_charged = theOtherPair_charged.second;
198
199
201 if (thisCluster_matched) continue;
202
203
204 std::vector<std::pair<const xAOD::IParticle*,float> > theOtherPairs_neutral = neutralFE->otherObjectsAndWeights();
205 for (auto& [theCluster_neutral, theClusterWeight_neutral] : theOtherPairs_neutral){
206
207
208 if (theCluster_charged == theCluster_neutral){
209
210
211 float newEnergy = neutralFE->e() + theClusterWeight_charged;
212 neutralFE->setP4(newEnergy/cosh(neutralFE->eta()),
213 neutralFE->eta(),
214 neutralFE->phi(),
215 neutralFE->m());
216
217 ATH_MSG_DEBUG(
"Updated neutral FlowElement with E, pt, eta and phi: "
218 << neutralFE->e() << ", " << neutralFE->pt() << ", "
219 << neutralFE->eta() << " and " << neutralFE->phi());
220
221 thisCluster_matched = true;
222 }
223
224 }
225 }
226
227
228
229 if ( !thisCluster_matched && theCluster_charged ){
230
231
232 bool belongsToElectron = false;
234
235
236 unsigned int chargedClusterIndex = theCluster_charged->
index();
237
239 if (!electronReadHandle.isValid()){
241 return StatusCode::FAILURE;
242 }
243
244 for (auto thisElectron : *electronReadHandle){
246 for (auto thisElectronTopoCluster : electronTopoClusters){
247 if (thisElectronTopoCluster->index() == chargedClusterIndex){
248 belongsToElectron = true;
249 break;
250 }
251 }
252 }
253 }
254
255 if (belongsToElectron) continue;
256
257 double muonCaloEnergy = 0.0;
260 std::vector<double> muonCaloEnergies = chargedFE_energy_match_muonReadHandle(*chargedFE);
261 muonCaloEnergy = muonCaloEnergies[iCluster];
262 }
263
265 selectedNeutralPFlowObjects->push_back(newFE);
266
267 newFE->
setP4((theClusterWeight_charged - muonCaloEnergy) / cosh(theCluster_charged->
eta()),
268 theCluster_charged->
eta(),
269 theCluster_charged->
phi(),
270 theCluster_charged->
m());
273
274 ATH_MSG_DEBUG(
"Created neutral FlowElement with E, pt, eta and phi: "
275 << newFE->
e() <<
", " << newFE->
pt() <<
", "
276 << newFE->
eta() <<
" and " << newFE->
phi());
277
278 std::vector<ElementLink<xAOD::IParticleContainer>> theClusters;
279 ElementLink< xAOD::IParticleContainer > theIParticleLink;
280 theIParticleLink.
resetWithKeyAndIndex(theOtherLinks_charged[iCluster].persKey(), theOtherLinks_charged[iCluster].persIndex());
281
282 theClusters.push_back(theIParticleLink);
284
285
286 FEHelpers::FillNeutralFlowElements FEFiller;
290
291 float layerEnergy_TileBar0 = castCluster_charged->
eSample(xAOD::CaloCluster::CaloSample::TileBar0);
292 float layerEnergy_TileExt0 = castCluster_charged->
eSample(xAOD::CaloCluster::CaloSample::TileExt0);
293 const static SG::AuxElement::Accessor<float> accFloatTIle0E("LAYERENERGY_TILE0");
294 accFloatTIle0E(*newFE) = layerEnergy_TileBar0 + layerEnergy_TileExt0;
295
296 const static SG::AuxElement::Accessor<float> accFloatTiming("TIMING");
297 accFloatTiming(*newFE) = castCluster_charged->
time();
298 }
299
300 }
301 }
302
303
305 if (!handle_ChargedPFlow_out.record(std::move(selectedChargedPFlowObjects), std::move(selectedChargedPFlowObjectsAux)) ){
307 return StatusCode::FAILURE;
308 }
309
311 if (!handle_NeutralPFlow_out.record(std::move(selectedNeutralPFlowObjects), std::move(selectedNeutralPFlowObjectsAux)) ){
313 return StatusCode::FAILURE;
314 }
315
316 return StatusCode::SUCCESS;
317}
void resetWithKeyAndIndex(const ID_type &dataID, index_type elemID, IProxyDict *sg=0)
Set the link to an element given by string key and index.
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_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
size_t index() const
Return the index of this element within its container.
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".