Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-07 04:37:28

0001 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0002 #include "FWCore/Framework/interface/Frameworkfwd.h"
0003 
0004 #include "FWCore/Framework/interface/Event.h"
0005 #include "FWCore/Framework/interface/EventSetup.h"
0006 
0007 #include "DataFormats/Candidate/interface/Candidate.h"
0008 #include "DataFormats/Candidate/interface/CandidateFwd.h"
0009 
0010 #include "DataFormats/EgammaCandidates/interface/Photon.h"
0011 #include "DataFormats/EgammaCandidates/interface/PhotonFwd.h"
0012 
0013 #include "DataFormats/PatCandidates/interface/Photon.h"
0014 
0015 #include "DataFormats/Common/interface/ValueMap.h"
0016 #include "FWCore/Framework/interface/ConsumesCollector.h"
0017 
0018 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0019 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0020 
0021 #include "PhysicsTools/IsolationAlgos/interface/IsoDepositVetoFactory.h"
0022 #include "DataFormats/RecoCandidate/interface/IsoDepositVetos.h"
0023 
0024 #include "PhysicsTools/IsolationAlgos/interface/CITKIsolationConeDefinitionBase.h"
0025 #include "DataFormats/Math/interface/deltaR.h"
0026 
0027 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
0028 
0029 #include <unordered_map>
0030 
0031 namespace reco {
0032   typedef edm::Ptr<reco::Photon> recoPhotonPtr;
0033 }
0034 
0035 namespace pat {
0036   typedef edm::Ptr<pat::Photon> patPhotonPtr;
0037   typedef edm::Ptr<pat::PackedCandidate> PackedCandidatePtr;
0038 }  // namespace pat
0039 
0040 namespace {
0041   // This template function finds whether theCandidate is in thefootprint
0042   // collection. It is templated to be able to handle both reco and pat
0043   // photons (from AOD and miniAOD, respectively).
0044   template <class T, class U>
0045   bool isInFootprint(const T& thefootprint, const U& theCandidate) {
0046     for (auto itr = thefootprint.begin(); itr != thefootprint.end(); ++itr) {
0047       if (itr->key() == theCandidate.key())
0048         return true;
0049     }
0050     return false;
0051   }
0052 
0053   //This function is needed because pfNoPileUpCandidates have changed keys,
0054   //and thus the solution is to use sourceCandidatePtr(0)
0055   // This function *shouldn't be used for packedCandidate*
0056   template <class T, class U>
0057   bool isInFootprintAlternative(const T& thefootprint, const U& theCandidate) {
0058     for (auto itr = thefootprint.begin(); itr != thefootprint.end(); ++itr) {
0059       if (itr->key() == theCandidate->sourceCandidatePtr(0).key())
0060         return true;
0061     }
0062     return false;
0063   }
0064 }  // namespace
0065 
0066 class PhotonPFIsolationWithMapBasedVeto : public citk::IsolationConeDefinitionBase {
0067 public:
0068   PhotonPFIsolationWithMapBasedVeto(const edm::ParameterSet& c)
0069       : citk::IsolationConeDefinitionBase(c),
0070         _isolateAgainst(c.getParameter<std::string>("isolateAgainst")),  //isolate against either h+, h0 or gamma
0071         _miniAODVertexCodes(c.getParameter<std::vector<unsigned> >(
0072             "miniAODVertexCodes")),  //quality flags to be used for association with the vertex configurable, the vertex can be chosen
0073         _vertexIndex(c.getParameter<int>("vertexIndex")),  //vertex of interest
0074         _particleBasedIsolation(c.getParameter<edm::InputTag>("particleBasedIsolation")) {}
0075 
0076   PhotonPFIsolationWithMapBasedVeto(const PhotonPFIsolationWithMapBasedVeto&) = delete;
0077   PhotonPFIsolationWithMapBasedVeto& operator=(const PhotonPFIsolationWithMapBasedVeto&) = delete;
0078 
0079   bool isInIsolationCone(const reco::CandidatePtr& photon, const reco::CandidatePtr& pfCandidate) const final;
0080 
0081   // this object is needed for reco case
0082   edm::Handle<edm::ValueMap<std::vector<reco::PFCandidateRef> > > particleBasedIsolationMap;
0083   edm::EDGetTokenT<edm::ValueMap<std::vector<reco::PFCandidateRef> > > particleBasedIsolationToken_;
0084 
0085   void getEventInfo(const edm::Event& iEvent) override {
0086     iEvent.getByToken(particleBasedIsolationToken_, particleBasedIsolationMap);
0087   };
0088 
0089   //As far as I understand now, the object particleBasedIsolationMap should be fixed, so we don't configure the name
0090   void setConsumes(edm::ConsumesCollector iC) override {
0091     particleBasedIsolationToken_ =
0092         iC.mayConsume<edm::ValueMap<std::vector<reco::PFCandidateRef> > >(_particleBasedIsolation);
0093   }
0094 
0095   //! Destructor
0096   ~PhotonPFIsolationWithMapBasedVeto() override {}
0097 
0098 private:
0099   const std::string _isolateAgainst, _vertexCollection;
0100   const std::vector<unsigned> _miniAODVertexCodes;
0101   const unsigned _vertexIndex;
0102   const edm::InputTag _particleBasedIsolation;
0103 };
0104 
0105 DEFINE_EDM_PLUGIN(CITKIsolationConeDefinitionFactory,
0106                   PhotonPFIsolationWithMapBasedVeto,
0107                   "PhotonPFIsolationWithMapBasedVeto");
0108 
0109 //This function defines whether particular PFCandidate is inside of isolation cone of photon or not by checking deltaR and whether footprint removal for this candidate should be done. Additionally, for miniAOD charged hadrons from the PV are considered. *** For AOD this should be done by the corresponding sequence beforehand!!! ***
0110 
0111 bool PhotonPFIsolationWithMapBasedVeto::isInIsolationCone(const reco::CandidatePtr& photon,
0112                                                           const reco::CandidatePtr& pfCandidate) const {
0113   //convert the photon and candidate objects to the corresponding pat or reco objects. What is used depends on what is user running on: miniAOD or AOD
0114   pat::patPhotonPtr aspat_photonptr(photon);
0115 
0116   pat::PackedCandidatePtr aspacked(pfCandidate);
0117   reco::PFCandidatePtr aspf(pfCandidate);
0118 
0119   bool inFootprint = false;
0120   bool result = true;
0121   const float deltar2 =
0122       reco::deltaR2(*photon, *pfCandidate);  //calculate deltaR2 distance between PFCandidate and photon
0123 
0124   // dealing here with patObjects: miniAOD case
0125   if (aspacked.get()) {
0126     inFootprint = isInFootprint(aspat_photonptr->associatedPackedPFCandidates(), aspacked);
0127 
0128     //checking if the charged candidates come from the appropriate vertex
0129     if (aspacked->charge() != 0) {
0130       bool is_vertex_allowed = false;
0131       for (const unsigned vtxtype : _miniAODVertexCodes) {
0132         if (vtxtype == aspacked->fromPV(_vertexIndex)) {
0133           is_vertex_allowed = true;
0134           break;
0135         }
0136       }
0137 
0138       result &= (is_vertex_allowed);
0139     }
0140     //return true if the candidate is inside the cone and not in the footprint
0141     result &= deltar2 < _coneSize2 && (!inFootprint);
0142 
0143   }
0144 
0145   // dealing here with recoObjects: AOD case
0146   else if (aspf.get() && aspf.isNonnull()) {
0147     inFootprint = isInFootprintAlternative((*particleBasedIsolationMap)[photon], aspf);
0148     result &= deltar2 < _coneSize2 && (!inFootprint);
0149 
0150   }
0151 
0152   // throw exception if it is not a patObject or recoObject
0153   else {
0154     throw cms::Exception("InvalidIsolationInput") << "The supplied candidate to be used as isolation "
0155                                                   << "was neither a reco::Photon nor a pat::Photon!";
0156   }
0157 
0158   return result;
0159 }