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
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
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
0051
0052
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
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
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
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
0137 if (reco::deltaR2((*recoelectron), (*jetRef)) > DeltaRElectronJet * DeltaRElectronJet)
0138 continue;
0139
0140 if (recoelectron->gsfTrack().get() == nullptr)
0141 continue;
0142 reco::SoftLeptonProperties properties;
0143
0144 if (!isElecClean(iEvent, recoelectron))
0145 continue;
0146
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
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);