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

#include <PixelSensorSD.h>

Inheritance diagram for PixelSensorSD:
Collaboration diagram for PixelSensorSD:

Public Member Functions

 PixelSensorSD (const std::string &name, const std::string &hitCollectionName)
 
G4bool ProcessHits (G4Step *, G4TouchableHistory *) override final
 
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...
 

Private Member Functions

 FRIEND_TEST (PixelSensorSDtest, ProcessHits)
 
 FRIEND_TEST (PixelSensorSDtest, AddHit)
 

Private Attributes

std::string m_HitCollName
 
SiHitCollectionm_HitColl {nullptr}
 

Detailed Description

Definition at line 26 of file PixelSensorSD.h.

Constructor & Destructor Documentation

◆ PixelSensorSD()

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

Definition at line 33 of file PixelSensorSD.cxx.

34  : G4VSensitiveDetector( name )
35  , m_HitCollName( hitCollectionName )
36 {
37 }

Member Function Documentation

◆ AddHit()

template<class... Args>
void PixelSensorSD::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 43 of file PixelSensorSD.h.

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

◆ FRIEND_TEST() [1/2]

PixelSensorSD::FRIEND_TEST ( PixelSensorSDtest  ,
AddHit   
)
private

◆ FRIEND_TEST() [2/2]

PixelSensorSD::FRIEND_TEST ( PixelSensorSDtest  ,
ProcessHits   
)
private

◆ Initialize()

void PixelSensorSD::Initialize ( G4HCofThisEvent *  )
finaloverride

Definition at line 41 of file PixelSensorSD.cxx.

42 {
43  // ISF calls G4SDManager::PrepareNewEvent() before the Geant4 event loop starts...
44  if(auto* eventManger = G4EventManager::GetEventManager()){
45  if(auto* eventInfo = static_cast<AtlasG4EventUserInfo*>(eventManger->GetUserInformation())){
46  m_HitColl = eventInfo->GetHitCollectionMap()->Find<SiHitCollection>(m_HitCollName);
47  }
48  }
49 }

◆ ProcessHits()

G4bool PixelSensorSD::ProcessHits ( G4Step *  aStep,
G4TouchableHistory *   
)
finaloverride

Definition at line 53 of file PixelSensorSD.cxx.

54 {
55  if (verboseLevel>5) G4cout << "Process Hit" << G4endl;
56 
57  G4double edep = aStep->GetTotalEnergyDeposit();
58  edep *= CLHEP::MeV;
59  if(edep==0.) {
60  if(aStep->GetTrack()->GetDefinition() != G4Geantino::GeantinoDefinition() &&
61  aStep->GetTrack()->GetDefinition() != G4ChargedGeantino::ChargedGeantinoDefinition())
62  return false;
63  }
64 
65  //use the global time. i.e. the time from the beginning of the event
66  //
67  // Get the Touchable History:
68  //
69  const G4TouchableHistory *myTouch = dynamic_cast<const G4TouchableHistory*>(aStep->GetPreStepPoint()->GetTouchable());
70  if (not myTouch) {
71  G4cout << "PixelSensorSD::ProcessHits bad dynamic_cast" << G4endl;
72  return false;
73  }
74  if(verboseLevel>5){
75  for (int i=0;i<myTouch->GetHistoryDepth();i++){
76  std::string detname=myTouch->GetVolume(i)->GetLogicalVolume()->GetName();
77  int copyno=myTouch->GetVolume(i)->GetCopyNo();
78  G4cout << "Volume " <<detname <<" Copy Nr. " << copyno << G4endl;
79  }
80  }
81  //
82  // Get the hit coordinates. Start and End Point
83  //
84  G4ThreeVector coord1 = aStep->GetPreStepPoint()->GetPosition();
85  G4ThreeVector coord2 = aStep->GetPostStepPoint()->GetPosition();
86 
87  // Calculate the local step begin and end position.
88  // From a G4 FAQ:
89  // http://geant4-hn.slac.stanford.edu:5090/HyperNews/public/get/geometry/17/1.html
90  //
91  const G4AffineTransform transformation = myTouch->GetHistory()->GetTopTransform();
92  G4ThreeVector localPosition1 = transformation.TransformPoint(coord1);
93  G4ThreeVector localPosition2 = transformation.TransformPoint(coord2);
94 
95  HepGeom::Point3D<double> lP1,lP2;
96  lP1[SiHit::xEta] = localPosition1[2]*CLHEP::mm;
97  lP1[SiHit::xPhi] = localPosition1[1]*CLHEP::mm;
98  lP1[SiHit::xDep] = localPosition1[0]*CLHEP::mm;
99 
100  lP2[SiHit::xEta] = localPosition2[2]*CLHEP::mm;
101  lP2[SiHit::xPhi] = localPosition2[1]*CLHEP::mm;
102  lP2[SiHit::xDep] = localPosition2[0]*CLHEP::mm;
103 
104  //
105  // Get it into a vector in local coords and with the right units:
106 
107 
108  // Now Navigate the history to know in what detector the step is:
109  // and finally set the ID of det element in which the hit is.
110  //
111  //G4int History;
112  //
113  // Is it TB, barrel or endcap?
114  //
115  int BrlEcap = 0;
116  int LayerDisk = 0;
117  int etaMod = 0;
118  int phiMod = 0;
119  int side = 0;
120 
121  // G4VPhysicalVolume* TheVolume = myTouch->GetVolume();
122  //
123  // In the case of the TB the positioning integers won't be initialized
124  // and the identifying integer will be zero. There is no need to do
125  // anything else
126 
127  int BEcopyNo = myTouch->GetVolume()->GetCopyNo();
128 
129  // Barrel
130  if(BEcopyNo == 100) {
131  // Move up of one level in the tree to get the module number:
132  //
133  etaMod = myTouch->GetVolume(1)->GetCopyNo();
134  //
135  // Another level for the ladder
136  //
137  phiMod = myTouch->GetVolume(2)->GetCopyNo();
138  //
139  // Another one for the layer
140  //
141  LayerDisk = myTouch->GetVolume(3)->GetCopyNo();
142  //
143  // Some printout
144  //
145  if (verboseLevel>5){
146  G4cout << "In the Pixel Barrel" << G4endl;
147  G4cout << "----- Phi Module # " << phiMod << G4endl;
148  G4cout << "----- Eta Ladder # " << etaMod << G4endl;
149  G4cout << "----- Layer # " << LayerDisk << G4endl;
150  }
151 
152  // Standard ATLAS EndCap
153  } else if (BEcopyNo == 200) {
154 
155  // Use the copy no. to get the id:
156  phiMod = myTouch->GetVolume(1)->GetCopyNo();
157  if (phiMod == 48) phiMod = 0;
158 
159  // etaMod always 0.
160 
161  // Move up of one level in the tree to get the disk number:
162  LayerDisk = myTouch->GetVolume(2)->GetCopyNo();
163 
164  // Move up of one level in the tree to get the EC number:
165  BrlEcap = myTouch->GetVolume(3)->GetCopyNo();
166  //The following is no longer necessary
167  //if(BrlEcap == -2) BrlEcap = 1;
168 
169  // Workaround for bug in cosmic setup
170  if (BrlEcap == 0) {
171  BrlEcap = (coord1.z() > 0) ? 2 : -2;
172  }
173 
174  // Some printout
175  if (verboseLevel>5){
176  G4cout << "In the Pixel EndCap" << G4endl;
177  G4cout << "----- PhiModule # " << phiMod << G4endl;
178  G4cout << "----- Disk # " << LayerDisk << G4endl;
179  G4cout << "----- Endcap # " << BrlEcap << G4endl;
180  }
181 
182  // SLHC EndCap
183  } else if (BEcopyNo == 300) {
184 
185  // Use the copy no. to get the id:
186  phiMod = myTouch->GetVolume(1)->GetCopyNo();
187 
188  // Note: copyNo is 2*ieta for front face, 2*ieta+1 for back face
189  etaMod = myTouch->GetVolume(2)->GetCopyNo()/2;
190 
191  // Move up of one level in the tree to get the disk number:
192  LayerDisk = myTouch->GetVolume(3)->GetCopyNo();
193 
194  // Move up of one level in the tree to get the EC number:
195  BrlEcap = myTouch->GetVolume(4)->GetCopyNo();
196  //if(BrlEcap == -2) BrlEcap = 1;
197 
198  // Some printout
199  if (verboseLevel>5){
200  G4cout << "In the SLHC Pixel EndCap" << G4endl;
201  G4cout << "----- PhiModule # " << phiMod << G4endl;
202  G4cout << "----- Ring/Eta # " << etaMod << G4endl;
203  G4cout << "----- Disk # " << LayerDisk << G4endl;
204  G4cout << "----- Endcap # " << BrlEcap << G4endl;
205  }
206 
207  } else if(BEcopyNo == 400) { //DBM
208 
209  // Note: there is one volume (3-layers unit) contain the diamond+chip volume
210  // so one increment is needed after 'layerDisk'
211 
212  // only one eta module for the DBM
213  etaMod = 0;
214 
215  // Move up one level to get the layer number, 3 layers per telescope
216  LayerDisk = myTouch->GetVolume(1)->GetCopyNo();
217 
218  // Move up two level to get the phi module, azimuthal position of telescope
219  phiMod = myTouch->GetVolume(3)->GetCopyNo();
220 
221  // Move up one level to get the DBM side, A side or C side
222  BrlEcap = myTouch->GetVolume(4)->GetCopyNo();
223 
224  // Some printout
225  if (verboseLevel>5){
226  G4cout << "In the DBM" << G4endl;
227  G4cout << "----- PhiModule # " << phiMod << G4endl;
228  G4cout << "----- Ring/Eta # " << etaMod << G4endl;
229  G4cout << "----- Disk # " << LayerDisk << G4endl;
230  G4cout << "----- Endcap # " << BrlEcap << G4endl;
231  }
232 
233  } else if(BEcopyNo == 500) { //Inclined
234 
235  std::string volName = myTouch->GetVolume()->GetName();
236 
237  // split the volname vs '_'
238  std::replace(volName.begin(),volName.end(),'_',' ');
239 
240  std::vector<std::string> v;
241  std::istringstream s(volName);
242  std::string tmp;
243  while (s >> tmp) {
244  v.push_back(tmp);
245  }
246 
247  BrlEcap = 0; // no endcap defined in alpine
248  LayerDisk = atoi(v[1].c_str());
249  phiMod = atoi(v[2].c_str());
250  etaMod = atoi(v[3].c_str());
251 
252  if (verboseLevel>5){
253  G4cout << "Volume name " << volName <<G4endl;
254  double xpos = coord1.x();
255  double ypos = coord1.y();
256  double zpos = coord1.z();
257  double r = sqrt(xpos*xpos+ypos*ypos);
258  G4cout << "In the Alpine " << G4endl;
259  G4cout << "----- PhiModule # " << phiMod << G4endl;
260  G4cout << "----- Ring/Eta # " << etaMod << G4endl;
261  G4cout << "----- Disk # " << LayerDisk << G4endl;
262  G4cout << "----- Endcap # " << BrlEcap << G4endl;
263  G4cout << "----- Pos # " << r<<" "<<zpos << G4endl;
264  G4cout << "----- volume " << myTouch->GetVolume()->GetName()<< G4endl;
265  G4cout << " " << myTouch->GetVolume(1)->GetName()<<" "<<
266  myTouch->GetVolume(2)->GetName()<< " " << myTouch->GetVolume(3)->GetName()<<G4endl;
267  }
268 
269  } else if(BEcopyNo == 600) { //ITk ECring
270 
271  std::string volName = myTouch->GetVolume()->GetName();
272 
273  // split the volname vs '_'
274  std::replace(volName.begin(),volName.end(),'_',' ');
275 
276  std::vector<std::string> v;
277  std::istringstream s(volName);
278  std::string tmp;
279  while (s >> tmp) {
280  v.push_back(tmp);
281  }
282 
283  BrlEcap = atoi(v[1].c_str());
284  LayerDisk = atoi(v[2].c_str());
285  phiMod = atoi(v[3].c_str());
286  etaMod = atoi(v[4].c_str());
287 
288  if (verboseLevel>5){
289  double xpos = coord1.x();
290  double ypos = coord1.y();
291  double zpos = coord1.z();
292  double r = sqrt(xpos*xpos+ypos*ypos);
293  G4cout << "Volume name " << volName <<G4endl;
294  G4cout << "In the ITk EC ring " << G4endl;
295  G4cout << "----- PhiModule # " << phiMod << G4endl;
296  G4cout << "----- Ring/Eta # " << etaMod << G4endl;
297  G4cout << "----- Disk # " << LayerDisk << G4endl;
298  G4cout << "----- Endcap # " << BrlEcap << G4endl;
299  G4cout << "----- Pos # " << r<<" "<<zpos << G4endl;
300  G4cout << "----- volume " << myTouch->GetVolume()->GetName()<< G4endl;
301  G4cout << " " << myTouch->GetVolume(1)->GetName()<<" "<<
302  myTouch->GetVolume(2)->GetName()<< " " << myTouch->GetVolume(3)->GetName()<<G4endl;
303  }
304  }
305  else {
306  // Do not expect other numbers. Need to fix PixelGeoModel if this occurs.
307  G4ExceptionDescription description;
308  description << "ProcessHits: Unrecognized geometry in Pixel sensitive detector. Please contact the maintainer of the Pixel Detector Description.";
309  description << "If you are processing a GeoModelXML geometry, please ensure a PixelSensorGmxSD instance is used instead of this (PixelSensorSD).";
310  G4Exception("PixelSensorSD", "UnrecognizedPixelGeometry", FatalException, description);
311  abort();
312  }
313 
314  // get the HepMcParticleLink from the TrackHelper
315 
316  TrackHelper trHelp(aStep->GetTrack());
317  // Temporary solution to get EventContext from a Geant4 thread
318  EventContext const* eventContext{nullptr};
319  if(auto* eventInfo = AtlasG4EventUserInfo::GetEventUserInfo()){
320  eventContext = &eventInfo->GetEventContext();
321  }
322 
323  m_HitColl->Emplace(lP1,
324  lP2,
325  edep,
326  aStep->GetPreStepPoint()->GetGlobalTime(),
327  eventContext ? trHelp.GenerateParticleLink(*eventContext) : trHelp.GenerateParticleLink(),
328  0,BrlEcap,LayerDisk,etaMod,phiMod,side);
329  return true;
330 }

Member Data Documentation

◆ m_HitColl

SiHitCollection* PixelSensorSD::m_HitColl {nullptr}
private

Definition at line 48 of file PixelSensorSD.h.

◆ m_HitCollName

std::string PixelSensorSD::m_HitCollName
private

Definition at line 47 of file PixelSensorSD.h.


The documentation for this class was generated from the following files:
AtlasG4EventUserInfo::GetEventUserInfo
static AtlasG4EventUserInfo * GetEventUserInfo()
Definition: AtlasG4EventUserInfo.h:125
SiHit::xPhi
@ xPhi
Definition: SiHit.h:162
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:310
beamspotman.r
def r
Definition: beamspotman.py:672
AtlasG4EventUserInfo
This class is attached to G4Event objects as UserInformation. It holds a pointer to the HepMC::GenEve...
Definition: AtlasG4EventUserInfo.h:27
python.SystemOfUnits.mm
float mm
Definition: SystemOfUnits.py:98
python.CaloAddPedShiftConfig.args
args
Definition: CaloAddPedShiftConfig.py:47
AtlasHitsVector< SiHit >
PixelSensorSD::m_HitCollName
std::string m_HitCollName
Definition: PixelSensorSD.h:47
python.SystemOfUnits.MeV
float MeV
Definition: SystemOfUnits.py:172
TRT::Hit::side
@ side
Definition: HitInfo.h:83
PixelSensorSD::m_HitColl
SiHitCollection * m_HitColl
Definition: PixelSensorSD.h:48
AtlasHitsVector::Emplace
void Emplace(Args &&... args)
Definition: AtlasHitsVector.h:80
TrackHelper
Definition: TrackHelper.h:16
LayerDisk
Definition: WaferTree.h:57
lumiFormat.i
int i
Definition: lumiFormat.py:85
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
SiHit::xDep
@ xDep
Definition: SiHit.h:162
SiHit::xEta
@ xEta
Definition: SiHit.h:162
python.PyAthena.v
v
Definition: PyAthena.py:154
python.SystemOfUnits.s
float s
Definition: SystemOfUnits.py:147
CxxUtils::atoi
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
Definition: Control/CxxUtils/Root/StringUtils.cxx:85
fillSCTHists.etaMod
etaMod
Definition: fillSCTHists.py:23
description
std::string description
glabal timer - how long have I taken so far?
Definition: hcg.cxx:91