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     /// @todo We can do better than this...
00011     if (_vetofsnames.size() != 0) return UNDEFINED;
00012     const VetoedFinalState& other = dynamic_cast<const VetoedFinalState&>(p);
00013     return \
00014       cmp(_vetoCodes, other._vetoCodes) ||
00015       cmp(_compositeVetoes, other._compositeVetoes) ||
00016       cmp(_parentVetoes, other._parentVetoes);
00017   }
00018 
00019 
00020   void VetoedFinalState::project(const Event& e) {
00021     const FinalState& fs = applyProjection<FinalState>(e, "FS");
00022     _theParticles.clear();
00023     _theParticles.reserve(fs.particles().size());
00024     foreach (const Particle& p, fs.particles()) {
00025       if (getLog().isActive(Log::TRACE)) {
00026         vector<long> codes;
00027         for (VetoDetails::const_iterator code = _vetoCodes.begin(); code != _vetoCodes.end(); ++code) {
00028           codes.push_back(code->first);
00029         }
00030         const string codestr = "{ " + join(codes) + " }";
00031         MSG_TRACE(p.pid() << " vs. veto codes = " << codestr << " (" << codes.size() << ")");
00032       }
00033       VetoDetails::iterator iter = _vetoCodes.find(p.pid());
00034       if (iter == _vetoCodes.end()) {
00035         MSG_TRACE("Storing with PDG code = " << p.pid() << ", pT = " << p.pT());
00036         _theParticles.push_back(p);
00037       } else {
00038         // This particle code is listed as a possible veto... check pT.
00039         // Make sure that the pT range is sensible:
00040         BinaryCut ptrange = iter->second;
00041         assert(ptrange.first <= ptrange.second);
00042         stringstream rangess;
00043         if (ptrange.first < numeric_limits<double>::max()) rangess << ptrange.second;
00044         rangess << " - ";
00045         if (ptrange.second < numeric_limits<double>::max()) rangess << ptrange.second;
00046         MSG_TRACE("ID = " << p.pid() << ", pT range = " << rangess.str());
00047         stringstream debugline;
00048         debugline << "with PDG code = " << p.pid() << " pT = " << p.pT();
00049         if (p.pT() < ptrange.first || p.pT() > ptrange.second) {
00050           MSG_TRACE("Storing " << debugline.str());
00051           _theParticles.push_back(p);
00052         } else {
00053           MSG_TRACE("Vetoing " << debugline.str());
00054         }
00055       }
00056     }
00057 
00058     set<Particles::iterator> toErase;
00059     for (set<int>::iterator nIt = _nCompositeDecays.begin();
00060          nIt != _nCompositeDecays.end() && !_theParticles.empty(); ++nIt) {
00061       map<set<Particles::iterator>, FourMomentum> oldMasses;
00062       map<set<Particles::iterator>, FourMomentum> newMasses;
00063       set<Particles::iterator> start;
00064       start.insert(_theParticles.begin());
00065       oldMasses.insert(pair<set<Particles::iterator>, FourMomentum>
00066                        (start, _theParticles.begin()->momentum()));
00067 
00068       for (int nParts = 1; nParts != *nIt; ++nParts) {
00069         for (map<set<Particles::iterator>, FourMomentum>::iterator mIt = oldMasses.begin();
00070              mIt != oldMasses.end(); ++mIt) {
00071           Particles::iterator pStart = *(mIt->first.rbegin());
00072           for (Particles::iterator pIt = pStart + 1; pIt != _theParticles.end(); ++pIt) {
00073             FourMomentum cMom = mIt->second + pIt->momentum();
00074             set<Particles::iterator> pList(mIt->first);
00075             pList.insert(pIt);
00076             newMasses[pList] = cMom;
00077           }
00078         }
00079         oldMasses = newMasses;
00080         newMasses.clear();
00081       }
00082       for (map<set<Particles::iterator>, FourMomentum>::iterator mIt = oldMasses.begin();
00083            mIt != oldMasses.end(); ++mIt) {
00084         double mass2 = mIt->second.mass2();
00085         if (mass2 >= 0.0) {
00086           double mass = sqrt(mass2);
00087           for (CompositeVeto::iterator cIt = _compositeVetoes.lower_bound(*nIt);
00088                cIt != _compositeVetoes.upper_bound(*nIt); ++cIt) {
00089             BinaryCut massRange = cIt->second;
00090             if (mass < massRange.second && mass > massRange.first) {
00091               for (set<Particles::iterator>::iterator lIt = mIt->first.begin();
00092                    lIt != mIt->first.end(); ++lIt) {
00093                 toErase.insert(*lIt);
00094               }
00095             }
00096           }
00097         }
00098       }
00099     }
00100 
00101     for (set<Particles::iterator>::reverse_iterator p = toErase.rbegin(); p != toErase.rend(); ++p) {
00102       _theParticles.erase(*p);
00103     }
00104 
00105     // Remove particles whose parents match entries in the parent veto PDG ID codes list
00106     /// @todo There must be a nice way to do this -- an STL algorithm (or we provide a nicer wrapper)
00107     foreach (PdgId vetoid, _parentVetoes) {
00108       for (Particles::iterator ip = _theParticles.begin(); ip != _theParticles.end(); ++ip) {
00109         const GenVertex* startVtx = ip->genParticle()->production_vertex();
00110         if (startVtx == NULL) continue;
00111         // Loop over parents and test their IDs
00112         /// @todo Could use any() here?
00113         foreach (const GenParticle* parent, Rivet::particles(startVtx, HepMC::ancestors)) {
00114           if (vetoid == parent->pdg_id()) {
00115             ip = _theParticles.erase(ip); --ip; //< Erase this _theParticles entry
00116             break;
00117           }
00118         }
00119       }
00120     }
00121 
00122     // Now veto on the FS
00123     foreach (const string& ifs, _vetofsnames) {
00124       const FinalState& vfs = applyProjection<FinalState>(e, ifs);
00125       const Particles& vfsp = vfs.particles();
00126       for (Particles::iterator icheck = _theParticles.begin(); icheck != _theParticles.end(); ++icheck) {
00127         if (icheck->genParticle() == NULL) continue;
00128         bool found = false;
00129         for (Particles::const_iterator ipart = vfsp.begin(); ipart != vfsp.end(); ++ipart){
00130           if (ipart->genParticle() == NULL) continue;
00131           MSG_TRACE("Comparing barcode " << icheck->genParticle()->barcode()
00132                    << " with veto particle " << ipart->genParticle()->barcode());
00133           if (ipart->genParticle()->barcode() == icheck->genParticle()->barcode()){
00134             found = true;
00135             break;
00136           }
00137         }
00138         if (found) {
00139           _theParticles.erase(icheck);
00140           --icheck;
00141         }
00142       }
00143     }
00144   }
00145 
00146 
00147 }