CDF_2008_S7540469.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 #include "Rivet/Projections/FinalState.hh"
00004 #include "Rivet/Projections/IdentifiedFinalState.hh"
00005 #include "Rivet/Projections/VetoedFinalState.hh"
00006 #include "Rivet/Projections/FastJets.hh"
00007 #include "Rivet/RivetAIDA.hh"
00008 #include "Rivet/Tools/Logging.hh"
00009 
00010 namespace Rivet {
00011 
00012 
00013   /// @brief Measurement differential Z/gamma* + jet + X cross sections
00014   /// @author Frank Siegert
00015   class CDF_2008_S7540469 : public Analysis {
00016 
00017   public:
00018 
00019     /// Constructor
00020     CDF_2008_S7540469()
00021       : Analysis("CDF_2008_S7540469")
00022     {
00023       setBeams(PROTON, ANTIPROTON);
00024       setNeedsCrossSection(true);
00025     }
00026 
00027  
00028     /// @name Analysis methods
00029     //@{
00030 
00031     /// Book histograms
00032     void init() {
00033       // Full final state
00034       FinalState fs(-5.0, 5.0);
00035       addProjection(fs, "FS");
00036    
00037       // Leading electrons in tracking acceptance
00038       IdentifiedFinalState elfs(-5.0, 5.0, 25.0*GeV);
00039       elfs.acceptIdPair(ELECTRON);
00040       addProjection(elfs, "LeadingElectrons");
00041 
00042       _h_jet_multiplicity = bookHistogram1D(1, 1, 1);
00043       _h_jet_pT_cross_section_incl_1jet = bookHistogram1D(2, 1, 1);
00044       _h_jet_pT_cross_section_incl_2jet = bookHistogram1D(3, 1, 1);
00045     }
00046  
00047  
00048     /// Do the analysis
00049     void analyze(const Event & event) {
00050       const double weight = event.weight();
00051    
00052       // Skip if the event is empty
00053       const FinalState& fs = applyProjection<FinalState>(event, "FS");
00054       if (fs.empty()) {
00055         getLog() << Log::DEBUG << "Skipping event " << event.genEvent().event_number()
00056                  << " because no final state pair found " << endl;
00057         vetoEvent;
00058       }
00059    
00060       // Find the Z candidates
00061       const FinalState & electronfs = applyProjection<FinalState>(event, "LeadingElectrons");
00062       std::vector<std::pair<Particle, Particle> > Z_candidates;
00063       ParticleVector all_els=electronfs.particles();
00064       for (size_t i=0; i<all_els.size(); ++i) {
00065         for (size_t j=i+1; j<all_els.size(); ++j) {
00066           bool candidate=true;
00067           double mZ=FourMomentum(all_els[i].momentum()+all_els[j].momentum()).mass()/GeV;
00068           if (mZ<66.0 || mZ>116.0) {
00069             candidate=false;
00070           }
00071           double abs_eta_0=fabs(all_els[i].momentum().pseudorapidity());
00072           double abs_eta_1=fabs(all_els[j].momentum().pseudorapidity());
00073           if (abs_eta_1<abs_eta_0) {
00074             double tmp=abs_eta_0;
00075             abs_eta_0=abs_eta_1;
00076             abs_eta_1=tmp;
00077           }
00078           if (abs_eta_0>1.0) {
00079             candidate=false;
00080           }
00081           if (!(abs_eta_1<1.0 || (abs_eta_1>1.2 && abs_eta_1<2.8))) {
00082             candidate=false;
00083           }
00084           if (candidate) {
00085             Z_candidates.push_back(make_pair(all_els[i], all_els[j]));
00086           }
00087         }
00088       }
00089       if (Z_candidates.size() != 1) {
00090         getLog() << Log::DEBUG << "Skipping event " << event.genEvent().event_number()
00091                  << " because no unique electron pair found " << endl;
00092         vetoEvent;
00093       }
00094    
00095       // Now build the jets on a FS without the electrons from the Z
00096       // (including their QED radiation)
00097       ParticleVector jetparts;
00098       foreach (const Particle& p, fs.particles()) {
00099         bool copy = true;
00100         if (p.pdgId() == PHOTON) {
00101           FourMomentum p_e0 = Z_candidates[0].first.momentum();
00102           FourMomentum p_e1 = Z_candidates[0].second.momentum();
00103           FourMomentum p_P = p.momentum();
00104           if (deltaR(p_e0.pseudorapidity(), p_e0.azimuthalAngle(),
00105                      p_P.pseudorapidity(), p_P.azimuthalAngle()) < 0.2) {
00106             copy = false;
00107           }
00108           if (deltaR(p_e1.pseudorapidity(), p_e1.azimuthalAngle(),
00109                      p_P.pseudorapidity(), p_P.azimuthalAngle()) < 0.2) {
00110             copy = false;
00111           }
00112         } else {
00113           if (p.genParticle().barcode()==Z_candidates[0].first.genParticle().barcode()) {
00114             copy = false;
00115           }
00116           if (p.genParticle().barcode()==Z_candidates[0].second.genParticle().barcode()) {
00117             copy = false;
00118           }
00119         }
00120         if (copy) jetparts.push_back(p);
00121       }
00122       /// @todo Allow proj creation w/o FS as ctor arg, so that calc can be used more easily.
00123       FastJets jetpro(fs, FastJets::CDFMIDPOINT, 0.7);
00124       jetpro.calc(jetparts);
00125    
00126       // Take jets with pt > 30, |eta| < 2.1:
00127       /// @todo Make this neater, using the JetAlg interface and the built-in sorting
00128       const Jets& jets = jetpro.jets();
00129       Jets jets_cut;
00130       foreach (const Jet& j, jets) {
00131         if (j.momentum().pT()/GeV > 30.0 && fabs(j.momentum().pseudorapidity()) < 2.1) {
00132           jets_cut.push_back(j);
00133         }
00134       }
00135       getLog() << Log::DEBUG << "Num jets above 30 GeV = " << jets_cut.size() << endl;
00136    
00137       // Return if there are no jets:
00138       if (jets_cut.empty()) {
00139         getLog() << Log::DEBUG << "No jets pass cuts " << endl;
00140         vetoEvent;
00141       }
00142    
00143       // Sort by pT:
00144       sort(jets_cut.begin(), jets_cut.end(), cmpJetsByPt);
00145    
00146       // cut on Delta R between jet and electrons
00147       foreach (const Jet& j, jets_cut) {
00148         Particle el = Z_candidates[0].first;
00149         if (deltaR(el.momentum().pseudorapidity(), el.momentum().azimuthalAngle(),
00150                    j.momentum().pseudorapidity(), j.momentum().azimuthalAngle()) < 0.7) {
00151           vetoEvent;
00152         }
00153         el = Z_candidates[0].second;
00154         if (deltaR(el.momentum().pseudorapidity(), el.momentum().azimuthalAngle(),
00155                    j.momentum().pseudorapidity(), j.momentum().azimuthalAngle()) < 0.7) {
00156           vetoEvent;
00157         }
00158       }
00159    
00160       for (size_t njet=1; njet<=jets_cut.size(); ++njet) {
00161         _h_jet_multiplicity->fill(njet, weight);
00162       }
00163       foreach (const Jet& j, jets_cut) {
00164         if (jets_cut.size()>0) {
00165           _h_jet_pT_cross_section_incl_1jet->fill(j.momentum().pT(), weight);
00166         }
00167         if (jets_cut.size()>1) {
00168           _h_jet_pT_cross_section_incl_2jet->fill(j.momentum().pT(), weight);
00169         }
00170       }
00171     }
00172  
00173  
00174     /// Rescale histos
00175     void finalize() {
00176       const double invlumi = crossSection()/femtobarn/sumOfWeights();
00177       scale(_h_jet_multiplicity, invlumi);
00178       scale(_h_jet_pT_cross_section_incl_1jet, invlumi);
00179       scale(_h_jet_pT_cross_section_incl_2jet, invlumi);
00180     }
00181 
00182     //@}
00183 
00184   private:
00185  
00186     /// @name Histograms
00187     //@{
00188     AIDA::IHistogram1D * _h_jet_multiplicity;
00189     AIDA::IHistogram1D * _h_jet_pT_cross_section_incl_1jet;
00190     AIDA::IHistogram1D * _h_jet_pT_cross_section_incl_2jet;
00191     //@}
00192  
00193   };
00194 
00195 
00196   // This global object acts as a hook for the plugin system
00197   AnalysisBuilder<CDF_2008_S7540469> plugin_CDF_2008_S7540469;
00198 
00199 }