Rivet analyses

Measurements of flavor dependent fragmentation functions in Z0− > q events

Experiment: OPAL (LEP 1)

Inspire ID: 472637

Status: VALIDATED

Authors: - Hendrik Hoeth

References: - Eur. Phys. J, C7, 369–381 (1999) - hep-ex/9807004

Beams: e+ e-

Beam energies: (45.6, 45.6)GeV

Run details: - Hadronic Z decay events generated on the Z pole ($\sqrt{s} = 91.2$ GeV)

Measurement of scaled momentum distributions and total charged multiplicities in flavour tagged events at LEP 1. OPAL measured these observables in uds-, c-, and b-events separately. An inclusive measurement is also included.

Source code:OPAL_1998_I472637.cc

// -*- C++ -*-
#include "Rivet/Analysis.hh"
#include "Rivet/Projections/Beam.hh"
#include "Rivet/Projections/ChargedFinalState.hh"
#include "Rivet/Projections/FinalState.hh"

#define I_KNOW_THE_INITIAL_QUARKS_PROJECTION_IS_DODGY_BUT_NEED_TO_USE_IT
#include "Rivet/Projections/InitialQuarks.hh"

namespace Rivet {


  /// @brief OPAL flavour-dependent fragmentation paper
  ///
  /// @author Hendrik Hoeth
  class OPAL_1998_I472637 : public Analysis {
  public:

    RIVET_DEFAULT_ANALYSIS_CTOR(OPAL_1998_I472637);


    /// @name Analysis methods
    /// @{

    void analyze(const Event& e) {
      // First, veto on leptonic events by requiring at least 4 charged FS particles
      const FinalState& fs = apply<FinalState>(e, "FS");
      const size_t numParticles = fs.particles().size();

      // Even if we only generate hadronic events, we still need a cut on numCharged >= 2.
      if (numParticles < 2) {
        MSG_DEBUG("Failed ncharged cut");
        vetoEvent;
      }
      MSG_DEBUG("Passed ncharged cut");

      _weightedTotalPartNum->fill(numParticles);

      // Get beams and average beam momentum
      const ParticlePair& beams = apply<Beam>(e, "Beams").beams();
      const double meanBeamMom = (beams.first.p3().mod() + beams.second.p3().mod()) / 2.0;
      MSG_DEBUG("Avg beam momentum = " << meanBeamMom);

      int flavour = 0;
      const InitialQuarks& iqf = apply<InitialQuarks>(e, "IQF");

      // If we only have two quarks (qqbar), just take the flavour.
      // If we have more than two quarks, look for the highest energetic q-qbar pair.
      /// @todo Yuck... does this *really* have to be quark-based?!?
      if (iqf.particles().size() == 2) {
        flavour = iqf.particles().front().abspid();
      }
      else {
        map<int, double> quarkmap;
        for (const Particle& p : iqf.particles()) {
          if (quarkmap[p.pid()] < p.E()) {
            quarkmap[p.pid()] = p.E();
          }
        }
        double maxenergy = 0.;
        for (int i = 1; i <= 5; ++i) {
          if (quarkmap[i] + quarkmap[-i] > maxenergy) {
            flavour = i;
          }
        }
      }

      switch (flavour) {
        case 1:
        case 2:
        case 3: _SumOfudsWeights->fill(); break;
        case 4: _SumOfcWeights->fill(); break;
        case 5: _SumOfbWeights->fill(); break;
      }

      for (const Particle& p : fs.particles()) {
        const double xp = p.p3().mod() / meanBeamMom;
        const double logxp = -std::log(xp);
        _histXpall->fill(xp);
        _histLogXpall->fill(logxp);
        _histMultiChargedall->fill(Ecm);
        switch (flavour) {
            /// @todo Use PDG code enums
          case PID::DQUARK:
          case PID::UQUARK:
          case PID::SQUARK:
            _histXpuds->fill(xp);
            _histLogXpuds->fill(logxp);
            _histMultiChargeduds->fill(Ecm);
            break;
          case PID::CQUARK:
            _histXpc->fill(xp);
            _histLogXpc->fill(logxp);
            _histMultiChargedc->fill(Ecm);
            break;
          case PID::BQUARK:
            _histXpb->fill(xp);
            _histLogXpb->fill(logxp);
            _histMultiChargedb->fill(Ecm);
            break;
        }
      }
    }


    void init() {
      // Projections
      declare(Beam(), "Beams");
      declare(ChargedFinalState(), "FS");
      declare(InitialQuarks(), "IQF");

      // Book histos
      book(_histXpuds, 1, 1, 1);
      book(_histXpc, 2, 1, 1);
      book(_histXpb, 3, 1, 1);
      book(_histXpall, 4, 1, 1);
      book(_histLogXpuds, 5, 1, 1);
      book(_histLogXpc, 6, 1, 1);
      book(_histLogXpb, 7, 1, 1);
      book(_histLogXpall, 8, 1, 1);
      book(_histMultiChargeduds, 9, 1, 1);
      book(_histMultiChargedc, 9, 1, 2);
      book(_histMultiChargedb, 9, 1, 3);
      book(_histMultiChargedall, 9, 1, 4);
      // Counters
      book(_weightedTotalPartNum, "_TotalPartNum");
      book(_SumOfudsWeights, "_udsWeights");
      book(_SumOfcWeights, "_cWeights");
      book(_SumOfbWeights, "_bWeights");
    }


    /// Finalize
    void finalize() {
      const double avgNumParts = dbl(*_weightedTotalPartNum) / sumOfWeights();
      normalize(_histXpuds, avgNumParts);
      normalize(_histXpc, avgNumParts);
      normalize(_histXpb, avgNumParts);
      normalize(_histXpall, avgNumParts);
      normalize(_histLogXpuds, avgNumParts);
      normalize(_histLogXpc, avgNumParts);
      normalize(_histLogXpb, avgNumParts);
      normalize(_histLogXpall, avgNumParts);

      scale(_histMultiChargeduds, 1.0 / *_SumOfudsWeights);
      scale(_histMultiChargedc, 1.0 / *_SumOfcWeights);
      scale(_histMultiChargedb, 1.0 / *_SumOfbWeights);
      scale(_histMultiChargedall, 1.0 / sumOfWeights());
    }

    /// @}


  private:

    /// Store the weighted sums of numbers of charged / charged+neutral
    /// particles - used to calculate average number of particles for the
    /// inclusive single particle distributions' normalisations.
    /// @{
    CounterPtr _weightedTotalPartNum;

    CounterPtr _SumOfudsWeights;
    CounterPtr _SumOfcWeights;
    CounterPtr _SumOfbWeights;

    Histo1DPtr _histXpuds;
    Histo1DPtr _histXpc;
    Histo1DPtr _histXpb;
    Histo1DPtr _histXpall;
    Histo1DPtr _histLogXpuds;
    Histo1DPtr _histLogXpc;
    Histo1DPtr _histLogXpb;
    Histo1DPtr _histLogXpall;
    BinnedHistoPtr<string> _histMultiChargeduds;
    BinnedHistoPtr<string> _histMultiChargedc;
    BinnedHistoPtr<string> _histMultiChargedb;
    BinnedHistoPtr<string> _histMultiChargedall;
    const string Ecm = "91.2";
    /// @}
  };


  RIVET_DECLARE_ALIASED_PLUGIN(OPAL_1998_I472637, OPAL_1998_S3780481);

}

Aliases: - OPAL_1998_S3780481