Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:24:54

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/GsfElectron.h"
0011 #include "DataFormats/EgammaCandidates/interface/GsfElectronFwd.h"
0012 
0013 #include "DataFormats/PatCandidates/interface/Electron.h"
0014 
0015 #include "DataFormats/PatCandidates/interface/Photon.h"
0016 
0017 #include "DataFormats/Common/interface/ValueMap.h"
0018 #include "FWCore/Framework/interface/ConsumesCollector.h"
0019 
0020 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0021 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0022 
0023 #include "PhysicsTools/IsolationAlgos/interface/IsoDepositVetoFactory.h"
0024 #include "DataFormats/RecoCandidate/interface/IsoDepositVetos.h"
0025 
0026 #include "PhysicsTools/IsolationAlgos/interface/CITKIsolationConeDefinitionBase.h"
0027 #include "DataFormats/Math/interface/deltaR.h"
0028 
0029 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
0030 
0031 #include <unordered_map>
0032 namespace reco {
0033   typedef edm::Ptr<reco::GsfElectron> GsfElectronPtr;
0034 }
0035 
0036 namespace pat {
0037   typedef edm::Ptr<pat::PackedCandidate> PackedCandidatePtr;
0038   typedef edm::Ptr<pat::Electron> patElectronPtr;
0039 }  // namespace pat
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   //
0045   template <class T, class U>
0046   bool isInFootprint(const T& thefootprint, const U& theCandidate) {
0047     for (auto itr = thefootprint.begin(); itr != thefootprint.end(); ++itr) {
0048       if (itr->key() == theCandidate.key())
0049         return true;
0050     }
0051     return false;
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 
0065 }  // namespace
0066 class ElectronPFIsolationWithMapBasedVeto : public citk::IsolationConeDefinitionBase {
0067 public:
0068   ElectronPFIsolationWithMapBasedVeto(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         _particleBasedIsolation(c.getParameter<edm::InputTag>("particleBasedIsolation")) {
0074   }  // particle based isolation map (used for footprint removal)
0075 
0076   ElectronPFIsolationWithMapBasedVeto(const ElectronPFIsolationWithMapBasedVeto&) = delete;
0077   ElectronPFIsolationWithMapBasedVeto& operator=(const ElectronPFIsolationWithMapBasedVeto&) = delete;
0078 
0079   bool isInIsolationCone(const reco::CandidatePtr& photon, const reco::CandidatePtr& other) 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   ~ElectronPFIsolationWithMapBasedVeto() override{};
0097 
0098 private:
0099   const std::string _isolateAgainst, _vertexCollection;
0100   const std::vector<unsigned> _miniAODVertexCodes;
0101   const edm::InputTag _particleBasedIsolation;
0102 };
0103 
0104 DEFINE_EDM_PLUGIN(CITKIsolationConeDefinitionFactory,
0105                   ElectronPFIsolationWithMapBasedVeto,
0106                   "ElectronPFIsolationWithMapBasedVeto");
0107 
0108 //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!!! ***
0109 
0110 bool ElectronPFIsolationWithMapBasedVeto::isInIsolationCone(const reco::CandidatePtr& electron,
0111                                                             const reco::CandidatePtr& pfCandidate) const {
0112   //convert the electron and candidate objects to the corresponding pat or reco objects. What is used depends on what is user running on: miniAOD or AOD
0113   pat::patElectronPtr aspat_electronptr(electron);
0114 
0115   pat::PackedCandidatePtr aspacked(pfCandidate);
0116   reco::PFCandidatePtr aspf(pfCandidate);
0117 
0118   bool inFootprint = false;
0119   bool result = true;
0120   const float deltar2 =
0121       reco::deltaR2(*electron, *pfCandidate);  //calculate deltaR2 distance between PFCandidate and photon
0122 
0123   // dealing here with patObjects: miniAOD case
0124   if (aspacked.get()) {
0125     inFootprint = isInFootprint(aspat_electronptr->associatedPackedPFCandidates(), aspacked);
0126 
0127     //checking if the charged candidates come from the appropriate vertex
0128     if (aspacked->charge() != 0) {
0129       bool is_vertex_allowed = false;
0130       for (const unsigned vtxtype : _miniAODVertexCodes) {
0131         if (vtxtype == aspacked->fromPV()) {
0132           is_vertex_allowed = true;
0133           break;
0134         }
0135       }
0136 
0137       result &= (is_vertex_allowed);
0138     }
0139     //return true if the candidate is inside the cone and not in the footprint
0140     result &= deltar2 < _coneSize2 && (!inFootprint);
0141   }
0142 
0143   // dealing here with recoObjects: AOD case
0144   else if (aspf.get()) {
0145     inFootprint = isInFootprintAlternative((*particleBasedIsolationMap)[electron], pfCandidate);
0146     //return true if the candidate is inside the cone and not in the footprint
0147     result &= deltar2 < _coneSize2 && (!inFootprint);
0148   }
0149 
0150   // throw exception if it is not a patObject or recoObject
0151   else {
0152     throw cms::Exception("InvalidIsolationInput") << "The supplied candidate to be used as isolation "
0153                                                   << "was neither a reco::Photon nor a pat::Photon!";
0154   }
0155 
0156   return result;
0157 }