Geant4  10.02.p02
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 // $Id: G4VUserDetectorConstruction.cc 92599 2015-09-07 07:11:43Z gcosmo $
28 //
29 
31 #include "G4VPhysicalVolume.hh"
32 #include "G4VUserParallelWorld.hh"
33 #include "G4LogicalVolume.hh"
34 #include "G4LogicalVolumeStore.hh"
35 #include "G4VSensitiveDetector.hh"
36 #include "G4FieldManager.hh"
37 #include "G4SDManager.hh"
39 #include <assert.h>
40 
42 {;}
43 
45 {;}
46 
48 {
49  std::vector<G4VUserParallelWorld*>::iterator pwItr;
50  for(pwItr=parallelWorld.begin();pwItr!=parallelWorld.end();pwItr++)
51  {
52  if((*pwItr)->GetName()==aPW->GetName())
53  {
54  G4String eM = "A parallel world <";
55  eM += aPW->GetName();
56  eM += "> is already registered to the user detector construction.";
57  G4Exception("G4VUserDetectorConstruction::RegisterParallelWorld",
58  "Run0051",FatalErrorInArgument,eM);
59  }
60  }
61  parallelWorld.push_back(aPW);
62 }
63 
65 {
66  G4int nP = 0;
67  std::vector<G4VUserParallelWorld*>::iterator pwItr;
68  for(pwItr=parallelWorld.begin();pwItr!=parallelWorld.end();pwItr++)
69  {
70  (*pwItr)->Construct();
71  nP++;
72  }
73  return nP;
74 }
75 
77 {
78  std::vector<G4VUserParallelWorld*>::iterator pwItr;
79  for(pwItr=parallelWorld.begin();pwItr!=parallelWorld.end();pwItr++)
80  { (*pwItr)->ConstructSD(); }
81 }
82 
84 { return parallelWorld.size(); }
85 
87 {
88  if(i<0||i>=GetNumberOfParallelWorld()) return 0;
89  return parallelWorld[i];
90 }
91 
92 #include "G4RunManager.hh"
93 
95 {
96 // G4RunManager::RMType rmtype = G4RunManager::GetRunManager()->GetRunManagerType();
97 // if(rmtype != G4RunManager::sequentialRM)
98 // {
99 // G4cout
100 // << "User-derived detector construction class does not implement \n"
101 // << "ConstructSDandFiled method: i.e. workers will not have SD and fields!\n"
102 // << "The user can safely ignore this message if (s)he has no sensitive\n"
103 // << "detector or field in her/his application." << G4endl;
104 // }
105 }
106 
107 #include <map>
109 {
110  typedef std::map<G4FieldManager*,G4FieldManager*> FMtoFMmap;
111  typedef std::pair<G4FieldManager*,G4FieldManager*> FMpair;
112  FMtoFMmap masterToWorker;
114  assert( logVolStore != NULL );
115  for ( G4LogicalVolumeStore::const_iterator it = logVolStore->begin() ; it != logVolStore->end() ; ++it )
116  {
117  G4LogicalVolume *g4LogicalVolume = *it;
118  //Use shadow of master to get instance of FM
119  G4FieldManager* masterFM = 0;//g4LogicalVolume->fFieldManager;
120  G4FieldManager* clonedFM = 0;
121  if ( masterFM )
122  {
123  FMtoFMmap::iterator fmFound = masterToWorker.find(masterFM);
124  if ( fmFound == masterToWorker.end() )
125  {
126  //First time we see this SD, let's clone and remember...
127  try {
128  std::pair<FMtoFMmap::iterator,bool> insertedEl = masterToWorker.insert( FMpair(masterFM, masterFM->Clone()) );
129  clonedFM = (insertedEl.first)->second;
130  }
131  catch (...)
132  {
134  msg << "Cloning of G4FieldManager failed."
135  << " But derived class does not implement cloning. Cannot continue.";
136  G4Exception("G4VUserDetectorConstruction::CloneSD", "Run0053", FatalException,msg);
137 
138  }
139  }
140  else
141  {
142  // We have already seen this SD attached to a fifferent LogicalVolume, let's re-use previous clone
143  clonedFM = (*fmFound).second;
144  }
145  }// masterFM != 0
146  //Note that we do not push FM to doughters (false argument), however, since we area looping on all
147  //logical volumes and we implemented the "trick" of the map master<->cloned the final
148  //effect is the same as using here the correct boolean flag: log-volumes that originally were sharing
149  //the same FM they will have cloned ones
150  g4LogicalVolume->SetFieldManager(clonedFM, false);
151  }
152 }
153 
155 {
156  //Loop on ALL logial volumes to search for attached SD
158  assert( logVolStore != NULL );
159 
160  typedef std::map<G4VSensitiveDetector*,G4VSensitiveDetector*> SDtoSDmap;
161  typedef std::pair<G4VSensitiveDetector*,G4VSensitiveDetector*> SDpair;
162  SDtoSDmap masterToWorker;
163 
164  for ( G4LogicalVolumeStore::const_iterator it = logVolStore->begin() ; it != logVolStore->end() ; ++it )
165  {
166  G4LogicalVolume *g4LogicalVolume = *it;
167  //Use shadow of master to get the instance of SD
168  G4VSensitiveDetector* masterSD = 0;//g4LogicalVolume->fSensitiveDetector;
169  G4VSensitiveDetector* clonedSD = 0;
170  if ( masterSD )
171  {
172  SDtoSDmap::iterator sdFound = masterToWorker.find(masterSD);
173  if ( sdFound == masterToWorker.end() )
174  {
175  //First time we see this SD, let's clone and remember...
176  try {
177  std::pair<SDtoSDmap::iterator,bool> insertedEl = masterToWorker.insert( SDpair(masterSD,masterSD->Clone()) );
178  clonedSD = (insertedEl.first)->second;
179  }
180  catch (...)
181  {
183  msg << "Cloning of G4VSensitiveDetector requested for:" << masterSD->GetName() << "\n"
184 #ifndef WIN32
185  << " (full path name: " << masterSD->GetFullPathName() << ").\n"
186 #endif
187  << " But derived class does not implement cloning. Cannot continue.";
188  G4Exception("G4VUserDetectorConstruction::CloneSD", "Run0053", FatalException,msg);
189  }
190 
191  }
192  else
193  {
194  // We have already seen this SD attached to a fifferent LogicalVolume, let's re-use previous clone
195  clonedSD = (*sdFound).second;
196 
197  }
198  }// masterSD!=0
199  g4LogicalVolume->SetSensitiveDetector(clonedSD);
200 
201  }
202 }
203 
205 (const G4String& logVolName, G4VSensitiveDetector* aSD, G4bool multi)
206 {
207  G4bool found = false;
209  for(G4LogicalVolumeStore::iterator pos=store->begin(); pos!=store->end(); pos++)
210  {
211  if((*pos)->GetName()==logVolName)
212  {
213  if(found && !multi)
214  {
215  G4String eM = "More than one logical volumes of the name <";
216  eM += (*pos)->GetName();
217  eM += "> are found and thus the sensitive detector <";
218  eM += aSD->GetName();
219  eM += "> cannot be uniquely assigned.";
220  G4Exception("G4VUserDetectorConstruction::SetSensitiveDetector",
221  "Run0052",FatalErrorInArgument,eM);
222  }
223  found = true;
224  SetSensitiveDetector(*pos,aSD);
225  }
226  }
227  if(!found)
228  {
229  G4String eM2 = "No logical volume of the name <";
230  eM2 += logVolName;
231  eM2 += "> is found. The specified sensitive detector <";
232  eM2 += aSD->GetName();
233  eM2 += "> couldn't be assigned to any volume.";
234  G4Exception("G4VUserDetectorConstruction::SetSensitiveDetector",
235  "Run0053",FatalErrorInArgument,eM2);
236  }
237 }
238 
241 {
242  assert(logVol!=nullptr&&aSD!=nullptr);
243 
245 
246  //New Logic: allow for "multiple" SDs being attached to a single LV.
247  //To do that we use a special proxy SD called G4MultiSensitiveDetector
248 
249  //Get existing SD if already set and check if it is of the special type
250  G4VSensitiveDetector* originalSD = logVol->GetSensitiveDetector();
251  if ( originalSD == nullptr ) {
252  logVol->SetSensitiveDetector(aSD);
253  } else {
254  G4MultiSensitiveDetector* msd = dynamic_cast<G4MultiSensitiveDetector*>(originalSD);
255  if ( msd != nullptr ) {
256  msd->AddSD(aSD);
257  } else {
258  const G4String msdname = "/MultiSD_"+logVol->GetName();
259  msd = new G4MultiSensitiveDetector(msdname);
260  //We need to register the proxy to have correct handling of IDs
262  msd->AddSD(originalSD);
263  msd->AddSD(aSD);
264  logVol->SetSensitiveDetector(msd);
265  }
266  }
267 }
virtual G4FieldManager * Clone() const
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
void AddSD(G4VSensitiveDetector *sd)
int G4int
Definition: G4Types.hh:78
void SetFieldManager(G4FieldManager *pFieldMgr, G4bool forceToAllDaughters)
void RegisterParallelWorld(G4VUserParallelWorld *)
virtual G4VSensitiveDetector * Clone() const
bool G4bool
Definition: G4Types.hh:79
std::vector< G4VUserParallelWorld * > parallelWorld
static G4LogicalVolumeStore * GetInstance()
static const double second
Definition: G4SIunits.hh:156
G4VUserParallelWorld * GetParallelWorld(G4int i) const
G4String GetFullPathName() const
void SetSensitiveDetector(const G4String &logVolName, G4VSensitiveDetector *aSD, G4bool multi=false)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
void AddNewDetector(G4VSensitiveDetector *aSD)
Definition: G4SDManager.cc:71
static G4SDManager * GetSDMpointer()
Definition: G4SDManager.cc:40
const G4String & GetName() const
G4VSensitiveDetector * GetSensitiveDetector() const
void SetSensitiveDetector(G4VSensitiveDetector *pSDetector)
static const G4double pos