ATLAS Offline Software
EMConversionBuilder.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 /********************************************************************
6 NAME: EMConversionBuilder.cxx
7 PACKAGE: offline/Reconstruction/egamma/egammaRec
8 
9 AUTHORS: D. Zerwas, B. Lenzi , C. Anastopoulos
10 CREATED: Jul, 2005
11 CHANGES: Mar, 2014 (BL) xAOD migration
12 CHANGES: 2020 (CA) Athena MT migration
13 
14 PURPOSE: subAlgorithm which creates an EMConversion object.
15 
16 ********************************************************************/
17 
18 // INCLUDE HEADER FILES:
19 
20 #include "EMConversionBuilder.h"
21 #include "FourMomUtils/P4Helpers.h"
22 #include "GaudiKernel/EventContext.h"
23 #include "StoreGate/ReadHandle.h"
27 #include "xAODTracking/Vertex.h"
29 
30 // END OF HEADER FILES INCLUDE
31 
33 
34 namespace {
46 bool
47 ConvVxSorter(const xAOD::Vertex& vx1, const xAOD::Vertex& vx2)
48 {
51  convType1 = xAOD::EgammaHelpers::conversionType(&vx1);
52  convType2 = xAOD::EgammaHelpers::conversionType(&vx2);
53 
54  if (convType1 != convType2) {
55  // Different conversion type, preference to vertices with Si tracks
56  int nSi1 = xAOD::EgammaHelpers::numberOfSiTracks(convType1);
57  int nSi2 = xAOD::EgammaHelpers::numberOfSiTracks(convType2);
58  if (nSi1 != nSi2)
59  return nSi1 > nSi2;
60 
61  // Same number of Si tracks: either 0 or 1 (Si+TRT vs. Si single)
62  // For 1 Si track, preference to Si+TRT
63  if (nSi1 != 0)
64  return convType1 == xAOD::EgammaParameters::doubleSiTRT;
65 
66  // No Si track, preference to doubleTRT over single TRT
67  return convType1 == xAOD::EgammaParameters::doubleTRT;
68  }
69 
70  // Same conversion type, preference to lower radius
71  return (vx1.position().perp() < vx2.position().perp());
72 }
73 } // end of namespace
74 
75 using namespace xAOD::EgammaParameters;
76 
78  const std::string& name,
79  const IInterface* parent)
81 {
82 
83  // declare interface
84  declareInterface<IEMConversionBuilder>(this);
85 }
86 
89 {
90 
91  ATH_MSG_DEBUG("Initializing EMConversionBuilder");
92 
93  ATH_CHECK(m_conversionContainerKey.initialize());
94 
95  // the extrapolation tool
96  if (m_extrapolationTool.retrieve().isFailure()) {
97  ATH_MSG_ERROR("Cannot retrieve extrapolationTool " << m_extrapolationTool);
98  return StatusCode::FAILURE;
99  }
100  ATH_MSG_DEBUG("Retrieved extrapolationTool " << m_extrapolationTool);
101 
102  return StatusCode::SUCCESS;
103 }
104 
106 EMConversionBuilder::executeRec(const EventContext& ctx, egammaRec* egRec) const
107 {
108  // retrieve Conversion Container
109 
111  ctx);
112 
113  // only for serial running; remove for MT
114  ATH_CHECK(conversions.isValid());
115  // reset the vertices
116  std::vector<ElementLink<xAOD::VertexContainer>> vertices;
117  egRec->setVertices(vertices);
118  ATH_CHECK(vertexExecute(ctx, egRec, conversions.cptr()));
119  return StatusCode::SUCCESS;
120 }
121 
124  const EventContext& ctx,
125  egammaRec* egRec,
126  const xAOD::VertexContainer* conversions) const
127 {
128 
129  if (!egRec || !conversions) {
131  "trackExecute: NULL pointer to egammaRec or VertexContainer");
132  return StatusCode::SUCCESS;
133  }
134 
135  static const SG::AuxElement::Accessor<float> accetaAtCalo("etaAtCalo");
136  static const SG::AuxElement::Accessor<float> accphiAtCalo("phiAtCalo");
137 
138  float etaAtCalo(0);
139  float phiAtCalo(0);
140  for (unsigned int iVtx = 0; iVtx < conversions->size(); ++iVtx) {
141 
142  const xAOD::Vertex* vertex = conversions->at(iVtx);
143  // Check if vertex was already decorated with etaAtCalo, phiAtCalo
144  if (accetaAtCalo.isAvailable(*vertex) &&
145  accphiAtCalo.isAvailable(*vertex)) {
146  etaAtCalo = accetaAtCalo(*vertex);
147  phiAtCalo = accphiAtCalo(*vertex);
148  }
149  // check extrapolation, skip vertex in case of failure
150  else if (!m_extrapolationTool->getEtaPhiAtCalo(
151  ctx, vertex, &etaAtCalo, &phiAtCalo)) {
152  continue;
153  }
154  const xAOD::CaloCluster* cluster = egRec->caloCluster();
155  if (!passPtAndEoverP(ctx, *vertex, *cluster)) {
156  continue;
157  }
158  if (!m_extrapolationTool->matchesAtCalo(
159  cluster, vertex, etaAtCalo, phiAtCalo)) {
160  continue;
161  }
162  const ElementLink<xAOD::VertexContainer> vertexLink(*conversions, iVtx, ctx);
163 
164  // If this is the best (or the first) vertex, push front and keep deltaEta,
165  // deltaPhi
166  if (!egRec->getNumberOfVertices() ||
167  ConvVxSorter(*vertex, *egRec->vertex())) {
168  egRec->pushFrontVertex(vertexLink);
169  egRec->setDeltaEtaVtx(cluster->etaBE(2) - etaAtCalo);
170  egRec->setDeltaPhiVtx(P4Helpers::deltaPhi(cluster->phiBE(2), phiAtCalo));
171  } else { // Not the best vertex, push back
172  egRec->pushBackVertex(vertexLink);
173  }
174  }
175  return StatusCode::SUCCESS;
176 }
177 
178 bool
179 EMConversionBuilder::passPtAndEoverP(const EventContext& ctx,
180  const xAOD::Vertex& vertex,
181  const xAOD::CaloCluster& cluster) const
182 {
184  m_extrapolationTool->getMomentumAtVertex(ctx, vertex);
185  float pt = momentum.perp();
186  float EoverP = cluster.e() / momentum.mag();
187 
189  bool isSingle = (convType == singleTRT || convType == singleSi);
190  bool isTRT =
191  (convType == singleTRT || convType == xAOD::EgammaParameters::doubleTRT);
192  float EoverPcut = m_maxEoverP_singleTrack *
193  (1 + m_maxEoverP_singleTrack_EtSf * cluster.et() * 1e-3);
194 
195  // Check TRT tube hit fraction
196  float tubeHitFraction = getMaxTRTTubeHitFraction(vertex);
197  if (isTRT && tubeHitFraction > m_maxTRTTubeHitFraction) {
198  ATH_MSG_DEBUG("Conversion failed cut on TRT tube hit fraction: "
199  << tubeHitFraction << " vs. " << m_maxTRTTubeHitFraction);
200  return false;
201  }
202 
203  bool reject =
204  ((isTRT && m_rejectAllTRT) || (isSingle && pt < m_minPt_singleTrack) ||
205  (!isSingle && pt < m_minSumPt_double) ||
206  (isSingle && EoverP > EoverPcut) ||
207  (convType == singleTRT && pt < m_minPt_singleTRT) ||
208  (convType == doubleTRT && pt < m_minSumPt_doubleTRT));
209 
210  if (reject) {
211  ATH_MSG_DEBUG("Conversion failed pt or E/p cuts");
212  }
213  return !reject;
214 }
215 
216 float
218 {
219  auto getTRTTubeHitFraction = [](const xAOD::TrackParticle* trk) {
220  uint8_t nTRT;
221  uint8_t nTRTTube;
222  if (!trk || !trk->summaryValue(nTRT, xAOD::numberOfTRTHits) || !nTRT)
223  return 0.;
224  return trk->summaryValue(nTRTTube, xAOD::numberOfTRTTubeHits)
225  ? 1. * nTRTTube / nTRT
226  : 0.;
227  };
228 
229  float maxTubeHitFraction = 0.;
230  for (unsigned int i = 0; i < vertex.nTrackParticles(); ++i) {
231  if (!vertex.trackParticle(i)) {
232  ATH_MSG_WARNING("NULL pointer to track particle in conversion vertex");
233  } else {
234  float tubeHitFraction = getTRTTubeHitFraction(vertex.trackParticle(i));
235  if (tubeHitFraction > maxTubeHitFraction) {
236  maxTubeHitFraction = tubeHitFraction;
237  }
238  }
239  }
240  return maxTubeHitFraction;
241 }
egammaRec::pushFrontVertex
void pushFrontVertex(const ElementLink< xAOD::VertexContainer > &vertexElementLink)
Push front another vertex.
Definition: egammaRec.cxx:82
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
xAOD::name
name
Definition: TriggerMenuJson_v1.cxx:29
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:557
egammaRec::getNumberOfVertices
size_t getNumberOfVertices() const
Return the number xAOD::Vertex/vertices that match the photon candidate.
SG::ReadHandle::cptr
const_pointer_type cptr()
Dereference the pointer.
EMConversionBuilder::executeRec
virtual StatusCode executeRec(const EventContext &ctx, egammaRec *egRec) const override final
execute method
Definition: EMConversionBuilder.cxx:106
SG::Accessor
Helper class to provide type-safe access to aux data.
Definition: Control/AthContainers/AthContainers/Accessor.h:68
EMConversionBuilder.h
EMConversionBuilder::m_maxTRTTubeHitFraction
Gaudi::Property< float > m_maxTRTTubeHitFraction
"Maximum fraction of tube hits for vertices with TRT tracks
Definition: EMConversionBuilder.h:171
EMConversionBuilder::m_minSumPt_double
Gaudi::Property< float > m_minSumPt_double
minimum sum pT for double track conversion vertices
Definition: EMConversionBuilder.h:138
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
EMConversionBuilder::m_minSumPt_doubleTRT
Gaudi::Property< float > m_minSumPt_doubleTRT
minimum sum pT for double TRT track conversion vertices
Definition: EMConversionBuilder.h:146
EMConversionBuilder::m_maxEoverP_singleTrack
Gaudi::Property< float > m_maxEoverP_singleTrack
maximum E/p for single track conversion vertices (E is not calibrated)
Definition: EMConversionBuilder.h:155
EMConversionBuilder::initialize
StatusCode initialize() override final
initialize method
Definition: EMConversionBuilder.cxx:88
egammaRec::caloCluster
const xAOD::CaloCluster * caloCluster(size_t index=0) const
Pointer to the xAOD::CaloCluster/s that define the electron candidate.
Definition: egammaRec.cxx:8
test_pyathena.pt
pt
Definition: test_pyathena.py:11
xAOD::CaloCluster_v1::et
double et() const
Definition: CaloCluster_v1.h:856
EMConversionBuilder::getMaxTRTTubeHitFraction
float getMaxTRTTubeHitFraction(const xAOD::Vertex &vertex) const
Return the maximum fraction of TRT tube hits among the tracks.
Definition: EMConversionBuilder.cxx:217
EMConversionBuilder::m_extrapolationTool
ToolHandle< IEMExtrapolationTools > m_extrapolationTool
EMExtrapolationTools.
Definition: EMConversionBuilder.h:86
xAOD::numberOfTRTHits
@ numberOfTRTHits
number of TRT hits [unit8_t].
Definition: TrackingPrimitives.h:275
xAOD::Vertex_v1::position
const Amg::Vector3D & position() const
Returns the 3-pos.
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::EgammaParameters::ConversionType
ConversionType
Definition: EgammaEnums.h:268
xAOD::numberOfTRTTubeHits
@ numberOfTRTTubeHits
number of TRT tube hits [unit8_t].
Definition: TrackingPrimitives.h:283
EMConversionBuilder::m_conversionContainerKey
SG::ReadHandleKey< xAOD::VertexContainer > m_conversionContainerKey
Name of conversion container.
Definition: EMConversionBuilder.h:78
EMConversionBuilder::passPtAndEoverP
bool passPtAndEoverP(const EventContext &ctx, const xAOD::Vertex &, const xAOD::CaloCluster &) const
Return true if vertex and cluster pass Pt and E/p cuts.
Definition: EMConversionBuilder.cxx:179
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::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
P4Helpers::deltaPhi
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
Definition: P4Helpers.h:34
EgammaxAODHelpers.h
xAOD::EgammaHelpers::numberOfSiTracks
std::size_t numberOfSiTracks(const xAOD::Photon *eg)
return the number of Si tracks in the conversion
Definition: PhotonxAODHelpers.cxx:57
egammaRec::setDeltaPhiVtx
void setDeltaPhiVtx(float value)
set deltaPhiVtx
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ParticleGun_EoverP_Config.momentum
momentum
Definition: ParticleGun_EoverP_Config.py:63
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
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
EMConversionBuilder::vertexExecute
StatusCode vertexExecute(const EventContext &ctx, egammaRec *egRec, const xAOD::VertexContainer *conversions) const
actual implementation method
Definition: EMConversionBuilder.cxx:123
egammaRec::pushBackVertex
void pushBackVertex(const ElementLink< xAOD::VertexContainer > &vertexElementLink)
Push back another vertex.
Definition: egammaRec.cxx:76
egammaRec.h
test_pyathena.parent
parent
Definition: test_pyathena.py:15
EMConversionBuilder::m_minPt_singleTrack
Gaudi::Property< float > m_minPt_singleTrack
minimum pT for single-track conversion vertices
Definition: EMConversionBuilder.h:113
egammaRec::setVertices
void setVertices(const std::vector< ElementLink< xAOD::VertexContainer >> &links)
set Pointer to the xAOD::vertex/vertices that match the photon candidate
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
Vertex.h
xAOD::EgammaParameters::doubleSiTRT
@ doubleSiTRT
two tracks, only one with Si hits
Definition: EgammaEnums.h:285
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
xAOD::EgammaParameters::singleTRT
@ singleTRT
one track only, no Si hits (TRT only)
Definition: EgammaEnums.h:276
egammaRec::setDeltaEtaVtx
void setDeltaEtaVtx(float value)
set deltaEtaVtx
P4Helpers.h
xAOD::EgammaParameters
Definition: EgammaDefs.h:19
xAOD::EgammaParameters::singleSi
@ singleSi
one track only, with Si hits
Definition: EgammaEnums.h:273
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
VertexContainer.h
xAOD::Vertex_v1
Class describing a Vertex.
Definition: Vertex_v1.h:42
EMConversionBuilder::m_minPt_singleTRT
Gaudi::Property< float > m_minPt_singleTRT
minimum pT for TRT-only single-track conversion vertices
Definition: EMConversionBuilder.h:121
egammaRec::vertex
const xAOD::Vertex * vertex(size_t index=0) const
Pointer to the xAOD::Vertex/es that match the photon candidate.
Definition: egammaRec.cxx:54
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
EMConversionBuilder::m_maxEoverP_singleTrack_EtSf
Gaudi::Property< float > m_maxEoverP_singleTrack_EtSf
Scale maxEoverP_singleTrack by 1+sf*Et(cluster)/GeV
Definition: EMConversionBuilder.h:163
xAOD::EgammaHelpers::conversionType
xAOD::EgammaParameters::ConversionType conversionType(const xAOD::Photon *ph)
return the photon conversion type (see EgammaEnums)
Definition: PhotonxAODHelpers.cxx:26
egammaRec
Definition: egammaRec.h:31
SG::ConstAccessor< T, AuxAllocator_t< T > >::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
xAOD::EgammaParameters::doubleTRT
@ doubleTRT
two tracks, none with Si hits (TRT only)
Definition: EgammaEnums.h:282
egammaRecContainer.h
AllowedVariables::EoverP
@ EoverP
Definition: AsgElectronSelectorTool.cxx:56
xAOD::TrackParticle_v1
Class describing a TrackParticle.
Definition: TrackParticle_v1.h:43
DataVector::at
const T * at(size_type n) const
Access an element, as an rvalue.
ReadHandle.h
Handle class for reading from StoreGate.
AthAlgTool
Definition: AthAlgTool.h:26
EMConversionBuilder::EMConversionBuilder
EMConversionBuilder(const std::string &type, const std::string &name, const IInterface *parent)
Default constructor.
Definition: EMConversionBuilder.cxx:77
EMConversionBuilder::m_rejectAllTRT
Gaudi::Property< bool > m_rejectAllTRT
Ignore all conversion vertices that contain exclusively TRT-only tracks.
Definition: EMConversionBuilder.h:95
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
xAOD::CaloCluster_v1::e
virtual double e() const
The total energy of the particle.
Definition: CaloCluster_v1.cxx:265