ATLAS Offline Software
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
12 #include "xAODEgamma/EgammaDefs.h"
14 
15 // Framework includes
19 
20 // ROOT includes
21 #include "TFile.h"
22 #include "TH1F.h"
23 
24 // std includes
25 #include <algorithm>
26 
27 namespace CP {
28 
29 //____________________________________________________________________________
31  : asg::AsgMetadataTool(name)
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 //____________________________________________________________________________
46 {
47  SafeDelete(m_zCorrection);
48 }
49 
50 //____________________________________________________________________________
52 {
53  ATH_MSG_INFO("Initializing PhotonVertexSelectionTool..." << name());
54 
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::ShowerDepthTool::getRZ(etas1, 1);
207  std::pair<float, float> RZ2 = CP::ShowerDepthTool::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::ShowerDepthTool::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
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
egPhotonWrtPoint.h
CP::PhotonPointingTool::m_isMC
bool m_isMC
Definition: PhotonPointingTool.h:62
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
get_generator_info.result
result
Definition: get_generator_info.py:21
constants.EMB1
int EMB1
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:53
SG::WriteDecorHandle::isAvailable
bool isAvailable()
Test to see if this variable exists in the store, for the referenced object.
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
ParticleTest.eg
eg
Definition: ParticleTest.py:29
ShowerDepthTool.h
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
CP::PhotonPointingTool::PhotonPointingTool
PhotonPointingTool(const std::string &name)
Definition: PhotonPointingTool.cxx:30
CP::PhotonPointingTool::getCaloPointing
std::pair< float, float > getCaloPointing(const xAOD::Egamma *egamma) const
Return calo pointing variables.
Definition: PhotonPointingTool.cxx:174
asg
Definition: DataHandleTestTool.h:28
downloadSingle.dataType
string dataType
Definition: downloadSingle.py:18
asg::AsgMetadataTool::inputMetaStore
MetaStorePtr_t inputMetaStore() const
Accessor for the input metadata store.
Definition: AsgMetadataTool.cxx:88
xAOD::CaloCluster_v1::phiBE
float phiBE(const unsigned layer) const
Get the phi in one layer of the EM Calo.
Definition: CaloCluster_v1.cxx:680
xAOD::Egamma_v1
Definition: Egamma_v1.h:56
CP::PhotonPointingTool::m_zOscFileData
std::string m_zOscFileData
Definition: PhotonPointingTool.h:63
CP::PhotonPointingTool::m_zOscFileMC
std::string m_zOscFileMC
Definition: PhotonPointingTool.h:63
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
CP::PhotonPointingTool::m_zvertexDecorName
std::string m_zvertexDecorName
Definition: PhotonPointingTool.h:64
CP
Select isolated Photons, Electrons and Muons.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:48
xAOD::EventInfo_v1::beamPosX
float beamPosX() const
X coordinate of the beam spot position.
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
egamma
Definition: egamma.h:58
xAOD::FileMetaData_v1::value
bool value(MetaDataType type, std::string &val) const
Get a pre-defined string value out of the object.
Definition: FileMetaData_v1.cxx:195
xAOD::FileMetaData_v1::simFlavour
@ simFlavour
Fast or Full sim [string].
Definition: FileMetaData_v1.h:76
CP::PhotonPointingTool::m_HPV_errz
SG::WriteDecorHandleKey< xAOD::EgammaContainer > m_HPV_errz
Definition: PhotonPointingTool.h:56
xAOD::CaloCluster_v1::etaBE
float etaBE(const unsigned layer) const
Get the eta in one layer of the EM Calo.
Definition: CaloCluster_v1.cxx:644
xAOD::EventInfo_v1::beamPosY
float beamPosY() const
Y coordinate of the beam spot position.
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
CP::PhotonPointingTool::m_HPV_zvertexDecorName
std::string m_HPV_zvertexDecorName
Definition: PhotonPointingTool.h:66
xAOD::CaloCluster_v1::inEndcap
bool inEndcap() const
Returns true if at least one clustered cell in the endcap.
Definition: CaloCluster_v1.h:901
CP::PhotonPointingTool::initialize
virtual StatusCode initialize()
Function initialising the tool.
Definition: PhotonPointingTool.cxx:51
xAOD::EgammaHelpers::numberOfSiTracks
std::size_t numberOfSiTracks(const xAOD::Photon *eg)
return the number of Si tracks in the conversion
Definition: PhotonxAODHelpers.cxx:57
xAOD::CaloCluster_v1::eta
virtual double eta() const
The pseudorapidity ( ) of the particle.
Definition: CaloCluster_v1.cxx:251
CP::ShowerDepthTool::getRZ
static std::pair< float, float > getRZ(float eta, int sampling)
Shower depth in R,Z for the given sampling.
Definition: ShowerDepthTool.cxx:107
CP::PhotonPointingTool::m_errzDecorName
std::string m_errzDecorName
Definition: PhotonPointingTool.h:65
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
SG::WriteDecorHandle
Handle class for adding a decoration to an object.
Definition: StoreGate/StoreGate/WriteDecorHandle.h:99
CP::PhotonPointingTool::m_HPV_errzDecorName
std::string m_HPV_errzDecorName
Definition: PhotonPointingTool.h:67
file
TFile * file
Definition: tile_monitor.h:29
xAOD::CaloCluster_v1::inBarrel
bool inBarrel() const
Returns true if at least one clustered cell in the barrel.
Definition: CaloCluster_v1.h:896
constants.EME1
int EME1
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:55
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
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
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
xAOD::FileMetaData_v1
Class holding file-level metadata about an xAOD file.
Definition: FileMetaData_v1.h:34
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
CP::PhotonPointingTool::m_errz
SG::WriteDecorHandleKey< xAOD::EgammaContainer > m_errz
Definition: PhotonPointingTool.h:54
CP::PhotonPointingTool::m_zCorrection
TH1F * m_zCorrection
Create a proper constructor for Athena.
Definition: PhotonPointingTool.h:43
PhotonVertexHelpers.h
CP::PhotonPointingTool::getCorrectedZ
float getCorrectedZ(float zPointing, float etas2) const
Definition: PhotonPointingTool.cxx:167
PathResolver.h
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
CP::PhotonPointingTool::m_evtInfo
SG::ReadHandleKey< xAOD::EventInfo > m_evtInfo
Definition: PhotonPointingTool.h:45
CP::PhotonPointingTool::~PhotonPointingTool
virtual ~PhotonPointingTool()
Definition: PhotonPointingTool.cxx:45
xAOD::Photon
Photon_v1 Photon
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Photon.h:17
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
xAOD::CaloCluster_v1::eSample
float eSample(const CaloSample sampling) const
Definition: CaloCluster_v1.cxx:521
VertexContainer.h
xAOD::photon
@ photon
Definition: TrackingPrimitives.h:199
FileMetaData.h
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
TH1F
Definition: rootspy.cxx:320
xAOD::Photon_v1
Definition: Photon_v1.h:37
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
CP::PhotonPointingTool::updatePointingAuxdata
StatusCode updatePointingAuxdata(const xAOD::EgammaContainer &egammas) const
Add calo and conversion (HPV) pointing variables.
Definition: PhotonPointingTool.cxx:115
PhotonPointingTool.h
CP::PhotonPointingTool::m_HPV_zvertex
SG::WriteDecorHandleKey< xAOD::EgammaContainer > m_HPV_zvertex
Definition: PhotonPointingTool.h:55
EgammaDefs.h
CP::PhotonPointingTool::getConvPointing
std::pair< float, float > getConvPointing(const xAOD::Photon *photon) const
Return conversion (HPV) pointing variables.
Definition: PhotonPointingTool.cxx:225
merge.status
status
Definition: merge.py:17
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
CP::PhotonPointingTool::m_ContainerName
std::string m_ContainerName
Definition: PhotonPointingTool.h:68
CP::PhotonPointingTool::m_zvertex
SG::WriteDecorHandleKey< xAOD::EgammaContainer > m_zvertex
Definition: PhotonPointingTool.h:53
PhotonContainer.h
xAOD::CaloCluster_v1::e
virtual double e() const
The total energy of the particle.
Definition: CaloCluster_v1.cxx:265
pdg_comparison.conv
conv
Definition: pdg_comparison.py:321