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::DEBUG)) {
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         getLog() << Log::TRACE << p.pdgId() << " vs. veto codes = "
00035                  << codestr << " (" << codes.size() << ")" << endl;
00036       }
00037       const long pdgid = p.pdgId();
00038       const double pt = p.momentum().pT();
00039       VetoDetails::iterator iter = _vetoCodes.find(pdgid);
00040       if (iter == _vetoCodes.end()) {
00041         getLog() << Log::TRACE << "Storing with PDG code = " << pdgid << ", pT = " << pt << endl;
00042         _theParticles.push_back(p);
00043       } else {
00044         // This particle code is listed as a possible veto... check pT.
00045         // Make sure that the pT range is sensible:
00046         BinaryCut ptrange = iter->second;
00047         assert(ptrange.first <= ptrange.second);
00048         stringstream rangess;
00049         if (ptrange.first < numeric_limits<double>::max()) rangess << ptrange.second;
00050         rangess << " - ";
00051         if (ptrange.second < numeric_limits<double>::max()) rangess << ptrange.second;
00052         getLog() << Log::TRACE << "ID = " << pdgid << ", pT range = " << rangess.str();
00053         stringstream debugline;
00054         debugline << "with PDG code = " << pdgid << " pT = " << p.momentum().pT();
00055         if (pt < ptrange.first || pt > ptrange.second) {
00056           getLog() << Log::TRACE << "Storing " << debugline.str() << endl;
00057           _theParticles.push_back(p);
00058         } else {
00059           getLog() << Log::TRACE << "Vetoing " << debugline.str() << endl;
00060         }
00061       }
00062     }
00063 
00064     set<ParticleVector::iterator> toErase;
00065     for (set<int>::iterator nIt = _nCompositeDecays.begin();
00066          nIt != _nCompositeDecays.end() && !_theParticles.empty(); ++nIt) {
00067       map<set<ParticleVector::iterator>, FourMomentum> oldMasses;
00068       map<set<ParticleVector::iterator>, FourMomentum> newMasses;
00069       set<ParticleVector::iterator> start;
00070       start.insert(_theParticles.begin());
00071       oldMasses.insert(pair<set<ParticleVector::iterator>, FourMomentum>
00072                        (start, _theParticles.begin()->momentum()));
00073    
00074       for (int nParts = 1; nParts != *nIt; ++nParts) {
00075         for (map<set<ParticleVector::iterator>, FourMomentum>::iterator mIt = oldMasses.begin();
00076              mIt != oldMasses.end(); ++mIt) {
00077           ParticleVector::iterator pStart = *(mIt->first.rbegin());
00078           for (ParticleVector::iterator pIt = pStart + 1; pIt != _theParticles.end(); ++pIt) {
00079             FourMomentum cMom = mIt->second + pIt->momentum();
00080             set<ParticleVector::iterator> pList(mIt->first);
00081             pList.insert(pIt);
00082             newMasses[pList] = cMom;
00083           }
00084         }
00085         oldMasses = newMasses;
00086         newMasses.clear();
00087       }
00088       for (map<set<ParticleVector::iterator>, FourMomentum>::iterator mIt = oldMasses.begin();
00089            mIt != oldMasses.end(); ++mIt) {
00090         double mass2 = mIt->second.mass2();
00091         if (mass2 >= 0.0) {
00092           double mass = sqrt(mass2);
00093           for (CompositeVeto::iterator cIt = _compositeVetoes.lower_bound(*nIt);
00094                cIt != _compositeVetoes.upper_bound(*nIt); ++cIt) {
00095             BinaryCut massRange = cIt->second;
00096             if (mass < massRange.second && mass > massRange.first) {
00097               for (set<ParticleVector::iterator>::iterator lIt = mIt->first.begin();
00098                    lIt != mIt->first.end(); ++lIt) {
00099                 toErase.insert(*lIt);
00100               }
00101             }
00102           }
00103         }
00104       }
00105     }
00106  
00107     for (set<ParticleVector::iterator>::reverse_iterator p = toErase.rbegin(); p != toErase.rend(); ++p) {
00108       _theParticles.erase(*p);
00109     }
00110 
00111     /// @todo Improve!
00112     for (ParentVetos::const_iterator vIt = _parentVetoes.begin(); vIt != _parentVetoes.end(); ++vIt) {
00113       for (ParticleVector::iterator p = _theParticles.begin(); p != _theParticles.end(); ++p) {
00114         GenVertex* startVtx = ((*p).genParticle()).production_vertex();
00115         bool veto = false;
00116         if (startVtx!=0) {
00117           for (GenVertex::particle_iterator pIt = startVtx->particles_begin(HepMC::ancestors);
00118                    pIt != startVtx->particles_end(HepMC::ancestors) && !veto; ++pIt) {
00119             if (*vIt == (*pIt)->pdg_id()) {
00120               veto = true;
00121               p = _theParticles.erase(p);
00122               --p;
00123             }
00124           }
00125         }
00126       }
00127     }
00128     
00129     // Now veto on the FS
00130     foreach (const string& ifs, _vetofsnames) {
00131       const FinalState& vfs = applyProjection<FinalState>(e, ifs);
00132       const ParticleVector& vfsp = vfs.particles();
00133       for (ParticleVector::iterator icheck = _theParticles.begin(); icheck != _theParticles.end(); ++icheck) {
00134         if (!icheck->hasGenParticle()) continue;
00135         bool found = false;
00136         for (ParticleVector::const_iterator ipart = vfsp.begin(); ipart != vfsp.end(); ++ipart){
00137           if (!ipart->hasGenParticle()) continue;
00138           getLog() << Log::TRACE << "Comparing barcode " << icheck->genParticle().barcode() 
00139                    << " with veto particle " << ipart->genParticle().barcode() << endl;
00140           if (ipart->genParticle().barcode() == icheck->genParticle().barcode()){
00141             found = true;
00142             break;
00143           }
00144         }
00145         if (found) {
00146           _theParticles.erase(icheck);
00147           --icheck;
00148         }   
00149       } 
00150     }
00151   }
00152 
00153 
00154 }