00001
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
00018
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
00056
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
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
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 }