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 EventContext& ctx)
const
162 return StatusCode::SUCCESS;
166 std::vector<const xAOD::IParticle*>& pfolist,
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() );
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,
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 EventContext& ctx)
const
319 return StatusCode::SUCCESS;
324 std::vector<const xAOD::IParticle*>& felist,
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);
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,
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.
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
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
StatusCode extractPFOsFromLinks(const xAOD::Egamma *eg, std::vector< const xAOD::IParticle * > &pfolist, const met::METAssociator::ConstitHolder &constits, const EventContext &ctx) const
SG::ReadDecorHandleKey< xAOD::ElectronContainer > m_electronChargedPFOReadDecorKey
virtual 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 EventContext &ctx) 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
virtual 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 EventContext &ctx) const final
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
StatusCode extractFEsFromLinks(const xAOD::Egamma *eg, std::vector< const xAOD::IParticle * > &felist, const met::METAssociator::ConstitHolder &constits, const EventContext &ctx) const
SG::ReadDecorHandleKey< xAOD::ElectronContainer > m_electronNeutralFEReadDecorKey
virtual ~METEgammaAssociator()
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
StatusCode extractTopoClusters(const xAOD::IParticle *obj, std::vector< const xAOD::IParticle * > &tclist, const met::METAssociator::ConstitHolder &constits, const EventContext &ctx) const final
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 final
The transverse momentum ( ) of the particle.
virtual Type::ObjectType type() const override=0
The type of the object as a simple enumeration, remains pure virtual in e/gamma.
uint16_t author(uint16_t bitmask=EgammaParameters::AuthorALL) const
Get author.
const Egamma_v1 * ambiguousObject() const
Get ambiguous.
virtual FourMom_t p4() const override final
The full 4-momentum of the particle as a TLoretzVector.
const xAOD::CaloCluster * caloCluster(size_t index=0) const
Pointer to the xAOD::CaloCluster/s that define the electron candidate.
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.
bool isCharged() const
is a charged PFO
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.
SG::Decorator< T, ALLOC > Decorator
Helper class to provide type-safe access to aux data, specialized for JaggedVecElt.
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