ATLAS Offline Software
InDetPhysValTruthDecoratorAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
11 #include "safeDecorator.h"
12 #include <limits>
13 
14 #include "xAODTruth/TruthVertex.h"
16 
17 #include "TDatabasePDG.h"
18 #include "TParticlePDG.h"
19 #include "TrkParameters/TrackParameters.h" // Contains typedef to Trk::CurvilinearParameters
20 #include <cmath>
21 
22 // ref:
23 // https://svnweb.cern.ch/trac/atlasoff/browser/Tracking/TrkEvent/TrkParametersBase/trunk/TrkParametersBase/CurvilinearParametersT.h
24 
25 
26 
27 
28 
29 InDetPhysValTruthDecoratorAlg::InDetPhysValTruthDecoratorAlg(const std::string& name, ISvcLocator* pSvcLocator) :
30  AthReentrantAlgorithm(name, pSvcLocator)
31 {
32 }
33 
35  // nop
36 }
37 
40  ATH_CHECK(m_extrapolator.retrieve());
41  ATH_CHECK(m_beamSpotDecoKey.initialize());
42  ATH_CHECK( m_truthPixelClusterName.initialize() );
43  ATH_CHECK( m_truthSCTClusterName.initialize() );
44  ATH_CHECK( m_truthSelectionTool.retrieve( EnableTool { not m_truthSelectionTool.name().empty() } ) );
45  if (not m_truthSelectionTool.name().empty() ) {
46  m_cutFlow = CutFlow(m_truthSelectionTool->nCuts() );
47  }
48 
50  if (!m_truthParticleIndexDecor.key().empty()) {
52  }
54 
55  std::vector<std::string> decor_names(kNDecorators);
56  decor_names[kDecorD0]="d0";
57  decor_names[kDecorZ0]="z0";
58  decor_names[kDecorPhi]="phi";
59  decor_names[kDecorTheta]="theta";
60  decor_names[kDecorZ0st]="z0st";
61  decor_names[kDecorQOverP]="qOverP";
62  decor_names[kDecorProdR]="prodR";
63  decor_names[kDecorProdZ]="prodZ";
64  decor_names[kDecorNSilHits]="nSilHits";
65 
67  assert( m_decor.size() == kNDecorators);
68  return StatusCode::SUCCESS;
69 }
70 
73  if (not m_truthSelectionTool.name().empty()) {
74  std::lock_guard<std::mutex> lock(m_mutex);
75  ATH_MSG_DEBUG( "Truth selection cut flow : " << m_cutFlow.report(m_truthSelectionTool->names()) );
76  }
78  ATH_MSG_INFO( "Clusters which reference missing / thinned truth particles : " << m_nMissingTruthParticles );
79  }
80  return StatusCode::SUCCESS;
81 }
82 
84 InDetPhysValTruthDecoratorAlg::execute(const EventContext &ctx) const {
86  if ((not ptruth.isValid())) {
87  return StatusCode::FAILURE;
88  }
89  std::size_t ptruth_size=ptruth->size();
90 
91  std::vector<unsigned int> truthIndexMap;
94  unsigned int max_size=0;
95  assert( ptruth_size < std::numeric_limits<unsigned int>::max());
96  for (const xAOD::TruthParticle *truth_particle : *ptruth) {
97  max_size = std::max( max_size, decor_index(*truth_particle) );
98  }
100  ATH_MSG_ERROR("Truth index exceed max allowed range.");
101  return StatusCode::FAILURE;
102  }
103  ++max_size;
104  truthIndexMap.resize( max_size, std::numeric_limits<unsigned int>::max());
105  unsigned int new_index=0;
106  for (const xAOD::TruthParticle *truth_particle : *ptruth) {
107  truthIndexMap.at( decor_index(*truth_particle) ) = new_index;
108  ++new_index;
109  }
110  }
111  else {
112  truthIndexMap.reserve(ptruth_size);
113  for (unsigned int i=0; i<ptruth_size; ++i) {
114  truthIndexMap.push_back(i);
115  }
116  }
117 
118  std::vector< IDPVM::OptionalDecoration<xAOD::TruthParticleContainer,float> >
119  float_decor( IDPVM::createDecoratorsIfNeeded(*ptruth, m_decor, ctx, msgLvl(MSG::DEBUG)) );
120 
122  std::vector< std::array<uint16_t, kNClusterTypes> > tp_clustercount;
123  tp_clustercount.resize(ptruth_size,std::array<uint16_t,kNClusterTypes>{});
124  unsigned int missing_truth_particle=0u;
125  //Loop over the pixel and sct clusters to fill the truth barcode - cluster count maps
128  //only decorate the truth particles with truth silicon hits if both containers are available
129  if (sctClusters.isValid() && pixelClusters.isValid()) {
130  for (const auto *const sct : *sctClusters) {
131  const xAOD::TrackMeasurementValidation* sctCluster = sct;
132  static const SG::AuxElement::ConstAccessor< std::vector<unsigned int> > truthIndexAcc("truth_index");
133  if (truthIndexAcc.isAvailable(*sctCluster)) {
134  const std::vector<unsigned int> &truth_indices = truthIndexAcc(*sctCluster);
135  for (auto index : truth_indices) {
137  if (index < truthIndexMap.size() && truthIndexMap[index] != std::numeric_limits<unsigned int>::max()) {
138  ++tp_clustercount.at(truthIndexMap[index])[kSCT];
139  }
140  else {
141  ++missing_truth_particle;
142  }
143  }
144  }
145  }
146  } // Loop over SCT clusters
147 
148  for (const auto *const pix : *pixelClusters) {
149  const xAOD::TrackMeasurementValidation* pixCluster = pix;
150  static const SG::AuxElement::ConstAccessor< std::vector<unsigned int> > truthIndexAcc("truth_index");
151  if (truthIndexAcc.isAvailable(*pixCluster)) {
152  const std::vector<unsigned int> &truth_indices = truthIndexAcc(*pixCluster);
153  for (auto index : truth_indices) {
155  if (index < truthIndexMap.size() && truthIndexMap[index] != std::numeric_limits<unsigned int>::max()) {
156  ++tp_clustercount.at(truthIndexMap[index])[kPixel];
157  }
158  else {
159  ++missing_truth_particle;
160  }
161  }
162  }
163  }
164  } // Loop over PIX clusters
165  }
166  m_nMissingTruthParticles += missing_truth_particle;
167 
168  if (not float_decor.empty()) {
172  Amg::Vector3D beamPos = Amg::Vector3D(beamPosX(0), beamPosY(0), beamPosZ(0));
173 
174  if ( m_truthSelectionTool.get() ) {
175  CutFlow tmp_cut_flow(m_truthSelectionTool->nCuts());
176  for (const xAOD::TruthParticle *truth_particle : *ptruth) {
177  auto passed = m_truthSelectionTool->accept(truth_particle);
178  tmp_cut_flow.update( passed.missingCuts() );
179  if (not passed) continue;
180  decorateTruth(*truth_particle, float_decor, beamPos, tp_clustercount);
181  }
182  std::lock_guard<std::mutex> lock(m_mutex);
183  m_cutFlow.merge(std::move(tmp_cut_flow));
184  }
185  else {
186  for (const xAOD::TruthParticle *truth_particle : *ptruth) {
187  decorateTruth(*truth_particle, float_decor, beamPos, tp_clustercount);
188  }
189  }
190  }
191  return StatusCode::SUCCESS;
192 }
193 
194 
195 
196 bool
199  const Amg::Vector3D& beamPos,
200  const std::vector<std::array<uint16_t,kNClusterTypes> > &counts) const {
201  ATH_MSG_VERBOSE("Decorate truth with d0 etc");
202  if (particle.isNeutral()) {
203  return false;
204  }
205  const EventContext& ctx = Gaudi::Hive::currentContext();
206  const Amg::Vector3D momentum(particle.px(), particle.py(), particle.pz());
207  const int pid(particle.pdgId());
208  double charge = particle.charge();
209 
210  if (std::isnan(charge)) {
211  ATH_MSG_DEBUG("charge not found on particle with pid " << pid);
212  return false;
213  }
214 
215  // @TODO float?
216  float nSiHits = std::accumulate(counts.at(particle.index()).begin(), counts[particle.index()].end(), 0u);
217 
219 
220  const xAOD::TruthVertex* ptruthVertex(nullptr);
221  try{
222  ptruthVertex = particle.prodVtx();
223  } catch (const std::exception& e) {
224  if (not m_errorEmitted) {
225  ATH_MSG_WARNING("A non existent production vertex was requested in calculating the track parameters d0 etc");
226  }
227  m_errorEmitted = true;
228  return false;
229  }
230  if (!ptruthVertex) {
231  ATH_MSG_DEBUG("A production vertex pointer was retrieved, but it is NULL");
232  return false;
233  }
234  const auto xPos = ptruthVertex->x();
235  const auto yPos = ptruthVertex->y();
236  const auto z_truth = ptruthVertex->z();
237  const Amg::Vector3D position(xPos, yPos, z_truth);
238  const float prodR_truth = std::sqrt(xPos * xPos + yPos * yPos);
239  // delete ptruthVertex;ptruthVertex=0;
240  const Trk::CurvilinearParameters cParameters(position, momentum, charge);
241 
242  Trk::PerigeeSurface persf(beamPos);
243 
244  std::unique_ptr<const Trk::TrackParameters> tP ( m_extrapolator->extrapolate(ctx,
245  cParameters,
246  persf, Trk::anyDirection, false) );
247  if (tP) {
248  float d0_truth = tP->parameters()[Trk::d0];
249  float theta_truth = tP->parameters()[Trk::theta];
250  float z0_truth = tP->parameters()[Trk::z0];
251  float phi_truth = tP->parameters()[Trk::phi];
252  float qOverP_truth = tP->parameters()[Trk::qOverP]; // P or Pt ??
253  float z0st_truth = z0_truth * std::sin(theta_truth);
254 
255  // 'safeDecorator' used to prevent a crash in case of adding something which pre-exists.
256  // behaviour chosen is to reject quietly
257  IDPVM::decorateOrRejectQuietly(particle,float_decor[kDecorD0],d0_truth);
258  IDPVM::decorateOrRejectQuietly(particle,float_decor[kDecorZ0],z0_truth);
259  IDPVM::decorateOrRejectQuietly(particle,float_decor[kDecorPhi],phi_truth);
260  IDPVM::decorateOrRejectQuietly(particle,float_decor[kDecorTheta],theta_truth);
261  IDPVM::decorateOrRejectQuietly(particle,float_decor[kDecorZ0st],z0st_truth);
262  IDPVM::decorateOrRejectQuietly(particle,float_decor[kDecorQOverP],qOverP_truth);
263  IDPVM::decorateOrRejectQuietly(particle,float_decor[kDecorProdR],prodR_truth);
265 
266  return true;
267  } else {
268  ATH_MSG_DEBUG("The TrackParameters pointer for this TruthParticle is NULL");
269  return false;
270  }
271 }
272 
Trk::anyDirection
@ anyDirection
Definition: PropDirection.h:22
InDetPhysValTruthDecoratorAlg::kDecorProdR
@ kDecorProdR
Definition: InDetPhysValTruthDecoratorAlg.h:93
InDetPhysValTruthDecoratorAlg::m_truthSelectionTool
PublicToolHandle< IAthSelectionTool > m_truthSelectionTool
Definition: InDetPhysValTruthDecoratorAlg.h:60
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:76
max
#define max(a, b)
Definition: cfImp.cxx:41
TrackParameters.h
InDetPhysValTruthDecoratorAlg::~InDetPhysValTruthDecoratorAlg
virtual ~InDetPhysValTruthDecoratorAlg()
Definition: InDetPhysValTruthDecoratorAlg.cxx:34
TrigCompositeUtils::passed
bool passed(DecisionID id, const DecisionIDContainer &idSet)
checks if required decision ID is in the set of IDs in the container
Definition: TrigCompositeUtilsRoot.cxx:117
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
Trk::PerigeeSurface
Definition: PerigeeSurface.h:43
InDetPhysValTruthDecoratorAlg::kDecorTheta
@ kDecorTheta
Definition: InDetPhysValTruthDecoratorAlg.h:90
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
index
Definition: index.py:1
InDetPhysValTruthDecoratorAlg::m_beamSpotDecoKey
SG::ReadDecorHandleKeyArray< xAOD::EventInfo > m_beamSpotDecoKey
Definition: InDetPhysValTruthDecoratorAlg.h:55
InDetPhysValTruthDecoratorAlg::kPixel
@ kPixel
Definition: InDetPhysValTruthDecoratorAlg.h:45
InDetPhysValTruthDecoratorAlg::decorateTruth
bool decorateTruth(const xAOD::TruthParticle &particle, std::vector< std::pair< SG::WriteDecorHandle< xAOD::TruthParticleContainer, float >, bool > > &float_decor, const Amg::Vector3D &beamPos, const std::vector< std::array< uint16_t, kNClusterTypes > > &counts) const
Definition: InDetPhysValTruthDecoratorAlg.cxx:197
InDetPhysValTruthDecoratorAlg::m_decor
std::vector< std::pair< SG::WriteDecorHandleKey< xAOD::TruthParticleContainer >, SG::AuxElement::ConstAccessor< float > > > m_decor
Definition: InDetPhysValTruthDecoratorAlg.h:98
accumulate
bool accumulate(AccumulateMap &map, std::vector< module_t > const &modules, FPGATrackSimMatrixAccumulator const &acc)
Accumulates an accumulator (e.g.
Definition: FPGATrackSimMatrixAccumulator.cxx:22
InDetPhysValTruthDecoratorAlg::kDecorZ0
@ kDecorZ0
Definition: InDetPhysValTruthDecoratorAlg.h:88
IDPVM::createDecoratorKeysAndAccessor
void createDecoratorKeysAndAccessor(T_Parent &parent, const SG::ReadHandleKey< T_Cont > &container_key, const std::string &prefix, const std::vector< std::string > &decor_names, std::vector< WriteKeyAccessorPair< T_Cont, T > > &decor_out)
Definition: safeDecorator.h:52
safeDecorator.h
Trk::z0
@ z0
Definition: ParamDefs.h:70
AthCommonMsg< Gaudi::Algorithm >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
InDetPhysValTruthDecoratorAlg::m_nMissingTruthParticles
std::atomic< std::size_t > m_nMissingTruthParticles
Definition: InDetPhysValTruthDecoratorAlg.h:65
SG::ConstAccessor
Helper class to provide constant type-safe access to aux data.
Definition: ConstAccessor.h:54
InDetPhysValTruthDecoratorAlg::kDecorProdZ
@ kDecorProdZ
Definition: InDetPhysValTruthDecoratorAlg.h:94
InDetPhysValTruthDecoratorAlg::initialize
virtual StatusCode initialize()
Definition: InDetPhysValTruthDecoratorAlg.cxx:39
InDetPhysValTruthDecoratorAlg::m_errorEmitted
std::atomic< bool > m_errorEmitted
Definition: InDetPhysValTruthDecoratorAlg.h:66
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
SG::VarHandleKey::empty
bool empty() const
Test if the key is blank.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:150
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:83
xAOD::TruthVertex_v1::y
float y() const
Vertex y displacement.
CutFlow::update
void update(bool)
Definition: CutFlow.h:192
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
InDetPhysValTruthDecoratorAlg::execute
virtual StatusCode execute(const EventContext &ctx) const
Definition: InDetPhysValTruthDecoratorAlg.cxx:84
InDetPhysValTruthDecoratorAlg::finalize
virtual StatusCode finalize()
Definition: InDetPhysValTruthDecoratorAlg.cxx:72
InDetPhysValTruthDecoratorAlg::kSCT
@ kSCT
Definition: InDetPhysValTruthDecoratorAlg.h:45
xAOD::TrackMeasurementValidation_v1
Class describing a TrackMeasurementValidation.
Definition: TrackMeasurementValidation_v1.h:27
InDetPhysValTruthDecoratorAlg::kDecorZ0st
@ kDecorZ0st
Definition: InDetPhysValTruthDecoratorAlg.h:91
TauGNNUtils::Variables::Track::nSiHits
bool nSiHits(const xAOD::TauJet &, const xAOD::TauTrack &track, double &out)
Definition: TauGNNUtils.cxx:691
InDetPhysValTruthDecoratorAlg::kDecorD0
@ kDecorD0
Definition: InDetPhysValTruthDecoratorAlg.h:87
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
SG::ReadDecorHandle
Handle class for reading a decoration on an object.
Definition: StoreGate/StoreGate/ReadDecorHandle.h:94
ParticleGun_EoverP_Config.momentum
momentum
Definition: ParticleGun_EoverP_Config.py:63
lumiFormat.i
int i
Definition: lumiFormat.py:92
IDPVM::OptionalDecoration
std::pair< SG::WriteDecorHandle< ContainerType, VariableType >, bool > OptionalDecoration
Definition: safeDecorator.h:48
SG::ReadDecorHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
InDetPhysValTruthDecoratorAlg::kNDecorators
@ kNDecorators
Definition: InDetPhysValTruthDecoratorAlg.h:96
Trk::theta
@ theta
Definition: ParamDefs.h:72
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
IDPVM::decorateOrRejectQuietly
void decorateOrRejectQuietly(const T_Cont_Elm &particle, OptionalDecoration< T_Cont, T > &decorator, const T &value)
Definition: safeDecorator.h:175
xAOD::TruthParticle_v1
Class describing a truth particle in the MC record.
Definition: TruthParticle_v1.h:41
calibdata.exception
exception
Definition: calibdata.py:496
ParticleGun_EoverP_Config.pid
pid
Definition: ParticleGun_EoverP_Config.py:62
InDetPhysValTruthDecoratorAlg::kDecorQOverP
@ kDecorQOverP
Definition: InDetPhysValTruthDecoratorAlg.h:92
CutFlow
Definition: CutFlow.h:166
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
Trk::CurvilinearParametersT
Definition: CurvilinearParametersT.h:48
InDetPhysValTruthDecoratorAlg::m_truthParticleName
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_truthParticleName
TruthParticle container's name needed to create decorators.
Definition: InDetPhysValTruthDecoratorAlg.h:70
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
TruthVertex.h
IDPVM::createDecoratorsIfNeeded
std::vector< OptionalDecoration< T_Cont, T > > createDecoratorsIfNeeded(const T_Cont &container, const std::vector< WriteKeyAccessorPair< T_Cont, T > > &keys, const EventContext &ctx, bool verbose=false)
Definition: safeDecorator.h:70
xAOD::TruthVertex_v1
Class describing a truth vertex in the MC record.
Definition: TruthVertex_v1.h:41
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
Trk::d0
@ d0
Definition: ParamDefs.h:69
charge
double charge(const T &p)
Definition: AtlasPID.h:494
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
xAOD::TruthVertex_v1::x
float x() const
Vertex x displacement.
InDetPhysValTruthDecoratorAlg::m_prefix
Gaudi::Property< std::string > m_prefix
Definition: InDetPhysValTruthDecoratorAlg.h:73
InDetPhysValTruthDecoratorAlg::InDetPhysValTruthDecoratorAlg
InDetPhysValTruthDecoratorAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: InDetPhysValTruthDecoratorAlg.cxx:29
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
InDetPhysValTruthDecoratorAlg::m_truthPixelClusterName
SG::ReadHandleKey< xAOD::TrackMeasurementValidationContainer > m_truthPixelClusterName
TruthPixelClusterContainer and TruthSCTClusterContainer needed for truth silicon hit cut.
Definition: InDetPhysValTruthDecoratorAlg.h:77
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
xAOD::TruthVertex_v1::z
float z() const
Vertex longitudinal distance along the beam line form the origin.
InDetPhysValTruthDecoratorAlg::kDecorPhi
@ kDecorPhi
Definition: InDetPhysValTruthDecoratorAlg.h:89
InDetPhysValTruthDecoratorAlg::m_mutex
std::mutex m_mutex
Definition: InDetPhysValTruthDecoratorAlg.h:62
DEBUG
#define DEBUG
Definition: page_access.h:11
Trk::qOverP
@ qOverP
perigee
Definition: ParamDefs.h:73
InDetPhysValTruthDecoratorAlg::m_extrapolator
PublicToolHandle< Trk::IExtrapolator > m_extrapolator
Definition: InDetPhysValTruthDecoratorAlg.h:53
InDetPhysValTruthDecoratorAlg::m_truthParticleIndexDecor
SG::ReadDecorHandleKey< xAOD::TruthParticleContainer > m_truthParticleIndexDecor
Definition: InDetPhysValTruthDecoratorAlg.h:83
ReadDecorHandle.h
Handle class for reading a decoration on an object.
SG::ConstAccessor::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
Trk::phi
@ phi
Definition: ParamDefs.h:81
InDetPhysValTruthDecoratorAlg::m_truthSCTClusterName
SG::ReadHandleKey< xAOD::TrackMeasurementValidationContainer > m_truthSCTClusterName
Definition: InDetPhysValTruthDecoratorAlg.h:80
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
pix
Definition: PixelMapping.cxx:16
InDetPhysValTruthDecoratorAlg.h
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
InDetPhysValTruthDecoratorAlg::kDecorNSilHits
@ kDecorNSilHits
Definition: InDetPhysValTruthDecoratorAlg.h:95