File indexing completed on 2024-04-06 12:13:39
0001 #include "GeneratorInterface/GenFilters/plugins/EMEnrichingFilterAlgo.h"
0002 #include "DataFormats/Common/interface/Handle.h"
0003 #include "DataFormats/Math/interface/deltaR.h"
0004 #include "DataFormats/Math/interface/deltaPhi.h"
0005 #include "FWCore/Framework/interface/ConsumesCollector.h"
0006 #include "FWCore/Framework/interface/Event.h"
0007 #include "FWCore/Framework/interface/EventSetup.h"
0008 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0009 #include "FWCore/Utilities/interface/InputTag.h"
0010
0011 #include "DataFormats/GeometrySurface/interface/Cylinder.h"
0012 #include "DataFormats/GeometrySurface/interface/Plane.h"
0013 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
0014 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
0015
0016 #include "TrackingTools/GeomPropagators/interface/AnalyticalPropagator.h"
0017 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
0018 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
0019
0020 #include <cmath>
0021 #include <cstdint>
0022 #include <cstdlib>
0023
0024 using namespace edm;
0025 using namespace std;
0026
0027 EMEnrichingFilterAlgo::EMEnrichingFilterAlgo(const edm::ParameterSet &iConfig, edm::ConsumesCollector &&iConsumes)
0028
0029 : FILTER_TKISOCUT_(4),
0030 FILTER_CALOISOCUT_(7),
0031 FILTER_ETA_MIN_(0),
0032 FILTER_ETA_MAX_(2.4),
0033 ECALBARRELMAXETA_(1.479),
0034 ECALBARRELRADIUS_(129.0),
0035 ECALENDCAPZ_(304.5),
0036 isoGenParETMin_((float)iConfig.getParameter<double>("isoGenParETMin")),
0037 isoGenParConeSize_((float)iConfig.getParameter<double>("isoGenParConeSize")),
0038 clusterThreshold_((float)iConfig.getParameter<double>("clusterThreshold")),
0039 isoConeSize_((float)iConfig.getParameter<double>("isoConeSize")),
0040 hOverEMax_((float)iConfig.getParameter<double>("hOverEMax")),
0041 tkIsoMax_((float)iConfig.getParameter<double>("tkIsoMax")),
0042 caloIsoMax_((float)iConfig.getParameter<double>("caloIsoMax")),
0043 requireTrackMatch_(iConfig.getParameter<bool>("requireTrackMatch")),
0044 genParSourceToken_(
0045 iConsumes.consumes<reco::GenParticleCollection>(iConfig.getParameter<edm::InputTag>("genParSource"))),
0046 magneticFieldToken_(iConsumes.esConsumes<MagneticField, IdealMagneticFieldRecord>()) {}
0047
0048 bool EMEnrichingFilterAlgo::filter(const edm::Event &iEvent, const edm::EventSetup &iSetup) const {
0049 Handle<reco::GenParticleCollection> genParsHandle;
0050 iEvent.getByToken(genParSourceToken_, genParsHandle);
0051 reco::GenParticleCollection genPars = *genParsHandle;
0052
0053
0054 std::vector<reco::GenParticle> genParsCurved = applyBFieldCurv(genPars, iSetup);
0055
0056 bool result1 = filterPhotonElectronSeed(
0057 clusterThreshold_, isoConeSize_, hOverEMax_, tkIsoMax_, caloIsoMax_, requireTrackMatch_, genPars, genParsCurved);
0058
0059 bool result2 = filterIsoGenPar(isoGenParETMin_, isoGenParConeSize_, genPars, genParsCurved);
0060
0061 bool result = result1 || result2;
0062
0063 return result;
0064 }
0065
0066
0067
0068
0069
0070
0071 bool EMEnrichingFilterAlgo::filterPhotonElectronSeed(float clusterthreshold,
0072 float isoConeSize,
0073 float hOverEMax,
0074 float tkIsoMax,
0075 float caloIsoMax,
0076 bool requiretrackmatch,
0077 const std::vector<reco::GenParticle> &genPars,
0078 const std::vector<reco::GenParticle> &genParsCurved) const {
0079 float seedthreshold = 5;
0080 float conesizeendcap = 15;
0081
0082 bool retval = false;
0083
0084 vector<reco::GenParticle> seeds;
0085
0086 for (uint32_t is = 0; is < genParsCurved.size(); is++) {
0087 const reco::GenParticle &gp = genParsCurved.at(is);
0088 if (gp.status() != 1 || fabs(gp.eta()) > FILTER_ETA_MAX_ || fabs(gp.eta()) < FILTER_ETA_MIN_)
0089 continue;
0090 int absid = abs(gp.pdgId());
0091 if (absid != 11 && absid != 22)
0092 continue;
0093 if (gp.et() > seedthreshold)
0094 seeds.push_back(gp);
0095 }
0096
0097 bool matchtrack = false;
0098
0099
0100 for (uint32_t is = 0; is < seeds.size(); is++) {
0101 float eTInCone = 0;
0102 float tkIsoET = 0;
0103 float caloIsoET = 0;
0104 float hadET =
0105 0;
0106 bool isBarrel = fabs(seeds.at(is).eta()) < ECALBARRELMAXETA_;
0107 for (uint32_t ig = 0; ig < genParsCurved.size(); ig++) {
0108 const reco::GenParticle &gp = genParsCurved.at(ig);
0109 const reco::GenParticle &gpUnCurv = genPars.at(ig);
0110 if (gp.status() != 1)
0111 continue;
0112 int gpabsid = abs(gp.pdgId());
0113 if (gp.et() < 1)
0114 continue;
0115
0116 if (isBarrel) {
0117 float dr = deltaR(seeds.at(is), gp);
0118 float dphi = deltaPhi(seeds.at(is).phi(), gp.phi());
0119 float deta = fabs(seeds.at(is).eta() - gp.eta());
0120 if (deta < 0.03 && dphi < 0.2) {
0121 if (gpabsid == 22 || gpabsid == 11 || gpabsid == 211 || gpabsid == 321) {
0122
0123 eTInCone += gp.et();
0124
0125 if ((gpabsid == 11 || gpabsid == 211 || gpabsid == 321) && gp.et() > 5)
0126 matchtrack = true;
0127 } else {
0128
0129 hadET += gp.et();
0130 }
0131 } else {
0132 float drUnCurv = deltaR(seeds.at(is), gpUnCurv);
0133 if ((gp.charge() == 0 && dr < isoConeSize && gpabsid != 22) || (gp.charge() != 0 && drUnCurv < isoConeSize)) {
0134
0135 caloIsoET += gp.et();
0136 }
0137 if (gp.charge() != 0 && drUnCurv < isoConeSize) {
0138
0139 tkIsoET += gp.et();
0140 }
0141 }
0142
0143 } else {
0144 float drxy = deltaRxyAtEE(seeds.at(is), gp);
0145 float dr = deltaR(seeds.at(is), gp);
0146 if (drxy < conesizeendcap) {
0147 if (gpabsid == 22 || gpabsid == 11 || gpabsid == 211 || gpabsid == 321) {
0148
0149 eTInCone += gp.et();
0150
0151 if ((gpabsid == 11 || gpabsid == 211 || gpabsid == 321) && gp.et() > 5)
0152 matchtrack = true;
0153 } else {
0154
0155 hadET += gp.et();
0156 }
0157 } else {
0158 float drUnCurv = deltaR(seeds.at(is), gpUnCurv);
0159 if ((gp.charge() == 0 && dr < isoConeSize && gpabsid != 22) || (gp.charge() != 0 && drUnCurv < isoConeSize)) {
0160
0161 caloIsoET += gp.et();
0162 }
0163 if (gp.charge() != 0 && drUnCurv < isoConeSize) {
0164
0165 tkIsoET += gp.et();
0166 }
0167 }
0168 }
0169 }
0170
0171 if (eTInCone > clusterthreshold && (!requiretrackmatch || matchtrack)) {
0172
0173 if (hadET / eTInCone < hOverEMax && tkIsoET < tkIsoMax && caloIsoET < caloIsoMax)
0174 retval = true;
0175 break;
0176 }
0177 }
0178
0179 return retval;
0180 }
0181
0182
0183
0184 std::vector<reco::GenParticle> EMEnrichingFilterAlgo::applyBFieldCurv(const std::vector<reco::GenParticle> &genPars,
0185 const edm::EventSetup &iSetup) const {
0186 vector<reco::GenParticle> curvedPars;
0187
0188 MagneticField const *magField = &iSetup.getData(magneticFieldToken_);
0189
0190 Cylinder::CylinderPointer theBarrel =
0191 Cylinder::build(Surface::PositionType(0, 0, 0), Surface::RotationType(), ECALBARRELRADIUS_);
0192 Plane::PlanePointer endCapPlus = Plane::build(Surface::PositionType(0, 0, ECALENDCAPZ_), Surface::RotationType());
0193 Plane::PlanePointer endCapMinus =
0194 Plane::build(Surface::PositionType(0, 0, -1 * ECALENDCAPZ_), Surface::RotationType());
0195
0196 AnalyticalPropagator propagator(magField, alongMomentum);
0197
0198 for (uint32_t ig = 0; ig < genPars.size(); ig++) {
0199 const reco::GenParticle &gp = genPars.at(ig);
0200
0201
0202
0203 if (gp.charge() == 0 || gp.status() != 1 || gp.et() < 1) {
0204 curvedPars.push_back(gp);
0205 continue;
0206 }
0207 GlobalPoint vertex(gp.vx(), gp.vy(), gp.vz());
0208 GlobalVector gvect(gp.px(), gp.py(), gp.pz());
0209 FreeTrajectoryState fts(vertex, gvect, gp.charge(), magField);
0210 TrajectoryStateOnSurface impact;
0211
0212 if (fabs(gp.eta()) < ECALBARRELMAXETA_) {
0213 impact = propagator.propagate(fts, *theBarrel);
0214 } else if (gp.eta() > 0) {
0215 impact = propagator.propagate(fts, *endCapPlus);
0216 } else {
0217 impact = propagator.propagate(fts, *endCapMinus);
0218 }
0219
0220
0221 if (!impact.isValid()) {
0222 curvedPars.push_back(gp);
0223 continue;
0224 }
0225 math::XYZTLorentzVector newp4;
0226
0227
0228
0229
0230 float et = gp.et();
0231 float phinew = impact.globalPosition().phi();
0232 float pxnew = et * cos(phinew);
0233 float pynew = et * sin(phinew);
0234 newp4.SetPx(pxnew);
0235 newp4.SetPy(pynew);
0236 newp4.SetPz(gp.pz());
0237 newp4.SetE(gp.energy());
0238 reco::GenParticle gpnew = gp;
0239 gpnew.setP4(newp4);
0240 curvedPars.push_back(gpnew);
0241 }
0242 return curvedPars;
0243 }
0244
0245
0246
0247 float EMEnrichingFilterAlgo::deltaRxyAtEE(const reco::GenParticle &gp1, const reco::GenParticle &gp2) const {
0248 if (gp1.pz() * gp2.pz() < 0)
0249 return 9999.;
0250
0251 float rxy1 = ECALENDCAPZ_ * tan(gp1.theta());
0252 float x1 = cos(gp1.phi()) * rxy1;
0253 float y1 = sin(gp1.phi()) * rxy1;
0254
0255 float rxy2 = ECALENDCAPZ_ * tan(gp2.theta());
0256 float x2 = cos(gp2.phi()) * rxy2;
0257 float y2 = sin(gp2.phi()) * rxy2;
0258
0259 float dxy = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
0260 return dxy;
0261 }
0262
0263
0264
0265
0266
0267
0268
0269 bool EMEnrichingFilterAlgo::filterIsoGenPar(float etmin,
0270 float conesize,
0271 const reco::GenParticleCollection &gph,
0272 const reco::GenParticleCollection &gphCurved) const {
0273 for (uint32_t ip = 0; ip < gph.size(); ip++) {
0274 const reco::GenParticle &gp = gph.at(ip);
0275 const reco::GenParticle &gpCurved = gphCurved.at(ip);
0276 int gpabsid = abs(gp.pdgId());
0277
0278 if (gp.et() <= etmin || gp.status() != 1)
0279 continue;
0280 if (gpabsid != 11 && gpabsid != 211 && gpabsid != 321)
0281 continue;
0282 if (fabs(gp.eta()) < FILTER_ETA_MIN_)
0283 continue;
0284 if (fabs(gp.eta()) > FILTER_ETA_MAX_)
0285 continue;
0286
0287
0288 float tkiso = 0;
0289 float caloiso = 0;
0290 for (uint32_t jp = 0; jp < gph.size(); jp++) {
0291 if (jp == ip)
0292 continue;
0293 const reco::GenParticle &pp = gph.at(jp);
0294 const reco::GenParticle &ppCurved = gphCurved.at(jp);
0295 if (pp.status() != 1)
0296 continue;
0297 float dr = deltaR(gp, pp);
0298 float drCurved = deltaR(gpCurved, ppCurved);
0299 if (abs(pp.charge()) == 1 && pp.et() > 2 && dr < conesize) {
0300 tkiso += pp.et();
0301 }
0302 if (pp.et() > 2 && abs(pp.pdgId()) != 22 && drCurved < conesize) {
0303 caloiso += pp.energy();
0304 }
0305 }
0306 if (tkiso < FILTER_TKISOCUT_ && caloiso < FILTER_CALOISOCUT_)
0307 return true;
0308 }
0309 return false;
0310 }