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