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);
111 std::sort(inputTC.begin(),inputTC.end(),
greaterPt);
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,
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 ) ||
248 ( pfo->isCharged() && PVMatchedAcc(*pfo)
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.;
275 std::sort(nearbyPFO.begin(),nearbyPFO.end(),
greaterPtPFO);
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,
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.;
437 std::sort(nearbyFE.begin(),nearbyFE.end(),
greaterPtFE);
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 ) {
508 if(fe_itr->isCharged() && !PVMatchedAcc(*fe_itr)){
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;