InvMassFinalState.cc
Go to the documentation of this file.
00001 // -*- C++ -*- 00002 #include "Rivet/Projections/InvMassFinalState.hh" 00003 00004 namespace Rivet { 00005 00006 00007 InvMassFinalState::InvMassFinalState(const FinalState& fsp, 00008 const pair<PdgId, PdgId>& idpair, // pair of decay products 00009 double minmass, // min inv mass 00010 double maxmass, // max inv mass 00011 double masstarget) 00012 : _minmass(minmass), _maxmass(maxmass), _masstarget(masstarget), _useTransverseMass(false) 00013 { 00014 setName("InvMassFinalState"); 00015 addProjection(fsp, "FS"); 00016 _decayids.push_back(idpair); 00017 } 00018 00019 00020 InvMassFinalState::InvMassFinalState(const FinalState& fsp, 00021 const vector<pair<PdgId, PdgId> >& idpairs, // vector of pairs of decay products 00022 double minmass, // min inv mass 00023 double maxmass, // max inv mass 00024 double masstarget) 00025 : _decayids(idpairs), _minmass(minmass), _maxmass(maxmass), _masstarget(masstarget), _useTransverseMass(false) 00026 { 00027 setName("InvMassFinalState"); 00028 addProjection(fsp, "FS"); 00029 } 00030 00031 00032 InvMassFinalState::InvMassFinalState(const pair<PdgId, PdgId>& idpair, // pair of decay products 00033 double minmass, // min inv mass 00034 double maxmass, // max inv mass 00035 double masstarget) 00036 : _minmass(minmass), _maxmass(maxmass), _masstarget(masstarget), _useTransverseMass(false) 00037 { 00038 setName("InvMassFinalState"); 00039 _decayids.push_back(idpair); 00040 } 00041 00042 00043 InvMassFinalState::InvMassFinalState(const vector<pair<PdgId, PdgId> >& idpairs, // vector of pairs of decay products 00044 double minmass, // min inv mass 00045 double maxmass, // max inv mass 00046 double masstarget) 00047 : _decayids(idpairs), _minmass(minmass), _maxmass(maxmass), _masstarget(masstarget), _useTransverseMass(false) 00048 { 00049 setName("InvMassFinalState"); 00050 } 00051 00052 00053 int InvMassFinalState::compare(const Projection& p) const { 00054 // First compare the final states we are running on 00055 int fscmp = mkNamedPCmp(p, "FS"); 00056 if (fscmp != EQUIVALENT) return fscmp; 00057 00058 // Then compare the two as final states 00059 const InvMassFinalState& other = dynamic_cast<const InvMassFinalState&>(p); 00060 fscmp = FinalState::compare(other); 00061 if (fscmp != EQUIVALENT) return fscmp; 00062 00063 // Compare the mass limits 00064 int masstypecmp = cmp(_useTransverseMass, other._useTransverseMass); 00065 if (masstypecmp != EQUIVALENT) return masstypecmp; 00066 int massllimcmp = cmp(_minmass, other._minmass); 00067 if (massllimcmp != EQUIVALENT) return massllimcmp; 00068 int masshlimcmp = cmp(_maxmass, other._maxmass); 00069 if (masshlimcmp != EQUIVALENT) return masshlimcmp; 00070 00071 // Compare the decay species 00072 int decaycmp = cmp(_decayids, other._decayids); 00073 if (decaycmp != EQUIVALENT) return decaycmp; 00074 00075 // Finally compare them as final states 00076 return FinalState::compare(other); 00077 } 00078 00079 00080 void InvMassFinalState::project(const Event& e) { 00081 const FinalState& fs = applyProjection<FinalState>(e, "FS"); 00082 calc(fs.particles()); 00083 } 00084 00085 00086 void InvMassFinalState::calc(const Particles& inparticles) { 00087 _theParticles.clear(); 00088 _particlePairs.clear(); 00089 00090 // Containers for the particles of type specified in the pair 00091 vector<const Particle*> type1; 00092 vector<const Particle*> type2; 00093 // Get all the particles of the type specified in the pair from the particle list 00094 foreach (const Particle& ipart, inparticles) { 00095 // Loop around possible particle pairs (typedef needed to keep BOOST_FOREACH happy) 00096 foreach (const PdgIdPair& ipair, _decayids) { 00097 if (ipart.pdgId() == ipair.first) { 00098 if (accept(ipart)) { 00099 type1 += &ipart; 00100 } 00101 } else if (ipart.pdgId() == ipair.second) { 00102 if (accept(ipart)) { 00103 type2 += &ipart; 00104 } 00105 } 00106 } 00107 } 00108 if (type1.empty() || type2.empty()) return; 00109 00110 // Temporary container of selected particles iterators 00111 // Useful to compare iterators and avoid double occurrences of the same 00112 // particle in case it matches with more than another particle 00113 vector<const Particle*> tmp; 00114 00115 // Now calculate the inv mass 00116 pair<double, pair<Particle, Particle> > closestPair; 00117 closestPair.first = 1e30; 00118 foreach (const Particle* i1, type1) { 00119 foreach (const Particle* i2, type2) { 00120 // Check this is actually a pair 00121 // (if more than one pair in vector particles can be unrelated) 00122 bool found = false; 00123 foreach (const PdgIdPair& ipair, _decayids) { 00124 if (i1->pdgId() == ipair.first && i2->pdgId() == ipair.second) { 00125 found = true; 00126 break; 00127 } 00128 } 00129 if (!found) continue; 00130 00131 FourMomentum v4 = i1->momentum() + i2->momentum(); 00132 if (v4.mass2() < 0) { 00133 MSG_DEBUG("Constructed negative inv mass2: skipping!"); 00134 continue; 00135 } 00136 bool passedMassCut = false; 00137 if (_useTransverseMass) { 00138 passedMassCut = inRange(massT(i1->momentum(), i2->momentum()), _minmass, _maxmass); 00139 } else { 00140 passedMassCut = inRange(v4.mass(), _minmass, _maxmass); 00141 } 00142 00143 if (passedMassCut) { 00144 MSG_DEBUG("Selecting particles with IDs " << i1->pdgId() << " & " << i2->pdgId() 00145 << " and mass = " << v4.mass()/GeV << " GeV"); 00146 // Store accepted particles, avoiding duplicates 00147 if (find(tmp.begin(), tmp.end(), i1) == tmp.end()) { 00148 tmp.push_back(i1); 00149 _theParticles += *i1; 00150 } 00151 if (find(tmp.begin(), tmp.end(), i2) == tmp.end()) { 00152 tmp.push_back(i2); 00153 _theParticles += *i2; 00154 } 00155 // Store accepted particle pairs 00156 _particlePairs += make_pair(*i1, *i2); 00157 if (_masstarget>0.0) { 00158 double diff=fabs(v4.mass()-_masstarget); 00159 if (diff<closestPair.first) { 00160 closestPair.first=diff; 00161 closestPair.second=make_pair(*i1, *i2); 00162 } 00163 } 00164 } 00165 } 00166 } 00167 if (_masstarget > 0.0 && closestPair.first < 1e30) { 00168 _theParticles.clear(); 00169 _particlePairs.clear(); 00170 _theParticles += closestPair.second.first; 00171 _theParticles += closestPair.second.second; 00172 _particlePairs += closestPair.second; 00173 } 00174 00175 MSG_DEBUG("Selected " << _theParticles.size() << " particles " << "(" << _particlePairs.size() << " pairs)"); 00176 if (getLog().isActive(Log::TRACE)) { 00177 foreach (const Particle& p, _theParticles) { 00178 MSG_TRACE("ID: " << p.pdgId() << ", barcode: " << p.genParticle()->barcode()); 00179 } 00180 } 00181 } 00182 00183 00184 /// Constituent pairs 00185 const std::vector<std::pair<Particle, Particle> >& InvMassFinalState::particlePairs() const { 00186 return _particlePairs; 00187 } 00188 00189 00190 } Generated on Thu Feb 6 2014 17:38:45 for The Rivet MC analysis system by 1.7.6.1 |