72 return StatusCode::FAILURE;
75 return StatusCode::SUCCESS;
81 return StatusCode::SUCCESS;
88 std::vector<const xAOD::IParticle*>& tclist,
99 std::vector<const IParticle*> inputTC;
103 for(
const auto *
const cl : *constits.
tcCont) {
107 inputTC.push_back(cl);
115 for(
const auto& el : tcLinkAcc(*swclus)) {
117 inputTC.push_back(*el);
119 ATH_MSG_ERROR(
"Invalid constituentClusterLinks on input electron/photon!");
120 return StatusCode::FAILURE;
126 return StatusCode::FAILURE;
131 return StatusCode::SUCCESS;
136 std::vector<const xAOD::IParticle*>& constlist,
140 std::set<const xAOD::TrackParticle*> trackset;
142 for(
const auto&
track : trackset) {
144 constlist.push_back(
track);
147 return StatusCode::SUCCESS;
151 std::vector<const xAOD::IParticle*>& pfolist,
153 std::map<const IParticle*,MissingETBase::Types::constvec_t> &)
const
162 return StatusCode::SUCCESS;
166 std::vector<const xAOD::IParticle*>& pfolist,
170 ATH_MSG_DEBUG(
"Extract PFOs From Links for " << eg->type() <<
" with pT " << eg->pt());
172 std::vector<PFOLink_t> cPFOLinks;
173 std::vector<PFOLink_t> nPFOLinks;
178 nPFOLinks=neutralPFOReadDecorHandle(*eg);
179 cPFOLinks=chargedPFOReadDecorHandle(*eg);
184 nPFOLinks=neutralPFOReadDecorHandle(*eg);
185 cPFOLinks=chargedPFOReadDecorHandle(*eg);
190 for (
const PFOLink_t& pfoLink : cPFOLinks) {
191 if (!pfoLink.isValid())
continue;
193 for (
const auto *
const pfo : *constits.
pfoCont){
194 if (pfo->index() == pfo_init->
index() && pfo->isCharged()){
197 ATH_MSG_DEBUG(
"Accept cPFO with pt " << pfo->pt() <<
", e " << pfo->e() <<
", eta " << pfo->eta() <<
", phi " << pfo->phi() );
205 double eg_cl_e = eg->caloCluster()->e();
206 double sumE_pfo = 0.;
208 for (
const PFOLink_t& pfoLink : nPFOLinks) {
209 if (!pfoLink.isValid())
continue;
211 for (
const auto *
const pfo : *constits.
pfoCont){
212 if (pfo->index() == pfo_init->
index() && !pfo->isCharged()){
213 double pfo_e = pfo->eEM();
214 if( ( !pfo->isCharged()&& pfo->e() > FLT_MIN ) ){
216 ATH_MSG_DEBUG(
"E match with new nPFO: " << fabs(sumE_pfo+pfo_e - eg_cl_e) / eg_cl_e);
217 ATH_MSG_DEBUG(
"Accept nPFO with pt " << pfo->pt() <<
", e " << pfo->e() <<
", eta " << pfo->eta() <<
", phi " << pfo->phi() <<
" in sum.");
218 ATH_MSG_DEBUG(
"Energy ratio of nPFO to eg: " << pfo_e / eg_cl_e);
219 pfolist.push_back(pfo);
226 return StatusCode::SUCCESS;
230 std::vector<const xAOD::IParticle*>& pfolist,
237 ANA_MSG_VERBOSE(
"Extract PFOs with DeltaR for " << eg->type() <<
" with pT " << eg->pt());
240 std::vector<const xAOD::PFO*> nearbyPFO;
241 nearbyPFO.reserve(20);
242 for(
const auto *
const pfo : *constits.
pfoCont) {
247 if( ( !pfo->isCharged() && pfo->e() > FLT_MIN ) ||
251 nearbyPFO.push_back(pfo);
257 std::set<const xAOD::TrackParticle*> trackset;
259 for(
const auto&
track : trackset) {
260 for(
const auto& pfo : nearbyPFO) {
261 if(pfo->isCharged() && pfo->track(0) ==
track) {
262 pfolist.push_back(pfo);
266 double eg_cl_e = swclus->
e();
273 double sumE_pfo = 0.;
276 for(
const auto& pfo : nearbyPFO) {
280 double pfo_e = pfo->eEM();
283 ATH_MSG_VERBOSE(
"Reject topocluster in sum. Ratio vs eg cluster: " << (pfo_e/eg_cl_e));
284 if( !bestbadmatch || (fabs(pfo_e/eg_cl_e-1.) < fabs(bestbadmatch->
e()/eg_cl_e-1.)) ) bestbadmatch = pfo;
288 ATH_MSG_VERBOSE(
"E match with new nPFO: " << fabs(sumE_pfo+pfo_e - eg_cl_e) / eg_cl_e);
289 if( (doSum = fabs(sumE_pfo+pfo_e-eg_cl_e) < fabs(sumE_pfo - eg_cl_e)) ) {
290 pfolist.push_back(pfo);
292 ATH_MSG_VERBOSE(
"Accept pfo with pt " << pfo->pt() <<
", e " << pfo->e() <<
" in sum.");
294 ATH_MSG_VERBOSE(
"E match with new PFO: " << fabs(sumE_pfo+pfo_e - eg_cl_e) / eg_cl_e);
298 if(sumE_pfo<FLT_MIN && bestbadmatch) {
299 ATH_MSG_VERBOSE(
"No better matches found -- add bad match topocluster with pt "
300 << bestbadmatch->
pt() <<
", e " << bestbadmatch->
e() <<
".");
301 pfolist.push_back(bestbadmatch);
304 return StatusCode::SUCCESS;
308 std::vector<const xAOD::IParticle*>& felist,
310 std::map<const IParticle*,MissingETBase::Types::constvec_t> &)
const
319 return StatusCode::SUCCESS;
324 std::vector<const xAOD::IParticle*>& felist,
328 ATH_MSG_DEBUG(
"Extract FEs From Links for " << eg->type() <<
" with pT " << eg->pt());
330 std::vector<FELink_t> nFELinks;
331 std::vector<FELink_t> cFELinks;
336 nFELinks=neutralFEReadDecorHandle(*eg);
337 cFELinks=chargedFEReadDecorHandle(*eg);
342 nFELinks=neutralFEReadDecorHandle(*eg);
343 cFELinks=chargedFEReadDecorHandle(*eg);
348 for (
const FELink_t& feLink : cFELinks) {
349 if (!feLink.isValid())
continue;
351 for (
const auto *
const fe : *constits.
feCont){
352 if (fe->index() == fe_init->
index() && fe->isCharged()){
355 ATH_MSG_DEBUG(
"Accept cFE with pt " << fe->pt() <<
", e " << fe->e() <<
", eta " << fe->eta() <<
", phi " << fe->phi() );
356 felist.push_back(fe);
363 double eg_cl_e = eg->caloCluster()->e();
366 for (
const FELink_t& feLink : nFELinks) {
367 if (!feLink.isValid())
continue;
369 for (
const auto *
const fe : *constits.
feCont){
370 if (fe->index() == fe_init->
index() && !fe->isCharged()){
371 double fe_e = fe->e();
372 if( ( !fe->isCharged()&& fe->e() > FLT_MIN ) ){
374 ATH_MSG_DEBUG(
"E match with new nFE: " << fabs(sumE_fe+fe_e - eg_cl_e) / eg_cl_e);
375 ATH_MSG_DEBUG(
"Accept nFE with pt " << fe->pt() <<
", e " << fe->e() <<
", eta " << fe->eta() <<
", phi " << fe->phi() <<
" in sum.");
376 ATH_MSG_DEBUG(
"Energy ratio of nFE to eg: " << fe_e / eg_cl_e);
377 felist.push_back(fe);
384 return StatusCode::SUCCESS;
388 std::vector<const xAOD::IParticle*>& felist,
391 ATH_MSG_VERBOSE(
"Extract FEs From DeltaR for " << eg->type() <<
" with pT " << eg->pt());
398 std::vector<const xAOD::FlowElement*> nearbyFE;
399 nearbyFE.reserve(20);
402 ATH_MSG_ERROR(
"Attempted to extract non-PFlow FlowElements. This is not supported!");
403 return StatusCode::FAILURE;
409 if( ( !fe->
isCharged() && fe->
e() > FLT_MIN ) ||
413 nearbyFE.push_back(fe);
417 ATH_MSG_VERBOSE(
"Found " << nearbyFE.size() <<
" nearby FlowElements (PFOs)");
419 std::set<const xAOD::TrackParticle*> trackset;
424 felist.push_back(fe);
428 double eg_cl_e = swclus->
e();
435 double sumE_pfo = 0.;
443 double pfo_e = fe->
e();
446 ATH_MSG_VERBOSE(
"Reject topocluster in sum. Ratio vs eg cluster: " << (pfo_e/eg_cl_e));
447 if( !bestbadmatch || (fabs(pfo_e/eg_cl_e-1.) < fabs(bestbadmatch->
e()/eg_cl_e-1.)) ) bestbadmatch = fe;
451 ATH_MSG_VERBOSE(
"E match with new nPFO: " << fabs(sumE_pfo+pfo_e - eg_cl_e) / eg_cl_e);
452 if( (doSum = fabs(sumE_pfo+pfo_e-eg_cl_e) < fabs(sumE_pfo - eg_cl_e)) ) {
453 felist.push_back(fe);
455 ATH_MSG_VERBOSE(
"Accept pfo with pt " << fe->
pt() <<
", e " << fe->
e() <<
" in sum.");
457 ATH_MSG_VERBOSE(
"E match with new PFO: " << fabs(sumE_pfo+pfo_e - eg_cl_e) / eg_cl_e);
461 if(sumE_pfo<FLT_MIN && bestbadmatch) {
462 ATH_MSG_VERBOSE(
"No better matches found -- add bad match topocluster with pt "
463 << bestbadmatch->
pt() <<
", e " << bestbadmatch->
e() <<
".");
464 felist.push_back(bestbadmatch);
467 return StatusCode::SUCCESS;
474 std::vector<const xAOD::IParticle*> hardObjs,
475 std::vector<const xAOD::IParticle*>& felist,
477 std::map<const IParticle*,MissingETBase::Types::constvec_t> & ,
484 return StatusCode::SUCCESS;
489 for(
const auto fe : *constits.
feCont) {
491 if( ( !fe->isCharged() && fe->e() > FLT_MIN ) ||
493 felist.push_back(fe);
502 for(
const auto fe_itr : *constits.
feCont) {
503 if( fe_itr->pt() < 0 || fe_itr->e() < 0 ) {
515 std::vector<const xAOD::Egamma*> v_eg;
516 for(
const auto& obj_i : hardObjs){
518 v_eg.push_back( eg_curr );
522 for(
const auto fe_i : *constits.
feCont) {
523 if( fe_i->pt() < 0 || fe_i->e() < 0 ) {
527 for(
const auto& eg_i : v_eg) {
528 double dR =
P4Helpers::deltaR( fe_i->eta(), fe_i->phi(), eg_i->eta(), eg_i->phi() );
537 std::vector<TLorentzVector> v_egTLV;
538 v_egTLV.reserve(v_eg.size());
539 for(
const auto& eg_i : v_eg) {
540 v_egTLV.push_back( eg_i->p4() );
544 TLorentzVector egTLV = eg->p4();
550 return StatusCode::SUCCESS;
557 const std::vector<const IParticle*>& inputTC,
558 std::vector<const xAOD::IParticle*>& tclist)
const
560 double eg_cl_e = swclus->
e();
565 for(
const auto& cl : inputTC) {
566 double tcl_e = cl->e();
570 ATH_MSG_VERBOSE(
"Reject topocluster in sum. Ratio vs eg cluster: " << (tcl_e/eg_cl_e));
571 if( !bestbadmatch || (fabs(tcl_e/eg_cl_e-1.) < fabs(bestbadmatch->
e()/eg_cl_e-1.)) ) bestbadmatch = cl;
575 ATH_MSG_VERBOSE(
"E match with new cluster: " << fabs(sumE_tc+tcl_e - eg_cl_e) / eg_cl_e);
576 if( (doSum = (fabs(sumE_tc+tcl_e - eg_cl_e) < fabs(sumE_tc - eg_cl_e))) ) {
577 ATH_MSG_VERBOSE(
"Accept topocluster with pt " << cl->pt() <<
", e " << cl->e() <<
" in sum.");
579 ATH_MSG_VERBOSE(
"E match with new cluster: " << fabs(sumE_tc+tcl_e - eg_cl_e) / eg_cl_e);
580 tclist.push_back(cl);
584 if(sumE_tc<FLT_MIN && bestbadmatch) {
585 ATH_MSG_VERBOSE(
"No better matches found -- add bad match topocluster with pt "
586 << bestbadmatch->
pt() <<
", e " << bestbadmatch->
e() <<
".");
587 tclist.push_back(bestbadmatch);
589 return StatusCode::SUCCESS;
594 std::set<const xAOD::TrackParticle*>& tracklist)
const
599 for(
const auto&
track : egtracks) {
601 tracklist.insert(
track);
608 for(
const auto&
track : egtracks) {
610 tracklist.insert(
track);
615 for(
const auto *
const track : *trkCont) {
618 uint8_t expect_innermostHit(
false);
620 uint8_t expect_nextToInnermostHit(
false);
621 uint8_t N_nextToInnermostHit(
false);
624 ATH_MSG_WARNING(
"Track summary retrieval failed for 'expect(NextTo)InnermostPixelLayerHit'");
625 return StatusCode::FAILURE;
627 if(expect_innermostHit) {
629 ATH_MSG_WARNING(
"Track summary retrieval failed for 'numberOfInnermostPixelLayerHits'");
630 return StatusCode::FAILURE;
631 if(N_innermostHit==0 ) {
633 tracklist.insert(
track);
636 }
else if(expect_nextToInnermostHit) {
638 ATH_MSG_WARNING(
"Track summary retrieval failed for 'numberOfNextToInnermostPixelLayerHits'");
639 return StatusCode::FAILURE;
640 if(N_nextToInnermostHit==0 ) {
642 tracklist.insert(
track);
649 return StatusCode::SUCCESS;
655 bool has_unmatched=
false;
657 float unmatchedSumpt=0;
659 float unmatchedTotEMFrac=0;
670 TLorentzVector totVec(0.,0.,0.,0.), unmatchedVec(0.,0.,0.,0.);
672 std::set<const xAOD::CaloCluster*> cPFOClusters;
675 for (
int cl = 0; cl < nCluscPFO; ++cl) {
679 std::vector<const xAOD::CaloCluster*> unmatchedClusters;
681 TLorentzVector tmpVec;
682 tmpVec.SetPtEtaPhiE(pfoclus->pt(),pfoclus->eta(),pfoclus->phi(),pfoclus->e());
683 totSumpt+=pfoclus->pt();
685 bool inEgamma =
false;
687 if (pfoclus == phclus) {
692 unmatchedClusters.push_back(pfoclus);
693 unmatchedSumpt+=pfoclus->pt();
694 unmatchedE+=pfoclus->e();
695 unmatchedVec+=tmpVec;
697 unmatchedTotEMFrac=unmatchedTotEMFrac+emfrac*pfoclus->e();
702 ATH_MSG_DEBUG(
"PFO associated to "<<nCluscPFO<<
" cluster, of which " << unmatchedClusters.size() <<
"unmatched one and unmatched pt "<<unmatchedSumpt);
703 dec_unmatchedFrac(*pfo)=nCluscPFO>0 ?
float(unmatchedClusters.size())/
float(nCluscPFO) : -1;
704 dec_unmatchedFracPt(*pfo)= totVec.Pt()>0 ?
float(unmatchedVec.Pt()/totVec.Pt()): -1;
705 dec_unmatchedFracSumpt(*pfo)= totSumpt>0 ?
float(unmatchedSumpt/totSumpt): -1;
706 dec_unmatchedFracE(*pfo)= totVec.E()>0 ?
float(unmatchedE/totVec.E()): -1;
707 dec_unmatchedTotEMFrac(*pfo)= totVec.E()>0 ?
float(unmatchedTotEMFrac/totVec.E()): -1;
708 dec_unmatchedFracEClusterPFO(*pfo)= pfo->
e()>0 ?
float(unmatchedE/pfo->
e()): -1;
709 dec_unmatchedFracPtClusterPFO(*pfo)= pfo->
pt()>0 ?
float(unmatchedE/pfo->
pt()): -1;
711 return has_unmatched;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
ElementLink< xAOD::PFOContainer > PFOLink_t
ElementLink< xAOD::PhotonContainer > PhotonLink_t
ElementLink< xAOD::ElectronContainer > ElectronLink_t
ElementLink< xAOD::FlowElementContainer > FELink_t
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ElementLink implementation for ROOT usage.
SG::ConstAccessor< T, ALLOC > ConstAccessor
SG::Decorator< T, ALLOC > Decorator
size_t index() const
Return the index of this element within its container.
Helper class to provide constant type-safe access to aux data.
Handle class for reading a decoration on an object.
SG::ReadDecorHandleKey< xAOD::PhotonContainer > m_photonNeutralFEReadDecorKey
StatusCode extractTopoClusters(const xAOD::IParticle *obj, std::vector< const xAOD::IParticle * > &tclist, const met::METAssociator::ConstitHolder &constits) const final
SG::ReadDecorHandleKey< xAOD::ElectronContainer > m_electronNeutralPFOReadDecorKey
StatusCode selectEgammaClusters(const xAOD::CaloCluster *swclus, const std::vector< const xAOD::IParticle * > &inputTC, std::vector< const xAOD::IParticle * > &tclist) const
SG::ReadDecorHandleKey< xAOD::ElectronContainer > m_electronChargedFEReadDecorKey
SG::ReadDecorHandleKey< xAOD::ElectronContainer > m_electronChargedPFOReadDecorKey
StatusCode extractFE(const xAOD::IParticle *obj, std::vector< const xAOD::IParticle * > &felist, const met::METAssociator::ConstitHolder &constits, std::map< const xAOD::IParticle *, MissingETBase::Types::constvec_t > &momenta) const final
StatusCode extractFEHR(const xAOD::IParticle *obj, std::vector< const xAOD::IParticle * > hardObjs, std::vector< const xAOD::IParticle * > &felist, const met::METAssociator::ConstitHolder &constits, std::map< const xAOD::IParticle *, MissingETBase::Types::constvec_t > &momenta, float &UEcorr) const final
StatusCode extractFEsFromLinks(const xAOD::Egamma *eg, std::vector< const xAOD::IParticle * > &felist, const met::METAssociator::ConstitHolder &constits) const
StatusCode initialize()
Dummy implementation of the initialisation function.
StatusCode extractTracks(const xAOD::IParticle *obj, std::vector< const xAOD::IParticle * > &constlist, const met::METAssociator::ConstitHolder &constits) const final
SG::ReadDecorHandleKey< xAOD::PhotonContainer > m_photonNeutralPFOReadDecorKey
StatusCode selectEgammaTracks(const xAOD::Egamma *el, const xAOD::TrackParticleContainer *trkCont, std::set< const xAOD::TrackParticle * > &tracklist) const
SG::ReadDecorHandleKey< xAOD::PhotonContainer > m_photonChargedPFOReadDecorKey
bool hasUnmatchedClusters(const xAOD::Egamma *eg, const xAOD::PFO *pfo) const
SG::ReadDecorHandleKey< xAOD::ElectronContainer > m_electronNeutralFEReadDecorKey
StatusCode extractPFO(const xAOD::IParticle *obj, std::vector< const xAOD::IParticle * > &pfolist, const met::METAssociator::ConstitHolder &constits, std::map< const xAOD::IParticle *, MissingETBase::Types::constvec_t > &momenta) const final
virtual ~METEgammaAssociator()
StatusCode extractPFOsFromLinks(const xAOD::Egamma *eg, std::vector< const xAOD::IParticle * > &pfolist, const met::METAssociator::ConstitHolder &constits) const
StatusCode extractPFOs(const xAOD::Egamma *eg, std::vector< const xAOD::IParticle * > &pfolist, const met::METAssociator::ConstitHolder &constits) const
static constexpr float m_MinDistCone
unsigned short m_tcMatch_method
static constexpr float m_Drcone
double m_extraTrkMatch_dR
StatusCode extractFEs(const xAOD::Egamma *eg, std::vector< const xAOD::IParticle * > &felist, const met::METAssociator::ConstitHolder &constits) const
SG::ReadDecorHandleKey< xAOD::PhotonContainer > m_photonChargedFEReadDecorKey
METEgammaAssociator()
Default constructor:
virtual double e() const
The total energy of the particle.
@ ENG_FRAC_EM
Energy fraction in EM calorimeters.
virtual double pt() const override
signal_t signalType() const
const xAOD::IParticle * chargedObject(std::size_t i) const
virtual double e() const override
The total energy of the particle.
Class providing the definition of the 4-vector interface.
virtual double pt() const =0
The transverse momentum ( ) of the particle.
virtual double e() const =0
The total energy of the particle.
unsigned int nCaloCluster() const
Find out how many CaloCluster are linked.
virtual double e() const
The total energy of the particle.
virtual double pt() const
The transverse momentum ( ) of the particle.
const CaloCluster * cluster(unsigned int index) const
Retrieve a const pointer to a CaloCluster.
static const SG::ConstAccessor< char > PVMatchedAcc("matchedToPV")
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
@ Photon
The object is a photon.
@ Electron
The object is an electron.
std::set< const xAOD::TrackParticle * > getTrackParticles(const xAOD::Egamma *eg, bool useBremAssoc=true, bool allParticles=true)
Return a list of all or only the best TrackParticle associated to the object.
std::vector< const xAOD::CaloCluster * > getAssociatedTopoClusters(const xAOD::CaloCluster *cluster)
Return a vector of all the topo clusters associated with the egamma cluster.
const uint16_t AuthorAmbiguous
Object Reconstructed by standard cluster-based algorithm.
bool isInDeltaR(const xAOD::IParticle &p1, const xAOD::IParticle &p2, double dR, bool useRapidity=true)
Check if 2 xAOD::IParticle are in a cone.
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
PFO_v1 PFO
Definition of the current "pfo version".
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
FlowElement_v1 FlowElement
Definition of the current "pfo version".
TrackParticle_v1 TrackParticle
Reference the current persistent version:
Egamma_v1 Egamma
Definition of the current "egamma version".
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
@ expectInnermostPixelLayerHit
Do we expect a 0th-layer barrel hit for this track?
@ numberOfNextToInnermostPixelLayerHits
these are the hits in the 1st pixel barrel layer
@ expectNextToInnermostPixelLayerHit
Do we expect a 1st-layer barrel hit for this track?
@ numberOfInnermostPixelLayerHits
these are the hits in the 0th pixel barrel layer