rivet is hosted by Hepforge, IPPP Durham
FinalState.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Projections/FinalState.hh"
00003 
00004 namespace Rivet {
00005 
00006 
00007   FinalState::FinalState(double mineta, double maxeta, double minpt)
00008     : _ptmin(minpt)
00009   {
00010     setName("FinalState");
00011     const bool openpt = isZero(minpt);
00012     const bool openeta = (mineta <= -MAXRAPIDITY && maxeta >= MAXRAPIDITY);
00013     MSG_TRACE("Check for open FS conditions:" << std::boolalpha
00014               << " eta=" << openeta
00015               << ", pt=" << openpt);
00016     if (!openeta || !openpt) {
00017       addProjection(FinalState(), "OpenFS");
00018       if (!openeta) {
00019         _etaRanges.push_back(make_pair(mineta, maxeta));
00020       }
00021     }
00022   }
00023 
00024 
00025   FinalState::FinalState(const vector<pair<double, double> >& etaRanges, double minpt)
00026     : _etaRanges(etaRanges), _ptmin(minpt)
00027   {
00028     setName("FinalState");
00029     const bool openpt = isZero(minpt);
00030     /// @todo Properly check whether any of these eta ranges (or their combination) are actually open
00031     const bool openeta = etaRanges.empty();
00032     MSG_TRACE("Check for open FS conditions:" << std::boolalpha
00033               << " eta=" << openeta
00034               << ", pt=" << openpt);
00035     if (!openeta || !openpt) {
00036       addProjection(FinalState(), "OpenFS");
00037     }
00038   }
00039 
00040 
00041 
00042   int FinalState::compare(const Projection& p) const {
00043     const FinalState& other = dynamic_cast<const FinalState&>(p);
00044 
00045     //MSG_TRACE("FS::compare: " << 1 << " " << this << " " << &p);
00046     std::vector<std::pair<double, double> > eta1(_etaRanges);
00047     std::vector<std::pair<double, double> > eta2(other._etaRanges);
00048     std::sort(eta1.begin(), eta1.end());
00049     std::sort(eta2.begin(), eta2.end());
00050 
00051     //MSG_TRACE("FS::compare: " << 2 << " " << this << " " << &p);
00052     if (eta1 < eta2) return ORDERED;
00053     else if (eta2 < eta1) return UNORDERED;
00054 
00055     //MSG_TRACE("FS::compare: " << 3 << " " << this << " " << &p);
00056     return cmp(_ptmin, other._ptmin);
00057   }
00058 
00059 
00060 
00061   void FinalState::project(const Event& e) {
00062     _theParticles.clear();
00063 
00064     // Handle "open FS" special case
00065     if (_etaRanges.empty() && _ptmin == 0) {
00066       //MSG_TRACE("Open FS processing: should only see this once per event ("
00067       //           << e.genEvent().event_number() << ")");
00068       foreach (const GenParticle* p, Rivet::particles(e.genEvent())) {
00069         if (p->status() == 1) {
00070           //MSG_TRACE("FS GV = " << p->production_vertex());
00071           _theParticles.push_back(Particle(*p));
00072         }
00073       }
00074       return;
00075     }
00076 
00077     // If this is not itself the "open" FS, base the calculations on the open FS' results
00078     /// @todo In general, we'd like to calculate a restrictive FS based on the most restricted superset FS.
00079     const Particles allstable = applyProjection<FinalState>(e, "OpenFS").particles();
00080     foreach (const Particle& p, allstable) {
00081       const bool passed = accept(p);
00082       MSG_TRACE("Choosing: ID = " << p.pdgId()
00083                 << ", pT = " << p.pT()
00084                 << ", eta = " << p.eta()
00085                 << ": result = " << std::boolalpha << passed);
00086       if (passed) _theParticles.push_back(p);
00087     }
00088     //MSG_DEBUG("Number of final-state particles = " << _theParticles.size());
00089   }
00090 
00091 
00092   /// Decide if a particle is to be accepted or not.
00093   bool FinalState::accept(const Particle& p) const {
00094     // Not having s.c. == 1 should never happen!
00095     assert(p.genParticle() == NULL || p.genParticle()->status() == 1);
00096 
00097     // Check pT cut
00098     if (_ptmin > 0.0) {
00099       if (p.pT() < _ptmin) return false;
00100     }
00101 
00102     // Check eta cuts
00103     if (!_etaRanges.empty()) {
00104       bool eta_pass = false;
00105       typedef pair<double,double> EtaPair;
00106       foreach (const EtaPair& etacuts, _etaRanges) {
00107         if (inRange(p.eta(), etacuts.first, etacuts.second)) {
00108           eta_pass = true;
00109           break;
00110         }
00111       }
00112       if (!eta_pass) return false;
00113     }
00114 
00115     return true;
00116   }
00117 
00118 
00119 }