ATLAS Offline Software
Loading...
Searching...
No Matches
PhotonPointingTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Local includes
8
9// EDM includes
14
15// Framework includes
19
20// ROOT includes
21#include "TFile.h"
22#include "TH1F.h"
23
24// std includes
25#include <algorithm>
26
27namespace CP {
28
29//____________________________________________________________________________
32 , m_zCorrection(nullptr)
33{
34 declareProperty("isSimulation", m_isMC);
35 declareProperty("zOscillationFileMC", m_zOscFileMC = "PhotonVertexSelection/v1/pointing_correction_mc.root");
36 declareProperty("zOscillationFileData", m_zOscFileData = "PhotonVertexSelection/v1/pointing_correction_data.root");
37 declareProperty("zvertex", m_zvertexDecorName = "zvertex");
38 declareProperty("errz", m_errzDecorName = "errz");
39 declareProperty("HPV_zvertex", m_HPV_zvertexDecorName = "HPV_zvertex");
40 declareProperty("HPV_errz", m_HPV_errzDecorName = "HPV_errz");
41 declareProperty("ContainerName", m_ContainerName = "Photons");
42}
43
44//____________________________________________________________________________
49
50//____________________________________________________________________________
52{
53 ATH_MSG_INFO("Initializing PhotonVertexSelectionTool..." << name());
54
55 ATH_CHECK( m_evtInfo.initialize() );
56
57 if(m_ContainerName.empty()) m_ContainerName = "Photons";
58
63
64 ATH_CHECK(m_zvertex.initialize());
65 ATH_CHECK(m_errz.initialize());
66 ATH_CHECK(m_HPV_zvertex.initialize());
67 ATH_CHECK(m_HPV_errz.initialize());
68
69 // Determine if this is MC or data
70 std::string dataType("");
71 m_isMC = true;
72 if (inputMetaStore()->contains<xAOD::FileMetaData>("FileMetaData")) {
73 const xAOD::FileMetaData* fmd = nullptr;
74 ATH_CHECK(inputMetaStore()->retrieve(fmd, "FileMetaData"));
75 std::string simType("");
76 const bool s = fmd->value(xAOD::FileMetaData::simFlavour, simType);
77 if (!s) {
78 ATH_MSG_DEBUG("no sim flavour from metadata: must be data");
79 m_isMC = false;
80 }
81 } else {
82 ATH_MSG_WARNING("Failed to retrieve FileMetaData : assuming to be MC");
83 }
84
85
86 std::string filepath = PathResolverFindCalibFile(m_isMC ? m_zOscFileMC :
88 TFile *file = TFile::Open(filepath.c_str(), "READ");
89
90 if (file == nullptr) {
91 ATH_MSG_WARNING("Couldn't find file for z-correction: " << filepath.c_str());
92 ATH_MSG_WARNING("Failed to initialize.");
93 return StatusCode::FAILURE;
94 }
95
96 TH1F *temp = nullptr;
97 file->GetObject("dz_trk_pointing_vs_etas2", temp);
98
99 if (temp == nullptr) {
100 ATH_MSG_WARNING("Couldn't find 'dz_trk_pointing_vs_etas2' histogram in file: " << filepath.c_str());
101 ATH_MSG_WARNING("Failed to initialize.");
102 return StatusCode::FAILURE;
103 }
104
105 bool status = TH1::AddDirectoryStatus();
106 TH1::AddDirectory(false);
107 m_zCorrection = dynamic_cast<TH1F*>(temp->Clone("zCorrection"));
108 SafeDelete(file);
109 TH1::AddDirectory(status);
110
111 return StatusCode::SUCCESS;
112}
113
114//____________________________________________________________________________
116{
117 const EventContext& ctx = Gaudi::Hive::currentContext();
118
119 // create the decorators
124
125 bool isDecorAvailable = s_zvertex.isAvailable();
126
127 // Loop over photons and add calo pointing auxdata
128 std::pair<float, float> result;
129 for (const auto *egamma: egammas) {
130 if(egamma==nullptr){
131 ATH_MSG_DEBUG("Passed Egamma was a nullptr -- skipping");
132 continue;
133 }
134 // Get calo pointing variables
136
137 // Set photon auxdata with new value
138 if(isDecorAvailable){
139 ATH_MSG_DEBUG("Called updatePointingAuxdata but decoration is already available");
140 }
141 else{
142 s_zvertex(*egamma) = result.first;
143 s_errz(*egamma) = result.second;
144 }
145
146 // Get conv pointing variables
147 if (egamma->type() == xAOD::Type::Photon) {
148 const xAOD::Egamma *eg = static_cast<const xAOD::Egamma*>(egamma);
149 const xAOD::Photon *photon = dynamic_cast<const xAOD::Photon*>(eg);
150
153 }
154
155 // Set photon auxdata with new value
156 if(!isDecorAvailable){
157 s_HPV_zvertex(*egamma) = result.first;
158 s_HPV_errz(*egamma) = result.second;
159 }
160
161 }
162
163 return StatusCode::SUCCESS;
164}
165
166 //____________________________________________________________________________
167 float PhotonPointingTool::getCorrectedZ(float zPointing, float etas2) const
168 {
169 if (fabs(etas2) < 1.37) return zPointing;
170 return zPointing - m_zCorrection->Interpolate(etas2);
171 }
172
173 //____________________________________________________________________________
174 std::pair<float, float> PhotonPointingTool::getCaloPointing(const xAOD::Egamma *egamma) const
175 {
176 if (egamma == nullptr) {
177 ATH_MSG_WARNING("Passed Egamma was a nullptr, returning (0,0).");
178 return std::make_pair(0,0);
179 }
180
181 // Get the EventInfo
183 if(!eventInfo.isValid()){
184 ATH_MSG_WARNING("Couldn't retrieve EventInfo from TEvent, egamma won't be decorated.");
185 return std::make_pair(0, 0);
186 }
187
188 // Beam parameters
189 double d_beamSpot = hypot(eventInfo->beamPosY(), eventInfo->beamPosX());
190 double phi_beamSpot = atan2(eventInfo->beamPosY(), eventInfo->beamPosX());
191
192 // Photon variables
193 const xAOD::CaloCluster *cluster = egamma->caloCluster();
194 if (cluster == nullptr) {
195 ATH_MSG_WARNING("Couldn't retrieve CaloCluster from Photon, egammas won't be decorated.");
196 return std::make_pair(0, 0);
197 }
198
199 float cl_e = cluster->e();
200 float etas1 = cluster->etaBE(1);
201 float etas2 = cluster->etaBE(2);
202 float phis2 = cluster->phiBE(2);
203 float cl_theta = 2.0*atan(exp(-1.0*cluster->eta()));
204
205 // Shower depths
206 std::pair<float, float> RZ1 = CP::ShowerDepthUtil::getRZ(etas1, 1);
207 std::pair<float, float> RZ2 = CP::ShowerDepthUtil::getRZ(etas2, 2);
208
209 // Calo cluster pointing calculation
210 double r0_with_beamSpot = d_beamSpot*cos(phis2 - phi_beamSpot);
211
212 float s_zvertex = 0, s_errz = 0;
213 s_zvertex = (RZ1.second * (RZ2.first - r0_with_beamSpot) -
214 RZ2.second * (RZ1.first - r0_with_beamSpot)) /
215 (RZ2.first - RZ1.first);
216 s_zvertex = getCorrectedZ(s_zvertex, etas2);
217
218 s_errz = 0.5 * (RZ2.first + RZ1.first) * (0.060 / sqrt(cl_e * 0.001)) /
219 (sin(cl_theta) * sin(cl_theta));
220
221 return std::make_pair(s_zvertex, s_errz);
222 }
223
224 //____________________________________________________________________________
225 std::pair<float, float> PhotonPointingTool::getConvPointing(const xAOD::Photon *photon) const
226 {
227 if (photon == nullptr) {
228 ATH_MSG_WARNING("Passed Egamma was a nullptr, returning (0,0).");
229 return std::make_pair(0,0);
230 }
231
232 // Get the EventInfo
234 if(!eventInfo.isValid()){
235 ATH_MSG_WARNING("Couldn't retrieve EventInfo from TEvent, photons won't be decorated.");
236 return std::make_pair(0, 0);
237 }
238
239 // Beam parameters
240 double d_beamSpot = hypot(eventInfo->beamPosY(), eventInfo->beamPosX());
241 double phi_beamSpot = atan2(eventInfo->beamPosY(), eventInfo->beamPosX());
242
243 // Photon variables
244 const xAOD::CaloCluster *cluster = photon->caloCluster();
245 if (cluster == nullptr) {
246 ATH_MSG_WARNING("Couldn't retrieve CaloCluster from Photon, photons won't be decorated.");
247 return std::make_pair(0, 0);
248 }
249
250 float etas1 = cluster->etaBE(1);
251 float phis2 = cluster->phiBE(2);
252
253 const xAOD::Vertex *conv = photon->vertex();
254 if (cluster == nullptr) {
255 ATH_MSG_WARNING("Couldn't retrieve conversion Vertex from Photon, photons won't be decorated.");
256 return std::make_pair(0, 0);
257 }
258
259 float conv_x = conv->x();
260 float conv_y = conv->y();
261 float conv_z = conv->z();
262
263 // Shower depths
264 std::pair<float, float> RZ1 = CP::ShowerDepthUtil::getRZ(etas1, 1);
265
266 // Photon conversion
267 double conv_r = hypot(conv_x, conv_y);
268
269 // HPV pointing calculation
270 double phi_Calo = atan2(sin(phis2), cos(phis2));
271 double r0_with_beamSpot = d_beamSpot*cos(phi_Calo - phi_beamSpot);
272
273 float s_zvertex = (RZ1.second*(conv_r - r0_with_beamSpot) - conv_z*(RZ1.first - r0_with_beamSpot)) / (conv_r - RZ1.first);
274
275 float dist_vtx_to_conv = hypot(conv_r - r0_with_beamSpot, conv_z - s_zvertex);
276 float dist_conv_to_s1 = hypot(RZ1.first - conv_r, RZ1.second - conv_z);
277
278 float error_etaS1 = 0.001; // FIXME is there a tool which provides a better value?
279 float s_errz = 0.0;
280
281 if ((cluster->inBarrel() && !cluster->inEndcap()) ||
282 (cluster->inBarrel() && cluster->inEndcap() && cluster->eSample(CaloSampling::EMB1) > cluster->eSample(CaloSampling::EME1))) {
283 // Barrel case
284 float error_Z_Calo_1st_Sampling_barrel = error_etaS1*RZ1.first*fabs(cosh(etas1));
285 s_errz = error_Z_Calo_1st_Sampling_barrel*dist_vtx_to_conv/dist_conv_to_s1;
286 } else {
287 // Endcap case
288 float error_R_Calo_1st_Sampling_endcap = error_etaS1*cosh(etas1)*RZ1.first*RZ1.first/fabs(RZ1.second);
289 s_errz = error_R_Calo_1st_Sampling_endcap*fabs(sinh(etas1))*dist_vtx_to_conv/dist_conv_to_s1;
290 }
291
292 return std::make_pair(s_zvertex, s_errz);
293 }
294
295} // namespace CP
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
float getCorrectedZ(float zPointing, float etas2) const
std::pair< float, float > getCaloPointing(const xAOD::Egamma *egamma) const
Return calo pointing variables.
SG::WriteDecorHandleKey< xAOD::EgammaContainer > m_errz
SG::WriteDecorHandleKey< xAOD::EgammaContainer > m_HPV_zvertex
PhotonPointingTool(const std::string &name)
StatusCode updatePointingAuxdata(const xAOD::EgammaContainer &egammas) const
Add calo and conversion (HPV) pointing variables.
TH1F * m_zCorrection
Create a proper constructor for Athena.
SG::WriteDecorHandleKey< xAOD::EgammaContainer > m_zvertex
virtual StatusCode initialize()
Function initialising the tool.
SG::ReadHandleKey< xAOD::EventInfo > m_evtInfo
SG::WriteDecorHandleKey< xAOD::EgammaContainer > m_HPV_errz
std::pair< float, float > getConvPointing(const xAOD::Photon *photon) const
Return conversion (HPV) pointing variables.
static std::pair< float, float > getRZ(float eta, int sampling)
Shower depth in R,Z for the given sampling.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Handle class for adding a decoration to an object.
bool isAvailable()
Test to see if this variable exists in the store, for the referenced object.
AsgMetadataTool(const std::string &name)
Normal ASG tool constructor with a name.
MetaStorePtr_t inputMetaStore() const
Accessor for the input metadata store.
elec/gamma data class.
Definition egamma.h:58
float phiBE(const unsigned layer) const
Get the phi in one layer of the EM Calo.
virtual double eta() const
The pseudorapidity ( ) of the particle.
virtual double e() const
The total energy of the particle.
bool inBarrel() const
Returns true if at least one clustered cell in the barrel.
float eSample(const CaloSample sampling) const
bool inEndcap() const
Returns true if at least one clustered cell in the endcap.
float etaBE(const unsigned layer) const
Get the eta in one layer of the EM Calo.
@ simFlavour
Fast or Full sim [string].
bool value(MetaDataType type, std::string &val) const
Get a pre-defined string value out of the object.
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:114
Select isolated Photons, Electrons and Muons.
@ Photon
The object is a photon.
Definition ObjectType.h:47
std::size_t numberOfSiTracks(const xAOD::Photon *eg)
return the number of Si tracks in the conversion
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
Vertex_v1 Vertex
Define the latest version of the vertex class.
Egamma_v1 Egamma
Definition of the current "egamma version".
Definition Egamma.h:17
Photon_v1 Photon
Definition of the current "egamma version".
FileMetaData_v1 FileMetaData
Declare the latest version of the class.
EgammaContainer_v1 EgammaContainer
Definition of the current "egamma container version".
TFile * file