00001 #include "Rivet/Jet.hh"
00002 #include "Rivet/Tools/Logging.hh"
00003 #include "Rivet/Tools/ParticleIdUtils.hh"
00004 #include "Rivet/ParticleName.hh"
00005 #include "Rivet/RivetBoost.hh"
00006
00007 namespace Rivet {
00008
00009
00010 Jet::Jet()
00011 : ParticleBase()
00012 {
00013 clear();
00014 }
00015
00016
00017 Jet& Jet::setParticles(const vector<FourMomentum>& particles) {
00018 _particles = particles;
00019 _resetCaches();
00020 return *this;
00021 }
00022
00023
00024 Jet& Jet::addParticle(const FourMomentum& particle) {
00025 _particles.push_back(particle);
00026 _resetCaches();
00027 return *this;
00028 }
00029
00030
00031 Jet& Jet::addParticle(const Particle& particle) {
00032 _fullParticles.push_back(particle);
00033 _particles.push_back(particle.momentum());
00034 _resetCaches();
00035 return *this;
00036 }
00037
00038
00039 bool Jet::containsParticle(const Particle& particle) const {
00040 const int barcode = particle.genParticle().barcode();
00041 foreach (const Particle& p, particles()) {
00042 if (p.genParticle().barcode() == barcode) return true;
00043 }
00044 return false;
00045 }
00046
00047
00048 bool Jet::containsParticleId(PdgId pid) const {
00049 foreach (const Particle& p, particles()) {
00050 if (p.pdgId() == pid) return true;
00051 }
00052 return false;
00053 }
00054
00055
00056 bool Jet::containsParticleId(const vector<PdgId>& pids) const {
00057 foreach (const Particle& p, particles()) {
00058 foreach (PdgId pid, pids) {
00059 if (p.pdgId() == pid) return true;
00060 }
00061 }
00062 return false;
00063 }
00064
00065
00066
00067
00068
00069 double Jet::totalEnergy() const {
00070 return momentum().E();
00071 }
00072
00073
00074 double Jet::neutralEnergy() const {
00075 double e_neutral = 0.0;
00076 foreach (const Particle& p, particles()) {
00077 const PdgId pid = p.pdgId();
00078 if (PID::threeCharge(pid) == 0) {
00079 e_neutral += p.momentum().E();
00080 }
00081 }
00082 return e_neutral;
00083 }
00084
00085
00086 double Jet::hadronicEnergy() const {
00087 double e_hadr = 0.0;
00088 foreach (const Particle& p, particles()) {
00089 const PdgId pid = p.pdgId();
00090 if (PID::isHadron(pid)) {
00091 e_hadr += p.momentum().E();
00092 }
00093 }
00094 return e_hadr;
00095 }
00096
00097
00098 bool Jet::containsCharm() const {
00099 foreach (const Particle& p, particles()) {
00100 const PdgId pid = p.pdgId();
00101 if (abs(pid) == CQUARK) return true;
00102 if (PID::isHadron(pid) && PID::hasCharm(pid)) return true;
00103 HepMC::GenVertex* gv = p.genParticle().production_vertex();
00104 if (gv) {
00105 foreach (const GenParticle* pi, Rivet::particles(gv, HepMC::ancestors)) {
00106 const PdgId pid2 = pi->pdg_id();
00107 if (PID::isHadron(pid2) && PID::hasCharm(pid2)) return true;
00108 }
00109 }
00110 }
00111 return false;
00112 }
00113
00114
00115 bool Jet::containsBottom() const {
00116 foreach (const Particle& p, particles()) {
00117 const PdgId pid = p.pdgId();
00118 if (abs(pid) == BQUARK) return true;
00119 if (PID::isHadron(pid) && PID::hasBottom(pid)) return true;
00120 HepMC::GenVertex* gv = p.genParticle().production_vertex();
00121 if (gv) {
00122 foreach (const GenParticle* pi, Rivet::particles(gv, HepMC::ancestors)) {
00123 const PdgId pid2 = pi->pdg_id();
00124 if (PID::isHadron(pid2) && PID::hasBottom(pid2)) return true;
00125 }
00126 }
00127 }
00128 return false;
00129 }
00130
00131
00132 Jet& Jet::clear() {
00133 _particles.clear();
00134 _fullParticles.clear();
00135 _resetCaches();
00136 return *this;
00137 }
00138
00139
00140 double Jet::ptWeightedEta() const {
00141 _calcPtAvgs();
00142 assert(_okPtWeightedEta);
00143 return _ptWeightedEta;
00144 }
00145
00146
00147 double Jet::ptWeightedPhi() const {
00148 _calcPtAvgs();
00149 assert(_okPtWeightedPhi);
00150 return _ptWeightedPhi;
00151 }
00152
00153
00154 double Jet::eta() const {
00155 return momentum().eta();
00156
00157 }
00158
00159
00160 double Jet::phi() const {
00161 return momentum().phi();
00162 }
00163
00164
00165 const FourMomentum& Jet::momentum() const {
00166 _calcMomVector();
00167 return _momentum;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177 double Jet::ptSum() const {
00178 return momentum().pT();
00179 }
00180
00181
00182 double Jet::EtSum() const {
00183 return momentum().Et();
00184 }
00185
00186
00187 void Jet::_resetCaches() const {
00188 _okPtWeightedPhi = false;
00189 _okPtWeightedEta = false;
00190 _okMomentum = false;
00191 }
00192
00193
00194 void Jet::_calcMomVector() const {
00195 if (!_okMomentum) {
00196 _momentum = accumulate(begin(), end(), FourMomentum());
00197 _okMomentum = true;
00198 }
00199 }
00200
00201
00202 void Jet::_calcPtAvgs() const {
00203 if (!_okPtWeightedEta || !_okPtWeightedPhi) {
00204 double ptwetasum(0.0), ptwdphisum(0.0), ptsum(0.0);
00205 double phi0 = phi();
00206 foreach (const FourMomentum& p, momenta()) {
00207 double pt = p.pT();
00208 ptsum += pt;
00209 ptwetasum += pt * p.pseudorapidity();
00210 ptwdphisum += pt * mapAngleMPiToPi(phi0 - p.azimuthalAngle());
00211 }
00212 _ptWeightedEta = ptwetasum/ptsum;
00213 _okPtWeightedEta = true;
00214 _ptWeightedPhi = mapAngleMPiToPi(phi0 + ptwdphisum/ptsum);
00215 _okPtWeightedPhi = true;
00216 }
00217 }
00218
00219
00220 }