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