Rivet analyses
Higgs diphoton events at 8 TeV in ATLAS
Experiment: ATLAS (LHC)
Inspire ID: 1306615
Status: VALIDATED
Authors: - Michaela Queitsch-Maitland
References: - Expt page: ATLAS-HIGG-2013-10 - arXiv: 1407.4222 - JHEP 09 (2014) 112
Beams: p+ p+
Beam energies: (4000.0, 4000.0)GeV
Run details: - pp Higgs production at 8 TeV, include all processes (ggH, VH, VBF, ttH)
Measurements of fiducial and differential cross sections are presented for Higgs boson production in proton-proton collisions at a centre-of-mass energy of 8TeV. The analysis is performed in the Higgs diphoton decay channel using 20.3/fb of data recorded by the ATLAS experiment at the CERN Large Hadron Collider. The signal yields are corrected for the effects of detector inefficiency and resolution. Differential cross sections are also presented, as a function of variables related to the diphoton kinematics and the jet activity produced in the Higgs boson events. The observed spectra are statistically limited but broadly in line with the theoretical expectations. Note on reinterpretation: Since the background is subtracted from a fit, any BSM signal would presumably also have beed subtracted. Therefore should not be used to constrain BSM signals unless they comes from a genuine excess of SM Higgs->gammagamma.
Source
code:ATLAS_2014_I1306615.cc
// -*- C++ -*-
#include "Rivet/Analysis.hh"
#include "Rivet/Projections/FinalState.hh"
#include "Rivet/Projections/PromptFinalState.hh"
#include "Rivet/Projections/LeptonFinder.hh"
#include "Rivet/Projections/VetoedFinalState.hh"
#include "Rivet/Projections/FastJets.hh"
namespace Rivet {
/// @brief ATLAS H->yy differential cross-sections measurement
///
/// @author Michaela Queitsch-Maitland <michaela.queitsch-maitland@cern.ch>
//
// arXiv: http://arxiv.org/abs/ARXIV:1407.4222
// HepData: http://hepdata.cedar.ac.uk/view/ins1306615
class ATLAS_2014_I1306615 : public Analysis {
public:
// Constructor
ATLAS_2014_I1306615()
: Analysis("ATLAS_2014_I1306615")
{ }
// Book histograms and initialise projections before the run
void init() {
// Final state
// All particles within |eta| < 5.0
const FinalState FS(Cuts::abseta<5.0);
declare(FS,"FS");
// Project photons with pT > 25 GeV and |eta| < 2.37
PromptFinalState ph_FS(Cuts::abseta<2.37 && Cuts::pT>25*GeV && Cuts::pid == PID::PHOTON);
declare(ph_FS, "PH_FS");
// Project photons for dressing
FinalState ph_dressing_FS(Cuts::abspid == PID::PHOTON);
// Project bare electrons
PromptFinalState el_bare_FS(Cuts::abseta < 5.0 && Cuts::abspid == PID::ELECTRON);
// Project dressed electrons with pT > 15 GeV and |eta| < 2.47
LeptonFinder el_dressed_FS(el_bare_FS, ph_dressing_FS, 0.1, Cuts::abseta < 2.47 && Cuts::pT > 15*GeV);
declare(el_dressed_FS,"EL_DRESSED_FS");
// Project bare muons
PromptFinalState mu_bare_FS(Cuts::abseta < 5.0 && Cuts::abspid == PID::MUON);
// Project dressed muons with pT > 15 GeV and |eta| < 2.47
LeptonFinder mu_dressed_FS(mu_bare_FS, ph_dressing_FS, 0.1, Cuts::abseta < 2.47 && Cuts::pT > 15*GeV);
declare(mu_dressed_FS,"MU_DRESSED_FS");
// Final state excluding muons and neutrinos (for jet building and photon isolation)
VetoedFinalState veto_mu_nu_FS(FS);
veto_mu_nu_FS.vetoNeutrinos();
veto_mu_nu_FS.addVetoPairId(PID::MUON);
declare(veto_mu_nu_FS, "VETO_MU_NU_FS");
// Build the anti-kT R=0.4 jets, using FinalState particles (vetoing muons and neutrinos)
FastJets jets(veto_mu_nu_FS, JetAlg::ANTIKT, 0.4);
declare(jets, "JETS");
// Book histograms
// 1D distributions
book(_h_pT_yy ,1,1,1);
book(_h_y_yy ,2,1,1);
book(_h_Njets30 ,3,1,1);
book(_h_Njets50 ,4,1,1);
book(_h_pT_j1 ,5,1,1);
book(_h_y_j1 ,6,1,1);
book(_h_HT ,7,1,1);
book(_h_pT_j2 ,8,1,1);
book(_h_Dy_jj ,9,1,1);
book(_h_Dphi_yy_jj ,10,1,1);
book(_h_cosTS_CS ,11,1,1);
book(_h_cosTS_CS_5bin ,12,1,1);
book(_h_Dphi_jj ,13,1,1);
book(_h_pTt_yy ,14,1,1);
book(_h_Dy_yy ,15,1,1);
book(_h_tau_jet ,16,1,1);
book(_h_sum_tau_jet ,17,1,1);
book(_h_y_j2 ,18,1,1);
book(_h_pT_j3 ,19,1,1);
book(_h_m_jj ,20,1,1);
book(_h_pT_yy_jj ,21,1,1);
// 2D distributions of cosTS_CS x pT_yy
book(_h_cosTS_pTyy_low, 22,1,1);
book(_h_cosTS_pTyy_high, 22,1,2);
book(_h_cosTS_pTyy_rest, 22,1,3);
// 2D distributions of Njets x pT_yy
book(_h_pTyy_Njets0, 23,1,1);
book(_h_pTyy_Njets1, 23,1,2);
book(_h_pTyy_Njets2, 23,1,3);
book(_h_pTj1_excl, 24,1,1);
// Fiducial regions
book(_h_fidXSecs, 30,1,1);
}
// Perform the per-event analysis
void analyze(const Event& event) {
// Get final state particles
const Particles& FS_ptcls = apply<FinalState>(event, "FS").particles();
const Particles& ptcls_veto_mu_nu = apply<VetoedFinalState>(event, "VETO_MU_NU_FS").particles();
const Particles& photons = apply<PromptFinalState>(event, "PH_FS").particlesByPt();
DressedLeptons good_el = apply<LeptonFinder>(event, "EL_DRESSED_FS").dressedLeptons();
DressedLeptons good_mu = apply<LeptonFinder>(event, "MU_DRESSED_FS").dressedLeptons();
// For isolation calculation
float dR_iso = 0.4;
float ETcut_iso = 14.0;
FourMomentum ET_iso;
// Fiducial selection: pT > 25 GeV, |eta| < 2.37 and isolation (in cone deltaR = 0.4) is < 14 GeV
Particles fid_photons;
for (const Particle& ph : photons) {
// Calculate isolation
ET_iso = - ph.momentum();
// Loop over fs truth particles (excluding muons and neutrinos)
for (const Particle& p : ptcls_veto_mu_nu) {
// Check if the truth particle is in a cone of 0.4
if ( deltaR(ph, p) < dR_iso ) ET_iso += p.momentum();
}
// Check isolation
if ( ET_iso.Et() > ETcut_iso ) continue;
// Fill vector of photons passing fiducial selection
fid_photons.push_back(ph);
}
if (fid_photons.size() < 2) vetoEvent;
const FourMomentum y1 = fid_photons[0].momentum();
const FourMomentum y2 = fid_photons[1].momentum();
double m_yy = (y1 + y2).mass();
// Relative pT cuts
if ( y1.pT() < 0.35 * m_yy || y2.pT() < 0.25 * m_yy ) vetoEvent;
// Mass window cut
if ( m_yy < 105 || m_yy > 160 ) vetoEvent;
// -------------------------------------------- //
// Passed diphoton baseline fiducial selection! //
// -------------------------------------------- //
// Muon and Electron selection
idiscard(good_mu, [&](const DressedLepton& lep) { return deltaR(lep, y1) < 0.4 || deltaR(lep, y2) < 0.4; });
idiscard(good_el, [&](const DressedLepton& lep) { return deltaR(lep, y1) < 0.4 || deltaR(lep, y2) < 0.4; });
// Find prompt, invisible particles for missing ET calculation
// Based on VisibleFinalState projection
FourMomentum invisible(0,0,0,0);
for (const Particle& p : FS_ptcls) {
// Veto non-prompt particles (from hadron or tau decay)
if ( !p.isPrompt() ) continue;
// Charged particles are visible
if ( PID::charge3( p.pid() ) != 0 ) continue;
// Neutral hadrons are visible
if ( PID::isHadron( p.pid() ) ) continue;
// Photons are visible
if ( p.pid() == PID::PHOTON ) continue;
// Gluons are visible (for parton level analyses)
if ( p.pid() == PID::GLUON ) continue;
// Everything else is invisible
invisible += p.momentum();
}
double MET = invisible.Et();
// Jet selection
// Get jets with pT > 25 GeV and |rapidity| < 4.4
const Jets& jets = apply<FastJets>(event, "JETS").jetsByPt(Cuts::pT>25*GeV && Cuts::absrap <4.4);
Jets jets_25, jets_30, jets_50;
for (const Jet& jet : jets) {
bool passOverlap = true;
// Overlap with leading photons
if ( deltaR(y1, jet.momentum()) < 0.4 ) passOverlap = false;
if ( deltaR(y2, jet.momentum()) < 0.4 ) passOverlap = false;
// Overlap with good electrons
for (const auto& el : good_el) {
if ( deltaR(el, jet) < 0.2 ) passOverlap = false;
}
if ( ! passOverlap ) continue;
if ( jet.abseta() < 2.4 || ( jet.abseta() > 2.4 && jet.pT() > 30*GeV) ) jets_25 += jet;
if ( jet.pT() > 30*GeV ) jets_30 += jet;
if ( jet.pT() > 50*GeV ) jets_50 += jet;
}
// Fiducial regions
_h_fidXSecs->fill(1);
if ( jets_30.size() >= 1 ) _h_fidXSecs->fill(2);
if ( jets_30.size() >= 2 ) _h_fidXSecs->fill(3);
if ( jets_30.size() >= 3 ) _h_fidXSecs->fill(4);
if ( jets_30.size() >= 2 && passVBFCuts(y1 + y2, jets_30.at(0).momentum(), jets_30.at(1).momentum()) ) _h_fidXSecs->fill(5);
if ( (good_el.size() + good_mu.size()) > 0 ) _h_fidXSecs->fill(6);
if ( MET > 80 ) _h_fidXSecs->fill(7);
// Fill histograms
// Inclusive variables
_pT_yy = (y1 + y2).pT();
_y_yy = (y1 + y2).absrap();
_cosTS_CS = cosTS_CS(y1, y2);
_pTt_yy = pTt(y1, y2);
_Dy_yy = fabs( deltaRap(y1, y2) );
_Njets30 = jets_30.size() > 3 ? 3 : jets_30.size();
_Njets50 = jets_50.size() > 3 ? 3 : jets_50.size();
_h_Njets30->fill(_Njets30);
_h_Njets50->fill(_Njets50);
_pT_j1 = jets_30.size() > 0 ? jets_30[0].momentum().pT() : 0.;
_pT_j2 = jets_30.size() > 1 ? jets_30[1].momentum().pT() : 0.;
_pT_j3 = jets_30.size() > 2 ? jets_30[2].momentum().pT() : 0.;
_HT = 0.0;
for (const Jet& jet : jets_30) { _HT += jet.pT(); }
_tau_jet = tau_jet_max(y1 + y2, jets_25);
_sum_tau_jet = sum_tau_jet(y1 + y2, jets_25);
_h_pT_yy ->fill(_pT_yy);
_h_y_yy ->fill(_y_yy);
_h_pT_j1 ->fill(_pT_j1);
_h_cosTS_CS ->fill(_cosTS_CS);
_h_cosTS_CS_5bin->fill(_cosTS_CS);
_h_HT ->fill(_HT);
_h_pTt_yy ->fill(_pTt_yy);
_h_Dy_yy ->fill(_Dy_yy);
_h_tau_jet ->fill(_tau_jet);
_h_sum_tau_jet ->fill(_sum_tau_jet);
// >=1 jet variables
if ( jets_30.size() >= 1 ) {
FourMomentum j1 = jets_30[0].momentum();
_y_j1 = j1.absrap();
_h_pT_j2->fill(_pT_j2);
_h_y_j1 ->fill(_y_j1);
}
// >=2 jet variables
if ( jets_30.size() >= 2 ) {
FourMomentum j1 = jets_30[0].momentum();
FourMomentum j2 = jets_30[1].momentum();
_Dy_jj = fabs( deltaRap(j1, j2) );
_Dphi_jj = fabs( deltaPhi(j1, j2) );
_Dphi_yy_jj = fabs( deltaPhi(y1 + y2, j1 + j2) );
_m_jj = (j1 + j2).mass();
_pT_yy_jj = (y1 + y2 + j1 + j2).pT();
_y_j2 = j2.absrap();
_h_Dy_jj ->fill(_Dy_jj);
_h_Dphi_jj ->fill(_Dphi_jj);
_h_Dphi_yy_jj ->fill(_Dphi_yy_jj);
_h_m_jj ->fill(_m_jj);
_h_pT_yy_jj ->fill(_pT_yy_jj);
_h_pT_j3 ->fill(_pT_j3);
_h_y_j2 ->fill(_y_j2);
}
// 2D distributions of cosTS_CS x pT_yy
if ( _pT_yy < 80 )
_h_cosTS_pTyy_low->fill(_cosTS_CS);
else if ( _pT_yy > 80 && _pT_yy < 200 )
_h_cosTS_pTyy_high->fill(_cosTS_CS);
else if ( _pT_yy > 200 )
_h_cosTS_pTyy_rest->fill(_cosTS_CS);
// 2D distributions of pT_yy x Njets
if ( _Njets30 == 0 )
_h_pTyy_Njets0->fill(_pT_yy);
else if ( _Njets30 == 1 )
_h_pTyy_Njets1->fill(_pT_yy);
else if ( _Njets30 >= 2 )
_h_pTyy_Njets2->fill(_pT_yy);
if ( _Njets30 == 1 ) _h_pTj1_excl->fill(_pT_j1);
}
// Normalise histograms after the run
void finalize() {
const double xs = crossSectionPerEvent()/femtobarn;
scale(_h_pT_yy, xs);
scale(_h_y_yy, xs);
scale(_h_pT_j1, xs);
scale(_h_y_j1, xs);
scale(_h_HT, xs);
scale(_h_pT_j2, xs);
scale(_h_Dy_jj, xs);
scale(_h_Dphi_yy_jj, xs);
scale(_h_cosTS_CS, xs);
scale(_h_cosTS_CS_5bin, xs);
scale(_h_Dphi_jj, xs);
scale(_h_pTt_yy, xs);
scale(_h_Dy_yy, xs);
scale(_h_tau_jet, xs);
scale(_h_sum_tau_jet, xs);
scale(_h_y_j2, xs);
scale(_h_pT_j3, xs);
scale(_h_m_jj, xs);
scale(_h_pT_yy_jj, xs);
scale(_h_cosTS_pTyy_low, xs);
scale(_h_cosTS_pTyy_high, xs);
scale(_h_cosTS_pTyy_rest, xs);
scale(_h_pTyy_Njets0, xs);
scale(_h_pTyy_Njets1, xs);
scale(_h_pTyy_Njets2, xs);
scale(_h_pTj1_excl, xs);
scale(_h_Njets30, xs);
scale(_h_Njets50, xs);
scale(_h_fidXSecs, xs);
}
// VBF-enhanced dijet topology selection cuts
bool passVBFCuts(const FourMomentum &H, const FourMomentum &j1, const FourMomentum &j2) {
return ( fabs(deltaRap(j1, j2)) > 2.8 && (j1 + j2).mass() > 400 && fabs(deltaPhi(H, j1 + j2)) > 2.6 );
}
// Cosine of the decay angle in the Collins-Soper frame
double cosTS_CS(const FourMomentum &y1, const FourMomentum &y2) {
return fabs( ( (y1.E() + y1.pz())* (y2.E() - y2.pz()) - (y1.E() - y1.pz()) * (y2.E() + y2.pz()) )
/ ((y1 + y2).mass() * sqrt(pow((y1 + y2).mass(), 2) + pow((y1 + y2).pt(), 2)) ) );
}
// Diphoton pT along thrust axis
double pTt(const FourMomentum &y1, const FourMomentum &y2) {
return fabs(y1.px() * y2.py() - y2.px() * y1.py()) / (y1 - y2).pT()*2;
}
// Tau of jet (see paper for description)
// tau_jet = mT/(2*cosh(y*)), where mT = pT (+) m, and y* = rapidty in Higgs rest frame
double tau_jet( const FourMomentum &H, const FourMomentum &jet ) {
return sqrt( pow(jet.pT(),2) + pow(jet.mass(),2) ) / (2.0 * cosh( jet.rapidity() - H.rapidity() ) );
}
// Maximal (leading) tau_jet (see paper for description)
double tau_jet_max(const FourMomentum &H, const Jets& jets, double tau_jet_cut = 8.) {
double max_tj = 0;
for (const auto& jet : jets) {
FourMomentum j = jet.momentum();
if (tau_jet(H, j) > tau_jet_cut) max_tj = max(tau_jet(H, j), max_tj);
}
return max_tj;
}
// Scalar sum of tau for all jets (see paper for description)
double sum_tau_jet(const FourMomentum &H, const Jets& jets, double tau_jet_cut = 8.) {
double sum_tj = 0;
for (const auto& jet : jets) {
FourMomentum j = jet.momentum();
if (tau_jet(H, j) > tau_jet_cut) sum_tj += tau_jet(H, j);
}
return sum_tj;
}
private:
Histo1DPtr _h_pT_yy;
Histo1DPtr _h_y_yy;
Histo1DPtr _h_Njets30;
Histo1DPtr _h_Njets50;
Histo1DPtr _h_pT_j1;
Histo1DPtr _h_y_j1;
Histo1DPtr _h_HT;
Histo1DPtr _h_pT_j2;
Histo1DPtr _h_Dy_jj;
Histo1DPtr _h_Dphi_yy_jj;
Histo1DPtr _h_cosTS_CS;
Histo1DPtr _h_cosTS_CS_5bin;
Histo1DPtr _h_Dphi_jj;
Histo1DPtr _h_pTt_yy;
Histo1DPtr _h_Dy_yy;
Histo1DPtr _h_tau_jet;
Histo1DPtr _h_sum_tau_jet;
Histo1DPtr _h_y_j2;
Histo1DPtr _h_pT_j3;
Histo1DPtr _h_m_jj;
Histo1DPtr _h_pT_yy_jj;
Histo1DPtr _h_cosTS_pTyy_low;
Histo1DPtr _h_cosTS_pTyy_high;
Histo1DPtr _h_cosTS_pTyy_rest;
Histo1DPtr _h_pTyy_Njets0;
Histo1DPtr _h_pTyy_Njets1;
Histo1DPtr _h_pTyy_Njets2;
Histo1DPtr _h_pTj1_excl;
Histo1DPtr _h_fidXSecs;
int _Njets30;
int _Njets50;
double _pT_yy;
double _y_yy;
double _cosTS_CS;
double _pT_j1;
double _m_jj;
double _y_j1;
double _HT;
double _pT_j2;
double _y_j2;
double _Dphi_yy_jj;
double _pT_yy_jj;
double _Dphi_jj;
double _Dy_jj;
double _pT_j3;
double _pTt_yy;
double _Dy_yy;
double _tau_jet;
double _sum_tau_jet;
};
RIVET_DECLARE_PLUGIN(ATLAS_2014_I1306615);
}