ATLAS Offline Software
Loading...
Searching...
No Matches
RpcSensitiveDetector.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#include "G4Trd.hh"
9
11#include "GaudiKernel/SystemOfUnits.h"
12#include "GeoModelKernel/throwExcept.h"
13
14using namespace MuonGMR4;
15using namespace CxxUtils;
16using namespace ActsTrk;
17
18// construction/destruction
19namespace MuonG4R4 {
20
21
22G4bool RpcSensitiveDetector::ProcessHits(G4Step* aStep,G4TouchableHistory*) {
23
24 if (!processStep(aStep)) {
25 return true;
26 }
27 const G4TouchableHistory* touchHist = static_cast<const G4TouchableHistory*>(aStep->GetPreStepPoint()->GetTouchable());
28 const MuonGMR4::RpcReadoutElement* readOutEle = getReadoutElement(touchHist);
29 if (!readOutEle) {
30 return false;
31 }
32
34
35
36 const Amg::Transform3D localToGlobal = getTransform(touchHist, 0);
37 ATH_MSG_VERBOSE(" Track is inside volume "
38 <<touchHist->GetHistory()->GetTopVolume()->GetName()
39 <<" transformation: "<<Amg::toString(localToGlobal));
42 const Amg::Vector3D locPreStep{localToGlobal.inverse()*Amg::Hep3VectorToEigen(aStep->GetPreStepPoint()->GetPosition())};
43 const Amg::Vector3D locPostStep{localToGlobal.inverse()*Amg::Hep3VectorToEigen(aStep->GetPostStepPoint()->GetPosition())};
44
45 const Amg::Vector3D locStepDir = (locPostStep - locPreStep).unit();
46 const std::optional<double> lambda = Amg::intersect<3>(locPreStep, locStepDir, Amg::Vector3D::UnitX(), 0.);
47 Amg::Vector3D gapCentreCross = localToGlobal * ( (lambda ? 1. : 0.) *locPreStep + lambda.value_or(0.) * locStepDir);
48 const Identifier etaHitID = getIdentifier(gctx, readOutEle, gapCentreCross);
49 if (!etaHitID.is_valid()) {
50 ATH_MSG_VERBOSE("No valid hit found");
51 return true;
52 }
54 const Amg::Transform3D toGasGap{readOutEle->globalToLocalTransform(gctx, etaHitID)};
55 propagateAndSaveStrip(etaHitID, toGasGap, aStep);
56 return true;
57}
58
60 const MuonGMR4::RpcReadoutElement* readOutEle,
61 const Amg::Vector3D& hitAtGapPlane) const {
62 const RpcIdHelper& idHelper{m_detMgr->idHelperSvc()->rpcIdHelper()};
63 constexpr bool phiGap = false;
64 const Identifier firstChan = idHelper.channelID(readOutEle->identify(),
65 readOutEle->doubletZ(),
66 readOutEle->doubletPhi(), 1, phiGap, 1);
67
68 const Amg::Vector3D locHitPos{readOutEle->globalToLocalTransform(gctx, firstChan) *
69 hitAtGapPlane};
70 const double gapHalfWidth = readOutEle->stripEtaLength() / 2;
71 const double gapHalfLength = readOutEle->stripPhiLength()/ 2;
72 ATH_MSG_VERBOSE("Detector element: "<<m_detMgr->idHelperSvc()->toStringDetEl(firstChan)
73 <<" locPos: "<<Amg::toString(locHitPos, 2)
74 <<" gap thickness "<<readOutEle->gasGapPitch()
75 <<" gap width: "<<gapHalfWidth
76 <<" gap length: "<<gapHalfLength);
77 const int doubletPhi = std::abs(locHitPos.y()) > gapHalfWidth ? readOutEle->doubletPhiMax() :
78 readOutEle->doubletPhi();
79 const int gasGap = std::round(std::abs(locHitPos.z()) / readOutEle->gasGapPitch()) + 1;
80
81 return idHelper.channelID(readOutEle->identify(),
82 readOutEle->doubletZ(),
83 doubletPhi, gasGap, phiGap, 1);
84}
85const MuonGMR4::RpcReadoutElement* RpcSensitiveDetector::getReadoutElement(const G4TouchableHistory* touchHist) const {
87 const std::string stationVolume = touchHist->GetVolume(3)->GetName();
88
89 const std::vector<std::string> volumeTokens = tokenize(stationVolume, "_");
90 ATH_MSG_VERBOSE("Name of the station volume is "<<stationVolume);
91 if (volumeTokens.size() != 7) {
92 THROW_EXCEPTION(" Cannot deduce the station name from "<<stationVolume);
93 }
96 const std::string stName = volumeTokens[0].substr(0,3);
97 const int stationEta = atoi(volumeTokens[2]);
98 const int stationPhi = atoi(volumeTokens[3]);
99 const int doubletR = atoi(volumeTokens[4]);
100 const int doubletPhi = atoi(volumeTokens[5]);
101 const int doubletZ = atoi(volumeTokens[6]);
102 const RpcIdHelper& idHelper{m_detMgr->idHelperSvc()->rpcIdHelper()};
103
104 const Identifier detElId = idHelper.padID(idHelper.stationNameIndex(stName),
105 stationEta, stationPhi, doubletR, doubletZ, doubletPhi);
106 const RpcReadoutElement* readOutElem = m_detMgr->getRpcReadoutElement(detElId);
107 if (!readOutElem) {
108 THROW_EXCEPTION(" Failed to retrieve a valid detector element from "
109 <<m_detMgr->idHelperSvc()->toStringDetEl(detElId)<<" "<<stationVolume);
110 }
111 return readOutElem;
112}
113}
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
#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.
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.
const MuonGMR4::RpcReadoutElement * getReadoutElement(const G4TouchableHistory *touchHist) const
Retrieves the MuonReadoutElement associated to the rpc chamber in which the energy deposit is taking ...
virtual G4bool ProcessHits(G4Step *aStep, G4TouchableHistory *ROhist) override final
Identifier getIdentifier(const ActsTrk::GeometryContext &gctx, const MuonGMR4::RpcReadoutElement *readOutEle, const Amg::Vector3D &hitAtGapPlane) const
Identify the gas gap in which the G4 hit produced.
Amg::Transform3D globalToLocalTransform(const ActsTrk::GeometryContext &ctx) const
Returns the transformation from the global ATLAS coordinate system into the local coordinate system o...
Identifier identify() const override final
Return the ATLAS identifier.
int doubletZ() const
Returns the doublet Z field of the MuonReadoutElement identifier.
int doubletPhi() const
Returns the doublet Phi field of the MuonReadoutElement identifier.
double stripPhiLength() const
Returns the length of a phi strip.
int doubletPhiMax() const
Returns the maximum phi panel.
double stripEtaLength() const
Returns the length of an eta strip.
double gasGapPitch() const
Returns the thickness of a RPC gasgap.
int stationNameIndex(const std::string &name) const
Identifier padID(const Identifier &elementID, int doubletZ, int doubletPhi) const
Identifier channelID(int stationName, int stationEta, int stationPhi, int doubletR, int doubletZ, int doubletPhi, int gasGap, int measuresPhi, int strip) const
The AlignStoreProviderAlg loads the rigid alignment corrections and pipes them through the readout ge...
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.
Amg::Vector3D Hep3VectorToEigen(const CLHEP::Hep3Vector &CLHEPvector)
Converts a CLHEP-based CLHEP::Hep3Vector into an Eigen-based Amg::Vector3D.
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