rivet is hosted by Hepforge, IPPP Durham
D0_2001_S4674421.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 #include "Rivet/Projections/LeadingParticlesFinalState.hh"
00004 #include "Rivet/Projections/VetoedFinalState.hh"
00005 
00006 namespace Rivet {
00007 
00008 
00009   /// @brief D0 Run I differential W/Z boson cross-section analysis
00010   /// @author Lars Sonnenschein
00011   class D0_2001_S4674421 : public Analysis {
00012   public:
00013 
00014     /// @name Constructors etc.
00015     //@{
00016 
00017     /// Constructor.
00018     D0_2001_S4674421()
00019       : Analysis("D0_2001_S4674421")
00020     {    }
00021 
00022 
00023     /// @name Analysis methods
00024     //@{
00025 
00026     void init() {
00027       // Final state projection
00028       FinalState fs(-5.0, 5.0); // corrected for detector acceptance
00029       addProjection(fs, "FS");
00030 
00031       // Z -> e- e+
00032       LeadingParticlesFinalState eeFS(FinalState(-5.0, 5.0, 0.)); //20.);
00033       eeFS.addParticleIdPair(PID::ELECTRON);
00034       addProjection(eeFS, "eeFS");
00035 
00036       // W- -> e- nu_e~
00037       LeadingParticlesFinalState enuFS(FinalState(-5.0, 5.0, 0.)); //25.);
00038       enuFS.addParticleId(PID::ELECTRON).addParticleId(PID::NU_EBAR);
00039       addProjection(enuFS, "enuFS");
00040 
00041       // W+ -> e+ nu_e
00042       LeadingParticlesFinalState enubFS(FinalState(-5.0, 5.0, 0.)); //25.);
00043       enubFS.addParticleId(PID::POSITRON).addParticleId(PID::NU_E);
00044       addProjection(enubFS, "enubFS");
00045 
00046       // Remove neutrinos for isolation of final state particles
00047       VetoedFinalState vfs(fs);
00048       vfs.vetoNeutrinos();
00049       addProjection(vfs, "VFS");
00050 
00051       // Counters
00052       _eventsFilledW = 0.0;
00053       _eventsFilledZ = 0.0;
00054 
00055       // Histograms
00056       _h_dsigdpt_w = bookHisto1D(1, 1, 1);
00057       _h_dsigdpt_z = bookHisto1D(1, 1, 2);
00058       _h_dsigdpt_scaled_z = bookScatter2D(2, 1, 1);
00059     }
00060 
00061 
00062 
00063     void analyze(const Event& event) {
00064       const double weight = event.weight();
00065 
00066       const LeadingParticlesFinalState& eeFS = applyProjection<LeadingParticlesFinalState>(event, "eeFS");
00067       // Z boson analysis
00068       if (eeFS.particles().size() >= 2) {
00069         // If there is a Z candidate:
00070         // Fill Z pT distributions
00071         double deltaM2=1e30,mass2(0.);
00072         double pT=-1.;
00073         const Particles& Zdaughters = eeFS.particles();
00074         for(unsigned int ix=0;ix<Zdaughters.size();++ix) {
00075           for(unsigned int iy=ix+1;iy<Zdaughters.size();++iy) {
00076             if(Zdaughters[ix].pdgId()!=-Zdaughters[iy].pdgId()) continue;
00077             const FourMomentum pmom = Zdaughters[ix].momentum() + Zdaughters[iy].momentum();
00078             double mz2 = pmom.mass2();
00079             double dm2 = abs(mz2-sqr(91.118*GeV));
00080             if(dm2<deltaM2) {
00081               pT = pmom.pT();
00082               deltaM2 = dm2;
00083               mass2 = mz2;
00084             }
00085           }
00086         }
00087         if (pT>0. && mass2 > 0. && inRange(sqrt(mass2)/GeV, 75.0, 105.0)) {
00088           _eventsFilledZ += weight;
00089           MSG_DEBUG("Z pmom.pT() = " << pT/GeV << " GeV");
00090           _h_dsigdpt_z->fill(pT/GeV, weight);
00091           // return if found a Z
00092           return;
00093         }
00094       }
00095       // There is no Z -> ee candidate... so this might be a W event
00096       const LeadingParticlesFinalState& enuFS = applyProjection<LeadingParticlesFinalState>(event, "enuFS");
00097       const LeadingParticlesFinalState& enubFS = applyProjection<LeadingParticlesFinalState>(event, "enubFS");
00098 
00099       double deltaM2=1e30;
00100       double pT=-1.;
00101       for(unsigned int iw=0;iw<2;++iw) {
00102         Particles Wdaughters;
00103         Wdaughters = iw==0 ? enuFS.particles() : enubFS.particles();
00104         for(unsigned int ix=0;ix<Wdaughters.size();++ix) {
00105           for(unsigned int iy=ix+1;iy<Wdaughters.size();++iy) {
00106             if(Wdaughters[ix].pdgId()==Wdaughters[iy].pdgId())  continue;
00107             const FourMomentum pmom = Wdaughters[0].momentum() + Wdaughters[1].momentum();
00108             double dm2 = abs(pmom.mass2()-sqr(80.4*GeV));
00109             if(dm2<deltaM2) {
00110               pT = pmom.pT();
00111               deltaM2 = dm2;
00112             }
00113           }
00114         }
00115       }
00116       if(pT>0.) {
00117         _eventsFilledW += weight;
00118         _h_dsigdpt_w->fill(pT/GeV, weight);
00119       }
00120     }
00121 
00122 
00123 
00124     void finalize() {
00125       // Get cross-section per event (i.e. per unit weight) from generator
00126       const double xSecPerEvent = crossSectionPerEvent()/picobarn;
00127 
00128       // Correct W pT distribution to W cross-section
00129       const double xSecW = xSecPerEvent * _eventsFilledW;
00130 
00131       // Correct Z pT distribution to Z cross-section
00132       const double xSecZ = xSecPerEvent * _eventsFilledZ;
00133 
00134       // Get W and Z pT integrals
00135       const double wpt_integral = integral(_h_dsigdpt_w);
00136       const double zpt_integral = integral(_h_dsigdpt_z);
00137 
00138       // Divide and scale ratio histos
00139       if (xSecW == 0 || wpt_integral == 0 || xSecZ == 0 || zpt_integral == 0) {
00140         MSG_WARNING("Not filling ratio plot because input histos are empty");
00141       } else {
00142         // Scale factor converts event counts to cross-sections, and inverts the
00143         // branching ratios since only one decay channel has been analysed for each boson.
00144         // Oh, and we put MW/MZ in, like they do in the paper.
00145         const double MW_MZ = 0.8820; // Ratio M_W/M_Z
00146         const double BRZEE_BRWENU = 0.033632 / 0.1073; // Ratio of branching fractions
00147         const double scalefactor = (xSecW / wpt_integral) / (xSecZ / zpt_integral) * MW_MZ * BRZEE_BRWENU;
00148         for (size_t ibin = 0; ibin < _h_dsigdpt_w->numBins(); ibin++) {
00149           const double xval = _h_dsigdpt_w->bin(ibin).midpoint();
00150           const double xerr = _h_dsigdpt_w->bin(ibin).width() / 2.;
00151           double yval(0), yerr(0);
00152           if (_h_dsigdpt_w->bin(ibin).sumW() != 0 && _h_dsigdpt_z->bin(ibin).sumW() != 0) {
00153             yval = scalefactor * _h_dsigdpt_w->bin(ibin).sumW() / _h_dsigdpt_z->bin(ibin).sumW();
00154             yerr = yval * sqrt( sqr(_h_dsigdpt_w->bin(ibin).relErr()) + sqr(_h_dsigdpt_z->bin(ibin).areaErr()) );
00155           }
00156           _h_dsigdpt_scaled_z->addPoint(xval, yval, xerr, yerr);
00157         }
00158       }
00159 
00160       // Normalize non-ratio histos
00161       normalize(_h_dsigdpt_w, xSecW);
00162       normalize(_h_dsigdpt_z, xSecZ);
00163     }
00164 
00165 
00166     //@}
00167 
00168   private:
00169 
00170     /// @name Event counters for cross section normalizations
00171     //@{
00172     double _eventsFilledW;
00173     double _eventsFilledZ;
00174     //@}
00175 
00176     //@{
00177     /// Histograms
00178     Histo1DPtr  _h_dsigdpt_w;
00179     Histo1DPtr  _h_dsigdpt_z;
00180     Scatter2DPtr _h_dsigdpt_scaled_z;
00181     //@}
00182 
00183   };
00184 
00185 
00186 
00187   // The hook for the plugin system
00188   DECLARE_RIVET_PLUGIN(D0_2001_S4674421);
00189 
00190 }