Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4VUserDetectorConstruction Class Referenceabstract

#include <G4VUserDetectorConstruction.hh>

Public Member Functions

 G4VUserDetectorConstruction ()=default
 
virtual ~G4VUserDetectorConstruction ()=default
 
virtual G4VPhysicalVolumeConstruct ()=0
 
virtual void ConstructSDandField ()
 
virtual void CloneSD ()
 
virtual void CloneF ()
 
void RegisterParallelWorld (G4VUserParallelWorld *)
 
G4int ConstructParallelGeometries ()
 
void ConstructParallelSD ()
 
G4int GetNumberOfParallelWorld () const
 
G4VUserParallelWorldGetParallelWorld (G4int i) const
 

Protected Member Functions

void SetSensitiveDetector (const G4String &logVolName, G4VSensitiveDetector *aSD, G4bool multi=false)
 
void SetSensitiveDetector (G4LogicalVolume *logVol, G4VSensitiveDetector *aSD)
 

Detailed Description

Definition at line 50 of file G4VUserDetectorConstruction.hh.

Constructor & Destructor Documentation

◆ G4VUserDetectorConstruction()

G4VUserDetectorConstruction::G4VUserDetectorConstruction ( )
default

◆ ~G4VUserDetectorConstruction()

virtual G4VUserDetectorConstruction::~G4VUserDetectorConstruction ( )
virtualdefault

Member Function Documentation

◆ CloneF()

void G4VUserDetectorConstruction::CloneF ( )
virtual

Definition at line 97 of file G4VUserDetectorConstruction.cc.

98{
99 using FMtoFMmap = std::map<G4FieldManager*, G4FieldManager*>;
100 using FMpair = std::pair<G4FieldManager*, G4FieldManager*>;
101
102 FMtoFMmap masterToWorker;
104 for (const auto& g4LogicalVolume : *logVolStore) {
105 // Use shadow of master to get instance of FM
106 G4FieldManager* masterFM = nullptr; // g4LogicalVolume->fFieldManager;
107 G4FieldManager* clonedFM = nullptr;
108 if (masterFM != nullptr) {
109 auto fmFound = masterToWorker.find(masterFM);
110 if (fmFound == masterToWorker.cend()) {
111 // First time we see this SD, let's clone and remember...
112 try {
113 auto insertedEl = masterToWorker.insert(FMpair(masterFM, masterFM->Clone()));
114 clonedFM = (insertedEl.first)->second;
115 }
116 catch (...) {
118 msg << "Cloning of G4FieldManager failed."
119 << " But derived class does not implement cloning. Cannot "
120 "continue.";
121 G4Exception("G4VUserDetectorConstruction::CloneSD()", "Run0053", FatalException, msg);
122 }
123 }
124 else {
125 // We have already seen this SD attached to a different LogicalVolume,
126 // let's re-use previous clone
127 clonedFM = (*fmFound).second;
128 }
129 } // masterFM != 0
130 // Note that we do not push FM to daughters (false argument), however, since
131 // we area looping on all logical volumes and we implemented the "trick" of
132 // the map master<->cloned the final effect is the same as using here the
133 // correct Boolean flag: log-volumes that originally were sharing the same
134 // FM they will have cloned ones
135 g4LogicalVolume->SetFieldManager(clonedFM, false);
136 }
137}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
virtual G4FieldManager * Clone() const
static G4LogicalVolumeStore * GetInstance()

◆ CloneSD()

void G4VUserDetectorConstruction::CloneSD ( )
virtual

Definition at line 140 of file G4VUserDetectorConstruction.cc.

141{
142 // Loop on ALL logial volumes to search for attached SD
144
145 using SDtoSDmap = std::map<G4VSensitiveDetector*, G4VSensitiveDetector*>;
146 using SDpair = std::pair<G4VSensitiveDetector*, G4VSensitiveDetector*>;
147 SDtoSDmap masterToWorker;
148
149 for (const auto& g4LogicalVolume : *logVolStore) {
150 // Use shadow of master to get the instance of SD
151 G4VSensitiveDetector* masterSD = nullptr;
152 G4VSensitiveDetector* clonedSD = nullptr;
153 if (masterSD != nullptr) {
154 auto sdFound = masterToWorker.find(masterSD);
155 if (sdFound == masterToWorker.cend()) {
156 // First time we see this SD, let's clone and remember...
157 try {
158 auto insertedEl = masterToWorker.insert(SDpair(masterSD, masterSD->Clone()));
159 clonedSD = (insertedEl.first)->second;
160 }
161 catch (...) {
163 msg << "Cloning of G4VSensitiveDetector requested for:" << masterSD->GetName() << "\n"
164#ifndef WIN32
165 << " (full path name: " << masterSD->GetFullPathName() << ").\n"
166#endif
167 << " But derived class does not implement cloning. Cannot "
168 "continue.";
169 G4Exception("G4VUserDetectorConstruction::CloneSD()", "Run0053", FatalException, msg);
170 }
171 }
172 else {
173 // We have already seen this SD attached to a different LogicalVolume,
174 // let's re-use previous clone
175 clonedSD = (*sdFound).second;
176 }
177 } // masterSD!=0
178 g4LogicalVolume->SetSensitiveDetector(clonedSD);
179 }
180}
virtual G4VSensitiveDetector * Clone() const
G4String GetFullPathName() const

◆ Construct()

virtual G4VPhysicalVolume * G4VUserDetectorConstruction::Construct ( )
pure virtual

◆ ConstructParallelGeometries()

G4int G4VUserDetectorConstruction::ConstructParallelGeometries ( )

Definition at line 62 of file G4VUserDetectorConstruction.cc.

63{
64 G4int nP = 0;
65 for (const auto& pwItr : parallelWorld) {
66 pwItr->Construct();
67 ++nP;
68 }
69 return nP;
70}
int G4int
Definition G4Types.hh:85

Referenced by G4RunManager::InitializeGeometry().

◆ ConstructParallelSD()

void G4VUserDetectorConstruction::ConstructParallelSD ( )

Definition at line 73 of file G4VUserDetectorConstruction.cc.

74{
75 for (const auto& pwItr : parallelWorld) {
76 pwItr->ConstructSD();
77 }
78}

Referenced by G4RunManager::InitializeGeometry(), and G4WorkerRunManager::InitializeGeometry().

◆ ConstructSDandField()

void G4VUserDetectorConstruction::ConstructSDandField ( )
virtual

◆ GetNumberOfParallelWorld()

G4int G4VUserDetectorConstruction::GetNumberOfParallelWorld ( ) const

Definition at line 81 of file G4VUserDetectorConstruction.cc.

82{
83 return (G4int)parallelWorld.size();
84}

Referenced by GetParallelWorld().

◆ GetParallelWorld()

G4VUserParallelWorld * G4VUserDetectorConstruction::GetParallelWorld ( G4int i) const

Definition at line 87 of file G4VUserDetectorConstruction.cc.

88{
89 if (i < 0 || i >= GetNumberOfParallelWorld()) return nullptr;
90 return parallelWorld[i];
91}

◆ RegisterParallelWorld()

void G4VUserDetectorConstruction::RegisterParallelWorld ( G4VUserParallelWorld * aPW)

Definition at line 48 of file G4VUserDetectorConstruction.cc.

49{
50 auto pwItr = std::find(parallelWorld.cbegin(), parallelWorld.cend(), aPW);
51 if (pwItr != parallelWorld.cend()) {
52 G4String eM = "A parallel world <";
53 eM += aPW->GetName();
54 eM += "> is already registered to the user detector construction.";
55 G4Exception("G4VUserDetectorConstruction::RegisterParallelWorld", "Run0051",
57 }
58 parallelWorld.push_back(aPW);
59}
@ FatalErrorInArgument
const G4String & GetName()

◆ SetSensitiveDetector() [1/2]

void G4VUserDetectorConstruction::SetSensitiveDetector ( const G4String & logVolName,
G4VSensitiveDetector * aSD,
G4bool multi = false )
protected

Definition at line 183 of file G4VUserDetectorConstruction.cc.

185{
186 G4bool found = false;
188 auto volmap = store->GetMap();
189 auto pos = volmap.find(logVolName);
190 if (pos != volmap.cend()) {
191 if ((pos->second.size() > 1) && !multi) {
192 G4String eM = "More than one logical volumes of name <";
193 eM += pos->first;
194 eM += "> are found and thus the sensitive detector <";
195 eM += aSD->GetName();
196 eM += "> cannot be uniquely assigned.";
197 G4Exception("G4VUserDetectorConstruction::SetSensitiveDetector()", "Run0052",
199 }
200 found = true;
201 for (auto& i : pos->second) {
202 SetSensitiveDetector(i, aSD);
203 }
204 }
205 if (!found) {
206 G4String eM2 = "No logical volume of name <";
207 eM2 += logVolName;
208 eM2 += "> is found. The specified sensitive detector <";
209 eM2 += aSD->GetName();
210 eM2 += "> couldn't be assigned to any volume.";
211 G4Exception("G4VUserDetectorConstruction::SetSensitiveDetector()", "Run0053",
213 }
214}
bool G4bool
Definition G4Types.hh:86
const std::map< G4String, std::vector< G4LogicalVolume * > > & GetMap() const
void SetSensitiveDetector(const G4String &logVolName, G4VSensitiveDetector *aSD, G4bool multi=false)

Referenced by SetSensitiveDetector().

◆ SetSensitiveDetector() [2/2]

void G4VUserDetectorConstruction::SetSensitiveDetector ( G4LogicalVolume * logVol,
G4VSensitiveDetector * aSD )
protected

Definition at line 217 of file G4VUserDetectorConstruction.cc.

219{
220 assert(logVol != nullptr && aSD != nullptr);
221
222 // The aSD has already been added by user to the manager if needed
223 // G4SDManager::GetSDMpointer()->AddNewDetector(aSD);
224
225 // New Logic: allow for "multiple" SDs being attached to a single LV.
226 // To do that we use a special proxy SD called G4MultiSensitiveDetector
227
228 // Get existing SD if already set and check if it is of the special type
229 G4VSensitiveDetector* originalSD = logVol->GetSensitiveDetector();
230 if (originalSD == aSD) {
232 msg << "Attempting to add multiple times the same sensitive detector (\"";
233 msg << originalSD->GetName() << "\") is not allowed, skipping.";
234 G4Exception("G4VUserDetectorConstruction::SetSensitiveDetector", "Run0054", JustWarning, msg);
235 return;
236 }
237 if (originalSD == nullptr) {
238 logVol->SetSensitiveDetector(aSD);
239 }
240 else {
241 auto msd = dynamic_cast<G4MultiSensitiveDetector*>(originalSD);
242 if (msd != nullptr) {
243 msd->AddSD(aSD);
244 }
245 else {
246 std::ostringstream mn;
247 mn << "/MultiSD_" << logVol->GetName() << "_" << logVol;
248 const G4String msdname = mn.str();
249 msd = new G4MultiSensitiveDetector(msdname);
250 // We need to register the proxy to have correct handling of IDs
252 msd->AddSD(originalSD);
253 msd->AddSD(aSD);
254 logVol->SetSensitiveDetector(msd);
255 }
256 }
257}
@ JustWarning
G4VSensitiveDetector * GetSensitiveDetector() const
const G4String & GetName() const
void SetSensitiveDetector(G4VSensitiveDetector *pSDetector)
static G4SDManager * GetSDMpointer()
void AddNewDetector(G4VSensitiveDetector *aSD)

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