47 ATH_MSG_ERROR(
"excludeChargedElectronFE and includeChargedMuonFE are mutually exclusive!");
48 return StatusCode::FAILURE;
52 ATH_MSG_ERROR(
"excludeChargedElectronFE and includeChargedElectronFE are mutually exclusive!");
53 return StatusCode::FAILURE;
57 if (! ChargedPFlowObjects.
isValid()){
59 return StatusCode::FAILURE;
63 if (! NeutralPFlowObjects.
isValid()){
65 return StatusCode::FAILURE;
69 if (!chargedFE_ElectronLinks.isValid()){
70 ATH_MSG_ERROR(
"Can't retrieve input decoration " << chargedFE_ElectronLinks.key());
71 return StatusCode::FAILURE;
75 if (!chargedFE_MuonLinks.isValid()){
76 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< chargedFE_MuonLinks.key());
77 return StatusCode::FAILURE;
81 if (!neutralFE_ElectronLinks.isValid()){
82 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< neutralFE_ElectronLinks.key());
83 return StatusCode::FAILURE;
87 if (!neutralFE_MuonLinks.isValid()){
88 ATH_MSG_ERROR(
"Can't retrieve input decoration "<< neutralFE_MuonLinks.key());
89 return StatusCode::FAILURE;
92 auto selectedChargedPFlowObjects = std::make_unique<xAOD::FlowElementContainer>();
93 auto selectedChargedPFlowObjectsAux = std::make_unique<xAOD::FlowElementAuxContainer>();
94 selectedChargedPFlowObjects->setStore(selectedChargedPFlowObjectsAux.get());
96 auto selectedNeutralPFlowObjects = std::make_unique<xAOD::FlowElementContainer>();
97 auto selectedNeutralPFlowObjectsAux = std::make_unique<xAOD::FlowElementAuxContainer>();
98 selectedNeutralPFlowObjects->setStore(selectedNeutralPFlowObjectsAux.get());
101 std::vector< const xAOD::FlowElement* > ChargedPFlowObjects_matched;
109 bool isMuonToExclude;
110 bool isMuonToInclude;
112 isMuonToExclude =
false;
113 isMuonToInclude =
false;
121 bool excludeChargedFE =
false;
138 if ( !excludeChargedFE) {
140 selectedChargedPFlowObjects->push_back(selectedFE);
144 ChargedPFlowObjects_matched.push_back(fe);
152 bool isMuonToExclude;
153 bool isMuonToInclude;
155 isMuonToExclude =
false;
156 isMuonToInclude =
false;
168 bool vetoElectron_IncludeMode =
false;
171 if (vetoElectron_IncludeMode)
continue;
174 selectedNeutralPFlowObjects->push_back(selectedFE);
177 bool excludeNeutralMuon =
false;
188 if (excludeNeutralMuon) {
202 std::vector<std::pair<const xAOD::IParticle*,float> > theOtherPairs_charged = chargedFE->otherObjectsAndWeights();
203 std::vector<ElementLink<xAOD::IParticleContainer>> theOtherLinks_charged = chargedFE->otherObjectLinks();
206 for (
unsigned int iCluster = 0; iCluster < chargedFE->nOtherObjects(); ++iCluster){
208 bool thisCluster_matched =
false;
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;
216 if (thisCluster_matched)
continue;
219 std::vector<std::pair<const xAOD::IParticle*,float> > theOtherPairs_neutral = neutralFE->otherObjectsAndWeights();
220 for (
auto& [theCluster_neutral, theClusterWeight_neutral] : theOtherPairs_neutral){
223 if (theCluster_charged == theCluster_neutral){
226 float newEnergy = neutralFE->e() + theClusterWeight_charged;
227 neutralFE->setP4(newEnergy/cosh(neutralFE->eta()),
232 ATH_MSG_DEBUG(
"Updated neutral FlowElement with E, pt, eta and phi: "
233 << neutralFE->e() <<
", " << neutralFE->pt() <<
", "
234 << neutralFE->eta() <<
" and " << neutralFE->phi());
236 thisCluster_matched =
true;
244 if ( !thisCluster_matched && theCluster_charged ){
247 bool belongsToElectron =
false;
251 unsigned int chargedClusterIndex = theCluster_charged->index();
254 if (!electronReadHandle.
isValid()){
256 return StatusCode::FAILURE;
259 for (
auto thisElectron : *electronReadHandle){
261 for (
auto thisElectronTopoCluster : electronTopoClusters){
262 if (thisElectronTopoCluster->index() == chargedClusterIndex){
263 belongsToElectron =
true;
270 if (belongsToElectron)
continue;
272 double muonCaloEnergy = 0.0;
275 std::vector<double> muonCaloEnergies = chargedFE_energy_match_muonReadHandle(*chargedFE);
276 muonCaloEnergy = muonCaloEnergies[iCluster];
280 selectedNeutralPFlowObjects->push_back(newFE);
282 newFE->
setP4((theClusterWeight_charged - muonCaloEnergy) / cosh(theCluster_charged->
eta()),
283 theCluster_charged->
eta(),
284 theCluster_charged->
phi(),
285 theCluster_charged->
m());
289 ATH_MSG_DEBUG(
"Created neutral FlowElement with E, pt, eta and phi: "
290 << newFE->
e() <<
", " << newFE->
pt() <<
", "
291 << newFE->
eta() <<
" and " << newFE->
phi());
293 std::vector<ElementLink<xAOD::IParticleContainer>> theClusters;
295 theIParticleLink.
resetWithKeyAndIndex(theOtherLinks_charged[iCluster].persKey(), theOtherLinks_charged[iCluster].persIndex());
297 theClusters.push_back(theIParticleLink);
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;
311 const static SG::AuxElement::Accessor<float> accFloatTiming(
"TIMING");
312 accFloatTiming(*newFE) = castCluster_charged->
time();
320 if (!handle_ChargedPFlow_out.record(std::move(selectedChargedPFlowObjects), std::move(selectedChargedPFlowObjectsAux)) ){
322 return StatusCode::FAILURE;
326 if (!handle_NeutralPFlow_out.record(std::move(selectedNeutralPFlowObjects), std::move(selectedNeutralPFlowObjectsAux)) ){
328 return StatusCode::FAILURE;
331 return StatusCode::SUCCESS;
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.