38 return StatusCode::SUCCESS;
46 ATH_MSG_ERROR(
"excludeChargedElectronFE and includeChargedMuonFE are mutually exclusive!");
47 return StatusCode::FAILURE;
51 ATH_MSG_ERROR(
"excludeChargedElectronFE and includeChargedElectronFE are mutually exclusive!");
52 return StatusCode::FAILURE;
56 if (! ChargedPFlowObjects.
isValid()){
58 return StatusCode::FAILURE;
62 if (! NeutralPFlowObjects.
isValid()){
64 return StatusCode::FAILURE;
68 if (!chargedFE_ElectronLinks.isValid()){
69 ATH_MSG_ERROR(
"Can't retrieve input decoration " << chargedFE_ElectronLinks.key());
70 return StatusCode::FAILURE;
74 if (!chargedFE_MuonLinks.isValid()){
75 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< chargedFE_MuonLinks.key());
76 return StatusCode::FAILURE;
80 if (!neutralFE_ElectronLinks.isValid()){
81 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< neutralFE_ElectronLinks.key());
82 return StatusCode::FAILURE;
86 if (!neutralFE_MuonLinks.isValid()){
87 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< neutralFE_MuonLinks.key());
88 return StatusCode::FAILURE;
91 auto selectedChargedPFlowObjects = std::make_unique<xAOD::FlowElementContainer>();
92 auto selectedChargedPFlowObjectsAux = std::make_unique<xAOD::FlowElementAuxContainer>();
93 selectedChargedPFlowObjects->setStore(selectedChargedPFlowObjectsAux.get());
95 auto selectedNeutralPFlowObjects = std::make_unique<xAOD::FlowElementContainer>();
96 auto selectedNeutralPFlowObjectsAux = std::make_unique<xAOD::FlowElementAuxContainer>();
97 selectedNeutralPFlowObjects->setStore(selectedNeutralPFlowObjectsAux.get());
100 std::vector< const xAOD::FlowElement* > ChargedPFlowObjects_matched;
113 bool excludeChargedFE =
false;
130 if ( !excludeChargedFE) {
132 selectedChargedPFlowObjects->push_back(selectedFE);
136 ChargedPFlowObjects_matched.push_back(fe);
153 bool vetoElectron_IncludeMode =
false;
156 if (vetoElectron_IncludeMode)
continue;
159 selectedNeutralPFlowObjects->push_back(selectedFE);
162 bool excludeNeutralMuon =
false;
173 if (excludeNeutralMuon) {
187 std::vector<std::pair<const xAOD::IParticle*,float> > theOtherPairs_charged = chargedFE->otherObjectsAndWeights();
188 std::vector<ElementLink<xAOD::IParticleContainer>> theOtherLinks_charged = chargedFE->otherObjectLinks();
191 for (
unsigned int iCluster = 0; iCluster < chargedFE->nOtherObjects(); ++iCluster){
193 bool thisCluster_matched =
false;
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;
201 if (thisCluster_matched)
continue;
204 std::vector<std::pair<const xAOD::IParticle*,float> > theOtherPairs_neutral = neutralFE->otherObjectsAndWeights();
205 for (
auto& [theCluster_neutral, theClusterWeight_neutral] : theOtherPairs_neutral){
208 if (theCluster_charged == theCluster_neutral){
211 float newEnergy = neutralFE->
e() + theClusterWeight_charged;
212 neutralFE->setP4(newEnergy/cosh(neutralFE->eta()),
217 ATH_MSG_DEBUG(
"Updated neutral FlowElement with E, pt, eta and phi: "
218 << neutralFE->e() <<
", " << neutralFE->pt() <<
", "
219 << neutralFE->eta() <<
" and " << neutralFE->phi());
221 thisCluster_matched =
true;
229 if ( !thisCluster_matched && theCluster_charged ){
232 bool belongsToElectron =
false;
236 unsigned int chargedClusterIndex = theCluster_charged->
index();
239 if (!electronReadHandle.
isValid()){
241 return StatusCode::FAILURE;
244 for (
auto thisElectron : *electronReadHandle){
246 for (
auto thisElectronTopoCluster : electronTopoClusters){
247 if (thisElectronTopoCluster->index() == chargedClusterIndex){
248 belongsToElectron =
true;
255 if (belongsToElectron)
continue;
257 double muonCaloEnergy = 0.0;
260 std::vector<double> muonCaloEnergies = chargedFE_energy_match_muonReadHandle(*chargedFE);
261 muonCaloEnergy = muonCaloEnergies[iCluster];
265 selectedNeutralPFlowObjects->push_back(newFE);
267 newFE->
setP4((theClusterWeight_charged - muonCaloEnergy) / cosh(theCluster_charged->
eta()),
268 theCluster_charged->
eta(),
269 theCluster_charged->
phi(),
270 theCluster_charged->
m());
272 newFE->
setSignalType(xAOD::FlowElement::SignalType::NeutralPFlow);
274 ATH_MSG_DEBUG(
"Created neutral FlowElement with E, pt, eta and phi: "
275 << newFE->
e() <<
", " << newFE->
pt() <<
", "
276 << newFE->
eta() <<
" and " << newFE->
phi());
278 std::vector<ElementLink<xAOD::IParticleContainer>> theClusters;
280 theIParticleLink.
resetWithKeyAndIndex(theOtherLinks_charged[iCluster].persKey(), theOtherLinks_charged[iCluster].persIndex());
282 theClusters.push_back(theIParticleLink);
294 accFloatTIle0E(*newFE) = layerEnergy_TileBar0 + layerEnergy_TileExt0;
297 accFloatTiming(*newFE) = castCluster_charged->
time();
305 if (!handle_ChargedPFlow_out.record(std::move(selectedChargedPFlowObjects), std::move(selectedChargedPFlowObjectsAux)) ){
307 return StatusCode::FAILURE;
311 if (!handle_NeutralPFlow_out.record(std::move(selectedNeutralPFlowObjects), std::move(selectedNeutralPFlowObjectsAux)) ){
313 return StatusCode::FAILURE;
316 return StatusCode::SUCCESS;