ATLAS Offline Software
Loading...
Searching...
No Matches
SctSensorSD.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3*/
4
5//
6// SCT Sensitive Detector.
7// The Hits are processed here. For every hit I get the position and
8// an information on the sensor in which the interaction happened
9//
10
11// class headers
12#include "SctSensorSD.h"
13
14// athena includes
16#include "MCTruth/TrackHelper.h"
17
18// Geant4 includes
19#include "G4Step.hh"
20#include "G4ThreeVector.hh"
21#include "G4SDManager.hh"
22#include "G4Geantino.hh"
23#include "G4ChargedGeantino.hh"
24#include <G4EventManager.hh>
25
26// CLHEP transform
27#include "CLHEP/Geometry/Transform3D.h"
28
29//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
30
31SctSensorSD::SctSensorSD( const std::string& name, const std::string& hitCollectionName )
32 : G4VSensitiveDetector( name )
33 , m_HitCollName( hitCollectionName )
34{
35}
36
37//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
38
39void SctSensorSD::Initialize(G4HCofThisEvent *)
40{
41 // ISF calls G4SDManager::PrepareNewEvent() before the Geant4 event loop starts...
42 if(auto* eventManger = G4EventManager::GetEventManager()){
43 if(auto* eventInfo = static_cast<AtlasG4EventUserInfo*>(eventManger->GetUserInformation())){
44 m_HitColl = eventInfo->GetHitCollectionMap()->Find<SiHitCollection>(m_HitCollName);
45 m_g4UserEventInfo = eventInfo;
46 }
47 }
48}
49
50//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
51
52G4bool SctSensorSD::ProcessHits(G4Step* aStep, G4TouchableHistory* /*ROhist*/)
53{
54 double edep = aStep->GetTotalEnergyDeposit();
55 if(edep==0.) {
56 if(aStep->GetTrack()->GetDefinition()!=G4Geantino::GeantinoDefinition() &&
57 aStep->GetTrack()->GetDefinition()!=G4ChargedGeantino::ChargedGeantinoDefinition())
58 return false;
59 }
60 edep *= CLHEP::MeV;
61 //
62 // Get the Touchable History:
63 //
64 const G4TouchableHistory *myTouch = dynamic_cast<const G4TouchableHistory*>(aStep->GetPreStepPoint()->GetTouchable());
65 if (not myTouch) {
66 G4cout << "SctSensorSD::ProcessHits bad dynamic_cast" << G4endl;
67 return false;
68 }
69 //
70 // Get the hit coordinates. Start and End Point
71 //
72 G4ThreeVector coord1 = aStep->GetPreStepPoint()->GetPosition();
73 G4ThreeVector coord2 = aStep->GetPostStepPoint()->GetPosition();
74 //
75 // Calculate the local step begin and end position.
76 // From a G4 FAQ:
77 // http://geant4-hn.slac.stanford.edu:5090/HyperNews/public/get/geometry/17/1.html
78 //
79 const G4AffineTransform transformation = myTouch->GetHistory()->GetTopTransform();
80 G4ThreeVector localPosition1 = transformation.TransformPoint(coord1);
81 G4ThreeVector localPosition2 = transformation.TransformPoint(coord2);
82 //
83 // Get it into a vector in local coords and with the right units:
84 //
85 HepGeom::Point3D<double> lP1,lP2;
86
87 lP1[SiHit::xEta] = localPosition1[2]*CLHEP::mm;
88 lP1[SiHit::xPhi] = localPosition1[1]*CLHEP::mm;
89 lP1[SiHit::xDep] = localPosition1[0]*CLHEP::mm;
90
91 lP2[SiHit::xEta] = localPosition2[2]*CLHEP::mm;
92 lP2[SiHit::xPhi] = localPosition2[1]*CLHEP::mm;
93 lP2[SiHit::xDep] = localPosition2[0]*CLHEP::mm;
94
95 // Now Navigate the history to know in what detector the step is:
96 // and finally set the ID of det element in which the hit is.
97 //
98 //G4int History;
99 //
100 // Is it TB, barrel or endcap?
101 //
102 int brlEcap = 0;
103 int layerDisk = 0;
104 int etaMod = 0;
105 int phiMod = 0;
106 int side = 0;
107 this->indexMethod(myTouch, coord1.z(), brlEcap, layerDisk, etaMod, phiMod, side);
108 // get the HepMcParticleLink from the TrackHelper
109 TrackHelper trHelp(aStep->GetTrack());
110 m_HitColl->Emplace(lP1,
111 lP2,
112 edep,
113 aStep->GetPreStepPoint()->GetGlobalTime(),//use the global time. i.e. the time from the beginning of the event
114 trHelp.GenerateParticleLink(m_g4UserEventInfo ? m_g4UserEventInfo->GetEventStore() : nullptr),
115 1,brlEcap,layerDisk,etaMod,phiMod,side);
116 return true;
117}
118
119void SctSensorSD::indexMethod(const G4TouchableHistory *myTouch, double coord1z,
120 int &brlEcap, int &layerDisk, int &etaMod, int &phiMod, int &side) {
121
122
123 //
124 // In the case of the TB the positioning integers won't be initialized
125 // and the identifying integer will be zero. There is no need to do
126 // anything else
127
128 const int sensorCopyNo = myTouch->GetVolume()->GetCopyNo();
129
130 if (verboseLevel>5){
131 for (int i=0;i<myTouch->GetHistoryDepth();i++){
132 std::string detname=myTouch->GetVolume(i)->GetLogicalVolume()->GetName();
133 int copyno=myTouch->GetVolume(i)->GetCopyNo();
134 G4cout << "Volume "<<detname << " Copy Nr. " << copyno << G4endl;
135 }
136 }
137
138 // Barrel geometry from GeoModel. Flag it with a 1000 in the IdTag
139 //
140 if(sensorCopyNo/1000) {
141 // Barrel
142 if(sensorCopyNo == 1000) {
143 side = myTouch->GetVolume(1)->GetCopyNo();
144 etaMod = myTouch->GetVolume(2)->GetCopyNo();
145 phiMod = myTouch->GetVolume(3)->GetCopyNo();
146 layerDisk = myTouch->GetVolume(5)->GetCopyNo();
147 } else if(sensorCopyNo == 1100) {
148 // SLHC stave layout
149 int etaModTmp = myTouch->GetVolume(1)->GetCopyNo();
150 int sign = (etaModTmp>=0)? +1 : -1;
151 side = std::abs(etaModTmp)%2;
152 etaMod = sign * std::abs(etaModTmp)/2;
153 phiMod = myTouch->GetVolume(2)->GetCopyNo();
154 layerDisk = myTouch->GetVolume(4)->GetCopyNo();
155 } else if(sensorCopyNo/100 == 12) {
156 // Segmented sensor (SLHC only)
157 int iSegment = sensorCopyNo%100;
158 int sensorEnvCopyNo = myTouch->GetVolume(1)->GetCopyNo();
159 if (sensorEnvCopyNo == 1000) {
160 side = myTouch->GetVolume(2)->GetCopyNo();
161 etaMod = myTouch->GetVolume(3)->GetCopyNo() + iSegment;
162 phiMod = myTouch->GetVolume(4)->GetCopyNo();
163 layerDisk = myTouch->GetVolume(6)->GetCopyNo();
164 } else if (sensorEnvCopyNo == 1100) {
165 // Stave layout
166 int etaModTmp = myTouch->GetVolume(2)->GetCopyNo();
167 int sign = (etaModTmp>=0)? +1 : -1;
168 side = std::abs(etaModTmp)%2;
169 etaMod = sign * std::abs(etaModTmp)/2 + iSegment;
170 phiMod = myTouch->GetVolume(3)->GetCopyNo();
171 layerDisk = myTouch->GetVolume(5)->GetCopyNo();
172 } else {
173 G4ExceptionDescription description;
174 description << "ProcessHits: Unrecognized geometry in SCT sensitive detector. Please contact the maintainer of the SCT Detector Description.";
175 G4Exception("SctSensorSD", "UnrecognizedSCTGeometry1", FatalException, description);
176 abort();
177 }
178 } else {
179 G4ExceptionDescription description;
180 description << "ProcessHits: Unrecognized geometry in SCT sensitive detector. Please contact the maintainer of the SCT Detector Description.";
181 G4Exception("SctSensorSD", "UnrecognizedSCTGeometry2", FatalException, description);
182 abort();
183 }
184 if (verboseLevel>5){
185 G4cout << "In the SCT Barrel" << G4endl;
186 G4cout << "----- side : " << side << G4endl;
187 G4cout << "----- eta_module : " << etaMod << G4endl;
188 G4cout << "----- phi_module : " << phiMod << G4endl;
189 G4cout << "----- layer : " << layerDisk << G4endl;
190 G4cout << "----- barrel_ec : " << brlEcap<< G4endl;
191 }
192 } else {
193 // Endcap geometry from GeoModel. Flag it with a 500 or 600 in the IdTag
194 // The level in the hierarchy is different for different geometries
195 // 500 For pre DC3
196 // 600 For DC3 and later (including SLHC)
197 int sensorCopyNoTest = sensorCopyNo/100;
198 if(sensorCopyNoTest == 5 || sensorCopyNoTest == 6) {
199 int signZ = (coord1z > 0) ? 1 : -1;
200 brlEcap = 2 * signZ;
201 side = myTouch->GetVolume(0)->GetCopyNo() % 2;
202 if (sensorCopyNoTest == 5) { // DC2 and Rome
203 etaMod = myTouch->GetVolume(3)->GetCopyNo();
204 layerDisk = myTouch->GetVolume(4)->GetCopyNo();
205 } else { // DC3 and later and SLHC
206 etaMod = myTouch->GetVolume(2)->GetCopyNo();
207 layerDisk = myTouch->GetVolume(3)->GetCopyNo();
208 }
209 int phiNumber = myTouch->GetVolume(1)->GetCopyNo();
210 // Number of modules in ring and module which becomes 0 is encoded in the copy number.
211 // This is in order to recreate the correct id in the negative endcap.
212 int maxModules = (phiNumber & 0x00ff0000) >> 16;
213 int moduleZero = (phiNumber & 0xff000000) >> 24; // When phiMod = moduleZero -> 0 after inverting
214 phiMod = phiNumber & 0x0000ffff;
215 // If -ve endcap then invert numbering
216 // maxModules is non-zero, but check for maxModules != 0 safeguards
217 // against divide by zero (in case we create a geometry without the encoding).
218 if (maxModules && signZ < 0) phiMod = (maxModules + moduleZero - phiMod) % maxModules;
219
220 // Some printout
221 if (verboseLevel>5){
222 G4cout << "In the SCT EndCap" << G4endl;
223 G4cout << "----- side : " << side << G4endl;
224 G4cout << "----- phi_module : " << phiMod<< G4endl;
225 G4cout << "----- eta_module : " << etaMod << G4endl;
226 G4cout << "----- layerDisk : " << layerDisk << G4endl;
227 G4cout << "----- barrel_ec : " << brlEcap << G4endl;
228 }
229 } else {
230 // Do not expect other numbers. Need to fix SCT_GeoModel or SCT_SLHC_GeoModel if this occurs.
231 G4ExceptionDescription description;
232 description << "ProcessHits: Unrecognized geometry in SCT sensitive detector. Please contact the maintainer of the SCT Detector Description.";
233 G4Exception("SctSensorSD", "UnrecognizedSCTGeometry3", FatalException, description);
234 abort();
235 }
236 }
237 return;
238}
AtlasHitsVector< SiHit > SiHitCollection
int sign(int a)
This class is attached to G4Event objects as UserInformation.
void indexMethod(const G4TouchableHistory *myTouch, double coord1z, int &brlEcap, int &layerDisk, int &etaMod, int &phiMod, int &side)
std::string m_HitCollName
Definition SctSensorSD.h:51
G4bool ProcessHits(G4Step *, G4TouchableHistory *) override
void Initialize(G4HCofThisEvent *) override final
SctSensorSD(const std::string &name, const std::string &hitCollectionName)
SiHitCollection * m_HitColl
Definition SctSensorSD.h:52
AtlasG4EventUserInfo * m_g4UserEventInfo
Definition SctSensorSD.h:53
@ xPhi
Definition SiHit.h:162
@ xEta
Definition SiHit.h:162
@ xDep
Definition SiHit.h:162
HepMcParticleLink GenerateParticleLink()
Generates a creates new HepMcParticleLink object on the stack based on GetUniqueID(),...
Definition TrackHelper.h:52
std::string description
glabal timer - how long have I taken so far?
Definition hcg.cxx:91