ATLAS Offline Software
MvaTESVariableDecorator.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // local include(s)
8 
11 #include "CxxUtils/trapping_fp.h"
12 
14  : TauRecToolBase(name) {
15 }
16 
17 
19 
20  ATH_CHECK(m_aveIntPerXKey.initialize());
23 
24  return StatusCode::SUCCESS;
25 }
26 
27 
28 
30  // Tell clang to optimize assuming that FP operations may trap.
32 
33  int mu = 0;
35  if (!eventInfoDecorHandle.isPresent()) {
36  ATH_MSG_WARNING ( "EventInfo decoration not available! Will set mu=0." );
37  }
38  else {
39  // convert from float to int to ignore peculiar values used in MC
40  mu = static_cast<int>(eventInfoDecorHandle(0));
41  }
42  static const SG::Accessor<float> acc_mu("mu");
43  acc_mu(xTau) = mu;
44 
45  if (!m_vertexContainerKey.empty()) {
46  int nVtxPU = 0;
48  if (!vertexInHandle.isValid()) {
49  ATH_MSG_WARNING ("Could not retrieve HiveDataObj with key " << vertexInHandle.key() << ", will set nVtxPU=0.");
50  }
51  else {
52  const xAOD::VertexContainer* vertexContainer = vertexInHandle.cptr();
53  for (const auto *xVertex : *vertexContainer){
54  if (xVertex->vertexType() == xAOD::VxType::PileUp)
55  ++nVtxPU;
56  }
57  }
58  static const SG::Accessor<int> acc_nVtxPU("nVtxPU");
59  acc_nVtxPU(xTau) = nVtxPU;
60  }
61 
62  if (!m_eventShapeKey.empty()) {
63  double rho = 0.;
65  if (!eventShape.isValid()) {
66  ATH_MSG_WARNING ("Could not retrieve EventShape with key " << m_eventShapeKey );
67  }
68  else if (!eventShape->getDensity(xAOD::EventShape::Density, rho)) {
69  ATH_MSG_WARNING ("Could not retrieve rho.");
70  }
71  static const SG::Accessor<float> acc_rho("rho");
72  acc_rho(xTau) = static_cast<float>(rho);
73  }
74 
75  double center_lambda=0. , first_eng_dens=0. , em_probability=0. , second_lambda=0. ;
76  double mean_center_lambda=0. , mean_first_eng_dens=0. , mean_em_probability=0. , mean_second_lambda=0. ;
77  double mean_presampler_frac=0., lead_cluster_frac=0. , second_cluster_frac=0. , third_cluster_frac=0. ;
78  double clE=0., Etot=0.;
79 
80  // approximate Upsilon based on clusters, not PFOs (for online TES)
81  TLorentzVector clusters_EM_P4;
82  clusters_EM_P4.SetPtEtaPhiM(0,0,0,0);
83  TLorentzVector clusters_had_P4;
84  clusters_had_P4.SetPtEtaPhiM(0,0,0,0);
85  TLorentzVector tauIntermediateAxisEM;
86  tauIntermediateAxisEM.SetPtEtaPhiM(0,0,0,0);
87 
88  TLorentzVector tauAxis = tauRecTools::getTauAxis(xTau, m_doVertexCorrection);
89 
90  // in the trigger, we must ignore the tau vertex, otherwise ptFinalCalib computed at calo-only step and precision step will differ
91  const xAOD::Vertex* vertex = nullptr;
92  if (m_doVertexCorrection) vertex = xTau.vertex();
93 
94  // loop over tau clusters
95  std::vector<xAOD::CaloVertexedTopoCluster> vertexedClusters = xTau.vertexedClusters();
96 
97  for (const xAOD::CaloVertexedTopoCluster& vertexedCluster : vertexedClusters) {
98  const xAOD::CaloCluster& cluster = vertexedCluster.clust();
99 
100  TLorentzVector clusterP4 = m_doVertexCorrection? vertexedCluster.p4() : cluster.p4();
101  if (clusterP4.DeltaR(tauAxis) > 0.2) continue;
102 
103  // FIXME: should we use calE for EMTopo clusters ?
104  // what's the energy scale when calculating the cluster momentum
105  clE = cluster.calE();
106  Etot += clE;
107 
108  if (clE > lead_cluster_frac) {
109  third_cluster_frac = second_cluster_frac;
110  second_cluster_frac = lead_cluster_frac;
111  lead_cluster_frac = clE;
112  }
113  else if (clE > second_cluster_frac) {
114  third_cluster_frac = second_cluster_frac;
115  second_cluster_frac = clE;
116  }
117  else if (clE > third_cluster_frac) {
118  third_cluster_frac = clE;
119  }
120 
122  mean_center_lambda += clE*center_lambda;
123  else ATH_MSG_WARNING("Failed to retrieve moment: CENTER_LAMBDA");
124 
126  mean_first_eng_dens += clE*first_eng_dens;
127  else ATH_MSG_WARNING("Failed to retrieve moment: FIRST_ENG_DENS");
128 
130  mean_em_probability += clE*em_probability;
131 
132  // FIXME: should we use calE for EMTopo clusters ?
133  // what's the energy scale when calculating the cluster momentum
134  if (em_probability>0.5) clusters_EM_P4 += cluster.p4(xAOD::CaloCluster::State::CALIBRATED);
135  else clusters_had_P4 += cluster.p4(xAOD::CaloCluster::State::CALIBRATED);
136  }
137  else ATH_MSG_WARNING("Failed to retrieve moment: EM_PROBABILITY");
138 
140  mean_second_lambda += clE*second_lambda;
141  else ATH_MSG_WARNING("Failed to retrieve moment: SECOND_LAMBDA");
142 
143  mean_presampler_frac += (cluster.eSample(CaloSampling::PreSamplerB) + cluster.eSample(CaloSampling::PreSamplerE));
144 
145  // EM-scale equivalent of IntermediateAxis p4
146  if (vertex) {
147  xAOD::CaloVertexedTopoCluster vertexedClusterEM(cluster, xAOD::CaloCluster::State::UNCALIBRATED, vertex->position());
148  tauIntermediateAxisEM += vertexedClusterEM.p4();
149  }
150  else {
151  tauIntermediateAxisEM += cluster.p4(xAOD::CaloCluster::State::UNCALIBRATED);
152  }
153  }
154 
155  // calculate mean values
156  if (Etot>0.) {
157  mean_center_lambda /= Etot;
158  mean_first_eng_dens /= Etot;
159  mean_em_probability /= Etot;
160  mean_second_lambda /= Etot;
161  mean_presampler_frac /= Etot;
162  lead_cluster_frac /= Etot;
163  second_cluster_frac /= Etot;
164  third_cluster_frac /= Etot;
165 
166  if (mean_first_eng_dens>0.) mean_first_eng_dens = TMath::Log10(mean_first_eng_dens/Etot);
167  }
168 
169  // cluster-based upsilon, ranges from -1 to 1
170  double upsilon_cluster = -2.;
171  if (clusters_had_P4.E()+clusters_EM_P4.E()!=0.)
172  upsilon_cluster = (clusters_had_P4.E()-clusters_EM_P4.E())/(clusters_had_P4.E()+clusters_EM_P4.E());
173 
174  xTau.setDetail(xAOD::TauJetParameters::ClustersMeanCenterLambda, static_cast<float>(mean_center_lambda));
175  xTau.setDetail(xAOD::TauJetParameters::ClustersMeanFirstEngDens, static_cast<float>(mean_first_eng_dens));
176  xTau.setDetail(xAOD::TauJetParameters::ClustersMeanEMProbability, static_cast<float>(mean_em_probability));
177  xTau.setDetail(xAOD::TauJetParameters::ClustersMeanSecondLambda, static_cast<float>(mean_second_lambda));
178  xTau.setDetail(xAOD::TauJetParameters::ClustersMeanPresamplerFrac, static_cast<float>(mean_presampler_frac));
179 
180  static const SG::Accessor<float> acc_ClusterTotalEnergy("ClusterTotalEnergy");
181  acc_ClusterTotalEnergy(xTau) = static_cast<float>(Etot);
182 
183  static const SG::Accessor<float> acc_ptIntermediateAxisEM("ptIntermediateAxisEM");
184  acc_ptIntermediateAxisEM(xTau) = static_cast<float>(tauIntermediateAxisEM.Pt());
185 
186  // online-specific, not defined in TauDefs enum
187  static const SG::Accessor<float> acc_LeadClusterFrac("LeadClusterFrac");
188  static const SG::Accessor<float> acc_UpsilonCluster("UpsilonCluster");
189  acc_LeadClusterFrac(xTau) = static_cast<float>(lead_cluster_frac);
190  acc_UpsilonCluster(xTau) = static_cast<float>(upsilon_cluster);
191 
192  if (inTrigger()) {
193  // for now only used by trigger, but could be used by offline 0p in the 2022 reprocessing
194  static const SG::Accessor<float> acc_SecondClusterFrac("SecondClusterFrac");
195  static const SG::Accessor<float> acc_ThirdClusterFrac("ThirdClusterFrac");
196  acc_SecondClusterFrac(xTau) = static_cast<float>(second_cluster_frac);
197  acc_ThirdClusterFrac(xTau) = static_cast<float>(third_cluster_frac);
198 
199  return StatusCode::SUCCESS;
200  }
201  // no seed jets in AOD
202  if (!inAOD()) {
203  // retrieve Ghost Muon Segment Count (for punch-through studies)
204  const xAOD::Jet* jetSeed = xTau.jet();
205  if (jetSeed == nullptr) {
206  ATH_MSG_ERROR("Tau jet link is invalid.");
207  return StatusCode::FAILURE;
208  }
209 
210  int nMuSeg=0;
211  if (!jetSeed->getAttribute<int>("GhostMuonSegmentCount", nMuSeg)) nMuSeg=0;
213  }
214 
215 
216  // summing corrected Pi0 PFO energies
217  TLorentzVector Pi0_totalP4;
218  Pi0_totalP4.SetPtEtaPhiM(0,0,0,0);
219 
220  for (size_t i=0; i<xTau.nPi0PFOs(); i++){
221  Pi0_totalP4 += xTau.pi0PFO(i)->p4();
222  }
223 
224  double Pi0_totalE = Pi0_totalP4.E();
225 
226  // summing tau track momenta
227  TLorentzVector charged_totalP4;
228  charged_totalP4.SetPtEtaPhiM(0,0,0,0);
229 
230  for (const xAOD::TauTrack* track : xTau.tracks()) {
231  charged_totalP4 += track->p4();
232  }
233 
234  double charged_totalE = charged_totalP4.E();
235 
236  // calculate relative difference and decorate onto tau
237  double relDiff=0.;
238  if (Pi0_totalE+charged_totalE != 0.){
239  relDiff = (charged_totalE - Pi0_totalE) / (charged_totalE + Pi0_totalE) ;
240  }
241  xTau.setDetail(xAOD::TauJetParameters::PFOEngRelDiff, static_cast<float>(relDiff));
242 
243  return StatusCode::SUCCESS;
244 }
xAOD::EventShape_v1::getDensity
bool getDensity(EventDensityID id, double &v) const
Get a density variable from the object.
Definition: EventShape_v1.cxx:135
MvaTESVariableDecorator::initialize
virtual StatusCode initialize() override
Tool initializer.
Definition: MvaTESVariableDecorator.cxx:18
CXXUTILS_TRAPPING_FP
#define CXXUTILS_TRAPPING_FP
Definition: trapping_fp.h:24
TauGNNUtils::Variables::Cluster::CENTER_LAMBDA
bool CENTER_LAMBDA(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:851
xAOD::TauJetParameters::PFOEngRelDiff
@ PFOEngRelDiff
Definition: TauDefs.h:318
xAOD::CaloVertexedClusterBase::p4
virtual FourMom_t p4() const final
The full 4-momentum of the particle.
Definition: Event/xAOD/xAODCaloEvent/xAODCaloEvent/CaloVertexedClusterBase.h:88
xAOD::TauJet_v3::jet
const Jet * jet() const
xAOD::TauJetParameters::GhostMuonSegmentCount
@ GhostMuonSegmentCount
Definition: TauDefs.h:317
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
TauGNNUtils::Variables::Cluster::EM_PROBABILITY
bool EM_PROBABILITY(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:920
SG::Accessor< float >
xAOD::TauJetParameters::ClustersMeanSecondLambda
@ ClustersMeanSecondLambda
Definition: TauDefs.h:315
TauRecToolBase::inAOD
bool inAOD() const
Definition: TauRecToolBase.h:88
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
tauRecTools::getTauAxis
TLorentzVector getTauAxis(const xAOD::TauJet &tau, bool doVertexCorrection=true)
Return the four momentum of the tau axis The tau axis is widely used to select clusters and cells in ...
Definition: Reconstruction/tauRecTools/Root/HelperFunctions.cxx:33
xAOD::CaloCluster_v1::calE
flt_t calE() const
Geet Energy in signal state CALIBRATED.
TauRecToolBase
The base class for all tau tools.
Definition: TauRecToolBase.h:21
SG::ReadDecorHandle::isPresent
bool isPresent() const
Is the referenced container present in SG?
MvaTESVariableDecorator::execute
virtual StatusCode execute(xAOD::TauJet &xTau) const override
Execute - called for each tau candidate.
Definition: MvaTESVariableDecorator.cxx:29
xAOD::TauJetParameters::ClustersMeanPresamplerFrac
@ ClustersMeanPresamplerFrac
Definition: TauDefs.h:316
TauRecToolBase::inTrigger
bool inTrigger() const
Definition: TauRecToolBase.h:87
xAOD::Jet_v1::getAttribute
bool getAttribute(AttributeID type, T &value) const
Retrieve attribute moment by enum.
xAOD::TauJet_v3::nPi0PFOs
size_t nPi0PFOs() const
Get the number of pi0 PFO particles associated with this tau.
Definition: TauJet_v3.cxx:840
MvaTESVariableDecorator::m_eventShapeKey
SG::ReadHandleKey< xAOD::EventShape > m_eventShapeKey
Definition: MvaTESVariableDecorator.h:44
xAOD::TauJet_v3::pi0PFO
const PFO * pi0PFO(size_t i) const
Get the pointer to a given pi0 PFO associated with this tau.
xAOD::EventShape_v1::Density
@ Density
Definition: EventShape_v1.h:47
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:62
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
SG::ReadDecorHandle
Handle class for reading a decoration on an object.
Definition: StoreGate/StoreGate/ReadDecorHandle.h:94
lumiFormat.i
int i
Definition: lumiFormat.py:85
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
xAOD::TauJet_v3
Class describing a tau jet.
Definition: TauJet_v3.h:41
MvaTESVariableDecorator::m_aveIntPerXKey
SG::ReadDecorHandleKey< xAOD::EventInfo > m_aveIntPerXKey
Definition: MvaTESVariableDecorator.h:34
xAOD::PFO_v1::p4
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition: PFO_v1.cxx:95
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
xAOD::CaloCluster_v1::retrieveMoment
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
Definition: CaloCluster_v1.cxx:692
TauGNNUtils::Variables::Cluster::SECOND_LAMBDA
bool SECOND_LAMBDA(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:846
MvaTESVariableDecorator::MvaTESVariableDecorator
MvaTESVariableDecorator(const std::string &name="MvaTESVariableDecorator")
Definition: MvaTESVariableDecorator.cxx:13
MvaTESVariableDecorator.h
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
xAOD::CaloCluster_v1::p4
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition: CaloCluster_v1.cxx:465
trapping_fp.h
Tell the compiler to optimize assuming that FP may trap.
xAOD::VxType::PileUp
@ PileUp
Pile-up vertex.
Definition: TrackingPrimitives.h:574
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
ReadHandle.h
Handle class for reading from StoreGate.
xAOD::TauJetParameters::ClustersMeanEMProbability
@ ClustersMeanEMProbability
Definition: TauDefs.h:313
xAOD::TauJetParameters::ClustersMeanCenterLambda
@ ClustersMeanCenterLambda
Definition: TauDefs.h:312
xAOD::TauJet_v3::vertexedClusters
std::vector< xAOD::CaloVertexedTopoCluster > vertexedClusters() const
Definition: TauJet_v3.cxx:586
SG::VarHandleBase::key
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleBase.cxx:64
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
MvaTESVariableDecorator::m_vertexContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexContainerKey
Definition: MvaTESVariableDecorator.h:39
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
xAOD::CaloCluster_v1::eSample
float eSample(const CaloSample sampling) const
Definition: CaloCluster_v1.cxx:514
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
xAOD::TauJet_v3::vertex
const Vertex * vertex() const
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
CaloCell_ID_FCS::PreSamplerE
@ PreSamplerE
Definition: FastCaloSim_CaloCell_ID.h:23
xAOD::TauTrack_v1
Definition: TauTrack_v1.h:27
CaloCell_ID_FCS::PreSamplerB
@ PreSamplerB
Definition: FastCaloSim_CaloCell_ID.h:19
HelperFunctions.h
ReadDecorHandle.h
Handle class for reading a decoration on an object.
xAOD::TauJet_v3::setDetail
void setDetail(TauJetParameters::Detail detail, int value)
Definition: TauJet_v3.cxx:309
TauGNNUtils::Variables::Cluster::FIRST_ENG_DENS
bool FIRST_ENG_DENS(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:913
xAOD::TauJetParameters::ClustersMeanFirstEngDens
@ ClustersMeanFirstEngDens
Definition: TauDefs.h:314
xAOD::track
@ track
Definition: TrackingPrimitives.h:513
MvaTESVariableDecorator::m_doVertexCorrection
Gaudi::Property< bool > m_doVertexCorrection
Definition: MvaTESVariableDecorator.h:32
xAOD::CaloVertexedTopoCluster
Evaluate cluster kinematics with a different vertex / signal state.
Definition: Event/xAOD/xAODCaloEvent/xAODCaloEvent/CaloVertexedTopoCluster.h:38
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:51
SG::AllowEmpty
@ AllowEmpty
Definition: StoreGate/StoreGate/VarHandleKey.h:30
xAOD::TauJet_v3::tracks
std::vector< const TauTrack * > tracks(TauJetParameters::TauTrackFlag flag=TauJetParameters::TauTrackFlag::classifiedCharged) const
Get the v<const pointer> to a given tauTrack collection associated with this tau.
Definition: TauJet_v3.cxx:461
fitman.rho
rho
Definition: fitman.py:532
xAOD::TauHelpers::vertexedClusters
std::vector< xAOD::CaloVertexedTopoCluster > vertexedClusters(const xAOD::TauJet &tau, double dRMax)
Definition: TauxAODHelpers.cxx:66