Geant4 VMC Version 6.8
Loading...
Searching...
No Matches
TG4SDServices.cxx
Go to the documentation of this file.
1//------------------------------------------------
2// The Geant4 Virtual Monte Carlo package
3// Copyright (C) 2007 - 2014 Ivana Hrivnacova
4// All rights reserved.
5//
6// For the licensing terms see geant4_vmc/LICENSE.
7// Contact: root-vmc@cern.ch
8//-------------------------------------------------
9
14
15#include "TG4SDServices.h"
16#include "TG4GeometryServices.h"
17#include "TG4Globals.h"
19
20#include <G4LogicalVolume.hh>
21#include <G4LogicalVolumeStore.hh>
22#include <G4Material.hh>
23#include <G4VSensitiveDetector.hh>
24
25#include <TVirtualMCSensitiveDetector.h>
26
27#include <iomanip>
28
31
32G4ThreadLocal std::set<TVirtualMCSensitiveDetector*>* TG4SDServices::fgUserSDs =
33 0;
34G4ThreadLocal std::map<G4String, TVirtualMCSensitiveDetector*>*
36
37//_____________________________________________________________________________
39 : fIsStopRun(false),
44 fIsUserSDs(false)
45{
47
48 if (fgInstance) {
49 TG4Globals::Exception("TG4SDServices", "TG4SDServices",
50 "Cannot create two instances of singleton.");
51 }
52 fgInstance = this;
53}
54
55//_____________________________________________________________________________
61
62//
63// public methods
64//
65
66//_____________________________________________________________________________
68{
69 // Called on the master before rebuilding volume IDs; workers only read.
70 fVolNameToIdMap.clear();
71 fVolIdToLVMap.clear();
72 fLVToVolIdMap.clear();
73 fInstanceToVolId.clear();
74}
75
76//_____________________________________________________________________________
78 G4LogicalVolume* lv, G4int id, G4bool /*fillLVToVolIdMap*/)
79{
80 // Every representation must have a reverse entry, including user SDs.
81 // Keep the third argument for source compatibility with existing clients.
82 if (fLVToVolIdMap.find(lv) != fLVToVolIdMap.end()) return;
83 G4String name = TG4GeometryServices::Instance()->UserVolumeName(lv);
84 auto source = fVolNameToIdMap.emplace(name, id).first;
85 id = source->second;
86 fLVToVolIdMap.emplace(lv, id);
87 fVolIdToLVMap.emplace(id, lv);
88 auto instanceId = static_cast<std::size_t>(lv->GetInstanceID());
89 if (fInstanceToVolId.size() <= instanceId) fInstanceToVolId.resize(instanceId + 1, 0);
90 fInstanceToVolId[instanceId] = id;
91}
92
93//_____________________________________________________________________________
95 const G4String& volumeName, TVirtualMCSensitiveDetector* userSD)
96{
99
100 // G4cout << "TG4SDServices::MapUserSD "
101 // << volumeName << " " << userSD << G4endl;
102
103 // Create the map if it does not yet exist
104 if (!fgUserSDs) {
105 fgUserSDs = new std::set<TVirtualMCSensitiveDetector*>();
106 fgUserSDMap = new std::map<G4String, TVirtualMCSensitiveDetector*>();
107 fIsUserSDs = true;
108 }
109
110 // Add the userSD in the vector only once
111 if (fgUserSDs->find(userSD) == fgUserSDs->end()) {
112 fgUserSDs->insert(userSD);
113 }
114
115 if (fgUserSDMap->find(volumeName) == fgUserSDMap->end()) {
116 (*fgUserSDMap)[volumeName] = userSD;
117 }
118 else {
119 TG4Globals::Warning("TG4SDServices", "MapUserSD",
120 TString("A sensitive detector for volume ") + TString(volumeName.data()) +
121 TString(" has been already defined.") + TG4Globals::Endl() +
122 TString("Setting was ingored."));
123 }
124}
125
126//_____________________________________________________________________________
127void TG4SDServices::PrintStatistics(G4bool open, G4bool close) const
128{
130
131 if (open) TG4Globals::PrintStars(true);
132
133 G4cout << " " << std::setw(5) << NofSensitiveDetectors()
134 << " sensitive detectors" << G4endl;
135
136 if (close) TG4Globals::PrintStars(false);
137}
138
139//_____________________________________________________________________________
141{
143
144 if (fVolNameToIdMap.size()) {
145 G4cout << "Dump of VolNameToIdMap - " << fVolNameToIdMap.size()
146 << " entries:" << G4endl;
147 G4int counter = 0;
148 std::map<G4String, G4int>::const_iterator it;
149 for (it = fVolNameToIdMap.begin(); it != fVolNameToIdMap.end(); ++it) {
150 G4cout << "Map element " << std::right << std::setw(3) << counter++
151 << " ";
152 G4cout << std::left << std::setw(20) << it->first << " ";
153 G4cout << std::right << std::setw(8) << it->second << " ";
154 G4cout << G4endl;
155 }
156 }
157}
158
159//_____________________________________________________________________________
161{
163
164 if (fVolIdToLVMap.size()) {
165 G4cout << "Dump of VolIdToLVMap - " << fVolIdToLVMap.size()
166 << " entries:" << G4endl;
167 G4int counter = 0;
168 std::multimap<G4int, G4LogicalVolume*>::const_iterator it;
169 for (it = fVolIdToLVMap.begin(); it != fVolIdToLVMap.end(); ++it) {
170 G4cout << "Map element " << std::right << std::setw(3) << counter++
171 << " ";
172 G4cout << std::right << std::setw(8) << it->first << " ";
173 G4cout << std::right << std::setw(12) << it->second << " ";
174 G4cout << std::left << std::setw(20) << it->second->GetName() << " ";
175 G4cout << std::right << G4endl;
176 }
177 }
178}
179
180//_____________________________________________________________________________
182{
184
185 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
186
187 G4cout << "Sensitive volumes (volId, volName): " << G4endl;
188 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
189 G4LogicalVolume* lv = (*lvStore)[i];
190 if (lv->GetSensitiveDetector()) {
191 G4cout << " ";
192 G4cout << std::right << std::setw(4) << GetVolumeID(lv) << " ";
193 G4cout << std::left << std::setw(20) << lv->GetName();
194 G4cout << std::right << G4endl;
195 }
196 }
197}
198
199//_____________________________________________________________________________
201{
203
204 G4LogicalVolumeStore* lvStore = G4LogicalVolumeStore::GetInstance();
205
206 G4cout << "User sensitive detectors (volId, volName, sdName): " << G4endl;
207 for (G4int i = 0; i < G4int(lvStore->size()); i++) {
208 G4LogicalVolume* lv = (*lvStore)[i];
209 auto sd = dynamic_cast<TG4SensitiveDetector*>(lv->GetSensitiveDetector());
210 TVirtualMCSensitiveDetector* userSD = sd ? sd->GetUserSD() : nullptr;
211 if (userSD) {
212 G4cout << " ";
213 G4cout << std::right << std::setw(4) << GetVolumeID(lv) << " ";
214 G4cout << std::left << std::setw(20) << lv->GetName() << " ";
215 G4cout << std::left << std::setw(20) << userSD->GetName() << " ";
216 G4cout << std::right << G4endl;
217 }
218 }
219}
220
221//_____________________________________________________________________________
222G4int TG4SDServices::GetVolumeID(const G4String& volName) const
223{
225
226 std::map<G4String, G4int>::const_iterator it = fVolNameToIdMap.find(volName);
227
228 if (it == fVolNameToIdMap.end()) {
229 TG4Globals::Warning("TG4SDServices", "GetVolumeID",
230 "Unknown Volume Id for " + TString(volName.data()));
231 return 0;
232 }
233
234 return it->second;
235}
236
237//_____________________________________________________________________________
238G4int TG4SDServices::GetVolumeID(G4LogicalVolume* logicalVolume) const
239{
240 // The map is authoritative: instance IDs identify representations, not
241 // VMC source volumes; a user SD may also serve several source volumes.
242 // Preserve constant-time access on the stepping path.
243 auto instanceId = static_cast<std::size_t>(logicalVolume->GetInstanceID());
244 if (instanceId < fInstanceToVolId.size() && fInstanceToVolId[instanceId] != 0)
245 return fInstanceToVolId[instanceId];
246 TG4Globals::Warning("TG4SDServices", "GetVolumeID",
247 "Unknown Volume Id for " + TString(logicalVolume->GetName()));
248 return 0;
249}
250
251//_____________________________________________________________________________
252G4int TG4SDServices::GetMediumID(G4LogicalVolume* logicalVolume) const
253{
255
256 if (fIsUserSDs) {
257 return TG4GeometryServices::Instance()->GetMediumId(logicalVolume);
258 }
259
260#ifdef MCDEBUG
261 G4VSensitiveDetector* sd = logicalVolume->GetSensitiveDetector();
262
263 if (sd) {
264 return GetSensitiveDetector(sd)->GetMediumID();
265 }
266 else {
267 return TG4GeometryServices::Instance()->GetMediumId(logicalVolume);
268 }
269#else
270 G4VSensitiveDetector* sd = logicalVolume->GetSensitiveDetector();
271 if (sd)
272 return ((TG4SensitiveDetector*)sd)->GetMediumID();
273 else {
274 return TG4GeometryServices::Instance()->GetMediumId(logicalVolume);
275 }
276#endif
277}
278
279//_____________________________________________________________________________
280TVirtualMCSensitiveDetector* TG4SDServices::GetUserSD(
281 G4String volumeName, G4bool warn) const
282{
283
284 if (!fgUserSDMap) return 0;
285
286 std::map<G4String, TVirtualMCSensitiveDetector*>::const_iterator it =
287 fgUserSDMap->find(volumeName);
288
289 if (it == fgUserSDMap->end()) {
290 if (warn) {
291 TG4Globals::Warning("TG4SDServices", "GetLogicalVolume",
292 "No sensitive detector is defined for volume " +
293 TString(volumeName.data()));
294 }
295 return 0;
296 }
297
298 return it->second;
299}
300
301//_____________________________________________________________________________
302G4String TG4SDServices::GetVolumeName(G4int volumeId) const
303{
307
308 G4LogicalVolume* lv = GetLogicalVolume(volumeId, false);
309
310 if (!lv) {
311 TString text = "volumeId=";
312 text += volumeId;
313 TG4Globals::Warning("TG4SDServices", "GetVolumeName",
314 "Sensitive detector with " + text + " is not defined.");
315 return "";
316 }
317
319}
320
321//_____________________________________________________________________________
322std::vector<G4LogicalVolume*> TG4SDServices::GetLogicalVolumes(G4int volumeId) const
323{
324 std::vector<G4LogicalVolume*> result;
325 auto range = fVolIdToLVMap.equal_range(volumeId);
326 for (auto it = range.first; it != range.second; ++it) result.push_back(it->second);
327 return result;
328}
329
330//_____________________________________________________________________________
332 G4int volumeId, G4bool warn) const
333{
336
337 std::multimap<G4int, G4LogicalVolume*>::const_iterator it =
338 fVolIdToLVMap.find(volumeId);
339
340 if (it == fVolIdToLVMap.end()) {
341 if (warn) {
342 TString text = "volumeId=";
343 text += volumeId;
344 TG4Globals::Warning("TG4SDServices", "GetLogicalVolume",
345 "Sensitive detector with " + text + " is not defined.");
346 }
347 return 0;
348 }
349
350 return it->second;
351}
352
353//_____________________________________________________________________________
354Int_t TG4SDServices::GetMediumId(G4int volumeId) const
355{
357
359 GetLogicalVolume(volumeId));
360}
361
362//_____________________________________________________________________________
369
370//_____________________________________________________________________________
372 G4VSensitiveDetector* sd) const
373{
375
376 if (!sd) return 0;
377
378 TG4SensitiveDetector* tsd = dynamic_cast<TG4SensitiveDetector*>(sd);
379
380 if (!tsd) {
381 TG4Globals::Exception("TG4SDServices", "GetSensitiveDetector",
382 "Wrong sensitive detector type.");
383 return 0;
384 }
385 else
386 return tsd;
387}
388
389//_____________________________________________________________________________
390Int_t TG4SDServices::NofVolDaughters(const char* volName) const
391{
393
394 G4int volId = GetVolumeID(volName);
395 G4LogicalVolume* lv = GetLogicalVolume(volId);
396
397 if (!lv) return 0;
398
399 return lv->GetNoDaughters();
400}
401
402//_____________________________________________________________________________
403const char* TG4SDServices::VolDaughterName(const char* volName, Int_t i) const
404{
406
407 G4int volId = GetVolumeID(volName);
408 G4LogicalVolume* lv = GetLogicalVolume(volId);
409
410 if (!lv) return "";
411
412 G4int nofDaughters = lv->GetNoDaughters();
413 if (i < 0 || i >= nofDaughters) {
414 TString text = "index=";
415 text += i;
416 TG4Globals::Warning("TG4SDServices", "VolDaughterName",
417 "Mother volume " + TString(volName) + " has no daughter with " + text +
418 ".");
419 return "";
420 }
421
422 G4VPhysicalVolume* daughter = lv->GetDaughter(i);
423 // UserVolumeName(string) can refer to the argument; keep storage alive.
424 static thread_local G4String name;
425 name = TG4GeometryServices::Instance()->UserVolumeName(daughter->GetLogicalVolume());
426 return name.c_str();
427}
428
429//_____________________________________________________________________________
430Int_t TG4SDServices::VolDaughterCopyNo(const char* volName, Int_t i) const
431{
433
434 G4int volId = GetVolumeID(volName);
435 G4LogicalVolume* lv = GetLogicalVolume(volId);
436
437 if (!lv) return 0;
438
439 G4int nofDaughters = lv->GetNoDaughters();
440 if (i < 0 || i >= nofDaughters) {
441 TString text = "index=";
442 text += i;
443 TG4Globals::Warning("TG4SDServices", "VolDaughterCopyNo",
444 "Mother volume " + TString(volName) + " has no daughter with " + text +
445 ".");
446 return 0;
447 }
448
449 return lv->GetDaughter(i)->GetCopyNo();
450}
Definition of the TG4GeometryServices class.
Definition of the TG4Globals class and basic container types.
Definition of the TG4SDServices class.
Definition of the TG4SensitiveDetector class.
G4int GetMediumId(G4LogicalVolume *lv) const
const G4String & UserVolumeName(const G4String &name) const
static TG4GeometryServices * Instance()
static void PrintStars(G4bool emptyLineFirst)
static void Warning(const TString &className, const TString &methodName, const TString &text)
static void Exception(const TString &className, const TString &methodName, const TString &text)
static TString Endl()
Definition TG4Globals.h:101
Sensitive detectors services.
G4int GetMediumID(G4LogicalVolume *volume) const
static G4ThreadLocal std::set< TVirtualMCSensitiveDetector * > * fgUserSDs
vector of user SDs
static TG4SDServices * fgInstance
this instance
G4bool fIsUserSDs
info about user SDs
static G4ThreadLocal std::map< G4String, TVirtualMCSensitiveDetector * > * fgUserSDMap
map volume name -> user SD
TG4SensitiveDetector * GetSensitiveDetector(G4VSensitiveDetector *sd) const
std::vector< G4int > fInstanceToVolId
Dense read-only stepping cache, indexed by Geant4 instance ID.
std::map< G4LogicalVolume *, G4int > fLVToVolIdMap
map logical volume -> volume id
TVirtualMCSensitiveDetector * GetUserSD(G4String volumeName, G4bool warn=true) const
void PrintUserSensitiveDetectors() const
G4int GetVolumeID(const G4String &volumeName) const
G4bool fIsStopRun
info about run stopping by user
void PrintSensitiveVolumes() const
void PrintVolNameToIdMap() const
Int_t NofVolDaughters(const char *volName) const
void MapVolume(G4LogicalVolume *lv, G4int id, G4bool fillLVToVolIdMap)
std::map< G4String, G4int > fVolNameToIdMap
map volume name -> volume id
static const G4int fgkFirstVolumeId
the first volume id
Int_t NofSensitiveDetectors() const
void MapUserSD(const G4String &volumeName, TVirtualMCSensitiveDetector *userSD)
void PrintStatistics(G4bool open, G4bool close) const
void PrintVolIdToLVMap() const
Int_t VolDaughterCopyNo(const char *volName, Int_t i) const
G4String GetVolumeName(G4int volumeId) const
std::vector< G4LogicalVolume * > GetLogicalVolumes(G4int volumeId) const
G4int GetMediumId(G4int volumeId) const
std::multimap< G4int, G4LogicalVolume * > fVolIdToLVMap
one VMC source ID -> all its Geant4 representations
G4LogicalVolume * GetLogicalVolume(G4int volumeId, G4bool warn=true) const
const char * VolDaughterName(const char *volName, Int_t i) const
Sensitive detector class for calling a user defined stepping function.
static G4int GetTotalNofSensitiveDetectors()
TVirtualMCSensitiveDetector * GetUserSD() const