ATLAS Offline Software
Public Member Functions | Protected Attributes | Private Member Functions | List of all members
SctSensorSD Class Reference

#include <SctSensorSD.h>

Inheritance diagram for SctSensorSD:
Collaboration diagram for SctSensorSD:

Public Member Functions

 SctSensorSD (const std::string &name, const std::string &hitCollectionName)
 
 ~SctSensorSD ()
 
G4bool ProcessHits (G4Step *, G4TouchableHistory *) override
 
void Initialize (G4HCofThisEvent *) override final
 
template<class... Args>
void AddHit (Args &&... args)
 Templated method to stuff a single hit into the sensitive detector class. More...
 

Protected Attributes

SG::WriteHandle< SiHitCollectionm_HitColl
 

Private Member Functions

 FRIEND_TEST (SctSensorSDtest, Initialize)
 
 FRIEND_TEST (SctSensorSDtest, ProcessHits)
 
 FRIEND_TEST (SctSensorSDtest, indexMethod)
 
 FRIEND_TEST (SctSensorSDtest, AddHit)
 
void indexMethod (const G4TouchableHistory *myTouch, double coord1z, int &brlEcap, int &layerDisk, int &etaMod, int &phiMod, int &side)
 

Detailed Description

Definition at line 24 of file SctSensorSD.h.

Constructor & Destructor Documentation

◆ SctSensorSD()

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

Definition at line 31 of file SctSensorSD.cxx.

32  : G4VSensitiveDetector( name )
33  , m_HitColl( hitCollectionName )
34 {
35 }

◆ ~SctSensorSD()

SctSensorSD::~SctSensorSD ( )
inline

Definition at line 35 of file SctSensorSD.h.

35 { /* If all goes well we do not own myHitColl here */ }

Member Function Documentation

◆ AddHit()

template<class... Args>
void SctSensorSD::AddHit ( Args &&...  args)
inline

Templated method to stuff a single hit into the sensitive detector class.

This could get rather tricky, but the idea is to allow fast simulations to use the very same SD classes as the standard simulation.

Definition at line 46 of file SctSensorSD.h.

46 { m_HitColl->Emplace( args... ); }

◆ FRIEND_TEST() [1/4]

SctSensorSD::FRIEND_TEST ( SctSensorSDtest  ,
AddHit   
)
private

◆ FRIEND_TEST() [2/4]

SctSensorSD::FRIEND_TEST ( SctSensorSDtest  ,
indexMethod   
)
private

◆ FRIEND_TEST() [3/4]

SctSensorSD::FRIEND_TEST ( SctSensorSDtest  ,
Initialize   
)
private

◆ FRIEND_TEST() [4/4]

SctSensorSD::FRIEND_TEST ( SctSensorSDtest  ,
ProcessHits   
)
private

◆ indexMethod()

void SctSensorSD::indexMethod ( const G4TouchableHistory *  myTouch,
double  coord1z,
int &  brlEcap,
int &  layerDisk,
int &  etaMod,
int &  phiMod,
int &  side 
)
private

Definition at line 113 of file SctSensorSD.cxx.

114  {
115 
116 
117  //
118  // In the case of the TB the positioning integers won't be initialized
119  // and the identifying integer will be zero. There is no need to do
120  // anything else
121 
122  const int sensorCopyNo = myTouch->GetVolume()->GetCopyNo();
123 
124  if (verboseLevel>5){
125  for (int i=0;i<myTouch->GetHistoryDepth();i++){
126  std::string detname=myTouch->GetVolume(i)->GetLogicalVolume()->GetName();
127  int copyno=myTouch->GetVolume(i)->GetCopyNo();
128  G4cout << "Volume "<<detname << " Copy Nr. " << copyno << G4endl;
129  }
130  }
131 
132  // Barrel geometry from GeoModel. Flag it with a 1000 in the IdTag
133  //
134  if(sensorCopyNo/1000) {
135  // Barrel
136  if(sensorCopyNo == 1000) {
137  side = myTouch->GetVolume(1)->GetCopyNo();
138  etaMod = myTouch->GetVolume(2)->GetCopyNo();
139  phiMod = myTouch->GetVolume(3)->GetCopyNo();
140  layerDisk = myTouch->GetVolume(5)->GetCopyNo();
141  } else if(sensorCopyNo == 1100) {
142  // SLHC stave layout
143  int etaModTmp = myTouch->GetVolume(1)->GetCopyNo();
144  int sign = (etaModTmp>=0)? +1 : -1;
145  side = std::abs(etaModTmp)%2;
146  etaMod = sign * std::abs(etaModTmp)/2;
147  phiMod = myTouch->GetVolume(2)->GetCopyNo();
148  layerDisk = myTouch->GetVolume(4)->GetCopyNo();
149  } else if(sensorCopyNo/100 == 12) {
150  // Segmented sensor (SLHC only)
151  int iSegment = sensorCopyNo%100;
152  int sensorEnvCopyNo = myTouch->GetVolume(1)->GetCopyNo();
153  if (sensorEnvCopyNo == 1000) {
154  side = myTouch->GetVolume(2)->GetCopyNo();
155  etaMod = myTouch->GetVolume(3)->GetCopyNo() + iSegment;
156  phiMod = myTouch->GetVolume(4)->GetCopyNo();
157  layerDisk = myTouch->GetVolume(6)->GetCopyNo();
158  } else if (sensorEnvCopyNo == 1100) {
159  // Stave layout
160  int etaModTmp = myTouch->GetVolume(2)->GetCopyNo();
161  int sign = (etaModTmp>=0)? +1 : -1;
162  side = std::abs(etaModTmp)%2;
163  etaMod = sign * std::abs(etaModTmp)/2 + iSegment;
164  phiMod = myTouch->GetVolume(3)->GetCopyNo();
165  layerDisk = myTouch->GetVolume(5)->GetCopyNo();
166  } else {
167  G4ExceptionDescription description;
168  description << "ProcessHits: Unrecognized geometry in SCT sensitive detector. Please contact the maintainer of the SCT Detector Description.";
169  G4Exception("SctSensorSD", "UnrecognizedSCTGeometry1", FatalException, description);
170  abort();
171  }
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", "UnrecognizedSCTGeometry2", FatalException, description);
176  abort();
177  }
178  if (verboseLevel>5){
179  G4cout << "In the SCT Barrel" << G4endl;
180  G4cout << "----- side : " << side << G4endl;
181  G4cout << "----- eta_module : " << etaMod << G4endl;
182  G4cout << "----- phi_module : " << phiMod << G4endl;
183  G4cout << "----- layer : " << layerDisk << G4endl;
184  G4cout << "----- barrel_ec : " << brlEcap<< G4endl;
185  }
186  } else {
187  // Endcap geometry from GeoModel. Flag it with a 500 or 600 in the IdTag
188  // The level in the hierarchy is different for different geometries
189  // 500 For pre DC3
190  // 600 For DC3 and later (including SLHC)
191  int sensorCopyNoTest = sensorCopyNo/100;
192  if(sensorCopyNoTest == 5 || sensorCopyNoTest == 6) {
193  int signZ = (coord1z > 0) ? 1 : -1;
194  brlEcap = 2 * signZ;
195  side = myTouch->GetVolume(0)->GetCopyNo() % 2;
196  if (sensorCopyNoTest == 5) { // DC2 and Rome
197  etaMod = myTouch->GetVolume(3)->GetCopyNo();
198  layerDisk = myTouch->GetVolume(4)->GetCopyNo();
199  } else { // DC3 and later and SLHC
200  etaMod = myTouch->GetVolume(2)->GetCopyNo();
201  layerDisk = myTouch->GetVolume(3)->GetCopyNo();
202  }
203  int phiNumber = myTouch->GetVolume(1)->GetCopyNo();
204  // Number of modules in ring and module which becomes 0 is encoded in the copy number.
205  // This is in order to recreate the correct id in the negative endcap.
206  int maxModules = (phiNumber & 0x00ff0000) >> 16;
207  int moduleZero = (phiNumber & 0xff000000) >> 24; // When phiMod = moduleZero -> 0 after inverting
208  phiMod = phiNumber & 0x0000ffff;
209  // If -ve endcap then invert numbering
210  // maxModules is non-zero, but check for maxModules != 0 safeguards
211  // against divide by zero (in case we create a geometry without the encoding).
212  if (maxModules && signZ < 0) phiMod = (maxModules + moduleZero - phiMod) % maxModules;
213 
214  // Some printout
215  if (verboseLevel>5){
216  G4cout << "In the SCT EndCap" << G4endl;
217  G4cout << "----- side : " << side << G4endl;
218  G4cout << "----- phi_module : " << phiMod<< G4endl;
219  G4cout << "----- eta_module : " << etaMod << G4endl;
220  G4cout << "----- layerDisk : " << layerDisk << G4endl;
221  G4cout << "----- barrel_ec : " << brlEcap << G4endl;
222  }
223  } else {
224  // Do not expect other numbers. Need to fix SCT_GeoModel or SCT_SLHC_GeoModel if this occurs.
225  G4ExceptionDescription description;
226  description << "ProcessHits: Unrecognized geometry in SCT sensitive detector. Please contact the maintainer of the SCT Detector Description.";
227  G4Exception("SctSensorSD", "UnrecognizedSCTGeometry3", FatalException, description);
228  abort();
229  }
230  }
231  return;
232 }

◆ Initialize()

void SctSensorSD::Initialize ( G4HCofThisEvent *  )
finaloverride

Definition at line 39 of file SctSensorSD.cxx.

40 {
41  if (!m_HitColl.isValid()) m_HitColl = std::make_unique<SiHitCollection>();
42 }

◆ ProcessHits()

G4bool SctSensorSD::ProcessHits ( G4Step *  aStep,
G4TouchableHistory *   
)
override

Definition at line 46 of file SctSensorSD.cxx.

47 {
48  double edep = aStep->GetTotalEnergyDeposit();
49  if(edep==0.) {
50  if(aStep->GetTrack()->GetDefinition()!=G4Geantino::GeantinoDefinition() &&
51  aStep->GetTrack()->GetDefinition()!=G4ChargedGeantino::ChargedGeantinoDefinition())
52  return false;
53  }
54  edep *= CLHEP::MeV;
55  //
56  // Get the Touchable History:
57  //
58  const G4TouchableHistory *myTouch = dynamic_cast<const G4TouchableHistory*>(aStep->GetPreStepPoint()->GetTouchable());
59  if (not myTouch) {
60  G4cout << "SctSensorSD::ProcessHits bad dynamic_cast" << G4endl;
61  return false;
62  }
63  //
64  // Get the hit coordinates. Start and End Point
65  //
66  G4ThreeVector coord1 = aStep->GetPreStepPoint()->GetPosition();
67  G4ThreeVector coord2 = aStep->GetPostStepPoint()->GetPosition();
68  //
69  // Calculate the local step begin and end position.
70  // From a G4 FAQ:
71  // http://geant4-hn.slac.stanford.edu:5090/HyperNews/public/get/geometry/17/1.html
72  //
73  const G4AffineTransform transformation = myTouch->GetHistory()->GetTopTransform();
74  G4ThreeVector localPosition1 = transformation.TransformPoint(coord1);
75  G4ThreeVector localPosition2 = transformation.TransformPoint(coord2);
76  //
77  // Get it into a vector in local coords and with the right units:
78  //
79  HepGeom::Point3D<double> lP1,lP2;
80 
81  lP1[SiHit::xEta] = localPosition1[2]*CLHEP::mm;
82  lP1[SiHit::xPhi] = localPosition1[1]*CLHEP::mm;
83  lP1[SiHit::xDep] = localPosition1[0]*CLHEP::mm;
84 
85  lP2[SiHit::xEta] = localPosition2[2]*CLHEP::mm;
86  lP2[SiHit::xPhi] = localPosition2[1]*CLHEP::mm;
87  lP2[SiHit::xDep] = localPosition2[0]*CLHEP::mm;
88 
89  // Now Navigate the history to know in what detector the step is:
90  // and finally set the ID of det element in which the hit is.
91  //
92  //G4int History;
93  //
94  // Is it TB, barrel or endcap?
95  //
96  int brlEcap = 0;
97  int layerDisk = 0;
98  int etaMod = 0;
99  int phiMod = 0;
100  int side = 0;
101  this->indexMethod(myTouch, coord1.z(), brlEcap, layerDisk, etaMod, phiMod, side);
102  // get the HepMcParticleLink from the TrackHelper
103  TrackHelper trHelp(aStep->GetTrack());
104  m_HitColl->Emplace(lP1,
105  lP2,
106  edep,
107  aStep->GetPreStepPoint()->GetGlobalTime(),//use the global time. i.e. the time from the beginning of the event
108  trHelp.GenerateParticleLink(),
109  1,brlEcap,layerDisk,etaMod,phiMod,side);
110  return true;
111 }

Member Data Documentation

◆ m_HitColl

SG::WriteHandle<SiHitCollection> SctSensorSD::m_HitColl
protected

Definition at line 52 of file SctSensorSD.h.


The documentation for this class was generated from the following files:
SiHit::xPhi
@ xPhi
Definition: SiHit.h:162
python.SystemOfUnits.MeV
int MeV
Definition: SystemOfUnits.py:154
SctSensorSD::m_HitColl
SG::WriteHandle< SiHitCollection > m_HitColl
Definition: SctSensorSD.h:52
TRT::Hit::side
@ side
Definition: HitInfo.h:83
TrackHelper
Definition: TrackHelper.h:14
lumiFormat.i
int i
Definition: lumiFormat.py:92
sign
int sign(int a)
Definition: TRT_StrawNeighbourSvc.h:127
SctSensorSD::indexMethod
void indexMethod(const G4TouchableHistory *myTouch, double coord1z, int &brlEcap, int &layerDisk, int &etaMod, int &phiMod, int &side)
Definition: SctSensorSD.cxx:113
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
SiHit::xDep
@ xDep
Definition: SiHit.h:162
SiHit::xEta
@ xEta
Definition: SiHit.h:162
python.SystemOfUnits.mm
int mm
Definition: SystemOfUnits.py:83
fillSCTHists.etaMod
etaMod
Definition: fillSCTHists.py:23
python.CaloScaleNoiseConfig.args
args
Definition: CaloScaleNoiseConfig.py:80
description
std::string description
glabal timer - how long have I taken so far?
Definition: hcg.cxx:88