rivet is hosted by Hepforge, IPPP Durham
H1_2000_S4129130.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 #include "Rivet/Math/Constants.hh"
00004 #include "Rivet/Projections/FinalState.hh"
00005 #include "Rivet/Projections/DISKinematics.hh"
00006 
00007 namespace Rivet {
00008 
00009   
00010 
00011 
00012   /// @brief H1 energy flow and charged particle spectra
00013   /// @author Peter Richardson
00014   /// Based on the HZTOOL analysis HZ99091
00015   class H1_2000_S4129130 : public Analysis {
00016   public:
00017 
00018     /// Constructor
00019     H1_2000_S4129130()
00020       : Analysis("H1_2000_S4129130")
00021     {    }
00022 
00023 
00024     /// @name Analysis methods
00025     //@{
00026 
00027     void analyze(const Event& event) {
00028       // Get the projections
00029       const FinalState & fs = applyProjection<FinalState>(event, "FS");
00030       const DISKinematics& dk = applyProjection<DISKinematics>(event, "Kinematics");
00031       const DISLepton    & dl = applyProjection<DISLepton>(event,"Lepton");
00032 
00033       // Get the DIS kinematics
00034       double q2  = dk.Q2();
00035       double x   = dk.x();
00036       double y   = dk.y();
00037       double w2  = dk.W2();
00038 
00039       // Momentum of the scattered lepton
00040       FourMomentum leptonMom = dl.out().momentum();
00041       // pT energy and angle
00042       double enel = leptonMom.E();
00043       double thel = 180 - leptonMom.angle(dl.in().momentum())/degree;
00044 
00045       // Extract the particles other than the lepton
00046       Particles particles;
00047       particles.reserve(fs.particles().size());
00048       const GenParticle* dislepGP = dl.out().genParticle();
00049       foreach (const Particle& p, fs.particles()) {
00050         const GenParticle* loopGP = p.genParticle();
00051         if (loopGP == dislepGP) continue;
00052         particles.push_back(p);
00053       }
00054 
00055       // Cut on the forward energy
00056       double efwd = 0.;
00057       foreach (const Particle& p, particles) {
00058         double th = 180.-p.angle(dl.in().momentum())/degree;
00059         if (th > 4.4 && th < 15.0) efwd += p.E();
00060       }
00061       // There are four possible selections for events
00062       bool evcut[4];
00063       // Low  Q2 selection a
00064       evcut[0] = enel/GeV > 12. && w2 >= 4400.*GeV2 && efwd/GeV > 0.5 && inRange(thel,157.,176.);
00065       // Low  Q2 selection b
00066       evcut[1] = enel/GeV > 12. && inRange(y,0.3,0.5);
00067       // High Q2 selection a
00068       evcut[2] = inRange(thel,12.,150.) && inRange(y,0.05,0.6) && w2 >= 4400.*GeV2 && efwd > 0.5;
00069       // High Q2 selection b
00070       evcut[3] = inRange(thel,12.,150.) && inRange(y,0.05,0.6) && inRange(w2,27110.*GeV2,45182.*GeV2);
00071 
00072       // Veto if fails all cuts
00073       if (! (evcut[0] || evcut[1] || evcut[2] || evcut[3]) ) {
00074         vetoEvent;
00075       }
00076 
00077       // Find the bins
00078       int bin[4] = {-1,-1,-1,-1};
00079       // For the low Q2 selection a)
00080       if (q2 > 2.5*GeV && q2 <= 5.*GeV) {
00081         if (x > 0.00005 && x <= 0.0001 ) bin[0] = 0;
00082         if (x > 0.0001  && x <= 0.0002 ) bin[0] = 1;
00083         if (x > 0.0002  && x <= 0.00035) bin[0] = 2;
00084         if (x > 0.00035 && x <= 0.0010 ) bin[0] = 3;
00085       }
00086       else if (q2 > 5.*GeV && q2 <= 10.*GeV) {
00087         if (x > 0.0001  && x <= 0.0002 ) bin[0] = 4;
00088         if (x > 0.0002  && x <= 0.00035) bin[0] = 5;
00089         if (x > 0.00035 && x <= 0.0007 ) bin[0] = 6;
00090         if (x > 0.0007  && x <= 0.0020 ) bin[0] = 7;
00091       }
00092       else if (q2 > 10.*GeV && q2 <= 20.*GeV) {
00093         if (x > 0.0002 && x <= 0.0005) bin[0] = 8;
00094         if (x > 0.0005 && x <= 0.0008) bin[0] = 9;
00095         if (x > 0.0008 && x <= 0.0015) bin[0] = 10;
00096         if (x > 0.0015 && x <= 0.040 ) bin[0] = 11;
00097       }
00098       else if (q2 > 20.*GeV && q2 <= 50.*GeV) {
00099         if (x > 0.0005 && x <= 0.0014) bin[0] = 12;
00100         if (x > 0.0014 && x <= 0.0030) bin[0] = 13;
00101         if (x > 0.0030 && x <= 0.0100) bin[0] = 14;
00102       }
00103       else if (q2 > 50.*GeV && q2 <= 100.*GeV) {
00104         if (x >0.0008 && x <= 0.0030) bin[0] = 15;
00105         if (x >0.0030 && x <= 0.0200) bin[0] = 16;
00106       }
00107       // check in one of the bins
00108       evcut[0] &= bin[0] >= 0;
00109       // For the low Q2 selection b)
00110       if (q2 > 2.5*GeV && q2 <= 5.  *GeV) bin[1] = 0;
00111       if (q2 > 5. *GeV && q2 <= 10. *GeV) bin[1] = 1;
00112       if (q2 > 10.*GeV && q2 <= 20. *GeV) bin[1] = 2;
00113       if (q2 > 20.*GeV && q2 <= 50. *GeV) bin[1] = 3;
00114       if (q2 > 50.*GeV && q2 <= 100.*GeV) bin[1] = 4;
00115       // check in one of the bins
00116       evcut[1] &= bin[1] >= 0;
00117       // for the high Q2 selection a)
00118       if (q2 > 100.*GeV && q2 <= 400.*GeV) {
00119         if (x > 0.00251 && x <= 0.00631) bin[2] = 0;
00120         if (x > 0.00631 && x <= 0.0158 ) bin[2] = 1;
00121         if (x > 0.0158  && x <= 0.0398 ) bin[2] = 2;
00122       }
00123       else if (q2 > 400.*GeV && q2 <= 1100.*GeV) {
00124         if (x > 0.00631 && x <= 0.0158 ) bin[2] = 3;
00125         if (x > 0.0158  && x <= 0.0398 ) bin[2] = 4;
00126         if (x > 0.0398  && x <= 1.     ) bin[2] = 5;
00127       }
00128       else if (q2 > 1100.*GeV && q2 <= 100000.*GeV) {
00129         if (x > 0. && x <= 1.) bin[2] = 6;
00130       }
00131       // check in one of the bins
00132       evcut[2] &= bin[2] >= 0;
00133       // for the high Q2 selection b)
00134       if      (q2 > 100.*GeV && q2 <= 220.*GeV) bin[3] = 0;
00135       else if (q2 > 220.*GeV && q2 <= 400.*GeV) bin[3] = 1;
00136       else if (q2 > 400.              ) bin[3] = 2;
00137       // check in one of*GeV the bins
00138       evcut[3] &= bin[3] >= 0;
00139 
00140       // Veto if fails all cuts after bin selection
00141       if (! (evcut[0] || evcut[1] || evcut[2] || evcut[3])) {
00142         vetoEvent;
00143       }
00144 
00145       // Increment the count for normalisation
00146       const double weight = event.weight();
00147       if (evcut[0]) _weightETLowQa [bin[0]] += weight;
00148       if (evcut[1]) _weightETLowQb [bin[1]] += weight;
00149       if (evcut[2]) _weightETHighQa[bin[2]] += weight;
00150       if (evcut[3]) _weightETHighQb[bin[3]] += weight;
00151 
00152       // Boost to hadronicCM
00153       const LorentzTransform hcmboost = dk.boostHCM();
00154 
00155       // Loop over the particles
00156       double etcent = 0;
00157       double etfrag = 0;
00158       foreach (const Particle& p, particles) {
00159         // Boost momentum to CMS
00160         const FourMomentum hcmMom = hcmboost.transform(p.momentum());
00161         double et = fabs(hcmMom.Et());
00162         double eta = hcmMom.eta();
00163         // Averages in central and forward region
00164         if (fabs(eta) < .5 ) etcent += et;
00165         if (eta > 2 && eta <= 3.) etfrag += et;
00166         // Histograms of Et flow
00167         if (evcut[0]) _histETLowQa [bin[0]]->fill(eta, et*weight);
00168         if (evcut[1]) _histETLowQb [bin[1]]->fill(eta, et*weight);
00169         if (evcut[2]) _histETHighQa[bin[2]]->fill(eta, et*weight);
00170         if (evcut[3]) _histETHighQb[bin[3]]->fill(eta, et*weight);
00171       }
00172       // Fill histograms for the average quantities
00173       if (evcut[1] || evcut[3]) {
00174         _histAverETCentral->fill(q2, etcent*weight,weight);
00175         _histAverETFrag   ->fill(q2, etfrag*weight,weight);
00176       }
00177     }
00178 
00179 
00180     void init() {
00181       // Projections
00182       addProjection(DISLepton(), "Lepton");
00183       addProjection(DISKinematics(), "Kinematics");
00184       addProjection(FinalState(), "FS");
00185 
00186       // Histos
00187       Histo1DPtr h;
00188 
00189       // Histograms and weight vectors for low Q^2 a
00190       _histETLowQa.reserve(17);
00191       _weightETLowQa.reserve(17);
00192       for (size_t ix = 0; ix < 17; ++ix) {
00193         h = bookHisto1D(ix+1, 1, 1);
00194         _histETLowQa.push_back(h);
00195         _weightETLowQa.push_back(0.);
00196       }
00197 
00198       // Histograms and weight vectors for high Q^2 a
00199       _histETHighQa.reserve(7);
00200       _weightETHighQa.reserve(7);
00201       for (size_t ix = 0; ix < 7; ++ix) {
00202         h = bookHisto1D(ix+18, 1, 1);
00203         _histETHighQa.push_back(h);
00204         _weightETHighQa.push_back(0.);
00205       }
00206 
00207       // Histograms and weight vectors for low Q^2 b
00208       _histETLowQb.reserve(5);
00209       _weightETLowQb.reserve(5);
00210       for (size_t ix = 0; ix < 5; ++ix) {
00211         h = bookHisto1D(ix+25, 1, 1);
00212         _histETLowQb.push_back(h);
00213         _weightETLowQb.push_back(0.);
00214       }
00215 
00216       // Histograms and weight vectors for high Q^2 b
00217       _histETHighQb.reserve(3);
00218       _weightETHighQb.reserve(3);
00219       for (size_t ix = 0; ix < 3; ++ix) {
00220         h = bookHisto1D(30+ix, 1, 1);
00221         _histETHighQb.push_back(h);
00222         _weightETHighQb.push_back(0.0);
00223       }
00224 
00225       // Histograms for the averages
00226       _histAverETCentral = bookProfile1D(33,  1, 1);
00227       _histAverETFrag = bookProfile1D(34,  1, 1);
00228     }
00229 
00230 
00231     // Finalize
00232     void finalize() {
00233       // Normalization of the Et distributions
00234       /// @todo Simplify by using normalize() instead? Are all these being normalized to area=1?
00235       for (size_t ix = 0; ix < 17; ++ix) if (_weightETLowQa[ix]  != 0) scale(_histETLowQa[ix],  1/_weightETLowQa[ix]);
00236       for (size_t ix = 0; ix <  7; ++ix) if (_weightETHighQa[ix] != 0) scale(_histETHighQa[ix], 1/_weightETHighQa[ix]);
00237       for (size_t ix = 0; ix <  5; ++ix) if (_weightETLowQb[ix]  != 0) scale(_histETLowQb[ix],  1/_weightETLowQb[ix]);
00238       for (size_t ix = 0; ix <  3; ++ix) if (_weightETHighQb[ix] != 0) scale(_histETHighQb[ix], 1/_weightETHighQb[ix]);
00239     }
00240 
00241 
00242     //@}
00243 
00244 
00245   private:
00246 
00247     /// @name Histograms
00248     //@{
00249     vector<Histo1DPtr> _histETLowQa;
00250     vector<Histo1DPtr> _histETHighQa;
00251     vector<Histo1DPtr> _histETLowQb;
00252     vector<Histo1DPtr> _histETHighQb;
00253     Profile1DPtr _histAverETCentral;
00254     Profile1DPtr _histAverETFrag;
00255     //@}
00256 
00257     /// @name storage of weights for normalisation
00258     //@{
00259     vector<double> _weightETLowQa;
00260     vector<double> _weightETHighQa;
00261     vector<double> _weightETLowQb;
00262     vector<double> _weightETHighQb;
00263     //@}
00264   };
00265 
00266 
00267 
00268   // The hook for the plugin system
00269   DECLARE_RIVET_PLUGIN(H1_2000_S4129130);
00270 
00271 }