ATLAS Offline Software
Loading...
Searching...
No Matches
DiTauSelectionCuts.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6// local include(s)
9
10#include "PATCore/AcceptData.h"
11#include "PATCore/AcceptInfo.h"
12
13using namespace TauAnalysisTools;
14using namespace ADD_CMODE(TauAnalysisTools);
15
16//______________________________________________________________________________
17DiTauSelectionCut::DiTauSelectionCut(const std::string& sName, DiTauSelectionTool* tDTST)
18 : m_sName(sName)
19 , m_tDTST(tDTST)
20{}
21
22//______________________________________________________________________________
23DiTauSelectionCut::~DiTauSelectionCut()
24{
25}
26
27//______________________________________________________________________________
28void DiTauSelectionCut::writeControlHistograms()
29{
30 m_hHistCutPre->Write();
31 m_hHistCut->Write();
32}
33
34//______________________________________________________________________________
35std::unique_ptr<TH1F> DiTauSelectionCut::CreateControlPlot(const char* sName, const char* sTitle, int iBins, double dXLow, double dXUp)
36{
37 if (m_tDTST->m_bCreateControlPlots)
38 {
39 auto hHist = std::make_unique<TH1F>(sName, sTitle, iBins, dXLow, dXUp);
40 hHist->SetDirectory(0);
41 return hHist;
42 }
43
44 return nullptr;
45}
46
47//______________________________________________________________________________
48void DiTauSelectionCut::fillHistogramCutPre(const xAOD::DiTauJet& xDiTau)
49{
50 fillHistogram(xDiTau, *m_hHistCutPre);
51}
52
53//______________________________________________________________________________
54void DiTauSelectionCut::fillHistogramCut(const xAOD::DiTauJet& xDiTau)
55{
56 fillHistogram(xDiTau, *m_hHistCut);
57}
58
59
60//______________________________________________________________________________
61void DiTauSelectionCut::setProperty(const std::string& name, const std::string& value)
62{
63 std::map<std::string, std::string&>::iterator it = m_mProperties.find(name);
64 if(it == m_mProperties.end() )
65 throw std::runtime_error (("Undeclared property: " + name + "\n").c_str());
66 it->second = value;
67}
68
69//______________________________________________________________________________
70void DiTauSelectionCut::declareProperty(const std::string& name, std::string& loc)
71{
72 m_mProperties.try_emplace(name, loc);
73}
74
75//______________________________________________________________________________
76std::string DiTauSelectionCut::getProperty(const std::string& name)
77{
78 std::map<std::string, std::string&>::iterator it = m_mProperties.find(name);
79 if(it == m_mProperties.end() )
80 throw std::runtime_error (("Undeclared property: " + name + "\n").c_str());
81
82 return it->second;
83}
84
85
86//_______________________________SelectionCutPt_________________________________
87//______________________________________________________________________________
88DiTauSelectionCutPt::DiTauSelectionCutPt(DiTauSelectionTool* tDTST)
89 : DiTauSelectionCut("CutPt", tDTST)
90{
91 m_hHistCutPre = CreateControlPlot("hPt_pre","Pt_pre;di-#tau-p_{T} [GeV]; events",1000,0,1000);
92 m_hHistCut = CreateControlPlot("hPt_cut","Pt_cut;di-#tau-p_{T} [GeV]; events",1000,0,1000);
93}
94
95//______________________________________________________________________________
96void DiTauSelectionCutPt::fillHistogram(const xAOD::DiTauJet& xDiTau, TH1F& hHist) const
97{
98 hHist.Fill(xDiTau.pt()/1000.);
99}
100
101//______________________________________________________________________________
102void DiTauSelectionCutPt::setAcceptInfo(asg::AcceptInfo& info) const
103{
104 info.addCut( "Pt",
105 "Selection of ditaus according to their transverse momentum" );
106}
107//______________________________________________________________________________
108bool DiTauSelectionCutPt::accept(const xAOD::DiTauJet& xDiTau,
109 asg::AcceptData& acceptData)
110{
111 // save ditau pt in GeV
112 double pt = xDiTau.pt() / 1000.;
113 // in case of only one entry in vector, run for lower limits
114 if (m_tDTST->m_vPtRegion.size() == 1)
115 {
116 if ( pt >= m_tDTST->m_vPtRegion.at(0) )
117 {
118 acceptData.setCutResult( "Pt", true );
119 return true;
120 }
121 }
122 unsigned int iNumPtRegion = m_tDTST->m_vPtRegion.size()/2;
123 for( unsigned int iPtRegion = 0; iPtRegion < iNumPtRegion; iPtRegion++ )
124 {
125 if ( pt >= m_tDTST->m_vPtRegion.at(iPtRegion*2) and pt <= m_tDTST->m_vPtRegion.at(iPtRegion*2+1))
126 {
127 acceptData.setCutResult( "Pt", true );
128 return true;
129 }
130 }
131 m_tDTST->msg() << MSG::VERBOSE << "DiTau failed pt requirement, ditau pt [GeV]: " << pt << endmsg;
132 return false;
133}
134
135//_____________________________SelectionCutAbsEta_______________________________
136//______________________________________________________________________________
137DiTauSelectionCutAbsEta::DiTauSelectionCutAbsEta(DiTauSelectionTool* tDTST)
138 : DiTauSelectionCut("CutAbsEta", tDTST)
139{
140 m_hHistCutPre = CreateControlPlot("hEta_pre","Eta_pre;di-#tau-#eta; events",100,-3,3);
141 m_hHistCut = CreateControlPlot("hEta_cut","Eta_cut;di-#tau-#eta; events",100,-3,3);
142}
143
144//______________________________________________________________________________
145void DiTauSelectionCutAbsEta::fillHistogram(const xAOD::DiTauJet& xDiTau, TH1F& hHist) const
146{
147 hHist.Fill(xDiTau.eta());
148}
149
150//______________________________________________________________________________
151void DiTauSelectionCutAbsEta::setAcceptInfo(asg::AcceptInfo& info) const
152{
153 info.addCut( "AbsEta",
154 "Selection of ditaus according to their absolute pseudorapidity" );
155}
156//______________________________________________________________________________
157bool DiTauSelectionCutAbsEta::accept(const xAOD::DiTauJet& xDiTau,
158 asg::AcceptData& acceptData)
159{
160 // check regions of eta, if ditau is in one region then return true; false otherwise
161 unsigned int iNumEtaRegion = m_tDTST->m_vAbsEtaRegion.size()/2;
162 for( unsigned int iEtaRegion = 0; iEtaRegion < iNumEtaRegion; iEtaRegion++ )
163 {
164 if ( std::abs( xDiTau.eta() ) >= m_tDTST->m_vAbsEtaRegion.at(iEtaRegion*2) and std::abs( xDiTau.eta() ) <= m_tDTST->m_vAbsEtaRegion.at(iEtaRegion*2+1))
165 {
166 acceptData.setCutResult( "AbsEta", true );
167 return true;
168 }
169 }
170 m_tDTST->msg() << MSG::VERBOSE << "DiTau failed eta requirement, ditau eta: " << xDiTau.eta() << endmsg;
171 return false;
172}
173
174//_______________________________SelectionCutNSubjets_________________________________
175//______________________________________________________________________________
176DiTauSelectionCutNSubjets::DiTauSelectionCutNSubjets(DiTauSelectionTool* tDTST)
177 : DiTauSelectionCut("CutNSubjets", tDTST)
178{
179 m_hHistCutPre = CreateControlPlot("hNSubjets_pre","NSubjets_pre;di-#tau NSubjets; events",30,0,30);
180 m_hHistCut = CreateControlPlot("hNSubjets_cut","NSubjets_cut;di-#tau NSubjets; events",30,0,30);
181}
182
183//______________________________________________________________________________
184void DiTauSelectionCutNSubjets::fillHistogram(const xAOD::DiTauJet& xDiTau, TH1F& hHist) const
185{
186 hHist.Fill(xDiTau.nSubjets());
187}
188
189//______________________________________________________________________________
190void DiTauSelectionCutNSubjets::setAcceptInfo(asg::AcceptInfo& info) const
191{
192 info.addCut( "NSubjets",
193 "Selection of ditaus according to their number of subjets" );
194}
195//______________________________________________________________________________
196bool DiTauSelectionCutNSubjets::accept(const xAOD::DiTauJet& xDiTau,
197 asg::AcceptData& acceptData)
198{
199 float nsubjets = xDiTau.nSubjets();
200 // in case of only one entry in vector, run for lower limits
201 if (m_tDTST->m_vNSubjetsRegion.size() == 1)
202 {
203 if ( nsubjets >= m_tDTST->m_vNSubjetsRegion.at(0) )
204 {
205 acceptData.setCutResult( "NSubjets", true );
206 return true;
207 }
208 }
209 unsigned int iNumNSubjetsRegion = m_tDTST->m_vNSubjetsRegion.size()/2;
210 for( unsigned int iNSubjetsRegion = 0; iNSubjetsRegion < iNumNSubjetsRegion; iNSubjetsRegion++ )
211 {
212 if ( nsubjets >= m_tDTST->m_vNSubjetsRegion.at(iNSubjetsRegion*2) and nsubjets <= m_tDTST->m_vNSubjetsRegion.at(iNSubjetsRegion*2+1))
213 {
214 acceptData.setCutResult( "NSubjets", true );
215 return true;
216 }
217 }
218 m_tDTST->msg() << MSG::VERBOSE << "DiTau failed NSubjets requirement, ditau number of subjets: " << nsubjets << endmsg;
219 return false;
220}
221
222//____________________________SelectionCutAbsCharge_____________________________
223//______________________________________________________________________________
224DiTauSelectionCutAbsCharge::DiTauSelectionCutAbsCharge(DiTauSelectionTool* tDTST)
225 : DiTauSelectionCut("CutAbsCharge", tDTST),
226 m_bDiTauCharge(-1234)
227{
228 m_hHistCutPre = CreateControlPlot("hCharge_pre","Charge_pre;charge; events",7,-3.5,3.5);
229 m_hHistCut = CreateControlPlot("hCharge_cut","Charge_cut;charge; events",7,-3.5,3.5);
230}
231
232//______________________________________________________________________________
233void DiTauSelectionCutAbsCharge::fillHistogram(const xAOD::DiTauJet& /*xTau*/, TH1F& hHist) const
234{
235 hHist.Fill(m_bDiTauCharge);
236}
237
238//______________________________________________________________________________
239void DiTauSelectionCutAbsCharge::setAcceptInfo(asg::AcceptInfo& info) const
240{
241 info.addCut( "AbsCharge",
242 "Selection of taus according to their absolute charge" );
243}
244//______________________________________________________________________________
245bool DiTauSelectionCutAbsCharge::accept(const xAOD::DiTauJet& xTau,
246 asg::AcceptData& acceptData)
247{
248 m_bDiTauCharge = 0;
249 static const SG::ConstAccessor<float> acc_charge ("charge");
250 if ( acc_charge.isAvailable(xTau) ) {
251 m_bDiTauCharge = acc_charge(xTau);
252 } else {
253 for (const auto& xTrack : xTau.trackLinks()) {
254 if (!xTrack.isValid())
255 continue;
256
257 if(xTau.nSubjets() >= 2){
258 for (int i = 0; i < 2; ++i) { // loop over two leading subjets
259 TLorentzVector tlvSubjet = TLorentzVector();
260 tlvSubjet.SetPtEtaPhiE(xTau.subjetPt(i), xTau.subjetEta(i),
261 xTau.subjetPhi(i), xTau.subjetE(i));
262 double dR = tlvSubjet.DeltaR((*xTrack)->p4());
263 if (dR < 0.1) {
264 m_bDiTauCharge += (*xTrack)->charge();
265 break; //prevents double counting of tracks
266 }
267 } // loop over subjets
268 }
269 } // loop over tracks
270 }
271
272 // check charge, if ditau has one of the charges requiered then return true; false otherwise
273 for( unsigned int iCharge = 0; iCharge < m_tDTST->m_vAbsCharges.size(); iCharge++ )
274 {
275 if ( std::abs( m_bDiTauCharge ) == m_tDTST->m_vAbsCharges.at(iCharge) )
276 {
277 acceptData.setCutResult( "AbsCharge", true );
278 return true;
279 }
280 }
281 m_tDTST->msg() << MSG::VERBOSE << "DiTau failed charge requirement, ditau charge: " << m_bDiTauCharge << endmsg;
282 return false;
283
284}
285
286//___________________________SelectionCutOmniScore_____________________________
287//______________________________________________________________________________
288DiTauSelectionCutOmniScore::DiTauSelectionCutOmniScore(DiTauSelectionTool* tDTST)
289 : DiTauSelectionCut("CutOmniScore", tDTST)
290{
291 m_hHistCutPre = CreateControlPlot("hOmniScore_pre","OmniScore_pre;OmniScore; events",100,0,1);
292 m_hHistCut = CreateControlPlot("hOmniScore_cut","OmniScore_cut;OmniScore; events",100,0,1);
293}
294//______________________________________________________________________________
295void DiTauSelectionCutOmniScore::fillHistogram(const xAOD::DiTauJet& xTau, TH1F& hHist) const
296{
297 static const SG::ConstAccessor<float> acc_OmniScore("omni_score");
298 hHist.Fill(acc_OmniScore(xTau));
299}
300//______________________________________________________________________________
301void DiTauSelectionCutOmniScore::setAcceptInfo(asg::AcceptInfo& info) const
302{
303 info.addCut( "OmniScore",
304 "Selection of taus according to their OmniScore" );
305}
306//______________________________________________________________________________
307bool DiTauSelectionCutOmniScore::accept(const xAOD::DiTauJet& xTau,
308 asg::AcceptData& acceptData)
309{
310 // check OmniScore score, if tau has a OmniScore score in one of the regions requiered then return true; false otherwise
311 static const SG::ConstAccessor<float> acc ("omni_score");
312 float dOmniScore = acc(xTau);
313 unsigned int iNumOmniScoreRegion = m_tDTST->m_vOmniScoreRegion.size()/2;
314 for( unsigned int iOmniScoreRegion = 0; iOmniScoreRegion < iNumOmniScoreRegion; iOmniScoreRegion++ )
315 {
316 if ( dOmniScore >= m_tDTST->m_vOmniScoreRegion.at(iOmniScoreRegion*2) and dOmniScore <= m_tDTST->m_vOmniScoreRegion.at(iOmniScoreRegion*2+1))
317 {
318 acceptData.setCutResult( "OmniScore", true );
319 return true;
320 }
321 }
322 m_tDTST->msg() << MSG::VERBOSE << "Tau failed OmniScore requirement, tau OmniScore: " << dOmniScore << endmsg;
323 return false;
324}
325
326//_____________________________SelectionCutOmniIDWP______________________________
327//_______________________________________________________________________________
328DiTauSelectionCutOmniIDWP::DiTauSelectionCutOmniIDWP(DiTauSelectionTool* tDTST)
329 : DiTauSelectionCut("CutOmniIDWP", tDTST)
330{
331 m_hHistCutPre = CreateControlPlot("hOmniIDWP_pre","OmniIDWP_pre;; events",8,-.5,7.5);
332 m_hHistCut = CreateControlPlot("hOmniIDWP_cut","OmniIDWP_cut;; events",8,-.5,7.5);
333 // only proceed if histograms are defined
334 if (!m_hHistCutPre or !m_hHistCut)
335 return;
336
337 m_hHistCutPre->GetXaxis()->SetBinLabel(1,"!VeryLoose");
338 m_hHistCutPre->GetXaxis()->SetBinLabel(2,"VeryLoose");
339 m_hHistCutPre->GetXaxis()->SetBinLabel(3,"!Loose");
340 m_hHistCutPre->GetXaxis()->SetBinLabel(4,"Loose");
341 m_hHistCutPre->GetXaxis()->SetBinLabel(5,"!Medium");
342 m_hHistCutPre->GetXaxis()->SetBinLabel(6,"Medium");
343 m_hHistCutPre->GetXaxis()->SetBinLabel(7,"!Tight");
344 m_hHistCutPre->GetXaxis()->SetBinLabel(8,"Tight");
345 m_hHistCut->GetXaxis()->SetBinLabel(1,"!VeryLoose");
346 m_hHistCut->GetXaxis()->SetBinLabel(2,"VeryLoose");
347 m_hHistCut->GetXaxis()->SetBinLabel(3,"!Loose");
348 m_hHistCut->GetXaxis()->SetBinLabel(4,"Loose");
349 m_hHistCut->GetXaxis()->SetBinLabel(5,"!Medium");
350 m_hHistCut->GetXaxis()->SetBinLabel(6,"Medium");
351 m_hHistCut->GetXaxis()->SetBinLabel(7,"!Tight");
352 m_hHistCut->GetXaxis()->SetBinLabel(8,"Tight");
353}
354
355//______________________________________________________________________________
356void DiTauSelectionCutOmniIDWP::fillHistogram(const xAOD::DiTauJet& xTau, TH1F& hHist) const
357{
358 if(m_tDTST->m_useOmniScore){
359 static const SG::ConstAccessor<char> acc_OmniVeryLoose("omni_score_VL");
360 static const SG::ConstAccessor<char> acc_OmniLoose("omni_score_L");
361 static const SG::ConstAccessor<char> acc_OmniMedium("omni_score_M");
362 static const SG::ConstAccessor<char> acc_OmniTight("omni_score_T");
363 hHist.Fill(acc_OmniVeryLoose(xTau));
364 hHist.Fill(acc_OmniLoose(xTau)+2);
365 hHist.Fill(acc_OmniMedium(xTau)+4);
366 hHist.Fill(acc_OmniTight(xTau)+6);
367 }
368}
369
370//______________________________________________________________________________
371void DiTauSelectionCutOmniIDWP::setAcceptInfo(asg::AcceptInfo& info) const
372{
373 info.addCut( "OmniIDWP",
374 "Selection of ditaus according to their OmniIDScore" );
375}
376//______________________________________________________________________________
377bool DiTauSelectionCutOmniIDWP::accept(const xAOD::DiTauJet& xTau,
378 asg::AcceptData& acceptData)
379{
380 // check Omni ID working point, if ditau passes OmniID working point then return true; false otherwise
381 bool bPass = false;
382 switch (m_tDTST->m_iOmniIDWP)
383 {
384 case OMNIIDNONE:
385 bPass = true;
386 break;
387 case OMNIIDVERYLOOSE:
388 static const SG::ConstAccessor<char> acc_OmniVeryLoose("omni_score_VL");
389 if (!acc_OmniVeryLoose.isAvailable(xTau)) m_tDTST->msg() << MSG::WARNING << "Omni VeryLoose WP not available" << endmsg;
390 else bPass = acc_OmniVeryLoose(xTau);
391 break;
392 case OMNIIDLOOSE:
393 static const SG::ConstAccessor<char> acc_OmniLoose("omni_score_L");
394 if (!acc_OmniLoose.isAvailable(xTau)) m_tDTST->msg() << MSG::WARNING << "Omni Loose WP not available" << endmsg;
395 else bPass = acc_OmniLoose(xTau);
396 break;
397 case OMNIIDMEDIUM:
398 static const SG::ConstAccessor<char> acc_OmniMedium("omni_score_M");
399 if (!acc_OmniMedium.isAvailable(xTau)) m_tDTST->msg() << MSG::WARNING << "Omni Medium WP not available" << endmsg;
400 else bPass = acc_OmniMedium(xTau);
401 break;
402 case OMNIIDTIGHT:
403 static const SG::ConstAccessor<char> acc_OmniTight("omni_score_T");
404 if (!acc_OmniTight.isAvailable(xTau)) m_tDTST->msg() << MSG::WARNING << "Omni Tight WP not available" << endmsg;
405 else bPass = acc_OmniTight(xTau);
406 break;
407 default:
408 m_tDTST->msg() << MSG::WARNING << "The Omni ID working point with the enum " << m_tDTST->m_iOmniIDWP << " is not available" << endmsg;
409 break;
410 }
411 if (bPass)
412 {
413 acceptData.setCutResult( "OmniIDWP", true );
414 return true;
415 }
416 m_tDTST->msg() << MSG::VERBOSE << "DiTau failed OmniIDWP requirement" << endmsg;
417 return false;
418}
419
420
#define endmsg
#define ADD_CMODE(name)
Helper class to provide constant type-safe access to aux data.
void setCutResult(const std::string &cutName, bool cutResult)
Set the result of a cut, based on the cut name (safer).
Definition AcceptData.h:135
virtual double eta() const
The pseudorapidity ( ) of the particle.
float subjetEta(unsigned int numSubjet) const
virtual double pt() const
The transverse momentum ( ) of the particle.
float subjetE(unsigned int numSubjet) const
float subjetPt(unsigned int numSubjet) const
float subjetPhi(unsigned int numSubjet) const
const TrackParticleLinks_t & trackLinks() const
float nSubjets() const
DiTauJet_v1 DiTauJet
Definition of the current version.
Definition DiTauJet.h:17