rivet is hosted by Hepforge, IPPP Durham
OPAL_1998_S3780481.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 #include "Rivet/Analysis.hh"
00003 #include "Rivet/Projections/Beam.hh"
00004 #include "Rivet/Projections/FinalState.hh"
00005 #include "Rivet/Projections/ChargedFinalState.hh"
00006 #include "Rivet/Projections/InitialQuarks.hh"
00007 
00008 namespace Rivet {
00009 
00010 
00011   /// @brief OPAL flavour-dependent fragmentation paper
00012   /// @author Hendrik Hoeth
00013   class OPAL_1998_S3780481 : public Analysis {
00014   public:
00015 
00016     /// Constructor
00017     OPAL_1998_S3780481() : Analysis("OPAL_1998_S3780481") {
00018       // Counters
00019       _weightedTotalPartNum = 0;
00020       _SumOfudsWeights = 0;
00021       _SumOfcWeights = 0;
00022       _SumOfbWeights = 0;
00023     }
00024 
00025 
00026     /// @name Analysis methods
00027     //@{
00028 
00029     void analyze(const Event& e) {
00030       // First, veto on leptonic events by requiring at least 4 charged FS particles
00031       const FinalState& fs = applyProjection<FinalState>(e, "FS");
00032       const size_t numParticles = fs.particles().size();
00033 
00034       // Even if we only generate hadronic events, we still need a cut on numCharged >= 2.
00035       if (numParticles < 2) {
00036         MSG_DEBUG("Failed ncharged cut");
00037         vetoEvent;
00038       }
00039       MSG_DEBUG("Passed ncharged cut");
00040 
00041       // Get event weight for histo filling
00042       const double weight = e.weight();
00043       _weightedTotalPartNum += numParticles * weight;
00044 
00045       // Get beams and average beam momentum
00046       const ParticlePair& beams = applyProjection<Beam>(e, "Beams").beams();
00047       const double meanBeamMom = ( beams.first.momentum().vector3().mod() +
00048                                    beams.second.momentum().vector3().mod() ) / 2.0;
00049       MSG_DEBUG("Avg beam momentum = " << meanBeamMom);
00050 
00051       int flavour = 0;
00052       const InitialQuarks& iqf = applyProjection<InitialQuarks>(e, "IQF");
00053 
00054       // If we only have two quarks (qqbar), just take the flavour.
00055       // If we have more than two quarks, look for the highest energetic q-qbar pair.
00056       /// @todo Yuck... does this *really* have to be quark-based?!?
00057       if (iqf.particles().size() == 2) {
00058         flavour = abs( iqf.particles().front().pdgId() );
00059       } else {
00060         map<int, double> quarkmap;
00061         foreach (const Particle& p, iqf.particles()) {
00062           if (quarkmap[p.pdgId()] < p.momentum().E()) {
00063             quarkmap[p.pdgId()] = p.momentum().E();
00064           }
00065         }
00066         double maxenergy = 0.;
00067         for (int i = 1; i <= 5; ++i) {
00068           if (quarkmap[i]+quarkmap[-i] > maxenergy) {
00069             flavour = i;
00070           }
00071         }
00072       }
00073 
00074       switch (flavour) {
00075       case 1:
00076       case 2:
00077       case 3:
00078         _SumOfudsWeights += weight;
00079         break;
00080       case 4:
00081         _SumOfcWeights += weight;
00082         break;
00083       case 5:
00084         _SumOfbWeights += weight;
00085         break;
00086       }
00087 
00088       foreach (const Particle& p, fs.particles()) {
00089         const double xp = p.momentum().vector3().mod()/meanBeamMom;
00090         const double logxp = -std::log(xp);
00091         _histXpall->fill(xp, weight);
00092         _histLogXpall->fill(logxp, weight);
00093         _histMultiChargedall->fill(_histMultiChargedall->bin(0).midpoint(), weight);
00094         switch (flavour) {
00095           /// @todo Use PDG code enums
00096         case PID::DQUARK:
00097         case PID::UQUARK:
00098         case PID::SQUARK:
00099           _histXpuds->fill(xp, weight);
00100           _histLogXpuds->fill(logxp, weight);
00101           _histMultiChargeduds->fill(_histMultiChargeduds->bin(0).midpoint(), weight);
00102           break;
00103         case PID::CQUARK:
00104           _histXpc->fill(xp, weight);
00105           _histLogXpc->fill(logxp, weight);
00106           _histMultiChargedc->fill(_histMultiChargedc->bin(0).midpoint(), weight);
00107           break;
00108         case PID::BQUARK:
00109           _histXpb->fill(xp, weight);
00110           _histLogXpb->fill(logxp, weight);
00111           _histMultiChargedb->fill(_histMultiChargedb->bin(0).midpoint(), weight);
00112           break;
00113         }
00114       }
00115 
00116     }
00117 
00118 
00119     void init() {
00120       // Projections
00121       addProjection(Beam(), "Beams");
00122       addProjection(ChargedFinalState(), "FS");
00123       addProjection(InitialQuarks(), "IQF");
00124 
00125       // Book histos
00126       _histXpuds           = bookHisto1D(1, 1, 1);
00127       _histXpc             = bookHisto1D(2, 1, 1);
00128       _histXpb             = bookHisto1D(3, 1, 1);
00129       _histXpall           = bookHisto1D(4, 1, 1);
00130       _histLogXpuds        = bookHisto1D(5, 1, 1);
00131       _histLogXpc          = bookHisto1D(6, 1, 1);
00132       _histLogXpb          = bookHisto1D(7, 1, 1);
00133       _histLogXpall        = bookHisto1D(8, 1, 1);
00134       _histMultiChargeduds = bookHisto1D(9, 1, 1);
00135       _histMultiChargedc   = bookHisto1D(9, 1, 2);
00136       _histMultiChargedb   = bookHisto1D(9, 1, 3);
00137       _histMultiChargedall = bookHisto1D(9, 1, 4);
00138     }
00139 
00140 
00141     /// Finalize
00142     void finalize() {
00143       const double avgNumParts = _weightedTotalPartNum / sumOfWeights();
00144       normalize(_histXpuds    , avgNumParts);
00145       normalize(_histXpc      , avgNumParts);
00146       normalize(_histXpb      , avgNumParts);
00147       normalize(_histXpall    , avgNumParts);
00148       normalize(_histLogXpuds , avgNumParts);
00149       normalize(_histLogXpc   , avgNumParts);
00150       normalize(_histLogXpb   , avgNumParts);
00151       normalize(_histLogXpall , avgNumParts);
00152 
00153       scale(_histMultiChargeduds, 1.0/_SumOfudsWeights);
00154       scale(_histMultiChargedc  , 1.0/_SumOfcWeights);
00155       scale(_histMultiChargedb  , 1.0/_SumOfbWeights);
00156       scale(_histMultiChargedall, 1.0/sumOfWeights());
00157     }
00158 
00159     //@}
00160 
00161 
00162   private:
00163 
00164     /// Store the weighted sums of numbers of charged / charged+neutral
00165     /// particles - used to calculate average number of particles for the
00166     /// inclusive single particle distributions' normalisations.
00167     double _weightedTotalPartNum;
00168 
00169     double _SumOfudsWeights;
00170     double _SumOfcWeights;
00171     double _SumOfbWeights;
00172 
00173     Histo1DPtr _histXpuds;
00174     Histo1DPtr _histXpc;
00175     Histo1DPtr _histXpb;
00176     Histo1DPtr _histXpall;
00177     Histo1DPtr _histLogXpuds;
00178     Histo1DPtr _histLogXpc;
00179     Histo1DPtr _histLogXpb;
00180     Histo1DPtr _histLogXpall;
00181     Histo1DPtr _histMultiChargeduds;
00182     Histo1DPtr _histMultiChargedc;
00183     Histo1DPtr _histMultiChargedb;
00184     Histo1DPtr _histMultiChargedall;
00185 
00186     //@}
00187 
00188   };
00189 
00190 
00191 
00192   // The hook for the plugin system
00193   DECLARE_RIVET_PLUGIN(OPAL_1998_S3780481);
00194 
00195 }