ATLAS Offline Software
Loading...
Searching...
No Matches
TGCSensitiveDetector Class Reference

#include <TGCSensitiveDetector.h>

Inheritance diagram for TGCSensitiveDetector:
Collaboration diagram for TGCSensitiveDetector:

Public Member Functions

 TGCSensitiveDetector (const std::string &name, const std::string &hitCollectionName)
 construction/destruction
void Initialize (G4HCofThisEvent *HCE) override final
 member functions
G4bool ProcessHits (G4Step *aStep, G4TouchableHistory *ROHist) override final

Private Member Functions

 FRIEND_TEST (TGCSensitiveDetectortest, Initialize)
 FRIEND_TEST (TGCSensitiveDetectortest, ProcessHits)

Private Attributes

std::string m_hitCollectionName
 member data
TGCSimHitCollectionm_myTGCHitColl {nullptr}
AtlasG4EventUserInfom_g4UserEventInfo {nullptr}
const TgcHitIdHelperm_muonHelper

Detailed Description

Author
haseg.nosp@m.awa@.nosp@m.azusa.nosp@m..shi.nosp@m.nshu-.nosp@m.u.ac.nosp@m..jp

Class methods and properties

The method TGCSensitiveDetector::ProcessHits is executed by the G4 kernel each time a charged particle (or a geantino) crosses one of the TGC Gas volumes.

Navigating with the touchableHistory method GetHistoryDepth() through the hierarchy of the volumes crossed by the particles, the TGCSensitiveDetector determinates the correct set of geometry parameters to be folded in the Simulation Identifier associated to each hit. The TGC SimIDs are 32-bit unsigned integers, built using the MuonSimEvent/TgcHitIdHelper class which inherits from the MuonHitIdHelper base class.

We describe in the following, how each field of the identifier is retrieved.

1) stationName and stationPhi: when a volume is found in the hierarchy, whose name contains the substring "station", the stationName is extracted from the volume's name; stationPhi is calculated starting from the volume copy number assigned by MuonGeoModel. Separate cases when the station are "F" or "E" type.

2) stationEta: when a volume is found in the hierarchy, whose name contains the substring "tgccomponent", stationEta is calculated starting from the volume copy number assigned by MuonGeoModel. Possibility to calculate the stationPhi at this level, from the copy number assigned by MuonGeoModel (if the copyNo > 1000).

3) gasGap: when a volume is found in the hierarchy, whose name contains the substring "Gas Volume Layer" or "TGCGas", the gasGap is calculated from the volume copy number, according to the positive or negative Z value, in the Atlas global reference system.

@section Some notes:

1) since the volume copy numbers strongly depend on the database layout, the volume name (whether it contains the string "Q02", for instance) is used to retrieve geometry information. In the year 2018 and even some years before there are not any more other database layouts / volumes than MUONQ02 and therefore some logic was removed

2) for each hit, the time of flight (the G4 globalTime), is recorded and associated to the hit.

3) the TGCHit object contains: the SimID, the globalTime, the hit position in the local reference system, the track director cosine in the local reference system and the track identifier.

Definition at line 73 of file TGCSensitiveDetector.h.

Constructor & Destructor Documentation

◆ TGCSensitiveDetector()

TGCSensitiveDetector::TGCSensitiveDetector ( const std::string & name,
const std::string & hitCollectionName )

construction/destruction

Definition at line 18 of file TGCSensitiveDetector.cxx.

19 : G4VSensitiveDetector( name )
20 , m_hitCollectionName( hitCollectionName )
21{
23}
std::string m_hitCollectionName
member data
const TgcHitIdHelper * m_muonHelper
static const TgcHitIdHelper * GetHelper()

Member Function Documentation

◆ FRIEND_TEST() [1/2]

TGCSensitiveDetector::FRIEND_TEST ( TGCSensitiveDetectortest ,
Initialize  )
private

◆ FRIEND_TEST() [2/2]

TGCSensitiveDetector::FRIEND_TEST ( TGCSensitiveDetectortest ,
ProcessHits  )
private

◆ Initialize()

void TGCSensitiveDetector::Initialize ( G4HCofThisEvent * HCE)
finaloverride

member functions

Definition at line 26 of file TGCSensitiveDetector.cxx.

27{
28 m_myTGCHitColl = nullptr;
29 if (auto* eventInfo = AtlasG4EventUserInfo::GetEventUserInfo()) {
30 m_myTGCHitColl = eventInfo->GetHitCollectionMap()->Find<TGCSimHitCollection>(m_hitCollectionName);
31 m_g4UserEventInfo = eventInfo;
32 }
33}
AtlasHitsVector< TGCSimHit > TGCSimHitCollection
static AtlasG4EventUserInfo * GetEventUserInfo()
TGCSimHitCollection * m_myTGCHitColl
AtlasG4EventUserInfo * m_g4UserEventInfo

◆ ProcessHits()

G4bool TGCSensitiveDetector::ProcessHits ( G4Step * aStep,
G4TouchableHistory * ROHist )
finaloverride

Definition at line 35 of file TGCSensitiveDetector.cxx.

35 {
36
37 if (!m_myTGCHitColl) {
38 G4Exception("TGCSensitiveDetector::ProcessHits", "TGCHitCollectionMissing", FatalException,
39 "Hit collection not initialized; did SetupEvent run?");
40 return false;
41 }
42
43 G4Track* track = aStep->GetTrack();
44
45 if (track->GetDefinition()->GetPDGCharge() == 0.0) {
46 if (track->GetDefinition()!=G4Geantino::GeantinoDefinition()) return true;
47 else if (track->GetDefinition()==G4ChargedGeantino::ChargedGeantinoDefinition()) return true;
48 }
49 const G4TouchableHistory* touchHist = static_cast<const G4TouchableHistory*>(aStep->GetPreStepPoint()->GetTouchable());
50 G4ThreeVector position = aStep->GetPreStepPoint()->GetPosition();
51 const G4AffineTransform trans = track->GetTouchable()->GetHistory()->GetTopTransform();
52
53 // fields for the TGC identifier construction
54 std::string stationName;
55 int stationEta(0);
56 int stationPhi(0);
57 int gasGap = 0;
58
59 // TGC hit information
60 double globalTime = aStep->GetPreStepPoint()->GetGlobalTime();
61 Amg::Vector3D localPosition = Amg::Hep3VectorToEigen( trans.TransformPoint(position) );
62 G4ThreeVector direcos = aStep->GetPreStepPoint()->GetMomentumDirection();
63 Amg::Vector3D localDireCos = Amg::Hep3VectorToEigen( trans.TransformAxis(direcos) );
64
65 // scan geometry tree to identify hit channel
66 int zside(0);
67 bool isAssembly = false;
68 for (int i=touchHist->GetHistoryDepth();i>=0;i--) {
69
70 std::string::size_type npos;
71 std::string::size_type nposStat;
72 std::string volName = touchHist->GetVolume(i)->GetName();
73
74 // check if this station is an assembly
75 if ((npos = volName.find("av_")) != std::string::npos &&
76 (npos = volName.find("impr_")) != std::string::npos) isAssembly = true;
77
78 // stationName and stationPhi
79 if ((npos = volName.find("station")) != std::string::npos && (!isAssembly)) {
80
81 stationName = volName.substr(0,npos-2);
82 int volCopyNo = touchHist->GetVolume(i)->GetCopyNo();
83 if (volCopyNo > 0) {
84 zside = 1;
85 } else {
86 zside = -1;
87 }
88 if (stationName.at(2) == 'F') {
89
90 stationPhi = (abs(volCopyNo%100)-1)*3;
91 if (abs(volCopyNo/100) > 3) {
92 stationPhi += abs(volCopyNo/100)-3;
93 } else {
94 stationPhi += abs(volCopyNo/100);
95 }
96
97 stationPhi -= 1;
98 if (stationPhi <= 0) {
100 }
101
102 } else if (stationName.at(2) == 'E') {
103 if (stationName.at(1) == '4') {
104
105 stationPhi = (abs(volCopyNo%100)-1)*3+abs(volCopyNo/100);
106
107 if (abs(volCopyNo%100) < 4) {
109 if (stationPhi <= 0) {
110 stationPhi = 21 - stationPhi;
111 }
112 } else if(abs(volCopyNo%100) < 7) {
113 stationPhi = stationPhi - 1 - 1;
114 } else {
115 stationPhi = stationPhi - 2 - 1;
116 }
117
118 } else {
119
120 stationPhi = (abs(volCopyNo%100)-1)*6+abs(volCopyNo/100);
121
122 stationPhi -= 2;
123 if (stationPhi <= 0) {
124 stationPhi = 48 - stationPhi;
125 }
126 }
127 }
128 } else if ((nposStat = volName.find("impr_")) != std::string::npos &&
129 (npos = volName.find("TGC")) != std::string::npos && isAssembly ) {
130 // vol name for Assembly components are
131 // av_WWW_impr_XXX_Muon::BMSxMDTxx_pv_ZZZ_NAME
132 // where WWW is ass. istance nr.
133 // XXX is comp. imprint nr.
134 // BMSxMDTxx is the name of the comp. log.Vol.
135 // x station sub-type; xx technology subtype
136 // ZZZ is No of order of this daugther
137 // NAME is the comp. tag (geoIdentifierTag)
138 // for TGCs it is stPhiJob[aaa] with
139 // aaa = 1000*stationPhi+Job;
140 // copy numbers for Ass.components are =
141 // CopyNoBase(= geoIdentifierTag of the assembly) + geoIdentifierTag of the component
142 // geoIdentifierTag of the component = Job
143 // geoIdentifierTag of the assembly = (sideC*10000 +
144 // mirsign*1000 + abs(zi)*100 + fi+1)*100000;
145 // mirsign*1000 + abs(zi)*100 + fi+1)*100000;
146 // mirsign = 1 if zi<0 and !mirrored; otherwise 0
147 std::string::size_type loc1,loc2;
148 if ((loc1 = volName.find("Muon::")) != std::string::npos) {
149 stationName = volName.substr(loc1+6,3); //type only
150 }
151
152 int volCopyNo = touchHist->GetVolume(i)->GetCopyNo();
153 int copyNrBase = int(volCopyNo/100000);
154 int sideC = int(copyNrBase/10000);
155 int zi = int((copyNrBase%1000)/100);
156 if (sideC == 1) zi = -zi;
157 if (sideC) {
158 zside = -1;
159 } else {
160 zside = 1;
161 }
162 if (stationName.at(2) == 'F') {
163
164 stationPhi = (abs(copyNrBase%100)-1)*3;
165 if (abs(copyNrBase/100) > 3) {
166 stationPhi += abs(copyNrBase/100)-3;
167 } else {
168 stationPhi += abs(copyNrBase/100);
169 }
170
171 stationPhi -= 1;
172 if (stationPhi <= 0) {
173 stationPhi = 24 - stationPhi;
174 }
175
176 } else if (stationName.at(2) == 'E') {
177 if (stationName.at(1) == '4') {
178
179 stationPhi = (abs(copyNrBase%100)-1)*3+abs(copyNrBase/100);
180
181 if (abs(copyNrBase%100) < 4) {
183 if (stationPhi <= 0) {
184 stationPhi = 21 - stationPhi;
185 }
186 } else if(abs(copyNrBase%100) < 7) {
187 stationPhi = stationPhi - 1 - 1;
188 } else {
189 stationPhi = stationPhi - 2 - 1;
190 }
191 } else {
192
193 stationPhi = (abs(copyNrBase%100)-1)*6+abs(copyNrBase/100);
194
195 stationPhi -= 2;
196 if (stationPhi <= 0) {
197 stationPhi = 48 - stationPhi;
198 }
199 }
200 }
201
202 // now get the geoIdentifierTag of the rpc components
203 int gmID = 0;
204 if ((loc1 = volName.find('[')) != std::string::npos) {
205 if ((loc2 = volName.find(']', loc1+1)) != std::string::npos) {
206 std::istringstream istrvar(volName.substr(loc1+1,loc2-loc1-1));
207 istrvar>>gmID;
208 }
209 }
210 // stationEta, stationPhi
211 stationEta = zside*int(gmID%100);
212 if (gmID > 999) stationPhi = gmID/1000;
213
214 // stationEta
215 } else if ((npos = volName.find("tgccomponent")) != std::string::npos && (!isAssembly)) {
216 int volCopyNo = abs(touchHist->GetVolume(i)->GetCopyNo());
217 stationEta = zside*volCopyNo%100;
218 if (volCopyNo > 1000) { // stationPhi overridden by the number assigned by MuonGeoModel
219 stationPhi = volCopyNo/1000;
220 }
221 // gasGap
222 } else if ((npos = volName.find("Gas Volume Layer")) != std::string::npos) {
223 int volCopyNo = touchHist->GetVolume(i)->GetCopyNo();
224 int iStation = atoi(stationName.substr(1,1).c_str());
225 if (zside < 0) {
226 if (iStation == 1)
227 gasGap = 3-(volCopyNo-3)/4;
228 else
229 gasGap = 2-(volCopyNo-3)/4;
230 } else {
231// if (iStation == 1)
232 gasGap = (volCopyNo-3)/4+1;
233// else
234// gasGap = (volCopyNo-3)/4+1;
235 }
236 } else if ((npos = volName.find("TGCGas")) != std::string::npos) {
237
238 int volCopyNo = touchHist->GetVolume(i)->GetCopyNo();
239
240 if (volCopyNo != 0)
241 gasGap = volCopyNo;
242 }
243
244 }
245
246 //construct the hit identifier
247 HitID TGCid = m_muonHelper->BuildTgcHitId(stationName,
248 stationPhi,
249 stationEta,
250 gasGap);
251 //m_muonHelper->Print(TGCid);
252
253 // construct new tgc hit
254 TrackHelper trHelp(aStep->GetTrack());
255
256 m_myTGCHitColl->Emplace(TGCid,
257 globalTime,
258 localPosition,
259 localDireCos,
260 trHelp.GenerateParticleLink(m_g4UserEventInfo ? m_g4UserEventInfo->GetEventStore() : nullptr),
261 aStep->GetTotalEnergyDeposit(),
262 aStep->GetStepLength(),
263 track->GetDefinition()->GetPDGEncoding(),
264 aStep->GetPreStepPoint()->GetKineticEnergy());
265 return true;
266}
int HitID
Amg::Vector3D Hep3VectorToEigen(const CLHEP::Hep3Vector &CLHEPvector)
Converts a CLHEP-based CLHEP::Hep3Vector into an Eigen-based Amg::Vector3D.
Eigen::Matrix< double, 3, 1 > Vector3D
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
constexpr uint8_t stationPhi
station Phi 1 to 8
unsigned int constexpr sideC
Definition RPDUtils.h:15
@ loc2
generic first and second local coordinate
Definition ParamDefs.h:35
@ loc1
Definition ParamDefs.h:34

Member Data Documentation

◆ m_g4UserEventInfo

AtlasG4EventUserInfo* TGCSensitiveDetector::m_g4UserEventInfo {nullptr}
private

Definition at line 89 of file TGCSensitiveDetector.h.

89{nullptr};

◆ m_hitCollectionName

std::string TGCSensitiveDetector::m_hitCollectionName
private

member data

Definition at line 87 of file TGCSensitiveDetector.h.

◆ m_muonHelper

const TgcHitIdHelper* TGCSensitiveDetector::m_muonHelper
private

Definition at line 90 of file TGCSensitiveDetector.h.

◆ m_myTGCHitColl

TGCSimHitCollection* TGCSensitiveDetector::m_myTGCHitColl {nullptr}
private

Definition at line 88 of file TGCSensitiveDetector.h.

88{nullptr};

The documentation for this class was generated from the following files: