rivet is hosted by Hepforge, IPPP Durham
CDF_2008_S7541902.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/VetoedFinalState.hh"
00005 #include "Rivet/Projections/InvMassFinalState.hh"
00006 #include "Rivet/Projections/FastJets.hh"
00007 #include <algorithm>
00008 
00009 namespace Rivet {
00010 
00011 
00012   /// @brief CDF jet pT and multiplicity distributions in W + jets events
00013   ///
00014   /// This CDF analysis provides jet pT distributions for 4 jet multiplicity bins
00015   /// as well as the jet multiplicity distribution in W + jets events.
00016   /// e-Print: arXiv:0711.4044 [hep-ex]
00017   class CDF_2008_S7541902 : public Analysis {
00018   public:
00019 
00020     /// Constructor
00021     CDF_2008_S7541902()
00022       : Analysis("CDF_2008_S7541902"),
00023         _electronETCut(20.0*GeV), _electronETACut(1.1),
00024         _eTmissCut(30.0*GeV), _mTCut(20.0*GeV),
00025         _jetEtCutA(20.0*GeV),  _jetEtCutB(25.0*GeV), _jetETA(2.0),
00026         _sumW(0)
00027     {    }
00028 
00029 
00030     /// @name Analysis methods
00031     //@{
00032 
00033     void init() {
00034       // Set up projections
00035       // Basic FS
00036       FinalState fs(-3.6, 3.6);
00037       addProjection(fs, "FS");
00038 
00039       // Create a final state with any e-nu pair with invariant mass 65 -> 95 GeV and ET > 20 (W decay products)
00040       vector<pair<PdgId,PdgId> > vids;
00041       vids += make_pair(PID::ELECTRON, PID::NU_EBAR);
00042       vids += make_pair(PID::POSITRON, PID::NU_E);
00043       FinalState fs2(-3.6, 3.6, 20*GeV);
00044       InvMassFinalState invfs(fs2, vids, 65*GeV, 95*GeV);
00045       addProjection(invfs, "INVFS");
00046 
00047       // Make a final state without the W decay products for jet clustering
00048       VetoedFinalState vfs(fs);
00049       vfs.addVetoOnThisFinalState(invfs);
00050       addProjection(vfs, "VFS");
00051       addProjection(FastJets(vfs, FastJets::CDFJETCLU, 0.4), "Jets");
00052 
00053       // Book histograms
00054       for (int i = 0 ; i < 4 ; ++i) {
00055         _histJetEt[i] = bookHisto1D(1+i, 1, 1);
00056         _histJetMultRatio[i] = bookScatter2D(5, 1, i+1, true);
00057         /// @todo These would be better off as YODA::Counter until finalize()
00058         _histJetMult[i] = bookHisto1D(6+i, 1, 1); // _sumW is essentially the 0th "histo" counter
00059       }
00060     }
00061 
00062 
00063     /// Do the analysis
00064     void analyze(const Event& event) {
00065       // Get the W decay products (electron and neutrino)
00066       const InvMassFinalState& invMassFinalState = applyProjection<InvMassFinalState>(event, "INVFS");
00067       const Particles&  wDecayProducts = invMassFinalState.particles();
00068 
00069       FourMomentum electronP, neutrinoP;
00070       bool gotElectron(false), gotNeutrino(false);
00071       foreach (const Particle& p, wDecayProducts) {
00072         FourMomentum p4 = p.momentum();
00073         if (p4.Et() > _electronETCut && fabs(p4.eta()) < _electronETACut && abs(p.pdgId()) == PID::ELECTRON) {
00074           electronP = p4;
00075           gotElectron = true;
00076         }
00077         else if (p4.Et() > _eTmissCut && abs(p.pdgId()) == PID::NU_E) {
00078           neutrinoP = p4;
00079           gotNeutrino = true;
00080         }
00081       }
00082 
00083       // Veto event if the electron or MET cuts fail
00084       if (!gotElectron || !gotNeutrino) vetoEvent;
00085 
00086       // Veto event if the MTR cut fails
00087       double mT2 = 2.0 * ( electronP.pT()*neutrinoP.pT() - electronP.px()*neutrinoP.px() - electronP.py()*neutrinoP.py() );
00088       if (sqrt(mT2) < _mTCut ) vetoEvent;
00089 
00090       // Get the jets
00091       const JetAlg& jetProj = applyProjection<FastJets>(event, "Jets");
00092       Jets theJets = jetProj.jetsByEt(_jetEtCutA);
00093       size_t njetsA(0), njetsB(0);
00094       foreach (const Jet& j, theJets) {
00095         const FourMomentum pj = j.momentum();
00096         if (fabs(pj.rapidity()) < _jetETA) {
00097           // Fill differential histograms for top 4 jets with Et > 20
00098           if (njetsA < 4 && pj.Et() > _jetEtCutA) {
00099             ++njetsA;
00100             _histJetEt[njetsA-1]->fill(pj.Et(), event.weight());
00101           }
00102           // Count number of jets with Et > 25 (for multiplicity histograms)
00103           if (pj.Et() > _jetEtCutB) ++njetsB;
00104         }
00105       }
00106 
00107       // Increment event counter
00108       _sumW += event.weight();
00109 
00110       // Jet multiplicity
00111       for (size_t i = 1; i <= njetsB; ++i) {
00112         /// @todo This isn't really a histogram: replace with a YODA::Counter when we have one!
00113         _histJetMult[i-1]->fill(1960., event.weight());
00114         if (i == 4) break;
00115       }
00116     }
00117 
00118 
00119 
00120     /// Finalize
00121     void finalize() {
00122 
00123       // Fill the 0th ratio histogram specially
00124       /// @todo This special case for 1-to-0 will disappear if we use Counters for all mults including 0.
00125       if (_sumW > 0) {
00126         const YODA::Histo1D::Bin& b0 = _histJetMult[0]->bin(0);
00127         double ratio = b0.area()/_sumW;
00128         double frac_err = 1/_sumW; //< This 1/sqrt{N} error treatment isn't right for weighted events: use YODA::Counter
00129         if (b0.area() > 0) frac_err = sqrt( sqr(frac_err) + sqr(b0.areaErr()/b0.area()) );
00130         _histJetMultRatio[0]->point(0).setY(ratio, ratio*frac_err);
00131       }
00132 
00133       // Loop over the non-zero multiplicities
00134       for (size_t i = 0; i < 3; ++i) {
00135         const YODA::Histo1D::Bin& b1 = _histJetMult[i]->bin(0);
00136         const YODA::Histo1D::Bin& b2 = _histJetMult[i+1]->bin(0);
00137         if (b1.area() == 0.0) continue;
00138         double ratio = b2.area()/b1.area();
00139         double frac_err = b1.areaErr()/b1.area();
00140         if (b2.area() > 0) frac_err = sqrt( sqr(frac_err) + sqr(b2.areaErr()/b2.area()) );
00141         _histJetMultRatio[i+1]->point(0).setY(ratio, ratio*frac_err);
00142       }
00143 
00144       // Normalize the non-ratio histograms
00145       for (size_t i = 0; i < 4; ++i) {
00146         normalize(_histJetEt[i], crossSection()/picobarn);
00147         normalize(_histJetMult[i], crossSection()/picobarn);
00148       }
00149 
00150     }
00151 
00152     //@}
00153 
00154 
00155   private:
00156 
00157     /// @name Cuts
00158     //@{
00159 
00160     /// Cut on the electron ET:
00161     double _electronETCut;
00162     /// Cut on the electron ETA:
00163     double _electronETACut;
00164     /// Cut on the missing ET
00165     double _eTmissCut;
00166     /// Cut on the transverse mass squared
00167     double _mTCut;
00168     /// Cut on the jet ET for differential cross sections
00169     double _jetEtCutA;
00170     /// Cut on the jet ET for jet multiplicity
00171     double _jetEtCutB;
00172     /// Cut on the jet ETA
00173     double _jetETA;
00174 
00175     //@}
00176 
00177     /// @name Histograms
00178     //@{
00179     Histo1DPtr _histJetEt[4];
00180     Histo1DPtr _histJetMultNorm;
00181     Scatter2DPtr _histJetMultRatio[4];
00182     Histo1DPtr _histJetMult[4];
00183     double _sumW;
00184     //@}
00185 
00186   };
00187 
00188 
00189 
00190   // The hook for the plugin system
00191   DECLARE_RIVET_PLUGIN(CDF_2008_S7541902);
00192 
00193 }