ATLAS Offline Software
Loading...
Searching...
No Matches
MvaTESVariableDecorator.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// local include(s)
8
12
14 : TauRecToolBase(name) {
15}
16
17
19
20 ATH_CHECK(m_aveIntPerXKey.initialize());
23
24 if (std::string(m_seedJet).find("EM") != std::string::npos) {
25 ATH_MSG_INFO("Set the cluster state to UNCALIBRATED");
27 } else {
29 }
30
31 return StatusCode::SUCCESS;
32}
33
34
36 const EventContext& ctx) const {
37
38 // Tell clang to optimize assuming that FP operations may trap.
40
41 int mu = 0;
43 if (!eventInfoDecorHandle.isPresent()) {
44 ATH_MSG_WARNING ( "EventInfo decoration not available! Will set mu=0." );
45 }
46 else {
47 // convert from float to int to ignore peculiar values used in MC
48 mu = static_cast<int>(eventInfoDecorHandle(0));
49 }
50 static const SG::Accessor<float> acc_mu("mu");
51 acc_mu(xTau) = mu;
52
53 if (!m_vertexContainerKey.empty()) {
54 int nVtxPU = 0;
56 if (!vertexInHandle.isValid()) {
57 ATH_MSG_WARNING ("Could not retrieve HiveDataObj with key " << vertexInHandle.key() << ", will set nVtxPU=0.");
58 }
59 else {
60 const xAOD::VertexContainer* vertexContainer = vertexInHandle.cptr();
61 for (const auto *xVertex : *vertexContainer){
62 if (xVertex->vertexType() == xAOD::VxType::PileUp)
63 ++nVtxPU;
64 }
65 }
66 static const SG::Accessor<int> acc_nVtxPU("nVtxPU");
67 acc_nVtxPU(xTau) = nVtxPU;
68 }
69
70 if (!m_eventShapeKey.empty()) {
71 double rho = 0.;
73 if (!eventShape.isValid()) {
74 ATH_MSG_WARNING ("Could not retrieve EventShape with key " << m_eventShapeKey );
75 }
76 else if (!eventShape->getDensity(xAOD::EventShape::Density, rho)) {
77 ATH_MSG_WARNING ("Could not retrieve rho.");
78 }
79 static const SG::Accessor<float> acc_rho("rho");
80 acc_rho(xTau) = static_cast<float>(rho);
81 }
82
83 double center_lambda=0. , first_eng_dens=0. , em_probability=0. , second_lambda=0. ;
84 double mean_center_lambda=0. , mean_first_eng_dens=0. , mean_em_probability=0. , mean_second_lambda=0. ;
85 double mean_presampler_frac=0., lead_cluster_frac=0. , second_cluster_frac=0. , third_cluster_frac=0. ;
86 double clE=0., Etot=0.;
87
88 // approximate Upsilon based on clusters, not PFOs (for online TES)
89 TLorentzVector clusters_EM_P4;
90 clusters_EM_P4.SetPtEtaPhiM(0,0,0,0);
91 TLorentzVector clusters_had_P4;
92 clusters_had_P4.SetPtEtaPhiM(0,0,0,0);
93 TLorentzVector tauIntermediateAxisEM;
94 tauIntermediateAxisEM.SetPtEtaPhiM(0,0,0,0);
95
96 TLorentzVector tauAxis = tauRecTools::getTauAxis(xTau, m_doVertexCorrection);
97
98 // in the trigger, we must ignore the tau vertex, otherwise ptFinalCalib computed at calo-only step and precision step will differ
99 const xAOD::Vertex* vertex = nullptr;
100 if (m_doVertexCorrection) vertex = xTau.vertex();
101
102 // loop over tau clusters
103 std::vector<xAOD::CaloVertexedTopoCluster> vertexedClusters = xTau.vertexedClusters();
104
105 for (const xAOD::CaloVertexedTopoCluster& vertexedCluster : vertexedClusters) {
106 const xAOD::CaloCluster& cluster = vertexedCluster.clust();
107
108 TLorentzVector clusterP4 = m_doVertexCorrection? vertexedCluster.p4() : cluster.p4();
109 if (clusterP4.DeltaR(tauAxis) > 0.2) continue;
110
111 // FIXME: should we use calE for EMTopo clusters ?
112 // what's the energy scale when calculating the cluster momentum
113 clE = cluster.calE();
114 Etot += clE;
115
116 if (clE > lead_cluster_frac) {
117 third_cluster_frac = second_cluster_frac;
118 second_cluster_frac = lead_cluster_frac;
119 lead_cluster_frac = clE;
120 }
121 else if (clE > second_cluster_frac) {
122 third_cluster_frac = second_cluster_frac;
123 second_cluster_frac = clE;
124 }
125 else if (clE > third_cluster_frac) {
126 third_cluster_frac = clE;
127 }
128
130 mean_center_lambda += clE*center_lambda;
131 else ATH_MSG_WARNING("Failed to retrieve moment: CENTER_LAMBDA");
132
134 mean_first_eng_dens += clE*first_eng_dens;
135 else ATH_MSG_WARNING("Failed to retrieve moment: FIRST_ENG_DENS");
136
138 mean_em_probability += clE*em_probability;
139
140 // FIXME: should we use calE for EMTopo clusters ?
141 // what's the energy scale when calculating the cluster momentum
142 if (em_probability>0.5) clusters_EM_P4 += cluster.p4(m_clusterState);
143 else clusters_had_P4 += cluster.p4(m_clusterState);
144 }
145 else ATH_MSG_WARNING("Failed to retrieve moment: EM_PROBABILITY");
146
148 mean_second_lambda += clE*second_lambda;
149 else ATH_MSG_WARNING("Failed to retrieve moment: SECOND_LAMBDA");
150
151 mean_presampler_frac += (cluster.eSample(CaloSampling::PreSamplerB) + cluster.eSample(CaloSampling::PreSamplerE));
152
153 // EM-scale equivalent of IntermediateAxis p4
154 if (vertex) {
155 xAOD::CaloVertexedTopoCluster vertexedClusterEM(cluster, xAOD::CaloCluster::State::UNCALIBRATED, vertex->position());
156 tauIntermediateAxisEM += vertexedClusterEM.p4();
157 }
158 else {
159 tauIntermediateAxisEM += cluster.p4(xAOD::CaloCluster::State::UNCALIBRATED);
160 }
161 }
162
163 // calculate mean values
164 if (Etot>0.) {
165 mean_center_lambda /= Etot;
166 mean_first_eng_dens /= Etot;
167 mean_em_probability /= Etot;
168 mean_second_lambda /= Etot;
169 mean_presampler_frac /= Etot;
170 lead_cluster_frac /= Etot;
171 second_cluster_frac /= Etot;
172 third_cluster_frac /= Etot;
173
174 if (mean_first_eng_dens>0.) mean_first_eng_dens = TMath::Log10(mean_first_eng_dens/Etot);
175 }
176
177 // cluster-based upsilon, ranges from -1 to 1
178 double upsilon_cluster = -2.;
179 if (clusters_had_P4.E()+clusters_EM_P4.E()!=0.)
180 upsilon_cluster = (clusters_had_P4.E()-clusters_EM_P4.E())/(clusters_had_P4.E()+clusters_EM_P4.E());
181
182 xTau.setDetail(xAOD::TauJetParameters::ClustersMeanCenterLambda, static_cast<float>(mean_center_lambda));
183 xTau.setDetail(xAOD::TauJetParameters::ClustersMeanFirstEngDens, static_cast<float>(mean_first_eng_dens));
184 xTau.setDetail(xAOD::TauJetParameters::ClustersMeanEMProbability, static_cast<float>(mean_em_probability));
185 xTau.setDetail(xAOD::TauJetParameters::ClustersMeanSecondLambda, static_cast<float>(mean_second_lambda));
186 xTau.setDetail(xAOD::TauJetParameters::ClustersMeanPresamplerFrac, static_cast<float>(mean_presampler_frac));
187
188 static const SG::Accessor<float> acc_ClusterTotalEnergy("ClusterTotalEnergy");
189 acc_ClusterTotalEnergy(xTau) = static_cast<float>(Etot);
190
191 static const SG::Accessor<float> acc_ptIntermediateAxisEM("ptIntermediateAxisEM");
192 acc_ptIntermediateAxisEM(xTau) = static_cast<float>(tauIntermediateAxisEM.Pt());
193
194 // online-specific, not defined in TauDefs enum
195 static const SG::Accessor<float> acc_LeadClusterFrac("LeadClusterFrac");
196 static const SG::Accessor<float> acc_UpsilonCluster("UpsilonCluster");
197 acc_LeadClusterFrac(xTau) = static_cast<float>(lead_cluster_frac);
198 acc_UpsilonCluster(xTau) = static_cast<float>(upsilon_cluster);
199
200 if (inTrigger()) {
201 // for now only used by trigger, but could be used by offline 0p in the 2022 reprocessing
202 static const SG::Accessor<float> acc_SecondClusterFrac("SecondClusterFrac");
203 static const SG::Accessor<float> acc_ThirdClusterFrac("ThirdClusterFrac");
204 acc_SecondClusterFrac(xTau) = static_cast<float>(second_cluster_frac);
205 acc_ThirdClusterFrac(xTau) = static_cast<float>(third_cluster_frac);
206
207 return StatusCode::SUCCESS;
208 }
209
210 // summing corrected Pi0 PFO energies
211 TLorentzVector Pi0_totalP4;
212 Pi0_totalP4.SetPtEtaPhiM(0,0,0,0);
213
214 for (size_t i=0; i<xTau.nPi0PFOs(); i++){
215 Pi0_totalP4 += xTau.pi0PFO(i)->p4();
216 }
217
218 double Pi0_totalE = Pi0_totalP4.E();
219
220 // summing tau track momenta
221 TLorentzVector charged_totalP4;
222 charged_totalP4.SetPtEtaPhiM(0,0,0,0);
223
224 for (const xAOD::TauTrack* track : xTau.tracks()) {
225 charged_totalP4 += track->p4();
226 }
227
228 double charged_totalE = charged_totalP4.E();
229
230 // calculate relative difference and decorate onto tau
231 double relDiff=0.;
232 if (Pi0_totalE+charged_totalE != 0.){
233 relDiff = (charged_totalE - Pi0_totalE) / (charged_totalE + Pi0_totalE) ;
234 }
235 xTau.setDetail(xAOD::TauJetParameters::PFOEngRelDiff, static_cast<float>(relDiff));
236
237 return StatusCode::SUCCESS;
238}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
Handle class for reading a decoration on an object.
Handle class for reading from StoreGate.
SG::ReadHandleKey< xAOD::VertexContainer > m_vertexContainerKey
virtual StatusCode executeTool(xAOD::TauJet &xTau, const EventContext &ctx) const override
Execute - called for each tau candidate.
Gaudi::Property< std::string > m_seedJet
SG::ReadDecorHandleKey< xAOD::EventInfo > m_aveIntPerXKey
virtual StatusCode initialize() override
Tool initializer.
SG::ReadHandleKey< xAOD::EventShape > m_eventShapeKey
MvaTESVariableDecorator(const std::string &name="MvaTESVariableDecorator")
xAOD::CaloCluster::State m_clusterState
Gaudi::Property< bool > m_doVertexCorrection
Helper class to provide type-safe access to aux data.
Handle class for reading a decoration on an object.
bool isPresent() const
Is the referenced container present in SG?
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
virtual const std::string & key() const override final
Return the StoreGate ID for the referenced object.
TauRecToolBase(const std::string &name)
bool inTrigger() const
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
float eSample(const CaloSample sampling) const
@ SECOND_LAMBDA
Second Moment in .
@ EM_PROBABILITY
Classification probability to be em-like.
@ FIRST_ENG_DENS
First Moment in E/V.
@ CENTER_LAMBDA
Shower depth at Cluster Centroid.
flt_t calE() const
Geet Energy in signal state CALIBRATED.
virtual FourMom_t p4() const
The full 4-momentum of the particle.
virtual FourMom_t p4() const final
The full 4-momentum of the particle.
Evaluate cluster kinematics with a different vertex / signal state.
virtual FourMom_t p4() const
The full 4-momentum of the particle.
Definition PFO_v1.cxx:95
std::vector< xAOD::CaloVertexedTopoCluster > vertexedClusters() const
const PFO * pi0PFO(size_t i) const
Get the pointer to a given pi0 PFO associated with this tau.
size_t nPi0PFOs() const
Get the number of pi0 PFO particles associated with this tau.
void setDetail(TauJetParameters::Detail detail, int value)
const Vertex * vertex() const
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.
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:140
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 ...
@ PileUp
Pile-up vertex.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.
TauTrack_v1 TauTrack
Definition of the current version.
Definition TauTrack.h:16
TauJet_v3 TauJet
Definition of the current "tau version".
Definition TauJet.h:17
Tell the compiler to optimize assuming that FP may trap.
#define CXXUTILS_TRAPPING_FP
Definition trapping_fp.h:24