ATLAS Offline Software
TrigTauMonitorTruthAlgorithm.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
10 
11 
12 TrigTauMonitorTruthAlgorithm::TrigTauMonitorTruthAlgorithm(const std::string& name, ISvcLocator* pSvcLocator)
13  : TrigTauMonitorBaseAlgorithm(name, pSvcLocator)
14 {}
15 
16 
19 
21 
22  return StatusCode::SUCCESS;
23 }
24 
25 
26 std::pair<std::vector<std::shared_ptr<xAOD::TruthParticle>>, std::vector<std::shared_ptr<xAOD::TruthParticle>>> TrigTauMonitorTruthAlgorithm::getTruthTaus(const EventContext& ctx, const float threshold) const
27 {
28  std::vector<std::shared_ptr<xAOD::TruthParticle>> true_taus_1p;
29  std::vector<std::shared_ptr<xAOD::TruthParticle>> true_taus_3p;
30 
31  // Truth Taus distributions
33  if(!truth_cont.isValid()) {
34  ATH_MSG_WARNING("Failed to retrieve truth Taus");
35  return {true_taus_1p, true_taus_3p};
36  }
37 
38  // Fill truth tau containers
39  for(const auto xTruthParticle : *truth_cont) {
40  if(xTruthParticle->isTau()) {
41  ATH_MSG_DEBUG("Tau with status " << xTruthParticle->status() << " and charge " << xTruthParticle->charge());
42 
43  // Create a copy of the original TruthParticle, to augment it with tau-specific properties
44  std::shared_ptr xTruthTau = std::make_shared<xAOD::TruthParticle>();
45  xTruthTau->makePrivateStore(*xTruthParticle);
46 
47  // Keep only truth taus
48  if(examineTruthTau(xTruthTau).isFailure()) continue;
49 
50  // Keep only the hadronic decay mode
51  static const SG::ConstAccessor<char> IsLeptonicTauAcc("IsLeptonicTau");
52  if(IsLeptonicTauAcc(*xTruthTau)) continue;
53 
54  static const SG::ConstAccessor<double> pt_visAcc("pt_vis");
55  static const SG::ConstAccessor<double> eta_visAcc("eta_vis");
56  float pt = pt_visAcc(*xTruthTau);
57  float eta = eta_visAcc(*xTruthTau);
58  ATH_MSG_DEBUG("True Tau visible pt: " << pt << ", eta: " << eta);
59 
60  // Keep only truth taus in the barrel region, with a pT > 20 GeV (offline minimum threshold)
61  if(pt < threshold || std::abs(eta) > 2.47) continue;
62 
63  static const SG::ConstAccessor<int> nTracksAcc("nTracks");
64  if(nTracksAcc(*xTruthTau) == 1) true_taus_1p.push_back(xTruthTau);
65  else if(nTracksAcc(*xTruthTau) == 3) true_taus_3p.push_back(xTruthTau);
66  }
67  }
68 
69  return {true_taus_1p, true_taus_3p};
70 }
71 
72 
73 StatusCode TrigTauMonitorTruthAlgorithm::examineTruthTau(const std::shared_ptr<xAOD::TruthParticle>& xTruthTau) const
74 {
75  if(!xTruthTau->hasDecayVtx()) return StatusCode::FAILURE;
76 
77  static const SG::Decorator<char> IsLeptonicTauDec("IsLeptonicTau");
78  IsLeptonicTauDec(*xTruthTau) = false;
79 
80  TLorentzVector VisSumTLV;
81  static const SG::Decorator<double> pt_visDec("pt_vis");
82  static const SG::Decorator<double> eta_visDec("eta_vis");
83  static const SG::Decorator<double> phi_visDec("phi_vis");
84  static const SG::Decorator<double> mvisDec("mvis");
85  static const SG::Decorator<int> childChargeSumDec("childChargeSum");
86  static const SG::Decorator<int> nTracksDec("nTracks");
87  pt_visDec(*xTruthTau) = 0;
88  eta_visDec(*xTruthTau) = 0;
89  phi_visDec(*xTruthTau) = 0;
90  mvisDec(*xTruthTau) = 0;
91  childChargeSumDec(*xTruthTau) = 0;
92  nTracksDec(*xTruthTau) = 0;
93 
94  const xAOD::TruthVertex* decayvtx = xTruthTau->decayVtx();
95  if(decayvtx) {
96  const std::size_t nChildren = decayvtx->nOutgoingParticles();
97  for(std::size_t iChild = 0; iChild != nChildren; ++iChild) {
98  const xAOD::TruthParticle* child = decayvtx->outgoingParticle(iChild);
99  if(child) {
100  if(MC::isSMNeutrino(child)) continue;
101  if(!MC::isPhysical(child)) continue;
102  ATH_MSG_DEBUG("Child " << child->pdgId() << ", status " << child->status() << ", charge " << child->charge());
103  if(MC::isSMLepton(child)) IsLeptonicTauDec(*xTruthTau) = true; // Just selects charged SM Leptons as we have already skipped SM neutrinos
104  VisSumTLV += child->p4();
105  childChargeSumDec(*xTruthTau) += child->charge();
106  nTracksDec(*xTruthTau) += std::abs(child->charge());
107  }
108  }
109  }
110 
111  pt_visDec(*xTruthTau) = VisSumTLV.Pt();
112  eta_visDec(*xTruthTau) = VisSumTLV.Eta();
113  phi_visDec(*xTruthTau) = VisSumTLV.Phi();
114  mvisDec(*xTruthTau) = VisSumTLV.M();
115 
116  if(childChargeSumDec(*xTruthTau) != xTruthTau->charge() || nTracksDec(*xTruthTau)%2 == 0) {
117  ATH_MSG_WARNING("Strange tau: charge " << childChargeSumDec(*xTruthTau) << " and " << nTracksDec(*xTruthTau) << " tracks");
118  const std::size_t nChildren = decayvtx->nOutgoingParticles();
119  for(std::size_t iChild = 0; iChild != nChildren; ++iChild) {
120  const xAOD::TruthParticle * child = decayvtx->outgoingParticle(iChild);
121  if(child) ATH_MSG_WARNING("Child "<< child->pdgId() << ", status "<< child->status() << ", charge "<< child->charge());
122  }
123  }
124 
125  return StatusCode::SUCCESS;
126 }
127 
128 
130 {
131  // Truth taus
132  auto true_taus = getTruthTaus(ctx, 20.0);
133  std::vector<std::shared_ptr<xAOD::TruthParticle>> true_taus_1p = true_taus.first;
134  std::vector<std::shared_ptr<xAOD::TruthParticle>> true_taus_3p = true_taus.second;
135 
136  for(const std::string& trigger : m_triggers) {
137 
138  // skip ditau and T&P chains:
140  if( info.isHLTTandP() || info.isHLTDiTau()) continue;
141 
142  // Online taus
143  std::vector<const xAOD::TauJet*> hlt_taus = getOnlineTausAll(trigger, true);
144 
145 
146  if(!true_taus_1p.empty()) {
147  if(m_do_variable_plots) fillTruthVars(hlt_taus, true_taus_1p, trigger, "1P");
148  if(m_do_efficiency_plots) fillTruthEfficiency(hlt_taus, true_taus_1p, trigger, "1P");
149  }
150 
151  if(!true_taus_3p.empty()) {
152  if(m_do_variable_plots) fillTruthVars(hlt_taus, true_taus_3p, trigger, "3P");
153  if(m_do_efficiency_plots) fillTruthEfficiency(hlt_taus, true_taus_3p, trigger, "3P");
154  }
155  }
156 
157  return StatusCode::SUCCESS;
158 }
159 
160 
161 void TrigTauMonitorTruthAlgorithm::fillTruthEfficiency(const std::vector<const xAOD::TauJet*>& online_tau_vec, const std::vector<std::shared_ptr<xAOD::TruthParticle>>& true_taus, const std::string& trigger, const std::string& nProng) const
162 {
163  ATH_MSG_DEBUG("Fill Truth Tau Matching to Offline and Online Taus efficiencies: " << trigger);
164 
166 
167  auto monGroup = getGroup(trigger+"_Truth_Efficiency_"+nProng);
168 
169  // Truth Tau + HLT Tau / Truth Tau
170  auto pt_vis = Monitored::Scalar<float>("pt_vis", 0.0);
171  auto eta_vis = Monitored::Scalar<float>("eta_vis", 0.0);
172  auto phi_vis = Monitored::Scalar<float>("phi_vis", 0.0);
173  auto HLT_truth_match = Monitored::Scalar<bool>("HLT_pass", false);
174  auto HLT_truth_match_highPt = Monitored::Scalar<bool>("HLT_pass_highPt", false);
175 
176  bool hlt_fires = m_trigDecTool->isPassed(trigger, TrigDefs::Physics | TrigDefs::allowResurrectedDecision);
177  static const SG::ConstAccessor<double> pt_visAcc("pt_vis");
178  static const SG::ConstAccessor<double> eta_visAcc("eta_vis");
179  static const SG::ConstAccessor<double> phi_visAcc("phi_vis");
180  for(const std::shared_ptr<xAOD::TruthParticle>& true_tau : true_taus) {
181  pt_vis = pt_visAcc(*true_tau)/Gaudi::Units::GeV;
182  eta_vis = eta_visAcc(*true_tau);
183  phi_vis = phi_visAcc(*true_tau);
184 
185  HLT_truth_match = matchObjects(true_tau.get(), online_tau_vec, 0.2) && hlt_fires;
186 
187  bool is_highPt = false;
188  if(info.isHLTSingleTau()) is_highPt = pt_vis > info.getHLTTauThreshold() + 20.0;
189 
190  fill(monGroup, pt_vis, eta_vis, phi_vis, HLT_truth_match);
191 
192  if(is_highPt) {
193  HLT_truth_match_highPt = static_cast<bool>(HLT_truth_match);
194  fill(monGroup, eta_vis, phi_vis, HLT_truth_match_highPt);
195  }
196  }
197  ATH_MSG_DEBUG("After fill Truth efficiencies");
198 }
199 
200 
201 void TrigTauMonitorTruthAlgorithm::fillTruthVars(const std::vector<const xAOD::TauJet*>& ef_taus, const std::vector<std::shared_ptr<xAOD::TruthParticle>>& true_taus, const std::string& trigger, const std::string& nProng) const
202 {
203  ATH_MSG_DEBUG("Fill Truth variables: " << trigger);
204 
205  auto monGroup = getGroup(trigger+"_TruthVars_"+nProng);
206 
207  std::vector<float> ratio, ptvis, etavis, phivis, mvis;
208 
209  auto PtRatio = Monitored::Collection("PtRatio", ratio);
210  auto pt_vis = Monitored::Collection("pt_vis", ptvis);
211  auto eta_vis = Monitored::Collection("eta_vis", etavis);
212  auto phi_vis = Monitored::Collection("phi_vis", phivis);
213  auto mass_vis = Monitored::Collection("mass_vis", mvis);
214 
215  float matchedRatio = -999, matchedptvis = -999, matchedetavis = 999, matchedphivis = 999, matchedmvis = -999;
216 
217  // Visible-Truth Tau matching to HLT Tau
218  static const SG::ConstAccessor<double> pt_visAcc("pt_vis");
219  static const SG::ConstAccessor<double> eta_visAcc("eta_vis");
220  static const SG::ConstAccessor<double> phi_visAcc("phi_vis");
221  static const SG::ConstAccessor<double> mvisAcc("mvis");
222  for(auto& HLTTau : ef_taus) {
223  for(const std::shared_ptr<xAOD::TruthParticle>& true_tau : true_taus) {
224  TLorentzVector true_tau4V;
225  true_tau4V.SetPtEtaPhiM(pt_visAcc(*true_tau),
226  eta_visAcc(*true_tau),
227  phi_visAcc(*true_tau),
228  mvisAcc(*true_tau));
229  if(true_tau4V.DeltaR(HLTTau->p4()) < 0.2) {
230  matchedptvis = (pt_visAcc(*true_tau)/Gaudi::Units::GeV);
231  matchedetavis = eta_visAcc(*true_tau);
232  matchedphivis = phi_visAcc(*true_tau);
233  matchedmvis = mvisAcc(*true_tau);
234  matchedRatio = (HLTTau->p4().Pt() - pt_visAcc(*true_tau))/pt_visAcc(*true_tau);
235  }
236  }
237 
238  if(matchedptvis > 0) {
239  ptvis.push_back(matchedptvis);
240  etavis.push_back(matchedetavis);
241  phivis.push_back(matchedphivis);
242  mvis.push_back(matchedmvis);
243  ratio.push_back(matchedRatio);
244  }
245  }
246 
247  fill(monGroup, pt_vis, eta_vis, phi_vis, mass_vis, PtRatio);
248 
249  ATH_MSG_DEBUG("After fill Truth variables");
250 }
grepfile.info
info
Definition: grepfile.py:38
TrigTauMonitorTruthAlgorithm::TrigTauMonitorTruthAlgorithm
TrigTauMonitorTruthAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Definition: TrigTauMonitorTruthAlgorithm.cxx:12
xAOD::TruthVertex_v1::nOutgoingParticles
size_t nOutgoingParticles() const
Get the number of outgoing particles.
python.TIDAMonTool.monGroup
def monGroup(analysis_chain)
Definition: TIDAMonTool.py:295
AthMonitorAlgorithm::m_trigDecTool
PublicToolHandle< Trig::TrigDecisionTool > m_trigDecTool
Tool to tell whether a specific trigger is passed.
Definition: AthMonitorAlgorithm.h:340
TrigTauMonitorBaseAlgorithm::initialize
virtual StatusCode initialize() override
initialize
Definition: TrigTauMonitorBaseAlgorithm.cxx:16
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
test_pyathena.pt
pt
Definition: test_pyathena.py:11
SG::ConstAccessor< char >
TrigTauMonitorBaseAlgorithm::m_do_variable_plots
Gaudi::Property< bool > m_do_variable_plots
Definition: TrigTauMonitorBaseAlgorithm.h:41
TrigTauMonitorTruthAlgorithm.h
isSMLepton
bool isSMLepton(const T &p)
Definition: AtlasPID.h:134
Monitored::Collection
ValuesCollection< T > Collection(std::string name, const T &collection)
Declare a monitored (double-convertible) collection.
Definition: MonitoredCollection.h:38
MC::isPhysical
bool isPhysical(const T &p)
Definition: HepMCHelpers.h:32
TrigTauMonitorTruthAlgorithm::examineTruthTau
StatusCode examineTruthTau(const std::shared_ptr< xAOD::TruthParticle > &xTruthParticle) const
Definition: TrigTauMonitorTruthAlgorithm.cxx:73
TrigTauMonitorBaseAlgorithm::getOnlineTausAll
std::vector< const xAOD::TauJet * > getOnlineTausAll(const std::string &trigger, bool include_0P=true) const
Definition: TrigTauMonitorBaseAlgorithm.cxx:55
xAOD::TruthParticle_v1::hasDecayVtx
bool hasDecayVtx() const
Check for a decay vertex on this particle.
SG::Decorator< char >
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:41
TrigTauMonitorTruthAlgorithm::fillTruthEfficiency
void fillTruthEfficiency(const std::vector< const xAOD::TauJet * > &online_tau_vec_all, const std::vector< std::shared_ptr< xAOD::TruthParticle >> &true_taus, const std::string &trigger, const std::string &nProng) const
Definition: TrigTauMonitorTruthAlgorithm.cxx:161
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
AthMonitorAlgorithm::fill
void fill(const ToolHandle< GenericMonitoringTool > &groupHandle, std::vector< std::reference_wrapper< Monitored::IMonitoredVariable >> &&variables) const
Fills a vector of variables to a group by reference.
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
xAOD::TruthParticle_v1::decayVtx
const TruthVertex_v1 * decayVtx() const
The decay vertex of this particle.
xAOD::TruthVertex_v1
Class describing a truth vertex in the MC record.
Definition: TruthVertex_v1.h:41
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
TrigTauMonitorTruthAlgorithm::initialize
virtual StatusCode initialize() override
initialize
Definition: TrigTauMonitorTruthAlgorithm.cxx:17
threshold
Definition: chainparser.cxx:74
TrigTauMonitorBaseAlgorithm
Definition: TrigTauMonitorBaseAlgorithm.h:24
TrigTauMonitorBaseAlgorithm::m_do_efficiency_plots
Gaudi::Property< bool > m_do_efficiency_plots
Definition: TrigTauMonitorBaseAlgorithm.h:40
TrigTauInfo
Definition: TrigTauInfo.h:15
xAOD::TruthParticle_v1::status
int status() const
Status code.
TrigTauMonitorTruthAlgorithm::getTruthTaus
std::pair< std::vector< std::shared_ptr< xAOD::TruthParticle > >, std::vector< std::shared_ptr< xAOD::TruthParticle > > > getTruthTaus(const EventContext &ctx, const float threshold=20.0) const
Definition: TrigTauMonitorTruthAlgorithm.cxx:26
python.compareTCTs.ratio
ratio
Definition: compareTCTs.py:295
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
TrigTauMonitorBaseAlgorithm::matchObjects
bool matchObjects(const T1 *tau, const std::vector< const T2 * > &tau_vec, float threshold) const
Definition: TrigTauMonitorBaseAlgorithm.h:73
isSMNeutrino
bool isSMNeutrino(const T &p)
Definition: AtlasPID.h:155
TrigTauMonitorBaseAlgorithm::m_triggers
Gaudi::Property< std::vector< std::string > > m_triggers
Definition: TrigTauMonitorBaseAlgorithm.h:32
TrigTauMonitorBaseAlgorithm::getTrigInfo
const TrigTauInfo & getTrigInfo(const std::string &trigger) const
Definition: TrigTauMonitorBaseAlgorithm.h:45
xAOD::TruthParticle_v1::p4
virtual FourMom_t p4() const override final
The full 4-momentum of the particle.
Definition: TruthParticle_v1.cxx:196
ConstAccessor.h
Helper class to provide constant type-safe access to aux data.
Monitored::Scalar
Declare a monitored scalar variable.
Definition: MonitoredScalar.h:34
xAOD::TruthParticle_v1::pdgId
int pdgId() const
PDG ID code.
TrigTauMonitorTruthAlgorithm::processEvent
virtual StatusCode processEvent(const EventContext &ctx) const override
Definition: TrigTauMonitorTruthAlgorithm.cxx:129
TrigTauMonitorTruthAlgorithm::fillTruthVars
void fillTruthVars(const std::vector< const xAOD::TauJet * > &tau_vec, const std::vector< std::shared_ptr< xAOD::TruthParticle >> &true_taus, const std::string &trigger, const std::string &nProng) const
Definition: TrigTauMonitorTruthAlgorithm.cxx:201
GeV
#define GeV
Definition: CaloTransverseBalanceVecMon.cxx:30
Decorator.h
Helper class to provide type-safe access to aux data.
xAOD::TruthVertex_v1::outgoingParticle
const TruthParticle_v1 * outgoingParticle(size_t index) const
Get one of the outgoing particles.
Definition: TruthVertex_v1.cxx:121
AthMonitorAlgorithm::getGroup
const ToolHandle< GenericMonitoringTool > & getGroup(const std::string &name) const
Get a specific monitoring tool from the tool handle array.
Definition: AthMonitorAlgorithm.cxx:164
xAOD::TruthParticle_v1::charge
double charge() const
Physical charge.
HepMCHelpers.h
TrigTauMonitorTruthAlgorithm::m_truthParticleKey
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_truthParticleKey
Definition: TrigTauMonitorTruthAlgorithm.h:32
PhysDESDM_Quirks.trigger
trigger
Definition: PhysDESDM_Quirks.py:27