ATLAS Offline Software
Loading...
Searching...
No Matches
TruthSegmentMaker.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4#include "TruthSegmentMaker.h"
5
6
8
15
18
19#include "GaudiKernel/PhysicalConstants.h"
20
21#include <unordered_map>
22
23namespace{
24 constexpr double c_inv = 1./Gaudi::Units::c_light;
25}
26
27namespace MuonR4{
28 using namespace SegmentFit;
29
31 ATH_CHECK(m_idHelperSvc.retrieve());
32 ATH_CHECK(m_readKeys.initialize());
33 if (m_readKeys.empty()){
34 ATH_MSG_ERROR("No simulated hit containers have been parsed to build the segments from ");
35 return StatusCode::FAILURE;
36 }
37 for (const auto& truthLink : m_readKeys) {
38 m_segLinkKeys.emplace_back(truthLink, m_segLinkKey);
39 }
40 ATH_CHECK(m_segLinkKeys.initialize());
41 ATH_CHECK(m_mdtCalibKey.initialize(m_idHelperSvc->hasMDT()));
42 ATH_CHECK(m_nswUncertKey.initialize(m_idHelperSvc->hasMM() || m_idHelperSvc->hasSTGC()));
43
44 ATH_CHECK(m_segmentKey.initialize());
45 ATH_CHECK(m_eleLinkKey.initialize());
46 ATH_CHECK(m_ptKey.initialize());
47
48 ATH_CHECK(m_locParKey.initialize());
49 ATH_CHECK(m_qKey.initialize());
50
51 ATH_CHECK(m_geoCtxKey.initialize());
52 ATH_CHECK(detStore()->retrieve(m_detMgr));
53 return StatusCode::SUCCESS;
54 }
55 float TruthSegmentMaker::hitUncertainty(const EventContext& ctx, const xAOD::MuonSimHit& hit) const {
56 const Identifier hitId{hit.identify()};
57 switch (const auto techIdx = m_idHelperSvc->technologyIndex(hitId)) {
59 case MDT: {
60 const MuonCalib::MdtCalibDataContainer* calibCont{nullptr};
61 if (!SG::get(calibCont, m_mdtCalibKey, ctx).isSuccess()) {
62 THROW_EXCEPTION("Failed to retrieve Mdt calib constants");
63 }
64 const auto& rtCalib{calibCont->getCalibData(hitId, msgStream())->rtRelation};
65 const double driftTime = rtCalib->tr()->driftTime(hit.localPosition().perp()).value_or(rtCalib->tr()->maxRadius());
66 return rtCalib->rtRes()->resolution(driftTime);
67 } case RPC: {
68 const auto* re = m_detMgr->getRpcReadoutElement(hitId);
69 return re->stripEtaPitch() / std::sqrt(12.);
70 } case TGC: {
71 const auto* re = m_detMgr->getTgcReadoutElement(hitId);
72 const IdentifierHash measHash = re->measurementHash(hitId);
73 const auto& design = re->wireGangLayout(measHash);
74 return design.stripPitch() / std::sqrt(12.);
75 } case STGC:
76 case MM: {
77 const NswErrorCalibData* errorCalibDB{nullptr};
78 if (!SG::get(errorCalibDB, m_nswUncertKey, ctx).isSuccess()) {
79 THROW_EXCEPTION("Failed to retrieve the STGC calibration constants");
80 }
81 NswErrorCalibData::Input errorCalibInput{};
82 errorCalibInput.stripId= hitId;
83 errorCalibInput.locTheta = 180.*Gaudi::Units::deg - hit.localDirection().theta();
84 if (techIdx == STGC) {
85 errorCalibInput.clusterAuthor = 3; // centroid
86 } else {
87 errorCalibInput.clusterAuthor=66; // cluster time projection method
88 }
89 return errorCalibDB->clusterUncertainty(errorCalibInput);
90 }
91 default:
92 break;
93 }
94 return 0.;
95 }
96 float TruthSegmentMaker::muonPt(const xAOD::MuonSimHit& hit, const Amg::Vector3D& globDir) const{
97 const auto& link = hit.genParticleLink();
98 if (link.isValid()) {
99 return link->momentum().perp();
100 }
101 const float e{hit.kineticEnergy()},m{hit.mass()};
102 return std::sqrt(std::max(e*e - m*m, 0.f)) * std::sin(globDir.theta());
103 }
105 const Identifier& chanId) const {
106 const MuonGMR4::MuonReadoutElement* reEle = m_detMgr->getReadoutElement(chanId);
107 const IdentifierHash trfHash{reEle->detectorType() == ActsTrk::DetectorType::Mdt ?
108 reEle->measurementHash(chanId) :
109 reEle->layerHash(chanId)};
110 return reEle->msSector()->globalToLocalTransform(gctx) * reEle->localToGlobalTransform(gctx, trfHash);
111
112 }
113
114 void TruthSegmentMaker::buildSegmentsFromBkg(const EventContext& ctx,
115 const Amg::Transform3D& locToGlob,
116 const SimHitVec_t& simHits,
117 WriteDecorHolder& out)const {
118
119 ATH_MSG_DEBUG(__func__<<"() "<<__LINE__<<" - Assemble segments from "<<simHits.size()<<" background hits.");
120 std::vector<char> alreadyUsed(simHits.size(), 0);
121 for (std::size_t h = 0 ;h < simHits.size(); ++h) {
122 if (alreadyUsed[h]) {
123 continue;
124 }
125 const auto& [refHit, refPos, refDir] = simHits[h];
127 ATH_MSG_DEBUG(__func__<<"() "<<__LINE__<<" - Try to find other hits on trajectory given by "
128 <<m_idHelperSvc->toString(refHit->identify())
129 <<", "<<Amg::toString(refPos)<<", "<<Amg::toString(refDir)<<", E: "<<refHit->kineticEnergy() / Gaudi::Units::GeV<<" [GeV] "
130 <<", pt: "<<muonPt(*refHit, locToGlob.linear()* refDir)/ Gaudi::Units::GeV <<" [GeV].");
131 std::vector<std::size_t> indicesOnSeg{h};
132 for (std::size_t h1 = h +1; h1 < simHits.size(); ++h1) {
133 if (alreadyUsed[h1]) {
134 continue;
135 }
136 const auto&[testHit, testPos, testDir] = simHits[h1];
138 if (MC::charge(refHit) != MC::charge(testHit)){
139 continue;
140 }
141
142 const double angleDir = Amg::angle(testDir, refDir);
143 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Test hit "<<m_idHelperSvc->toString(testHit->identify())<<", "
144 <<Amg::toString(testPos)<<", testDir: "<<Amg::toString(testDir)
145 <<", E: "<<(testHit->kineticEnergy() / Gaudi::Units::GeV)<<", angle: "
146 <<(angleDir / Gaudi::Units::deg)<<", dE: "
147 <<std::abs(refHit->kineticEnergy() - testHit->kineticEnergy())
148 <<", "<<testHit->genParticleLink()<<".");
149
150 if (std::abs(angleDir) > m_pileUpHitAngleCone ||
151 testHit->genParticleLink().id() != refHit->genParticleLink().id() ||
152 std::abs(refHit->kineticEnergy() - testHit->kineticEnergy()) > m_pileUpHitELoss) {
153 ATH_MSG_VERBOSE(__func__<<"() "<<__LINE__<<" - Failed: "<<m_pileUpHitELoss<<", "<<m_pileUpHitAngleCone / Gaudi::Units::deg);
154 continue;
155 }
156 indicesOnSeg.push_back(h1);
157 }
159 const Amg::Vector3D globPos = locToGlob * refPos;
160 const Amg::Vector3D globDir = locToGlob.linear() * refDir;
161 const Amg::Vector3D perigee = globPos + Amg::intersect<3>(Amg::Vector3D::Zero(), Amg::Vector3D::UnitZ(),
162 globPos, globDir).value_or(0.) * globDir;
163 ATH_MSG_VERBOSE("Found "<<indicesOnSeg.size()<<" matching hits. Closest perigee "
164 <<Amg::toString(perigee)<<", "<<m_idCylinderR<<", "<<m_idCylinderHalfZ);
165 SimHitVec_t hitsOnSeg{};
166 std::ranges::transform(indicesOnSeg,
167 std::back_inserter(hitsOnSeg),
168 [&simHits](const auto idx) {
169 return simHits[idx];
170 });
174 if (perigee.perp() > m_idCylinderR || std::abs(perigee.z()) > m_idCylinderHalfZ ||
175 constructSegmentFromHits(ctx, locToGlob, hitsOnSeg, out)){
176 std::ranges::for_each(indicesOnSeg,
177 [&alreadyUsed](const auto idx) {
178 alreadyUsed[idx] = 1;
179 });
180 }
181 }
182 }
185 const Amg::Transform3D& locToGlob,
186 const SimHitVec_t& simHits,
187 WriteDecorHolder& out) const {
190 auto refHit_itr = std::ranges::min_element(simHits,
191 [](const HitPosTuple_t& a, const HitPosTuple_t& b){
192 return std::abs(std::get<1>(a).z()) <std::abs(std::get<1>(b).z());
193 });
194
195 const auto [simHit, localPos, chamberDir] = (*refHit_itr);
196 ATH_MSG_VERBOSE("Create segement from hit: "<<m_idHelperSvc->toString(simHit->identify())<<
197 " pdgId: "<<simHit->pdgId()<<", energy: "<<simHit->kineticEnergy()
198 <<", genParticle: "<<simHit->genParticleLink().cptr());
199 const Identifier segId{simHit->identify()};
200
202 const double distance = Amg::intersect<3>(localPos, chamberDir, Amg::Vector3D::UnitZ(), 0.).value_or(0.);
203 const Amg::Vector3D chamberPos = localPos + distance*chamberDir;
204
205 const Amg::Vector3D globPos = locToGlob * chamberPos;
206 const Amg::Vector3D globDir = locToGlob.linear() * chamberDir;
207 HitLinkVec_t associatedHits{};
208 unsigned nMdt{0}, nRpcEta{0}, nRpcPhi{0}, nTgcEta{0}, nTgcPhi{0};
209 unsigned nMm{0}, nStgcEta{0}, nStgcPhi{0};
211 float chi2{0.f};
212 for (const auto& [assocMe, pos, dir] : simHits) {
213 chi2 += std::pow(Amg::signedDistance(pos,dir, chamberPos, chamberDir) / hitUncertainty(ctx,*assocMe), 2);
214 const MuonGMR4::MuonReadoutElement* assocRE = m_detMgr->getReadoutElement(assocMe->identify());
215 switch (assocRE->detectorType()) {
217 ++nMdt;
218 break;
220 auto castRE{static_cast<const MuonGMR4::RpcReadoutElement*>(assocRE)};
221 if (castRE->nEtaStrips()) ++nRpcEta;
222 if (castRE->nPhiStrips()) ++nRpcPhi;
223 break;
225 auto castRE{static_cast<const MuonGMR4::TgcReadoutElement*>(assocRE)};
226 const IdentifierHash gapHash = assocRE->measurementHash(assocMe->identify());
227 if (castRE->numStrips(gapHash)){
228 ++nTgcPhi;
229 }
230 if (castRE->numWireGangs(gapHash)) {
231 ++nTgcEta;
232 }
233 break;
235 ++nStgcEta;
236 ++nStgcPhi;
237 break;
239 ++nMm;
240 break;
241 } default:
242 ATH_MSG_WARNING("Csc are not defined "<<m_idHelperSvc->toString(simHit->identify()));
243 }
244 ATH_MSG_VERBOSE("Associate hit "<<m_idHelperSvc->toString(assocMe->identify())
245 <<" pdgId: "<<assocMe->pdgId()<<", energy: "<<assocMe->kineticEnergy()
246 <<", genParticle: "<<assocMe->genParticleLink().cptr()<<", beta: "<<simHit->beta()
247 <<" global time: "<<simHit->globalTime()<<", pos: "<<Amg::toString(pos)
248 <<", dir: "<<Amg::toString(dir));
249 EleLink_t link{*static_cast<const xAOD::MuonSimHitContainer*>(assocMe->container()), assocMe->index()};
250 associatedHits.push_back(std::move(link));
251 }
252 int nPrecisionHits = nMdt + nMm + nStgcEta;
253 int nPhiLayers = nTgcPhi + nRpcPhi + nStgcPhi;
254 // if nMdt + nMm + nStgcEta < 3, do not create a segment
255 if (nPrecisionHits < 3) {
256 return nullptr;
257 }
258
259 xAOD::MuonSegment* truthSegment = out.segments.push_back(std::make_unique<xAOD::MuonSegment>());
260 out.ptDecor(*truthSegment) = muonPt(*simHit, globDir);
261 out.chargeDecor(*truthSegment) = MC::charge(simHit);
262 SegPars_t& locPars{out.paramDecor(*truthSegment)};
263 locPars[Acts::toUnderlying(ParamDefs::x0)] = chamberPos.x();
264 locPars[Acts::toUnderlying(ParamDefs::y0)] = chamberPos.y();
265 constexpr float betaLowLimit = 1.e-6;
266 locPars[Acts::toUnderlying(ParamDefs::t0)] = simHit->globalTime() + distance *c_inv / std::max(simHit->beta(), betaLowLimit);
267 locPars[Acts::toUnderlying(ParamDefs::theta)] = chamberDir.theta();
268 locPars[Acts::toUnderlying(ParamDefs::phi)] = chamberDir.phi();
269
270 truthSegment->setPosition(globPos.x(), globPos.y(), globPos.z());
271 truthSegment->setDirection(globDir.x(), globDir.y(), globDir.z());
272 truthSegment->setT0Error(locPars[Acts::toUnderlying(ParamDefs::t0)], 0.);
273
274 truthSegment->setNHits(nPrecisionHits, nPhiLayers, nTgcEta + nRpcEta);
275 truthSegment->setNOutliers(0, 0, 0);
276 truthSegment->setNHoles(0, 0, 0);
277
278
279 truthSegment->setIdentifier(m_idHelperSvc->sector(segId),
280 m_idHelperSvc->chamberIndex(segId),
281 m_idHelperSvc->stationEta(segId),
282 m_idHelperSvc->technologyIndex(segId));
283 // adding chi2 and ndof (nHits - 5 for 2 position, 2 direction and 1 time)
284 if (nPhiLayers == 0){
285 truthSegment->setFitQuality(chi2, (nPrecisionHits + nTgcEta + nRpcEta - 3));
286 } else {
287 truthSegment->setFitQuality(chi2, (nPrecisionHits + nPhiLayers + nTgcEta + nRpcEta - 5));
288 }
289 out.hitLinkDecor(*truthSegment) = std::move(associatedHits);
290 return truthSegment;
291 }
292
293 StatusCode TruthSegmentMaker::execute(const EventContext& ctx) const {
294 const ActsTrk::GeometryContext* gctx{nullptr};
295 ATH_CHECK(SG::get(gctx, m_geoCtxKey, ctx));
296
297 using HitsPerParticle = std::unordered_map<HepMC::ConstGenParticlePtr, SimHitVec_t>;
298 using HitCollector = std::unordered_map<const MuonGMR4::SpectrometerSector*, HitsPerParticle>;
299 HitCollector hitCollector{};
300
302 const xAOD::MuonSimHitContainer* simHits{nullptr};
303 ATH_CHECK(SG::get(simHits, key, ctx));
304 for (const xAOD::MuonSimHit* simHit : *simHits) {
305 const MuonGMR4::MuonReadoutElement* reElement = m_detMgr->getReadoutElement(simHit->identify());
306 const MuonGMR4::SpectrometerSector* id{reElement->msSector()};
307 auto genLink = simHit->genParticleLink();
308 HepMC::ConstGenParticlePtr genParticle = nullptr;
309 if (genLink.isValid()){
310 genParticle = genLink.cptr();
311 }
312 if ( (!genParticle && (!m_includePileUpHits || simHit->kineticEnergy() < m_pileUpHitMinE
313 || !MC::isMuon(simHit))) || (m_useOnlyMuonHits && !MC::isMuon(simHit))) {
314 ATH_MSG_VERBOSE("Skip hit "<<m_idHelperSvc->toString(simHit->identify())<<
315 " pdgId: "<<simHit->pdgId()<<", energy: "<<simHit->kineticEnergy()
316 <<", genParticle: "<<genParticle);
317 continue;
318 }
319 const Amg::Transform3D toChTrf{toChamber(*gctx, simHit->identify())};
320 hitCollector[id][genParticle].emplace_back(simHit,
321 toChTrf *xAOD::toEigen(simHit->localPosition()),
322 toChTrf.linear()* xAOD::toEigen(simHit->localDirection()));
323 }
324 }
325
326 SG::WriteHandle writeHandle{m_segmentKey, ctx};
327 ATH_CHECK(writeHandle.record(std::make_unique<xAOD::MuonSegmentContainer>(),
328 std::make_unique<xAOD::MuonSegmentAuxContainer>()));
329
330 WriteDecorHolder writerHolder{*writeHandle,*this, ctx};
331
332 for (auto& [chamber, collectedParts] : hitCollector) {
333 const Amg::Transform3D& locToGlob{chamber->localToGlobalTransform(*gctx)};
334 for (auto& [particle, simHits]: collectedParts) {
335 /* Sort hits by local z */
336 std::ranges::stable_sort(simHits,[](const HitPosTuple_t& a, const HitPosTuple_t& b){
337 return std::get<1>(a).z() < std::get<1>(b).z();
338 });
339 if (!particle) {
340 buildSegmentsFromBkg(ctx, locToGlob, simHits, writerHolder);
341 continue;
342 }
343 constructSegmentFromHits(ctx, locToGlob, simHits, writerHolder);
344 }
345 }
346 ATH_CHECK(linkSegmentsToHits(ctx, *writeHandle));
347 ATH_MSG_DEBUG("Constructed "<<writeHandle->size()<<" truth segments in total ");
348 return StatusCode::SUCCESS;
349 }
350 StatusCode TruthSegmentMaker::linkSegmentsToHits(const EventContext& ctx,
351 const xAOD::MuonSegmentContainer& segments) const {
354 std::unordered_map<const SG::AuxVectorData*, DecorHandle_t> handleMap{};
355 for (const auto& decorKey : m_segLinkKeys) {
356 DecorHandle_t decorHandle{decorKey, ctx};
357 if (decorHandle->empty()) {
358 ATH_MSG_DEBUG("Don't setup a decoration handle for "<<decorKey.fullKey());
359 continue;
360 }
361 decorHandle(*decorHandle->front()) = SegLink_t{};
362 handleMap.insert(std::make_pair(decorHandle.cptr(), std::move(decorHandle)));
363 }
364 for (const xAOD::MuonSegment* segment: segments) {
365 SegLink_t segLink{&segments, segment->index()};
366 for (const xAOD::MuonSimHit* simHit : getMatchingSimHits(*segment)) {
367 handleMap.at(simHit->container())(*simHit) = segLink;
368 }
369 }
370 return StatusCode::SUCCESS;
371 }
372}
const std::regex re(r_e)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
ATLAS-specific HepMC functions.
static Double_t a
@ STGC
Definition RegSelEnums.h:39
@ MM
Definition RegSelEnums.h:38
@ RPC
Definition RegSelEnums.h:32
@ MDT
Definition RegSelEnums.h:31
#define z
virtual DetectorType detectorType() const =0
Returns the detector element type.
const ServiceHandle< StoreGateSvc > & detStore() const
Header file for AthHistogramAlgorithm.
This is a "hash" representation of an Identifier.
const MdtFullCalibData * getCalibData(const Identifier &measId, MsgStream &msg) const
Returns the calibration data associated with this station.
MuonReadoutElement is an abstract class representing the geometry of a muon detector.
const SpectrometerSector * msSector() const
Returns the pointer to the envelope volume enclosing all chambers in the sector.
virtual IdentifierHash measurementHash(const Identifier &measId) const =0
The measurement hash is a continous numbering schema of all readout channels described by the specifi...
const Amg::Transform3D & localToGlobalTransform(const ActsTrk::GeometryContext &ctx) const override final
Returns the transformation from the local coordinate system of the readout element into the global AT...
virtual IdentifierHash layerHash(const Identifier &measId) const =0
The layer hash removes the bits from the IdentifierHash corresponding to the measurement's channel nu...
A spectrometer sector forms the envelope of all chambers that are placed in the same MS sector & laye...
Amg::Transform3D globalToLocalTransform(const ActsTrk::GeometryContext &gctx) const
Returns the global -> local transformation from the ATLAS global.
SG::WriteDecorHandleKey< xAOD::MuonSegmentContainer > m_locParKey
Decoration key of the local parameters.
std::vector< HitPosTuple_t > SimHitVec_t
ActsTrk::GeoContextReadKey_t m_geoCtxKey
Key to the geometry context.
Gaudi::Property< float > m_pileUpHitMinE
Minimum energy threshold for pile up hits to be converted.
StatusCode execute(const EventContext &ctx) const override
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
IdHelperSvc to decode the Identifiers.
Gaudi::Property< float > m_pileUpHitAngleCone
Maximum scattering angle between two pile-up hits.
Gaudi::Property< float > m_idCylinderR
ID / ITk cylinder radius.
Amg::Transform3D toChamber(const ActsTrk::GeometryContext &gctx, const Identifier &chanId) const
Returns the transform from the local simHit frame -> chamber frame.
const MuonGMR4::MuonDetectorManager * m_detMgr
Pointer to the muon readout geometry.
StatusCode initialize() override final
SG::WriteDecorHandleKey< xAOD::MuonSegmentContainer > m_eleLinkKey
Decoration key of the associated sim hit links.
SG::ReadCondHandleKey< MuonCalib::MdtCalibDataContainer > m_mdtCalibKey
Data dependency on the Mdt calibration container to calculate the uncertainty.
ElementLink< xAOD::MuonSimHitContainer > EleLink_t
Gaudi::Property< float > m_pileUpHitELoss
Maximum energy loss between two pile-up hits.
std::vector< EleLink_t > HitLinkVec_t
Gaudi::Property< float > m_idCylinderHalfZ
ID / Itk cylinder half length.
SG::WriteDecorHandleKey< xAOD::MuonSegmentContainer > m_qKey
Decoration key of the muon charge.
xAOD::MuonSegment * constructSegmentFromHits(const EventContext &ctx, const Amg::Transform3D &locToGlob, const SimHitVec_t &hits, WriteDecorHolder &writeShip) const
Takes a list of related sim hits and transforms them into a truth segment.
SG::WriteDecorHandleKey< xAOD::MuonSegmentContainer > m_ptKey
Decoration key of the associated particle pt.
Gaudi::Property< bool > m_useOnlyMuonHits
Build segments from muon hits only.
SG::WriteDecorHandleKeyArray< xAOD::MuonSimHitContainer > m_segLinkKeys
Decorate the truth segment link to the simHit.
xAOD::PosAccessor< Acts::toUnderlying(SegmentFit::ParamDefs::nPars)>::element_type SegPars_t
Gaudi::Property< std::string > m_segLinkKey
Name of the link to the truth segment.
void buildSegmentsFromBkg(const EventContext &ctx, const Amg::Transform3D &locToGlob, const SimHitVec_t &simHits, WriteDecorHolder &writeShip) const
Attempts to assemble truth segments from a list of loose sim hits, i.e., the hits are stemming from a...
std::tuple< const xAOD::MuonSimHit *, Amg::Vector3D, Amg::Vector3D > HitPosTuple_t
Tuple consisting out of pointer to the sim hit and the position & direction expressed in the chamber'...
SG::WriteHandleKey< xAOD::MuonSegmentContainer > m_segmentKey
Key under which the segment Container will be recorded in StoreGate.
SG::ReadCondHandleKey< NswErrorCalibData > m_nswUncertKey
Data dependency on the Nsw calibration container to estimate the uncertaintys.
Gaudi::Property< bool > m_includePileUpHits
Construct segments from pile-up hits without GenParticleLink.
float hitUncertainty(const EventContext &ctx, const xAOD::MuonSimHit &hit) const
Evaluates the hit uncertainty.
float muonPt(const xAOD::MuonSimHit &hit, const Amg::Vector3D &globDir) const
Returns the muon pt from the sim hit.
StatusCode linkSegmentsToHits(const EventContext &ctx, const xAOD::MuonSegmentContainer &segments) const
Establish the link from the simulated hit -> truth segment.
SG::ReadHandleKeyArray< xAOD::MuonSimHitContainer > m_readKeys
List of sim hit containers from which the truth segments shall be retrieved.
double clusterUncertainty(const Input &clustInfo) const
Property holding a SG store/key/clid from which a ReadHandle is made.
Handle class for adding a decoration to an object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
void setDirection(float px, float py, float pz)
Sets the direction.
void setFitQuality(float chiSquared, float numberDoF)
Set the 'Fit Quality' information.
void setT0Error(float t0, float t0Error)
Sets the time error.
void setNHits(const std::uint8_t nPrecisionHits, const std::uint8_t nPhiLayers, const std::uint8_t nTrigEtaLayers)
Assign the segment hit summary.
void setNOutliers(const std::uint8_t nPrecOutliers, const std::uint8_t nTrigPhiOutliers, const std::uint8_t nTrigEtaOutliers)
Assign the number of hits with a large pull per hit category.
void setNHoles(const std::uint8_t nPrecHoles, const std::uint8_t nTrigPhiHoles, const std::uint8_t nTrigEtaHoles)
Assign the number of expected but missing hits.
void setPosition(float x, float y, float z)
Sets the global position.
void setIdentifier(const std::uint8_t sector, const ::Muon::MuonStationIndex::ChIndex chamberIndex, const std::int8_t etaIndex, const ::Muon::MuonStationIndex::TechnologyIndex technology)
Set the Identifier fields of the Segment.
ConstVectorMap< 3 > localDirection() const
Returns the local direction of the traversing particle.
float mass() const
Returns the rest-mass of the traversing particle.
Identifier identify() const
Returns the global ATLAS identifier of the SimHit.
ConstVectorMap< 3 > localPosition() const
Returns the local postion of the traversing particle.
const HepMcParticleLink & genParticleLink() const
Returns the link to the HepMC particle producing this hit.
float kineticEnergy() const
Returns the kinetic energy of the traversing particle.
double chi2(TH1 *h0, TH1 *h1)
@ Mm
Maybe not needed in the migration.
@ Tgc
Resitive Plate Chambers.
@ sTgc
Micromegas (NSW).
@ Rpc
Monitored Drift Tubes.
@ Mdt
MuonSpectrometer.
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the point B' along the line B that's closest to a second line A.
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
double signedDistance(const Amg::Vector3D &posA, const Amg::Vector3D &dirA, const Amg::Vector3D &posB, const Amg::Vector3D &dirB)
Calculates the signed distance between two lines in 3D space.
double angle(const Amg::Vector3D &v1, const Amg::Vector3D &v2)
calculates the opening angle between two vectors
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
HepMC3::ConstGenParticlePtr ConstGenParticlePtr
Definition GenParticle.h:20
bool isMuon(const T &p)
double charge(const T &p)
This header ties the generic definitions in this package.
std::unordered_set< const xAOD::MuonSimHit * > getMatchingSimHits(const xAOD::MuonSegment &segment)
: Returns all sim hits matched to a xAOD::MuonSegment
ElementLink< MuonR4::SegmentContainer > SegLink_t
Abrivation of the link to the reco segment container.
TechnologyIndex
enum to classify the different layers in the muon spectrometer
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
Definition TgcBase.h:6
MuonSimHitContainer_v1 MuonSimHitContainer
Define the version of the pixel cluster container.
MuonSegmentContainer_v1 MuonSegmentContainer
Definition of the current "MuonSegment container version".
MuonSimHit_v1 MuonSimHit
Defined the version of the MuonSimHit.
Definition MuonSimHit.h:12
MuonSegment_v1 MuonSegment
Reference the current persistent version:
Helper struct to ship the write DecorHandles and the reference to the output segment container throug...
Helper struct to be parsed to the object to derive the specific error of the cluster.
double locTheta
Direction of the muon in the local coordinate frame.
Identifier stripId
Identifier of the strip.
uint8_t clusterAuthor
Author of the cluster.
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10