Rivet analyses

Dijet dependence on photon virtuality in ep

Experiment: ZEUS (HERA)

Inspire ID: 649041

Status: VALIDATED

Authors: - Zain Mahmood

References: - arXiv: 0404033 - Eur.Phys.J.C 35 (2004) 487-500

Beams: p+ e-, p+ e+, e+ p+, e- p+

Beam energies: (820.0, 27.5); (820.0, 27.5); (27.5, 820.0); (27.5, 820.0)GeV

Run details: - 27.5 GeV positrons colliding with 820 GeV protons

The dependence of dijet production on the virtuality of the exchanged photon, $Q^2$, has been studied by measuring dijet cross sections in the range $0 \lesssim Q2 < 2000$ GeV$^2$ with the ZEUS detector at HERA using an integrated luminosity of 38.6 pb$^{-1}$. Dijet cross sections were measured for jets with transverse energy $E^\text{jet}\text{T} > 7.5$ and 6.5 GeV and pseudorapidities in the photon-proton centre-of-mass frame in the range $-3 < \eta^\text{jet} < 0$. The variable $x^\text{obs}\gamma$, a measure of the photon momentum entering the hard process, was used to enhance the sensitivity of the measurement to the photon structure. The $Q^2$ dependence of the ratio of low- to high-$x^\text{obs}\gamma$ events was measured. Next-to-leading-order QCD predictions were found to generally underestimate the low-$x^\mathrm{obs}\gamma$ contribution relative to that at high $x^\mathrm{obs}_\gamma$. Monte Carlo models based on leading-logarithmic parton-showers, using a partonic structure for the photon which falls smoothly with increasing $Q^2$, provide a qualitative description of the data.

Source code:ZEUS_2004_I649041.cc

// -*- C++ -*-
#include "Rivet/Analysis.hh"
#include "Rivet/Projections/Beam.hh"
#include "Rivet/Projections/DISFinalState.hh"
#include "Rivet/Projections/DISKinematics.hh"
#include "Rivet/Projections/FastJets.hh"
#include "Rivet/Projections/FinalState.hh"

namespace Rivet {

  /// @brief Dijet dependence on photon virtuality in ep
  class ZEUS_2004_I649041 : public Analysis {
  public:

    /// Constructor
    RIVET_DEFAULT_ANALYSIS_CTOR(ZEUS_2004_I649041);

    // Book projections and histograms
    void init() {
      // Declare your final-state and jet projections
      declare(FastJets(DISFinalState(DISFrame::HCM), fastjet::JetAlgorithm::kt_algorithm,
                       fastjet::RecombinationScheme::Et_scheme, 1.0),
              "DISFSJets");
      declare(DISKinematics(), "Kinematics");

      // Book single-differential histograms
      book(_h_Q2[0], 1, 1, 1);
      book(_h_Q2[1], 2, 1, 1);
      book(_h_Q2[2], 2, 1, 2);

      // Book double-differential vs. Q² and jet Et
      book(_h_Q2Et[0], 3, 1, 1);
      book(_h_Q2Et[1], 4, 1, 1);
      book(_h_Q2Et[2], 5, 1, 1);
      book(_h_Q2Et[3], 6, 1, 1);
      book(_h_Q2Et[4], 7, 1, 1);
      book(_h_Q2Et[5], 8, 1, 1);
      book(_h_Q2Et[6], 9, 1, 1);

      // Book double-differential vs. Q² and forward-jet eta
      book(_h_Q2etaf[0], 10, 1, 1);
      book(_h_Q2etaf[1], 11, 1, 1);
      book(_h_Q2etaf[2], 12, 1, 1);
      book(_h_Q2etaf[3], 13, 1, 1);
      book(_h_Q2etaf[4], 14, 1, 1);
      book(_h_Q2etaf[5], 15, 1, 1);
      book(_h_Q2etaf[6], 16, 1, 1);
    }


    // Do the analysis for each event
    void analyze(const Event& event) {

      // Get the DIS kinematics
      const DISKinematics& kin = apply<DISKinematics>(event, "Kinematics");
      if (kin.failed()) vetoEvent;
      const int orientation = kin.orientation();

      // Define kinematic variables
      double Q2 = kin.Q2();
      double y = kin.y();

      // Set pseudorapidity cuts in the HCM frame based on orientation:
      // If proton is along +z (orientation=+1) we use [-3,0]; if not, flip to [0,3].
      double etamin = -3.0;
      double etamax = 0.0;
      if (orientation < 0) {
        etamin = 0.0;
        etamax = 3.0;
      }

      // Basic Q² and inelasticity cuts
      if (!inRange(Q2, 0.0, 2000.0)) vetoEvent;
      if (!inRange(y, 0.2, 0.55)) vetoEvent;

      // Jet selection: use jets clustered in the HCM frame with the adjusted eta range
      const Jets jets = apply<FastJets>(event, "DISFSJets")
                            .jets(Cuts::Et > 6.5 * GeV && Cuts::etaIn(etamin, etamax), cmpMomByEt);
      MSG_DEBUG("Jet multiplicity = " << jets.size());
      if (jets.size() < 2) vetoEvent;
      const Jet& j1 = jets[0];
      const Jet& j2 = jets[1];

      // Cut on leading jet
      if (j1.Et() < 7.5 * GeV) vetoEvent;

      // Correct the jet pseudorapidities so they always represent the proton direction.
      const double eta1 = orientation * j1.eta();
      const double eta2 = orientation * j2.eta();

      // Calculate xobs according to the paper
      const double xobs = (j1.Et() * exp(-eta1) + j2.Et() * exp(-eta2))
          / (2 * kin.y() * kin.beamLepton().E());


      // Fill single-differential histograms
      _h_Q2[0]->fill(Q2);
      if (xobs < 0.75) _h_Q2[1]->fill(Q2);
      if (xobs > 0.75) _h_Q2[2]->fill(Q2);

      // Fill double-differential histograms: Q² vs. jet E_T.
      if (inRange(Q2, 0.0, 1.0)) _h_Q2Et[0]->fill(j1.Et());
      if (inRange(Q2, 0.1, 0.55)) _h_Q2Et[1]->fill(j1.Et());
      if (inRange(Q2, 1.0, 4.5)) _h_Q2Et[2]->fill(j1.Et());
      if (inRange(Q2, 4.5, 10.5)) _h_Q2Et[3]->fill(j1.Et());
      if (inRange(Q2, 10.5, 49.0)) _h_Q2Et[4]->fill(j1.Et());
      if (inRange(Q2, 49.0, 120.0)) _h_Q2Et[5]->fill(j1.Et());
      if (inRange(Q2, 120.0, 2000.0)) _h_Q2Et[6]->fill(j1.Et());

      // For the forward-jet η histograms: select the jet with the larger corrected pseudorapidity
      const Jet& fjet = (orientation * j1.eta() > orientation * j2.eta() ? j1 : j2);
      double fjetEta = orientation * fjet.eta();

      // Fill double-differential histograms: Q² vs. forward jet η.
      if (inRange(Q2, 0.0, 1.0)) _h_Q2etaf[0]->fill(fjetEta);
      if (inRange(Q2, 0.1, 0.55)) _h_Q2etaf[1]->fill(fjetEta);
      if (inRange(Q2, 1.0, 4.5)) _h_Q2etaf[2]->fill(fjetEta);
      if (inRange(Q2, 4.5, 10.5)) _h_Q2etaf[3]->fill(fjetEta);
      if (inRange(Q2, 10.5, 49.0)) _h_Q2etaf[4]->fill(fjetEta);
      if (inRange(Q2, 49.0, 120.0)) _h_Q2etaf[5]->fill(fjetEta);
      if (inRange(Q2, 120.0, 2000.0)) _h_Q2etaf[6]->fill(fjetEta);
    }


    // Finalize: scale histograms by cross section, etc.
    void finalize() {
      const double sf = crossSection() / picobarn / sumOfWeights();
      scale(_h_Q2, sf);
      scale(_h_Q2Et, sf);
      scale(_h_Q2etaf, sf);
      double q2BinWidths[7] = {1, .45, 3, 6, 38.5, 71, 1880};
      for (unsigned int ix = 0; ix < 7; ++ix) {
        scale(_h_Q2Et[ix], 1. / q2BinWidths[ix]);
        scale(_h_Q2etaf[ix], 1. / q2BinWidths[ix]);
      }
    }

  private:

    /// name histograms
    Histo1DPtr _h_Q2[3];
    Histo1DPtr _h_Q2Et[7];
    Histo1DPtr _h_Q2etaf[7];
  };

  RIVET_DECLARE_PLUGIN(ZEUS_2004_I649041);

}