00001 #include "GeneratorInterface/GenFilters/interface/EMEnrichingFilterAlgo.h"
00002
00003 #include "FWCore/Framework/interface/ESHandle.h"
00004
00005 #include "DataFormats/Math/interface/deltaR.h"
00006 #include "DataFormats/Math/interface/deltaPhi.h"
00007 #include "DataFormats/GeometrySurface/interface/Cylinder.h"
00008 #include "DataFormats/GeometrySurface/interface/Plane.h"
00009 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00010 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
00011
00012 #include "MagneticField/Engine/interface/MagneticField.h"
00013 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00014
00015 #include "TrackingTools/GeomPropagators/interface/AnalyticalPropagator.h"
00016 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00017 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00018
00019 #include "CLHEP/Vector/LorentzVector.h"
00020
00021
00022 using namespace edm;
00023 using namespace std;
00024
00025
00026 EMEnrichingFilterAlgo::EMEnrichingFilterAlgo(const edm::ParameterSet& iConfig) {
00027
00028
00029 FILTER_TKISOCUT_=4;
00030 FILTER_CALOISOCUT_=7;
00031 FILTER_ETA_MIN_=0;
00032 FILTER_ETA_MAX_=2.4;
00033 ECALBARRELMAXETA_=1.479;
00034 ECALBARRELRADIUS_=129.0;
00035 ECALENDCAPZ_=304.5;
00036
00037
00038
00039 isoGenParETMin_=(float) iConfig.getParameter<double>("isoGenParETMin");
00040 isoGenParConeSize_=(float) iConfig.getParameter<double>("isoGenParConeSize");
00041 clusterThreshold_=(float) iConfig.getParameter<double>("clusterThreshold");
00042 isoConeSize_=(float) iConfig.getParameter<double>("isoConeSize");
00043 hOverEMax_=(float) iConfig.getParameter<double>("hOverEMax");
00044 tkIsoMax_=(float) iConfig.getParameter<double>("tkIsoMax");
00045 caloIsoMax_=(float) iConfig.getParameter<double>("caloIsoMax");
00046 requireTrackMatch_=iConfig.getParameter<bool>("requireTrackMatch");
00047 genParSource_=iConfig.getParameter<edm::InputTag>("genParSource");
00048
00049 }
00050
00051 EMEnrichingFilterAlgo::~EMEnrichingFilterAlgo() {
00052 }
00053
00054
00055 bool EMEnrichingFilterAlgo::filter(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
00056
00057
00058 Handle<reco::GenParticleCollection> genParsHandle;
00059 iEvent.getByLabel(genParSource_,genParsHandle);
00060 reco::GenParticleCollection genPars=*genParsHandle;
00061
00062
00063 std::vector<reco::GenParticle> genParsCurved=applyBFieldCurv(genPars,iSetup);
00064
00065 bool result1=filterPhotonElectronSeed(clusterThreshold_,
00066 isoConeSize_,
00067 hOverEMax_,
00068 tkIsoMax_,
00069 caloIsoMax_,
00070 requireTrackMatch_,
00071 genPars,
00072 genParsCurved);
00073
00074 bool result2=filterIsoGenPar(isoGenParETMin_,isoGenParConeSize_,genPars,genParsCurved);
00075
00076
00077 bool result=result1 || result2;
00078
00079 return result;
00080
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 bool EMEnrichingFilterAlgo::filterPhotonElectronSeed(float clusterthreshold,
00092 float isoConeSize,
00093 float hOverEMax,
00094 float tkIsoMax,
00095 float caloIsoMax,
00096 bool requiretrackmatch,
00097 const std::vector<reco::GenParticle> &genPars,
00098 const std::vector<reco::GenParticle> &genParsCurved) {
00099
00100 float seedthreshold=5;
00101 float conesizeendcap=15;
00102
00103 bool retval=false;
00104
00105 vector<reco::GenParticle> seeds;
00106
00107 for (uint32_t is=0;is<genParsCurved.size();is++) {
00108 reco::GenParticle gp=genParsCurved.at(is);
00109 if (gp.status()!=1 || fabs(gp.eta()) > FILTER_ETA_MAX_ || fabs(gp.eta()) < FILTER_ETA_MIN_) continue;
00110 int absid=abs(gp.pdgId());
00111 if (absid!=11 && absid!=22) continue;
00112 if (gp.et()>seedthreshold) seeds.push_back(gp);
00113 }
00114
00115 bool matchtrack=false;
00116
00117
00118 for (uint32_t is=0;is<seeds.size();is++) {
00119 float eTInCone=0;
00120 float tkIsoET=0;
00121 float caloIsoET=0;
00122 float hadET=0;
00123 bool isBarrel=fabs(seeds.at(is).eta())<ECALBARRELMAXETA_;
00124 for (uint32_t ig=0;ig<genParsCurved.size();ig++) {
00125 reco::GenParticle gp=genParsCurved.at(ig);
00126 reco::GenParticle gpUnCurv=genPars.at(ig);
00127 if (gp.status()!=1) continue;
00128 int gpabsid=abs(gp.pdgId());
00129 if (gp.et()<1) continue;
00130
00131 if (isBarrel) {
00132 float dr=deltaR(seeds.at(is),gp);
00133 float dphi=deltaPhi(seeds.at(is).phi(),gp.phi());
00134 float deta=fabs(seeds.at(is).eta()-gp.eta());
00135 if (deta<0.03 && dphi<0.2) {
00136 if (gpabsid==22 || gpabsid==11 || gpabsid==211 || gpabsid==321) {
00137
00138 eTInCone+=gp.et();
00139
00140 if ((gpabsid==11 || gpabsid==211 || gpabsid==321) && gp.et()>5) matchtrack=true;
00141 } else {
00142
00143 hadET+=gp.et();
00144 }
00145 } else {
00146 float drUnCurv=deltaR(seeds.at(is),gpUnCurv);
00147 if ((gp.charge()==0 && dr<isoConeSize && gpabsid!=22) ||
00148 (gp.charge()!=0 && drUnCurv<isoConeSize)) {
00149
00150 caloIsoET+=gp.et();
00151 }
00152 if (gp.charge()!=0 && drUnCurv<isoConeSize) {
00153
00154 tkIsoET+=gp.et();
00155 }
00156 }
00157
00158 } else {
00159 float drxy=deltaRxyAtEE(seeds.at(is),gp);
00160 float dr=deltaR(seeds.at(is),gp);
00161 if (drxy<conesizeendcap) {
00162 if (gpabsid==22 || gpabsid==11 || gpabsid==211 || gpabsid==321) {
00163
00164 eTInCone+=gp.et();
00165
00166 if ((gpabsid==11 || gpabsid==211 || gpabsid==321) && gp.et()>5) matchtrack=true;
00167 } else {
00168
00169 hadET+=gp.et();
00170 }
00171 } else {
00172 float drUnCurv=deltaR(seeds.at(is),gpUnCurv);
00173 if ((gp.charge()==0 && dr<isoConeSize && gpabsid!=22) ||
00174 (gp.charge()!=0 && drUnCurv<isoConeSize)) {
00175
00176 caloIsoET+=gp.et();
00177 }
00178 if (gp.charge()!=0 && drUnCurv<isoConeSize) {
00179
00180 tkIsoET+=gp.et();
00181 }
00182 }
00183 }
00184 }
00185
00186 if (eTInCone>clusterthreshold && (!requiretrackmatch || matchtrack)) {
00187
00188 if (hadET/eTInCone<hOverEMax && tkIsoET<tkIsoMax && caloIsoET<caloIsoMax) retval=true;
00189 break;
00190 }
00191 }
00192
00193 return retval;
00194 }
00195
00196
00197
00198
00199
00200
00201 std::vector<reco::GenParticle> EMEnrichingFilterAlgo::applyBFieldCurv(const std::vector<reco::GenParticle> &genPars, const edm::EventSetup& iSetup) {
00202
00203
00204 vector<reco::GenParticle> curvedPars;
00205
00206 edm::ESHandle<MagneticField> magField;
00207 iSetup.get<IdealMagneticFieldRecord>().get(magField);
00208
00209 Cylinder::CylinderPointer theBarrel=Cylinder::build(Surface::PositionType(0,0,0),Surface::RotationType(),ECALBARRELRADIUS_);
00210 Plane::PlanePointer endCapPlus=Plane::build(Surface::PositionType(0,0,ECALENDCAPZ_),Surface::RotationType());
00211 Plane::PlanePointer endCapMinus=Plane::build(Surface::PositionType(0,0,-1*ECALENDCAPZ_),Surface::RotationType());
00212
00213 AnalyticalPropagator propagator(&(*magField),alongMomentum);
00214
00215 for (uint32_t ig=0;ig<genPars.size();ig++) {
00216 reco::GenParticle gp=genPars.at(ig);
00217
00218
00219
00220 if (gp.charge()==0 || gp.status()!=1 || gp.et()<1) {
00221 curvedPars.push_back(gp);
00222 continue;
00223 }
00224 GlobalPoint vertex(gp.vx(),gp.vy(),gp.vz());
00225 GlobalVector gvect(gp.px(),gp.py(),gp.pz());
00226 FreeTrajectoryState fts(vertex,gvect,gp.charge(),&(*magField));
00227 TrajectoryStateOnSurface impact;
00228
00229 if (fabs(gp.eta())<ECALBARRELMAXETA_) {
00230 impact=propagator.propagate(fts,*theBarrel);
00231 } else if (gp.eta()>0) {
00232 impact=propagator.propagate(fts,*endCapPlus);
00233 } else {
00234 impact=propagator.propagate(fts,*endCapMinus);
00235 }
00236
00237
00238 if (!impact.isValid()) {
00239 curvedPars.push_back(gp);
00240 continue;
00241 }
00242 math::XYZTLorentzVector newp4;
00243
00244
00245
00246
00247 float et=gp.et();
00248 float phinew=impact.globalPosition().phi();
00249 float pxnew=et*cos(phinew);
00250 float pynew=et*sin(phinew);
00251 newp4.SetPx(pxnew);
00252 newp4.SetPy(pynew);
00253 newp4.SetPz(gp.pz());
00254 newp4.SetE(gp.energy());
00255 reco::GenParticle gpnew=gp;
00256 gpnew.setP4(newp4);
00257 curvedPars.push_back(gpnew);
00258 }
00259 return curvedPars;
00260
00261
00262 }
00263
00264
00265
00266 float EMEnrichingFilterAlgo::deltaRxyAtEE(const reco::GenParticle &gp1, const reco::GenParticle &gp2) {
00267
00268 if (gp1.pz()*gp2.pz() < 0) return 9999.;
00269
00270 float rxy1=ECALENDCAPZ_*tan(gp1.theta());
00271 float x1=cos(gp1.phi())*rxy1;
00272 float y1=sin(gp1.phi())*rxy1;
00273
00274 float rxy2=ECALENDCAPZ_*tan(gp2.theta());
00275 float x2=cos(gp2.phi())*rxy2;
00276 float y2=sin(gp2.phi())*rxy2;
00277
00278 float dxy=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
00279 return dxy;
00280
00281
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291 bool EMEnrichingFilterAlgo::filterIsoGenPar(float etmin, float conesize,const reco::GenParticleCollection &gph,
00292 const reco::GenParticleCollection &gphCurved
00293 ) {
00294
00295 for (uint32_t ip=0;ip<gph.size();ip++) {
00296
00297 reco::GenParticle gp=gph.at(ip);
00298 reco::GenParticle gpCurved=gphCurved.at(ip);
00299 int gpabsid=abs(gp.pdgId());
00300
00301 if (gp.et()<=etmin || gp.status()!=1) continue;
00302 if (gpabsid!=11 && gpabsid != 211 && gpabsid!= 321) continue;
00303 if (fabs(gp.eta()) < FILTER_ETA_MIN_) continue;
00304 if (fabs(gp.eta()) > FILTER_ETA_MAX_) continue;
00305
00306
00307 float tkiso=0;
00308 float caloiso=0;
00309 for (uint32_t jp=0;jp<gph.size();jp++) {
00310 if (jp==ip) continue;
00311 reco::GenParticle pp=gph.at(jp);
00312 reco::GenParticle ppCurved=gphCurved.at(jp);
00313 if (pp.status() != 1) continue;
00314 float dr=deltaR(gp,pp);
00315 float drCurved=deltaR(gpCurved,ppCurved);
00316 if (abs(pp.charge())==1 && pp.et()>2 && dr<conesize) {
00317 tkiso+=pp.et();
00318 }
00319 if (pp.et()>2 && abs(pp.pdgId())!=22 && drCurved<conesize) {
00320 caloiso+=pp.energy();
00321 }
00322 }
00323 if (tkiso<FILTER_TKISOCUT_ && caloiso<FILTER_CALOISOCUT_) return true;
00324 }
00325 return false;
00326 }
00327