ATLAS Offline Software
Loading...
Searching...
No Matches
FEHelpers.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Author: Bill Balunas <bill.balunas@cern.ch>
6
8#include "xAODPFlow/PFODefs.h"
9#include <array>
10
11namespace FEHelpers {
12
13 TLorentzVector getVertexCorrectedFourVec(const xAOD::FlowElement& fe, const xAOD::Vertex& vertexToCorrectTo){
14 TVector3 theVertexVector(vertexToCorrectTo.x(), vertexToCorrectTo.y(), vertexToCorrectTo.z());
15 return getVertexCorrectedFourVec(fe, theVertexVector);
16 }
17
18 TLorentzVector getVertexCorrectedFourVec(const xAOD::FlowElement& fe, const TVector3& vertexToCorrectTo){
19
20 TLorentzVector theNewVector(0.0,0.0,0.0,0.0);
21 theNewVector.SetPtEtaPhiM(fe.pt(), fe.eta(), fe.phi(), fe.m());
22
23 vertexCorrectTheFourVector(fe, vertexToCorrectTo, theNewVector);
24 return theNewVector;
25 }
26
27 void vertexCorrectTheFourVector(const xAOD::FlowElement& fe, const TVector3& vertexToCorrectTo, TLorentzVector& theFourVector){
28
29 float clusterEta = theFourVector.Eta();
30
31 const static SG::AuxElement::ConstAccessor<float> accCenterMag("CENTER_MAG");
32 float centerMag = accCenterMag(fe);
33
34 float radius = centerMag/cosh(clusterEta);
35
36 float EtaVertexCorrection = 0.0, PhiVertexCorrection = 0.0;
37 float clusterPhi = theFourVector.Phi();
38
39 if (radius > 1.0 && centerMag > 1e-3){
40 EtaVertexCorrection = (-vertexToCorrectTo.Z()/cosh(clusterEta) + (vertexToCorrectTo.X()*cos(clusterPhi) + vertexToCorrectTo.Y()*sin(clusterPhi))*tanh(clusterEta))/radius;
41 PhiVertexCorrection = (vertexToCorrectTo.X()*sin(clusterPhi) - vertexToCorrectTo.Y()*cos(clusterPhi))/radius;
42 }
43
44 float etaVertexCorrected = clusterEta + EtaVertexCorrection;
45 float p = std::sqrt(theFourVector.E()*theFourVector.E()-theFourVector.M()*theFourVector.M());
46 float ptVertexCorrected = p/cosh(etaVertexCorrected);
47 theFourVector.SetPtEtaPhiM(ptVertexCorrected, etaVertexCorrected, clusterPhi + PhiVertexCorrection, theFourVector.M());
48
49 }
50
51 bool getClusterMoment(const xAOD::FlowElement& fe, xAOD::CaloCluster::MomentType momentType, float& value){
52
53 // First try to retrieve directly from the cluster
54 if(fe.nOtherObjects() >= 1){
55 const xAOD::CaloCluster* cluster = dynamic_cast<const xAOD::CaloCluster*>(fe.otherObject(0));
56 if(cluster != nullptr){
57 double tmpValue(-99.);
58 if(cluster->retrieveMoment(momentType, tmpValue)){
59 value = static_cast<float>(tmpValue);
60 return true;
61 }
62 }
63 }
64
65 // Cluster or moment from it was unavailable, try to retrieve from the FE itself instead
66 std::string momentName = getClusterMomentName(momentType);
67 if(!momentName.empty()){
68 const SG::AuxElement::ConstAccessor<float> acc(momentName);
69 if(acc.isAvailable(fe)){
70 value = acc(fe);
71 return true;
72 }
73 }
74
75 return false;
76 }
77
78 std::vector<float> getEnergiesPerSampling(const xAOD::FlowElement& fe){
79
80 const static SG::AuxElement::ConstAccessor< std::vector<float> > accEPerSampling("ePerSampling");
81 if(accEPerSampling.isAvailable(fe)) return accEPerSampling(fe);
82
83 // This wasn't stored as a vector, try to retrieve the individual elements
84 const static SG::AuxElement::ConstAccessor<float> accPreSamplerB("LAYERENERGY_PreSamplerB");
85 const static SG::AuxElement::ConstAccessor<float> accEMB1("LAYERENERGY_EMB1");
86 const static SG::AuxElement::ConstAccessor<float> accEMB2("LAYERENERGY_EMB2");
87 const static SG::AuxElement::ConstAccessor<float> accEMB3("LAYERENERGY_EMB3");
88 const static SG::AuxElement::ConstAccessor<float> accPreSamplerE("LAYERENERGY_PreSamplerE");
89 const static SG::AuxElement::ConstAccessor<float> accEME1("LAYERENERGY_EME1");
90 const static SG::AuxElement::ConstAccessor<float> accEME2("LAYERENERGY_EME2");
91 const static SG::AuxElement::ConstAccessor<float> accEME3("LAYERENERGY_EME3");
92 const static SG::AuxElement::ConstAccessor<float> accHEC0("LAYERENERGY_HEC0");
93 const static SG::AuxElement::ConstAccessor<float> accHEC1("LAYERENERGY_HEC1");
94 const static SG::AuxElement::ConstAccessor<float> accHEC2("LAYERENERGY_HEC2");
95 const static SG::AuxElement::ConstAccessor<float> accHEC3("LAYERENERGY_HEC3");
96 const static SG::AuxElement::ConstAccessor<float> accTileBar0("LAYERENERGY_TileBar0");
97 const static SG::AuxElement::ConstAccessor<float> accTileBar1("LAYERENERGY_TileBar1");
98 const static SG::AuxElement::ConstAccessor<float> accTileBar2("LAYERENERGY_TileBar2");
99 const static SG::AuxElement::ConstAccessor<float> accTileGap1("LAYERENERGY_TileGap1");
100 const static SG::AuxElement::ConstAccessor<float> accTileGap2("LAYERENERGY_TileGap2");
101 const static SG::AuxElement::ConstAccessor<float> accTileGap3("LAYERENERGY_TileGap3");
102 const static SG::AuxElement::ConstAccessor<float> accTileExt0("LAYERENERGY_TileExt0");
103 const static SG::AuxElement::ConstAccessor<float> accTileExt1("LAYERENERGY_TileExt1");
104 const static SG::AuxElement::ConstAccessor<float> accTileExt2("LAYERENERGY_TileExt2");
105 const static SG::AuxElement::ConstAccessor<float> accFCAL0("LAYERENERGY_FCAL0");
106 const static SG::AuxElement::ConstAccessor<float> accFCAL1("LAYERENERGY_FCAL1");
107 const static SG::AuxElement::ConstAccessor<float> accFCAL2("LAYERENERGY_FCAL2");
108 const static SG::AuxElement::ConstAccessor<float> accMINIFCAL0("LAYERENERGY_MINIFCAL0");
109 const static SG::AuxElement::ConstAccessor<float> accMINIFCAL1("LAYERENERGY_MINIFCAL1");
110 const static SG::AuxElement::ConstAccessor<float> accMINIFCAL2("LAYERENERGY_MINIFCAL2");
111 const static SG::AuxElement::ConstAccessor<float> accMINIFCAL3("LAYERENERGY_MINIFCAL3");
112
113 // Build the vector up from the individual samplings
114 std::vector<float> result(28, 0);
115 result[0] = accPreSamplerB(fe);
116 result[1] = accEMB1(fe);
117 result[2] = accEMB2(fe);
118 result[3] = accEMB3(fe);
119 result[4] = accPreSamplerE(fe);
120 result[5] = accEME1(fe);
121 result[6] = accEME2(fe);
122 result[7] = accEME3(fe);
123 result[8] = accHEC0(fe);
124 result[9] = accHEC1(fe);
125 result[10] = accHEC2(fe);
126 result[11] = accHEC3(fe);
127 result[12] = accTileBar0(fe);
128 result[13] = accTileBar1(fe);
129 result[14] = accTileBar2(fe);
130 result[15] = accTileGap1(fe);
131 result[16] = accTileGap2(fe);
132 result[17] = accTileGap3(fe);
133 result[18] = accTileExt0(fe);
134 result[19] = accTileExt1(fe);
135 result[20] = accTileExt2(fe);
136 result[21] = accFCAL0(fe);
137 result[22] = accFCAL1(fe);
138 result[23] = accFCAL2(fe);
139 result[24] = accMINIFCAL0(fe);
140 result[25] = accMINIFCAL1(fe);
141 result[26] = accMINIFCAL2(fe);
142 result[27] = accMINIFCAL3(fe);
143
144 return result;
145 }
146
148
149 switch(momentType){
150 case xAOD::CaloCluster::ENG_FRAC_CORE: return "ENG_FRAC_CORE";
151 case xAOD::CaloCluster::FIRST_ENG_DENS: return "FIRST_ENG_DENS";
152 case xAOD::CaloCluster::CENTER_LAMBDA: return "CENTER_LAMBDA";
153 case xAOD::CaloCluster::SECOND_R: return "SECOND_R";
154 case xAOD::CaloCluster::DELTA_ALPHA: return "DELTA_ALPHA";
155 case xAOD::CaloCluster::LATERAL: return "LATERAL";
156 case xAOD::CaloCluster::LONGITUDINAL: return "LONGITUDINAL";
157 case xAOD::CaloCluster::SECOND_LAMBDA: return "SECOND_LAMBDA";
158 case xAOD::CaloCluster::ISOLATION: return "ISOLATION";
159 case xAOD::CaloCluster::ENG_FRAC_MAX: return "ENG_FRAC_MAX";
160 case xAOD::CaloCluster::ENG_BAD_CELLS: return "ENG_BAD_CELLS";
161 case xAOD::CaloCluster::N_BAD_CELLS: return "N_BAD_CELLS";
162 case xAOD::CaloCluster::BADLARQ_FRAC: return "BADLARQ_FRAC";
163 case xAOD::CaloCluster::ENG_POS: return "ENG_POS";
164 case xAOD::CaloCluster::SIGNIFICANCE: return "SIGNIFICANCE";
165 case xAOD::CaloCluster::CELL_SIGNIFICANCE: return "CELL_SIGNIFICANCE";
166 case xAOD::CaloCluster::CELL_SIG_SAMPLING: return "CELL_SIG_SAMPLING";
167 case xAOD::CaloCluster::AVG_LAR_Q: return "AVG_LAR_Q";
168 case xAOD::CaloCluster::AVG_TILE_Q: return "AVG_TILE_Q";
169 case xAOD::CaloCluster::EM_PROBABILITY: return "EM_PROBABILITY";
170 case xAOD::CaloCluster::ENG_CALIB_TOT: return "ENG_CALIB_TOT";
171 case xAOD::CaloCluster::ENG_CALIB_FRAC_EM: return "ENG_CALIB_FRAC_EM";
172 case xAOD::CaloCluster::ENG_CALIB_FRAC_HAD: return "ENG_CALIB_FRAC_HAD";
173 case xAOD::CaloCluster::ENG_CALIB_FRAC_REST: return "ENG_CALIB_FRAC_REST";
174 default: return "";
175 }
176 }
177
188
190
192 const std::string& attributeName,
193 const xAOD::CaloCluster& theCluster,
194 xAOD::FlowElement& theFE) {
195
196 const SG::AuxElement::Accessor< float > feAttribute(attributeName);
197 double moment = 0.0;
198 if (theCluster.retrieveMoment(momentType, moment)) {
199 float float_moment = moment;
200 feAttribute(theFE) = float_moment;
201 }
202 return false;
203 }
204
206 const std::string& attributeName,
207 const xAOD::CaloCluster& theCluster,
208 xAOD::FlowElement& theFE) {
209 const SG::AuxElement::Accessor< float > feAttribute(attributeName);
210 feAttribute(theFE) = theCluster.eSample(sampling);
211 }
212
214
215 const std::array< std::pair<xAOD::CaloCluster::MomentType, const std::string>, 12> momentAttributePairs{{
216 {xAOD::CaloCluster::CENTER_MAG, "CENTER_MAG"},
217 {xAOD::CaloCluster::SECOND_R, "SECOND_R"},
218 {xAOD::CaloCluster::CENTER_LAMBDA, "CENTER_LAMBDA"},
219 {xAOD::CaloCluster::ENG_BAD_CELLS, "ENG_BAD_CELLS"},
220 {xAOD::CaloCluster::N_BAD_CELLS, "N_BAD_CELLS"},
221 {xAOD::CaloCluster::BADLARQ_FRAC, "BADLARQ_FRAC"},
222 {xAOD::CaloCluster::ENG_POS, "ENG_POS"},
223 {xAOD::CaloCluster::AVG_LAR_Q, "AVG_LAR_Q"},
224 {xAOD::CaloCluster::AVG_TILE_Q, "AVG_TILE_Q"},
225 {xAOD::CaloCluster::ISOLATION, "ISOLATION"},
226 {xAOD::CaloCluster::SECOND_LAMBDA, "SECOND_LAMBDA"},
227 {xAOD::CaloCluster::EM_PROBABILITY, "EM_PROBABILITY"}
228 }};
229
230 for (const auto & [moment,attribute]:momentAttributePairs) this->addMoment(moment,attribute,theCluster,theFE);
231 }
232
234
235 const std::array< std::pair<xAOD::CaloCluster::MomentType, const std::string>, 4> momentAttributePairs{{
236 {xAOD::CaloCluster::ENG_CALIB_TOT, "ENG_CALIB_TOT"},
237 {xAOD::CaloCluster::ENG_CALIB_FRAC_EM, "ENG_CALIB_FRAC_EM"},
238 {xAOD::CaloCluster::ENG_CALIB_FRAC_HAD, "ENG_CALIB_FRAC_HAD"},
239 {xAOD::CaloCluster::ENG_CALIB_FRAC_REST, "ENG_CALIB_FRAC_REST"}
240 }};
241
242 for (const auto & [moment,attribute]:momentAttributePairs) this->addMoment(moment,attribute,theCluster,theFE);
243
244 }
245
247
248 static const std::array< std::pair<xAOD::CaloCluster::CaloSample, const SG::AuxElement::Accessor<float>>, 28> samplingAttributePairs{{
249 {xAOD::CaloCluster::CaloSample::PreSamplerB,SG::AuxElement::Accessor<float>("LAYERENERGY_PreSamplerB")},
250 {xAOD::CaloCluster::CaloSample::EMB1,SG::AuxElement::Accessor<float>("LAYERENERGY_EMB1")},
251 {xAOD::CaloCluster::CaloSample::EMB2,SG::AuxElement::Accessor<float>("LAYERENERGY_EMB2")},
252 {xAOD::CaloCluster::CaloSample::EMB3,SG::AuxElement::Accessor<float>("LAYERENERGY_EMB3")},
253 {xAOD::CaloCluster::CaloSample::PreSamplerE,SG::AuxElement::Accessor<float>("LAYERENERGY_PreSamplerE")},
254 {xAOD::CaloCluster::CaloSample::EME1,SG::AuxElement::Accessor<float>("LAYERENERGY_EME1")},
255 {xAOD::CaloCluster::CaloSample::EME2,SG::AuxElement::Accessor<float>("LAYERENERGY_EME2")},
256 {xAOD::CaloCluster::CaloSample::EME3,SG::AuxElement::Accessor<float>("LAYERENERGY_EME3")},
257 {xAOD::CaloCluster::CaloSample::HEC0,SG::AuxElement::Accessor<float>("LAYERENERGY_HEC0")},
258 {xAOD::CaloCluster::CaloSample::HEC1,SG::AuxElement::Accessor<float>("LAYERENERGY_HEC1")},
259 {xAOD::CaloCluster::CaloSample::HEC2,SG::AuxElement::Accessor<float>("LAYERENERGY_HEC2")},
260 {xAOD::CaloCluster::CaloSample::HEC3,SG::AuxElement::Accessor<float>("LAYERENERGY_HEC3")},
261 {xAOD::CaloCluster::CaloSample::TileBar0,SG::AuxElement::Accessor<float>("LAYERENERGY_TileBar0")},
262 {xAOD::CaloCluster::CaloSample::TileBar1,SG::AuxElement::Accessor<float>("LAYERENERGY_TileBar1")},
263 {xAOD::CaloCluster::CaloSample::TileBar2,SG::AuxElement::Accessor<float>("LAYERENERGY_TileBar2")},
264 {xAOD::CaloCluster::CaloSample::TileGap1,SG::AuxElement::Accessor<float>("LAYERENERGY_TileGap1")},
265 {xAOD::CaloCluster::CaloSample::TileGap2,SG::AuxElement::Accessor<float>("LAYERENERGY_TileGap2")},
266 {xAOD::CaloCluster::CaloSample::TileGap3,SG::AuxElement::Accessor<float>("LAYERENERGY_TileGap3")},
267 {xAOD::CaloCluster::CaloSample::TileExt0,SG::AuxElement::Accessor<float>("LAYERENERGY_TileExt0")},
268 {xAOD::CaloCluster::CaloSample::TileExt1,SG::AuxElement::Accessor<float>("LAYERENERGY_TileExt1")},
269 {xAOD::CaloCluster::CaloSample::TileExt2,SG::AuxElement::Accessor<float>("LAYERENERGY_TileExt2")},
270 {xAOD::CaloCluster::CaloSample::FCAL0,SG::AuxElement::Accessor<float>("LAYERENERGY_FCAL0")},
271 {xAOD::CaloCluster::CaloSample::FCAL1,SG::AuxElement::Accessor<float>("LAYERENERGY_FCAL1")},
272 {xAOD::CaloCluster::CaloSample::FCAL2,SG::AuxElement::Accessor<float>("LAYERENERGY_FCAL2")},
273 {xAOD::CaloCluster::CaloSample::MINIFCAL0,SG::AuxElement::Accessor<float>("LAYERENERGY_MINIFCAL0")},
274 {xAOD::CaloCluster::CaloSample::MINIFCAL1,SG::AuxElement::Accessor<float>("LAYERENERGY_MINIFCAL1")},
275 {xAOD::CaloCluster::CaloSample::MINIFCAL2,SG::AuxElement::Accessor<float>("LAYERENERGY_MINIFCAL2")},
276 {xAOD::CaloCluster::CaloSample::MINIFCAL3,SG::AuxElement::Accessor<float>("LAYERENERGY_MINIFCAL3")},
277 }};
278
279 for (const auto & [sampling,attribute]:samplingAttributePairs) {
280 attribute(theFE) = theCluster.eSample(sampling);
281 }
282 }
283
284}
void addStandardSamplingEnergies(xAOD::FlowElement &theFE, const xAOD::CaloCluster &theCluster)
void addStandardCalHitMoments(xAOD::FlowElement &theFE, const xAOD::CaloCluster &theCluster)
void addStandardMoments(xAOD::FlowElement &theFE, const xAOD::CaloCluster &theCluster)
bool addMoment(const xAOD::CaloCluster::MomentType &momentType, const std::string &attributeName, const xAOD::CaloCluster &theCluster, xAOD::FlowElement &theFE)
Function to add cluster moments onto FE.
void addSamplingEnergy(const xAOD::CaloCluster::CaloSample &sampling, const std::string &attributeName, const xAOD::CaloCluster &theCluster, xAOD::FlowElement &theFE)
SG::ConstAccessor< T, ALLOC > ConstAccessor
Definition AuxElement.h:569
SG::Accessor< T, ALLOC > Accessor
Definition AuxElement.h:572
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
float eSample(const CaloSample sampling) const
MomentType
Enums to identify different moments.
@ DELTA_ALPHA
Angular shower axis deviation ( ) from IP-to-Center.
@ AVG_TILE_Q
Sum(E_cell_Tile^2 Q_cell_Tile)/Sum(E_cell_Tile^2)
@ SECOND_LAMBDA
Second Moment in .
@ CELL_SIGNIFICANCE
Cell significance = E/sig of the cell with the largest |E|/sig.
@ CELL_SIG_SAMPLING
CaloSample of the cell with the largest |E|/sig.
@ EM_PROBABILITY
Classification probability to be em-like.
@ LATERAL
Normalized lateral moment.
@ N_BAD_CELLS
number of bad cells
@ LONGITUDINAL
Normalized longitudinal moment.
@ ENG_FRAC_MAX
Energy fraction of hottest cell.
@ AVG_LAR_Q
Sum(E_cell_LAr^2 Q_cell_LAr)/Sum(E_cell_LAr^2)
@ SECOND_R
Second Moment in .
@ FIRST_ENG_DENS
First Moment in E/V.
@ ENG_FRAC_CORE
Energy fraction of the sum of the hottest cells in each sampling.
@ CENTER_LAMBDA
Shower depth at Cluster Centroid.
@ SIGNIFICANCE
Cluster significance.
@ CENTER_MAG
Cluster Centroid ( )
@ ENG_CALIB_FRAC_REST
Calibration Hit energy inside the cluster caused by other particles.
@ ENG_CALIB_FRAC_EM
Calibration Hit energy inside the cluster caused by e/gamma/pi0.
@ ENG_BAD_CELLS
Total em-scale energy of bad cells in this cluster.
@ ENG_CALIB_TOT
Calibration Hit energy inside the cluster.
@ ENG_CALIB_FRAC_HAD
Calibration Hit energy inside the cluster caused by charged pi+ and pi-.
@ ENG_POS
Total positive Energy of this cluster.
@ BADLARQ_FRAC
Energy fraction of LAr cells with quality larger than a given cut.
@ ISOLATION
Energy weighted fraction of non-clustered perimeter cells.
CaloSampling::CaloSample CaloSample
std::size_t nOtherObjects() const
virtual double pt() const override
virtual double m() const override
The invariant mass of the particle.
virtual double phi() const override
The azimuthal angle ( ) of the particle.
virtual double eta() const override
The pseudorapidity ( ) of the particle.
signal_t signalType() const
unsigned long signal_t
const xAOD::IParticle * otherObject(std::size_t i) const
float z() const
Returns the z position.
float y() const
Returns the y position.
float x() const
Returns the x position.
std::vector< float > getEnergiesPerSampling(const xAOD::FlowElement &fe)
Definition FEHelpers.cxx:78
void vertexCorrectTheFourVector(const xAOD::FlowElement &fe, const TVector3 &vertexToCorrectTo, TLorentzVector &theFourVector)
Definition FEHelpers.cxx:27
bool getClusterMoment(const xAOD::FlowElement &fe, xAOD::CaloCluster::MomentType momentType, float &value)
Definition FEHelpers.cxx:51
TLorentzVector getVertexCorrectedFourVec(const xAOD::FlowElement &fe, const xAOD::Vertex &vertexToCorrectTo)
Definition FEHelpers.cxx:13
std::string getClusterMomentName(xAOD::CaloCluster::MomentType momentType)
xAOD::Type::ObjectType signalToXAODType(const xAOD::FlowElement &fe)
ObjectType
Type of objects that have a representation in the xAOD EDM.
Definition ObjectType.h:32
@ TrackParticle
The object is a charged track particle.
Definition ObjectType.h:43
@ ParticleFlow
The object is a particle-flow object.
Definition ObjectType.h:41
@ Other
An object not falling into any of the other categories.
Definition ObjectType.h:34
@ CaloCluster
The object is a calorimeter cluster.
Definition ObjectType.h:39
@ Muon
The object is a muon.
Definition ObjectType.h:48
@ TrackCaloCluster
The object is a track-calo-cluster.
Definition ObjectType.h:51
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
FlowElement_v1 FlowElement
Definition of the current "pfo version".
Definition FlowElement.h:16
Vertex_v1 Vertex
Define the latest version of the vertex class.