Rivet analyses
Pseudo-top-antitop cross sections
Experiment: ATLAS (LHC)
Inspire ID: 1345452
Status: VALIDATED
Authors: - Longen Lan - Aldo Saavedra - Kevin Finelli
References: - Expt page: ATLAS-TOPQ-2013-07 - arXiv: 1502.05923
Beams: p+ p+
Beam energies: (3500.0, 3500.0)GeV
Run details: - top-antitop production, reconstructed from leptons + jets final state
Various differential cross-sections are measured in top-quark pair (tt̄) events produced in proton-proton collisions at a centre-of-mass energy of $\sqrt{s}=7$ TeV at the LHC with the ATLAS detector. These differential cross-sections are presented in a data set corresponding to an integrated luminosity of 4.6 fb−1. The differential cross-sections are presented in terms of kinematic variables of a top-quark proxy referred to as the pseudo-top-quark whose dependence on theoretical models is minimal. The pseudo-top-quark can be defined in terms of either reconstructed detector objects or stable particles in an analogous way. The measurements are performed on tt̄ events in the lepton+jets channel, requiring exactly one charged lepton and at least four jets with at least two of them tagged as originating from a b-quark. The hadronic and leptonic pseudo-top-quarks are defined via the leptonic or hadronic decay mode of the W boson produced by the top-quark decay in events with a single charged lepton. The cross-section is measured as a function of the transverse momentum and rapidity of both the hadronic and leptonic pseudo-top-quark as well as the transverse momentum, rapidity and invariant mass of the pseudo-top-quark pair system. The measurements are corrected for detector effects and are presented within a kinematic range that closely matches the detector acceptance.
Source
code:ATLAS_2015_I1345452.cc
// -*- C++ -*-
#include "Rivet/Analysis.hh"
#include "Rivet/Projections/FinalState.hh"
#include "Rivet/Projections/VetoedFinalState.hh"
#include "Rivet/Projections/IdentifiedFinalState.hh"
#include "Rivet/Projections/PromptFinalState.hh"
#include "Rivet/Projections/LeptonFinder.hh"
#include "Rivet/Projections/FastJets.hh"
namespace Rivet {
/// @brief ATLAS 7 TeV pseudo-top analysis
///
/// @author K .Finelli <kevin.finelli@cern.ch>
/// @author A. Saavedra <a.saavedra@physics.usyd.edu.au>
/// @author L. Lan <llan@physics.usyd.edu.au>
class ATLAS_2015_I1345452 : public Analysis {
public:
/// Constructor
RIVET_DEFAULT_ANALYSIS_CTOR(ATLAS_2015_I1345452);
void init() {
// Eta ranges
Cut eta_full = Cuts::abseta < 5.0 && Cuts::pT >= 1.0*MeV;
Cut eta_lep = Cuts::abseta < 2.5;
// All final state particles
FinalState fs(eta_full);
// Get photons to dress leptons
IdentifiedFinalState photons(fs);
photons.acceptIdPair(PID::PHOTON);
// Projection to find the electrons
IdentifiedFinalState el_id(fs);
el_id.acceptIdPair(PID::ELECTRON);
PromptFinalState electrons(el_id);
electrons.acceptTauDecays(true);
declare(electrons, "electrons");
LeptonFinder dressedelectrons(electrons, photons, 0.1, eta_lep && Cuts::pT > 25*GeV);
declare(dressedelectrons, "dressedelectrons");
LeptonFinder ewdressedelectrons(electrons, photons, 0.1, eta_full);
declare(ewdressedelectrons, "ewdressedelectrons");
LeptonFinder vetodressedelectrons(electrons, photons, 0.1, eta_lep && Cuts::pT > 15*GeV);
declare(vetodressedelectrons, "vetodressedelectrons");
// Projection to find the muons
IdentifiedFinalState mu_id(fs);
mu_id.acceptIdPair(PID::MUON);
PromptFinalState muons(mu_id);
muons.acceptTauDecays(true);
declare(muons, "muons");
LeptonFinder dressedmuons(muons, photons, 0.1, eta_lep && Cuts::pT > 25*GeV);
declare(dressedmuons, "dressedmuons");
LeptonFinder ewdressedmuons(muons, photons, 0.1, eta_full);
declare(ewdressedmuons, "ewdressedmuons");
LeptonFinder vetodressedmuons(muons, photons, 0.1, eta_lep && Cuts::pT > 15*GeV);
declare(vetodressedmuons, "vetodressedmuons");
// Projection to find neutrinos and produce MET
IdentifiedFinalState nu_id;
nu_id.acceptNeutrinos();
PromptFinalState neutrinos(nu_id);
neutrinos.acceptTauDecays(true);
declare(neutrinos, "neutrinos");
// Jet clustering.
VetoedFinalState vfs;
vfs.addVetoOnThisFinalState(ewdressedelectrons);
vfs.addVetoOnThisFinalState(ewdressedmuons);
vfs.addVetoOnThisFinalState(neutrinos);
FastJets jets(vfs, JetAlg::ANTIKT, 0.4);
jets.useInvisibles();
declare(jets, "jets");
//pseudotop leptons and hadrons
book(_h["ptpseudotophadron_mu"] , 1, 1, 2);
book(_h["ptpseudotophadron_el"] , 2, 1, 2);
book(_h["absrappseudotophadron_mu"] , 3, 1, 2);
book(_h["absrappseudotophadron_el"] , 4, 1, 2);
book(_h["ptpseudotoplepton_mu"] , 5, 1, 2);
book(_h["ptpseudotoplepton_el"] , 6, 1, 2);
book(_h["absrappseudotoplepton_mu"] , 7, 1, 2);
book(_h["absrappseudotoplepton_el"] , 8, 1, 2);
book(_h["ptttbar_mu"] , 9, 1, 2);
book(_h["ptttbar_el"] ,10, 1, 2);
book(_h["absrapttbar_mu"] ,11, 1, 2);
book(_h["absrapttbar_el"] ,12, 1, 2);
book(_h["ttbarmass_mu"] ,13, 1, 2);
book(_h["ttbarmass_el"] ,14, 1, 2);
book(_h["ptpseudotophadron"] ,15, 1, 2);
book(_h["absrappseudotophadron"] ,16, 1, 2);
book(_h["ptpseudotoplepton"] ,17, 1, 2);
book(_h["absrappseudotoplepton"] ,18, 1, 2);
book(_h["ptttbar"] ,19, 1, 2);
book(_h["absrapttbar"] ,20, 1, 2);
book(_h["ttbarmass"] ,21, 1, 2);
}
void analyze(const Event& event) {
// Get the selected objects, using the projections.
_dressedelectrons = apply<LeptonFinder>( event, "dressedelectrons").dressedLeptons();
_vetodressedelectrons = apply<LeptonFinder>( event, "vetodressedelectrons").dressedLeptons();
_dressedmuons = apply<LeptonFinder>( event, "dressedmuons").dressedLeptons();
_vetodressedmuons = apply<LeptonFinder>( event, "vetodressedmuons").dressedLeptons();
_neutrinos = apply<PromptFinalState>(event, "neutrinos").particlesByPt();
const Jets& all_jets = apply<FastJets>( event, "jets").jetsByPt(Cuts::pT > 25.0*GeV && Cuts::abseta < 2.5);
//get true l+jets events by removing events with more than 1 electron||muon neutrino
unsigned int n_elmu_neutrinos = 0;
for (const Particle & p : _neutrinos) {
if (p.abspid() == 12 || p.abspid() == 14) ++n_elmu_neutrinos;
}
if (n_elmu_neutrinos != 1) vetoEvent;
DressedLepton *lepton;
if ( _dressedelectrons.size()) lepton = &_dressedelectrons[0];
else if (_dressedmuons.size()) lepton = &_dressedmuons[0];
else vetoEvent;
// Calculate the missing ET, using the prompt neutrinos only (really?)
/// @todo Why not use MissingMomentum?
FourMomentum met;
for (const Particle& p : _neutrinos) met += p.momentum();
//remove jets if they are within dR < 0.2 of lepton
Jets jets;
for(const Jet& jet : all_jets) {
bool keep = true;
for (const DressedLepton& el : _vetodressedelectrons) {
keep &= deltaR(jet, el) >= 0.2;
}
if (keep) jets += jet;
}
bool overlap = false;
Jets bjets, lightjets;
for (unsigned int i = 0; i < jets.size(); ++i) {
const Jet& jet = jets[i];
for (const DressedLepton& el : _dressedelectrons) overlap |= deltaR(jet, el) < 0.4;
for (const DressedLepton& mu : _dressedmuons) overlap |= deltaR(jet, mu) < 0.4;
for (unsigned int j = i + 1; j < jets.size(); ++j) {
overlap |= deltaR(jet, jets[j]) < 0.5;
}
//// Count the number of b-tags
bool b_tagged = false; // This is closer to the
Particles bTags = jet.bTags(); // analysis. Something
for ( Particle b : bTags ) { // about ghost-associated
b_tagged |= b.pT() > 5*GeV; // B-hadrons
} //
if ( b_tagged ) bjets += jet;
else lightjets += jet;
}
// remove events with object overlap
if (overlap) vetoEvent;
if (bjets.size() < 2 || lightjets.size() < 2) vetoEvent;
FourMomentum pbjet1; //Momentum of bjet1
FourMomentum pbjet2; //Momentum of bjet2
if ( deltaR(bjets[0], *lepton) <= deltaR(bjets[1], *lepton) ) {
pbjet1 = bjets[0].momentum();
pbjet2 = bjets[1].momentum();
} else {
pbjet1 = bjets[1].momentum();
pbjet2 = bjets[0].momentum();
}
FourMomentum pjet1; // Momentum of jet1
if (lightjets.size()) pjet1 = lightjets[0].momentum();
FourMomentum pjet2; // Momentum of jet 2
if (lightjets.size() > 1) pjet2 = lightjets[1].momentum();
double pz = computeneutrinoz(lepton->momentum(), met);
FourMomentum ppseudoneutrino( sqrt(sqr(met.px()) + sqr(met.py()) + sqr(pz)), met.px(), met.py(), pz);
//compute leptonic, hadronic, combined pseudo-top
FourMomentum ppseudotoplepton = lepton->momentum() + ppseudoneutrino + pbjet1;
FourMomentum ppseudotophadron = pbjet2 + pjet1 + pjet2;
FourMomentum pttbar = ppseudotoplepton + ppseudotophadron;
// Evaluate basic event selection
bool pass_eljets = (_dressedelectrons.size() == 1) &&
(_vetodressedelectrons.size() < 2) &&
(_vetodressedmuons.empty()) &&
(met.pT() > 30*GeV) &&
(_mT(_dressedelectrons[0].momentum(), met) > 35*GeV) &&
(jets.size() >= 4);
bool pass_mujets = (_dressedmuons.size() == 1) &&
(_vetodressedmuons.size() < 2) &&
(_vetodressedelectrons.empty()) &&
(met.pT() > 30*GeV) &&
(_mT(_dressedmuons[0].momentum(), met) > 35*GeV) &&
(jets.size() >= 4);
// basic event selection requirements
if (!pass_eljets && !pass_mujets) vetoEvent;
// Fill histograms
//pseudotop hadrons and leptons fill histogram
_h["ptpseudotoplepton"]->fill( ppseudotoplepton.pt()); //pT of pseudo top lepton
_h["absrappseudotoplepton"]->fill(ppseudotoplepton.absrap()); //absolute rapidity of pseudo top lepton
_h["ptpseudotophadron"]->fill( ppseudotophadron.pt()); //pT of pseudo top hadron
_h["absrappseudotophadron"]->fill(ppseudotophadron.absrap()); //absolute rapidity of pseudo top hadron
_h["absrapttbar"]->fill( pttbar.absrap()); //absolute rapidity of ttbar
_h["ttbarmass"]->fill( pttbar.mass()); //mass of ttbar
_h["ptttbar"]->fill( pttbar.pt()); //fill pT of ttbar in combined channel
if (pass_eljets) { // electron channel fill histogram
_h["ptpseudotoplepton_el"]->fill( ppseudotoplepton.pt()); //pT of pseudo top lepton
_h["absrappseudotoplepton_el"]->fill(ppseudotoplepton.absrap()); //absolute rapidity of pseudo top lepton
_h["ptpseudotophadron_el"]->fill( ppseudotophadron.pt()); //pT of pseudo top hadron
_h["absrappseudotophadron_el"]->fill(ppseudotophadron.absrap()); //absolute rapidity of pseudo top hadron
_h["absrapttbar_el"]->fill( pttbar.absrap()); //absolute rapidity of ttbar
_h["ttbarmass_el"]->fill( pttbar.mass()); // fill electron channel ttbar mass
_h["ptttbar_el"]->fill( pttbar.pt()); //fill pT of ttbar in electron channel
}
else { // muon channel fill histogram
_h["ptpseudotoplepton_mu"]->fill( ppseudotoplepton.pt()); //pT of pseudo top lepton
_h["absrappseudotoplepton_mu"]->fill(ppseudotoplepton.absrap()); //absolute rapidity of pseudo top lepton
_h["ptpseudotophadron_mu"]->fill( ppseudotophadron.pt()); //pT of pseudo top hadron
_h["absrappseudotophadron_mu"]->fill(ppseudotophadron.absrap()); //absolute rapidity of pseudo top hadron
_h["absrapttbar_mu"]->fill( pttbar.absrap()); //absolute rapidity of ttbar
_h["ttbarmass_mu"]->fill( pttbar.mass()); //fill muon channel histograms
_h["ptttbar_mu"]->fill( pttbar.pt()); //fill pT of ttbar in electron channel
}
}
void finalize() {
// Normalize to cross-section
const double scalefactor(crossSection()/picobarn / sumOfWeights());
for (map<string, Histo1DPtr>::iterator hit = _h.begin(); hit != _h.end(); ++hit) {
double sf = scalefactor;
if ( (hit->first).find("_") == std::string::npos ) sf *= 0.5;
scale(hit->second, sf);
}
}
private:
double computeneutrinoz(const FourMomentum& lepton, FourMomentum& met) const {
//computing z component of neutrino momentum given lepton and met
double pzneutrino;
double m_W = 80.399; // in GeV, given in the paper
double k = (( sqr( m_W ) - sqr( lepton.mass() ) ) / 2 ) + (lepton.px() * met.px() + lepton.py() * met.py());
double a = sqr ( lepton.E() )- sqr ( lepton.pz() );
double b = -2*k*lepton.pz();
double c = sqr( lepton.E() ) * sqr( met.pT() ) - sqr( k );
double discriminant = sqr(b) - 4 * a * c;
double quad[2] = { (- b - sqrt(discriminant)) / (2 * a), (- b + sqrt(discriminant)) / (2 * a) }; //two possible quadratic solns
if (discriminant < 0) pzneutrino = - b / (2 * a); //if the discriminant is negative
else { //if the discriminant is greater than or equal to zero, take the soln with smallest absolute value
double absquad[2];
for (int n=0; n<2; ++n) absquad[n] = fabs(quad[n]);
if (absquad[0] < absquad[1]) pzneutrino = quad[0];
else pzneutrino = quad[1];
}
if ( !std::isfinite(pzneutrino) ) std::cout << "Found non-finite value\n";
return pzneutrino;
}
double _mT(const FourMomentum &l, FourMomentum &nu) const {
return sqrt( 2 * l.pT() * nu.pT() * (1 - cos(deltaPhi(l, nu))) );
}
/// @name Objects that are used by the event selection decisions
DressedLeptons _dressedelectrons, _vetodressedelectrons, _dressedmuons, _vetodressedmuons;
Particles _neutrinos;
map<string, Histo1DPtr> _h;
};
RIVET_DECLARE_PLUGIN(ATLAS_2015_I1345452);
}