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