FinalState.cc

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