ATLAS Offline Software
Loading...
Searching...
No Matches
MmSensitiveDetector.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
7#include "G4ThreeVector.hh"
8
9#include <sstream>
10
12#include "GeoModelKernel/throwExcept.h"
13#include "GaudiKernel/SystemOfUnits.h"
14
15
16using namespace MuonGMR4;
17using namespace CxxUtils;
18using namespace ActsTrk;
19
20namespace {
21 constexpr double tolerance = 10. * Gaudi::Units::micrometer;
22}
23
24// construction/destruction
25namespace MuonG4R4 {
26
27G4bool MmSensitiveDetector::ProcessHits(G4Step* aStep,G4TouchableHistory*) {
28
29 if (!processStep(aStep)) {
30 return true;
31 }
32
34
35 const G4TouchableHistory* touchHist = static_cast<const G4TouchableHistory*>(aStep->GetPreStepPoint()->GetTouchable());
36 const MuonGMR4::MmReadoutElement* readOutEle = getReadoutElement(gctx, touchHist);
37
38 const Amg::Transform3D localToGlobal = getTransform(touchHist, 0);
39 ATH_MSG_VERBOSE(" Track is inside volume "<< touchHist->GetHistory()->GetTopVolume()->GetName()
40 <<" transformation: "<<Amg::toString(localToGlobal));
41
42 const Identifier hitID = getIdentifier(gctx, readOutEle, localToGlobal.translation());
43 if (!hitID.is_valid()) {
44 ATH_MSG_VERBOSE("No valid hit found");
45 return true;
46 }
48 const Amg::Transform3D toGasGap{readOutEle->globalToLocalTransform(gctx, hitID)};
49 propagateAndSaveStrip(hitID, toGasGap, aStep);
50 return true;
51}
52
54 const MuonGMR4::MmReadoutElement* readOutEle,
55 const Amg::Vector3D& hitAtGapPlane) const {
57 for (unsigned int gap = 1; gap <= readOutEle->nGasGaps(); ++gap){
58 const Amg::Vector3D gapCentre = readOutEle->center(gctx, MmReadoutElement::createHash(gap, 0));
59 ATH_MSG_VERBOSE("Try to match "<<Amg::toString(hitAtGapPlane)<<" to "<<Amg::toString(gapCentre)
60 <<" in "<<m_detMgr->idHelperSvc()->toStringDetEl(readOutEle->identify())<<" dZ: "
61 <<std::abs(gapCentre.z() - hitAtGapPlane.z()));
62 if (std::abs(gapCentre.z() - hitAtGapPlane.z()) < tolerance) {
63 ATH_MSG_VERBOSE("Assign hit "<<Amg::toString(hitAtGapPlane)<<" to "
64 <<m_detMgr->idHelperSvc()->toStringDetEl(readOutEle->identify())<<" gasGap: "<<gap);
65 return readOutEle->measurementId(MmReadoutElement::createHash(gap, 1));
66 }
67 }
68 THROW_EXCEPTION("Invalid gasgap matching for hit "<<Amg::toString(hitAtGapPlane)<<" and detector element "
69 <<m_detMgr->idHelperSvc()->toStringDetEl(readOutEle->identify()));
70 return Identifier{};
71}
73 const G4TouchableHistory* touchHist) const {
75 const std::string& stationVolume = touchHist->GetVolume(4)->GetName();
77 const std::vector<std::string> volumeTokens = tokenize(stationVolume.substr(stationVolume.rfind("NSW") + 4), "_");
78 ATH_MSG_VERBOSE("Name of the station volume is "<<volumeTokens);
79 if (volumeTokens.size() != 4) {
80 THROW_EXCEPTION(" Cannot deduce the station name from "<<stationVolume);
81 }
83 const std::string stName = volumeTokens[0][0] == 'S' ? "MMS" : "MML";
84 const int stationEta = atoi(volumeTokens[2]);
85 const int stationPhi = atoi(volumeTokens[3]);
86
87 const MmIdHelper& idHelper{m_detMgr->idHelperSvc()->mmIdHelper()};
88 const Identifier detElIdMl1 = idHelper.channelID(idHelper.stationNameIndex(stName), stationEta, stationPhi, 1, 1, 1);
89 const Identifier detElIdMl2 = idHelper.multilayerID(detElIdMl1, 2);
90 const MmReadoutElement* readOutElemMl1 = m_detMgr->getMmReadoutElement(detElIdMl1);
91 const MmReadoutElement* readOutElemMl2 = m_detMgr->getMmReadoutElement(detElIdMl2);
92 if (!readOutElemMl1 || !readOutElemMl2) {
93 THROW_EXCEPTION(" Failed to retrieve a valid detector element from "
94 <<m_detMgr->idHelperSvc()->toStringDetEl(detElIdMl1)<<" "<<stationVolume);
95 }
97 const Amg::Vector3D transformCenter = getTransform(touchHist, 0).translation();
100 const Amg::Vector3D centerMl2 = readOutElemMl2->center(gctx, detElIdMl2);
101 ATH_MSG_VERBOSE("Local gap position "<<Amg::toString(centerMl2)<<" transform center "<<Amg::toString(transformCenter));
102 return std::abs(centerMl2.z()) - tolerance <= std::abs(transformCenter.z()) ? readOutElemMl2 : readOutElemMl1;
103}
104}
#define ATH_MSG_VERBOSE(x)
Utility helpers used by Run-4 muon sensitive detector implementations.
bool is_valid() const
Check if id is in a valid state.
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channel) const
Identifier multilayerID(const Identifier &channeldID) const
Identifier getIdentifier(const ActsTrk::GeometryContext &gctx, const MuonGMR4::MmReadoutElement *readOutEle, const Amg::Vector3D &hitAtGapPlane) const
Identify the gas gap in which the G4 hit produced.
virtual G4bool ProcessHits(G4Step *aStep, G4TouchableHistory *ROhist) override final
const MuonGMR4::MmReadoutElement * getReadoutElement(const ActsTrk::GeometryContext &gctx, const G4TouchableHistory *touchHist) const
Retrieves the readout element matching the Micromega multiplet in which the G4 energy depsoit is taki...
const MuonGMR4::MuonDetectorManager * m_detMgr
Pointer to the underlying detector manager.
xAOD::MuonSimHit * propagateAndSaveStrip(const Identifier &hitId, const Amg::Transform3D &toGasGap, const G4Step *hitStep)
Records the G4Step in the sim hit.
bool processStep(const G4Step *step) const
Checks whether the current step shall be processed at all.
ActsTrk::GeometryContext getGeoContext() const
Returns the current geometry context in the event.
unsigned int nGasGaps() const
Returns the number of gas gaps.
Identifier measurementId(const IdentifierHash &measHash) const override final
Back conversion of the measurement hash to a full Athena Identifier The behaviour is undefined if a l...
static IdentifierHash createHash(const int gasGap, const int strip)
Amg::Transform3D globalToLocalTransform(const ActsTrk::GeometryContext &ctx) const
Returns the transformation from the global ATLAS coordinate system into the local coordinate system o...
Amg::Vector3D center(const ActsTrk::GeometryContext &ctx) const
Returns the geometrical center point of the readout element.
Identifier identify() const override final
Return the ATLAS identifier.
int stationNameIndex(const std::string &name) const
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
std::vector< std::string > tokenize(std::string_view the_str, std::string_view delimiters)
Splits the string into smaller substrings.
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
Include the common definitions from the MuonReadoutGeometry.
Amg::Transform3D getTransform(const G4VTouchable *history, unsigned int level)
Extracts the local -> global transformation from a TouchableHistory at a given level.
The ReadoutGeomCnvAlg converts the Run4 Readout geometry build from the GeoModelXML into the legacy M...
#define THROW_EXCEPTION(MESSAGE)
Definition throwExcept.h:10