file analyses/Analysis_ATLAS_13TeV_bTaus_StopStau_139invfb.cpp
[No description available]
Namespaces
| Name |
|---|
| Gambit TODO: see if we can use this one: |
| Gambit::ColliderBit |
Classes
| Name | |
|---|---|
| class | Gambit::ColliderBit::Analysis_ATLAS_13TeV_bTaus_StopStau_139invfb |
Source code
///
/// \author Holly Pacey
/// \date 2023 September
///
/// *********************************************
// Based on https://atlas.web.cern.ch/Atlas/GROUPS/PHYSICS/PAPERS/SUSY-2019-18/
// Luminosity: 139 fb^-1
#include <vector>
#include <cmath>
#include <memory>
#include <iomanip>
#include <algorithm>
#include <fstream>
#include "gambit/ColliderBit/analyses/Analysis.hpp"
#include "gambit/ColliderBit/analyses/AnalysisMacros.hpp"
#include "gambit/ColliderBit/ATLASEfficiencies.hpp"
#include "gambit/ColliderBit/analyses/Cutflow.hpp"
#include "gambit/ColliderBit/mt2_bisect.h"
using namespace std;
namespace Gambit
{
namespace ColliderBit
{
class Analysis_ATLAS_13TeV_bTaus_StopStau_139invfb : public Analysis
{
private:
struct ptComparison
{
bool operator() (const HEPUtils::Particle* i,const HEPUtils::Particle* j) {return (i->pT()>j->pT());}
} comparePt;
struct ptJetComparison
{
bool operator() (const HEPUtils::Jet* i,const HEPUtils::Jet* j) {return (i->pT()>j->pT());}
} compareJetPt;
public:
// Required detector sim
static constexpr const char* detector = "ATLAS";
Analysis_ATLAS_13TeV_bTaus_StopStau_139invfb()
{
// std::cout<<"define analysis"<<std::endl;
set_analysis_name("ATLAS_13TeV_bTaus_StopStau_139invfb");
set_detector_name(detector);
set_luminosity(139);
//
// // Counters for the number of accepted events for each signal region
defineSignalRegion("SRdiTau_cuts_0", "di-tau preselection", "OS(tau1,tau2) == 1", "MET > 280 GeV");//, "mT2 > 70 GeV");
defineSignalRegion("SRsingleTau_pT50-100_cuts_0", "single-tau Preselection", "MET > 280 GeV", "mTtau > 150 GeV", "summTb > 700 GeV", "sT > 600 GeV");//, "pTtau1: [50, 100] GeV");
defineSignalRegion("SRsingleTau_pT100-200_cuts_0", "single-tau Preselection", "MET > 280 GeV", "mTtau > 150 GeV", "summTb > 700 GeV", "sT > 600 GeV");//, "pTtau1: [100, 200] GeV");
defineSignalRegion("SRsingleTau_pT200_cuts_0", "single-tau Preselection", "MET > 280 GeV", "mTtau > 150 GeV", "summTb > 700 GeV", "sT > 600 GeV");//, "pTtau1 > 200 GeV");
//
}
//
void run(const HEPUtils::Event* event)
{
// std::cout<<"start of run"<<std::endl;
// Baseline objects
vector<const HEPUtils::Particle*> baselineElectrons;
vector<const HEPUtils::Particle*> baselineMuons;
vector<const HEPUtils::Particle*> baselineLeptons;
vector<const HEPUtils::Particle*> baselineTaus;
vector<const HEPUtils::Jet*> baselineJets;
// Missing momentum and energy
HEPUtils::P4 metVec = event->missingmom();
double met = event->met();
// Baseline electrons have pT > 10 GeV, satisfy the "looseAndBLayer" ID criteria, and have |eta|<2.47.
for (const HEPUtils::Particle* electron : event->electrons())
{
if (electron->pT() > 10. && electron->abseta() < 2.47) baselineElectrons.push_back(electron);
}
// Apply electron efficiency
// LooseAndBLayer electron ID selection
applyEfficiency(baselineElectrons, ATLAS::eff1DEl.at("PERF_2017_01_ID_Loose"));
// Baseline muons have satisfy "medium" criteria and have pT > 10 GeV and |eta| < 2.7
for (const HEPUtils::Particle* muon : event->muons())
{
if (muon->pT() > 10. && muon->abseta() < 2.7) baselineMuons.push_back(muon);
}
// Apply muon efficiency
// TODO Missing: "Medium" muon ID criteria
applyEfficiency(baselineMuons, ATLAS::eff2DMu.at("R2"));
// TODO Missing: impact parameter cuts
// Only jet candidates with pT > 20 GeV and |η| < 2.8 are considered in the analysis
// TODO Missing: cut based on detector noise and non-collision backgrounds
float JVTeff = 0.95;
for (const HEPUtils::Jet* jet : event->jets("antikt_R04"))
{
if (jet->pT()>20. && jet->abseta()<2.8)
{
if ((jet->pT()<60. && jet->abseta()<2.4 && random_bool(JVTeff)) || jet->pT()>60. || jet->abseta()>2.4) baselineJets.push_back(jet);
}
}
// Baseline taus have pT > 10 GeV, satisfy the "medium" RNN ID criteria, and have |eta|<2.5, and not 1.37<|eta|<1.52
// need charge to be +-1 too.
for (const HEPUtils::Particle* tau : event->taus())
{
if (tau->pT() > 10 && tau->abspid()==15 && tau->abseta() < 2.5 && (tau->abseta()>1.52 || tau->abseta()<1.37))
{
// Veto electrons that fake 1-prong hadronic taus
// If DeltaR(tau,e) and e pt>5 GeV keep 95% of 1prong Loose ID taus
// 0.05*0.85 = 0.0425
bool vetoTau = false;
for (const HEPUtils::Particle* electron : baselineElectrons)
{
if (tau->mom().deltaR2_eta(electron->mom())<0.4 && electron->pT()>5.)
{
if (random_bool(0.0425)) vetoTau = true;
}
}
if (!vetoTau) baselineTaus.push_back(tau);
}
}
// Apply tau efficiency RNN Medium ID https://cds.cern.ch/record/2688062/
applyEfficiency(baselineTaus, ATLAS::effTau.at("R2_RNN_Medium"));
// Overlap removal
// 1) Remove taus within DeltaRy 0.2 of an electron
removeOverlap(baselineTaus, baselineElectrons, 0.2, true);
// 2) Remove taus within DeltaRy 0.2 of an muon
removeOverlap(baselineTaus, baselineMuons, 0.2, true);
// 3) Remove electron if share tracks with a muon
removeOverlap(baselineElectrons, baselineMuons, 0.01);
// 4) Remove jets if within DeltaRy 0.2 of an electron
removeOverlap(baselineJets, baselineElectrons, 0.2, true);
// 5) Remove electrons if within DeltaRy 0.4 of a jet
removeOverlap(baselineElectrons, baselineJets, 0.4, true);
// 6) Remove jet if share tracks with a muon
removeOverlap(baselineJets, baselineMuons, 0.01);
// 7) Remove jets if within DeltaRy 0.2 of an muon
removeOverlap(baselineJets, baselineMuons, 0.2, true);
// 8) Remove electrons if within DeltaRy 0.4 of a jet
removeOverlap(baselineMuons, baselineJets, 0.4, true);
// Signal objects
vector<const HEPUtils::Jet*> signalJets = baselineJets;
vector<const HEPUtils::Jet*> signalBJets;
vector<const HEPUtils::Particle*> signalTaus = baselineTaus;
// Find b-jets
double btag = 0.77; double cmisstag = 0.067; double misstag = 0.009;
for (const HEPUtils::Jet* jet : signalJets)
{
// Tag
if( jet->btag() && random_bool(btag) ) signalBJets.push_back(jet);
// Misstag c-jet
else if( jet->ctag() && random_bool(cmisstag) ) signalBJets.push_back(jet);
// Misstag light jet
else if( random_bool(misstag) ) signalBJets.push_back(jet);
}
// Sort by pT
sort(signalJets.begin(), signalJets.end(), compareJetPt);
sort(signalBJets.begin(), signalBJets.end(), compareJetPt);
sort(signalTaus.begin(), signalTaus.end(), comparePt);
int n_electrons = baselineElectrons.size();
int n_muons = baselineMuons.size();
int n_taus = signalTaus.size();
int n_jets = signalJets.size();
int n_bjets = signalBJets.size();
/* Preselection */
// True if passes this cut, false otherwise
bool bTaus_presel = false; // Total Pre-selection cut
bool bTaus_singleTau_presel = false; // single-tau Pre-selection cut
bool bTaus_diTau_presel = false; // di-tau Pre-selection cut
// Perform all pre-selection cuts
BEGIN_PRESELECTION
while(true)
{
// Passes the MET Trigger plateau cut
if (!(met > 250.))
{
break;
}
// Passes the light lepton vetoes
if (!(n_electrons == 0) || !(n_muons == 0))
{
break;
}
// Passes the jet selection
if (!(n_jets >= 2))
{
break;
}
// Set common preselection as passed :)
bTaus_presel = true;
// Passes the single-tau preselection
if (n_taus == 1 && n_bjets >= 2)
{
bTaus_singleTau_presel = true;
}
// Passes the di-tau preselection
else if (n_taus >= 2 && n_bjets >= 1){
bTaus_diTau_presel = true;
}
// Applied all cuts
break;
}
// If event doesn't pass Pre-selection, exit early
if (!bTaus_presel) return;
END_PRESELECTION
/* Signal Regions */
// Initialise some useful variables
double mT2 = -1.;
double sT = -1.;
double mTtau = -1.;
double summTb = -1.;
double pTtau1 = -1.;
// Calculate them
if (bTaus_diTau_presel)
{
mT2 = get_mT2(signalTaus.at(0), signalTaus.at(1), metVec, 0.);
}
else if (bTaus_singleTau_presel)
{
sT = signalTaus.at(0)->pT() + signalJets.at(0)->pT() + signalJets.at(1)->pT();
mTtau = get_mT(signalTaus.at(0), metVec);
summTb = get_mT(signalBJets.at(0)->mom(), metVec) + get_mT(signalBJets.at(1)->mom(), metVec);
pTtau1 = signalTaus.at(0)->pT();
}
// SR di-tau
while (true)
{
if (bTaus_diTau_presel)
{
// std::cout<<"passed presel"<<std::endl;
LOG_CUT("SRdiTau_cuts_0");
}
else {break;}
if (signalTaus.at(0)->pid()*signalTaus.at(1)->pid()<0)
{
// std::cout<<"OS pair"<<std::endl;
LOG_CUT("SRdiTau_cuts_0");
}
else {break;}
if (met > 280.)
{
// std::cout<<"met>280"<<std::endl;
LOG_CUT("SRdiTau_cuts_0");
}
else {break;}
if (mT2 > 70.)
{
// std::cout<<"mt2>70"<<std::endl;
FILL_SIGNAL_REGION("SRdiTau_cuts_0");
}
// Applied all cuts
break;
}
// SR signal-tau
while (true)
{
if (bTaus_singleTau_presel)
{
// std::cout<<"presel passed"<<std::endl;
LOG_CUT("SRsingleTau_pT50-100_cuts_0", "SRsingleTau_pT100-200_cuts_0", "SRsingleTau_pT200_cuts_0");
}
else {break;}
if (met > 280.)
{
// std::cout<<"met>280"<<std::endl;
LOG_CUT("SRsingleTau_pT50-100_cuts_0", "SRsingleTau_pT100-200_cuts_0", "SRsingleTau_pT200_cuts_0");
}
else {break;}
if (mTtau > 150.)
{
// std::cout<<"mTtau>150"<<std::endl;
LOG_CUT("SRsingleTau_pT50-100_cuts_0", "SRsingleTau_pT100-200_cuts_0", "SRsingleTau_pT200_cuts_0");
}
else {break;}
if (summTb > 700.)
{
// std::cout<<"summTb>700"<<std::endl;
LOG_CUT("SRsingleTau_pT50-100_cuts_0", "SRsingleTau_pT100-200_cuts_0", "SRsingleTau_pT200_cuts_0");
}
else {break;}
if (sT > 600.)
{
// std::cout<<"sT>600"<<std::endl;
LOG_CUT("SRsingleTau_pT50-100_cuts_0", "SRsingleTau_pT100-200_cuts_0", "SRsingleTau_pT200_cuts_0");
}
else {break;}
if (pTtau1 > 50. && pTtau1 <= 100.)
{
// std::cout<<"pTtau1=[0,100]"<<std::endl;
FILL_SIGNAL_REGION("SRsingleTau_pT50-100_cuts_0");
}
else if (pTtau1 > 100. && pTtau1 <= 200.)
{
// std::cout<<"pTtau1=[100,200]"<<std::endl;
FILL_SIGNAL_REGION("SRsingleTau_pT100-200_cuts_0");
}
else if (pTtau1 > 200.)
{
// std::cout<<"pTtau1>200"<<std::endl;
FILL_SIGNAL_REGION("SRsingleTau_pT200_cuts_0");
}
// Applied all cuts
break;
}
// std::cout<<"end of run"<<std::endl;
} // End run function
// This function can be overridden by the derived SR-specific classes
virtual void collect_results()
{
// std::cout<<"collect results"<<std::endl;
// Obs. Exp. Err.
COMMIT_SIGNAL_REGION("SRsingleTau_pT50-100_cuts_0", 8., 10.1, 1.8);
COMMIT_SIGNAL_REGION("SRsingleTau_pT100-200_cuts_0", 6., 5.1, 1.1);
COMMIT_SIGNAL_REGION("SRsingleTau_pT200_cuts_0", 2., 2.05, 0.64);
COMMIT_SIGNAL_REGION("SRdiTau_cuts_0", 2., 4.1, 1.0);
COMMIT_CUTFLOWS;
}
protected:
void analysis_specific_reset()
{
// std::cout<<"analysis_specific_reset"<<std::endl;
for (auto& pair : _counters)
{
pair.second.reset();
}
}
};
// Factory fn
DEFINE_ANALYSIS_FACTORY(ATLAS_13TeV_bTaus_StopStau_139invfb)
}
}
Updated on 2026-11-03 at 14:50:47 +0000