CMS 3D CMS Logo

EMEnrichingFilterAlgo.cc
Go to the documentation of this file.
2 
4 
11 
14 
18 
19 #include "CLHEP/Vector/LorentzVector.h"
20 
21 
22 using namespace edm;
23 using namespace std;
24 
25 
27 
28  //set constants
29  FILTER_TKISOCUT_=4;
30  FILTER_CALOISOCUT_=7;
31  FILTER_ETA_MIN_=0;
32  FILTER_ETA_MAX_=2.4;
33  ECALBARRELMAXETA_=1.479;
34  ECALBARRELRADIUS_=129.0;
35  ECALENDCAPZ_=304.5;
36 
37 
38 
39  isoGenParETMin_=(float) iConfig.getParameter<double>("isoGenParETMin");
40  isoGenParConeSize_=(float) iConfig.getParameter<double>("isoGenParConeSize");
41  clusterThreshold_=(float) iConfig.getParameter<double>("clusterThreshold");
42  isoConeSize_=(float) iConfig.getParameter<double>("isoConeSize");
43  hOverEMax_=(float) iConfig.getParameter<double>("hOverEMax");
44  tkIsoMax_=(float) iConfig.getParameter<double>("tkIsoMax");
45  caloIsoMax_=(float) iConfig.getParameter<double>("caloIsoMax");
46  requireTrackMatch_=iConfig.getParameter<bool>("requireTrackMatch");
47  genParSource_=iConfig.getParameter<edm::InputTag>("genParSource");
48 
49  genParSourceToken_ = iConsumes.consumes<reco::GenParticleCollection>(iConfig.getParameter<edm::InputTag>("genParSource"));
50 }
51 
53 }
54 
55 
57 
58 
60  //iEvent.getByLabel(genParSource_,genParsHandle);
61  iEvent.getByToken(genParSourceToken_,genParsHandle);
62  reco::GenParticleCollection genPars=*genParsHandle;
63 
64  //bending of traj. of charged particles under influence of B-field
65  std::vector<reco::GenParticle> genParsCurved=applyBFieldCurv(genPars,iSetup);
66 
67  bool result1=filterPhotonElectronSeed(clusterThreshold_,
68  isoConeSize_,
69  hOverEMax_,
70  tkIsoMax_,
71  caloIsoMax_,
72  requireTrackMatch_,
73  genPars,
74  genParsCurved);
75 
76  bool result2=filterIsoGenPar(isoGenParETMin_,isoGenParConeSize_,genPars,genParsCurved);
77 
78 
79  bool result=result1 || result2;
80 
81  return result;
82 
83 }
84 
85 
86 
87 //filter that uses clustering around photon and electron seeds
88 //only electrons, photons, charged pions, and charged kaons are clustered
89 //additional requirements:
90 
91 
92 //seed threshold, total threshold, and cone size/shape are specified separately for the barrel and the endcap
94  float isoConeSize,
95  float hOverEMax,
96  float tkIsoMax,
97  float caloIsoMax,
98  bool requiretrackmatch,
99  const std::vector<reco::GenParticle> &genPars,
100  const std::vector<reco::GenParticle> &genParsCurved) {
101 
102  float seedthreshold=5;
103  float conesizeendcap=15;
104 
105  bool retval=false;
106 
107  vector<reco::GenParticle> seeds;
108  //find electron and photon seeds - must have E>seedthreshold GeV
109  for (uint32_t is=0;is<genParsCurved.size();is++) {
110  reco::GenParticle gp=genParsCurved.at(is);
111  if (gp.status()!=1 || fabs(gp.eta()) > FILTER_ETA_MAX_ || fabs(gp.eta()) < FILTER_ETA_MIN_) continue;
112  int absid=abs(gp.pdgId());
113  if (absid!=11 && absid!=22) continue;
114  if (gp.et()>seedthreshold) seeds.push_back(gp);
115  }
116 
117  bool matchtrack=false;
118 
119  //for every seed, try to cluster stable particles about it in cone
120  for (uint32_t is=0;is<seeds.size();is++) {
121  float eTInCone=0;//eT associated to the electron cluster
122  float tkIsoET=0;//tracker isolation energy
123  float caloIsoET=0;//calorimeter isolation energy
124  float hadET=0;//isolation energy from heavy hadrons that goes in the same area as the "electron" - so contributes to H/E
125  bool isBarrel=fabs(seeds.at(is).eta())<ECALBARRELMAXETA_;
126  for (uint32_t ig=0;ig<genParsCurved.size();ig++) {
127  reco::GenParticle gp=genParsCurved.at(ig);
128  reco::GenParticle gpUnCurv=genPars.at(ig);//for tk isolation, p at vertex
129  if (gp.status()!=1) continue;
130  int gpabsid=abs(gp.pdgId());
131  if (gp.et()<1) continue;//ignore very soft particles
132  //BARREL
133  if (isBarrel) {
134  float dr=deltaR(seeds.at(is),gp);
135  float dphi=deltaPhi(seeds.at(is).phi(),gp.phi());
136  float deta=fabs(seeds.at(is).eta()-gp.eta());
137  if (deta<0.03 && dphi<0.2) {
138  if (gpabsid==22 || gpabsid==11 || gpabsid==211 || gpabsid==321) {
139  //contributes to electron
140  eTInCone+=gp.et();
141  //check for a matched track with at least 5 GeV
142  if ((gpabsid==11 || gpabsid==211 || gpabsid==321) && gp.et()>5) matchtrack=true;
143  } else {
144  //contributes to H/E
145  hadET+=gp.et();
146  }
147  } else {
148  float drUnCurv=deltaR(seeds.at(is),gpUnCurv);
149  if ((gp.charge()==0 && dr<isoConeSize && gpabsid!=22) ||
150  (gp.charge()!=0 && drUnCurv<isoConeSize)) {
151  //contributes to calo isolation energy
152  caloIsoET+=gp.et();
153  }
154  if (gp.charge()!=0 && drUnCurv<isoConeSize) {
155  //contributes to track isolation energy
156  tkIsoET+=gp.et();
157  }
158  }
159  //ENDCAP
160  } else {
161  float drxy=deltaRxyAtEE(seeds.at(is),gp);
162  float dr=deltaR(seeds.at(is),gp);//the isolation is done in dR
163  if (drxy<conesizeendcap) {
164  if (gpabsid==22 || gpabsid==11 || gpabsid==211 || gpabsid==321) {
165  //contributes to electron
166  eTInCone+=gp.et();
167  //check for a matched track with at least 5 GeV
168  if ((gpabsid==11 || gpabsid==211 || gpabsid==321) && gp.et()>5) matchtrack=true;
169  } else {
170  //contributes to H/E
171  hadET+=gp.et();
172  }
173  } else {
174  float drUnCurv=deltaR(seeds.at(is),gpUnCurv);
175  if ((gp.charge()==0 && dr<isoConeSize && gpabsid!=22) ||
176  (gp.charge()!=0 && drUnCurv<isoConeSize)) {
177  //contributes to calo isolation energy
178  caloIsoET+=gp.et();
179  }
180  if (gp.charge()!=0 && drUnCurv<isoConeSize) {
181  //contributes to track isolation energy
182  tkIsoET+=gp.et();
183  }
184  }
185  }
186  }
187 
188  if (eTInCone>clusterthreshold && (!requiretrackmatch || matchtrack)) {
189  // cout <<"isoET: "<<isoET<<endl;
190  if (hadET/eTInCone<hOverEMax && tkIsoET<tkIsoMax && caloIsoET<caloIsoMax) retval=true;
191  break;
192  }
193  }
194 
195  return retval;
196 }
197 
198 
199 
200 
201 //make new genparticles vector taking into account the bending of charged particles in the b field
202 //only stable-final-state (status==1) particles, with ET>=1 GeV, have their trajectories bent
203 std::vector<reco::GenParticle> EMEnrichingFilterAlgo::applyBFieldCurv(const std::vector<reco::GenParticle> &genPars, const edm::EventSetup& iSetup) {
204 
205 
206  vector<reco::GenParticle> curvedPars;
207 
209  iSetup.get<IdealMagneticFieldRecord>().get(magField);
210 
214 
216 
217  for (uint32_t ig=0;ig<genPars.size();ig++) {
218  reco::GenParticle gp=genPars.at(ig);
219  //don't bend trajectories of neutral particles, unstable particles, particles with < 1 GeV
220  //particles with < ~0.9 GeV don't reach the barrel
221  //so just put them as-is into the new vector
222  if (gp.charge()==0 || gp.status()!=1 || gp.et()<1) {
223  curvedPars.push_back(gp);
224  continue;
225  }
226  GlobalPoint vertex(gp.vx(),gp.vy(),gp.vz());
227  GlobalVector gvect(gp.px(),gp.py(),gp.pz());
228  FreeTrajectoryState fts(vertex,gvect,gp.charge(),&(*magField));
230  //choose to propagate to barrel, +Z endcap, or -Z endcap, according to eta
231  if (fabs(gp.eta())<ECALBARRELMAXETA_) {
232  impact=propagator.propagate(fts,*theBarrel);
233  } else if (gp.eta()>0) {
234  impact=propagator.propagate(fts,*endCapPlus);
235  } else {
236  impact=propagator.propagate(fts,*endCapMinus);
237  }
238  //in case the particle doesn't reach the barrel/endcap, just put it as-is into the new vector
239  //it should reach though.
240  if (!impact.isValid()) {
241  curvedPars.push_back(gp);
242  continue;
243  }
245 
246  //the magnitude of p doesn't change, only the direction
247  //NB I do get some small change in magnitude by the following,
248  //I think it is a numerical precision issue
249  float et=gp.et();
250  float phinew=impact.globalPosition().phi();
251  float pxnew=et*cos(phinew);
252  float pynew=et*sin(phinew);
253  newp4.SetPx(pxnew);
254  newp4.SetPy(pynew);
255  newp4.SetPz(gp.pz());
256  newp4.SetE(gp.energy());
257  reco::GenParticle gpnew=gp;
258  gpnew.setP4(newp4);
259  curvedPars.push_back(gpnew);
260  }
261  return curvedPars;
262 
263 
264 }
265 
266 //calculate the difference in the xy-plane positions of gp1 and gp1 at the ECAL endcap
267 //if they go in different z directions returns 9999.
269 
270  if (gp1.pz()*gp2.pz() < 0) return 9999.;
271 
272  float rxy1=ECALENDCAPZ_*tan(gp1.theta());
273  float x1=cos(gp1.phi())*rxy1;
274  float y1=sin(gp1.phi())*rxy1;
275 
276  float rxy2=ECALENDCAPZ_*tan(gp2.theta());
277  float x2=cos(gp2.phi())*rxy2;
278  float y2=sin(gp2.phi())*rxy2;
279 
280  float dxy=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
281  return dxy;
282 
283 
284 }
285 
286 
287 //filter looking for isolated charged pions, charged kaons, and electrons.
288 //isolation done in cone of given size, looking at charged particles and neutral hadrons
289 //photons aren't counted in the isolation requirements
290 
291 //need to have both the the curved and uncurved genpar collections
292 //because tracker iso has to be treated differently than calo iso
293 bool EMEnrichingFilterAlgo::filterIsoGenPar(float etmin, float conesize,const reco::GenParticleCollection &gph,
294  const reco::GenParticleCollection &gphCurved
295  ) {
296 
297  for (uint32_t ip=0;ip<gph.size();ip++) {
298 
299  reco::GenParticle gp=gph.at(ip);
300  reco::GenParticle gpCurved=gphCurved.at(ip);
301  int gpabsid=abs(gp.pdgId());
302  //find potential candidates
303  if (gp.et()<=etmin || gp.status()!=1) continue;
304  if (gpabsid!=11 && gpabsid != 211 && gpabsid!= 321) continue;
305  if (fabs(gp.eta()) < FILTER_ETA_MIN_) continue;
306  if (fabs(gp.eta()) > FILTER_ETA_MAX_) continue;
307 
308  //check isolation
309  float tkiso=0;
310  float caloiso=0;
311  for (uint32_t jp=0;jp<gph.size();jp++) {
312  if (jp==ip) continue;
313  reco::GenParticle pp=gph.at(jp);
314  reco::GenParticle ppCurved=gphCurved.at(jp);
315  if (pp.status() != 1) continue;
316  float dr=deltaR(gp,pp);
317  float drCurved=deltaR(gpCurved,ppCurved);
318  if (abs(pp.charge())==1 && pp.et()>2 && dr<conesize) {
319  tkiso+=pp.et();
320  }
321  if (pp.et()>2 && abs(pp.pdgId())!=22 && drCurved<conesize) {
322  caloiso+=pp.energy();
323  }
324  }
325  if (tkiso<FILTER_TKISOCUT_ && caloiso<FILTER_CALOISOCUT_) return true;
326  }
327  return false;
328 }
329 
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
T getParameter(std::string const &) const
int pdgId() const final
PDG identifier.
double eta() const final
momentum pseudorapidity
double theta() const final
momentum polar angle
double vy() const override
y coordinate of vertex position
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
bool isBarrel(GeomDetEnumerators::SubDetector m)
double px() const final
x coordinate of momentum vector
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
float deltaRxyAtEE(const reco::GenParticle &gp1, const reco::GenParticle &gp2)
int charge() const final
electric charge
Definition: LeafCandidate.h:91
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
static CylinderPointer build(const PositionType &pos, const RotationType &rot, Scalar radius, Bounds *bounds=0)
Definition: Cylinder.h:51
int iEvent
Definition: GenABIO.cc:224
double et() const final
transverse energy
EMEnrichingFilterAlgo(const edm::ParameterSet &, edm::ConsumesCollector &&)
double pz() const final
z coordinate of momentum vector
bool filterIsoGenPar(float etmin, float conesize, const reco::GenParticleCollection &gph, const reco::GenParticleCollection &gphCurved)
T sqrt(T t)
Definition: SSEVec.h:18
static PlanePointer build(Args &&...args)
Definition: Plane.h:33
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
double energy() const final
energy
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool filter(const edm::Event &iEvent, const edm::EventSetup &iSetup)
double vz() const override
z coordinate of vertex position
double py() const final
y coordinate of momentum vector
et
define resolution functions of each parameter
HLT enums.
T get() const
Definition: EventSetup.h:71
int status() const final
status word
std::vector< reco::GenParticle > applyBFieldCurv(const std::vector< reco::GenParticle > &genPars, const edm::EventSetup &iSetup)
double phi() const final
momentum azimuthal angle
bool filterPhotonElectronSeed(float clusterthreshold, float isoConeSize, float hOverEMax, float tkIsoMax, float caloIsoMax, bool requiretrackmatch, const std::vector< reco::GenParticle > &genPars, const std::vector< reco::GenParticle > &genParsCurved)
void setP4(const LorentzVector &p4) final
set 4-momentum
double vx() const override
x coordinate of vertex position