H1_2000_S4129130.cc

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