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