Rivet analyses
Ratios of V+jets observables between W and Z events
Experiment: ATLAS (LHC)
Inspire ID: 1312627
Status: VALIDATED
Authors: - Christian Gutschow
References: - Expt page: ATLAS-STDM-2012-25 - Eur.Phys.J. C74 (2014) 3168 - DOI: 10.1140/epjc/s10052-014-3168-9 - arXiv: 1408.6510
Beams: p+ p+
Beam energies: (3500.0, 3500.0)GeV
Run details: - Inclusive W and inclusive Z in both electron and muon channels
Measurements of the ratio of the production cross sections for W and Z bosons in association with jets in proton-proton collisions at $\sqrt{s} = 7$~TeV with the ATLAS experiment at the Large Hadron Collider. The measurement is based on the entire 2011 dataset, corresponding to an integrated luminosity of 4.6fb−1. Inclusive and differential cross-section ratios for massive vector bosons decaying to electrons and muons are measured in association with jets with transverse momentum pT > 30~GeV and jet rapidity |y| < 4.4. The default routine will pick up the electron decay channel of the heavy bosons and compare it to the combined (muon and electron channel) data. Individual channels (for data) are available as well, use ATLAS_2014_I1312627_EL and ATLAS_2014_I1312627_MU to specify the decay channel directly. NB #1: The “x01” Scatter2D objects are constructed from the ratio of “x02” to “x03” Histo1D objects. If several output yoda files are merged with yodamerge, the merged “x01” objects will become meaningless. New “x01” Scatter2Ds can easil be constructed in a postprocessing step from the merged “x02” (nominator) and “x03” (denominator) objects. NB #2: Special care ought to be taken when evaluating theoretical uncertainties due to potential cancellations/correlations between numerator and denominator.
Source
code:ATLAS_2014_I1312627.cc
// -*- C++ -*-
#include "Rivet/Analysis.hh"
#include "Rivet/Projections/FinalState.hh"
#include "Rivet/Projections/PromptFinalState.hh"
#include "Rivet/Projections/MissingMomentum.hh"
#include "Rivet/Projections/LeptonFinder.hh"
#include "Rivet/Projections/DileptonFinder.hh"
#include "Rivet/Projections/FastJets.hh"
#include "Rivet/Projections/VetoedFinalState.hh"
namespace Rivet {
/// Measurement of V+jets distributions, taken as ratios between W and Z channels
class ATLAS_2014_I1312627 : public Analysis {
public:
/// @name Plotting helper types
/// @{
struct Plots {
string ref;
Histo1DPtr comp[2]; // (de)nominator components
Estimate1DPtr ratio; // Rjets plot
};
/// @}
/// Constructor
RIVET_DEFAULT_ANALYSIS_CTOR(ATLAS_2014_I1312627);
/// @name Analysis methods
/// @{
/// Book histograms and initialise projections before the run
void init() {
// get option
_mode = 0;
if ( getOption("LMODE") == "EL" ) _mode = 1;
if ( getOption("LMODE") == "MU" ) _mode = 2;
// Set up cuts
Cut cuts;
if (_mode == 2) { // muon channel
cuts = Cuts::pT > 25*GeV && Cuts::abseta < 2.4;;
} else if (_mode) { // electron channel
cuts = Cuts::pT > 25*GeV && ( Cuts::abseta < 1.37 || Cuts::absetaIn(1.52, 2.47) );
} else { // combined data extrapolated to common phase space
cuts = Cuts::pT > 25*GeV && Cuts::abseta < 2.5;
}
// Boson finders
declare("MET", MissingMomentum());
LeptonFinder lf(0.1, cuts && Cuts::abspid == (_mode > 1 ? PID::MUON : PID::ELECTRON));
declare(lf, "Leptons");
DileptonFinder zf(91.2*GeV, 0.1, cuts && Cuts::abspid == (_mode > 1 ? PID::MUON : PID::ELECTRON), Cuts::massIn(66*GeV, 116*GeV));
declare(zf, "ZF");
// Jets
VetoedFinalState jet_fs;
jet_fs.addVetoOnThisFinalState(lf);
jet_fs.addVetoOnThisFinalState(zf);
FastJets jets(jet_fs, JetAlg::ANTIKT, 0.4, JetMuons::ALL, JetInvisibles::ALL); //< !!
declare(jets, "Jets");
// Book Rjets plots
_suff = string("-y0") + to_str(_mode + 1);
hInit("Njets_incl", "d01"); // inclusive number of jets
hInit("Njets_excl", "d04"); // exclusive number of jets
hInit("Pt1_N1incl", "d05"); // leading jet pT, at least 1 jet
hInit("Pt1_N1excl", "d06"); // leading jet pT, exactly 1 jet
hInit("Pt1_N2incl", "d07"); // leading jet pT, at least 2 jets
hInit("Pt1_N3incl", "d08"); // leading jet pT, at least 3 jets
hInit("Pt2_N2incl", "d09"); // subleading jet pT, at least 2 jets
hInit("Pt3_N3incl", "d10"); // sub-subleading jet pT, at least 3 jets
hInit("ST_N2incl", "d11"); // scalar jet pT sum, at least 2 jets
hInit("ST_N2excl", "d12"); // scalar jet pT sum, exactly 2 jets
hInit("ST_N3incl", "d13"); // scalar jet pT sum, at least 3 jets
hInit("ST_N3excl", "d14"); // scalar jet pT sum, exactly 3 jets
hInit("DR_N2incl", "d15"); // deltaR(j1, j2), at least 2 jets
hInit("DPhi_N2incl", "d16"); // deltaPhi(j1, j2), at least 2 jets
hInit("Mjj_N2incl", "d17"); // mjj, at least 2 jets
hInit("Rap1_N1incl", "d18"); // leading jet rapidity, at least 1 jet
hInit("Rap2_N2incl", "d19"); // subleading jet rapidity, at least 2 jets
hInit("Rap3_N3incl", "d20"); // sub-subleading jet rapidity, at least 3 jets
// Also book numerator and denominator for Rjets plots
for (auto& item : _plots) {
book(item.second.comp[0], item.second.ref + "2" + _suff, refData(item.second.ref + "1" + _suff));
book(item.second.comp[1], item.second.ref + "3" + _suff, refData(item.second.ref + "1" + _suff));
}
}
/// Perform the per-event analysis
void analyze(const Event& event) {
// W reco, starting with MET
const P4& pmiss = apply<MissingMom>(event, "MET").missingMom();
const Particles& ls = apply<LeptonFinder>(event, "Leptons").particles();
const Particles ls_mtfilt = select(ls, [&](const Particle& l){ return mT(l, pmiss) > 40*GeV; });
const int ifound = closestMatchIndex(ls_mtfilt, pmiss, Kin::mass, 80.4*GeV);
// Z reco
const DileptonFinder& zf = apply<DileptonFinder>(event, "ZF");
// Exit if no bosons found (note: overlapping W and Z reco is allowed)
if (ifound < 0 && zf.empty()) vetoEvent;
// Retrieve jets
const JetFinder& jetfs = apply<JetFinder>(event, "Jets");
Jets jets = jetfs.jetsByPt(Cuts::pT > 30*GeV && Cuts::absrap < 4.4);
// Apply boson cuts and fill histograms
if (!zf.empty()) {
const Particles& leptons = zf.constituents();
if (oppSign(leptons[0], leptons[1]) && deltaR(leptons[0], leptons[1]) > 0.2)
fillPlots(leptons, jets, 1);
}
if (ifound >= 0) {
const Particle& lepton = ls_mtfilt[ifound];
if (pmiss.pT() > 25*GeV)
fillPlots(Particles{lepton}, jets, 0);
}
}
/// Normalise histograms etc., after the run
void finalize() {
/// Normalise, scale and otherwise manipulate histograms here
const double sf( crossSection()/picobarn / sumOfWeights() );
for (auto& item : _plots) {
scale(item.second.comp[0], sf);
scale(item.second.comp[1], sf);
divide(item.second.comp[0], item.second.comp[1], item.second.ratio);
}
}
/// @}
/// Analysis helper functions
/// @{
/// Histogram filling function, to avoid duplication
void fillPlots(const Particles& leptons, Jets& jets, int isZ) {
// Do jet-lepton overlap removal
idiscardIfAnyDeltaRLess(jets, leptons, 0.5);
// Calculate jet ST
const size_t njets = jets.size();
const double ST = sum(jets, pT, 0.0)/GeV;
// Fill jet histos
_plots["Njets_excl"].comp[isZ]->fill(njets + 0.5);
for (size_t i = 0; i <= njets; ++i)
_plots["Njets_incl"].comp[isZ]->fill(i + 0.5);
if (njets > 0) {
const double pT1 = jets[0].pT()/GeV;
const double rap1 = jets[0].absrap();
_plots["Pt1_N1incl" ].comp[isZ]->fill(pT1);
_plots["Rap1_N1incl"].comp[isZ]->fill(rap1);
if (njets == 1) {
_plots["Pt1_N1excl"].comp[isZ]->fill(pT1);
} else if (njets > 1) {
const double pT2 = jets[1].pT()/GeV;
const double rap2 = jets[1].absrap();
const double dR = deltaR(jets[0], jets[1]);
const double dPhi = deltaPhi(jets[0], jets[1]);
const double mjj = (jets[0].momentum() + jets[1].momentum()).mass()/GeV;
_plots["Pt1_N2incl" ].comp[isZ]->fill(pT1);
_plots["Pt2_N2incl" ].comp[isZ]->fill(pT2);
_plots["Rap2_N2incl"].comp[isZ]->fill(rap2);
_plots["DR_N2incl" ].comp[isZ]->fill(dR);
_plots["DPhi_N2incl"].comp[isZ]->fill(dPhi);
_plots["Mjj_N2incl" ].comp[isZ]->fill(mjj);
_plots["ST_N2incl" ].comp[isZ]->fill(ST);
if (njets == 2) {
_plots["ST_N2excl"].comp[isZ]->fill(ST);
} else if (njets > 2) {
const double pT3 = jets[2].pT()/GeV;
const double rap3 = jets[2].absrap();
_plots["Pt1_N3incl" ].comp[isZ]->fill(pT1);
_plots["Pt3_N3incl" ].comp[isZ]->fill(pT3);
_plots["Rap3_N3incl"].comp[isZ]->fill(rap3);
_plots["ST_N3incl" ].comp[isZ]->fill(ST);
if (njets == 3)
_plots["ST_N3excl"].comp[isZ]->fill(ST);
}
}
}
}
/// Helper for histogram initialisation
void hInit(string label, string ident) {
string pre = ident + "-x0";
_plots[label].ref = pre;
book(_plots[label].ratio, pre + "1" + _suff);
}
/// @}
protected:
// Data members
size_t _mode;
string _suff;
private:
/// @name Map of histograms
map<string, Plots> _plots;
};
RIVET_DECLARE_PLUGIN(ATLAS_2014_I1312627);
}