Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4VUserDetectorConstruction.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27//
28
30#include "G4FieldManager.hh"
31#include "G4LogicalVolume.hh"
34#include "G4SDManager.hh"
35#include "G4VPhysicalVolume.hh"
38#include <assert.h>
39#include <sstream>
40
42
44
47{
48 std::vector<G4VUserParallelWorld*>::iterator pwItr;
49 for(pwItr = parallelWorld.begin(); pwItr != parallelWorld.end(); pwItr++)
50 {
51 if((*pwItr)->GetName() == aPW->GetName())
52 {
53 G4String eM = "A parallel world <";
54 eM += aPW->GetName();
55 eM += "> is already registered to the user detector construction.";
56 G4Exception("G4VUserDetectorConstruction::RegisterParallelWorld",
57 "Run0051", FatalErrorInArgument, eM);
58 }
59 }
60 parallelWorld.push_back(aPW);
61}
62
64{
65 G4int nP = 0;
66 std::vector<G4VUserParallelWorld*>::iterator pwItr;
67 for(pwItr = parallelWorld.begin(); pwItr != parallelWorld.end(); pwItr++)
68 {
69 (*pwItr)->Construct();
70 nP++;
71 }
72 return nP;
73}
74
76{
77 std::vector<G4VUserParallelWorld*>::iterator pwItr;
78 for(pwItr = parallelWorld.begin(); pwItr != parallelWorld.end(); pwItr++)
79 {
80 (*pwItr)->ConstructSD();
81 }
82}
83
85{
86 return parallelWorld.size();
87}
88
90 G4int i) const
91{
92 if(i < 0 || i >= GetNumberOfParallelWorld())
93 return 0;
94 return parallelWorld[i];
95}
96
97#include "G4RunManager.hh"
98
100{
101 // G4RunManager::RMType rmtype =
102 // G4RunManager::GetRunManager()->GetRunManagerType(); if(rmtype !=
103 // G4RunManager::sequentialRM)
104 // {
105 // G4cout
106 // << "User-derived detector construction class does not implement \n"
107 // << "ConstructSDandFiled method: i.e. workers will not have SD and
108 // fields!\n"
109 // << "The user can safely ignore this message if (s)he has no sensitive\n"
110 // << "detector or field in her/his application." << G4endl;
111 // }
112}
113
114#include <map>
116{
117 typedef std::map<G4FieldManager*, G4FieldManager*> FMtoFMmap;
118 typedef std::pair<G4FieldManager*, G4FieldManager*> FMpair;
119 FMtoFMmap masterToWorker;
121 assert(logVolStore != NULL);
122 for(G4LogicalVolumeStore::const_iterator it = logVolStore->begin();
123 it != logVolStore->end(); ++it)
124 {
125 G4LogicalVolume* g4LogicalVolume = *it;
126 // Use shadow of master to get instance of FM
127 G4FieldManager* masterFM = 0; // g4LogicalVolume->fFieldManager;
128 G4FieldManager* clonedFM = 0;
129 if(masterFM)
130 {
131 FMtoFMmap::iterator fmFound = masterToWorker.find(masterFM);
132 if(fmFound == masterToWorker.end())
133 {
134 // First time we see this SD, let's clone and remember...
135 try
136 {
137 std::pair<FMtoFMmap::iterator, bool> insertedEl =
138 masterToWorker.insert(FMpair(masterFM, masterFM->Clone()));
139 clonedFM = (insertedEl.first)->second;
140 } catch(...)
141 {
143 msg << "Cloning of G4FieldManager failed."
144 << " But derived class does not implement cloning. Cannot "
145 "continue.";
146 G4Exception("G4VUserDetectorConstruction::CloneSD", "Run0053",
147 FatalException, msg);
148 }
149 }
150 else
151 {
152 // We have already seen this SD attached to a fifferent LogicalVolume,
153 // let's re-use previous clone
154 clonedFM = (*fmFound).second;
155 }
156 } // masterFM != 0
157 // Note that we do not push FM to doughters (false argument), however, since
158 // we area looping on all logical volumes and we implemented the "trick" of
159 // the map master<->cloned the final effect is the same as using here the
160 // correct boolean flag: log-volumes that originally were sharing the same
161 // FM they will have cloned ones
162 g4LogicalVolume->SetFieldManager(clonedFM, false);
163 }
164}
165
167{
168 // Loop on ALL logial volumes to search for attached SD
170 assert(logVolStore != NULL);
171
172 typedef std::map<G4VSensitiveDetector*, G4VSensitiveDetector*> SDtoSDmap;
173 typedef std::pair<G4VSensitiveDetector*, G4VSensitiveDetector*> SDpair;
174 SDtoSDmap masterToWorker;
175
176 for(G4LogicalVolumeStore::const_iterator it = logVolStore->begin();
177 it != logVolStore->end(); ++it)
178 {
179 G4LogicalVolume* g4LogicalVolume = *it;
180 // Use shadow of master to get the instance of SD
181 G4VSensitiveDetector* masterSD = 0; // g4LogicalVolume->fSensitiveDetector;
182 G4VSensitiveDetector* clonedSD = 0;
183 if(masterSD)
184 {
185 SDtoSDmap::iterator sdFound = masterToWorker.find(masterSD);
186 if(sdFound == masterToWorker.end())
187 {
188 // First time we see this SD, let's clone and remember...
189 try
190 {
191 std::pair<SDtoSDmap::iterator, bool> insertedEl =
192 masterToWorker.insert(SDpair(masterSD, masterSD->Clone()));
193 clonedSD = (insertedEl.first)->second;
194 } catch(...)
195 {
197 msg << "Cloning of G4VSensitiveDetector requested for:"
198 << masterSD->GetName() << "\n"
199#ifndef WIN32
200 << " (full path name: " << masterSD->GetFullPathName() << ").\n"
201#endif
202 << " But derived class does not implement cloning. Cannot "
203 "continue.";
204 G4Exception("G4VUserDetectorConstruction::CloneSD", "Run0053",
205 FatalException, msg);
206 }
207 }
208 else
209 {
210 // We have already seen this SD attached to a fifferent LogicalVolume,
211 // let's re-use previous clone
212 clonedSD = (*sdFound).second;
213 }
214 } // masterSD!=0
215 g4LogicalVolume->SetSensitiveDetector(clonedSD);
216 }
217}
218
220 const G4String& logVolName, G4VSensitiveDetector* aSD, G4bool multi)
221{
222 G4bool found = false;
224 for(G4LogicalVolumeStore::iterator pos = store->begin(); pos != store->end();
225 pos++)
226 {
227 if((*pos)->GetName() == logVolName)
228 {
229 if(found && !multi)
230 {
231 G4String eM = "More than one logical volumes of the name <";
232 eM += (*pos)->GetName();
233 eM += "> are found and thus the sensitive detector <";
234 eM += aSD->GetName();
235 eM += "> cannot be uniquely assigned.";
236 G4Exception("G4VUserDetectorConstruction::SetSensitiveDetector",
237 "Run0052", FatalErrorInArgument, eM);
238 }
239 found = true;
240 SetSensitiveDetector(*pos, aSD);
241 }
242 }
243 if(!found)
244 {
245 G4String eM2 = "No logical volume of the name <";
246 eM2 += logVolName;
247 eM2 += "> is found. The specified sensitive detector <";
248 eM2 += aSD->GetName();
249 eM2 += "> couldn't be assigned to any volume.";
250 G4Exception("G4VUserDetectorConstruction::SetSensitiveDetector", "Run0053",
252 }
253}
254
257{
258 assert(logVol != nullptr && aSD != nullptr);
259
260 // The aSD has already been added by user to the manager if needed
261 // G4SDManager::GetSDMpointer()->AddNewDetector(aSD);
262
263 // New Logic: allow for "multiple" SDs being attached to a single LV.
264 // To do that we use a special proxy SD called G4MultiSensitiveDetector
265
266 // Get existing SD if already set and check if it is of the special type
267 G4VSensitiveDetector* originalSD = logVol->GetSensitiveDetector();
268 if(originalSD == aSD)
269 {
271 msg << "Attempting to add multiple times the same sensitive detector (\"";
272 msg << originalSD->GetName() << "\") is not allowed, skipping.";
273 G4Exception("G4VUserDetectorConstruction::SetSensitiveDetector", "Run0054",
274 JustWarning, msg);
275 return;
276 }
277 if(originalSD == nullptr)
278 {
279 logVol->SetSensitiveDetector(aSD);
280 }
281 else
282 {
284 dynamic_cast<G4MultiSensitiveDetector*>(originalSD);
285 if(msd != nullptr)
286 {
287 msd->AddSD(aSD);
288 }
289 else
290 {
291 std::ostringstream mn;
292 mn << "/MultiSD_" << logVol->GetName() << "_" << logVol;
293 const G4String msdname = mn.str();
294 msd = new G4MultiSensitiveDetector(msdname);
295 // We need to register the proxy to have correct handling of IDs
297 msd->AddSD(originalSD);
298 msd->AddSD(aSD);
299 logVol->SetSensitiveDetector(msd);
300 }
301 }
302}
@ JustWarning
@ FatalException
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
virtual G4FieldManager * Clone() const
static G4LogicalVolumeStore * GetInstance()
void SetFieldManager(G4FieldManager *pFieldMgr, G4bool forceToAllDaughters)
G4VSensitiveDetector * GetSensitiveDetector() const
const G4String & GetName() const
void SetSensitiveDetector(G4VSensitiveDetector *pSDetector)
void AddSD(G4VSensitiveDetector *sd)
static G4SDManager * GetSDMpointer()
Definition: G4SDManager.cc:39
void AddNewDetector(G4VSensitiveDetector *aSD)
Definition: G4SDManager.cc:71
virtual G4VSensitiveDetector * Clone() const
G4String GetFullPathName() const
G4VUserParallelWorld * GetParallelWorld(G4int i) const
void RegisterParallelWorld(G4VUserParallelWorld *)
void SetSensitiveDetector(const G4String &logVolName, G4VSensitiveDetector *aSD, G4bool multi=false)