38 return StatusCode::SUCCESS;
45 if (! ChargedPFlowObjects.
isValid()){
47 return StatusCode::FAILURE;
51 if (! NeutralPFlowObjects.
isValid()){
53 return StatusCode::FAILURE;
57 if (!chargedFE_ElectronLinks.isValid()){
58 ATH_MSG_ERROR(
"Can't retrieve input decoration " << chargedFE_ElectronLinks.key());
59 return StatusCode::FAILURE;
63 if (!chargedFE_MuonLinks.isValid()){
64 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< chargedFE_MuonLinks.key());
65 return StatusCode::FAILURE;
69 if (!neutralFE_ElectronLinks.isValid()){
70 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< neutralFE_ElectronLinks.key());
71 return StatusCode::FAILURE;
75 if (!neutralFE_MuonLinks.isValid()){
76 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< neutralFE_MuonLinks.key());
77 return StatusCode::FAILURE;
80 auto selectedChargedPFlowObjects = std::make_unique<xAOD::FlowElementContainer>();
81 auto selectedChargedPFlowObjectsAux = std::make_unique<xAOD::FlowElementAuxContainer>();
82 selectedChargedPFlowObjects->setStore(selectedChargedPFlowObjectsAux.get());
84 auto selectedNeutralPFlowObjects = std::make_unique<xAOD::FlowElementContainer>();
85 auto selectedNeutralPFlowObjectsAux = std::make_unique<xAOD::FlowElementAuxContainer>();
86 selectedNeutralPFlowObjects->setStore(selectedNeutralPFlowObjectsAux.get());
89 std::vector< const xAOD::FlowElement* > ChargedPFlowObjects_matched;
100 selectedChargedPFlowObjects->push_back(selectedFE);
104 ChargedPFlowObjects_matched.push_back(fe);
119 selectedNeutralPFlowObjects->push_back(selectedFE);
138 std::vector<std::pair<const xAOD::IParticle*,float> > theOtherPairs_charged = chargedFE->otherObjectsAndWeights();
139 std::vector<ElementLink<xAOD::IParticleContainer>> theOtherLinks_charged = chargedFE->otherObjectLinks();
142 for (
unsigned int iCluster = 0; iCluster < chargedFE->nOtherObjects(); ++iCluster){
144 bool thisCluster_matched =
false;
146 std::pair<const xAOD::IParticle*,float> theOtherPair_charged = theOtherPairs_charged[iCluster];
147 const xAOD::IParticle* theCluster_charged = theOtherPair_charged.first;
148 float theClusterWeight_charged = theOtherPair_charged.second;
152 if (thisCluster_matched)
continue;
155 std::vector<std::pair<const xAOD::IParticle*,float> > theOtherPairs_neutral = neutralFE->otherObjectsAndWeights();
156 for (
auto& [theCluster_neutral, theClusterWeight_neutral] : theOtherPairs_neutral){
159 if (theCluster_charged == theCluster_neutral){
162 float newEnergy = neutralFE->
e() + theClusterWeight_charged;
163 neutralFE->setP4(newEnergy/cosh(neutralFE->eta()),
168 ATH_MSG_DEBUG(
"Updated neutral FlowElement with E, pt, eta and phi: "
169 << neutralFE->e() <<
", " << neutralFE->pt() <<
", "
170 << neutralFE->eta() <<
" and " << neutralFE->phi());
172 thisCluster_matched =
true;
180 if ( !thisCluster_matched && theCluster_charged ){
183 bool belongsToElectron =
false;
187 unsigned int chargedClusterIndex = theCluster_charged->
index();
190 if (!electronReadHandle.
isValid()){
192 return StatusCode::FAILURE;
195 for (
auto thisElectron : *electronReadHandle){
197 for (
auto thisElectronTopoCluster : electronTopoClusters){
198 if (thisElectronTopoCluster->index() == chargedClusterIndex){
199 belongsToElectron =
true;
206 if (belongsToElectron)
continue;
208 bool belongsToMuon =
false;
209 double muonCaloEnergy = 0.0;
212 std::vector<double> muonCaloEnergies = chargedFE_energy_match_muonReadHandle(*chargedFE);
213 muonCaloEnergy = muonCaloEnergies[iCluster];
216 if (belongsToMuon)
continue;
219 selectedNeutralPFlowObjects->push_back(newFE);
221 newFE->
setP4((theClusterWeight_charged - muonCaloEnergy) / cosh(theCluster_charged->
eta()),
222 theCluster_charged->
eta(),
223 theCluster_charged->
phi(),
224 theCluster_charged->
m());
226 newFE->
setSignalType(xAOD::FlowElement::SignalType::NeutralPFlow);
228 ATH_MSG_DEBUG(
"Created neutral FlowElement with E, pt, eta and phi: "
229 << newFE->
e() <<
", " << newFE->
pt() <<
", "
230 << newFE->
eta() <<
" and " << newFE->
phi());
232 std::vector<ElementLink<xAOD::IParticleContainer>> theClusters;
234 theIParticleLink.
resetWithKeyAndIndex(theOtherLinks_charged[iCluster].persKey(), theOtherLinks_charged[iCluster].persIndex());
236 theClusters.push_back(theIParticleLink);
248 accFloatTIle0E(*newFE) = layerEnergy_TileBar0 + layerEnergy_TileExt0;
251 accFloatTiming(*newFE) = castCluster_charged->
time();
259 if (!handle_ChargedPFlow_out.record(std::move(selectedChargedPFlowObjects), std::move(selectedChargedPFlowObjectsAux)) ){
261 return StatusCode::FAILURE;
265 if (!handle_NeutralPFlow_out.record(std::move(selectedNeutralPFlowObjects), std::move(selectedNeutralPFlowObjectsAux)) ){
267 return StatusCode::FAILURE;
270 return StatusCode::SUCCESS;