CMS 3D CMS Logo

PythiaFilterIsolatedTrack.cc
Go to the documentation of this file.
5 
6 #include "CLHEP/Random/RandomEngine.h"
7 #include "CLHEP/Units/GlobalPhysicalConstants.h"
8 
9 #include <iostream>
10 #include<list>
11 #include<vector>
12 #include<cmath>
13 
14 std::pair<double,double> PythiaFilterIsolatedTrack::GetEtaPhiAtEcal(double etaIP, double phiIP, double pT, int charge, double vtxZ)
15 {
16  double deltaPhi;
17  double etaEC=100;
18  double phiEC=100;
19  double Rcurv=pT*33.3*100/38; //r(m)=pT(GeV)*33.3/B(kG)
20  double theta=2*atan(exp(-etaIP));
21  double zNew;
22  if (theta>CLHEP::halfpi) theta=CLHEP::pi-theta;
23  if (fabs(etaIP)<1.479) {
24  deltaPhi=-charge*asin(0.5*ecRad_/Rcurv);
25  double alpha1=2*asin(0.5*ecRad_/Rcurv);
26  double z=ecRad_/tan(theta);
27  if (etaIP>0) zNew=z*(Rcurv*alpha1)/ecRad_+vtxZ; //new z-coordinate of track
28  else zNew=-z*(Rcurv*alpha1)/ecRad_+vtxZ; //new z-coordinate of track
29  double zAbs=fabs(zNew);
30  if (zAbs<ecDist_) {
31  etaEC=-log(tan(0.5*atan(ecRad_/zAbs)));
32  deltaPhi=-charge*asin(0.5*ecRad_/Rcurv);
33  }
34  if (zAbs>ecDist_) {
35  zAbs=(fabs(etaIP)/etaIP)*ecDist_;
36  double Zflight=fabs(zAbs-vtxZ);
37  double alpha=(Zflight*ecRad_)/(z*Rcurv);
38  double Rec=2*Rcurv*sin(alpha/2);
39  deltaPhi=-charge*alpha/2;
40  etaEC=-log(tan(0.5*atan(Rec/ecDist_)));
41  }
42  } else {
43  zNew=(fabs(etaIP)/etaIP)*ecDist_;
44  double Zflight=fabs(zNew-vtxZ);
45  double Rvirt=fabs(Zflight*tan(theta));
46  double Rec=2*Rcurv*sin(Rvirt/(2*Rcurv));
47  deltaPhi=-(charge)*(Rvirt/(2*Rcurv));
48  etaEC=-log(tan(0.5*atan(Rec/ecDist_)));
49  }
50 
51  if (zNew<0) etaEC=-etaEC;
52  phiEC=phiIP+deltaPhi;
53 
54  if (phiEC<-CLHEP::pi) phiEC= 2*CLHEP::pi+phiEC;
55  if (phiEC> CLHEP::pi) phiEC=-2*CLHEP::pi+phiEC;
56 
57  std::pair<double,double> retVal(etaEC,phiEC);
58  return retVal;
59 }
60 
61 double PythiaFilterIsolatedTrack::getDistInCM(double eta1, double phi1, double eta2, double phi2)
62 {
63  double dR, Rec;
64  if (fabs(eta1)<1.479) Rec=ecRad_;
65  else Rec=ecDist_;
66  double ce1=cosh(eta1);
67  double ce2=cosh(eta2);
68  double te1=tanh(eta1);
69  double te2=tanh(eta2);
70 
71  double z=cos(phi1-phi2)/ce1/ce2+te1*te2;
72  if(z!=0) dR=fabs(Rec*ce1*sqrt(1./z/z-1.));
73  else dR=999999.;
74  return dR;
75 }
76 
78 
79  token_ = consumes<edm::HepMCProduct>(iConfig.getUntrackedParameter("ModuleLabel",edm::InputTag("generator","unsmeared")));
80  MaxSeedEta_ = iConfig.getUntrackedParameter<double>("MaxSeedEta", 2.3);
81  MinSeedMom_ = iConfig.getUntrackedParameter<double>("MinSeedMom", 20.);
82  MinIsolTrackMom_ = iConfig.getUntrackedParameter<double>("MinIsolTrackMom",2.0);
83  IsolCone_ = iConfig.getUntrackedParameter<double>("IsolCone", 40.0);
84  onlyHadrons_= iConfig.getUntrackedParameter<bool>("OnlyHadrons", true);
85 }
86 
88 
89 // ------------ method called to produce the data ------------
91 
92  ++nAll_;
94  iSetup.getData( pdt );
95 
97  iEvent.getByToken(token_, evt);
98 
99  const HepMC::GenEvent* myGenEvent = evt->GetEvent();
100 
101  // all of the stable, charged particles with momentum>MinIsolTrackMom_ and |eta|<MaxSeedEta_+0.5
102  std::vector<const HepMC::GenParticle *> chargedParticles;
103 
104  // all of the stable, charged particles with momentum>MinSeedMom_ and |eta|<MaxSeedEta_
105  std::vector<const HepMC::GenParticle *> seeds;
106 
107  // fill the vector of charged particles and seeds in the event
108  for (HepMC::GenEvent::particle_const_iterator iter=myGenEvent->particles_begin(); iter!=myGenEvent->particles_end(); ++iter) {
109  const HepMC::GenParticle *p=*iter;
110  if (!(pdt->particle(p->pdg_id()))) continue;
111  int charge3 = pdt->particle(p->pdg_id())->ID().threeCharge();
112  int status = p->status();
113  double momentum = p->momentum().rho();
114  double abseta = fabs(p->momentum().eta());
115 
116  // only consider stable, charged particles
117  if (abs(charge3)==3 && status==1 && momentum>MinIsolTrackMom_ && abseta<MaxSeedEta_+0.5) {
118  chargedParticles.push_back(p);
119  if (momentum>MinSeedMom_ && abseta<MaxSeedEta_) {
120  seeds.push_back(p);
121  }
122  }
123  }
124 
125  // loop over all the seeds and see if any of them are isolated
126  unsigned int ntrk(0);
127  for (std::vector<const HepMC::GenParticle *>::const_iterator it1=seeds.begin(); it1!=seeds.end(); ++it1) {
128  const HepMC::GenParticle *p1=*it1;
129  if (!(pdt->particle(p1->pdg_id()))) continue;
130  if (p1->pdg_id() < -100 || p1->pdg_id() > 100 || (!onlyHadrons_)) { // Select hadrons only
131  std::pair<double,double> EtaPhi1=GetEtaPhiAtEcal(p1->momentum().eta(),
132  p1->momentum().phi(),
133  p1->momentum().perp(),
134  (pdt->particle(p1->pdg_id()))->ID().threeCharge()/3,
135  0.0);
136 
137  // loop over all of the other charged particles in the event, and see if any are close by
138  bool failsIso=false;
139  for (std::vector<const HepMC::GenParticle *>::const_iterator it2=chargedParticles.begin(); it2!=chargedParticles.end(); ++it2) {
140  const HepMC::GenParticle *p2=*it2;
141 
142  // don't consider the seed particle among the other charge particles
143  if (p1!=p2) {
144 
145  std::pair<double,double> EtaPhi2=GetEtaPhiAtEcal(p2->momentum().eta(),
146  p2->momentum().phi(),
147  p2->momentum().perp(),
148  (pdt->particle(p2->pdg_id()))->ID().threeCharge()/3,
149  0.0);
150 
151  // find out how far apart the particles are
152  // if the seed fails the isolation requirement, try a different seed
153  // occasionally allow a seed to pass to isolation requirement
154  if (getDistInCM(EtaPhi1.first, EtaPhi1.second, EtaPhi2.first, EtaPhi2.second) < IsolCone_) {
155  failsIso=true;
156  break;
157  }
158  }
159  }
160 
161  if (!failsIso) ++ntrk;
162  }
163  } //loop over seeds
164  if (ntrk>0) {
165  ++nGood_;
166  return true;
167  } else {
168  return false;
169  }
170 }
171 
173  globalCache()->nAll_ += nAll_;
174  globalCache()->nGood_ += nGood_;
175 }
176 
178  edm::LogInfo("PythiaFilter") << "PythiaFilterIsolatedTrack::Accepts "
179  << count->nGood_ <<" events out of "
180  << count->nAll_ << std::endl;
181 }
T getUntrackedParameter(std::string const &, T const &) const
float alpha
Definition: AMPTWrapper.h:95
static void globalEndJob(const PythiaFilterIsoTracks::Counters *counters)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
uint32_t ID
Definition: Definitions.h:26
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
PythiaFilterIsolatedTrack(const edm::ParameterSet &, const PythiaFilterIsoTracks::Counters *count)
Geom::Theta< T > theta() const
const Double_t pi
bool getData(T &iHolder) const
Definition: EventSetup.h:111
int iEvent
Definition: GenABIO.cc:224
T sqrt(T t)
Definition: SSEVec.h:18
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
edm::EDGetTokenT< edm::HepMCProduct > token_
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double p2[4]
Definition: TauolaWrapper.h:90
std::atomic< unsigned int > nGood_
double getDistInCM(double eta1, double phi1, double eta2, double phi2)
const HepMC::GenEvent * GetEvent() const
Definition: HepMCProduct.h:38
bool filter(edm::Event &, edm::EventSetup const &) override
double p1[4]
Definition: TauolaWrapper.h:89
std::pair< double, double > GetEtaPhiAtEcal(double etaIP, double phiIP, double pT, int charge, double vtxZ)