rivet is hosted by Hepforge, IPPP Durham
VetoedFinalState.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Rivet.hh"
00003 #include "Rivet/Projections/VetoedFinalState.hh"
00004 #include "Rivet/Cmp.hh"
00005 #include "Rivet/Tools/Utils.hh"
00006 #include <algorithm>
00007 
00008 namespace Rivet {
00009 
00010 
00011   int VetoedFinalState::compare(const Projection& p) const {
00012     const PCmp fscmp = mkNamedPCmp(p, "FS");
00013     if (fscmp != EQUIVALENT) return fscmp;
00014     if (_vetofsnames.size() != 0) return UNDEFINED;
00015     const VetoedFinalState& other = dynamic_cast<const VetoedFinalState&>(p);
00016     return \
00017       cmp(_vetoCodes, other._vetoCodes) ||
00018       cmp(_compositeVetoes, other._compositeVetoes) ||
00019       cmp(_parentVetoes, other._parentVetoes);
00020   }
00021 
00022 
00023   void VetoedFinalState::project(const Event& e) {
00024     const FinalState& fs = applyProjection<FinalState>(e, "FS");
00025     _theParticles.clear();
00026     _theParticles.reserve(fs.particles().size());
00027     foreach (const Particle& p, fs.particles()) {
00028       if (getLog().isActive(Log::TRACE)) {
00029         vector<long> codes;
00030         for (VetoDetails::const_iterator code = _vetoCodes.begin(); code != _vetoCodes.end(); ++code) {
00031           codes.push_back(code->first);
00032         }
00033         const string codestr = "{ " + join(codes) + " }";
00034         MSG_TRACE(p.pdgId() << " vs. veto codes = " << codestr << " (" << codes.size() << ")");
00035       }
00036       const long pdgid = p.pdgId();
00037       const double pt = p.momentum().pT();
00038       VetoDetails::iterator iter = _vetoCodes.find(pdgid);
00039       if (iter == _vetoCodes.end()) {
00040         MSG_TRACE("Storing with PDG code = " << pdgid << ", pT = " << pt);
00041         _theParticles.push_back(p);
00042       } else {
00043         // This particle code is listed as a possible veto... check pT.
00044         // Make sure that the pT range is sensible:
00045         BinaryCut ptrange = iter->second;
00046         assert(ptrange.first <= ptrange.second);
00047         stringstream rangess;
00048         if (ptrange.first < numeric_limits<double>::max()) rangess << ptrange.second;
00049         rangess << " - ";
00050         if (ptrange.second < numeric_limits<double>::max()) rangess << ptrange.second;
00051         MSG_TRACE("ID = " << pdgid << ", pT range = " << rangess.str());
00052         stringstream debugline;
00053         debugline << "with PDG code = " << pdgid << " pT = " << p.momentum().pT();
00054         if (pt < ptrange.first || pt > ptrange.second) {
00055           MSG_TRACE("Storing " << debugline.str());
00056           _theParticles.push_back(p);
00057         } else {
00058           MSG_TRACE("Vetoing " << debugline.str());
00059         }
00060       }
00061     }
00062 
00063     set<ParticleVector::iterator> toErase;
00064     for (set<int>::iterator nIt = _nCompositeDecays.begin();
00065          nIt != _nCompositeDecays.end() && !_theParticles.empty(); ++nIt) {
00066       map<set<ParticleVector::iterator>, FourMomentum> oldMasses;
00067       map<set<ParticleVector::iterator>, FourMomentum> newMasses;
00068       set<ParticleVector::iterator> start;
00069       start.insert(_theParticles.begin());
00070       oldMasses.insert(pair<set<ParticleVector::iterator>, FourMomentum>
00071                        (start, _theParticles.begin()->momentum()));
00072 
00073       for (int nParts = 1; nParts != *nIt; ++nParts) {
00074         for (map<set<ParticleVector::iterator>, FourMomentum>::iterator mIt = oldMasses.begin();
00075              mIt != oldMasses.end(); ++mIt) {
00076           ParticleVector::iterator pStart = *(mIt->first.rbegin());
00077           for (ParticleVector::iterator pIt = pStart + 1; pIt != _theParticles.end(); ++pIt) {
00078             FourMomentum cMom = mIt->second + pIt->momentum();
00079             set<ParticleVector::iterator> pList(mIt->first);
00080             pList.insert(pIt);
00081             newMasses[pList] = cMom;
00082           }
00083         }
00084         oldMasses = newMasses;
00085         newMasses.clear();
00086       }
00087       for (map<set<ParticleVector::iterator>, FourMomentum>::iterator mIt = oldMasses.begin();
00088            mIt != oldMasses.end(); ++mIt) {
00089         double mass2 = mIt->second.mass2();
00090         if (mass2 >= 0.0) {
00091           double mass = sqrt(mass2);
00092           for (CompositeVeto::iterator cIt = _compositeVetoes.lower_bound(*nIt);
00093                cIt != _compositeVetoes.upper_bound(*nIt); ++cIt) {
00094             BinaryCut massRange = cIt->second;
00095             if (mass < massRange.second && mass > massRange.first) {
00096               for (set<ParticleVector::iterator>::iterator lIt = mIt->first.begin();
00097                    lIt != mIt->first.end(); ++lIt) {
00098                 toErase.insert(*lIt);
00099               }
00100             }
00101           }
00102         }
00103       }
00104     }
00105 
00106     for (set<ParticleVector::iterator>::reverse_iterator p = toErase.rbegin(); p != toErase.rend(); ++p) {
00107       _theParticles.erase(*p);
00108     }
00109 
00110     /// @todo Improve!
00111     for (ParentVetos::const_iterator vIt = _parentVetoes.begin(); vIt != _parentVetoes.end(); ++vIt) {
00112       for (ParticleVector::iterator p = _theParticles.begin(); p != _theParticles.end(); ++p) {
00113         GenVertex* startVtx = ((*p).genParticle()).production_vertex();
00114         bool veto = false;
00115         if (startVtx!=0) {
00116           for (GenVertex::particle_iterator pIt = startVtx->particles_begin(HepMC::ancestors);
00117                    pIt != startVtx->particles_end(HepMC::ancestors) && !veto; ++pIt) {
00118             if (*vIt == (*pIt)->pdg_id()) {
00119               veto = true;
00120               p = _theParticles.erase(p);
00121               --p;
00122             }
00123           }
00124         }
00125       }
00126     }
00127 
00128     // Now veto on the FS
00129     foreach (const string& ifs, _vetofsnames) {
00130       const FinalState& vfs = applyProjection<FinalState>(e, ifs);
00131       const ParticleVector& vfsp = vfs.particles();
00132       for (ParticleVector::iterator icheck = _theParticles.begin(); icheck != _theParticles.end(); ++icheck) {
00133         if (!icheck->hasGenParticle()) continue;
00134         bool found = false;
00135         for (ParticleVector::const_iterator ipart = vfsp.begin(); ipart != vfsp.end(); ++ipart){
00136           if (!ipart->hasGenParticle()) continue;
00137           MSG_TRACE("Comparing barcode " << icheck->genParticle().barcode()
00138                    << " with veto particle " << ipart->genParticle().barcode());
00139           if (ipart->genParticle().barcode() == icheck->genParticle().barcode()){
00140             found = true;
00141             break;
00142           }
00143         }
00144         if (found) {
00145           _theParticles.erase(icheck);
00146           --icheck;
00147         }
00148       }
00149     }
00150   }
00151 
00152 
00153 }