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 #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     MSG_TRACE("Check for open FS conditions:" << std::boolalpha
00016               << " eta=" << openeta
00017               << ", pt=" << openpt);
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     MSG_TRACE("Check for open FS conditions:" << std::boolalpha
00035               << " eta=" << openeta
00036               << ", pt=" << openpt);
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     //MSG_TRACE("FS::compare: " << 1 << " " << this << " " << &p);
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     //MSG_TRACE("FS::compare: " << 2 << " " << this << " " << &p);
00054     if (eta1 < eta2) return ORDERED;
00055     else if (eta2 < eta1) return UNORDERED;
00056 
00057     //MSG_TRACE("FS::compare: " << 3 << " " << this << " " << &p);
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       //MSG_TRACE("Open FS processing: should only see this once per event ("
00069       //           << e.genEvent().event_number() << ")");
00070       foreach (const GenParticle* p, Rivet::particles(e.genEvent())) {
00071         if (p->status() == 1) {
00072           //MSG_TRACE("FS GV = " << p->production_vertex());
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       // MSG_TRACE("Choosing: ID = " << p.pdgId()
00085       //           << ", pT = " << p.momentum().pT()
00086       //           << ", eta = " << p.momentum().eta()
00087       //           << ": result = " << std::boolalpha << passed);
00088       if (passed) _theParticles.push_back(p);
00089     }
00090     //MSG_DEBUG("Number of final-state particles = " << _theParticles.size());
00091   }
00092 
00093 
00094   /// Decide if a particle is to be accepted or not.
00095   bool FinalState::accept(const Particle& p) const {
00096     // Not having s.c. == 1 should never happen!
00097     assert(!p.hasGenParticle() || p.genParticle().status() == 1);
00098 
00099     // Check pT cut
00100     if (_ptmin > 0.0) {
00101       const double pT = p.momentum().pT();
00102       if (pT < _ptmin) return false;
00103     }
00104 
00105     // Check eta cuts
00106     if (!_etaRanges.empty()) {
00107       bool eta_pass = false;
00108       const double eta = p.momentum().eta();
00109       typedef pair<double,double> EtaPair;
00110       foreach (const EtaPair& etacuts, _etaRanges) {
00111         if (eta > etacuts.first && eta < etacuts.second) {
00112           eta_pass = true;
00113           break;
00114         }
00115       }
00116       if (!eta_pass) return false;
00117     }
00118 
00119     return true;
00120   }
00121 
00122 
00123 }