Bug Summary

File:scratch/gluex/scan-build-work/hdgeant4/src/GlueXDetectorConstruction.cc
Location:line 164, column 7
Description:Value stored to 'docEl' is never read

Annotated Source Code

1//
2// GlueXDetectorConstruction class implementation
3//
4// author: richard.t.jones at uconn.edu
5// version: may 12, 2012
6
7#include "GlueXDetectorConstruction.hh"
8#include "GlueXDetectorMessenger.hh"
9#include "GlueXMagneticField.hh"
10#include "HddmOutput.hh"
11
12#include "GlueXSensitiveDetectorCDC.hh"
13#include "GlueXSensitiveDetectorFDC.hh"
14#include "GlueXSensitiveDetectorSTC.hh"
15#include "GlueXSensitiveDetectorBCAL.hh"
16#include "GlueXSensitiveDetectorFCAL.hh"
17#include "GlueXSensitiveDetectorFCALinsert.hh"
18#include "GlueXSensitiveDetectorGCAL.hh"
19#include "GlueXSensitiveDetectorCCAL.hh"
20#include "GlueXSensitiveDetectorFTOF.hh"
21#include "GlueXSensitiveDetectorDIRC.hh"
22#include "GlueXSensitiveDetectorCERE.hh"
23#include "GlueXSensitiveDetectorFMWPC.hh"
24#include "GlueXSensitiveDetectorUPV.hh"
25#include "GlueXSensitiveDetectorPSC.hh"
26#include "GlueXSensitiveDetectorPS.hh"
27#include "GlueXSensitiveDetectorTPOL.hh"
28#include "GlueXSensitiveDetectorCTOF.hh"
29
30
31#include "G4Version.hh"
32#include "G4LogicalVolume.hh"
33#include "G4PVPlacement.hh"
34#include "G4SDManager.hh"
35#include "G4RunManager.hh"
36#include "G4LogicalVolumeStore.hh"
37#include "G4TransportationManager.hh"
38#include "G4MagIntegratorDriver.hh"
39#include "G4ChordFinder.hh"
40#include "G4Mag_UsualEqRhs.hh"
41#include "G4ExactHelixStepper.hh"
42#include "G4HelixMixedStepper.hh"
43#include "G4ClassicalRK4.hh"
44
45#include "G4SystemOfUnits.hh"
46
47#include "G4VisAttributes.hh"
48
49#include "G4ios.hh"
50
51#include <xercesc/util/PlatformUtils.hpp>
52#include <xercesc/util/XMLString.hpp>
53#include <xercesc/util/XMLStringTokenizer.hpp>
54#include <xercesc/sax/SAXParseException.hpp>
55#include <xercesc/parsers/XercesDOMParser.hpp>
56#include <xercesc/framework/LocalFileFormatTarget.hpp>
57#include <xercesc/dom/DOM.hpp>
58#include <xercesc/util/XercesDefs.hpp>
59#include <xercesc/sax/ErrorHandler.hpp>
60
61using namespace xercesc;
62
63#include "XString.hpp"
64#include "XParsers.hpp"
65
66#include <string.h>
67#include <libgen.h>
68#include <errno(*__errno_location ()).h>
69
70#define X(str)XString(str).unicode_str() XString(str).unicode_str()
71#define S(str)str.c_str() str.c_str()
72
73#define APP_NAME"HDGeant4" "HDGeant4"
74
75G4Mutex GlueXDetectorConstruction::fMutex = G4MUTEX_INITIALIZER{ { 0, 0, 0, 0, 0, 0, 0, { 0, 0 } } };
76std::list<GlueXDetectorConstruction*> GlueXDetectorConstruction::fInstance;
77
78GlueXDetectorConstruction::GlueXDetectorConstruction(G4String hddsFile)
79: fMaxStep(0),
80 fUniformField(0),
81 fpMagneticField(0),
82 fGeometryXML(0)
83{
84 G4AutoLock barrier(&fMutex);
85 fInstance.push_back(this);
86
87 // Initialize the class that implements custom interactive
88 // commands under the command prefix /hdgeant4/.
89
90 fpDetectorMessenger = new GlueXDetectorMessenger(this);
91
92 // Read the geometry description from a HDDS document
93 // (Hall D Detector Specification) and build a Geant4
94 // model of it in memory.
95
96 try
97 {
98 XMLPlatformUtils::Initialize();
99 }
100 catch (const XMLException& toCatch)
101 {
102 XString message(toCatch.getMessage());
103 G4cerr(*G4cerr_p) << APP_NAME"HDGeant4" << " - error during xercesc initialization!"
104 << G4endlstd::endl << S(message)message.c_str() << G4endlstd::endl;
105 exit(1);
106 }
107
108 DOMDocument* document;
109 if (hddsFile.size() > 0)
110 {
111 int size=100;
112 char *saved_cwd = new char[size];
113 while (getcwd(saved_cwd, size) == 0)
114 {
115 delete [] saved_cwd;
116 saved_cwd = new char[size *= 2];
117 }
118 XString xmlFile = hddsFile.c_str();
119 char *dirpath = new char[hddsFile.size() + 2];
120 chdir(dirname(strcpy(dirpath, hddsFile.c_str())));
121 document = buildDOMDocument(xmlFile,false);
122 chdir(saved_cwd);
123 delete [] saved_cwd;
124 delete [] dirpath;
125 }
126 else if (getenv("JANA_GEOMETRY_URL"))
127 {
128#ifndef FORCE_HDDS_FILES_PARSING
129 std::string url = getenv("JANA_GEOMETRY_URL");
130 int run = HddmOutput::getRunNo();
131 fGeometryXML = new HddsGeometryXML(url, run);
132 last_md5_checksum = fGeometryXML->GetChecksum();
133 document = fGeometryXML->getDocument();
134#else
135 int size=100;
136 char *saved_cwd = new char[size];
137 while (getcwd(saved_cwd, size) == 0)
138 {
139 delete [] saved_cwd;
140 saved_cwd = new char[size *= 2];
141 }
142 XString hddsdir = getenv("HDDS_HOME");
143 chdir(hddsdir.c_str());
144 XString xmlFile = "main_HDDS.xml";
145 document = buildDOMDocument(xmlFile,false);
146 chdir(saved_cwd);
147 delete [] saved_cwd;
148#endif
149 }
150 else {
151 G4cerr(*G4cerr_p) << APP_NAME"HDGeant4" << " - no hdds geometry file specified!"
152 << " Cannot continue" << G4endlstd::endl;
153 exit(9);
154 }
155 if (document == 0)
156 {
157 G4cerr(*G4cerr_p) << APP_NAME"HDGeant4" << " - error parsing HDDS document, "
158 << "cannot continue" << G4endlstd::endl;
159 exit(9);
160 }
161
162 DOMNode* docEl;
163 try {
164 docEl = document->getDocumentElement();
Value stored to 'docEl' is never read
165 }
166 catch (DOMException& e) {
167 G4cerr(*G4cerr_p) << APP_NAME"HDGeant4" << " - Woops " << e.msg << G4endlstd::endl;
168 exit(9);
169 }
170
171 DOMElement* rootEl = document->getElementById(X("everything")XString("everything").unicode_str());
172 if (rootEl == 0)
173 {
174 G4cerr(*G4cerr_p) << APP_NAME"HDGeant4" << " - error scanning HDDS document, " << G4endlstd::endl
175 << " no element named \"everything\" found, "
176 << "cannot continue" << G4endlstd::endl;
177 exit(9);
178 }
179
180 try {
181 fHddsBuilder.translate(rootEl);
182 }
183 catch (const DOMException &e) {
184 G4cerr(*G4cerr_p) << APP_NAME"HDGeant4" << " - error scanning HDDS document, "
185 << XString(e.getMessage()) << G4endlstd::endl;
186 exit(1);
187 }
188
189 XMLPlatformUtils::Terminate();
190}
191
192GlueXDetectorConstruction::
193GlueXDetectorConstruction(const GlueXDetectorConstruction &src)
194 : fHddsBuilder(src.fHddsBuilder)
195{
196 G4AutoLock barrier(&fMutex);
197 fInstance.push_back(this);
198 fMaxStep = src.fMaxStep;
199 fUniformField = src.fUniformField;
200 fpMagneticField = src.fpMagneticField; // shallow copy, sharing magfield
201 fpDetectorMessenger = src.fpDetectorMessenger; // shallow copy, sharing
202}
203
204GlueXDetectorConstruction::~GlueXDetectorConstruction()
205{
206 G4AutoLock barrier(&fMutex);
207 fInstance.remove(this);
208 delete fpDetectorMessenger;
209}
210
211const GlueXDetectorConstruction *GlueXDetectorConstruction::GetInstance()
212{
213 // Generally one only needs a single instance of this object
214 // per process, and this static method lets any component in the
215 // application obtain the primary instance, if any. If none has
216 // yet been constructed, it returns zero.
217
218 G4AutoLock barrier(&fMutex);
219 if (fInstance.size() > 0)
220 return *fInstance.begin();
221 return 0;
222}
223
224const HddsG4Builder *GlueXDetectorConstruction::GetBuilder()
225{
226 // Return a const pointer to the internal HddsG4Builder object.
227
228 G4AutoLock barrier(&fMutex);
229 if (fInstance.size() > 0)
230 return &(*fInstance.begin())->fHddsBuilder;
231 return 0;
232}
233
234void GlueXDetectorConstruction::SetUniformField(G4double field_T)
235{
236 // This method embeds the entire Hall D (spectrometer + beam line)
237 // in an external uniform magnetic field. Used only for testing,
238 // this is not how to simulate the GlueX spectrometer field!
239
240 fUniformField = field_T;
241 G4cout(*G4cout_p) << "setting up a new field manager with a uniform field "
242 << " of " << field_T << " Tesla." << G4endlstd::endl;
243 G4ThreeVector B(0,0,fUniformField);
244 G4AffineTransform xform;
245 fpMagneticField = new GlueXUniformMagField(B,tesla,xform);
246}
247
248void GlueXDetectorConstruction::SetMaxStep(G4double step_mm)
249{
250 fMaxStep = (step_mm > 0.)? step_mm*mm : 0;
251}
252
253G4VPhysicalVolume* GlueXDetectorConstruction::Construct()
254{
255 G4LogicalVolume *worldvol = fHddsBuilder.getWorldVolume();
256 G4cout(*G4cout_p) << "Root geometry volume " << worldvol->GetName();
257 worldvol->SetName("World");
258 G4cout(*G4cout_p) << " configured as " << worldvol->GetName() << G4endlstd::endl;
259 worldvol->SetVisAttributes(new G4VisAttributes(false));
260 return new G4PVPlacement(0, G4ThreeVector(), worldvol, "World", 0, 0, 0);
261}
262
263void GlueXDetectorConstruction::ConstructSDandField()
264{
265 G4RunManager::RMType rmtype = G4RunManager::GetRunManager()->
266 GetRunManagerType();
267
268 // Magnetic field objects that were created during geometry building
269 // will need to be reconstructed here in order to be properly
270 // configured to run in multithreaded mode.
271 if (rmtype != G4RunManager::sequentialRM)
272 CloneF();
273
274 G4SDManager* SDman = G4SDManager::GetSDMpointer();
275 GlueXSensitiveDetectorCDC* cdcHandler = 0;
276 GlueXSensitiveDetectorFDC* fdcHandler = 0;
277 GlueXSensitiveDetectorSTC* stcHandler = 0;
278 GlueXSensitiveDetectorBCAL* bcalHandler = 0;
279 GlueXSensitiveDetectorFCAL* fcalHandler = 0;
280 GlueXSensitiveDetectorFCALinsert* fcalInsertHandler = 0;
281 GlueXSensitiveDetectorGCAL* gcalHandler = 0;
282 GlueXSensitiveDetectorCCAL* ccalHandler = 0;
283 GlueXSensitiveDetectorFTOF* ftofHandler = 0;
284 GlueXSensitiveDetectorDIRC* dircHandler = 0;
285 GlueXSensitiveDetectorCERE* cereHandler = 0;
286 GlueXSensitiveDetectorFMWPC* fmwpcHandler = 0;
287 GlueXSensitiveDetectorUPV* upvHandler = 0;
288 GlueXSensitiveDetectorPSC* pscHandler = 0;
289 GlueXSensitiveDetectorPS* psHandler = 0;
290 GlueXSensitiveDetectorTPOL* tpolHandler = 0;
291 GlueXSensitiveDetectorCTOF* ctofHandler = 0;
292
293 // During geometry building, certain logical volumes were marked as
294 // sensitive by adding them to a list. Now we need to go down that
295 // list and pick out an explicit sensitive volume class to handle
296 // each one. If any are missing, report error.
297 const std::map<int, G4LogicalVolume*>
298 svolMap = fHddsBuilder.getSensitiveVolumes();
299 std::map<int, G4LogicalVolume*>::const_iterator iter;
300 for (iter = svolMap.begin(); iter != svolMap.end(); ++iter) {
301 G4String volname = iter->second->GetName();
302 if (volname == "STLA" || volname == "STRA") {
303 if (cdcHandler == 0) {
304 cdcHandler = new GlueXSensitiveDetectorCDC("cdc");
305 SDman->AddNewDetector(cdcHandler);
306 }
307 iter->second->SetSensitiveDetector(cdcHandler);
308 }
309 else if (volname == "FDA1" || volname == "FDA2" ||
310 volname == "FDA3" || volname == "FDA4")
311 {
312 if (fdcHandler == 0) {
313 fdcHandler = new GlueXSensitiveDetectorFDC("fdc");
314 SDman->AddNewDetector(fdcHandler);
315 }
316 iter->second->SetSensitiveDetector(fdcHandler);
317 }
318 else if (volname == "STRC") {
319 if (stcHandler == 0) {
320 stcHandler = new GlueXSensitiveDetectorSTC("stc");
321 SDman->AddNewDetector(stcHandler);
322 }
323 iter->second->SetSensitiveDetector(stcHandler);
324 }
325 else if (volname == "BM01" || volname == "BM02" ||
326 volname == "BM03" || volname == "BM04" ||
327 volname == "BM05" || volname == "BM06" ||
328 volname == "BMF7" || volname == "BMF8" ||
329 volname == "BMF9" || volname == "BMFA")
330 {
331 if (bcalHandler == 0) {
332 bcalHandler = new GlueXSensitiveDetectorBCAL("bcal");
333 SDman->AddNewDetector(bcalHandler);
334 // Also add support beam BCL0 as a "sensitive" element
335 // to catch incident particles as they enter the BCAL
336 G4LogicalVolume *bcl0 = GlueXDetectorConstruction::GetBuilder()->
337 getVolume("BCL0");
338 if (bcl0 != 0) {
339 bcl0->SetSensitiveDetector(bcalHandler);
340 }
341 else {
342 G4cerr(*G4cerr_p) << "Warning from GlueXDetectorConstruction"
343 << "::ConstructSDandField - "
344 << "special BCal volume BCL0 not found"
345 << " in geometry definition, bcalTruthShower"
346 << " information will not be generated."
347 << G4endlstd::endl;
348 }
349 }
350 iter->second->SetSensitiveDetector(bcalHandler);
351 }
352 else if (volname == "LGBL" || volname == "LGLG") {
353 if (fcalHandler == 0) {
354 fcalHandler = new GlueXSensitiveDetectorFCAL("fcal");
355 SDman->AddNewDetector(fcalHandler);
356 }
357 iter->second->SetSensitiveDetector(fcalHandler);
358 }
359 else if (volname == "LTB1") {
360 if (fcalHandler == 0) {
361 fcalInsertHandler = new GlueXSensitiveDetectorFCALinsert("fcalinsert");
362 SDman->AddNewDetector(fcalInsertHandler);
363 }
364 iter->second->SetSensitiveDetector(fcalInsertHandler);
365 }
366 else if (volname == "GCAL") {
367 if (gcalHandler == 0) {
368 gcalHandler = new GlueXSensitiveDetectorGCAL("gcal");
369 SDman->AddNewDetector(gcalHandler);
370 }
371 iter->second->SetSensitiveDetector(gcalHandler);
372 }
373 else if (volname == "LTBL") {
374 if (ccalHandler == 0) {
375 ccalHandler = new GlueXSensitiveDetectorCCAL("ccal");
376 SDman->AddNewDetector(ccalHandler);
377 }
378 iter->second->SetSensitiveDetector(ccalHandler);
379 }
380 else if (volname == "FTOC" || volname == "FTOX" ||
381 volname == "FTOH" || volname == "FTOL")
382 {
383 if (ftofHandler == 0) {
384 ftofHandler = new GlueXSensitiveDetectorFTOF("ftof");
385 SDman->AddNewDetector(ftofHandler);
386 }
387 iter->second->SetSensitiveDetector(ftofHandler);
388 }
389 else if (volname == "CTOF")
390 {
391 if (ctofHandler == 0) {
392 ctofHandler = new GlueXSensitiveDetectorCTOF("ctof");
393 SDman->AddNewDetector(ctofHandler);
394 }
395 iter->second->SetSensitiveDetector(ctofHandler);
396 }
397 // radiator volume: BNNM (NN = bar number 0-47 and M is sub-bar character A-D)
398 else if (volname == "PIXV" ||
399 (volname[0] == 'B' &&
400 10*((int)volname[1]-48)+(int)volname[2]-48 >= 0 &&
401 10*((int)volname[1]-48)+(int)volname[2]-48 < 48))
402 { // this is nasty, but it works
403 if (dircHandler == 0) {
404 dircHandler = new GlueXSensitiveDetectorDIRC("dirc");
405 SDman->AddNewDetector(dircHandler);
406 }
407 iter->second->SetSensitiveDetector(dircHandler);
408 }
409 else if (volname == "WM1N" || volname == "WM2N" || volname == "WM1S" || volname == "WM2S" ||
410 volname == "FTMN" || volname == "FTMS" ||
411 volname == "TM1N" || volname == "TM2N" || volname == "TM3N" ||
412 volname == "TM1S" || volname == "TM2S" || volname == "TM3S" ||
413 volname == "SM1N" || volname == "SM2N" || volname == "SM1S" || volname == "SM2S" ||
414 volname == "OWDG" || volname(0,2) == "AG" )
415 {
416 if (dircHandler == 0) {
417 dircHandler = new GlueXSensitiveDetectorDIRC("dirc");
418 SDman->AddNewDetector(dircHandler);
419 }
420 iter->second->SetSensitiveDetector(dircHandler);
421 }
422 else if (volname == "CERW" || volname == "CPPC") {
423 if (cereHandler == 0) {
424 cereHandler = new GlueXSensitiveDetectorCERE("cere");
425 SDman->AddNewDetector(cereHandler);
426 }
427 iter->second->SetSensitiveDetector(cereHandler);
428 }
429 else if (volname == "CPPG") {
430 if (fmwpcHandler == 0) {
431 fmwpcHandler = new GlueXSensitiveDetectorFMWPC("fmwpc");
432 SDman->AddNewDetector(fmwpcHandler);
433 }
434 iter->second->SetSensitiveDetector(fmwpcHandler);
435 }
436 else if (volname == "UPVP" || volname == "UPVC") {
437 if (upvHandler == 0) {
438 upvHandler = new GlueXSensitiveDetectorUPV("upv");
439 SDman->AddNewDetector(upvHandler);
440 }
441 iter->second->SetSensitiveDetector(upvHandler);
442 }
443 else if (volname == "PSCO") {
444 if (pscHandler == 0) {
445 pscHandler = new GlueXSensitiveDetectorPSC("psc");
446 SDman->AddNewDetector(pscHandler);
447 }
448 iter->second->SetSensitiveDetector(pscHandler);
449 }
450 else if (volname(0,3) == "PTS") {
451 if (tpolHandler == 0) {
452 tpolHandler = new GlueXSensitiveDetectorTPOL("tpol");
453 SDman->AddNewDetector(tpolHandler);
454 }
455 iter->second->SetSensitiveDetector(tpolHandler);
456 }
457 else if (volname == "PSF1" || volname == "PSF2") {
458 if (psHandler == 0) {
459 psHandler = new GlueXSensitiveDetectorPS("ps");
460 SDman->AddNewDetector(psHandler);
461 }
462 iter->second->SetSensitiveDetector(psHandler);
463 }
464 else {
465 G4cerr(*G4cerr_p) << "Warning from GlueXDetectorConstruction"
466 << "::ConstructSDandField - "
467 << "unsupported sensitive volume " << volname
468 << " found in geometry definition."
469 << G4endlstd::endl;
470 }
471 }
472}
473
474void GlueXDetectorConstruction::CloneF()
475{
476 typedef std::map<G4FieldManager*,G4FieldManager*> FMtoFMmap;
477 FMtoFMmap masterToWorker;
478 G4LogicalVolumeStore* const logVolStore = G4LogicalVolumeStore::GetInstance();
479 assert(logVolStore != NULL)((logVolStore != __null) ? static_cast<void> (0) : __assert_fail
("logVolStore != __null", "src/GlueXDetectorConstruction.cc"
, 479, __PRETTY_FUNCTION__))
;
480 for (G4LogicalVolumeStore::const_iterator iter = logVolStore->begin();
481 iter != logVolStore->end();
482 ++iter)
483 {
484 G4LogicalVolume *lvol = *iter;
485 G4FieldManager* masterFM = lvol->GetFieldManager();
486 G4FieldManager* clonedFM = 0;
487 if (masterFM) {
488 FMtoFMmap::iterator fmFound = masterToWorker.find(masterFM);
489 if (fmFound == masterToWorker.end()) {
490
491 // First time we see this FM, let's clone and remember...
492
493 G4ChordFinder *cfinder = masterFM->GetChordFinder();
494#if G4VERSION_NUMBER1042 >= 1040
495 G4VIntegrationDriver *midriver = cfinder->GetIntegrationDriver();
496 double stepMinimum = 1e-2;
497#else
498 G4MagInt_Driver *midriver = cfinder->GetIntegrationDriver();
499 double stepMinimum = midriver->GetHmin();
500#endif
501 G4MagIntegratorStepper *stepper = midriver->GetStepper();
502 const G4Field *field = masterFM->GetDetectorField();
503
504 G4MagneticField *field_copy;
505 if (dynamic_cast<const GlueXUniformMagField*>(field)) {
506 GlueXUniformMagField &orig = *(GlueXUniformMagField*)field;
507 field_copy = new GlueXUniformMagField(orig);
508 }
509 else if (dynamic_cast<const GlueXMappedMagField*>(field)) {
510 GlueXMappedMagField &orig = *(GlueXMappedMagField*)field;
511 field_copy = new GlueXMappedMagField(orig);
512 }
513 else if (dynamic_cast<const GlueXComputedMagField*>(field)) {
514 GlueXComputedMagField &orig = *(GlueXComputedMagField*)field;
515 field_copy = new GlueXComputedMagField(orig);
516 }
517 else if (dynamic_cast<const G4UniformMagField*>(field)) {
518 G4UniformMagField &orig = *(G4UniformMagField*)field;
519 field_copy = new G4UniformMagField(orig);
520 }
521 else {
522 G4cerr(*G4cerr_p) << "GlueXDetectorConstruction::CloneF error - "
523 << "unknown G4MagneticField class found "
524 << "attached to detector volume " << lvol->GetName()
525 << ", cannot continue!" << G4endlstd::endl;
526 exit(1);
527 }
528 G4Mag_UsualEqRhs *eqn_copy = new G4Mag_UsualEqRhs(field_copy);
529 G4MagIntegratorStepper *stepper_copy;
530 if (dynamic_cast<const G4ExactHelixStepper*>(stepper)) {
531 stepper_copy = new G4ExactHelixStepper(eqn_copy);
532 }
533 else if (dynamic_cast<const G4ClassicalRK4*>(stepper)) {
534 stepper_copy = new G4ClassicalRK4(eqn_copy);
535 }
536 else if (dynamic_cast<const G4HelixMixedStepper*>(stepper)) {
537 stepper_copy = new G4HelixMixedStepper(eqn_copy);
538 }
539 else {
540 G4cerr(*G4cerr_p) << "GlueXDetectorConstruction::CloneF error - "
541 << "unknown G4MagIntegratorStepper class found "
542 << "attached to detector volume " << lvol->GetName()
543 << ", cannot continue!" << G4endlstd::endl;
544 exit(1);
545 }
546 G4ChordFinder *cfinder_copy = new G4ChordFinder(field_copy,
547 stepMinimum,
548 stepper_copy);
549 clonedFM = new G4FieldManager(field_copy, cfinder_copy);
550 masterToWorker[masterFM] = clonedFM;
551 }
552 else {
553
554 // We have already seen this FM attached to a different
555 // LogicalVolume, let's re-use the previous clone
556
557 clonedFM = (*fmFound).second;
558 }
559 lvol->SetFieldManager(clonedFM, false);
560 }
561 }
562}
563
564int GlueXDetectorConstruction::GetParallelWorldCount() const
565{
566 for (int worlds=0; ; ++worlds) {
567 if (fHddsBuilder.getWorldVolume(worlds) == 0) {
568 return --worlds;
569 }
570 }
571 return 0;
572}
573
574G4String GlueXDetectorConstruction::GetParallelWorldName(int paraIndex) const
575{
576 std::stringstream worldStr;
577 worldStr << "ParallelWorld" << paraIndex;
578 return worldStr.str();
579}
580
581G4LogicalVolume*
582 GlueXDetectorConstruction::GetParallelWorldVolume(int paraIndex) const
583{
584 return fHddsBuilder.getWorldVolume(paraIndex);
585}
586
587G4ThreeVector
588GlueXDetectorConstruction::GetMagneticField(G4ThreeVector pos, double unit)
589const
590{
591 // Utility function for use by other simulation components,
592 // returns the magnetic field at an arbitrary location in
593 // the geometry. If geometry has not yet been constructed
594 // the value returned is always zero.
595
596 G4TransportationManager *tmanager;
597 G4Navigator *navigator;
598 G4VPhysicalVolume *pvol;
599 G4LogicalVolume *lvol;
600 G4FieldManager *fieldmgr;
601 const G4Field *field;
602 if ((tmanager = G4TransportationManager::GetTransportationManager()) &&
603 (navigator = tmanager->GetNavigatorForTracking()) &&
604 (pvol = navigator->LocateGlobalPointAndSetup(pos)) &&
605 (lvol = pvol->GetLogicalVolume()) &&
606 (fieldmgr = lvol->GetFieldManager()) &&
607 (field = fieldmgr->GetDetectorField()) )
608 {
609 double Bfield[3];
610 double xglob[4] = {pos[0], pos[1], pos[2], 0};
611 field->GetFieldValue(xglob, Bfield);
612 G4ThreeVector B(Bfield[0], Bfield[1], Bfield[2]);
613 return B / unit;
614 }
615 return G4ThreeVector();
616}
617
618
619
620GlueXParallelWorld::GlueXParallelWorld(const GlueXParallelWorld &src)
621 : G4VUserParallelWorld(src.fWorldName), fTopVolume(src.fTopVolume)
622{ }
623
624GlueXParallelWorld::~GlueXParallelWorld() { }
625
626void GlueXParallelWorld::Construct()
627{
628 G4VPhysicalVolume* ghostWorld = GetWorld();
629 G4LogicalVolume* worldLogical = ghostWorld->GetLogicalVolume();
630 for (int child = fTopVolume->GetNoDaughters() - 1; child >= 0; --child) {
631 G4VPhysicalVolume* pvol = fTopVolume->GetDaughter(child);
632 fTopVolume->RemoveDaughter(pvol);
633 worldLogical->AddDaughter(pvol);
634 }
635 if (worldLogical->GetNoDaughters()) {
636 G4cout(*G4cout_p) << "Additional geometry layer configured as "
637 << ghostWorld->GetName() << G4endlstd::endl;
638 }
639 else {
640 G4cout(*G4cout_p) << "Additional geometry layer configured as "
641 << ghostWorld->GetName() << " is EMPTY!" << G4endlstd::endl
642 << "This is probably due to a geometry bug -- "
643 << "PLEASE REPORT THIS TO THE AUTHORS" << G4endlstd::endl;
644 }
645}