CMS 3D CMS Logo

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