CMS 3D CMS Logo

List of all members | Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes
PFEGammaAlgo Class Reference

#include <PFEGammaAlgo.h>

Classes

struct  EgammaObjects
 
class  GBRForests
 
struct  PFEGConfigInfo
 
struct  ProtoEGObject
 

Public Types

using ClusterMap = std::unordered_map< PFClusterElement const *, std::vector< PFClusterElement const * > >
 
typedef reco::PFCluster::EEtoPSAssociation EEtoPSAssociation
 
typedef std::unordered_map< const PFKFElement *, float > KFValMap
 
typedef reco::PFBlockElementBrem PFBremElement
 
typedef reco::PFBlockElementCluster PFClusterElement
 
typedef reco::PFBlockElementGsfTrack PFGSFElement
 
typedef reco::PFBlockElementTrack PFKFElement
 
typedef reco::PFBlockElementSuperCluster PFSCElement
 

Public Member Functions

EgammaObjects operator() (const reco::PFBlockRef &block)
 
 PFEGammaAlgo (const PFEGConfigInfo &, GBRForests const &gbrForests, EEtoPSAssociation const &eetops, ESEEIntercalibConstants const &esEEInterCalib, ESChannelStatus const &channelStatus, reco::Vertex const &primaryVertex)
 

Private Member Functions

int attachPSClusters (const PFClusterElement *, ClusterMap::mapped_type &)
 
reco::SuperCluster buildRefinedSuperCluster (const ProtoEGObject &)
 
float calculateEleMVA (const ProtoEGObject &, reco::PFCandidateEGammaExtra &) const
 
void dumpCurrentRefinableObjects () const
 
float evaluateSingleLegMVA (const reco::PFBlockRef &blockref, const reco::Vertex &primaryVtx, unsigned int trackIndex)
 
void fillExtraInfo (const ProtoEGObject &, reco::PFCandidateEGammaExtra &)
 
EgammaObjects fillPFCandidates (const std::list< ProtoEGObject > &)
 
void initializeProtoCands (std::list< ProtoEGObject > &)
 
bool isMuon (const reco::PFBlockElement &)
 
bool isPrimaryTrack (const reco::PFBlockElementTrack &KfEl, const reco::PFBlockElementGsfTrack &GsfEl)
 
void linkKFTrackToECAL (PFKFElement const *, ProtoEGObject &)
 
void linkRefinableObjectBremTangentsToECAL (ProtoEGObject &)
 
void linkRefinableObjectConvSecondaryKFsToSecondaryKFs (ProtoEGObject &)
 
void linkRefinableObjectECALToSingleLegConv (ProtoEGObject &)
 
void linkRefinableObjectGSFTracksToKFs (ProtoEGObject &)
 
void linkRefinableObjectKFTracksToECAL (ProtoEGObject &)
 
void linkRefinableObjectPrimaryGSFTrackToECAL (ProtoEGObject &)
 
void linkRefinableObjectPrimaryGSFTrackToHCAL (ProtoEGObject &)
 
void linkRefinableObjectPrimaryKFsToSecondaryKFs (ProtoEGObject &)
 
void linkRefinableObjectSecondaryKFsToECAL (ProtoEGObject &)
 
void mergeROsByAnyLink (std::list< ProtoEGObject > &)
 
void removeOrLinkECALClustersToKFTracks ()
 
void unlinkRefinableObjectKFandECALMatchedToHCAL (ProtoEGObject &, bool removeFreeECAL=false, bool removeSCECAL=false)
 
void unlinkRefinableObjectKFandECALWithBadEoverP (ProtoEGObject &)
 
bool unwrapSuperCluster (const reco::PFBlockElementSuperCluster *, std::vector< FlaggedPtr< const PFClusterElement >> &, ClusterMap &)
 

Private Attributes

reco::PFBlockRef _currentblock
 
reco::PFBlock::LinkData _currentlinks
 
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
 
PFEGConfigInfo const & cfg_
 
ESChannelStatus const & channelStatus_
 
reco::PFCluster::EEtoPSAssociation const & eetops_
 
GBRForests const & gbrForests_
 
reco::Vertex const & primaryVertex_
 
PFEnergyCalibration thePFEnergyCalibration_
 

Detailed Description

Definition at line 62 of file PFEGammaAlgo.h.

Member Typedef Documentation

◆ ClusterMap

using PFEGammaAlgo::ClusterMap = std::unordered_map<PFClusterElement const*, std::vector<PFClusterElement const*> >

Definition at line 72 of file PFEGammaAlgo.h.

◆ EEtoPSAssociation

Definition at line 64 of file PFEGammaAlgo.h.

◆ KFValMap

typedef std::unordered_map<const PFKFElement*, float> PFEGammaAlgo::KFValMap

Definition at line 70 of file PFEGammaAlgo.h.

◆ PFBremElement

Definition at line 66 of file PFEGammaAlgo.h.

◆ PFClusterElement

Definition at line 69 of file PFEGammaAlgo.h.

◆ PFGSFElement

Definition at line 67 of file PFEGammaAlgo.h.

◆ PFKFElement

Definition at line 68 of file PFEGammaAlgo.h.

◆ PFSCElement

Definition at line 65 of file PFEGammaAlgo.h.

Constructor & Destructor Documentation

◆ PFEGammaAlgo()

PFEGammaAlgo::PFEGammaAlgo ( const PFEGConfigInfo cfg,
GBRForests const &  gbrForests,
EEtoPSAssociation const &  eetops,
ESEEIntercalibConstants const &  esEEInterCalib,
ESChannelStatus const &  channelStatus,
reco::Vertex const &  primaryVertex 
)

Definition at line 446 of file PFEGammaAlgo.cc.

References PFEnergyCalibration::initAlphaGamma_ESplanes_fromDB(), and thePFEnergyCalibration_.

452  : gbrForests_(gbrForests),
453  eetops_(eetops),
454  cfg_(cfg),
456  channelStatus_(channelStatus) {
458 }
reco::PFCluster::EEtoPSAssociation const & eetops_
Definition: PFEGammaAlgo.h:143
GBRForests const & gbrForests_
Definition: PFEGammaAlgo.h:135
reco::Vertex const & primaryVertex_
Definition: PFEGammaAlgo.h:222
void initAlphaGamma_ESplanes_fromDB(const ESEEIntercalibConstants *esEEInterCalib)
PFEGConfigInfo const & cfg_
Definition: PFEGammaAlgo.h:221
PFEnergyCalibration thePFEnergyCalibration_
Definition: PFEGammaAlgo.h:137
primaryVertex
hltOfflineBeamSpot for HLTMON
ESChannelStatus const & channelStatus_
Definition: PFEGammaAlgo.h:224

Member Function Documentation

◆ attachPSClusters()

int PFEGammaAlgo::attachPSClusters ( const PFClusterElement ,
ClusterMap::mapped_type &   
)
private

Definition at line 902 of file PFEGammaAlgo.cc.

References _splayedblock, a, b, docast, PFLayer::ECAL_BARREL, eetops_, edm::Ptr< T >::key(), reco::PFBlockElement::PS1, reco::PFBlockElement::PS2, edm::refToPtr(), and groupFilesInBlocks::temp.

Referenced by linkKFTrackToECAL(), linkRefinableObjectBremTangentsToECAL(), linkRefinableObjectPrimaryGSFTrackToECAL(), linkRefinableObjectSecondaryKFsToECAL(), and unwrapSuperCluster().

902  {
903  if (ecalclus->clusterRef()->layer() == PFLayer::ECAL_BARREL)
904  return 0;
905  edm::Ptr<reco::PFCluster> clusptr = refToPtr(ecalclus->clusterRef());
906  EEtoPSElement ecalkey(clusptr.key(), clusptr);
907  auto assc_ps =
908  std::equal_range(eetops_.cbegin(), eetops_.cend(), ecalkey, [](const EEtoPSElement& a, const EEtoPSElement& b) {
909  return a.first < b.first;
910  });
911  for (const auto& ps1 : _splayedblock[reco::PFBlockElement::PS1]) {
912  edm::Ptr<reco::PFCluster> temp = refToPtr(ps1->clusterRef());
913  for (auto pscl = assc_ps.first; pscl != assc_ps.second; ++pscl) {
914  if (pscl->second == temp) {
915  const ClusterElement* pstemp = docast(const ClusterElement*, ps1.get());
916  eslist.emplace_back(pstemp);
917  }
918  }
919  }
920  for (const auto& ps2 : _splayedblock[reco::PFBlockElement::PS2]) {
921  edm::Ptr<reco::PFCluster> temp = refToPtr(ps2->clusterRef());
922  for (auto pscl = assc_ps.first; pscl != assc_ps.second; ++pscl) {
923  if (pscl->second == temp) {
924  const ClusterElement* pstemp = docast(const ClusterElement*, ps2.get());
925  eslist.emplace_back(pstemp);
926  }
927  }
928  }
929  return eslist.size();
930 }
reco::PFCluster::EEtoPSAssociation const & eetops_
Definition: PFEGammaAlgo.h:143
Ptr< typename C::value_type > refToPtr(Ref< C, typename C::value_type, refhelper::FindUsingAdvance< C, typename C::value_type > > const &ref)
Definition: RefToPtr.h:18
double b
Definition: hdecay.h:118
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
key_type key() const
Definition: Ptr.h:163
double a
Definition: hdecay.h:119
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148

◆ buildRefinedSuperCluster()

reco::SuperCluster PFEGammaAlgo::buildRefinedSuperCluster ( const ProtoEGObject RO)
private

Definition at line 1791 of file PFEGammaAlgo.cc.

References reco::SuperCluster::addCluster(), reco::CaloCluster::addHitAndFraction(), reco::SuperCluster::addPreshowerCluster(), PFEGammaAlgo::PFEGConfigInfo::applyCrackCorrections, PFEnergyCalibration::calibrateEndcapClusterEnergies(), cfg_, channelStatus_, PFEnergyCalibration::CalibratedEndcapPFClusterEnergies::clusterEnergy, TauDecayModes::dec, PFEGammaAlgo::ProtoEGObject::ecal2ps, PFLayer::ECAL_ENDCAP, PFEGammaAlgo::ProtoEGObject::ecalclusters, Exception, spr::find(), edm::Ptr< T >::get(), PFClusterWidthAlgo::pflowEtaWidth(), PFClusterWidthAlgo::pflowPhiWidth(), RecoTauValidation_cfi::posX, RecoTauValidation_cfi::posY, reco::SuperCluster::preshowerClustersBegin(), reco::SuperCluster::preshowerClustersEnd(), reco::SuperCluster::rawEnergy(), reco::CaloCluster::setCorrectedEnergy(), reco::SuperCluster::setEtaWidth(), reco::SuperCluster::setPhiWidth(), reco::SuperCluster::setPreshowerEnergy(), reco::SuperCluster::setPreshowerEnergyPlane1(), reco::SuperCluster::setPreshowerEnergyPlane2(), reco::SuperCluster::setSeed(), and thePFEnergyCalibration_.

Referenced by fillPFCandidates().

1791  {
1792  if (RO.ecalclusters.empty()) {
1793  return reco::SuperCluster(0.0, math::XYZPoint(0, 0, 0));
1794  }
1795 
1796  bool isEE = false;
1797  // need the vector of raw pointers for a PF width class
1798  std::vector<const reco::PFCluster*> bare_ptrs;
1799  // calculate necessary parameters and build the SC
1800  double posX(0), posY(0), posZ(0), rawSCEnergy(0), corrSCEnergy(0), corrPSEnergy(0), ps1_energy(0.0), ps2_energy(0.0);
1801  for (auto& clus : RO.ecalclusters) {
1802  double ePS1 = 0;
1803  double ePS2 = 0;
1804  isEE = PFLayer::ECAL_ENDCAP == clus->clusterRef()->layer();
1805  auto clusptr = edm::refToPtr<reco::PFClusterCollection>(clus->clusterRef());
1806  bare_ptrs.push_back(clusptr.get());
1807 
1808  const double cluseraw = clusptr->energy();
1809  double cluscalibe = clusptr->correctedEnergy();
1810  const math::XYZPoint& cluspos = clusptr->position();
1811  posX += cluseraw * cluspos.X();
1812  posY += cluseraw * cluspos.Y();
1813  posZ += cluseraw * cluspos.Z();
1814  // update EE calibrated super cluster energies
1815  if (isEE && RO.ecal2ps.count(clus.get())) {
1816  const auto& psclusters = RO.ecal2ps.at(clus.get());
1817 
1818  std::vector<reco::PFCluster const*> psClusterPointers;
1819  psClusterPointers.reserve(psclusters.size());
1820  for (auto const& psc : psclusters) {
1821  psClusterPointers.push_back(psc->clusterRef().get());
1822  }
1823  auto calibratedEnergies = thePFEnergyCalibration_.calibrateEndcapClusterEnergies(
1824  *clusptr, psClusterPointers, channelStatus_, cfg_.applyCrackCorrections);
1825  cluscalibe = calibratedEnergies.clusterEnergy;
1826  ePS1 = calibratedEnergies.ps1Energy;
1827  ePS2 = calibratedEnergies.ps2Energy;
1828  }
1829  if (ePS1 == -1.)
1830  ePS1 = 0;
1831  if (ePS2 == -1.)
1832  ePS2 = 0;
1833 
1834  rawSCEnergy += cluseraw;
1835  corrSCEnergy += cluscalibe;
1836  ps1_energy += ePS1;
1837  ps2_energy += ePS2;
1838  corrPSEnergy += ePS1 + ePS2;
1839  }
1840  posX /= rawSCEnergy;
1841  posY /= rawSCEnergy;
1842  posZ /= rawSCEnergy;
1843 
1844  // now build the supercluster
1845  reco::SuperCluster new_sc(corrSCEnergy, math::XYZPoint(posX, posY, posZ));
1846 
1847  auto clusptr = edm::refToPtr<reco::PFClusterCollection>(RO.ecalclusters.front()->clusterRef());
1848  new_sc.setCorrectedEnergy(corrSCEnergy);
1849  new_sc.setSeed(clusptr);
1850  new_sc.setPreshowerEnergyPlane1(ps1_energy);
1851  new_sc.setPreshowerEnergyPlane2(ps2_energy);
1852  new_sc.setPreshowerEnergy(corrPSEnergy);
1853  for (const auto& clus : RO.ecalclusters) {
1854  clusptr = edm::refToPtr<reco::PFClusterCollection>(clus->clusterRef());
1855  new_sc.addCluster(clusptr);
1856  auto& hits_and_fractions = clusptr->hitsAndFractions();
1857  for (auto& hit_and_fraction : hits_and_fractions) {
1858  new_sc.addHitAndFraction(hit_and_fraction.first, hit_and_fraction.second);
1859  }
1860  // put the preshower stuff back in later
1861  if (RO.ecal2ps.count(clus.get())) {
1862  const auto& cluspsassociation = RO.ecal2ps.at(clus.get());
1863  // EE rechits should be uniquely matched to sets of pre-shower
1864  // clusters at this point, so we throw an exception if otherwise
1865  // now wrapped in EDM debug flags
1866  for (const auto& pscluselem : cluspsassociation) {
1867  edm::Ptr<reco::PFCluster> psclus = edm::refToPtr<reco::PFClusterCollection>(pscluselem->clusterRef());
1868 #ifdef PFFLOW_DEBUG
1869  auto found_pscluster =
1870  std::find(new_sc.preshowerClustersBegin(), new_sc.preshowerClustersEnd(), reco::CaloClusterPtr(psclus));
1871  if (found_pscluster == new_sc.preshowerClustersEnd()) {
1872 #endif
1873  new_sc.addPreshowerCluster(psclus);
1874 #ifdef PFFLOW_DEBUG
1875  } else {
1876  throw cms::Exception("PFECALSuperClusterAlgo::buildSuperCluster")
1877  << "Found a PS cluster matched to more than one EE cluster!" << std::endl
1878  << std::hex << psclus.get() << " == " << found_pscluster->get() << std::dec << std::endl;
1879  }
1880 #endif
1881  }
1882  }
1883  }
1884 
1885  // calculate linearly weighted cluster widths
1886  PFClusterWidthAlgo pfwidth(bare_ptrs);
1887  new_sc.setEtaWidth(pfwidth.pflowEtaWidth());
1888  new_sc.setPhiWidth(pfwidth.pflowPhiWidth());
1889 
1890  // cache the value of the raw energy
1891  new_sc.rawEnergy();
1892 
1893  return new_sc;
1894 }
edm::Ptr< CaloCluster > CaloClusterPtr
CalibratedEndcapPFClusterEnergies calibrateEndcapClusterEnergies(reco::PFCluster const &eeCluster, std::vector< reco::PFCluster const *> const &psClusterPointers, ESChannelStatus const &channelStatus, bool applyCrackCorrections) const
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
PFEGConfigInfo const & cfg_
Definition: PFEGammaAlgo.h:221
T const * get() const
Returns C++ pointer to the item.
Definition: Ptr.h:139
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
PFEnergyCalibration thePFEnergyCalibration_
Definition: PFEGammaAlgo.h:137
ESChannelStatus const & channelStatus_
Definition: PFEGammaAlgo.h:224

◆ calculateEleMVA()

float PFEGammaAlgo::calculateEleMVA ( const ProtoEGObject ro,
reco::PFCandidateEGammaExtra xtra 
) const
private

Definition at line 1606 of file PFEGammaAlgo.cc.

References _currentblock, a, funct::abs(), b, PFEGammaAlgo::ProtoEGObject::brems, CommutativePairs< T >::contains(), MillePedeFileConverter_cfg::e, PFEGammaAlgo::ProtoEGObject::ecalclusters, PFEGammaAlgo::GBRForests::ele_, PFEGammaAlgo::ProtoEGObject::electronClusters, f, PFEGammaAlgo::ProtoEGObject::firstBrem, gbrForests_, edm::Ref< C, T, F >::get(), reco::PFBlockElementGsfTrack::GsftrackRef(), PFEGammaAlgo::ProtoEGObject::hcalClusters, edm::Ref< C, T, F >::isNonnull(), PFEGammaAlgo::ProtoEGObject::lateBrem, PFEGammaAlgo::ProtoEGObject::localMap, dqm-mbProfile::log, SiStripPI::max, SiStripPI::min, PFEGammaAlgo::ProtoEGObject::nBremsWithClusters, PFClusterWidthAlgo::pflowSigmaEtaEta(), reco::PFBlockElementGsfTrack::positionAtECALEntrance(), reco::PFBlockElementGsfTrack::Pout(), PFEGammaAlgo::ProtoEGObject::primaryGSFs, PFEGammaAlgo::ProtoEGObject::primaryKFs, reco::PFCandidateEGammaExtra::setDeltaEta(), reco::PFCandidateEGammaExtra::setEarlyBrem(), reco::PFCandidateEGammaExtra::setGsfElectronClusterRef(), reco::PFCandidateEGammaExtra::setGsfTrackPout(), reco::PFCandidateEGammaExtra::setHadEnergy(), reco::PFCandidateEGammaExtra::setLateBrem(), reco::PFCandidateEGammaExtra::setSigmaEtaEta(), and HLT_2023v11_cff::sigmaEtaEta.

Referenced by fillPFCandidates().

1606  {
1607  if (ro.primaryGSFs.empty()) {
1608  return -2.0f;
1609  }
1610  const PFGSFElement* gsfElement = ro.primaryGSFs.front();
1611  const PFKFElement* kfElement = nullptr;
1612  if (!ro.primaryKFs.empty()) {
1613  kfElement = ro.primaryKFs.front();
1614  }
1615  auto const& refGsf = gsfElement->GsftrackRef();
1616  reco::TrackRef refKf;
1617  constexpr float mEl = 0.000511;
1618  const double eInGsf = std::hypot(refGsf->pMode(), mEl);
1619  double dEtGsfEcal = 1e6;
1620  double sigmaEtaEta = 1e-14;
1621  const double eneHcalGsf =
1622  std::accumulate(ro.hcalClusters.begin(), ro.hcalClusters.end(), 0.0, [](const double a, auto const& b) {
1623  return a + b->clusterRef()->energy();
1624  });
1625  if (!ro.primaryKFs.empty()) {
1626  refKf = ro.primaryKFs.front()->trackRef();
1627  }
1628  const double eOutGsf = gsfElement->Pout().t();
1629  const double etaOutGsf = gsfElement->positionAtECALEntrance().eta();
1630  double firstEcalGsfEnergy{0.0};
1631  double otherEcalGsfEnergy{0.0};
1632  double ecalBremEnergy{0.0};
1633  //shower shape of cluster closest to gsf track
1634  std::vector<const reco::PFCluster*> gsfCluster;
1635  for (const auto& ecal : ro.ecalclusters) {
1636  const double cenergy = ecal->clusterRef()->correctedEnergy();
1637  bool hasgsf = ro.localMap.contains(gsfElement, ecal.get());
1638  bool haskf = ro.localMap.contains(kfElement, ecal.get());
1639  bool hasbrem = false;
1640  for (const auto& brem : ro.brems) {
1641  if (ro.localMap.contains(brem, ecal.get())) {
1642  hasbrem = true;
1643  }
1644  }
1645  if (hasbrem && ecal.get() != ro.electronClusters[0]) {
1646  ecalBremEnergy += cenergy;
1647  }
1648  if (!hasbrem && ecal.get() != ro.electronClusters[0]) {
1649  if (hasgsf)
1650  otherEcalGsfEnergy += cenergy;
1651  if (haskf)
1652  ecalBremEnergy += cenergy; // from conv. brem!
1653  if (!(hasgsf || haskf))
1654  otherEcalGsfEnergy += cenergy; // stuff from SC
1655  }
1656  }
1657 
1658  if (ro.electronClusters[0]) {
1659  reco::PFClusterRef cref = ro.electronClusters[0]->clusterRef();
1660  xtra.setGsfElectronClusterRef(_currentblock, *(ro.electronClusters[0]));
1661  firstEcalGsfEnergy = cref->correctedEnergy();
1662  dEtGsfEcal = cref->positionREP().eta() - etaOutGsf;
1663  gsfCluster.push_back(cref.get());
1664  PFClusterWidthAlgo pfwidth(gsfCluster);
1665  sigmaEtaEta = pfwidth.pflowSigmaEtaEta();
1666  }
1667 
1668  // brem sequence information
1669  float firstBrem{-1.0f};
1670  float earlyBrem{-1.0f};
1671  float lateBrem{-1.0f};
1672  if (ro.nBremsWithClusters > 0) {
1673  firstBrem = ro.firstBrem;
1674  earlyBrem = ro.firstBrem < 4 ? 1.0f : 0.0f;
1675  lateBrem = ro.lateBrem == 1 ? 1.0f : 0.0f;
1676  }
1677  xtra.setEarlyBrem(earlyBrem);
1678  xtra.setLateBrem(lateBrem);
1679  if (firstEcalGsfEnergy > 0.0) {
1680  if (refGsf.isNonnull()) {
1681  xtra.setGsfTrackPout(gsfElement->Pout());
1682  // normalization observables
1683  const float ptGsf = refGsf->ptMode();
1684  const float etaGsf = refGsf->etaMode();
1685  // tracking observables
1686  const double ptModeErrorGsf = refGsf->ptModeError();
1687  float ptModeErrOverPtGsf = (ptModeErrorGsf > 0. ? ptModeErrorGsf / ptGsf : 1.0);
1688  float chi2Gsf = refGsf->normalizedChi2();
1689  float dPtOverPtGsf = (ptGsf - gsfElement->Pout().pt()) / ptGsf;
1690  // kalman filter vars
1691  float nHitKf = refKf.isNonnull() ? refKf->hitPattern().trackerLayersWithMeasurement() : 0;
1692  float chi2Kf = refKf.isNonnull() ? refKf->normalizedChi2() : -0.01;
1693 
1694  //tracker + calorimetry observables
1695  float eTotPinMode = (firstEcalGsfEnergy + otherEcalGsfEnergy + ecalBremEnergy) / eInGsf;
1696  float eGsfPoutMode = firstEcalGsfEnergy / eOutGsf;
1697  float eTotBremPinPoutMode = (ecalBremEnergy + otherEcalGsfEnergy) / (eInGsf - eOutGsf);
1698  float dEtaGsfEcalClust = std::abs(dEtGsfEcal);
1699  float logSigmaEtaEta = std::log(sigmaEtaEta);
1700  float hOverHe = eneHcalGsf / (eneHcalGsf + firstEcalGsfEnergy);
1701 
1702  xtra.setDeltaEta(dEtaGsfEcalClust);
1704  xtra.setHadEnergy(eneHcalGsf);
1705 
1706  // Apply bounds to variables and calculate MVA
1707  dPtOverPtGsf = std::clamp(dPtOverPtGsf, -0.2f, 1.0f);
1708  ptModeErrOverPtGsf = std::min(ptModeErrOverPtGsf, 0.3f);
1709  chi2Gsf = std::min(chi2Gsf, 10.0f);
1710  chi2Kf = std::min(chi2Kf, 10.0f);
1711  eTotPinMode = std::clamp(eTotPinMode, 0.0f, 5.0f);
1712  eGsfPoutMode = std::clamp(eGsfPoutMode, 0.0f, 5.0f);
1713  eTotBremPinPoutMode = std::clamp(eTotBremPinPoutMode, 0.0f, 5.0f);
1714  dEtaGsfEcalClust = std::min(dEtaGsfEcalClust, 0.1f);
1715  logSigmaEtaEta = std::max(logSigmaEtaEta, -14.0f);
1716 
1717  // not used for moment, weird behavior of variable
1718  //float dPtOverPtKf = refKf.isNonnull() ? (refKf->pt() - refKf->outerPt())/refKf->pt() : -0.01;
1719  //dPtOverPtKf = std::clamp(dPtOverPtKf,-0.2f, 1.0f);
1720 
1721  /*
1722  * To be used for debugging:
1723  * pretty-print the PFEgamma electron MVA input variables
1724  *
1725  * std::cout << " **** PFEG BDT observables ****" << endl;
1726  * std::cout << " < Normalization > " << endl;
1727  * std::cout << " ptGsf " << ptGsf << " Pin " << eInGsf
1728  * << " Pout " << eOutGsf << " etaGsf " << etaGsf << endl;
1729  * std::cout << " < PureTracking > " << endl;
1730  * std::cout << " ptModeErrOverPtGsf " << ptModeErrOverPtGsf
1731  * << " dPtOverPtGsf " << dPtOverPtGsf
1732  * << " chi2Gsf " << chi2Gsf
1733  * << " nhit_gsf " << nhit_gsf
1734  * << " dPtOverPtKf " << dPtOverPtKf
1735  * << " chi2Kf " << chi2Kf
1736  * << " nHitKf " << nHitKf << endl;
1737  * std::cout << " < track-ecal-hcal-ps " << endl;
1738  * std::cout << " eTotPinMode " << eTotPinMode
1739  * << " eGsfPoutMode " << eGsfPoutMode
1740  * << " eTotBremPinPoutMode " << eTotBremPinPoutMode
1741  * << " dEtaGsfEcalClust " << dEtaGsfEcalClust
1742  * << " logSigmaEtaEta " << logSigmaEtaEta
1743  * << " hOverHe " << hOverHe << " Hcal energy " << eneHcalGsf
1744  * << " lateBrem " << lateBrem
1745  * << " firstBrem " << firstBrem << endl;
1746  */
1747 
1748  float vars[] = {std::log(ptGsf),
1749  etaGsf,
1750  ptModeErrOverPtGsf,
1751  dPtOverPtGsf,
1752  chi2Gsf,
1753  nHitKf,
1754  chi2Kf,
1755  eTotPinMode,
1756  eGsfPoutMode,
1757  eTotBremPinPoutMode,
1758  dEtaGsfEcalClust,
1759  logSigmaEtaEta,
1760  hOverHe,
1761  lateBrem,
1762  firstBrem};
1763 
1764  return gbrForests_.ele_->GetAdaBoostClassifier(vars);
1765  }
1766  }
1767  return -2.0f;
1768 }
GBRForests const & gbrForests_
Definition: PFEGammaAlgo.h:135
void setGsfElectronClusterRef(const reco::PFBlockRef &blk, const reco::PFBlockElementCluster &ref)
set gsf electron cluster ref
void setHadEnergy(float val)
set the had energy. The cluster energies should be entered before
reco::PFBlockElementGsfTrack PFGSFElement
Definition: PFEGammaAlgo.h:67
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
void setSigmaEtaEta(float val)
set the sigmaetaeta
void setEarlyBrem(float val)
set EarlyBrem
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void setGsfTrackPout(const math::XYZTLorentzVector &pout)
set the pout (not trivial to get from the GSF track)
double f[11][100]
void setDeltaEta(float val)
set the delta eta
reco::PFBlockElementTrack PFKFElement
Definition: PFEGammaAlgo.h:68
double b
Definition: hdecay.h:118
double a
Definition: hdecay.h:119
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:232
const std::unique_ptr< const GBRForest > ele_
Definition: PFEGammaAlgo.h:80
vars
Definition: DeepTauId.cc:30
void setLateBrem(float val)
set LateBrem

◆ dumpCurrentRefinableObjects()

void PFEGammaAlgo::dumpCurrentRefinableObjects ( ) const
private

Definition at line 932 of file PFEGammaAlgo.cc.

References info().

Referenced by operator()().

932  {
933 #ifdef PFLOW_DEBUG
934  edm::LogVerbatim("PFEGammaAlgo")
935  //<< "Dumping current block: " << std::endl << *_currentblock << std::endl
936  << "Dumping " << refinableObjects.size() << " refinable objects for this block: " << std::endl;
937  for (const auto& ro : refinableObjects) {
938  std::stringstream info;
939  info << "Refinable Object:" << std::endl;
940  if (ro.parentSC) {
941  info << "\tSuperCluster element attached to object:" << std::endl << '\t';
942  ro.parentSC->Dump(info, "\t");
943  info << std::endl;
944  }
945  if (ro.electronSeed.isNonnull()) {
946  info << "\tGSF element attached to object:" << std::endl;
947  ro.primaryGSFs.front()->Dump(info, "\t");
948  info << std::endl;
949  info << "firstBrem : " << ro.firstBrem << " lateBrem : " << ro.lateBrem
950  << " nBrems with cluster : " << ro.nBremsWithClusters << std::endl;
951  ;
952  if (ro.electronClusters.size() && ro.electronClusters[0]) {
953  info << "electron cluster : ";
954  ro.electronClusters[0]->Dump(info, "\t");
955  info << std::endl;
956  } else {
957  info << " no electron cluster." << std::endl;
958  }
959  }
960  if (ro.primaryKFs.size()) {
961  info << "\tPrimary KF tracks attached to object: " << std::endl;
962  for (const auto& kf : ro.primaryKFs) {
963  kf->Dump(info, "\t");
964  info << std::endl;
965  }
966  }
967  if (ro.secondaryKFs.size()) {
968  info << "\tSecondary KF tracks attached to object: " << std::endl;
969  for (const auto& kf : ro.secondaryKFs) {
970  kf->Dump(info, "\t");
971  info << std::endl;
972  }
973  }
974  if (ro.brems.size()) {
975  info << "\tBrem tangents attached to object: " << std::endl;
976  for (const auto& brem : ro.brems) {
977  brem->Dump(info, "\t");
978  info << std::endl;
979  }
980  }
981  if (ro.ecalclusters.size()) {
982  info << "\tECAL clusters attached to object: " << std::endl;
983  for (const auto& clus : ro.ecalclusters) {
984  clus->Dump(info, "\t");
985  info << std::endl;
986  if (ro.ecal2ps.find(clus) != ro.ecal2ps.end()) {
987  for (const auto& psclus : ro.ecal2ps.at(clus)) {
988  info << "\t\t Attached PS Cluster: ";
989  psclus->Dump(info, "");
990  info << std::endl;
991  }
992  }
993  }
994  }
995  edm::LogVerbatim("PFEGammaAlgo") << info.str();
996  }
997 #endif
998 }
Log< level::Info, true > LogVerbatim
static const TGPicture * info(bool iBackgroundIsBlack)

◆ evaluateSingleLegMVA()

float PFEGammaAlgo::evaluateSingleLegMVA ( const reco::PFBlockRef blockref,
const reco::Vertex primaryVtx,
unsigned int  trackIndex 
)
private

Definition at line 460 of file PFEGammaAlgo.cc.

References groupFilesInBlocks::block, hltPixelTracks_cff::chi2, delPhi(), SiPixelRawToDigiRegional_cfi::deltaPhi, reco::PFBlockElement::ECAL, bookConverter::elements, gbrForests_, reco::PFBlockElement::HCAL, reco::PFBlock::LINKTEST_ALL, MuonTCMETValueMapProducer_cff::nLayers, PV3DBase< T, PVType, FrameType >::phi(), VtxSmearedParameters_cfi::Phi, PFEGammaAlgo::GBRForests::singleLeg_, listHistos::trackPt, X, reco::Vertex::x(), reco::Vertex::y(), and reco::Vertex::z().

Referenced by fillPFCandidates(), and linkRefinableObjectECALToSingleLegConv().

462  {
463  const reco::PFBlock& block = *blockRef;
465  //use this to store linkdata in the associatedElements function below
466  const PFBlock::LinkData& linkData = block.linkData();
467  //calculate MVA Variables
468  const float chi2 = elements[trackIndex].trackRef()->chi2() / elements[trackIndex].trackRef()->ndof();
469  const float nlost = elements[trackIndex].trackRef()->missingInnerHits();
470  const float nLayers = elements[trackIndex].trackRef()->hitPattern().trackerLayersWithMeasurement();
471  const float trackPt = elements[trackIndex].trackRef()->pt();
472  const float stip = elements[trackIndex].trackRefPF()->STIP();
473 
474  float linkedE = 0;
475  float linkedH = 0;
476  std::multimap<double, unsigned int> ecalAssoTrack;
477  block.associatedElements(
478  trackIndex, linkData, ecalAssoTrack, reco::PFBlockElement::ECAL, reco::PFBlock::LINKTEST_ALL);
479  std::multimap<double, unsigned int> hcalAssoTrack;
480  block.associatedElements(
481  trackIndex, linkData, hcalAssoTrack, reco::PFBlockElement::HCAL, reco::PFBlock::LINKTEST_ALL);
482  if (!ecalAssoTrack.empty()) {
483  for (auto& itecal : ecalAssoTrack) {
484  linkedE = linkedE + elements[itecal.second].clusterRef()->energy();
485  }
486  }
487  if (!hcalAssoTrack.empty()) {
488  for (auto& ithcal : hcalAssoTrack) {
489  linkedH = linkedH + elements[ithcal.second].clusterRef()->energy();
490  }
491  }
492  const float eOverPt = linkedE / elements[trackIndex].trackRef()->pt();
493  const float hOverPt = linkedH / elements[trackIndex].trackRef()->pt();
494  GlobalVector rvtx(elements[trackIndex].trackRef()->innerPosition().X() - primaryVtx.x(),
495  elements[trackIndex].trackRef()->innerPosition().Y() - primaryVtx.y(),
496  elements[trackIndex].trackRef()->innerPosition().Z() - primaryVtx.z());
497  double vtxPhi = rvtx.phi();
498  //delta Phi between conversion vertex and track
499  float delPhi = fabs(deltaPhi(vtxPhi, elements[trackIndex].trackRef()->innerMomentum().Phi()));
500 
501  float vars[] = {delPhi, nLayers, chi2, eOverPt, hOverPt, trackPt, stip, nlost};
502 
503  return gbrForests_.singleLeg_->GetAdaBoostClassifier(vars);
504 }
GBRForests const & gbrForests_
Definition: PFEGammaAlgo.h:135
double z() const
z coordinate
Definition: Vertex.h:133
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
#define X(str)
Definition: MuonsGrabber.cc:38
std::map< unsigned int, Link > LinkData
Definition: PFBlock.h:39
const std::unique_ptr< const GBRForest > singleLeg_
Definition: PFEGammaAlgo.h:81
static double delPhi(const double phi1, const double phi2)
double x() const
x coordinate
Definition: Vertex.h:129
double y() const
y coordinate
Definition: Vertex.h:131
vars
Definition: DeepTauId.cc:30
Block of elements.
Definition: PFBlock.h:26

◆ fillExtraInfo()

void PFEGammaAlgo::fillExtraInfo ( const ProtoEGObject RO,
reco::PFCandidateEGammaExtra xtra 
)
private

Definition at line 1770 of file PFEGammaAlgo.cc.

References _currentblock, _splayedblock, reco::PFCandidateEGammaExtra::addExtraNonConvTrack(), docast, PFEGammaAlgo::ProtoEGObject::ecalclusters, l1ctLayer1_patternWriters_cff::partition, reco::PFBlockElement::TRACK, and x.

Referenced by fillPFCandidates().

1770  {
1771  // add tracks associated to clusters that are not T_FROM_GAMMACONV
1772  // info about single-leg convs is already save, so just veto in loops
1773  auto KFbegin = _splayedblock[reco::PFBlockElement::TRACK].begin();
1774  auto KFend = _splayedblock[reco::PFBlockElement::TRACK].end();
1775  for (auto& ecal : RO.ecalclusters) {
1776  NotCloserToOther<reco::PFBlockElement::ECAL, reco::PFBlockElement::TRACK, true> ECALToTracks(_currentblock,
1777  ecal.get());
1778  auto notmatchedkf = std::partition(KFbegin, KFend, ECALToTracks);
1779  auto notconvkf = std::partition(KFbegin, notmatchedkf, [](auto const& x) { return x->trackType(ConvType); });
1780  // go through non-conv-identified kfs and check MVA to add conversions
1781  for (auto kf = notconvkf; kf != notmatchedkf; ++kf) {
1782  const reco::PFBlockElementTrack* elemaskf = docast(const reco::PFBlockElementTrack*, kf->get());
1783  xtra.addExtraNonConvTrack(_currentblock, *elemaskf);
1784  }
1785  }
1786 }
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148
void addExtraNonConvTrack(const reco::PFBlockRef &blk, const reco::PFBlockElementTrack &tkref)
track counting for electrons and photons

◆ fillPFCandidates()

PFEGammaAlgo::EgammaObjects PFEGammaAlgo::fillPFCandidates ( const std::list< ProtoEGObject > &  )
private

Definition at line 1471 of file PFEGammaAlgo.cc.

References _currentblock, reco::PFCandidateEGammaExtra::addConversionRef(), reco::PFCandidateEGammaExtra::addSingleLegConvTrackRefMva(), buildRefinedSuperCluster(), calculateEleMVA(), cfg_, reco::CaloCluster::energy(), evaluateSingleLegMVA(), fillExtraInfo(), ntupleEnum::gsf, reco::PFBlockElement::index(), edm::Ref< C, T, F >::index(), convertSQLitetoXML_cfg::output, reco::Vertex::position(), reco::CaloCluster::position(), primaryVertex_, PFEGammaAlgo::PFEGConfigInfo::produceEGCandsWithNoSuperCluster, reco::SuperCluster::rawEnergy(), reco::SuperCluster::seed(), reco::PFCandidateEGammaExtra::setGsfTrackRef(), reco::PFCandidateEGammaExtra::setKfTrackRef(), reco::PFCandidateEGammaExtra::setMVA(), reco::PFCandidateEGammaExtra::setSuperClusterPFECALRef(), and reco::PFCandidateEGammaExtra::setSuperClusterRef().

Referenced by operator()().

1471  {
1473 
1474  // reserve output collections
1475  output.candidates.reserve(ROs.size());
1476  output.candidateExtras.reserve(ROs.size());
1477  output.refinedSuperClusters.reserve(ROs.size());
1478 
1479  for (auto& RO : ROs) {
1480  if (RO.ecalclusters.empty() && !cfg_.produceEGCandsWithNoSuperCluster)
1481  continue;
1482 
1485  if (!RO.primaryGSFs.empty() || !RO.primaryKFs.empty()) {
1486  cand.setPdgId(-11); // anything with a primary track is an electron
1487  } else {
1488  cand.setPdgId(22); // anything with no primary track is a photon
1489  }
1490  if (!RO.primaryKFs.empty()) {
1491  cand.setCharge(RO.primaryKFs[0]->trackRef()->charge());
1492  xtra.setKfTrackRef(RO.primaryKFs[0]->trackRef());
1493  cand.setTrackRef(RO.primaryKFs[0]->trackRef());
1494  cand.setVertex(RO.primaryKFs[0]->trackRef()->vertex());
1495  cand.addElementInBlock(_currentblock, RO.primaryKFs[0]->index());
1496  }
1497  if (!RO.primaryGSFs.empty()) {
1498  cand.setCharge(RO.primaryGSFs[0]->GsftrackRef()->chargeMode());
1499  xtra.setGsfTrackRef(RO.primaryGSFs[0]->GsftrackRef());
1500  cand.setGsfTrackRef(RO.primaryGSFs[0]->GsftrackRef());
1501  cand.setVertex(RO.primaryGSFs[0]->GsftrackRef()->vertex());
1502  cand.addElementInBlock(_currentblock, RO.primaryGSFs[0]->index());
1503  }
1504  if (RO.parentSC) {
1505  xtra.setSuperClusterPFECALRef(RO.parentSC->superClusterRef());
1506  // we'll set to the refined supercluster back up in the producer
1507  cand.setSuperClusterRef(RO.parentSC->superClusterRef());
1508  xtra.setSuperClusterRef(RO.parentSC->superClusterRef());
1509  cand.addElementInBlock(_currentblock, RO.parentSC->index());
1510  }
1511  // add brems
1512  for (const auto& brem : RO.brems) {
1513  cand.addElementInBlock(_currentblock, brem->index());
1514  }
1515  // add clusters and ps clusters
1516  for (const auto& ecal : RO.ecalclusters) {
1517  const PFClusterElement* clus = ecal.get();
1518  cand.addElementInBlock(_currentblock, clus->index());
1519  if (RO.ecal2ps.count(clus)) {
1520  for (auto& psclus : RO.ecal2ps.at(clus)) {
1521  cand.addElementInBlock(_currentblock, psclus->index());
1522  }
1523  }
1524  }
1525  // add secondary tracks
1526  for (const auto& kf : RO.secondaryKFs) {
1527  cand.addElementInBlock(_currentblock, kf->index());
1528  const reco::ConversionRefVector& convrefs = kf->convRefs();
1529  bool no_conv_ref = true;
1530  for (const auto& convref : convrefs) {
1531  if (convref.isNonnull() && convref.isAvailable()) {
1532  xtra.addConversionRef(convref);
1533  no_conv_ref = false;
1534  }
1535  }
1536  if (no_conv_ref) {
1537  //single leg conversions
1538 
1539  //look for stored mva value in map or else recompute
1540  const auto& mvavalmapped = RO.singleLegConversionMvaMap.find(kf);
1541  //FIXME: Abuse single mva value to store both provenance and single leg mva score
1542  //by storing 3.0 + mvaval
1543  float mvaval = (mvavalmapped != RO.singleLegConversionMvaMap.end()
1544  ? mvavalmapped->second
1545  : 3.0 + evaluateSingleLegMVA(_currentblock, primaryVertex_, kf->index()));
1546 
1547  xtra.addSingleLegConvTrackRefMva(std::make_pair(kf->trackRef(), mvaval));
1548  }
1549  }
1550 
1551  // build the refined supercluster from those clusters left in the cand
1552  output.refinedSuperClusters.push_back(buildRefinedSuperCluster(RO));
1553 
1554  //*TODO* cluster time is not reliable at the moment, so only use track timing
1555  float trkTime = 0, trkTimeErr = -1;
1556  if (!RO.primaryGSFs.empty() && RO.primaryGSFs[0]->isTimeValid()) {
1557  trkTime = RO.primaryGSFs[0]->time();
1558  trkTimeErr = RO.primaryGSFs[0]->timeError();
1559  } else if (!RO.primaryKFs.empty() && RO.primaryKFs[0]->isTimeValid()) {
1560  trkTime = RO.primaryKFs[0]->time();
1561  trkTimeErr = RO.primaryKFs[0]->timeError();
1562  }
1563  if (trkTimeErr >= 0) {
1564  cand.setTime(trkTime, trkTimeErr);
1565  }
1566 
1567  const reco::SuperCluster& the_sc = output.refinedSuperClusters.back();
1568  // with the refined SC in hand we build a naive candidate p4
1569  // and set the candidate ECAL position to either the barycenter of the
1570  // supercluster (if super-cluster present) or the seed of the
1571  // new SC generated by the EGAlgo
1572  const double scE = the_sc.energy();
1573  if (scE != 0.0) {
1574  const math::XYZPoint& seedPos = the_sc.seed()->position();
1575  math::XYZVector egDir = the_sc.position() - primaryVertex_.position();
1576  egDir = egDir.Unit();
1577  cand.setP4(math::XYZTLorentzVector(scE * egDir.x(), scE * egDir.y(), scE * egDir.z(), scE));
1578  math::XYZPointF ecalPOS_f(seedPos.x(), seedPos.y(), seedPos.z());
1579  cand.setPositionAtECALEntrance(ecalPOS_f);
1580  cand.setEcalEnergy(the_sc.rawEnergy(), the_sc.energy());
1581  } else if (cfg_.produceEGCandsWithNoSuperCluster && !RO.primaryGSFs.empty()) {
1582  const PFGSFElement* gsf = RO.primaryGSFs[0];
1583  const reco::GsfTrackRef& gref = gsf->GsftrackRef();
1584  math::XYZTLorentzVector p4(gref->pxMode(), gref->pyMode(), gref->pzMode(), gref->pMode());
1585  cand.setP4(p4);
1586  cand.setPositionAtECALEntrance(gsf->positionAtECALEntrance());
1587  } else if (cfg_.produceEGCandsWithNoSuperCluster && !RO.primaryKFs.empty()) {
1588  const PFKFElement* kf = RO.primaryKFs[0];
1589  reco::TrackRef kref = RO.primaryKFs[0]->trackRef();
1590  math::XYZTLorentzVector p4(kref->px(), kref->py(), kref->pz(), kref->p());
1591  cand.setP4(p4);
1592  cand.setPositionAtECALEntrance(kf->positionAtECALEntrance());
1593  }
1594  const float eleMVAValue = calculateEleMVA(RO, xtra);
1595  fillExtraInfo(RO, xtra);
1596  //std::cout << "PFEG eleMVA: " << eleMVAValue << std::endl;
1597  xtra.setMVA(eleMVAValue);
1598  cand.set_mva_e_pi(eleMVAValue);
1599  output.candidates.push_back(cand);
1600  output.candidateExtras.push_back(xtra);
1601  }
1602 
1603  return output;
1604 }
const math::XYZPoint & position() const
cluster centroid position
Definition: CaloCluster.h:154
float evaluateSingleLegMVA(const reco::PFBlockRef &blockref, const reco::Vertex &primaryVtx, unsigned int trackIndex)
void setSuperClusterRef(reco::SuperClusterRef sc)
set reference to the corresponding supercluster
void addSingleLegConvTrackRefMva(const std::pair< reco::TrackRef, float > &trackrefmva)
add Single Leg Conversion TrackRef
const Point & position() const
position
Definition: Vertex.h:127
double rawEnergy() const
raw uncorrected energy (sum of energies of component BasicClusters)
Definition: SuperCluster.h:60
float calculateEleMVA(const ProtoEGObject &, reco::PFCandidateEGammaExtra &) const
reco::PFBlockElementGsfTrack PFGSFElement
Definition: PFEGammaAlgo.h:67
reco::Vertex const & primaryVertex_
Definition: PFEGammaAlgo.h:222
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:10
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
void setGsfTrackRef(const reco::GsfTrackRef &ref)
set gsftrack reference
PFEGConfigInfo const & cfg_
Definition: PFEGammaAlgo.h:221
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
reco::PFBlockElementCluster PFClusterElement
Definition: PFEGammaAlgo.h:69
double energy() const
cluster energy
Definition: CaloCluster.h:149
void fillExtraInfo(const ProtoEGObject &, reco::PFCandidateEGammaExtra &)
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
key_type index() const
Definition: Ref.h:253
reco::PFBlockElementTrack PFKFElement
Definition: PFEGammaAlgo.h:68
void setSuperClusterPFECALRef(reco::SuperClusterRef sc)
set reference to the corresponding supercluster
void addConversionRef(const reco::ConversionRef &convref)
add Conversions from PF
const CaloClusterPtr & seed() const
seed BasicCluster
Definition: SuperCluster.h:79
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:41
reco::SuperCluster buildRefinedSuperCluster(const ProtoEGObject &)
void setKfTrackRef(const reco::TrackRef &ref)
set kf track reference
void setMVA(float val)
set the result (mostly for debugging)

◆ initializeProtoCands()

void PFEGammaAlgo::initializeProtoCands ( std::list< ProtoEGObject > &  )
private

Definition at line 656 of file PFEGammaAlgo.cc.

References _currentblock, _currentlinks, _splayedblock, PFEGammaAlgo::ProtoEGObject::brems, docast, reco::PFBlockElementGsfTrack::Dump(), PFEGammaAlgo::ProtoEGObject::ecal2ps, PFEGammaAlgo::ProtoEGObject::ecalclusters, PFEGammaAlgo::ProtoEGObject::electronSeed, Exception, f, PFEGammaAlgo::ProtoEGObject::firstBrem, edm::Ref< C, T, F >::get(), reco::PFBlockElementGsfTrack::GsftrackRef(), reco::PFBlockElement::index(), CommutativePairs< T >::insert(), edm::Ref< C, T, F >::isAvailable(), edm::Ref< C, T, F >::isNonnull(), edm::Ref< C, T, F >::isNull(), PFEGammaAlgo::ProtoEGObject::lateBrem, reco::PFBlock::LINKTEST_ALL, PFEGammaAlgo::ProtoEGObject::localMap, LOGDRESSED, LOGVERB, eostools::move(), PFEGammaAlgo::ProtoEGObject::nBremsWithClusters, PFEGammaAlgo::ProtoEGObject::parentBlock, PFEGammaAlgo::ProtoEGObject::parentSC, PFEGammaAlgo::ProtoEGObject::primaryGSFs, reco::PFBlockElement::T_FROM_GAMMACONV, reco::PFBlockElementGsfTrack::trackType(), and unwrapSuperCluster().

Referenced by operator()().

656  {
657  // step 1: build SC based proto-candidates
658  // in the future there will be an SC Et requirement made here to control
659  // block size
660  for (auto& element : _splayedblock[PFBlockElement::SC]) {
661  LOGDRESSED("PFEGammaAlgo") << "creating SC-based proto-object" << std::endl
662  << "\tSC at index: " << element->index() << " has type: " << element->type()
663  << std::endl;
664  element.setFlag(false);
665  ProtoEGObject fromSC;
666  fromSC.nBremsWithClusters = -1;
667  fromSC.firstBrem = -1;
668  fromSC.lateBrem = -1;
669  fromSC.parentBlock = _currentblock;
670  fromSC.parentSC = docast(const PFSCElement*, element.get());
671  // splay the supercluster so we can knock out used elements
672  bool sc_success = unwrapSuperCluster(fromSC.parentSC, fromSC.ecalclusters, fromSC.ecal2ps);
673  if (sc_success) {
674  /*
675  auto ins_pos = std::lower_bound(refinableObjects.begin(),
676  refinableObjects.end(),
677  fromSC,
678  [&](const ProtoEGObject& a,
679  const ProtoEGObject& b){
680  const double a_en =
681  a.parentSC->superClusterRef()->energy();
682  const double b_en =
683  b.parentSC->superClusterRef()->energy();
684  return a_en < b_en;
685  });
686  */
687  egobjs.insert(egobjs.end(), fromSC);
688  }
689  }
690  // step 2: build GSF-seed-based proto-candidates
691  reco::GsfTrackRef gsfref_forextra;
692  reco::TrackExtraRef gsftrk_extra;
693  reco::ElectronSeedRef theseedref;
694  for (auto& element : _splayedblock[PFBlockElement::GSF]) {
695  LOGDRESSED("PFEGammaAlgo") << "creating GSF-based proto-object" << std::endl
696  << "\tGSF at index: " << element->index() << " has type: " << element->type()
697  << std::endl;
698  const PFGSFElement* elementAsGSF = docast(const PFGSFElement*, element.get());
699  if (elementAsGSF->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)) {
700  continue; // for now, do not allow dedicated brems to make proto-objects
701  }
702  element.setFlag(false);
703 
704  ProtoEGObject fromGSF;
705  fromGSF.nBremsWithClusters = -1;
706  fromGSF.firstBrem = -1;
707  fromGSF.lateBrem = 0;
708  gsfref_forextra = elementAsGSF->GsftrackRef();
709  gsftrk_extra = (gsfref_forextra.isAvailable() ? gsfref_forextra->extra() : reco::TrackExtraRef());
710  theseedref = (gsftrk_extra.isAvailable() ? gsftrk_extra->seedRef().castTo<reco::ElectronSeedRef>()
712  fromGSF.electronSeed = theseedref;
713  // exception if there's no seed
714  if (fromGSF.electronSeed.isNull() || !fromGSF.electronSeed.isAvailable()) {
715  std::stringstream gsf_err;
716  elementAsGSF->Dump(gsf_err, "\t");
717  throw cms::Exception("PFEGammaAlgo::initializeProtoCands()")
718  << "Found a GSF track with no seed! This should not happen!" << std::endl
719  << gsf_err.str() << std::endl;
720  }
721  // flag this GSF element as globally used and push back the track ref
722  // into the protocand
723  element.setFlag(false);
724  fromGSF.parentBlock = _currentblock;
725  fromGSF.primaryGSFs.push_back(elementAsGSF);
726  // add the directly matched brem tangents
727  for (auto& brem : _splayedblock[PFBlockElement::BREM]) {
728  float dist =
729  _currentblock->dist(elementAsGSF->index(), brem->index(), _currentlinks, reco::PFBlock::LINKTEST_ALL);
730  if (dist == 0.001f) {
731  const PFBremElement* eAsBrem = docast(const PFBremElement*, brem.get());
732  fromGSF.brems.push_back(eAsBrem);
733  fromGSF.localMap.insert(eAsBrem, elementAsGSF);
734  brem.setFlag(false);
735  }
736  }
737  // if this track is ECAL seeded reset links or import cluster
738  // tracker (this is pixel only, right?) driven seeds just get the GSF
739  // track associated since this only branches for ECAL Driven seeds
740  if (fromGSF.electronSeed->isEcalDriven()) {
741  // step 2a: either merge with existing ProtoEG object with SC or add
742  // SC directly to this proto EG object if not present
743  LOGDRESSED("PFEGammaAlgo") << "GSF-based proto-object is ECAL driven, merging SC-cand" << std::endl;
744  LOGVERB("PFEGammaAlgo") << "ECAL Seed Ptr: " << fromGSF.electronSeed.get()
745  << " isAvailable: " << fromGSF.electronSeed.isAvailable()
746  << " isNonnull: " << fromGSF.electronSeed.isNonnull() << std::endl;
747  SeedMatchesToProtoObject sctoseedmatch(fromGSF.electronSeed);
748  auto objsbegin = egobjs.begin();
749  auto objsend = egobjs.end();
750  // this auto is a std::list<ProtoEGObject>::iterator
751  auto clusmatch = std::find_if(objsbegin, objsend, sctoseedmatch);
752  if (clusmatch != objsend) {
753  fromGSF.parentSC = clusmatch->parentSC;
754  fromGSF.ecalclusters = std::move(clusmatch->ecalclusters);
755  fromGSF.ecal2ps = std::move(clusmatch->ecal2ps);
756  egobjs.erase(clusmatch);
757  } else if (fromGSF.electronSeed.isAvailable() && fromGSF.electronSeed.isNonnull()) {
758  // link tests in the gap region can current split a gap electron
759  // HEY THIS IS A WORK AROUND FOR A KNOWN BUG IN PFBLOCKALGO
760  // MAYBE WE SHOULD FIX IT??????????????????????????????????
761  LOGDRESSED("PFEGammaAlgo") << "Encountered the known GSF-SC splitting bug "
762  << " in PFBlockAlgo! We should really fix this!" << std::endl;
763  } else { // SC was not in a earlier proto-object
764  std::stringstream gsf_err;
765  elementAsGSF->Dump(gsf_err, "\t");
766  throw cms::Exception("PFEGammaAlgo::initializeProtoCands()")
767  << "Expected SuperCluster from ECAL driven GSF seed "
768  << "was not found in the block!" << std::endl
769  << gsf_err.str() << std::endl;
770  } // supercluster in block
771  } // is ECAL driven seed?
772 
773  egobjs.insert(egobjs.end(), fromGSF);
774  } // end loop on GSF elements of block
775 }
reco::PFBlockElementSuperCluster PFSCElement
Definition: PFEGammaAlgo.h:65
bool unwrapSuperCluster(const reco::PFBlockElementSuperCluster *, std::vector< FlaggedPtr< const PFClusterElement >> &, ClusterMap &)
reco::PFBlockElementGsfTrack PFGSFElement
Definition: PFEGammaAlgo.h:67
edm::Ref< TrackExtraCollection > TrackExtraRef
persistent reference to a TrackExtra
Definition: TrackExtraFwd.h:16
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
#define LOGVERB(x)
Definition: PFEGammaAlgo.cc:44
#define LOGDRESSED(x)
Definition: PFEGammaAlgo.cc:47
bool isAvailable() const
Definition: Ref.h:537
double f[11][100]
reco::PFBlockElementBrem PFBremElement
Definition: PFEGammaAlgo.h:66
reco::PFBlock::LinkData _currentlinks
Definition: PFEGammaAlgo.h:145
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148
def move(src, dest)
Definition: eostools.py:511

◆ isMuon()

bool PFEGammaAlgo::isMuon ( const reco::PFBlockElement pfbe)
private

Definition at line 506 of file PFEGammaAlgo.cc.

References _currentblock, _currentlinks, bookConverter::elements, reco::PFBlockElement::GSF, reco::PFBlockElement::index(), PFMuonAlgo::isMuon(), reco::PFBlock::LINKTEST_ALL, reco::PFBlockElement::TRACK, and reco::PFBlockElement::type().

Referenced by operator()().

506  {
507  switch (pfbe.type()) {
509  auto& elements = _currentblock->elements();
510  std::multimap<double, unsigned> tks;
511  _currentblock->associatedElements(
513  for (const auto& tk : tks) {
514  if (PFMuonAlgo::isMuon(elements[tk.second])) {
515  return true;
516  }
517  }
518  } break;
520  return PFMuonAlgo::isMuon(pfbe);
521  break;
522  default:
523  break;
524  }
525  return false;
526 }
static bool isMuon(const reco::PFBlockElement &elt)
Definition: PFMuonAlgo.cc:48
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
unsigned index() const
reco::PFBlock::LinkData _currentlinks
Definition: PFEGammaAlgo.h:145

◆ isPrimaryTrack()

bool PFEGammaAlgo::isPrimaryTrack ( const reco::PFBlockElementTrack KfEl,
const reco::PFBlockElementGsfTrack GsfEl 
)
private

Definition at line 2040 of file PFEGammaAlgo.cc.

References reco::PFBlockElementGsfTrack::GsftrackRefPF(), edm::Ref< C, T, F >::isNonnull(), phase2tkutil::isPrimary(), and reco::PFBlockElementTrack::trackRefPF().

Referenced by linkRefinableObjectGSFTracksToKFs().

2040  {
2041  bool isPrimary = false;
2042 
2043  const GsfPFRecTrackRef& gsfPfRef = GsfEl.GsftrackRefPF();
2044 
2045  if (gsfPfRef.isNonnull()) {
2046  const PFRecTrackRef& kfPfRef = KfEl.trackRefPF();
2047  PFRecTrackRef kfPfRef_fromGsf = (*gsfPfRef).kfPFRecTrackRef();
2048  if (kfPfRef.isNonnull() && kfPfRef_fromGsf.isNonnull()) {
2049  reco::TrackRef kfref = (*kfPfRef).trackRef();
2050  reco::TrackRef kfref_fromGsf = (*kfPfRef_fromGsf).trackRef();
2051  if (kfref.isNonnull() && kfref_fromGsf.isNonnull()) {
2052  if (kfref == kfref_fromGsf)
2053  isPrimary = true;
2054  }
2055  }
2056  }
2057 
2058  return isPrimary;
2059 }
bool isPrimary(const SimTrack &simTrk, const PSimHit *simHit)
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
const GsfPFRecTrackRef & GsftrackRefPF() const
const PFRecTrackRef & trackRefPF() const override

◆ linkKFTrackToECAL()

void PFEGammaAlgo::linkKFTrackToECAL ( PFKFElement const *  kfflagged,
ProtoEGObject RO 
)
private

Definition at line 1298 of file PFEGammaAlgo.cc.

References _currentblock, _splayedblock, attachPSClusters(), docast, reco::PFBlockElement::ECAL, PFEGammaAlgo::ProtoEGObject::ecal2ps, PFEGammaAlgo::ProtoEGObject::ecalclusters, CommutativePairs< T >::insert(), PFEGammaAlgo::ProtoEGObject::localMap, LOGDRESSED, and l1ctLayer1_patternWriters_cff::partition.

Referenced by linkRefinableObjectKFTracksToECAL().

1298  {
1299  std::vector<FlaggedPtr<const PFClusterElement>>& currentECAL = RO.ecalclusters;
1300  auto ECALbegin = _splayedblock[reco::PFBlockElement::ECAL].begin();
1301  auto ECALend = _splayedblock[reco::PFBlockElement::ECAL].end();
1302  NotCloserToOther<reco::PFBlockElement::TRACK, reco::PFBlockElement::ECAL> kfTrackToECALs(_currentblock, kfflagged);
1303  NotCloserToOther<reco::PFBlockElement::GSF, reco::PFBlockElement::ECAL> kfTrackGSFToECALs(_currentblock, kfflagged);
1304  //get the ECAL elements not used and not closer to another KF
1305  auto notmatched_sc = std::partition(currentECAL.begin(), currentECAL.end(), kfTrackToECALs);
1306  //get subset ECAL elements not used or closer to another GSF of any type
1307  notmatched_sc = std::partition(currentECAL.begin(), notmatched_sc, kfTrackGSFToECALs);
1308  for (auto ecalitr = currentECAL.begin(); ecalitr != notmatched_sc; ++ecalitr) {
1309  const PFClusterElement* elemascluster = docast(const PFClusterElement*, ecalitr->get());
1310  FlaggedPtr<const PFClusterElement> flaggedclus(elemascluster, true);
1311 
1312  LOGDRESSED("PFEGammaAlgo::linkKFTracktoECAL()") << "Found a cluster already in RO by KF extrapolation"
1313  << " at ECAL surface!" << std::endl
1314  << *elemascluster << std::endl;
1315  RO.localMap.insert(elemascluster, kfflagged);
1316  }
1317  //get the ECAL elements not used and not closer to another KF
1318  auto notmatched_blk = std::partition(ECALbegin, ECALend, kfTrackToECALs);
1319  //get subset ECAL elements not used or closer to another GSF of any type
1320  notmatched_blk = std::partition(ECALbegin, notmatched_blk, kfTrackGSFToECALs);
1321  for (auto ecalitr = ECALbegin; ecalitr != notmatched_blk; ++ecalitr) {
1322  const PFClusterElement* elemascluster = docast(const PFClusterElement*, ecalitr->get());
1323  if (addPFClusterToROSafe(elemascluster, RO)) {
1324  attachPSClusters(elemascluster, RO.ecal2ps[elemascluster]);
1325  ecalitr->setFlag(false);
1326 
1327  LOGDRESSED("PFEGammaAlgo::linkKFTracktoECAL()") << "Found a cluster not in RO by KF extrapolation"
1328  << " at ECAL surface!" << std::endl
1329  << *elemascluster << std::endl;
1330  RO.localMap.insert(elemascluster, kfflagged);
1331  }
1332  }
1333 }
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
#define LOGDRESSED(x)
Definition: PFEGammaAlgo.cc:47
reco::PFBlockElementCluster PFClusterElement
Definition: PFEGammaAlgo.h:69
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148
int attachPSClusters(const PFClusterElement *, ClusterMap::mapped_type &)

◆ linkRefinableObjectBremTangentsToECAL()

void PFEGammaAlgo::linkRefinableObjectBremTangentsToECAL ( ProtoEGObject RO)
private

Definition at line 1335 of file PFEGammaAlgo.cc.

References _currentblock, _splayedblock, funct::abs(), attachPSClusters(), PFEGammaAlgo::ProtoEGObject::brems, docast, bsc_activity_cfg::ecal, reco::PFBlockElement::ECAL, PFEGammaAlgo::ProtoEGObject::ecal2ps, PFEGammaAlgo::ProtoEGObject::ecalclusters, PFEGammaAlgo::ProtoEGObject::firstBrem, CommutativePairs< T >::insert(), PFEGammaAlgo::ProtoEGObject::localMap, LOGDRESSED, PFEGammaAlgo::ProtoEGObject::nBremsWithClusters, and l1ctLayer1_patternWriters_cff::partition.

Referenced by operator()().

1335  {
1336  if (RO.brems.empty())
1337  return;
1338  int FirstBrem = -1;
1339  int TrajPos = -1;
1340  int lastBremTrajPos = -1;
1341  for (auto& brem : RO.brems) {
1342  bool has_clusters = false;
1343  TrajPos = (brem->indTrajPoint()) - 2;
1344  auto ECALbegin = _splayedblock[reco::PFBlockElement::ECAL].begin();
1345  auto ECALend = _splayedblock[reco::PFBlockElement::ECAL].end();
1346  NotCloserToOther<reco::PFBlockElement::BREM, reco::PFBlockElement::ECAL> BremToECALs(_currentblock, brem);
1347  // check for late brem using clusters already in the SC
1348  auto RSCBegin = RO.ecalclusters.begin();
1349  auto RSCEnd = RO.ecalclusters.end();
1350  auto notmatched_rsc = std::partition(RSCBegin, RSCEnd, BremToECALs);
1351  for (auto ecal = RSCBegin; ecal != notmatched_rsc; ++ecal) {
1352  float deta = std::abs((*ecal)->clusterRef()->positionREP().eta() - brem->positionAtECALEntrance().eta());
1353  if (deta < 0.015) {
1354  has_clusters = true;
1355  if (lastBremTrajPos == -1 || lastBremTrajPos < TrajPos) {
1356  lastBremTrajPos = TrajPos;
1357  }
1358  if (FirstBrem == -1 || TrajPos < FirstBrem) { // set brem information
1359  FirstBrem = TrajPos;
1360  RO.firstBrem = TrajPos;
1361  }
1362  LOGDRESSED("PFEGammaAlgo::linkBremToECAL()") << "Found a cluster already in SC linked to brem extrapolation"
1363  << " at ECAL surface!" << std::endl;
1364  RO.localMap.insert(ecal->get(), brem);
1365  }
1366  }
1367  // grab new clusters from the block (ensured to not be late brem)
1368  auto notmatched_block = std::partition(ECALbegin, ECALend, BremToECALs);
1369  for (auto ecal = ECALbegin; ecal != notmatched_block; ++ecal) {
1370  float deta = std::abs((*ecal)->clusterRef()->positionREP().eta() - brem->positionAtECALEntrance().eta());
1371  if (deta < 0.015) {
1372  has_clusters = true;
1373  if (lastBremTrajPos == -1 || lastBremTrajPos < TrajPos) {
1374  lastBremTrajPos = TrajPos;
1375  }
1376  if (FirstBrem == -1 || TrajPos < FirstBrem) { // set brem information
1377 
1378  FirstBrem = TrajPos;
1379  RO.firstBrem = TrajPos;
1380  }
1381  const PFClusterElement* elemasclus = docast(const PFClusterElement*, ecal->get());
1382  if (addPFClusterToROSafe(elemasclus, RO)) {
1383  attachPSClusters(elemasclus, RO.ecal2ps[elemasclus]);
1384 
1385  RO.localMap.insert(ecal->get(), brem);
1386  ecal->setFlag(false);
1387  LOGDRESSED("PFEGammaAlgo::linkBremToECAL()") << "Found a cluster not already associated by brem extrapolation"
1388  << " at ECAL surface!" << std::endl;
1389  }
1390  }
1391  }
1392  if (has_clusters) {
1393  if (RO.nBremsWithClusters == -1)
1394  RO.nBremsWithClusters = 0;
1395  ++RO.nBremsWithClusters;
1396  }
1397  }
1398 }
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
#define LOGDRESSED(x)
Definition: PFEGammaAlgo.cc:47
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
reco::PFBlockElementCluster PFClusterElement
Definition: PFEGammaAlgo.h:69
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148
int attachPSClusters(const PFClusterElement *, ClusterMap::mapped_type &)

◆ linkRefinableObjectConvSecondaryKFsToSecondaryKFs()

void PFEGammaAlgo::linkRefinableObjectConvSecondaryKFsToSecondaryKFs ( ProtoEGObject RO)
private

Definition at line 1400 of file PFEGammaAlgo.cc.

References _currentblock, _splayedblock, HLT_2023v11_cff::distance, docast, heavyIonCSV_trainingSettings::idx, CommutativePairs< T >::insert(), PFEGammaAlgo::ProtoEGObject::localMap, l1ctLayer1_patternWriters_cff::partition, PFEGammaAlgo::ProtoEGObject::secondaryKFs, reco::PFBlockElement::TRACK, and x.

Referenced by operator()().

1400  {
1401  auto KFbegin = _splayedblock[reco::PFBlockElement::TRACK].begin();
1402  auto KFend = _splayedblock[reco::PFBlockElement::TRACK].end();
1403  auto BeginROskfs = RO.secondaryKFs.begin();
1404  auto EndROskfs = RO.secondaryKFs.end();
1405  auto ronotconv = std::partition(BeginROskfs, EndROskfs, [](auto const& x) { return x->trackType(ConvType); });
1406  size_t convkfs_end = std::distance(BeginROskfs, ronotconv);
1407  for (size_t idx = 0; idx < convkfs_end; ++idx) {
1408  auto const& secKFs =
1409  RO.secondaryKFs; //we want the entry at the index but we allocate to secondaryKFs in loop which invalidates all iterators, references and pointers, hence we need to get the entry fresh each time
1410  NotCloserToOther<reco::PFBlockElement::TRACK, reco::PFBlockElement::TRACK, true> TracksToTracks(_currentblock,
1411  secKFs[idx]);
1412  auto notmatched = std::partition(KFbegin, KFend, TracksToTracks);
1413  notmatched = std::partition(KFbegin, notmatched, [](auto const& x) { return x->trackType(ConvType); });
1414  for (auto kf = KFbegin; kf != notmatched; ++kf) {
1415  const reco::PFBlockElementTrack* elemaskf = docast(const reco::PFBlockElementTrack*, kf->get());
1416  RO.secondaryKFs.push_back(elemaskf);
1417  RO.localMap.insert(secKFs[idx], kf->get());
1418  kf->setFlag(false);
1419  }
1420  }
1421 }
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148

◆ linkRefinableObjectECALToSingleLegConv()

void PFEGammaAlgo::linkRefinableObjectECALToSingleLegConv ( ProtoEGObject RO)
private

Definition at line 1423 of file PFEGammaAlgo.cc.

References _currentblock, _splayedblock, cfg_, docast, PFEGammaAlgo::ProtoEGObject::ecalclusters, evaluateSingleLegMVA(), CommutativePairs< T >::insert(), PFEGammaAlgo::ProtoEGObject::localMap, PFEGammaAlgo::PFEGConfigInfo::mvaConvCut, l1ctLayer1_patternWriters_cff::partition, primaryVertex_, PFEGammaAlgo::ProtoEGObject::secondaryKFs, PFEGammaAlgo::ProtoEGObject::singleLegConversionMvaMap, reco::PFBlockElement::TRACK, and x.

Referenced by operator()().

1423  {
1424  auto KFbegin = _splayedblock[reco::PFBlockElement::TRACK].begin();
1425  auto KFend = _splayedblock[reco::PFBlockElement::TRACK].end();
1426  for (auto& ecal : RO.ecalclusters) {
1427  NotCloserToOther<reco::PFBlockElement::ECAL, reco::PFBlockElement::TRACK, true> ECALToTracks(_currentblock,
1428  ecal.get());
1429  auto notmatchedkf = std::partition(KFbegin, KFend, ECALToTracks);
1430  auto notconvkf = std::partition(KFbegin, notmatchedkf, [](auto const& x) { return x->trackType(ConvType); });
1431  // add identified KF conversion tracks
1432  for (auto kf = KFbegin; kf != notconvkf; ++kf) {
1433  const reco::PFBlockElementTrack* elemaskf = docast(const reco::PFBlockElementTrack*, kf->get());
1434  RO.secondaryKFs.push_back(elemaskf);
1435  RO.localMap.insert(ecal.get(), elemaskf);
1436  kf->setFlag(false);
1437  }
1438  // go through non-conv-identified kfs and check MVA to add conversions
1439  for (auto kf = notconvkf; kf != notmatchedkf; ++kf) {
1440  float mvaval = evaluateSingleLegMVA(_currentblock, primaryVertex_, (*kf)->index());
1441  if (mvaval > cfg_.mvaConvCut) {
1442  const reco::PFBlockElementTrack* elemaskf = docast(const reco::PFBlockElementTrack*, kf->get());
1443  RO.secondaryKFs.push_back(elemaskf);
1444  RO.localMap.insert(ecal.get(), elemaskf);
1445  kf->setFlag(false);
1446 
1447  RO.singleLegConversionMvaMap.emplace(elemaskf, mvaval);
1448  }
1449  }
1450  }
1451 }
float evaluateSingleLegMVA(const reco::PFBlockRef &blockref, const reco::Vertex &primaryVtx, unsigned int trackIndex)
reco::Vertex const & primaryVertex_
Definition: PFEGammaAlgo.h:222
unsigned int index
index type
Definition: Vertex.h:54
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
PFEGConfigInfo const & cfg_
Definition: PFEGammaAlgo.h:221
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148

◆ linkRefinableObjectGSFTracksToKFs()

void PFEGammaAlgo::linkRefinableObjectGSFTracksToKFs ( ProtoEGObject RO)
private

Definition at line 1162 of file PFEGammaAlgo.cc.

References _currentblock, _splayedblock, docast, PFEGammaAlgo::ProtoEGObject::electronSeed, relativeConstraints::empty, CommutativePairs< T >::insert(), edm::Ref< C, T, F >::isNull(), isPrimaryTrack(), PFEGammaAlgo::ProtoEGObject::localMap, l1ctLayer1_patternWriters_cff::partition, PFEGammaAlgo::ProtoEGObject::primaryGSFs, PFEGammaAlgo::ProtoEGObject::primaryKFs, PFEGammaAlgo::ProtoEGObject::secondaryKFs, reco::PFBlockElement::T_FROM_GAMMACONV, reco::PFBlockElement::TRACK, reco::PFBlockElementTrack::trackType(), and reco::PFBlockElementGsfTrack::trackType().

Referenced by operator()().

1162  {
1165  return;
1166  auto KFbegin = _splayedblock[reco::PFBlockElement::TRACK].begin();
1167  auto KFend = _splayedblock[reco::PFBlockElement::TRACK].end();
1168  for (auto& gsfflagged : RO.primaryGSFs) {
1169  const PFGSFElement* seedtk = gsfflagged;
1170  // don't process SC-only ROs or secondary seeded ROs
1171  if (RO.electronSeed.isNull() || seedtk->trackType(convType))
1172  continue;
1173  NotCloserToOther<reco::PFBlockElement::GSF, reco::PFBlockElement::TRACK> gsfTrackToKFs(_currentblock, seedtk);
1174  // get KF tracks not closer to another and not already used
1175  auto notlinked = std::partition(KFbegin, KFend, gsfTrackToKFs);
1176  // attach tracks and set as used
1177  for (auto kft = KFbegin; kft != notlinked; ++kft) {
1178  const PFKFElement* elemaskf = docast(const PFKFElement*, kft->get());
1179  // don't care about things that aren't primaries or directly
1180  // associated secondary tracks
1181  if (isPrimaryTrack(*elemaskf, *seedtk) && !elemaskf->trackType(convType)) {
1182  kft->setFlag(false);
1183  RO.primaryKFs.push_back(elemaskf);
1184  RO.localMap.insert(seedtk, elemaskf);
1185  } else if (elemaskf->trackType(convType)) {
1186  kft->setFlag(false);
1187  RO.secondaryKFs.push_back(elemaskf);
1188  RO.localMap.insert(seedtk, elemaskf);
1189  }
1190  } // loop on closest KFs not closer to other GSFs
1191  } // loop on GSF primaries on RO
1192 }
reco::PFBlockElementGsfTrack PFGSFElement
Definition: PFEGammaAlgo.h:67
bool isPrimaryTrack(const reco::PFBlockElementTrack &KfEl, const reco::PFBlockElementGsfTrack &GsfEl)
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
reco::PFBlockElementTrack PFKFElement
Definition: PFEGammaAlgo.h:68
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148

◆ linkRefinableObjectKFTracksToECAL()

void PFEGammaAlgo::linkRefinableObjectKFTracksToECAL ( ProtoEGObject RO)
private

Definition at line 1289 of file PFEGammaAlgo.cc.

References _splayedblock, reco::PFBlockElement::ECAL, relativeConstraints::empty, linkKFTrackToECAL(), PFEGammaAlgo::ProtoEGObject::primaryKFs, and PFEGammaAlgo::ProtoEGObject::secondaryKFs.

Referenced by operator()().

1289  {
1291  return;
1292  for (auto& primkf : RO.primaryKFs)
1293  linkKFTrackToECAL(primkf, RO);
1294  for (auto& secdkf : RO.secondaryKFs)
1295  linkKFTrackToECAL(secdkf, RO);
1296 }
void linkKFTrackToECAL(PFKFElement const *, ProtoEGObject &)
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148

◆ linkRefinableObjectPrimaryGSFTrackToECAL()

void PFEGammaAlgo::linkRefinableObjectPrimaryGSFTrackToECAL ( ProtoEGObject RO)
private

Definition at line 1225 of file PFEGammaAlgo.cc.

References _currentblock, _splayedblock, attachPSClusters(), docast, bsc_activity_cfg::ecal, reco::PFBlockElement::ECAL, PFEGammaAlgo::ProtoEGObject::ecal2ps, PFEGammaAlgo::ProtoEGObject::ecalclusters, PFEGammaAlgo::ProtoEGObject::electronClusters, relativeConstraints::empty, CommutativePairs< T >::insert(), PFEGammaAlgo::ProtoEGObject::localMap, LOGDRESSED, l1ctLayer1_patternWriters_cff::partition, PFEGammaAlgo::ProtoEGObject::primaryGSFs, groupFilesInBlocks::temp, and x.

Referenced by operator()().

1225  {
1227  RO.electronClusters.push_back(nullptr);
1228  return;
1229  }
1230  auto ECALbegin = _splayedblock[reco::PFBlockElement::ECAL].begin();
1231  auto ECALend = _splayedblock[reco::PFBlockElement::ECAL].end();
1232  for (auto& primgsf : RO.primaryGSFs) {
1233  NotCloserToOther<reco::PFBlockElement::GSF, reco::PFBlockElement::ECAL> gsfTracksToECALs(_currentblock, primgsf);
1234  // get set of matching ecals not already in SC
1235  auto notmatched_blk = std::partition(ECALbegin, ECALend, gsfTracksToECALs);
1236  notmatched_blk =
1237  std::partition(ECALbegin, notmatched_blk, [&primgsf](auto const& x) { return compatibleEoPOut(*x, *primgsf); });
1238  // get set of matching ecals already in the RO
1239  auto notmatched_sc = std::partition(RO.ecalclusters.begin(), RO.ecalclusters.end(), gsfTracksToECALs);
1240  notmatched_sc = std::partition(
1241  RO.ecalclusters.begin(), notmatched_sc, [&primgsf](auto const& x) { return compatibleEoPOut(*x, *primgsf); });
1242  // look inside the SC for the ECAL cluster
1243  for (auto ecal = RO.ecalclusters.begin(); ecal != notmatched_sc; ++ecal) {
1244  const PFClusterElement* elemascluster = docast(const PFClusterElement*, ecal->get());
1245  FlaggedPtr<const PFClusterElement> temp(elemascluster, true);
1246  LOGDRESSED("PFEGammaAlgo::linkGSFTracktoECAL()") << "Found a cluster already in RO by GSF extrapolation"
1247  << " at ECAL surface!" << std::endl
1248  << *elemascluster << std::endl;
1249 
1250  RO.localMap.insert(primgsf, temp.get());
1251  }
1252  // look outside the SC for the ecal cluster
1253  for (auto ecal = ECALbegin; ecal != notmatched_blk; ++ecal) {
1254  const PFClusterElement* elemascluster = docast(const PFClusterElement*, ecal->get());
1255  LOGDRESSED("PFEGammaAlgo::linkGSFTracktoECAL()") << "Found a cluster not already in RO by GSF extrapolation"
1256  << " at ECAL surface!" << std::endl
1257  << *elemascluster << std::endl;
1258  if (addPFClusterToROSafe(elemascluster, RO)) {
1259  attachPSClusters(elemascluster, RO.ecal2ps[elemascluster]);
1260  RO.localMap.insert(primgsf, elemascluster);
1261  ecal->setFlag(false);
1262  }
1263  }
1264  }
1265 }
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
#define LOGDRESSED(x)
Definition: PFEGammaAlgo.cc:47
reco::PFBlockElementCluster PFClusterElement
Definition: PFEGammaAlgo.h:69
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148
int attachPSClusters(const PFClusterElement *, ClusterMap::mapped_type &)

◆ linkRefinableObjectPrimaryGSFTrackToHCAL()

void PFEGammaAlgo::linkRefinableObjectPrimaryGSFTrackToHCAL ( ProtoEGObject RO)
private

Definition at line 1268 of file PFEGammaAlgo.cc.

References _currentblock, _splayedblock, docast, relativeConstraints::empty, reco::PFBlockElement::HCAL, hltEgammaHLTExtra_cfi::hcal, PFEGammaAlgo::ProtoEGObject::hcalClusters, CommutativePairs< T >::insert(), PFEGammaAlgo::ProtoEGObject::localMap, LOGDRESSED, l1ctLayer1_patternWriters_cff::partition, PFEGammaAlgo::ProtoEGObject::primaryGSFs, and groupFilesInBlocks::temp.

Referenced by operator()().

1268  {
1270  return;
1271  auto HCALbegin = _splayedblock[reco::PFBlockElement::HCAL].begin();
1272  auto HCALend = _splayedblock[reco::PFBlockElement::HCAL].end();
1273  for (auto& primgsf : RO.primaryGSFs) {
1274  NotCloserToOther<reco::PFBlockElement::GSF, reco::PFBlockElement::HCAL> gsfTracksToHCALs(_currentblock, primgsf);
1275  auto notmatched = std::partition(HCALbegin, HCALend, gsfTracksToHCALs);
1276  for (auto hcal = HCALbegin; hcal != notmatched; ++hcal) {
1277  const PFClusterElement* elemascluster = docast(const PFClusterElement*, hcal->get());
1278  FlaggedPtr<const PFClusterElement> temp(elemascluster, true);
1279  LOGDRESSED("PFEGammaAlgo::linkGSFTracktoECAL()")
1280  << "Found an HCAL cluster associated to GSF extrapolation" << std::endl;
1281  RO.hcalClusters.push_back(temp.get());
1282  RO.localMap.insert(primgsf, temp.get());
1283  hcal->setFlag(false);
1284  }
1285  }
1286 }
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
#define LOGDRESSED(x)
Definition: PFEGammaAlgo.cc:47
reco::PFBlockElementCluster PFClusterElement
Definition: PFEGammaAlgo.h:69
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148

◆ linkRefinableObjectPrimaryKFsToSecondaryKFs()

void PFEGammaAlgo::linkRefinableObjectPrimaryKFsToSecondaryKFs ( ProtoEGObject RO)
private

Definition at line 1194 of file PFEGammaAlgo.cc.

References _currentblock, _splayedblock, docast, relativeConstraints::empty, Exception, CommutativePairs< T >::insert(), PFEGammaAlgo::ProtoEGObject::localMap, l1ctLayer1_patternWriters_cff::partition, PFEGammaAlgo::ProtoEGObject::primaryKFs, PFEGammaAlgo::ProtoEGObject::secondaryKFs, reco::PFBlockElement::T_FROM_GAMMACONV, reco::PFBlockElement::TRACK, and reco::PFBlockElementTrack::trackType().

Referenced by operator()().

1194  {
1197  return;
1198  auto KFbegin = _splayedblock[reco::PFBlockElement::TRACK].begin();
1199  auto KFend = _splayedblock[reco::PFBlockElement::TRACK].end();
1200  for (auto& primkf : RO.primaryKFs) {
1201  // don't process SC-only ROs or secondary seeded ROs
1202  if (primkf->trackType(convType)) {
1203  throw cms::Exception("PFEGammaAlgo::linkRefinableObjectPrimaryKFsToSecondaryKFs()")
1204  << "A KF track from conversion has been assigned as a primary!!" << std::endl;
1205  }
1206  NotCloserToOther<reco::PFBlockElement::TRACK, reco::PFBlockElement::TRACK, true> kfTrackToKFs(_currentblock,
1207  primkf);
1208  // get KF tracks not closer to another and not already used
1209  auto notlinked = std::partition(KFbegin, KFend, kfTrackToKFs);
1210  // attach tracks and set as used
1211  for (auto kft = KFbegin; kft != notlinked; ++kft) {
1212  const PFKFElement* elemaskf = docast(const PFKFElement*, kft->get());
1213  // don't care about things that aren't primaries or directly
1214  // associated secondary tracks
1215  if (elemaskf->trackType(convType)) {
1216  kft->setFlag(false);
1217  RO.secondaryKFs.push_back(elemaskf);
1218  RO.localMap.insert(primkf, elemaskf);
1219  }
1220  } // loop on closest KFs not closer to other KFs
1221  } // loop on KF primaries on RO
1222 }
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
reco::PFBlockElementTrack PFKFElement
Definition: PFEGammaAlgo.h:68
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148

◆ linkRefinableObjectSecondaryKFsToECAL()

void PFEGammaAlgo::linkRefinableObjectSecondaryKFsToECAL ( ProtoEGObject RO)
private

Definition at line 1453 of file PFEGammaAlgo.cc.

References _currentblock, _splayedblock, attachPSClusters(), docast, bsc_activity_cfg::ecal, reco::PFBlockElement::ECAL, PFEGammaAlgo::ProtoEGObject::ecal2ps, f, CommutativePairs< T >::insert(), PFEGammaAlgo::ProtoEGObject::localMap, l1ctLayer1_patternWriters_cff::partition, and PFEGammaAlgo::ProtoEGObject::secondaryKFs.

Referenced by operator()().

1453  {
1454  auto ECALbegin = _splayedblock[reco::PFBlockElement::ECAL].begin();
1455  auto ECALend = _splayedblock[reco::PFBlockElement::ECAL].end();
1456  for (auto& skf : RO.secondaryKFs) {
1457  NotCloserToOther<reco::PFBlockElement::TRACK, reco::PFBlockElement::ECAL, false> TracksToECALwithCut(
1458  _currentblock, skf, 1.5f);
1459  auto notmatched = std::partition(ECALbegin, ECALend, TracksToECALwithCut);
1460  for (auto ecal = ECALbegin; ecal != notmatched; ++ecal) {
1461  const reco::PFBlockElementCluster* elemascluster = docast(const reco::PFBlockElementCluster*, ecal->get());
1462  if (addPFClusterToROSafe(elemascluster, RO)) {
1463  attachPSClusters(elemascluster, RO.ecal2ps[elemascluster]);
1464  RO.localMap.insert(skf, elemascluster);
1465  ecal->setFlag(false);
1466  }
1467  }
1468  }
1469 }
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
double f[11][100]
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148
int attachPSClusters(const PFClusterElement *, ClusterMap::mapped_type &)

◆ mergeROsByAnyLink()

void PFEGammaAlgo::mergeROsByAnyLink ( std::list< ProtoEGObject > &  )
private

Definition at line 1082 of file PFEGammaAlgo.cc.

References PFEGammaAlgo::ProtoEGObject::brems, CommutativePairs< T >::concatenate(), HLT_2023v11_cff::distance, PFEGammaAlgo::ProtoEGObject::ecal2ps, PFEGammaAlgo::ProtoEGObject::ecalclusters, PFEGammaAlgo::ProtoEGObject::electronClusters, PFEGammaAlgo::ProtoEGObject::electronSeed, PFEGammaAlgo::ProtoEGObject::firstBrem, edm::Ref< C, T, F >::isNonnull(), edm::Ref< C, T, F >::isNull(), PFEGammaAlgo::ProtoEGObject::lateBrem, PFEGammaAlgo::ProtoEGObject::localMap, LOGDRESSED, LOGWARN, PFEGammaAlgo::ProtoEGObject::nBremsWithClusters, PFEGammaAlgo::ProtoEGObject::parentSC, l1ctLayer1_patternWriters_cff::partition, PFEGammaAlgo::ProtoEGObject::primaryGSFs, PFEGammaAlgo::ProtoEGObject::primaryKFs, PFEGammaAlgo::ProtoEGObject::secondaryKFs, and std::swap().

Referenced by operator()().

1082  {
1083  if (ROs.size() < 2)
1084  return; // nothing to do with one or zero ROs
1085  bool check_for_merge = true;
1086  while (check_for_merge) {
1087  // bugfix for early termination merging loop (15 April 2014)
1088  // check all pairwise combinations in the list
1089  // if one has a merge shuffle it to the front of the list
1090  // if there are no merges left to do we can terminate
1091  for (auto it1 = ROs.begin(); it1 != ROs.end(); ++it1) {
1092  auto find_start = it1;
1093  ++find_start;
1094  auto has_merge = std::find_if(find_start, ROs.end(), std::bind(testIfROMergableByLink, _1, *it1));
1095  if (has_merge != ROs.end() && it1 != ROs.begin()) {
1096  std::swap(*(ROs.begin()), *it1);
1097  break;
1098  }
1099  } // ensure mergables are shuffled to the front
1100  ProtoEGObject& thefront = ROs.front();
1101  auto mergestart = ROs.begin();
1102  ++mergestart;
1103  auto nomerge = std::partition(mergestart, ROs.end(), std::bind(testIfROMergableByLink, _1, thefront));
1104  if (nomerge != mergestart) {
1105  LOGDRESSED("PFEGammaAlgo::mergeROsByAnyLink()")
1106  << "Found objects " << std::distance(mergestart, nomerge) << " to merge by links to the front!" << std::endl;
1107  for (auto roToMerge = mergestart; roToMerge != nomerge; ++roToMerge) {
1108  //bugfix! L.Gray 14 Jan 2016
1109  // -- check that the front is still mergeable!
1110  if (!thefront.ecalclusters.empty() && !roToMerge->ecalclusters.empty()) {
1111  if (thefront.ecalclusters.front()->clusterRef()->layer() !=
1112  roToMerge->ecalclusters.front()->clusterRef()->layer()) {
1113  LOGWARN("PFEGammaAlgo::mergeROsByAnyLink") << "Tried to merge EB and EE clusters! Skipping!";
1114  ROs.push_back(*roToMerge);
1115  continue;
1116  }
1117  }
1118  //end bugfix
1119  thefront.ecalclusters.insert(
1120  thefront.ecalclusters.end(), roToMerge->ecalclusters.begin(), roToMerge->ecalclusters.end());
1121  thefront.ecal2ps.insert(roToMerge->ecal2ps.begin(), roToMerge->ecal2ps.end());
1122  thefront.secondaryKFs.insert(
1123  thefront.secondaryKFs.end(), roToMerge->secondaryKFs.begin(), roToMerge->secondaryKFs.end());
1124 
1125  thefront.localMap.concatenate(roToMerge->localMap);
1126  // TO FIX -> use best (E_gsf - E_clustersum)/E_GSF
1127  if (!thefront.parentSC && roToMerge->parentSC) {
1128  thefront.parentSC = roToMerge->parentSC;
1129  }
1130  if (thefront.electronSeed.isNull() && roToMerge->electronSeed.isNonnull()) {
1131  thefront.electronSeed = roToMerge->electronSeed;
1132  thefront.primaryGSFs.insert(
1133  thefront.primaryGSFs.end(), roToMerge->primaryGSFs.begin(), roToMerge->primaryGSFs.end());
1134  thefront.primaryKFs.insert(
1135  thefront.primaryKFs.end(), roToMerge->primaryKFs.begin(), roToMerge->primaryKFs.end());
1136  thefront.brems.insert(thefront.brems.end(), roToMerge->brems.begin(), roToMerge->brems.end());
1137  thefront.electronClusters = roToMerge->electronClusters;
1138  thefront.nBremsWithClusters = roToMerge->nBremsWithClusters;
1139  thefront.firstBrem = roToMerge->firstBrem;
1140  thefront.lateBrem = roToMerge->lateBrem;
1141  } else if (thefront.electronSeed.isNonnull() && roToMerge->electronSeed.isNonnull()) {
1142  LOGDRESSED("PFEGammaAlgo::mergeROsByAnyLink")
1143  << "Need to implement proper merging of two gsf candidates!" << std::endl;
1144  }
1145  }
1146  ROs.erase(mergestart, nomerge);
1147  // put the merged element in the back of the cleaned list
1148  ROs.push_back(ROs.front());
1149  ROs.pop_front();
1150  } else {
1151  check_for_merge = false;
1152  }
1153  }
1154  LOGDRESSED("PFEGammaAlgo::mergeROsByAnyLink()")
1155  << "After merging by links there are: " << ROs.size() << " refinable EGamma objects!" << std::endl;
1156 }
#define LOGDRESSED(x)
Definition: PFEGammaAlgo.cc:47
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
#define LOGWARN(x)
Definition: PFEGammaAlgo.cc:45

◆ operator()()

PFEGammaAlgo::EgammaObjects PFEGammaAlgo::operator() ( const reco::PFBlockRef block)

Definition at line 528 of file PFEGammaAlgo.cc.

References _currentblock, _currentlinks, _splayedblock, a, b, reco::CaloCluster::badHcalMarker, groupFilesInBlocks::block, dumpCurrentRefinableObjects(), fillPFCandidates(), HCAL, initializeProtoCands(), isMuon(), linkRefinableObjectBremTangentsToECAL(), linkRefinableObjectConvSecondaryKFsToSecondaryKFs(), linkRefinableObjectECALToSingleLegConv(), linkRefinableObjectGSFTracksToKFs(), linkRefinableObjectKFTracksToECAL(), linkRefinableObjectPrimaryGSFTrackToECAL(), linkRefinableObjectPrimaryGSFTrackToHCAL(), linkRefinableObjectPrimaryKFsToSecondaryKFs(), linkRefinableObjectSecondaryKFsToECAL(), LOGDRESSED, LOGVERB, mergeROsByAnyLink(), removeOrLinkECALClustersToKFTracks(), jetUpdater_cfi::sort, unlinkRefinableObjectKFandECALMatchedToHCAL(), and unlinkRefinableObjectKFandECALWithBadEoverP().

528  {
529  LOGVERB("PFEGammaAlgo") << "Resetting PFEGammaAlgo for new block and running!" << std::endl;
530 
531  // candidate collections:
532  // this starts off as an inclusive list of prototype objects built from
533  // supercluster/ecal-driven seeds and tracker driven seeds in a block
534  // it is then refined through by various cleanings, determining the energy
535  // flow.
536  // use list for constant-time removals
537  std::list<ProtoEGObject> refinableObjects;
538 
539  _splayedblock.clear();
540  _splayedblock.resize(13); // make sure that we always have the HGCAL entry
541 
543  _currentlinks = block->linkData();
544  //LOGDRESSED("PFEGammaAlgo") << *_currentblock << std::endl;
545  LOGVERB("PFEGammaAlgo") << "Splaying block" << std::endl;
546  //unwrap the PF block into a fast access map
547  for (const auto& pfelement : _currentblock->elements()) {
548  if (isMuon(pfelement))
549  continue; // don't allow muons in our element list
550  if (pfelement.type() == PFBlockElement::HCAL && pfelement.clusterRef()->flags() & reco::CaloCluster::badHcalMarker)
551  continue; // skip also dead area markers for now
552  const size_t itype = (size_t)pfelement.type();
553  if (itype >= _splayedblock.size())
554  _splayedblock.resize(itype + 1);
555  _splayedblock[itype].emplace_back(&pfelement, true);
556  }
557 
558  // show the result of splaying the tree if it's really *really* needed
559 #ifdef PFLOW_DEBUG
560  std::stringstream splayout;
561  for (size_t itype = 0; itype < _splayedblock.size(); ++itype) {
562  splayout << "\tType: " << itype << " indices: ";
563  for (const auto& flaggedelement : _splayedblock[itype]) {
564  splayout << flaggedelement->index() << ' ';
565  }
566  if (itype != _splayedblock.size() - 1)
567  splayout << std::endl;
568  }
569  LOGVERB("PFEGammaAlgo") << splayout.str();
570 #endif
571 
572  // precleaning of the ECAL clusters with respect to primary KF tracks
573  // we don't allow clusters in super clusters to be locked out this way
575 
576  initializeProtoCands(refinableObjects);
577  LOGDRESSED("PFEGammaAlgo") << "Initialized " << refinableObjects.size() << " proto-EGamma objects" << std::endl;
579 
580  //
581  // now we start the refining steps
582  //
583  //
584 
585  // --- Primary Linking Step ---
586  // since this is particle flow and we try to work from the pixels out
587  // we start by linking the tracks together and finding the ECAL clusters
588  for (auto& RO : refinableObjects) {
589  // find the KF tracks associated to GSF primary tracks
591  // do the same for HCAL clusters associated to the GSF
593  // link secondary KF tracks associated to primary KF tracks
595  // pick up clusters that are linked to the GSF primary
597  // link associated KF to ECAL (ECAL part grabs PS clusters too if able)
599  // now finally look for clusters associated to brem tangents
601  }
602 
603  LOGDRESSED("PFEGammaAlgo") << "Dumping after GSF and KF Track (Primary) Linking : " << std::endl;
605 
606  // merge objects after primary linking
607  mergeROsByAnyLink(refinableObjects);
608 
609  LOGDRESSED("PFEGammaAlgo") << "Dumping after first merging operation : " << std::endl;
611 
612  // --- Secondary Linking Step ---
613  // after this we go through the ECAL clusters on the remaining tracks
614  // and try to link those in...
615  for (auto& RO : refinableObjects) {
616  // look for conversion legs
619  // look for tracks that complement conversion legs
621  // look again for ECAL clusters (this time with an e/p cut)
623  }
624 
625  LOGDRESSED("PFEGammaAlgo") << "Dumping after ECAL to Track (Secondary) Linking : " << std::endl;
627 
628  // merge objects after primary linking
629  mergeROsByAnyLink(refinableObjects);
630 
631  LOGDRESSED("PFEGammaAlgo") << "There are " << refinableObjects.size() << " after the 2nd merging step." << std::endl;
633 
634  // -- unlinking and proto-object vetos, final sorting
635  for (auto& RO : refinableObjects) {
636  // remove secondary KFs (and possibly ECALs) matched to HCAL clusters
638  // remove secondary KFs and ECALs linked to them that have bad E/p_in
639  // and spoil the resolution
641  // put things back in order after partitioning
642  std::sort(RO.ecalclusters.begin(), RO.ecalclusters.end(), [](auto const& a, auto const& b) {
643  return (a->clusterRef()->correctedEnergy() > b->clusterRef()->correctedEnergy());
644  });
645  setROElectronCluster(RO);
646  }
647 
648  LOGDRESSED("PFEGammaAlgo") << "There are " << refinableObjects.size() << " after the unlinking and vetos step."
649  << std::endl;
651 
652  // fill the PF candidates and then build the refined SC
653  return fillPFCandidates(refinableObjects);
654 }
void unlinkRefinableObjectKFandECALWithBadEoverP(ProtoEGObject &)
void dumpCurrentRefinableObjects() const
void linkRefinableObjectPrimaryGSFTrackToECAL(ProtoEGObject &)
void linkRefinableObjectBremTangentsToECAL(ProtoEGObject &)
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
void linkRefinableObjectECALToSingleLegConv(ProtoEGObject &)
#define LOGVERB(x)
Definition: PFEGammaAlgo.cc:44
#define LOGDRESSED(x)
Definition: PFEGammaAlgo.cc:47
void initializeProtoCands(std::list< ProtoEGObject > &)
void linkRefinableObjectPrimaryKFsToSecondaryKFs(ProtoEGObject &)
reco::PFBlock::LinkData _currentlinks
Definition: PFEGammaAlgo.h:145
bool isMuon(const reco::PFBlockElement &)
double b
Definition: hdecay.h:118
void linkRefinableObjectGSFTracksToKFs(ProtoEGObject &)
void removeOrLinkECALClustersToKFTracks()
EgammaObjects fillPFCandidates(const std::list< ProtoEGObject > &)
void unlinkRefinableObjectKFandECALMatchedToHCAL(ProtoEGObject &, bool removeFreeECAL=false, bool removeSCECAL=false)
double a
Definition: hdecay.h:119
void mergeROsByAnyLink(std::list< ProtoEGObject > &)
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148
void linkRefinableObjectKFTracksToECAL(ProtoEGObject &)
void linkRefinableObjectSecondaryKFsToECAL(ProtoEGObject &)
void linkRefinableObjectConvSecondaryKFsToSecondaryKFs(ProtoEGObject &)
void linkRefinableObjectPrimaryGSFTrackToHCAL(ProtoEGObject &)

◆ removeOrLinkECALClustersToKFTracks()

void PFEGammaAlgo::removeOrLinkECALClustersToKFTracks ( )
private

Definition at line 1001 of file PFEGammaAlgo.cc.

References _currentblock, _currentlinks, _splayedblock, docast, reco::PFBlockElement::ECAL, relativeConstraints::empty, f, reco::PFBlockElement::GSF, reco::PFBlockElement::index(), PFTrackAlgoTools::isGoodForEGMPrimary(), reco::PFBlock::LINKTEST_ALL, primaryVertex_, reco::PFBlockElement::SC, reco::PFBlockElement::T_FROM_GAMMACONV, reco::PFBlockElement::TRACK, reco::PFBlockElementTrack::trackRef(), reco::Vertex::tracks_begin(), reco::Vertex::tracks_end(), and reco::PFBlockElementGsfTrack::trackType().

Referenced by operator()().

1001  {
1002  typedef std::multimap<double, unsigned> MatchedMap;
1003  typedef const reco::PFBlockElementGsfTrack* GsfTrackElementPtr;
1005  return;
1006  MatchedMap matchedGSFs, matchedECALs;
1007  std::unordered_map<GsfTrackElementPtr, MatchedMap> gsf_ecal_cache;
1008  for (auto& kftrack : _splayedblock[reco::PFBlockElement::TRACK]) {
1009  matchedGSFs.clear();
1010  _currentblock->associatedElements(
1011  kftrack->index(), _currentlinks, matchedGSFs, reco::PFBlockElement::GSF, reco::PFBlock::LINKTEST_ALL);
1012  if (matchedGSFs.empty()) { // only run this if we aren't associated to GSF
1013  LesserByDistance closestTrackToECAL(_currentblock, _currentlinks, kftrack.get());
1014  auto ecalbegin = _splayedblock[reco::PFBlockElement::ECAL].begin();
1015  auto ecalend = _splayedblock[reco::PFBlockElement::ECAL].end();
1016  std::partial_sort(ecalbegin, ecalbegin + 1, ecalend, closestTrackToECAL);
1017  auto& closestECAL = _splayedblock[reco::PFBlockElement::ECAL].front();
1018  const float dist =
1019  _currentblock->dist(kftrack->index(), closestECAL->index(), _currentlinks, reco::PFBlock::LINKTEST_ALL);
1020  bool inSC = false;
1021  for (auto& sc : _splayedblock[reco::PFBlockElement::SC]) {
1022  float dist_sc =
1023  _currentblock->dist(sc->index(), closestECAL->index(), _currentlinks, reco::PFBlock::LINKTEST_ALL);
1024  if (dist_sc != -1.0f) {
1025  inSC = true;
1026  break;
1027  }
1028  }
1029 
1030  if (dist != -1.0f && closestECAL.flag()) {
1031  bool gsflinked = false;
1032  // check that this cluster is not associated to a GSF track
1033  for (const auto& gsfflag : _splayedblock[reco::PFBlockElement::GSF]) {
1034  const reco::PFBlockElementGsfTrack* elemasgsf = docast(const reco::PFBlockElementGsfTrack*, gsfflag.get());
1036  continue; // keep clusters that have a found conversion GSF near
1037  }
1038  // make sure cache exists
1039  if (!gsf_ecal_cache.count(elemasgsf)) {
1040  matchedECALs.clear();
1041  _currentblock->associatedElements(elemasgsf->index(),
1042  _currentlinks,
1043  matchedECALs,
1046  gsf_ecal_cache.emplace(elemasgsf, matchedECALs);
1047  MatchedMap().swap(matchedECALs);
1048  }
1049  const MatchedMap& ecal_matches = gsf_ecal_cache[elemasgsf];
1050  if (!ecal_matches.empty()) {
1051  if (ecal_matches.begin()->second == closestECAL->index()) {
1052  gsflinked = true;
1053  break;
1054  }
1055  }
1056  } // loop over primary GSF tracks
1057  if (!gsflinked && !inSC) {
1058  // determine if we should remove the matched cluster
1059  const reco::PFBlockElementTrack* kfEle = docast(const reco::PFBlockElementTrack*, kftrack.get());
1060  const reco::TrackRef& trackref = kfEle->trackRef();
1061 
1062  const int nexhits = trackref->missingInnerHits();
1063  bool fromprimaryvertex = false;
1064  for (auto vtxtks = primaryVertex_.tracks_begin(); vtxtks != primaryVertex_.tracks_end(); ++vtxtks) {
1065  if (trackref == vtxtks->castTo<reco::TrackRef>()) {
1066  fromprimaryvertex = true;
1067  break;
1068  }
1069  } // loop over tracks in primary vertex
1070  // if associated to good non-GSF matched track remove this cluster
1071  if ((PFTrackAlgoTools::isGoodForEGMPrimary(trackref->algo()) ||
1072  PFTrackAlgoTools::isGoodForEGMPrimary(trackref->originalAlgo())) &&
1073  nexhits == 0 && fromprimaryvertex) {
1074  closestECAL.setFlag(false);
1075  }
1076  }
1077  } // found a good closest ECAL match
1078  } // no GSF track matched to KF
1079  } // loop over KF elements
1080 }
reco::Vertex const & primaryVertex_
Definition: PFEGammaAlgo.h:222
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
trackRef_iterator tracks_end() const
last iterator over tracks
Definition: Vertex.h:110
unsigned index() const
trackRef_iterator tracks_begin() const
first iterator over tracks
Definition: Vertex.h:108
double f[11][100]
reco::PFBlock::LinkData _currentlinks
Definition: PFEGammaAlgo.h:145
bool trackType(TrackType trType) const override
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
const reco::TrackRef & trackRef() const override
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148
bool isGoodForEGMPrimary(const reco::TrackBase::TrackAlgorithm &)

◆ unlinkRefinableObjectKFandECALMatchedToHCAL()

void PFEGammaAlgo::unlinkRefinableObjectKFandECALMatchedToHCAL ( ProtoEGObject RO,
bool  removeFreeECAL = false,
bool  removeSCECAL = false 
)
private

Definition at line 1969 of file PFEGammaAlgo.cc.

References _currentblock, _currentlinks, _splayedblock, reco::PFBlockElementCluster::clusterRef(), CommutativePairs< T >::contains(), HLT_2023v11_cff::distance, docast, bsc_activity_cfg::ecal, PFEGammaAlgo::ProtoEGObject::ecalclusters, f, spr::goodTrack(), reco::PFBlockElement::HCAL, PFTrackAlgoTools::isGoodForEGM(), reco::PFBlock::LINKTEST_ALL, PFEGammaAlgo::ProtoEGObject::localMap, LOGDRESSED, PFEGammaAlgo::ProtoEGObject::parentSC, l1ctLayer1_patternWriters_cff::partition, and PFEGammaAlgo::ProtoEGObject::secondaryKFs.

Referenced by operator()().

1971  {
1972  std::vector<bool> cluster_in_sc;
1973  auto ecal_begin = RO.ecalclusters.begin();
1974  auto ecal_end = RO.ecalclusters.end();
1975  auto hcal_begin = _splayedblock[reco::PFBlockElement::HCAL].begin();
1976  auto hcal_end = _splayedblock[reco::PFBlockElement::HCAL].end();
1977  for (auto secd_kf = RO.secondaryKFs.begin(); secd_kf != RO.secondaryKFs.end(); ++secd_kf) {
1978  bool remove_this_kf = false;
1979  NotCloserToOther<reco::PFBlockElement::TRACK, reco::PFBlockElement::HCAL> tracksToHCALs(_currentblock, *secd_kf);
1980  reco::TrackRef trkRef = (*secd_kf)->trackRef();
1981 
1982  bool goodTrack = PFTrackAlgoTools::isGoodForEGM(trkRef->algo());
1983  const float secpin = trkRef->p();
1984 
1985  for (auto ecal = ecal_begin; ecal != ecal_end; ++ecal) {
1986  const double ecalenergy = (*ecal)->clusterRef()->correctedEnergy();
1987  // first check if the cluster is in the SC (use dist calc for fastness)
1988  const size_t clus_idx = std::distance(ecal_begin, ecal);
1989  if (cluster_in_sc.size() < clus_idx + 1) {
1990  float dist = -1.0f;
1991  if (RO.parentSC) {
1992  dist = _currentblock->dist((*secd_kf)->index(), (*ecal)->index(), _currentlinks, reco::PFBlock::LINKTEST_ALL);
1993  }
1994  cluster_in_sc.push_back(dist != -1.0f);
1995  }
1996 
1997  // if we've found a secondary KF that matches this ecal cluster
1998  // now we see if it is matched to HCAL
1999  // if it is matched to an HCAL cluster we take different
2000  // actions if the cluster was in an SC or not
2001  if (RO.localMap.contains(ecal->get(), *secd_kf)) {
2002  auto hcal_matched = std::partition(hcal_begin, hcal_end, tracksToHCALs);
2003  for (auto hcalclus = hcal_begin; hcalclus != hcal_matched; ++hcalclus) {
2004  const reco::PFBlockElementCluster* clusthcal = docast(const reco::PFBlockElementCluster*, hcalclus->get());
2005  const double hcalenergy = clusthcal->clusterRef()->energy();
2006  const double hpluse = ecalenergy + hcalenergy;
2007  const bool isHoHE = ((hcalenergy / hpluse) > 0.1 && goodTrack);
2008  const bool isHoE = (hcalenergy > ecalenergy);
2009  const bool isPoHE = (secpin > hpluse);
2010  if (cluster_in_sc[clus_idx]) {
2011  if (isHoE || isPoHE) {
2012  LOGDRESSED("PFEGammaAlgo") << "REJECTED TRACK FOR H/E or P/(H+E), CLUSTER IN SC"
2013  << " H/H+E " << (hcalenergy / hpluse) << " H/E " << (hcalenergy > ecalenergy)
2014  << " P/(H+E) " << (secpin / hpluse) << " HCAL ENE " << hcalenergy
2015  << " ECAL ENE " << ecalenergy << " secPIN " << secpin << " Algo Track "
2016  << trkRef->algo() << std::endl;
2017  remove_this_kf = true;
2018  }
2019  } else {
2020  if (isHoHE) {
2021  LOGDRESSED("PFEGammaAlgo") << "REJECTED TRACK FOR H/H+E, CLUSTER NOT IN SC"
2022  << " H/H+E " << (hcalenergy / hpluse) << " H/E " << (hcalenergy > ecalenergy)
2023  << " P/(H+E) " << (secpin / hpluse) << " HCAL ENE " << hcalenergy
2024  << " ECAL ENE " << ecalenergy << " secPIN " << secpin << " Algo Track "
2025  << trkRef->algo() << std::endl;
2026  remove_this_kf = true;
2027  }
2028  }
2029  }
2030  }
2031  }
2032  if (remove_this_kf) {
2033  secd_kf = RO.secondaryKFs.erase(secd_kf);
2034  if (secd_kf == RO.secondaryKFs.end())
2035  break;
2036  }
2037  }
2038 }
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
#define LOGDRESSED(x)
Definition: PFEGammaAlgo.cc:47
bool isGoodForEGM(const reco::TrackBase::TrackAlgorithm &)
bool goodTrack(const reco::Track *pTrack, math::XYZPoint leadPV, trackSelectionParameters parameters, bool debug=false)
double f[11][100]
const PFClusterRef & clusterRef() const override
reco::PFBlock::LinkData _currentlinks
Definition: PFEGammaAlgo.h:145
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148

◆ unlinkRefinableObjectKFandECALWithBadEoverP()

void PFEGammaAlgo::unlinkRefinableObjectKFandECALWithBadEoverP ( ProtoEGObject RO)
private

Definition at line 1896 of file PFEGammaAlgo.cc.

References _currentblock, _currentlinks, funct::abs(), PFEGammaAlgo::ProtoEGObject::brems, CommutativePairs< T >::contains(), HLT_2023v11_cff::distance, bsc_activity_cfg::ecal, PFEGammaAlgo::ProtoEGObject::ecalclusters, PVValHelper::eta, f, reco::PFBlock::LINKTEST_ALL, PFEGammaAlgo::ProtoEGObject::localMap, LOGDRESSED, PFEGammaAlgo::ProtoEGObject::primaryGSFs, and PFEGammaAlgo::ProtoEGObject::secondaryKFs.

Referenced by operator()().

1896  {
1897  // this only means something for ROs with a primary GSF track
1898  if (RO.primaryGSFs.empty())
1899  return;
1900  // need energy sums to tell if we've added crap or not
1901  const double Pin_gsf = RO.primaryGSFs.front()->GsftrackRef()->pMode();
1902  const double gsfOuterEta = RO.primaryGSFs.front()->positionAtECALEntrance().Eta();
1903  double tot_ecal = 0.0;
1904  std::vector<double> min_brem_dists;
1905  std::vector<double> closest_brem_eta;
1906  // first get the total ecal energy (we should replace this with a cache)
1907  for (const auto& ecal : RO.ecalclusters) {
1908  tot_ecal += ecal->clusterRef()->correctedEnergy();
1909  // we also need to look at the minimum distance to brems
1910  // since energetic brems will be closer to the brem than the track
1911  double min_brem_dist = 5000.0;
1912  double eta = -999.0;
1913  for (const auto& brem : RO.brems) {
1914  const float dist = _currentblock->dist(brem->index(), ecal->index(), _currentlinks, reco::PFBlock::LINKTEST_ALL);
1915  if (dist < min_brem_dist && dist != -1.0f) {
1916  min_brem_dist = dist;
1917  eta = brem->positionAtECALEntrance().Eta();
1918  }
1919  }
1920  min_brem_dists.push_back(min_brem_dist);
1921  closest_brem_eta.push_back(eta);
1922  }
1923 
1924  // loop through the ECAL clusters and remove ECAL clusters matched to
1925  // secondary track either in *or* out of the SC if the E/pin is bad
1926  for (auto secd_kf = RO.secondaryKFs.begin(); secd_kf != RO.secondaryKFs.end(); ++secd_kf) {
1927  reco::TrackRef trkRef = (*secd_kf)->trackRef();
1928  const float secpin = (*secd_kf)->trackRef()->p();
1929  bool remove_this_kf = false;
1930  for (auto ecal = RO.ecalclusters.begin(); ecal != RO.ecalclusters.end(); ++ecal) {
1931  size_t bremidx = std::distance(RO.ecalclusters.begin(), ecal);
1932  const float minbremdist = min_brem_dists[bremidx];
1933  const double ecalenergy = (*ecal)->clusterRef()->correctedEnergy();
1934  const double Epin = ecalenergy / secpin;
1935  const double detaGsf = std::abs(gsfOuterEta - (*ecal)->clusterRef()->positionREP().Eta());
1936  const double detaBrem = std::abs(closest_brem_eta[bremidx] - (*ecal)->clusterRef()->positionREP().Eta());
1937 
1938  bool kf_matched = RO.localMap.contains(ecal->get(), *secd_kf);
1939 
1940  const float tkdist =
1941  _currentblock->dist((*secd_kf)->index(), (*ecal)->index(), _currentlinks, reco::PFBlock::LINKTEST_ALL);
1942 
1943  // do not reject this track if it is closer to a brem than the
1944  // secondary track, or if it lies in the delta-eta plane with the
1945  // gsf track or if it is in the dEta plane with the brems
1946  if (Epin > 3 && kf_matched && tkdist != -1.0f && tkdist < minbremdist && detaGsf > 0.05 && detaBrem > 0.015) {
1947  double res_with = std::abs((tot_ecal - Pin_gsf) / Pin_gsf);
1948  double res_without = std::abs((tot_ecal - ecalenergy - Pin_gsf) / Pin_gsf);
1949  if (res_without < res_with) {
1950  LOGDRESSED("PFEGammaAlgo") << " REJECTED_RES totenergy " << tot_ecal << " Pin_gsf " << Pin_gsf
1951  << " cluster to secondary " << ecalenergy << " res_with " << res_with
1952  << " res_without " << res_without << std::endl;
1953  tot_ecal -= ecalenergy;
1954  remove_this_kf = true;
1955  ecal = RO.ecalclusters.erase(ecal);
1956  if (ecal == RO.ecalclusters.end())
1957  break;
1958  }
1959  }
1960  }
1961  if (remove_this_kf) {
1962  secd_kf = RO.secondaryKFs.erase(secd_kf);
1963  if (secd_kf == RO.secondaryKFs.end())
1964  break;
1965  }
1966  }
1967 }
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
#define LOGDRESSED(x)
Definition: PFEGammaAlgo.cc:47
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
reco::PFBlock::LinkData _currentlinks
Definition: PFEGammaAlgo.h:145

◆ unwrapSuperCluster()

bool PFEGammaAlgo::unwrapSuperCluster ( const reco::PFBlockElementSuperCluster thesc,
std::vector< FlaggedPtr< const PFClusterElement >> &  ecalclusters,
ClusterMap ecal2ps 
)
private

Definition at line 777 of file PFEGammaAlgo.cc.

References _currentblock, _splayedblock, attachPSClusters(), TauDecayModes::dec, HLT_2023v11_cff::distance, docast, reco::PFBlockElementCluster::Dump(), reco::PFBlockElementSuperCluster::Dump(), reco::PFBlockElement::ECAL, Exception, spr::find(), reco::PFBlockElementSuperCluster::fromPFSuperCluster(), edm::Ref< C, T, F >::get(), reco::PFBlockElement::HGCAL, edm::Ref< C, T, F >::isAvailable(), edm::Ref< C, T, F >::isNonnull(), LOGDRESSED, LOGERR, LOGVERB, l1ctLayer1_patternWriters_cff::partition, and reco::PFBlockElementSuperCluster::superClusterRef().

Referenced by initializeProtoCands().

779  {
780  ecalclusters.clear();
781  ecal2ps.clear();
782  LOGVERB("PFEGammaAlgo") << "Pointer to SC element: 0x" << std::hex << thesc << std::dec << std::endl
783  << "cleared ecalclusters and ecal2ps!" << std::endl;
784  auto ecalbegin = _splayedblock[reco::PFBlockElement::ECAL].begin();
785  auto ecalend = _splayedblock[reco::PFBlockElement::ECAL].end();
786  auto hgcalbegin = _splayedblock[reco::PFBlockElement::HGCAL].begin();
787  auto hgcalend = _splayedblock[reco::PFBlockElement::HGCAL].end();
788  if (ecalbegin == ecalend && hgcalbegin == hgcalend) {
789  LOGERR("PFEGammaAlgo::unwrapSuperCluster()") << "There are no ECAL elements in a block with imported SC!"
790  << " This is a bug we should fix this!" << std::endl;
791  return false;
792  }
793  reco::SuperClusterRef scref = thesc->superClusterRef();
794  const bool is_pf_sc = thesc->fromPFSuperCluster();
795  if (!(scref.isAvailable() && scref.isNonnull())) {
796  throw cms::Exception("PFEGammaAlgo::unwrapSuperCluster()")
797  << "SuperCluster pointed to by block element is null!" << std::endl;
798  }
799  LOGDRESSED("PFEGammaAlgo") << "Got a valid super cluster ref! 0x" << std::hex << scref.get() << std::dec << std::endl;
800  const size_t nscclusters = scref->clustersSize();
801  const size_t nscpsclusters = scref->preshowerClustersSize();
802  size_t npfpsclusters = 0;
803  size_t npfclusters = 0;
804  LOGDRESSED("PFEGammaAlgo") << "Precalculated cluster multiplicities: " << nscclusters << ' ' << nscpsclusters
805  << std::endl;
806  NotCloserToOther<reco::PFBlockElement::SC, reco::PFBlockElement::ECAL> ecalClustersInSC(_currentblock, thesc);
807  NotCloserToOther<reco::PFBlockElement::SC, reco::PFBlockElement::HGCAL> hgcalClustersInSC(_currentblock, thesc);
808  auto ecalfirstnotinsc = std::partition(ecalbegin, ecalend, ecalClustersInSC);
809  auto hgcalfirstnotinsc = std::partition(hgcalbegin, hgcalend, hgcalClustersInSC);
810  //reset the begin and end iterators
811  ecalbegin = _splayedblock[reco::PFBlockElement::ECAL].begin();
812  ecalend = _splayedblock[reco::PFBlockElement::ECAL].end();
813 
814  hgcalbegin = _splayedblock[reco::PFBlockElement::HGCAL].begin();
815  hgcalend = _splayedblock[reco::PFBlockElement::HGCAL].end();
816 
817  //get list of associated clusters by det id and energy matching
818  //(only needed when using non-pf supercluster)
819  std::vector<const ClusterElement*> safePFClusters =
820  is_pf_sc ? std::vector<const ClusterElement*>()
821  : getSCAssociatedECALsSafe(scref, _splayedblock[reco::PFBlockElement::ECAL]);
822 
823  if (ecalfirstnotinsc == ecalbegin && hgcalfirstnotinsc == hgcalbegin) {
824  LOGERR("PFEGammaAlgo::unwrapSuperCluster()") << "No associated block elements to SuperCluster!"
825  << " This is a bug we should fix!" << std::endl;
826  return false;
827  }
828  npfclusters = std::distance(ecalbegin, ecalfirstnotinsc) + std::distance(hgcalbegin, hgcalfirstnotinsc);
829  // ensure we have found the correct number of PF ecal clusters in the case
830  // that this is a PF supercluster, otherwise all bets are off
831  if (is_pf_sc && nscclusters != npfclusters) {
832  std::stringstream sc_err;
833  thesc->Dump(sc_err, "\t");
834  throw cms::Exception("PFEGammaAlgo::unwrapSuperCluster()")
835  << "The number of found ecal elements (" << nscclusters << ") in block is not the same as"
836  << " the number of ecal PF clusters reported by the PFSuperCluster"
837  << " itself (" << npfclusters << ")! This should not happen!" << std::endl
838  << sc_err.str() << std::endl;
839  }
840  for (auto ecalitr = ecalbegin; ecalitr != ecalfirstnotinsc; ++ecalitr) {
841  const PFClusterElement* elemascluster = docast(const PFClusterElement*, ecalitr->get());
842 
843  // reject clusters that really shouldn't be associated to the SC
844  // (only needed when using non-pf-supercluster)
845  if (!is_pf_sc && std::find(safePFClusters.begin(), safePFClusters.end(), elemascluster) == safePFClusters.end())
846  continue;
847 
848  //add cluster
849  ecalclusters.emplace_back(elemascluster, true);
850  //mark cluster as used
851  ecalitr->setFlag(false);
852 
853  // process the ES elements
854  // auto is a pair<Iterator,bool> here, bool is false when placing fails
855  auto emplaceresult = ecal2ps.emplace(elemascluster, ClusterMap::mapped_type());
856  if (!emplaceresult.second) {
857  std::stringstream clus_err;
858  elemascluster->Dump(clus_err, "\t");
859  throw cms::Exception("PFEGammaAlgo::unwrapSuperCluster()")
860  << "List of pointers to ECAL block elements contains non-unique items!"
861  << " This is very bad!" << std::endl
862  << "cluster ptr = 0x" << std::hex << elemascluster << std::dec << std::endl
863  << clus_err.str() << std::endl;
864  }
865  ClusterMap::mapped_type& eslist = emplaceresult.first->second;
866  npfpsclusters += attachPSClusters(elemascluster, eslist);
867  } // loop over ecal elements
868 
869  for (auto hgcalitr = hgcalbegin; hgcalitr != hgcalfirstnotinsc; ++hgcalitr) {
870  const PFClusterElement* elemascluster = docast(const PFClusterElement*, hgcalitr->get());
871 
872  // reject clusters that really shouldn't be associated to the SC
873  // (only needed when using non-pf-supercluster)
874  if (!is_pf_sc && std::find(safePFClusters.begin(), safePFClusters.end(), elemascluster) == safePFClusters.end())
875  continue;
876 
877  //add cluster
878  ecalclusters.emplace_back(elemascluster, true);
879  //mark cluster as used
880  hgcalitr->setFlag(false);
881  } // loop over ecal elements
882 
883  /*
884  if( is_pf_sc && nscpsclusters != npfpsclusters) {
885  std::stringstream sc_err;
886  thesc->Dump(sc_err,"\t");
887  throw cms::Exception("PFEGammaAlgo::unwrapSuperCluster()")
888  << "The number of found PF preshower elements ("
889  << npfpsclusters << ") in block is not the same as"
890  << " the number of preshower clusters reported by the PFSuperCluster"
891  << " itself (" << nscpsclusters << ")! This should not happen!"
892  << std::endl
893  << sc_err.str() << std::endl;
894  }
895  */
896 
897  LOGDRESSED("PFEGammaAlgo") << " Unwrapped SC has " << npfclusters << " ECAL sub-clusters"
898  << " and " << npfpsclusters << " PreShower layers 1 & 2 clusters!" << std::endl;
899  return true;
900 }
const SuperClusterRef & superClusterRef() const
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
reco::PFBlockRef _currentblock
Definition: PFEGammaAlgo.h:144
#define LOGERR(x)
Definition: PFEGammaAlgo.cc:46
#define LOGVERB(x)
Definition: PFEGammaAlgo.cc:44
#define LOGDRESSED(x)
Definition: PFEGammaAlgo.cc:47
bool isAvailable() const
Definition: Ref.h:537
reco::PFBlockElementCluster PFClusterElement
Definition: PFEGammaAlgo.h:69
#define docast(x, y)
Definition: PFEGammaAlgo.cc:43
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:232
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
Definition: PFEGammaAlgo.h:148
int attachPSClusters(const PFClusterElement *, ClusterMap::mapped_type &)
void Dump(std::ostream &out=std::cout, const char *tab=" ") const override
print the object inside the element

Member Data Documentation

◆ _currentblock

reco::PFBlockRef PFEGammaAlgo::_currentblock
private

◆ _currentlinks

reco::PFBlock::LinkData PFEGammaAlgo::_currentlinks
private

◆ _splayedblock

std::vector<std::vector<FlaggedPtr<const reco::PFBlockElement> > > PFEGammaAlgo::_splayedblock
private

◆ cfg_

PFEGConfigInfo const& PFEGammaAlgo::cfg_
private

◆ channelStatus_

ESChannelStatus const& PFEGammaAlgo::channelStatus_
private

Definition at line 224 of file PFEGammaAlgo.h.

Referenced by buildRefinedSuperCluster().

◆ eetops_

reco::PFCluster::EEtoPSAssociation const& PFEGammaAlgo::eetops_
private

Definition at line 143 of file PFEGammaAlgo.h.

Referenced by attachPSClusters().

◆ gbrForests_

GBRForests const& PFEGammaAlgo::gbrForests_
private

Definition at line 135 of file PFEGammaAlgo.h.

Referenced by calculateEleMVA(), and evaluateSingleLegMVA().

◆ primaryVertex_

reco::Vertex const& PFEGammaAlgo::primaryVertex_
private

◆ thePFEnergyCalibration_

PFEnergyCalibration PFEGammaAlgo::thePFEnergyCalibration_
private

Definition at line 137 of file PFEGammaAlgo.h.

Referenced by buildRefinedSuperCluster(), and PFEGammaAlgo().