ATLAS Offline Software
TruthSegmentMaker.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 #include "TruthSegmentMaker.h"
5 
7 #include "StoreGate/ReadHandle.h"
9 
11 
18 
20 
21 #include "GaudiKernel/PhysicalConstants.h"
22 
23 #include <unordered_map>
24 
25 namespace{
26  constexpr double c_inv = 1./Gaudi::Units::c_light;
27 }
28 
29 namespace MuonR4{
30  using namespace SegmentFit;
31  template <class ContainerType>
34  const ContainerType*& contToPush) const {
35  contToPush = nullptr;
36  if (key.empty()) {
37  ATH_MSG_VERBOSE("No key has been parsed for object "<< typeid(ContainerType).name());
38  return StatusCode::SUCCESS;
39  }
40  SG::ReadHandle readHandle{key, ctx};
41  ATH_CHECK(readHandle.isPresent());
42  contToPush = readHandle.cptr();
43  return StatusCode::SUCCESS;
44  }
46  ATH_CHECK(m_idHelperSvc.retrieve());
47  ATH_CHECK(m_readKeys.initialize());
48  if (m_readKeys.empty()){
49  ATH_MSG_ERROR("No simulated hit containers have been parsed to build the segments from ");
50  return StatusCode::FAILURE;
51  }
52  ATH_CHECK(m_segmentKey.initialize());
53  ATH_CHECK(m_eleLinkKey.initialize());
54  ATH_CHECK(m_ptKey.initialize());
55 
56  ATH_CHECK(m_locParKey.initialize());
57  ATH_CHECK(m_qKey.initialize());
58 
59  ATH_CHECK(m_geoCtxKey.initialize());
60  ATH_CHECK(detStore()->retrieve(m_detMgr));
61  return StatusCode::SUCCESS;
62  }
64  const Identifier& chanId) const {
65  const MuonGMR4::MuonReadoutElement* reEle = m_detMgr->getReadoutElement(chanId);
66  const IdentifierHash trfHash{reEle->detectorType() == ActsTrk::DetectorType::Mdt ?
67  reEle->measurementHash(chanId) :
68  reEle->layerHash(chanId)};
69  return reEle->msSector()->globalToLocalTrans(gctx) * reEle->localToGlobalTrans(gctx, trfHash);
70 
71  }
72  StatusCode TruthSegmentMaker::execute(const EventContext& ctx) const {
73  const ActsGeometryContext* gctx{nullptr};
74  ATH_CHECK(retrieveContainer(ctx, m_geoCtxKey, gctx));
75 
76 
77  using HitsPerParticle = std::unordered_map<HepMC::ConstGenParticlePtr, std::vector<const xAOD::MuonSimHit*>>;
78  using HitCollector = std::unordered_map<const MuonGMR4::SpectrometerSector*, HitsPerParticle>;
79  HitCollector hitCollector{};
80 
81  for (const SG::ReadHandleKey<xAOD::MuonSimHitContainer>& key : m_readKeys) {
82  const xAOD::MuonSimHitContainer* simHits{nullptr};
83  ATH_CHECK(retrieveContainer(ctx, key, simHits));
84  for (const xAOD::MuonSimHit* simHit : *simHits) {
85  const MuonGMR4::MuonReadoutElement* reElement = m_detMgr->getReadoutElement(simHit->identify());
86  const MuonGMR4::SpectrometerSector* id{reElement->msSector()};
87  auto genLink = simHit->genParticleLink();
88  HepMC::ConstGenParticlePtr genParticle = nullptr;
89  if (genLink.isValid()){
90  genParticle = genLink.cptr();
91  }
93  if (!genParticle || (m_useOnlyMuonHits && std::abs(simHit->pdgId()) != 13)) {
94  continue;
95  }
96  hitCollector[id][genParticle].push_back(simHit);
97  }
98  }
99 
100  SG::WriteHandle writeHandle{m_segmentKey, ctx};
101  ATH_CHECK(writeHandle.record(std::make_unique<xAOD::MuonSegmentContainer>(),
102  std::make_unique<xAOD::MuonSegmentAuxContainer>()));
103 
104  using HitLinkVec = std::vector<ElementLink<xAOD::MuonSimHitContainer>>;
110  for (auto& [chamber, collectedParts] : hitCollector) {
111  const Amg::Transform3D& locToGlob{chamber->localToGlobalTrans(*gctx)};
112 
113  for (auto& [particle, simHits]: collectedParts) {
114 
115  /* Take the hit that's closest to the chamber centre as reference */
116  std::ranges::stable_sort(simHits,[gctx,this](const xAOD::MuonSimHit*a, const xAOD::MuonSimHit*b){
117  return std::abs((toChamber(*gctx, a->identify())* xAOD::toEigen(a->localPosition())).z()) <
118  std::abs((toChamber(*gctx, b->identify())* xAOD::toEigen(b->localPosition())).z());
119  });
120  const xAOD::MuonSimHit* simHit = simHits.front();
121  const Identifier segId{simHit->identify()};
122 
123  const Amg::Transform3D inChamb = toChamber(*gctx, segId);
124  const Amg::Vector3D localPos{inChamb * xAOD::toEigen(simHit->localPosition())};
125  const Amg::Vector3D chamberDir = inChamb.linear() * xAOD::toEigen(simHit->localDirection());
126 
128  const double distance = Amg::intersect<3>(localPos, chamberDir, Amg::Vector3D::UnitZ(), 0.).value_or(0.);
129  const Amg::Vector3D chamberPos = localPos + distance*chamberDir;
130 
131  const Amg::Vector3D globPos = locToGlob * chamberPos;
132  const Amg::Vector3D globDir = locToGlob.linear() * chamberDir;
133  HitLinkVec associatedHits{};
134  unsigned int nMdt{0}, nRpcEta{0}, nRpcPhi{0}, nTgcEta{0}, nTgcPhi{0};
135  unsigned int nMm{0}, nStgcEta{0}, nStgcPhi{0};
136  for (const xAOD::MuonSimHit* assocMe : simHits) {
137  const MuonGMR4::MuonReadoutElement* assocRE = m_detMgr->getReadoutElement(assocMe->identify());
138  switch (assocRE->detectorType()) {
140  ++nMdt;
141  break;
143  auto castRE{static_cast<const MuonGMR4::RpcReadoutElement*>(assocRE)};
144  if (castRE->nEtaStrips()) ++nRpcEta;
145  if (castRE->nPhiStrips()) ++nRpcPhi;
146  break;
148  auto castRE{static_cast<const MuonGMR4::TgcReadoutElement*>(assocRE)};
149  const int gasGap = m_idHelperSvc->gasGap(assocMe->identify());
150  if (castRE->numStrips(gasGap)) ++nTgcPhi;
151  if (castRE->numWireGangs(gasGap)) ++nTgcEta;
152  break;
154  ++nStgcEta;
155  ++nStgcPhi;
156  break;
158  ++nMm;
159  break;
160  }
161  default:
162  ATH_MSG_WARNING("Csc are not defined "<<m_idHelperSvc->toString(simHit->identify()));
163  }
164  ElementLink<xAOD::MuonSimHitContainer> link{*static_cast<const xAOD::MuonSimHitContainer*>(assocMe->container()),
165  assocMe->index()};
166  associatedHits.push_back(std::move(link));
167  }
168  int nPrecisionHits = nMdt + nMm + nStgcEta;
169  int nPhiLayers = nTgcPhi + nRpcPhi + nStgcPhi;
170  // if nMdt + nMm + nStgcEta < 3, do not create a segment
171  if (nPrecisionHits < 3) continue;
172 
173  xAOD::MuonSegment* truthSegment = writeHandle->push_back(std::make_unique<xAOD::MuonSegment>());
174  ptDecor(*truthSegment) = particle->momentum().perp();
175  qDecor(*truthSegment) = particle->pdg_id() > 0 ? -1 : 1;
176  SegPars& locPars{parDecor(*truthSegment)};
177  locPars[toInt(ParamDefs::x0)] = chamberPos.x();
178  locPars[toInt(ParamDefs::y0)] = chamberPos.y();
179  locPars[toInt(ParamDefs::time)] = simHit->globalTime() + distance *c_inv /simHit->beta();
180  locPars[toInt(ParamDefs::theta)] = chamberDir.theta();
181  locPars[toInt(ParamDefs::phi)] = chamberDir.phi();
182  truthSegment->setPosition(globPos.x(), globPos.y(), globPos.z());
183  truthSegment->setDirection(globDir.x(), globDir.y(), globDir.z());
184  truthSegment->setT0Error(locPars[toInt(ParamDefs::time)], 0.);
185 
186  truthSegment->setNHits(nPrecisionHits, nPhiLayers, nTgcEta + nRpcEta);
187  truthSegment->setIdentifier(m_idHelperSvc->sector(segId),
188  m_idHelperSvc->chamberIndex(segId),
189  m_idHelperSvc->stationEta(segId),
190  m_idHelperSvc->technologyIndex(segId));
191  // adding chi2 and ndof (nHits - 5 for 2 position, 2 direction and 1 time)
192  if (nPhiLayers == 0){
193  truthSegment->setFitQuality(0, (nPrecisionHits + nTgcEta + nRpcEta - 3));
194  } else {
195  truthSegment->setFitQuality(0, (nPrecisionHits + nPhiLayers + nTgcEta + nRpcEta - 5));
196  }
197  hitDecor(*truthSegment) = std::move(associatedHits);
198  }
199  }
200  return StatusCode::SUCCESS;
201  }
202 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
xAOD::MuonSimHit_v1
Definition: MuonSimHit_v1.h:18
dumpTgcDigiDeadChambers.gasGap
list gasGap
Definition: dumpTgcDigiDeadChambers.py:33
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:76
MuonGMR4::MuonReadoutElement::msSector
const SpectrometerSector * msSector() const
Returns the pointer to the envelope volume enclosing all chambers in the sector.
MuonGMR4::SpectrometerSector
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
Definition: SpectrometerSector.h:39
xAOD::MuonSegment_v1::setPosition
void setPosition(float x, float y, float z)
Sets the global position.
Definition: MuonSegment_v1.cxx:26
calibdata.chamber
chamber
Definition: calibdata.py:32
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
MuonSegmentAuxContainer.h
MuonR4::TruthSegmentMaker::execute
StatusCode execute(const EventContext &ctx) const override
Definition: TruthSegmentMaker.cxx:72
ActsTrk::DetectorType::Tgc
@ Tgc
Resitive Plate Chambers.
MuonGMR4::MuonReadoutElement
The MuonReadoutElement is an abstract class representing the geometry representing the muon detector.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/MuonReadoutElement.h:38
xAOD::MuonSegment_v1
Class describing a MuonSegment.
Definition: MuonSegment_v1.h:33
ActsTrk::IDetectorElementBase::detectorType
virtual DetectorType detectorType() const =0
Returns the detector element type.
MuonGMR4::MuonReadoutElement::layerHash
virtual IdentifierHash layerHash(const Identifier &measId) const =0
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
SG::ReadHandleKey< ContainerType >
ActsTrk::DetectorType::sTgc
@ sTgc
Micromegas (NSW)
SpectrometerSector.h
MuonGMR4::RpcReadoutElement
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/RpcReadoutElement.h:17
xAOD::MuonSegment_v1::setT0Error
void setT0Error(float t0, float t0Error)
Sets the time error.
Definition: MuonSegment_v1.cxx:51
MuonR4::SegmentFit::ParamDefs::phi
@ phi
xAOD::MuonSegment_v1::setNHits
void setNHits(int nPrecisionHits, int nPhiLayers, int nTrigEtaLayers)
Set the number of hits/layers.
Definition: MuonSegment_v1.cxx:88
TruthSegmentMaker.h
sTgcReadoutElement.h
WriteHandle.h
Handle class for recording to StoreGate.
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ActsTrk::DetectorType::Mm
@ Mm
Maybe not needed in the migration.
MuonR4::TruthSegmentMaker::retrieveContainer
StatusCode retrieveContainer(const EventContext &ctx, const SG::ReadHandleKey< ContainerType > &key, const ContainerType *&contToPush) const
Helper method to retrieve any kind of container from a ReadHandleKey.
Definition: TruthSegmentMaker.cxx:32
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
MuonR4::SegPars
xAOD::MeasVector< toInt(ParamDefs::nPars)> SegPars
Definition: SegmentFitParDecorAlg.cxx:15
SG::WriteDecorHandle
Handle class for adding a decoration to an object.
Definition: StoreGate/StoreGate/WriteDecorHandle.h:100
MuonGMR4::SpectrometerSector::globalToLocalTrans
Amg::Transform3D globalToLocalTrans(const ActsGeometryContext &gctx) const
Returns the global -> local transformation from the ATLAS global.
Definition: SpectrometerSector.cxx:54
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
WriteDecorHandle.h
Handle class for adding a decoration to an object.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MuonR4::SegmentFit::ParamDefs::x0
@ x0
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
ActsGeometryContext
Include the GeoPrimitives which need to be put first.
Definition: ActsGeometryContext.h:27
MuonR4::SegmentFit::ParamDefs::time
@ time
xAOD::MeasVector
Eigen::Matrix< float, N, 1 > MeasVector
Abrivation of the Matrix & Covariance definitions.
Definition: MeasurementDefs.h:52
python.PyKernel.detStore
detStore
Definition: PyKernel.py:41
MuonR4::SegmentFit::ParamDefs::y0
@ y0
HepMC::ConstGenParticlePtr
const GenParticle * ConstGenParticlePtr
Definition: GenParticle.h:38
MuonHoughDefs.h
ActsTrk::DetectorType::Mdt
@ Mdt
MuonSpectrometer.
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:220
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
MuonR4::SegmentFit::toInt
constexpr int toInt(const ParamDefs p)
Definition: MuonHoughDefs.h:42
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
python.PhysicalConstants.c_light
float c_light
Definition: PhysicalConstants.py:63
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
RpcReadoutElement.h
MuonR4::TruthSegmentMaker::initialize
StatusCode initialize() override final
Definition: TruthSegmentMaker.cxx:45
MuonR4
This header ties the generic definitions in this package.
Definition: HoughEventData.h:16
SG::WriteHandle
Definition: StoreGate/StoreGate/WriteHandle.h:76
a
TList * a
Definition: liststreamerinfos.cxx:10
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
MdtReadoutElement.h
MuonR4::TruthSegmentMaker::toChamber
Amg::Transform3D toChamber(const ActsGeometryContext &gctx, const Identifier &chanId) const
Returns the transform from the local simHit frame -> chamber frame.
Definition: TruthSegmentMaker.cxx:63
xAOD::MuonSegment_v1::setIdentifier
void setIdentifier(int sector, ::Muon::MuonStationIndex::ChIndex chamberIndex, int etaIndex, ::Muon::MuonStationIndex::TechnologyIndex technology)
Set the identifier.
Definition: MuonSegment_v1.cxx:73
MuonGMR4::MuonReadoutElement::measurementHash
virtual IdentifierHash measurementHash(const Identifier &measId) const =0
Constructs the identifier hash from the full measurement Identifier.
ActsTrk::DetectorType::Rpc
@ Rpc
Monitored Drift Tubes.
xAOD::MuonSegment_v1::setDirection
void setDirection(float px, float py, float pz)
Sets the direction.
Definition: MuonSegment_v1.cxx:39
MuonGMR4::MuonReadoutElement::localToGlobalTrans
const Amg::Transform3D & localToGlobalTrans(const ActsGeometryContext &ctx) const
Returns the local to global transformation into the ATLAS coordinate system.
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/src/MuonReadoutElement.cxx:81
ReadHandle.h
Handle class for reading from StoreGate.
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
xAOD::MuonSegment_v1::setFitQuality
void setFitQuality(float chiSquared, float numberDoF)
Set the 'Fit Quality' information.
Definition: MuonSegment_v1.cxx:61
MuonR4::SegmentFit::ParamDefs::nPars
@ nPars
TgcReadoutElement.h
MuonGMR4::TgcReadoutElement
Definition: MuonPhaseII/MuonDetDescr/MuonReadoutGeometryR4/MuonReadoutGeometryR4/TgcReadoutElement.h:19
MuonR4::SegmentFit::ParamDefs::theta
@ theta
MmReadoutElement.h
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37
Identifier
Definition: IdentifierFieldParser.cxx:14