ATLAS Offline Software
Loading...
Searching...
No Matches
MMSimHitVariables.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
5
8
9namespace MuonPRDTest {
10 MMSimHitVariables::MMSimHitVariables(MuonTesterTree& tree, const std::string& container_name, MSG::Level msglvl) :
11 PrdTesterModule(tree, "MM_Sim", msglvl), m_key{container_name} {}
12
14
15 bool MMSimHitVariables::fill(const EventContext& ctx) {
16 ATH_MSG_DEBUG("do fill MmSimHitVariables()");
18 if (!mmContainer.isValid()) {
19 ATH_MSG_FATAL("Failed to retrieve digit container " << m_key.fullKey());
20 return false;
21 }
22 const MuonGM::MuonDetectorManager* MuonDetMgr = getDetMgr(ctx);
23 if (!MuonDetMgr) { return false; }
24 unsigned int n_hits{0};
25 // Get the MM Id hit helper
27 if (!mmContainer->size()) ATH_MSG_DEBUG("MM Sim container is empty");
28 for (const MMSimHit& hit : *mmContainer) {
29 int simId = hit.MMId();
30
31 if(hit.depositEnergy()==0.) continue; // SimHits without energy loss are not recorded.
32
33 // connect the hit with the MC truth
34 int barcode = hit.particleLink().barcode();
35 m_NSWMM_trackId.push_back(barcode);
36 m_NSWMM_globalTime.push_back(hit.globalTime());
37
38 const Amg::Vector3D& globalPosition = hit.globalPosition();
39 m_NSWMM_hitGlobalPosition.push_back(globalPosition);
40
41 const Amg::Vector3D& globalDirection = hit.globalDirection();
42 m_NSWMM_hitGlobalDirection.push_back(globalDirection);
43
44 m_NSWMM_particleEncoding.push_back(hit.particleEncoding());
45 m_NSWMM_kineticEnergy.push_back(hit.kineticEnergy());
46 m_NSWMM_depositEnergy.push_back(hit.depositEnergy());
47
48 std::string stname = mmhhelper->GetStationName(simId);
49 int steta = mmhhelper->GetZSector(simId);
50 int stphi = mmhhelper->GetPhiSector(simId);
51 int multilayer = mmhhelper->GetMultiLayer(simId);
52 int layer = mmhhelper->GetLayer(simId);
53 int side = mmhhelper->GetSide(simId);
54
55 if( stphi == 0 ){
56 ATH_MSG_ERROR("MicroMegas validation: unexpected phi range " << stphi);
57 return false;
58 }
59
60 Identifier offId = idHelperSvc()->mmIdHelper().channelID( stname[2] == 'L' ? "MML" : "MMS",
61 side == 1 ? steta+1 : -steta-1,
62 (stphi-1)/2+1,multilayer,layer,1 );
63 m_NSWMM_Id.push_back(offId);
64
65 // sanity checks
66 if( !idHelperSvc()->mmIdHelper().is_mm(offId) ){
67 ATH_MSG_WARNING("MM id is not a mm id! " << idHelperSvc()->mmIdHelper().print_to_string(offId));
68 }
69 if( !idHelperSvc()->mmIdHelper().is_muon(offId) ){
70 ATH_MSG_WARNING("MM id is not a muon id! " << idHelperSvc()->mmIdHelper().print_to_string(offId));
71 }
72 if( idHelperSvc()->mmIdHelper().is_mdt(offId)||idHelperSvc()->mmIdHelper().is_rpc(offId)||idHelperSvc()->mmIdHelper().is_tgc(offId)||idHelperSvc()->mmIdHelper().is_csc(offId)||idHelperSvc()->mmIdHelper().is_stgc(offId) ){
73 ATH_MSG_WARNING("MM id has wrong technology type! " << idHelperSvc()->mmIdHelper().is_mdt(offId) << " " << idHelperSvc()->mmIdHelper().is_rpc(offId)
74 << " " << idHelperSvc()->mmIdHelper().is_tgc(offId) << " " << idHelperSvc()->mmIdHelper().is_csc(offId) << " " << idHelperSvc()->mmIdHelper().is_stgc(offId) );
75 }
76 if( idHelperSvc()->mmIdHelper().gasGap(offId) != layer ) {
77 ATH_MSG_WARNING("MM id has bad layer field! " << idHelperSvc()->mmIdHelper().print_to_string(offId) );
78 }
79
80 int isSmall = stname[2] == 'S';
81 ATH_MSG_DEBUG("MicroMegas geometry, retrieving detector element for: isSmall " << isSmall << " eta " << idHelperSvc()->mmIdHelper().stationEta(offId)
82 << " phi " << idHelperSvc()->mmIdHelper().stationPhi(offId) << " ml " << idHelperSvc()->mmIdHelper().multilayer(offId) );
83
84 const MuonGM::MMReadoutElement* detEl = MuonDetMgr->getMMReadoutElement(offId);
85 if (!detEl) {
86 ATH_MSG_ERROR("MMSimHitVariables::fillVariables() - Failed to retrieve MMReadoutElement for "<<idHelperSvc()->mmIdHelper().print_to_string(offId).c_str());
87 return false;
88 }
89
90 // surface
91 const Trk::PlaneSurface& surf = detEl->surface(offId);
92 // compute hit position within the detector element/surfaces
93 Amg::Transform3D gToL = detEl->absTransform().inverse();
94 Amg::Vector3D hpos(hit.globalPosition().x(),hit.globalPosition().y(),hit.globalPosition().z());
95 Amg::Vector3D dSurface_pos = gToL*hpos;
96
97 // compute the hit position on the readout plane (same as in MuonFastDigitization)
98 Amg::Vector3D rSurface_pos = surf.transform().inverse()*hpos;
99
100 Amg::Vector2D posOnSurfUnProjected(rSurface_pos.x(),rSurface_pos.y());
101
102 // check where the readout plane is located and compute the local direction accordingly
103 Amg::Vector3D ldir(0., 0., 0.);
104 ldir = surf.transform().inverse().linear()*Amg::Vector3D(hit.globalDirection().x(), hit.globalDirection().y(), hit.globalDirection().z());
105
106 double scale, scaletop;
107 double gasgap = 5.;
108
109 scale = -rSurface_pos.z()/ldir.z();
110 scaletop = (gasgap+rSurface_pos.z())/ldir.z();
111
112 Amg::Vector3D hitOnSurface = rSurface_pos + scale*ldir;
113 Amg::Vector3D hitOnTopSurface = rSurface_pos + scaletop*ldir;
114 Amg::Vector2D posOnSurf (hitOnSurface.x(), hitOnSurface.y());
115 Amg::Vector2D posOnTopSurf (hitOnTopSurface.x(),hitOnTopSurface.y());
116
117
118 int stripNumber = detEl->stripNumber(posOnSurf,offId);
119
120 // perform bound check (making the call from the detector element to consider edge passivation)
121 m_NSWMM_isInsideBounds.push_back( detEl->insideActiveBounds(offId, posOnSurf) );
122
123 if( stripNumber == -1 ){
124 ATH_MSG_WARNING("MicroMegas validation: failed to obtain strip number " << idHelperSvc()->mmIdHelper().print_to_string(offId) );
125 ATH_MSG_WARNING(" pos " << posOnSurf << " z " << rSurface_pos.z() );
126 stripNumber = 1;
127 }
128
129 Identifier oldId = offId;
130 offId = idHelperSvc()->mmIdHelper().channelID(offId, idHelperSvc()->mmIdHelper().multilayer(offId), idHelperSvc()->mmIdHelper().gasGap(offId),stripNumber);
131 if( idHelperSvc()->mmIdHelper().gasGap(offId) != layer ) {
132 ATH_MSG_WARNING("MicroMegas validation: MM id has bad layer field(2)! " << std::endl << " " << idHelperSvc()->mmIdHelper().print_to_string(offId) << std::endl
133 << " " << idHelperSvc()->mmIdHelper().print_to_string(oldId) << " stripN " << stripNumber );
134 }
135
136 Amg::Vector2D fastDigitPos(0.,0.);
137 if( !detEl->stripPosition(offId,fastDigitPos ) ){
138 ATH_MSG_WARNING("MicroMegas validation: failed to obtain local position for identifier " << idHelperSvc()->mmIdHelper().print_to_string(offId) );
139 }
140
141 Amg::Vector3D detpos = detEl->globalPosition();
142 ATH_MSG_DEBUG("Global hit : r " << hit.globalPosition().perp() << ", phi " << hit.globalPosition().phi() << ", z " << hit.globalPosition().z()
143 << "; detEl: r " << detpos.perp() << ", phi " << detpos.phi() << ", z " << detpos.z()
144 << "; surf z " << surf.center().z() << ", ml " << multilayer << ", l " << layer );
145 ATH_MSG_DEBUG(" detEl: x " << dSurface_pos.x() << " y " << dSurface_pos.y() << " z " << dSurface_pos.z());
146 ATH_MSG_DEBUG("MM Fast digit: x " << fastDigitPos.x() << " y " << fastDigitPos.y()
147 << ", gToL: x " << rSurface_pos.x() << " y " << rSurface_pos.y() << " z " << rSurface_pos.z() );
148
149 // Fill ntuple with the hit/surface/digit positions
150 m_NSWMM_detector_globalPosition.push_back(detpos);
151 m_NSWMM_hitToDsurfacePosition.push_back(dSurface_pos);
152 m_NSWMM_hitToRsurfacePosition.push_back(rSurface_pos);
153
154 m_NSWMM_FastDigitRsurfacePositionX.push_back( posOnSurf.x() );
155 m_NSWMM_FastDigitRsurfacePositionY.push_back( posOnSurf.y() );
156
157 ++n_hits;
158 }
159 m_NSWMM_nSimHits = n_hits;
160
161 ATH_MSG_DEBUG("processed " << m_NSWMM_nSimHits << " MM hits");
162 return true;
163 }
164}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
int GetLayer(const int &hid) const
static const MicromegasHitIdHelper * GetHelper()
int GetSide(const int &hid) const
int GetPhiSector(const int &hid) const
int GetMultiLayer(const int &hid) const
int GetZSector(const int &hid) const
std::string GetStationName(const int &hid) const
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channel) const
An MMReadoutElement corresponds to a single STGC module; therefore typicaly a barrel muon station con...
virtual bool stripPosition(const Identifier &id, Amg::Vector2D &pos) const override final
strip position – local or global If the strip number is outside the range of valid strips,...
bool insideActiveBounds(const Identifier &id, const Amg::Vector2D &locpos, double tol1=0., double tol2=0.) const
boundary check Wrapper Trk::PlaneSurface::insideBounds() taking into account the passivated width
virtual int stripNumber(const Amg::Vector2D &pos, const Identifier &id) const override final
strip number corresponding to local position.
virtual const Trk::PlaneSurface & surface() const override
access to chamber surface (phi orientation), uses the first gas gap
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
const MMReadoutElement * getMMReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
ThreeVectorBranch m_NSWMM_hitGlobalPosition
ScalarBranch< unsigned int > & m_NSWMM_nSimHits
VectorBranch< float > & m_NSWMM_globalTime
VectorBranch< int > & m_NSWMM_trackId
VectorBranch< float > & m_NSWMM_depositEnergy
ThreeVectorBranch m_NSWMM_hitToDsurfacePosition
VectorBranch< float > & m_NSWMM_FastDigitRsurfacePositionY
VectorBranch< int > & m_NSWMM_particleEncoding
VectorBranch< float > & m_NSWMM_FastDigitRsurfacePositionX
VectorBranch< float > & m_NSWMM_kineticEnergy
VectorBranch< bool > & m_NSWMM_isInsideBounds
ThreeVectorBranch m_NSWMM_detector_globalPosition
bool fill(const EventContext &ctx) override final
The fill method checks if enough information is provided such that the branch is cleared from the inf...
ThreeVectorBranch m_NSWMM_hitGlobalDirection
ThreeVectorBranch m_NSWMM_hitToRsurfacePosition
SG::ReadHandleKey< MMSimHitCollection > m_key
MMSimHitVariables(MuonTesterTree &tree, const std::string &container_name, MSG::Level msglvl)
const MuonGM::MuonDetectorManager * getDetMgr(const EventContext &ctx) const
const Muon::IMuonIdHelperSvc * idHelperSvc() const
PrdTesterModule(MuonTesterTree &tree, const std::string &grp_name, MSG::Level msglvl)
bool declare_dependency(Key &key)
Declares the ReadHandle/ ReadCondHandleKey as data dependency of the algorithm.
TTree * tree() override final
Returns the underlying TTree object.
virtual const MmIdHelper & mmIdHelper() const =0
access to CscIdHelper
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
const Amg::Vector3D & center() const
Returns the center position of the Surface.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
bool isSmall(const ChIndex index)
Returns true if the chamber index is in a small sector.