Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "FWCore/Framework/interface/ModuleFactory.h"
0002 #include "FWCore/Framework/interface/MakerMacros.h"
0003 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
0004 #include "DataFormats/EgammaCandidates/interface/GsfElectronFwd.h"
0005 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
0006 #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
0007 #include "DataFormats/Math/interface/deltaR.h"
0008 #include "DataFormats/Math/interface/Vector3D.h"
0009 #include "DataFormats/Math/interface/Point3D.h"
0010 #include "FWCore/Utilities/interface/EDMException.h"
0011 #include "FWCore/Framework/interface/Frameworkfwd.h"
0012 #include "DataFormats/JetReco/interface/PFJetCollection.h"
0013 #include "DataFormats/JetReco/interface/Jet.h"
0014 #include "DataFormats/PatCandidates/interface/Jet.h"
0015 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0016 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
0017 #include "DataFormats/BTauReco/interface/SoftLeptonTagInfo.h"
0018 
0019 #include "FWCore/Framework/interface/global/EDProducer.h"
0020 #include "FWCore/Framework/interface/Event.h"
0021 #include "FWCore/Framework/interface/EventSetup.h"
0022 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0023 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
0024 #include "DataFormats/Common/interface/ValueMap.h"
0025 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0026 #include "DataFormats/JetReco/interface/PFJetCollection.h"
0027 
0028 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
0029 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
0030 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
0031 
0032 // Vertex
0033 #include "DataFormats/VertexReco/interface/Vertex.h"
0034 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0035 #include "DataFormats/BTauReco/interface/SoftLeptonTagInfo.h"
0036 #include "DataFormats/PatCandidates/interface/Electron.h"
0037 
0038 // Transient Track and IP
0039 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
0040 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
0041 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
0042 #include "TrackingTools/IPTools/interface/IPTools.h"
0043 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
0044 #include "CommonTools/Egamma/interface/ConversionTools.h"
0045 #include "DataFormats/PatCandidates/interface/Electron.h"
0046 
0047 #include <cmath>
0048 #include <vector>
0049 
0050 // SoftPFElectronTagInfoProducer:  the SoftPFElectronTagInfoProducer takes
0051 // a PFCandidateCollection as input and produces a RefVector
0052 // to the likely soft electrons in this collection.
0053 
0054 class SoftPFElectronTagInfoProducer : public edm::global::EDProducer<> {
0055 public:
0056   SoftPFElectronTagInfoProducer(const edm::ParameterSet& conf);
0057 
0058   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0059 
0060 private:
0061   void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const final;
0062   static bool isElecClean(edm::Event&, const reco::GsfElectron*);
0063   static float boostedPPar(const math::XYZVector&, const math::XYZVector&);
0064 
0065   // service used to make transient tracks from tracks
0066   const edm::EDGetTokenT<reco::VertexCollection> token_primaryVertex;
0067   const edm::EDGetTokenT<edm::View<reco::Jet> > token_jets;
0068   const edm::EDGetTokenT<edm::View<reco::GsfElectron> > token_elec;
0069   const edm::EDGetTokenT<reco::BeamSpot> token_BeamSpot;
0070   const edm::EDGetTokenT<reco::ConversionCollection> token_allConversions;
0071   const edm::ESGetToken<TransientTrackBuilder, TransientTrackRecord> token_builder;
0072   const edm::EDPutTokenT<reco::CandSoftLeptonTagInfoCollection> token_put;
0073   const float DeltaRElectronJet, MaxSip3Dsig;
0074 };
0075 
0076 SoftPFElectronTagInfoProducer::SoftPFElectronTagInfoProducer(const edm::ParameterSet& conf)
0077     : token_primaryVertex(consumes(conf.getParameter<edm::InputTag>("primaryVertex"))),
0078       token_jets(consumes(conf.getParameter<edm::InputTag>("jets"))),
0079       token_elec(consumes(conf.getParameter<edm::InputTag>("electrons"))),
0080       token_BeamSpot(consumes(edm::InputTag("offlineBeamSpot"))),
0081       token_allConversions(consumes(edm::InputTag("allConversions"))),
0082       token_builder(esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))),
0083       token_put(produces()),
0084       DeltaRElectronJet(conf.getParameter<double>("DeltaRElectronJet")),
0085       MaxSip3Dsig(conf.getParameter<double>("MaxSip3Dsig")) {}
0086 
0087 void SoftPFElectronTagInfoProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0088   edm::ParameterSetDescription desc;
0089   desc.add<edm::InputTag>("primaryVertex");
0090   desc.add<edm::InputTag>("jets");
0091   desc.add<edm::InputTag>("electrons");
0092   desc.add<double>("DeltaRElectronJet");
0093   desc.add<double>("MaxSip3Dsig");
0094   descriptions.addDefault(desc);
0095 }
0096 
0097 void SoftPFElectronTagInfoProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const {
0098   reco::CandSoftLeptonTagInfoCollection theElecTagInfo;
0099   const auto& transientTrackBuilder = iSetup.getData(token_builder);
0100 
0101   edm::Handle<reco::VertexCollection> PVCollection = iEvent.getHandle(token_primaryVertex);
0102   if (!PVCollection.isValid()) {
0103     iEvent.emplace(token_put, std::move(theElecTagInfo));
0104     return;
0105   }
0106   reco::ConversionCollection const& hConversions = iEvent.get(token_allConversions);
0107 
0108   edm::View<reco::Jet> const& theJetCollection = iEvent.get(token_jets);
0109 
0110   edm::View<reco::GsfElectron> const& theGEDGsfElectronCollection = iEvent.get(token_elec);
0111 
0112   if (PVCollection->empty() and not theJetCollection.empty() and not theGEDGsfElectronCollection.empty()) {
0113     //we would need to access a vertex from the collection but there isn't one.
0114     iEvent.emplace(token_put, std::move(theElecTagInfo));
0115     return;
0116   }
0117 
0118   const reco::BeamSpot& beamspot = iEvent.get(token_BeamSpot);
0119 
0120   for (unsigned int i = 0; i < theJetCollection.size(); i++) {
0121     edm::RefToBase<reco::Jet> jetRef = theJetCollection.refAt(i);
0122     reco::CandSoftLeptonTagInfo tagInfo;
0123     tagInfo.setJetRef(jetRef);
0124     for (unsigned int ie = 0, ne = theGEDGsfElectronCollection.size(); ie < ne; ++ie) {
0125       //Get the edm::Ptr and the GsfElectron
0126       edm::Ptr<reco::Candidate> lepPtr = theGEDGsfElectronCollection.ptrAt(ie);
0127       const reco::GsfElectron* recoelectron = theGEDGsfElectronCollection.refAt(ie).get();
0128       const pat::Electron* patelec = dynamic_cast<const pat::Electron*>(recoelectron);
0129       if (patelec) {
0130         if (!patelec->passConversionVeto())
0131           continue;
0132       } else {
0133         if (ConversionTools::hasMatchedConversion(*(recoelectron), hConversions, beamspot.position()))
0134           continue;
0135       }
0136       //Make sure that the electron is inside the jet
0137       if (reco::deltaR2((*recoelectron), (*jetRef)) > DeltaRElectronJet * DeltaRElectronJet)
0138         continue;
0139       // Need a gsfTrack
0140       if (recoelectron->gsfTrack().get() == nullptr)
0141         continue;
0142       reco::SoftLeptonProperties properties;
0143       // reject if it has issues with the track
0144       if (!isElecClean(iEvent, recoelectron))
0145         continue;
0146       //Compute the TagInfos members
0147       math::XYZVector pel = recoelectron->p4().Vect();
0148       math::XYZVector pjet = jetRef->p4().Vect();
0149       reco::TransientTrack transientTrack = transientTrackBuilder.build(recoelectron->gsfTrack());
0150       auto const& vertex = PVCollection->front();
0151       Measurement1D ip2d = IPTools::signedTransverseImpactParameter(
0152                                transientTrack, GlobalVector(jetRef->px(), jetRef->py(), jetRef->pz()), vertex)
0153                                .second;
0154       Measurement1D ip3d = IPTools::signedImpactParameter3D(
0155                                transientTrack, GlobalVector(jetRef->px(), jetRef->py(), jetRef->pz()), vertex)
0156                                .second;
0157       properties.sip2dsig = ip2d.significance();
0158       properties.sip3dsig = ip3d.significance();
0159       properties.sip2d = ip2d.value();
0160       properties.sip3d = ip3d.value();
0161       properties.deltaR = reco::deltaR((*jetRef), (*recoelectron));
0162       properties.ptRel = ((pjet - pel).Cross(pel)).R() / pjet.R();
0163       float mag = pel.R() * pjet.R();
0164       float dot = recoelectron->p4().Dot(jetRef->p4());
0165       properties.etaRel = -log((mag - dot) / (mag + dot)) / 2.;
0166       properties.ratio = recoelectron->pt() / jetRef->pt();
0167       properties.ratioRel = recoelectron->p4().Dot(jetRef->p4()) / pjet.Mag2();
0168       properties.p0Par = boostedPPar(recoelectron->momentum(), jetRef->momentum());
0169       properties.elec_mva = recoelectron->mva_e_pi();
0170       properties.charge = recoelectron->charge();
0171       if (std::abs(properties.sip3dsig) > MaxSip3Dsig)
0172         continue;
0173       // Fill the TagInfos
0174       tagInfo.insert(lepPtr, properties);
0175     }
0176     theElecTagInfo.push_back(tagInfo);
0177   }
0178   iEvent.emplace(token_put, std::move(theElecTagInfo));
0179 }
0180 
0181 bool SoftPFElectronTagInfoProducer::isElecClean(edm::Event& iEvent, const reco::GsfElectron* candidate) {
0182   using namespace reco;
0183   const HitPattern& hitPattern = candidate->gsfTrack().get()->hitPattern();
0184   uint32_t hit = hitPattern.getHitPattern(HitPattern::TRACK_HITS, 0);
0185   bool hitCondition =
0186       !(HitPattern::validHitFilter(hit) && ((HitPattern::pixelBarrelHitFilter(hit) && HitPattern::getLayer(hit) < 3) ||
0187                                             HitPattern::pixelEndcapHitFilter(hit)));
0188   if (hitCondition)
0189     return false;
0190 
0191   return true;
0192 }
0193 
0194 float SoftPFElectronTagInfoProducer::boostedPPar(const math::XYZVector& vector, const math::XYZVector& axis) {
0195   static const double lepton_mass = 0.00;
0196   static const double jet_mass = 5.279;
0197   ROOT::Math::LorentzVector<ROOT::Math::PxPyPzM4D<double> > lepton(
0198       vector.Dot(axis) / axis.r(), ROOT::Math::VectorUtil::Perp(vector, axis), 0., lepton_mass);
0199   ROOT::Math::LorentzVector<ROOT::Math::PxPyPzM4D<double> > jet(axis.r(), 0., 0., jet_mass);
0200   ROOT::Math::BoostX boost(-jet.Beta());
0201   return boost(lepton).x();
0202 }
0203 
0204 DEFINE_FWK_MODULE(SoftPFElectronTagInfoProducer);