rivet is hosted by Hepforge, IPPP Durham
ARGUS_1993_S2669951.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include <iostream>
00003 #include "Rivet/Analysis.hh"
00004 #include "Rivet/Projections/Beam.hh"
00005 #include "Rivet/Projections/UnstableFinalState.hh"
00006 #include "Rivet/ParticleName.hh"
00007 
00008 namespace Rivet {
00009 
00010 
00011   /// @brief Production of the $\eta'(958)$ and $f_0(980)$ in $e^+e^-$ annihilation in the Upsilon region
00012   /// @author Peter Richardson
00013   class ARGUS_1993_S2669951 : public Analysis {
00014   public:
00015 
00016     ARGUS_1993_S2669951()
00017       : Analysis("ARGUS_1993_S2669951"),
00018         _count_etaPrime_highZ(2, 0.), _count_etaPrime_allZ(3, 0.), _count_f0(3, 0.),
00019         _weightSum_cont(0.), _weightSum_Ups1(0.), _weightSum_Ups2(0.)
00020     {   }
00021 
00022 
00023     void init() {
00024       addProjection(Beam(), "Beams");
00025       addProjection(UnstableFinalState(), "UFS");
00026 
00027       _hist_cont_f0 = bookHisto1D(2, 1, 1);
00028       _hist_Ups1_f0 = bookHisto1D(3, 1, 1);
00029       _hist_Ups2_f0 = bookHisto1D(4, 1, 1);
00030     }
00031 
00032 
00033     void analyze(const Event& e) {
00034       const double weight = e.weight();
00035 
00036       const Beam beamproj = applyProjection<Beam>(e, "Beams");
00037       const double s = sqr(beamproj.sqrtS());
00038       const double roots = sqrt(s);
00039       const UnstableFinalState& ufs = applyProjection<UnstableFinalState>(e, "UFS");
00040 
00041       // Find the upsilons
00042       Particles upsilons;
00043       // First in unstable final state
00044       foreach (const Particle& p, ufs.particles())
00045         if (p.pdgId() == 553 || p.pdgId() == 100553 ) upsilons.push_back(p);
00046       // Then in whole event if fails
00047       if (upsilons.empty()) {
00048         foreach (GenParticle* p, Rivet::particles(e.genEvent())) {
00049           if ( p->pdg_id() != 553 && p->pdg_id() != 100553 ) continue;
00050           const GenVertex* pv = p->production_vertex();
00051           bool passed = true;
00052           if (pv) {
00053             for (GenVertex::particles_in_const_iterator pp = pv->particles_in_const_begin(); pp != pv->particles_in_const_end() ; ++pp) {
00054               if ( p->pdg_id() == (*pp)->pdg_id() ) {
00055                 passed = false;
00056                 break;
00057               }
00058             }
00059           }
00060           if (passed) upsilons.push_back(Particle(*p));
00061         }
00062       }
00063       // Continuum
00064       if (upsilons.empty()) {
00065         _weightSum_cont += weight;
00066         unsigned int nEtaA(0),nEtaB(0),nf0(0);
00067         foreach (const Particle& p, ufs.particles()) {
00068           int id = abs(p.pdgId());
00069           double xp = 2.*p.momentum().t()/roots;
00070           double beta = p.momentum().vector3().mod() / p.momentum().t();
00071           if (id == 9010221) {
00072             _hist_cont_f0->fill(xp, weight/beta);
00073             ++nf0;
00074           } else if (id == 331) {
00075             if (xp > 0.35) ++nEtaA;
00076             ++nEtaB;
00077           }
00078         }
00079         _count_f0[2]             += nf0*weight;
00080         _count_etaPrime_highZ[1] += nEtaA*weight;
00081         _count_etaPrime_allZ[2]  += nEtaB*weight;
00082       }
00083       else {
00084         // Find an Upsilon
00085         foreach (const Particle& ups, upsilons) {
00086           int parentId = ups.pdgId();
00087           ((parentId == 553) ? _weightSum_Ups1 : _weightSum_Ups2) += weight;
00088           Particles unstable;
00089           // Find the decay products we want
00090           findDecayProducts(ups.genParticle(), unstable);
00091           LorentzTransform cms_boost;
00092           if (ups.momentum().vector3().mod() > 1*MeV)
00093             cms_boost = LorentzTransform(-ups.momentum().boostVector());
00094           double mass = ups.momentum().mass();
00095           unsigned int nEtaA(0), nEtaB(0), nf0(0);
00096           foreach(const Particle& p , unstable) {
00097             const int id = abs(p.pdgId());
00098             FourMomentum p2 = cms_boost.transform(p.momentum());
00099             double xp = 2.*p2.t()/mass;
00100             double beta = p2.vector3().mod()/p2.t();
00101             if (id == 9010221) {
00102               ((parentId == 553) ? _hist_Ups1_f0 : _hist_Ups2_f0)->fill(xp, weight/beta);
00103               ++nf0;
00104             } else if (id == 331) {
00105               if (xp > 0.35) ++nEtaA;
00106               ++nEtaB;
00107             }
00108           }
00109           if (parentId == 553) {
00110             _count_f0[0]             +=   nf0*weight;
00111             _count_etaPrime_highZ[0] += nEtaA*weight;
00112             _count_etaPrime_allZ[0]  += nEtaB*weight;
00113           } else {
00114             _count_f0[1] += nf0*weight;
00115             _count_etaPrime_allZ[1]  += nEtaB*weight;
00116           }
00117         }
00118       }
00119     }
00120 
00121 
00122     void finalize() {
00123 
00124       /// @todo Better to group these by coherent 'if (weightSum_X)' statements?
00125 
00126       // High-Z eta' multiplicity
00127       Scatter2DPtr s111 = bookScatter2D(1, 1, 1, true);
00128       if (_weightSum_Ups1 > 0) // Point at 9.460
00129         s111->point(0).setY(_count_etaPrime_highZ[0] / _weightSum_Ups1, 0);
00130       if (_weightSum_cont > 0) // Point at 9.905
00131         s111->point(1).setY(_count_etaPrime_highZ[1] / _weightSum_cont, 0);
00132 
00133 
00134       // All-Z eta' multiplicity
00135       Scatter2DPtr s112 = bookScatter2D(1, 1, 2, true);
00136       if (_weightSum_Ups1 > 0) // Point at 9.460
00137         s112->point(0).setY(_count_etaPrime_allZ[0] / _weightSum_Ups1, 0);
00138       if (_weightSum_cont > 0) // Point at 9.905
00139         s112->point(1).setY(_count_etaPrime_allZ[2] / _weightSum_cont, 0);
00140       if (_weightSum_Ups2 > 0) // Point at 10.02
00141         s112->point(2).setY(_count_etaPrime_allZ[1] / _weightSum_Ups2, 0);
00142 
00143       // f0 multiplicity
00144       Scatter2DPtr s511 = bookScatter2D(5, 1, 1, true);
00145       if (_weightSum_Ups1 > 0) // Point at 9.46
00146         s112->point(0).setY(_count_f0[0] / _weightSum_Ups1, 0);
00147       if (_weightSum_Ups2 > 0) // Point at 10.02
00148         s112->point(1).setY(_count_f0[1] / _weightSum_Ups2, 0);
00149       if (_weightSum_cont > 0) // Point at 10.45
00150         s112->point(2).setY(_count_f0[2] / _weightSum_cont, 0);
00151 
00152       if (_weightSum_cont > 0.) scale(_hist_cont_f0, 1./_weightSum_cont);
00153       if (_weightSum_Ups1 > 0.) scale(_hist_Ups1_f0, 1./_weightSum_Ups1);
00154       if (_weightSum_Ups2 > 0.) scale(_hist_Ups2_f0, 1./_weightSum_Ups2);
00155     }
00156 
00157 
00158   private:
00159 
00160     /// @name Counters
00161     //@{
00162     vector<double> _count_etaPrime_highZ, _count_etaPrime_allZ, _count_f0;
00163     double _weightSum_cont,_weightSum_Ups1,_weightSum_Ups2;
00164     //@}
00165 
00166 
00167     /// Histos
00168     Histo1DPtr _hist_cont_f0, _hist_Ups1_f0, _hist_Ups2_f0;
00169 
00170 
00171     /// Recursively walk the HepMC tree to find decay products of @a p
00172     void findDecayProducts(const GenParticle* p, Particles& unstable) {
00173       const GenVertex* dv = p->end_vertex();
00174       /// @todo Use better looping
00175       for (GenVertex::particles_out_const_iterator pp = dv->particles_out_const_begin(); pp != dv->particles_out_const_end(); ++pp) {
00176         const int id = abs((*pp)->pdg_id());
00177         if (id == 331 || id == 9010221) unstable.push_back(Particle(*pp));
00178         else if ((*pp)->end_vertex()) findDecayProducts(*pp, unstable);
00179       }
00180     }
00181 
00182 
00183   };
00184 
00185 
00186   // The hook for the plugin system
00187   DECLARE_RIVET_PLUGIN(ARGUS_1993_S2669951);
00188 
00189 }