InvMassFinalState.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Projections/InvMassFinalState.hh"
00003 #include "Rivet/Tools/Logging.hh"
00004 #include "Rivet/Cmp.hh"
00005 
00006 namespace Rivet {
00007 
00008 
00009   InvMassFinalState::InvMassFinalState(const FinalState& fsp,
00010                                        const pair<PdgId, PdgId>& idpair, // pair of decay products
00011                                        double minmass, // min inv mass
00012                                        double maxmass) // max inv mass
00013     : _minmass(minmass), _maxmass(maxmass)
00014   {
00015     setName("InvMassFinalState");
00016     addProjection(fsp, "FS");
00017     _decayids.push_back(idpair);
00018   }
00019 
00020 
00021   InvMassFinalState::InvMassFinalState(const FinalState& fsp,
00022                                        const vector<pair<PdgId, PdgId> >& idpairs,  // vector of pairs of decay products
00023                                        double minmass, // min inv mass
00024                                        double maxmass) // max inv mass
00025     : _decayids(idpairs), _minmass(minmass), _maxmass(maxmass)
00026   {
00027     setName("InvMassFinalState");
00028     addProjection(fsp, "FS");
00029   }
00030 
00031 
00032   int InvMassFinalState::compare(const Projection& p) const {
00033     // First compare the final states we are running on
00034     int fscmp = mkNamedPCmp(p, "FS");
00035     if (fscmp != EQUIVALENT) return fscmp;
00036 
00037     // Then compare the two as final states
00038     const InvMassFinalState& other = dynamic_cast<const InvMassFinalState&>(p);
00039     fscmp = FinalState::compare(other);
00040     if (fscmp != EQUIVALENT) return fscmp;
00041 
00042     // Then compare the mass limits
00043     int massllimcmp = cmp(_minmass, other._minmass);
00044     if (massllimcmp != EQUIVALENT) return massllimcmp;
00045     int masshlimcmp = cmp(_maxmass, other._maxmass);
00046     if (masshlimcmp != EQUIVALENT) return masshlimcmp;
00047 
00048     // Compare the decay species
00049     int decaycmp = cmp(_decayids, other._decayids);
00050     if (decaycmp != EQUIVALENT) return decaycmp;
00051 
00052     // Finally compare them as final states
00053     return FinalState::compare(other);
00054   }
00055 
00056 
00057 
00058   void InvMassFinalState::project(const Event& e) {
00059     _theParticles.clear();
00060     _particlePairs.clear();
00061     const FinalState& fs = applyProjection<FinalState>(e, "FS");
00062 
00063     // Containers for the particles of type specified in the pair
00064     vector<const Particle*> type1;
00065     vector<const Particle*> type2;
00066     // Get all the particles of the type specified in the pair from the particle list
00067     foreach (const Particle& ipart, fs.particles()) {
00068       // Loop around possible particle pairs (typedef needed to keep BOOST_FOREACH happy)
00069       foreach (const PidPair& ipair, _decayids) {
00070         if (ipart.pdgId() == ipair.first) {
00071           if (accept(ipart.genParticle())) {
00072             type1 += &ipart;
00073           }
00074         } else if (ipart.pdgId() == ipair.second) {
00075           if (accept(ipart.genParticle())) {
00076             type2 += &ipart;
00077           }
00078         }
00079       }
00080     }
00081 
00082     // Temporary container of selected particles iterators
00083     // Useful to compare iterators and avoid double occurrences of the same
00084     // particle in case it matches with more than another particle
00085     vector<const Particle*> tmp;
00086 
00087     // Now calculate the inv mass
00088     foreach (const Particle* i1, type1) {
00089       foreach (const Particle* i2, type2) {
00090         FourMomentum v4 = i1->momentum() + i2->momentum();
00091         if (v4.mass() > _minmass && v4.mass() < _maxmass) {
00092           getLog() << Log::DEBUG << "Selecting particles with IDs "
00093                    << i1->pdgId() << " & " << i2->pdgId()
00094                    << " and mass = " << v4.mass()/GeV << " GeV" << endl;
00095           // Store accepted particles, avoiding duplicates
00096           if (find(tmp.begin(), tmp.end(), i1) == tmp.end()) {
00097             tmp.push_back(i1);
00098             _theParticles += *i1;
00099           }
00100           if (find(tmp.begin(), tmp.end(), i2) == tmp.end()) {
00101             tmp.push_back(i2);
00102             _theParticles += *i2;
00103           }
00104           // Store accepted particle pairs
00105           _particlePairs += make_pair(*i1, *i2);          
00106         }
00107       }
00108     }
00109  
00110     getLog() << Log::DEBUG << "Selected " << _theParticles.size() << " particles " 
00111              << "(" << _particlePairs.size() << " pairs)" << endl;
00112     if (getLog().isActive(Log::TRACE)) {
00113       foreach (const Particle& p, _theParticles) {
00114         getLog() << Log::TRACE << "ID: " << p.pdgId()
00115                  << ", barcode: " << p.genParticle().barcode() << endl;
00116       }
00117     }
00118   }
00119 
00120 
00121   /// Constituent pairs
00122   const std::vector<std::pair<Particle, Particle> >& InvMassFinalState::particlePairs() const {
00123     return _particlePairs;
00124   }
00125 
00126 
00127 }