ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4VUserDetectorConstruction.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4VUserDetectorConstruction.cc
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 "G4VPhysicalVolume.hh"
31 #include "G4VUserParallelWorld.hh"
32 #include "G4LogicalVolume.hh"
33 #include "G4LogicalVolumeStore.hh"
34 #include "G4VSensitiveDetector.hh"
35 #include "G4FieldManager.hh"
36 #include "G4SDManager.hh"
38 #include <assert.h>
39 #include <sstream>
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 
244  //The aSD has already been added by user to the manager if needed
245  //G4SDManager::GetSDMpointer()->AddNewDetector(aSD);
246 
247  //New Logic: allow for "multiple" SDs being attached to a single LV.
248  //To do that we use a special proxy SD called G4MultiSensitiveDetector
249 
250  //Get existing SD if already set and check if it is of the special type
251  G4VSensitiveDetector* originalSD = logVol->GetSensitiveDetector();
252  if ( originalSD == aSD ) {
254  msg << "Attempting to add multiple times the same sensitive detector (\"";
255  msg << originalSD->GetName()<<"\") is not allowed, skipping.";
256  G4Exception("G4VUserDetectorConstruction::SetSensitiveDetector",
257  "Run0054",JustWarning,msg);
258  return;
259 
260  }
261  if ( originalSD == nullptr ) {
262  logVol->SetSensitiveDetector(aSD);
263  } else {
264  G4MultiSensitiveDetector* msd = dynamic_cast<G4MultiSensitiveDetector*>(originalSD);
265  if ( msd != nullptr ) {
266  msd->AddSD(aSD);
267  } else {
268  std::ostringstream mn;
269  mn<<"/MultiSD_"<<logVol->GetName()<<"_"<<logVol;
270  const G4String msdname = mn.str();
271  msd = new G4MultiSensitiveDetector(msdname);
272  //We need to register the proxy to have correct handling of IDs
274  msd->AddSD(originalSD);
275  msd->AddSD(aSD);
276  logVol->SetSensitiveDetector(msd);
277  }
278  }
279 }