00001
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
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
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
00054 if (eta1 < eta2) return ORDERED;
00055 else if (eta2 < eta1) return UNORDERED;
00056
00057
00058 return cmp(_ptmin, other._ptmin);
00059 }
00060
00061
00062
00063 void FinalState::project(const Event& e) {
00064 _theParticles.clear();
00065
00066
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
00073 _theParticles.push_back(Particle(*p));
00074 }
00075 }
00076 return;
00077 }
00078
00079
00080
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
00099 bool FinalState::accept(const Particle& p) const {
00100
00101 assert(p.genParticle().status() == 1);
00102
00103
00104 if (_ptmin > 0.0) {
00105 const double pT = p.momentum().pT();
00106 if (pT < _ptmin) return false;
00107 }
00108
00109
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 }