ATLAS Offline Software
Loading...
Searching...
No Matches
sTGCSimHitVariables.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
5
8namespace MuonPRDTest {
9 sTGCSimHitVariables::sTGCSimHitVariables(MuonTesterTree& tree, const std::string& container_name, MSG::Level msglvl) :
10 PrdTesterModule(tree, "sTGC_Sim", msglvl), m_key{container_name} {}
11
13
14 bool sTGCSimHitVariables::fill(const EventContext& ctx) {
15 ATH_MSG_DEBUG("do fill sTGCSimHitVariables()");
17 if (!stgcContainer.isValid()) {
18 ATH_MSG_FATAL("Failed to retrieve SimHit container " << m_key.fullKey());
19 return false;
20 }
21 const MuonGM::MuonDetectorManager* MuonDetMgr = getDetMgr(ctx);
22 if (!MuonDetMgr) { return false; }
23 unsigned int n_hits{0};
24 // Get the sTGC Id hit helper
25 const sTgcHitIdHelper* stgchhelper = sTgcHitIdHelper::GetHelper();
26 const Amg::Vector3D dummyVector(-9999.9, 0.0, 0.0);
27 if (!stgcContainer->size()) ATH_MSG_DEBUG("sTGC Sim container is empty");
28 for (const sTGCSimHit& hit : *stgcContainer) {
29 if(hit.depositEnergy()==0.) continue; // SimHits without energy loss are not recorded.
30
31 for( int type=0;type<=2;++type ){
32 int simId = hit.sTGCId();
33 std::string stname = stgchhelper->GetStationName(simId);
34 int steta = stgchhelper->GetZSector(simId);
35 int stphi = stgchhelper->GetPhiSector(simId);
36 int multilayer = stgchhelper->GetMultiLayer(simId);
37 int layer = stgchhelper->GetLayer(simId);
38 int side = stgchhelper->GetSide(simId);
39
40 if ( stphi==0 ) {
41 ATH_MSG_ERROR("unexpected phi range: " << stphi);
42 return false;
43 }
44
45 // Old [7/12/12] implementation of the Station Name is: T[0-3][L/S][P/C]
46 // Current implementation of the Station Name is: Q[L/S][1-3][P/C]
47 int detNumber = -999, wedgeId = -999, wedgeType = -999;
48 if(stname.length()!=4) {
49 ATH_MSG_WARNING("sTGC validation: station Name exceeds 4 charactes, filling dummy information for detNumber, wedgeId and wedgeType");
50 }
51 else {
52 detNumber = atoi(stname.substr(2,1).c_str());
53 wedgeId = (stname.substr(1,1).compare("L")) ? 0 : 1;
54 wedgeType = (stname.substr(3,1).compare("P")) ? 0 : 1;
55 }
56
57 Identifier offId = idHelperSvc()->stgcIdHelper().channelID(stname[1] == 'L' ? "STL" : "STS",
58 side == 1 ? steta+1 : -steta-1,
59 (stphi-1)/2+1,multilayer,layer,1,1 );
60 m_NSWsTGC_Id.push_back(offId);
61 std::string stName = idHelperSvc()->stgcIdHelper().stationNameString(idHelperSvc()->stgcIdHelper().stationName(offId));
62 int off_channel = idHelperSvc()->stgcIdHelper().channel(offId);
63
64 int isSmall = stName[2] == 'S';
65
66 if( type == 2 && off_channel == 63) {
67 ATH_MSG_DEBUG("Found sTGC Wire Sim Hit with channel number 63 (dead region), skipping this hit");
68 continue;
69 }
70
71 const MuonGM::sTgcReadoutElement* detEl = MuonDetMgr->getsTgcReadoutElement(offId);
72 if (!detEl) {
73 ATH_MSG_ERROR("sTGCSimHitVariables::fillVariables() - Failed to retrieve sTgcReadoutElement for "<<idHelperSvc()->stgcIdHelper().print_to_string(offId).c_str());
74 return false;
75 }
76
77 if( !idHelperSvc()->stgcIdHelper().is_stgc(offId) ){
78 ATH_MSG_WARNING("sTgc id is not a stgc id! " << idHelperSvc()->stgcIdHelper().print_to_string(offId));
79 }
80 if( !idHelperSvc()->stgcIdHelper().is_muon(offId) ){
81 ATH_MSG_WARNING("sTgc id is not a muon id! " << idHelperSvc()->stgcIdHelper().print_to_string(offId));
82 }
83 if( idHelperSvc()->stgcIdHelper().is_mdt(offId)||idHelperSvc()->stgcIdHelper().is_rpc(offId)||idHelperSvc()->stgcIdHelper().is_tgc(offId)||idHelperSvc()->stgcIdHelper().is_csc(offId)||idHelperSvc()->stgcIdHelper().is_mm(offId) ){
84 ATH_MSG_WARNING("sTgc id has wrong technology type! " << idHelperSvc()->stgcIdHelper().is_mdt(offId) << " " << idHelperSvc()->stgcIdHelper().is_rpc(offId)
85 << " " << idHelperSvc()->stgcIdHelper().is_tgc(offId) << " " << idHelperSvc()->stgcIdHelper().is_csc(offId) << " " << idHelperSvc()->stgcIdHelper().is_mm(offId) );
86 }
87 if( idHelperSvc()->stgcIdHelper().gasGap(offId) != layer ) {
88 ATH_MSG_WARNING("sTgc id has bad layer field! " << idHelperSvc()->stgcIdHelper().print_to_string(offId) );
89 }
90
91 // connect the hit with the MC truth
92 int barcode = hit.particleLink().barcode();
93 m_NSWsTGC_trackId.push_back(barcode);
94 m_NSWsTGC_wedgeId.push_back(wedgeId);
95 m_NSWsTGC_wedgeType.push_back(wedgeType);
96 m_NSWsTGC_detectorNumber.push_back(detNumber);
97
98 m_NSWsTGC_globalTime.push_back(hit.globalTime());
99 const Amg::Vector3D& globalPosition = hit.globalPosition();
100 m_NSWsTGC_hitGlobalPosition.push_back(globalPosition);
101
102 const Amg::Vector3D& globalDirection = hit.globalDirection();
103 m_NSWsTGC_hitGlobalDirection.push_back(globalDirection);
104
105 m_NSWsTGC_particleEncoding.push_back(hit.particleEncoding());
106 m_NSWsTGC_depositEnergy.push_back(hit.depositEnergy());
107 m_NSWsTGC_kineticEnergy.push_back(hit.kineticEnergy());
108
109 const Amg::Vector3D& globalPrePosition = hit.globalPrePosition();
110 m_NSWsTGC_hitGlobalPrePosition.push_back(globalPrePosition);
111 if (hit.kineticEnergy() < 0.0) {
112 m_NSWsTGC_hitGlobalPrePosition.push_back(dummyVector);
113 }
114
115 ATH_MSG_DEBUG("sTGC geometry, retrieving detector element for: isSmall " << isSmall << " eta " << idHelperSvc()->stgcIdHelper().stationEta(offId)
116 << " phi " << idHelperSvc()->stgcIdHelper().stationPhi(offId) << " ml " << idHelperSvc()->stgcIdHelper().multilayer(offId) );
117
118 Identifier newId = idHelperSvc()->stgcIdHelper().channelID(idHelperSvc()->stgcIdHelper().parentID(offId), idHelperSvc()->stgcIdHelper().multilayer(offId), idHelperSvc()->stgcIdHelper().gasGap(offId),type,1);
119
120 // compute hit position within the detector element/surfaces
121 const Trk::PlaneSurface& surf = detEl->surface(newId);
122 Amg::Transform3D gToL = detEl->absTransform().inverse();
123 Amg::Vector3D dSurface_pos = gToL*globalPosition;
124
125 // compute the hit position on the readout plane (same as in MuonFastDigitization)
126 Amg::Vector3D rSurface_pos = surf.transform().inverse()*globalPosition;
127 Amg::Vector3D ldir = surf.transform().inverse().linear()*globalDirection;
128
129 ATH_MSG_DEBUG("sTGC channel type:" << type);
130
131 double scale = -rSurface_pos.z()/ldir.z();
132 Amg::Vector3D hitOnSurface = rSurface_pos + scale*ldir;
133
134 // hitOnSurface.x() will be susequent smeared to simulate the detector resolution, here we do not apply any smearing
135 Amg::Vector2D posOnSurf(hitOnSurface.x(), rSurface_pos.y());
136
137 // remember whether the given hit is inside the active volume (and produces a valid digit)
138 m_NSWsTGC_isInsideBounds.push_back( surf.insideBounds(posOnSurf) );
139
140 int stripNumber = detEl->stripNumber(posOnSurf,newId);
141 if( stripNumber == -1 ){
142 ATH_MSG_WARNING("sTGC validation: failed to obtain strip number " << idHelperSvc()->stgcIdHelper().print_to_string(offId) );
143 ATH_MSG_WARNING(" pos " << posOnSurf << " z " << rSurface_pos.z() );
144 stripNumber = 1;
145 }
146 Identifier oldId = offId;
147 offId = idHelperSvc()->stgcIdHelper().channelID(offId, idHelperSvc()->stgcIdHelper().multilayer(offId), idHelperSvc()->stgcIdHelper().gasGap(offId),1,stripNumber);
148 if( idHelperSvc()->stgcIdHelper().gasGap(offId) != layer ) {
149 ATH_MSG_WARNING("sTGC validation: sTgc id has bad layer field(2)! " << std::endl << " " << idHelperSvc()->stgcIdHelper().print_to_string(offId) << std::endl
150 << " " << idHelperSvc()->stgcIdHelper().print_to_string(oldId) << " stripN " << stripNumber );
151 }
152
153 Amg::Vector2D fastDigitPos(0,0);
154 if( !detEl->stripPosition(offId,fastDigitPos) ){
155 ATH_MSG_WARNING("sTGC validation: failed to obtain local position for identifier " << idHelperSvc()->stgcIdHelper().print_to_string(offId) );
156 }
157
158 Amg::Vector3D detpos = detEl->globalPosition();
159 ATH_MSG_DEBUG("sTGC Global hit: r " << hit.globalPosition().perp() << ", phi " << hit.globalPosition().phi() << ", z " << hit.globalPosition().z()
160 << "; detEl: r " << detpos.perp() << ", phi " << detpos.phi() << ", z " << detpos.z()
161 << "; surf z " << surf.center().z() << ", ml " << multilayer << ", l " << layer );
162
163 ATH_MSG_DEBUG(" detEl: x " << dSurface_pos.x() << " y " << dSurface_pos.y() << " z " << dSurface_pos.z());
164 ATH_MSG_DEBUG("sTGC Fast digit: x " << fastDigitPos.x() << " y " << fastDigitPos.y()
165 << ", gToL: x " << rSurface_pos.x() << " y " << rSurface_pos.y() << " z " << rSurface_pos.z() );
166
167 // Fill ntuple with the hit/surface/digit positions
168 m_NSWsTGC_detector_globalPosition.push_back(detpos);
169
170 m_NSWsTGC_hitToDsurfacePosition.push_back(dSurface_pos);
171
172 m_NSWsTGC_hitToRsurfacePosition.push_back(rSurface_pos);
173
174 m_NSWsTGC_FastDigitRsurfacePositionX.push_back(posOnSurf.x());
175 m_NSWsTGC_FastDigitRsurfacePositionY.push_back(posOnSurf.y());
176 m_NSWsTGC_stripNumber.push_back(stripNumber);
177 }
178 ++n_hits;
179 }
180 m_NSWsTGC_nSimHits = n_hits;
181
182 ATH_MSG_DEBUG("processed " << m_NSWsTGC_nSimHits << " sTgc hits");
183 return true;
184 }
185}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
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 sTgcReadoutElement * getsTgcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
An sTgcReadoutElement corresponds to a single STGC module; therefore typicaly a barrel muon station c...
virtual bool stripPosition(const Identifier &id, Amg::Vector2D &pos) const override final
strip position - should be renamed to channel position If the strip number is outside the range of va...
virtual int stripNumber(const Amg::Vector2D &pos, const Identifier &id) const override final
strip number corresponding to local position.
const std::string & stationNameString(const int &index) const
const MuonGM::MuonDetectorManager * getDetMgr(const EventContext &ctx) const
const Muon::IMuonIdHelperSvc * idHelperSvc() const
PrdTesterModule(MuonTesterTree &tree, const std::string &grp_name, MSG::Level msglvl)
ThreeVectorBranch m_NSWsTGC_hitGlobalPrePosition
VectorBranch< int > & m_NSWsTGC_stripNumber
sTGCSimHitVariables(MuonTesterTree &tree, const std::string &container_name, MSG::Level msglvl)
ScalarBranch< unsigned int > & m_NSWsTGC_nSimHits
SG::ReadHandleKey< sTGCSimHitCollection > m_key
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_NSWsTGC_hitToDsurfacePosition
VectorBranch< float > & m_NSWsTGC_kineticEnergy
VectorBranch< float > & m_NSWsTGC_globalTime
VectorBranch< float > & m_NSWsTGC_depositEnergy
VectorBranch< int > & m_NSWsTGC_wedgeType
ThreeVectorBranch m_NSWsTGC_hitToRsurfacePosition
VectorBranch< int > & m_NSWsTGC_particleEncoding
VectorBranch< int > & m_NSWsTGC_detectorNumber
VectorBranch< bool > & m_NSWsTGC_isInsideBounds
VectorBranch< int > & m_NSWsTGC_wedgeId
ThreeVectorBranch m_NSWsTGC_detector_globalPosition
VectorBranch< float > & m_NSWsTGC_FastDigitRsurfacePositionX
VectorBranch< int > & m_NSWsTGC_trackId
VectorBranch< float > & m_NSWsTGC_FastDigitRsurfacePositionY
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 sTgcIdHelper & stgcIdHelper() const =0
access to TgcIdHelper
virtual bool isValid() override final
Can the handle be successfully dereferenced?
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
virtual bool insideBounds(const Amg::Vector2D &locpos, double tol1=0., double tol2=0.) const override
This method calls the inside() method of the Bounds.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
const Amg::Vector3D & center() const
Returns the center position of the Surface.
int GetZSector(const int &hid) const
int GetMultiLayer(const int &hid) const
int GetSide(const int &hid) const
std::string GetStationName(const int &hid) const
int GetPhiSector(const int &hid) const
int GetLayer(const int &hid) const
static const sTgcHitIdHelper * GetHelper()
int channel(const Identifier &id) const override
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channelType, int channel) const
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.
const std::string & stName(StIndex index)
convert StIndex into a string