2817d3e2 |
1 | // $Id$ |
2 | // Category: geometry |
3 | // |
4 | // C++ interface to Geant3 basic routines |
5 | // for building Geant4 geometry |
6 | // |
7 | // by V. Berejnoi, 25.2.1999 |
8 | // materials, tracking media support |
9 | // added by I.Hrivnacova, 27.5.1999 |
10 | |
11 | #include "TG4GeometryManager.h" |
12 | #include "TG4GeometryOutputManager.h" |
154fc5a5 |
13 | #include "TG4GeometryServices.h" |
f1bdb708 |
14 | #include "TG4G3PhysicsManager.h" |
15 | #include "TG4G3Units.h" |
2817d3e2 |
16 | #include "TG4VSensitiveDetector.h" |
17 | #include "TG4Limits.h" |
18 | #include "TG4Globals.h" |
2817d3e2 |
19 | |
20 | #include <G3toG4.hh> |
21 | #include <G3toG4BuildTree.hh> |
22 | #include <G3VolTable.hh> |
23 | #include <G3RotTable.hh> |
24 | #include <G3EleTable.hh> |
25 | #include <G3MatTable.hh> |
26 | #include <G3MedTable.hh> |
27 | #include <G3SensVolVector.hh> |
28 | |
2817d3e2 |
29 | #include <G4VSensitiveDetector.hh> |
30 | #include <G4LogicalVolumeStore.hh> |
31 | #include <G4PVPlacement.hh> |
32 | #include <G4Material.hh> |
33 | #include <G4MaterialPropertiesTable.hh> |
34 | #include <G4Element.hh> |
35 | |
2817d3e2 |
36 | // extern global method from g3tog4 |
37 | void G3CLRead(G4String &, char *); |
38 | |
39 | TG4GeometryManager* TG4GeometryManager::fgInstance = 0; |
40 | |
41 | TG4GeometryManager::TG4GeometryManager() |
42 | : fMediumCounter(0), |
43 | fMaterialCounter(0), |
44 | fMatrixCounter(0), |
45 | fUseG3TMLimits(false), |
46 | fWriteGeometry(true) |
47 | { |
48 | // |
49 | if (fgInstance) { |
50 | TG4Globals::Exception( |
51 | "TG4GeometryManager: attempt to create two instances of singleton."); |
52 | } |
53 | |
54 | fOutputManager = new TG4GeometryOutputManager(); |
55 | |
154fc5a5 |
56 | fGeometryServices = new TG4GeometryServices(&fMediumIdVector, &fNameMap); |
57 | |
2817d3e2 |
58 | fgInstance = this; |
59 | |
60 | // instantiate the default element table |
61 | //TG4ElementTable::Instance(); |
62 | } |
63 | |
64 | TG4GeometryManager::TG4GeometryManager(const TG4GeometryManager& right) { |
65 | // |
66 | TG4Globals::Exception( |
67 | "Attempt to copy TG4GeometryManager singleton."); |
68 | } |
69 | |
70 | |
71 | TG4GeometryManager::~TG4GeometryManager() { |
72 | // |
73 | delete fOutputManager; |
154fc5a5 |
74 | delete fGeometryServices; |
2817d3e2 |
75 | } |
76 | |
77 | //==================================================================== ========= |
78 | // |
79 | // operators |
80 | // |
81 | //==================================================================== ========= |
82 | |
83 | TG4GeometryManager& |
84 | TG4GeometryManager::operator=(const TG4GeometryManager& right) |
85 | { |
86 | // check assignement to self |
87 | if (this == &right) return *this; |
88 | |
89 | TG4Globals::Exception( |
90 | "Attempt to assign TG4GeometryManager singleton."); |
91 | |
92 | return *this; |
93 | } |
94 | |
95 | |
96 | //============================================================================= |
97 | // |
98 | // private methods |
99 | // |
100 | //============================================================================= |
101 | |
102 | |
f1bdb708 |
103 | void TG4GeometryManager::GstparCut(G4int itmed, TG4G3Cut par, G4double parval) |
2817d3e2 |
104 | { |
105 | // Sets special tracking medium parameter. |
106 | // It is applied to all logical volumes that use the specified |
107 | // tracking medium. |
108 | // --- |
109 | |
110 | // get medium from table |
111 | G3MedTableEntry* medium = G3Med.get(itmed); |
112 | if (!medium) { |
113 | G4String text = "TG4GeometryManager::GstparCut: \n"; |
114 | text = text + " Medium not found."; |
115 | G4Exception(text); |
116 | } |
117 | |
118 | // get/create user limits |
119 | G4UserLimits* limits = medium->GetLimits(); |
120 | TG4Limits* tg4Limits; |
121 | if (limits) { |
122 | tg4Limits = dynamic_cast<TG4Limits*> (limits); |
123 | if (!tg4Limits) |
124 | G4Exception("TG4GeometryManager::GstparCut: Wrong limits type."); |
125 | } |
738dfd5f |
126 | else { |
2817d3e2 |
127 | tg4Limits = new TG4Limits(); |
128 | medium->SetLimits(tg4Limits); |
738dfd5f |
129 | |
2817d3e2 |
130 | // add verbose |
131 | G4cout << "TG4GeometryManager::GstparCut: new TG4Limits() for medium " |
3c7cd15a |
132 | << itmed << " has been created." << G4endl; |
2817d3e2 |
133 | } |
134 | // set parameter |
135 | tg4Limits->SetG3Cut(par, parval*GeV); |
136 | } |
137 | |
138 | |
f1bdb708 |
139 | void TG4GeometryManager::GstparControl(G4int itmed, TG4G3Control par, |
140 | G4double parval) |
2817d3e2 |
141 | { |
142 | // Sets special tracking medium parameter. |
143 | // It is applied to all logical volumes that use the specified |
144 | // tracking medium. |
145 | // --- |
146 | |
147 | // get medium from table |
148 | G3MedTableEntry* medium = G3Med.get(itmed); |
149 | if (!medium) { |
f1bdb708 |
150 | G4String text = "TG4GeometryManager::GstparControl: \n"; |
2817d3e2 |
151 | text = text + " Medium not found."; |
152 | G4Exception(text); |
153 | } |
154 | |
155 | // get/create user limits |
156 | G4UserLimits* limits = medium->GetLimits(); |
157 | TG4Limits* tg4Limits; |
158 | if (limits) { |
159 | tg4Limits = dynamic_cast<TG4Limits*> (limits); |
160 | if (!tg4Limits) |
f1bdb708 |
161 | G4Exception("TG4GeometryManager::GstparControl: Wrong limits type."); |
2817d3e2 |
162 | } |
163 | else { |
164 | tg4Limits = new TG4Limits(); |
165 | medium->SetLimits(tg4Limits); |
738dfd5f |
166 | |
2817d3e2 |
167 | // add verbose |
f1bdb708 |
168 | G4cout << "TG4GeometryManager::GstparControl: new TG4Limits() for medium" |
3c7cd15a |
169 | << itmed << " has been created." << G4endl; |
2817d3e2 |
170 | } |
171 | // set parameter |
f1bdb708 |
172 | tg4Limits->SetG3Control(par, parval); |
2817d3e2 |
173 | } |
174 | |
175 | |
176 | void TG4GeometryManager::FillMediumIdVector() |
177 | { |
178 | // The second index for materials (having its origin in |
179 | // G4 tracking media concept) is stored in a vector of G4int |
180 | // parallel to G4MaterialTable. |
181 | // --- |
182 | |
183 | // initialize vector |
184 | G4int nofMaterials = G4Material::GetNumberOfMaterials(); |
185 | G4int i; |
186 | for (i=0; i<nofMaterials; i++) |
187 | fMediumIdVector.push_back(0); |
188 | |
189 | // fill vector |
190 | for (i=0; i<fMediumCounter; i++) { |
191 | // material index (index in G4Material table) |
192 | G3MedTableEntry* mte = G3Med.get(i+1); |
193 | G4int materialIndex = mte->GetMaterial()->GetIndex(); |
194 | |
195 | // medium index (ID of G3MedTableEntry) |
196 | G4int mediumIndex = mte->GetID(); |
197 | |
198 | // store medium index in the vector |
199 | fMediumIdVector[materialIndex] = mediumIndex; |
200 | } |
201 | |
202 | // add verbose |
3c7cd15a |
203 | G4cout << "Total nof materials: " << nofMaterials << G4endl; |
204 | G4cout << "Total nof tracking medias: " << fMediumCounter << G4endl; |
2817d3e2 |
205 | } |
206 | |
207 | |
208 | //============================================================================= |
209 | // |
210 | // public methods - AliMC implementation |
211 | // |
212 | //============================================================================= |
213 | |
214 | |
215 | void TG4GeometryManager::Material(Int_t& kmat, const char* name, Float_t a, |
216 | Float_t z, Float_t dens, Float_t radl, Float_t absl, Float_t* buf, |
217 | Int_t nwbuf) |
218 | { |
219 | // Creates G4Material. |
220 | // !! Parameters radl, absl, buf, nwbuf are ignored in G4gsmate |
221 | // Comment: |
222 | // absl - this parameter is ignored by GEANT3, too |
223 | // --- |
224 | |
225 | kmat = ++fMaterialCounter; |
154fc5a5 |
226 | G4double* bufin = fGeometryServices->CreateG4doubleArray(buf, nwbuf); |
2817d3e2 |
227 | |
228 | // write token to the output file |
229 | if (fWriteGeometry) |
230 | fOutputManager->WriteGsmate(kmat, name, a, z, dens, radl, nwbuf, bufin); |
231 | |
232 | G4gsmate(kmat, name, a, z, dens, radl, nwbuf, bufin); |
233 | |
234 | delete [] bufin; |
235 | |
236 | if (nwbuf > 0) { |
237 | G4String matName = name; |
238 | G4String text |
239 | = "TG4GeometryManager: user defined parameters for material "; |
240 | text = text + matName; |
241 | text = text + " are ignored by Geant4."; |
242 | TG4Globals::Warning(text); |
243 | } |
244 | } |
245 | |
246 | |
247 | void TG4GeometryManager::Mixture(Int_t& kmat, const char *name, Float_t *a, |
248 | Float_t *z, Float_t dens, Int_t nlmat, Float_t *wmat) |
249 | { |
250 | // Creates G4Material composed of more elements. |
251 | // !! Parameters radl, absl, buf, nwbuf are ignored in G4gsmate |
252 | // Comment: |
253 | // absl - this parameter is ignored by GEANT3, too |
254 | // --- |
255 | |
256 | Int_t npar = abs(nlmat); |
154fc5a5 |
257 | G4double *ain = fGeometryServices->CreateG4doubleArray(a, npar); |
258 | G4double *zin = fGeometryServices->CreateG4doubleArray(z, npar); |
259 | G4double *wmatin = fGeometryServices->CreateG4doubleArray(wmat, npar); |
2817d3e2 |
260 | |
261 | kmat = ++fMaterialCounter; |
262 | |
263 | // write token to the output file |
264 | if (fWriteGeometry) |
265 | fOutputManager->WriteGsmixt(kmat, name, ain, zin, dens, nlmat, wmatin); |
266 | |
267 | G4gsmixt(kmat, name, ain, zin, dens, nlmat, wmatin); |
268 | |
269 | // !!! in Geant3: |
270 | // After a call with ratios by number (negative number of elements), |
271 | // the ratio array is changed to the ratio by weight, so all successive |
272 | // calls with the same array must specify the number of elements as |
273 | // positive |
274 | |
275 | // wmatin may be modified |
276 | for (G4int i=0; i<npar; i++) wmat[i] = wmatin[i]; |
277 | |
278 | delete [] ain; |
279 | delete [] zin; |
280 | delete [] wmatin; |
281 | } |
282 | |
283 | void TG4GeometryManager::Medium(Int_t& kmed, const char *name, Int_t nmat, |
284 | Int_t isvol, Int_t ifield, Float_t fieldm, Float_t tmaxfd, |
285 | Float_t stemax, Float_t deemax, Float_t epsil, |
286 | Float_t stmin, Float_t* ubuf, Int_t nbuf) |
287 | { |
288 | // Creates a temporary "medium" that is used for |
289 | // assigning corresponding parameters to G4 objects: |
290 | // NTMED is stored as a second material index; |
f1bdb708 |
291 | // ISVOL is used for builing G3SensVolVector; |
2817d3e2 |
292 | // STEMAX is passed in TG4Limits (if fUseG3TMLimits is set true); |
293 | // !! The other parameters (IFIELD, FIELDM, TMAXFD, DEEMAX, EPSIL, STMIN) |
294 | // are ignored by Geant4. |
295 | // --- |
296 | |
297 | // Geant3 desription: |
298 | // ================== |
299 | // NTMED Tracking medium number |
300 | // NAME Tracking medium name |
301 | // NMAT Material number |
302 | // ISVOL Sensitive volume flag |
303 | // IFIELD Magnetic field |
304 | // FIELDM Max. field value (Kilogauss) |
305 | // TMAXFD Max. angle due to field (deg/step) |
306 | // STEMAX Max. step allowed |
307 | // DEEMAX Max. fraction of energy lost in a step |
308 | // EPSIL Tracking precision (cm) |
309 | // STMIN Min. step due to continuos processes (cm) |
310 | // |
311 | // IFIELD = 0 if no magnetic field; IFIELD = -1 if user decision in GUSWIM; |
312 | // IFIELD = 1 if tracking performed with GRKUTA; IFIELD = 2 if tracking |
313 | // performed with GHELIX; IFIELD = 3 if tracking performed with GHELX3. |
314 | // --- |
315 | |
316 | kmed = ++fMediumCounter; |
317 | |
318 | // write token to the output file |
319 | if (fWriteGeometry) |
320 | fOutputManager->WriteGstmed(kmed, name, nmat, isvol, ifield, fieldm, tmaxfd, |
321 | stemax, deemax, epsil, stmin, 0, 0); |
322 | |
323 | G4gstmed(kmed, name, nmat, isvol, ifield, fieldm, tmaxfd, stemax, deemax, |
324 | epsil, stmin, 0, fUseG3TMLimits); |
325 | // !! instead of the nbuf argument the bool fIsG3Default is passed |
326 | |
327 | if (nbuf > 0) { |
328 | G4String medName = name; |
329 | G4String text |
330 | = "TG4GeometryManager: user defined parameters for medium "; |
331 | text = text + medName; |
332 | text = text + " are ignored by Geant4."; |
333 | TG4Globals::Warning(text); |
334 | } |
335 | } |
336 | |
337 | |
338 | void TG4GeometryManager::Matrix(Int_t& krot, Float_t thetaX, Float_t phiX, |
339 | Float_t thetaY, Float_t phiY, Float_t thetaZ, Float_t phiZ) |
340 | { |
341 | // Creates G4RotationMatrix. |
342 | // --- |
343 | |
344 | krot = ++fMatrixCounter; |
345 | |
346 | // write token to the output file |
347 | if (fWriteGeometry) |
348 | fOutputManager->WriteGsrotm(krot, thetaX, phiX, thetaY, phiY, thetaZ, phiZ); |
349 | |
350 | G4gsrotm(krot, thetaX, phiX, thetaY, phiY, thetaZ, phiZ); |
351 | } |
352 | |
353 | |
2817d3e2 |
354 | void TG4GeometryManager::Ggclos() |
355 | { |
356 | // Sets the top VTE in temporary G3 volume table. |
357 | // Close geometry output file (if fWriteGeometry is set true). |
358 | // |
359 | // Geant3 desription: |
360 | // ================== |
361 | // close out the geometry |
362 | // --- |
363 | |
364 | if (fWriteGeometry) fOutputManager->WriteGgclos(); |
365 | |
366 | G4ggclos(); |
367 | } |
368 | |
369 | |
370 | void TG4GeometryManager::Gfmate(Int_t imat, char *name, Float_t &a, |
371 | Float_t &z, Float_t &dens, Float_t &radl, Float_t &absl, |
372 | Float_t* ubuf, Int_t& nbuf) |
373 | { |
374 | // Geant3 desription: |
375 | // ================== |
376 | // Return parameters for material IMAT |
377 | // --- |
378 | |
379 | G4Material* material = G3Mat.get(imat); |
380 | |
381 | if (material) { |
382 | // to do: change this correctly |
383 | // !! unsafe conversion |
384 | const char* chName = material->GetName(); |
385 | name = (char*)chName; |
154fc5a5 |
386 | a = fGeometryServices->GetEffA(material); |
387 | z = fGeometryServices->GetEffZ(material); |
2817d3e2 |
388 | |
389 | dens = material->GetDensity(); |
f1bdb708 |
390 | dens /= TG4G3Units::MassDensity(); |
2817d3e2 |
391 | |
392 | radl = material->GetRadlen(); |
f1bdb708 |
393 | radl /= TG4G3Units::Length(); |
2817d3e2 |
394 | |
395 | // the following parameters are not defined in Geant4 |
396 | absl = 0.; |
397 | ubuf = 0; |
398 | nbuf = 0; |
399 | } |
400 | else { |
401 | TG4Globals::Exception( |
402 | "TG4GeometryManager::Gfmate: material has not been found."); |
403 | } |
404 | } |
405 | |
406 | |
407 | void TG4GeometryManager::Gstpar(Int_t itmed, const char *param, |
408 | Float_t parval) |
409 | { |
410 | // Passes the tracking medium parameter to TG4Limits. |
411 | // The tracking medium parameter is set only in case |
412 | // its value is different from the "global" physics setup. |
f1bdb708 |
413 | // (If: CheckCut/ControlWithG3Defaults is used checking |
2817d3e2 |
414 | // is performed with respect to G3 default values.) |
f1bdb708 |
415 | // When any cut/control parameter is set in limits |
2817d3e2 |
416 | // the physics manager is locked and the physics setup |
417 | // cannot be changed. |
418 | // Applying this TG4Limits to particles and physical |
419 | // processes is still in development. |
420 | // |
421 | // Geant3 desription: |
422 | // ================== |
423 | // To change the value of cut or mechanism "CHPAR" |
424 | // to a new value PARVAL for tracking medium ITMED |
425 | // The data structure JTMED contains the standard tracking |
426 | // parameters (CUTS and flags to control the physics processes) which |
427 | // are used by default for all tracking media. It is possible to |
428 | // redefine individually with GSTPAR any of these parameters for a |
429 | // given tracking medium. |
430 | // ITMED tracking medium number |
431 | // CHPAR is a character string (variable name) |
432 | // PARVAL must be given as a floating point. |
433 | // --- |
434 | |
435 | // write token to the output file |
436 | if (fWriteGeometry) |
437 | fOutputManager->WriteGstpar(itmed, param, parval); |
438 | |
f1bdb708 |
439 | // get G3 physics setup |
440 | TG4G3PhysicsManager* g3PhysicsManager = TG4G3PhysicsManager::Instance(); |
2817d3e2 |
441 | |
154fc5a5 |
442 | G4String name = fGeometryServices->CutName(param); |
f1bdb708 |
443 | TG4G3Cut cut; |
444 | if (g3PhysicsManager->CheckCutWithTheVector(name, parval, cut)) { |
445 | GstparCut(itmed, cut, parval); |
446 | g3PhysicsManager->Lock(); |
2817d3e2 |
447 | } |
448 | else { |
f1bdb708 |
449 | TG4G3Control control; |
450 | if (g3PhysicsManager->CheckControlWithTheVector(name, parval, control)) { |
451 | GstparControl(itmed, control, parval); |
452 | g3PhysicsManager->Lock(); |
2817d3e2 |
453 | } |
f1bdb708 |
454 | else if (cut==kNoG3Cuts && control==kNoG3Controls) { |
2817d3e2 |
455 | G4String text = "TG4GeometryManager::Gstpar:"; |
456 | text = text + name; |
457 | text = text + " parameter is not yet implemented."; |
458 | TG4Globals::Warning(text); |
459 | } |
460 | } |
461 | } |
462 | |
463 | |
ad390979 |
464 | void TG4GeometryManager::SetCerenkov(Int_t itmed, Int_t npckov, |
465 | Float_t* ppckov, Float_t* absco, Float_t* effic, |
466 | Float_t* rindex) |
2817d3e2 |
467 | { |
468 | // |
469 | // Geant3 desription: |
470 | // ================== |
471 | // |
472 | // Stores the tables for UV photon tracking in medium ITMED |
473 | // Please note that it is the user's responsability to |
474 | // provide all the coefficients: |
475 | // |
476 | // |
477 | // ITMED Tracking medium number |
478 | // NPCKOV Number of bins of each table |
479 | // PPCKOV Value of photon momentum (in GeV) |
480 | // ABSCO Absorbtion coefficients |
481 | // dielectric: absorbtion length in cm |
482 | // metals : absorbtion fraction (0<=x<=1) |
483 | // EFFIC Detection efficiency for UV photons |
484 | // RINDEX Refraction index (if=0 metal) |
485 | // --- |
486 | |
154fc5a5 |
487 | G4double* ppckovDbl = fGeometryServices->CreateG4doubleArray(ppckov, npckov); |
488 | G4double* abscoDbl = fGeometryServices->CreateG4doubleArray(absco, npckov); |
489 | G4double* efficDbl = fGeometryServices->CreateG4doubleArray(effic, npckov); |
490 | G4double* rindexDbl = fGeometryServices->CreateG4doubleArray(rindex, npckov); |
2817d3e2 |
491 | |
492 | // add units |
493 | G4int i; |
494 | for (i=0; i<npckov; i++) { |
f1bdb708 |
495 | ppckovDbl[i] = ppckovDbl[i]*TG4G3Units::Energy(); |
496 | abscoDbl[i] = abscoDbl[i]*TG4G3Units::Length(); |
2817d3e2 |
497 | } |
498 | |
499 | // create material properties table |
500 | G4MaterialPropertiesTable* table = new G4MaterialPropertiesTable(); |
501 | table->AddProperty("ABSLENGTH", ppckovDbl, abscoDbl, npckov); |
502 | // used in G4OpAbsorption process |
503 | table->AddProperty("EFFICIENCY", ppckovDbl, efficDbl, npckov); |
504 | // used in G4OpBoundary process |
505 | table->AddProperty("RINDEX", ppckovDbl, rindexDbl, npckov); |
506 | // used in G4Cerenkov, G4OpRayleigh, G4OpBoundary |
507 | |
508 | // get material of medium from table |
509 | G3MedTableEntry* medium = G3Med.get(itmed); |
510 | if (!medium) { |
ad390979 |
511 | G4String text = "TG4GeometryManager::SetCerenkov: \n"; |
2817d3e2 |
512 | text = text + " Medium not found."; |
513 | G4Exception(text); |
514 | } |
515 | G4Material* material = medium->GetMaterial(); |
516 | |
517 | // set material properties table |
518 | material->SetMaterialPropertiesTable(table); |
519 | |
520 | G4cout << "The tables for UV photon tracking set for " |
3c7cd15a |
521 | << material->GetName() << G4endl; |
2817d3e2 |
522 | for (i=0; i<npckov; i++) |
3c7cd15a |
523 | G4cout << ppckovDbl[i] << " " << rindexDbl[i] << G4endl; |
2817d3e2 |
524 | |
525 | delete ppckovDbl; |
526 | delete abscoDbl; |
527 | delete efficDbl; |
528 | delete rindexDbl; |
529 | } |
530 | |
531 | |
532 | void TG4GeometryManager::Gsdvn(const char *name, const char *mother, |
533 | Int_t ndiv, Int_t iaxis) |
534 | { |
535 | // Geant3 desription: |
536 | // ================== |
537 | // NAME Volume name |
538 | // MOTHER Mother volume name |
539 | // NDIV Number of divisions |
540 | // IAXIS Axis value |
541 | // |
542 | // X,Y,Z of CAXIS will be translated to 1,2,3 for IAXIS. |
543 | // It divides a previously defined volume. |
544 | // --- |
545 | |
546 | // write token to the output file |
547 | if (fWriteGeometry) |
548 | fOutputManager->WriteGsdvn(name, mother, ndiv, iaxis); |
549 | |
154fc5a5 |
550 | G4gsdvn(fGeometryServices->CutName(name), |
551 | fGeometryServices->CutName(mother), ndiv, iaxis); |
2817d3e2 |
552 | |
553 | // register name in name map |
154fc5a5 |
554 | fNameMap.AddName(fGeometryServices->CutName(name)); |
2817d3e2 |
555 | } |
556 | |
557 | |
558 | void TG4GeometryManager::Gsdvn2(const char *name, const char *mother, |
559 | Int_t ndiv, Int_t iaxis, Float_t c0i, Int_t numed) |
560 | { |
561 | // Geant3 desription: |
562 | // ================== |
563 | // DIVIDES MOTHER INTO NDIV DIVISIONS CALLED NAME |
564 | // ALONG AXIS IAXIS STARTING AT COORDINATE VALUE C0. |
565 | // THE NEW VOLUME CREATED WILL BE MEDIUM NUMBER NUMED. |
566 | // --- |
567 | |
568 | // write token to the output file |
569 | if (fWriteGeometry) |
570 | fOutputManager->WriteGsdvn2(name, mother, ndiv, iaxis, c0i, numed); |
571 | |
154fc5a5 |
572 | G4gsdvn2(fGeometryServices->CutName(name), |
573 | fGeometryServices->CutName(mother), ndiv, iaxis, c0i, numed); |
2817d3e2 |
574 | |
575 | // register name in name map |
154fc5a5 |
576 | fNameMap.AddName(fGeometryServices->CutName(name)); |
2817d3e2 |
577 | } |
578 | |
579 | |
580 | void TG4GeometryManager::Gsdvt(const char *name, const char *mother, |
581 | Float_t step, Int_t iaxis, Int_t numed, Int_t ndvmx) |
582 | { |
583 | // Geant3 desription: |
584 | // ================== |
585 | // Divides MOTHER into divisions called NAME along |
586 | // axis IAXIS in steps of STEP. If not exactly divisible |
587 | // will make as many as possible and will centre them |
588 | // with respect to the mother. Divisions will have medium |
589 | // number NUMED. If NUMED is 0, NUMED of MOTHER is taken. |
590 | // NDVMX is the expected maximum number of divisions |
591 | // (If 0, no protection tests are performed) |
592 | // --- |
593 | |
594 | // write token to the output file |
595 | if (fWriteGeometry) |
596 | fOutputManager->WriteGsdvt(name, mother, step, iaxis, numed, ndvmx); |
597 | |
154fc5a5 |
598 | G4gsdvt(fGeometryServices->CutName(name), |
599 | fGeometryServices->CutName(mother), step, iaxis, numed, ndvmx); |
2817d3e2 |
600 | |
601 | // register name in name map |
154fc5a5 |
602 | fNameMap.AddName(fGeometryServices->CutName(name)); |
2817d3e2 |
603 | } |
604 | |
605 | |
606 | void TG4GeometryManager::Gsdvt2(const char *name, const char *mother, |
607 | Float_t step, Int_t iaxis, Float_t c0, Int_t numed, Int_t ndvmx) |
608 | { |
609 | // Geant3 desription: |
610 | // ================== |
611 | // Create a new volume by dividing an existing one |
612 | // |
613 | // Divides MOTHER into divisions called NAME along |
614 | // axis IAXIS starting at coordinate value C0 with step |
615 | // size STEP. |
616 | // The new volume created will have medium number NUMED. |
617 | // If NUMED is 0, NUMED of mother is taken. |
618 | // NDVMX is the expected maximum number of divisions |
619 | // (If 0, no protection tests are performed) |
620 | // --- |
621 | |
622 | // write token to the output file |
623 | if (fWriteGeometry) |
624 | fOutputManager->WriteGsdvt2(name, mother, step, iaxis, c0, numed, ndvmx); |
625 | |
154fc5a5 |
626 | G4gsdvt2(fGeometryServices->CutName(name), |
627 | fGeometryServices->CutName(mother), step, iaxis, c0, numed, ndvmx); |
2817d3e2 |
628 | |
629 | // register name in name map |
154fc5a5 |
630 | fNameMap.AddName(fGeometryServices->CutName(name)); |
2817d3e2 |
631 | } |
632 | |
633 | |
634 | void TG4GeometryManager::Gsord(const char *name, Int_t iax) |
635 | { |
636 | // No corresponding action in G4. |
637 | // |
638 | // Geant3 desription: |
639 | // ================== |
640 | // Flags volume CHNAME whose contents will have to be ordered |
641 | // along axis IAX, by setting the search flag to -IAX |
642 | // IAX = 1 X axis |
643 | // IAX = 2 Y axis |
644 | // IAX = 3 Z axis |
645 | // IAX = 4 Rxy (static ordering only -> GTMEDI) |
646 | // IAX = 14 Rxy (also dynamic ordering -> GTNEXT) |
647 | // IAX = 5 Rxyz (static ordering only -> GTMEDI) |
648 | // IAX = 15 Rxyz (also dynamic ordering -> GTNEXT) |
649 | // IAX = 6 PHI (PHI=0 => X axis) |
650 | // IAX = 7 THETA (THETA=0 => Z axis) |
651 | // --- |
652 | |
653 | TG4Globals::Warning("TG4GeometryManager::Gsord: dummy method."); |
654 | } |
655 | |
656 | |
657 | void TG4GeometryManager::Gspos(const char *vname, Int_t num, |
658 | const char *vmoth, Float_t x, Float_t y, Float_t z, Int_t irot, |
659 | const char *vonly) |
660 | { |
661 | // Geant3 desription: |
662 | // ================== |
663 | // Position a volume into an existing one |
664 | // |
665 | // NAME Volume name |
666 | // NUMBER Copy number of the volume |
667 | // MOTHER Mother volume name |
668 | // X X coord. of the volume in mother ref. sys. |
669 | // Y Y coord. of the volume in mother ref. sys. |
670 | // Z Z coord. of the volume in mother ref. sys. |
671 | // IROT Rotation matrix number w.r.t. mother ref. sys. |
672 | // ONLY ONLY/MANY flag |
673 | // |
674 | // It positions a previously defined volume in the mother. |
675 | // --- |
676 | |
677 | // write token to the output file |
678 | if (fWriteGeometry) |
679 | fOutputManager->WriteGspos(vname, num, vmoth, x, y, z, irot, vonly); |
680 | |
154fc5a5 |
681 | G4gspos(fGeometryServices->CutName(vname), num, |
682 | fGeometryServices->CutName(vmoth), x, y, z, irot, vonly); |
2817d3e2 |
683 | |
684 | // register name in name map |
154fc5a5 |
685 | fNameMap.AddName(fGeometryServices->CutName(vname)); |
2817d3e2 |
686 | } |
687 | |
688 | |
689 | void TG4GeometryManager::Gsposp(const char *name, Int_t nr, |
690 | const char *mother, Float_t x, Float_t y, Float_t z, Int_t irot, |
691 | const char *konly, Float_t *upar, Int_t np ) |
692 | { |
693 | // Geant3 desription: |
694 | // ================== |
695 | // Place a copy of generic volume NAME with user number |
696 | // NR inside MOTHER, with its parameters UPAR(1..NP) |
697 | // --- |
698 | |
154fc5a5 |
699 | G4double* parin = fGeometryServices->CreateG4doubleArray(upar, np); |
2817d3e2 |
700 | |
701 | // write token to the output file |
702 | if (fWriteGeometry) |
703 | fOutputManager->WriteGsposp(name, nr, mother, x, y, z, irot, konly, parin, np); |
704 | |
154fc5a5 |
705 | G4gsposp(fGeometryServices->CutName(name), nr, |
706 | fGeometryServices->CutName(mother), x, y, z, irot, konly, |
2817d3e2 |
707 | parin, np); |
708 | |
709 | delete [] parin; |
710 | |
711 | // register name in name map |
154fc5a5 |
712 | fNameMap.AddName(fGeometryServices->CutName(name)); |
2817d3e2 |
713 | } |
714 | |
715 | |
716 | Int_t TG4GeometryManager::Gsvolu(const char *name, const char *shape, |
717 | Int_t nmed, Float_t *upar, Int_t npar) |
718 | { |
719 | // Geant3 desription: |
720 | // ================== |
721 | // NAME Volume name |
722 | // SHAPE Volume type |
723 | // NUMED Tracking medium number |
724 | // NPAR Number of shape parameters |
725 | // UPAR Vector containing shape parameters |
726 | // |
727 | // It creates a new volume in the JVOLUM data structure. |
728 | // --- |
729 | |
154fc5a5 |
730 | G4double* parin = fGeometryServices->CreateG4doubleArray(upar, npar); |
2817d3e2 |
731 | |
732 | // write token to the output file |
733 | if (fWriteGeometry) |
734 | fOutputManager->WriteGsvolu(name, shape, nmed, parin, npar); |
735 | |
154fc5a5 |
736 | G4gsvolu(fGeometryServices->CutName(name), |
737 | fGeometryServices->CutName(shape), nmed, parin, npar); |
2817d3e2 |
738 | |
739 | delete [] parin; |
740 | |
741 | // register name in name map |
154fc5a5 |
742 | fNameMap.AddName(fGeometryServices->CutName(name)); |
2817d3e2 |
743 | |
744 | return 0; |
745 | } |
746 | |
747 | |
57f88f6f |
748 | void TG4GeometryManager::WriteEuclid(const char* fileName, |
749 | const char* topVolName, Int_t number, Int_t nlevel) |
2817d3e2 |
750 | { |
751 | // Geant3 desription: |
752 | // ================== |
753 | // |
754 | // ****************************************************************** |
755 | // * * |
756 | // * Write out the geometry of the detector in EUCLID file format * |
757 | // * * |
758 | // * filnam : will be with the extension .euc * |
759 | // * topvol : volume name of the starting node * |
760 | // * number : copy number of topvol (relevant for gsposp) * |
761 | // * nlevel : number of levels in the tree structure * |
762 | // * to be written out, starting from topvol * |
763 | // * * |
764 | // * Author : M. Maire * |
765 | // * * |
766 | // ****************************************************************** |
767 | // |
768 | // File filnam.tme is written out with the definitions of tracking |
769 | // medias and materials. |
770 | // As to restore original numbers for materials and medias, program |
771 | // searches in the file euc_medi.dat and comparing main parameters of |
772 | // the mat. defined inside geant and the one in file recognizes them |
773 | // and is able to take number from file. If for any material or medium, |
774 | // this procedure fails, ordering starts from 1. |
775 | // Arrays IOTMED and IOMATE are used for this procedure |
776 | // --- |
777 | |
778 | TG4Globals::Warning( |
779 | "TG4GeometryManager::WriteEuclid(..) is not yet implemented."); |
780 | } |
781 | |
782 | |
783 | Int_t TG4GeometryManager::VolId(const Text_t* volName) const |
784 | { |
785 | // Returns the sensitive detector identifier. |
2817d3e2 |
786 | // --- |
787 | |
154fc5a5 |
788 | return fGeometryServices->GetVolumeID(volName); |
2817d3e2 |
789 | } |
790 | |
791 | |
792 | const char* TG4GeometryManager::VolName(Int_t id) const |
793 | { |
794 | // Returns the name of the sensitive detector with the given identifier. |
2817d3e2 |
795 | // --- |
796 | |
154fc5a5 |
797 | return fGeometryServices->GetVolumeName(id); |
2817d3e2 |
798 | } |
799 | |
800 | |
801 | Int_t TG4GeometryManager::NofVolumes() const |
802 | { |
803 | // Returns the total number of sensitive detectors. |
804 | // --- |
805 | |
154fc5a5 |
806 | return fGeometryServices->NofSensitiveDetectors(); |
2817d3e2 |
807 | } |
808 | |
809 | |
154fc5a5 |
810 | Int_t TG4GeometryManager::VolId2Mate(Int_t volumeId) const |
2817d3e2 |
811 | { |
154fc5a5 |
812 | // Return the material number for a given volume id |
2817d3e2 |
813 | // --- |
814 | |
154fc5a5 |
815 | return fGeometryServices->GetMediumId(volumeId); |
2817d3e2 |
816 | } |
2817d3e2 |
817 | |
154fc5a5 |
818 | |
2817d3e2 |
819 | //============================================================================= |
820 | // |
821 | // public methods - Geant4 only |
822 | // |
823 | //============================================================================= |
824 | |
825 | |
826 | G4VPhysicalVolume* TG4GeometryManager::CreateG4Geometry() |
827 | { |
828 | // Creates G4 geometry objects according to the G3VolTable |
829 | // and returns the top physical volume in case it was created |
830 | // (return zero otherwise). |
831 | // --- |
832 | |
833 | // set the first entry in the G3Vol table |
834 | Ggclos(); |
835 | G3VolTableEntry* first = G3Vol.GetFirstVTE(); |
2817d3e2 |
836 | |
837 | // create G4 geometry |
838 | G3toG4BuildTree(first,0); |
839 | |
840 | // print G3 volume table statistics |
841 | G3Vol.VTEStat(); |
842 | |
843 | // print G4 geometry statistics |
844 | G4cout << "G4 Stat: instantiated " |
154fc5a5 |
845 | << fGeometryServices->NofG4LogicalVolumes() |
846 | << " logical volumes \n" |
2817d3e2 |
847 | << " " |
154fc5a5 |
848 | << fGeometryServices->NofG4PhysicalVolumes() |
849 | << " physical volumes" << G4endl; |
2817d3e2 |
850 | |
851 | // position the first entry |
852 | // (in Geant3 the top volume cannot be positioned) |
853 | // |
854 | G4VPhysicalVolume* top = 0; |
855 | if (first->GetLV()->GetNoDaughters() == 0) { |
856 | top = new G4PVPlacement(0, G4ThreeVector(), first->GetName(), |
857 | first->GetLV(), 0, false, 0); |
858 | } |
859 | return top; |
860 | } |
861 | |
862 | |
154fc5a5 |
863 | void TG4GeometryManager::ReadG3Geometry(G4String filePath) |
864 | { |
865 | // Processes g3calls.dat file and fills G3 tables. |
866 | // --- |
867 | |
868 | // add verbose |
869 | G4cout << "Reading the call list file " << filePath << "..." << G4endl; |
870 | G3CLRead(filePath, NULL); |
871 | G4cout << "Call list file read completed. Build geometry" << G4endl; |
872 | } |
873 | |
874 | |
2817d3e2 |
875 | void TG4GeometryManager::UseG3TrackingMediaLimits() |
876 | { |
877 | // Sets fUseG3TMLimits option. |
878 | // !! This method has to be called only before starting |
879 | // creating geometry. |
880 | // --- |
881 | |
882 | if (fMediumCounter == 0) { |
883 | fUseG3TMLimits = true; |
884 | } |
885 | else { |
886 | G4String text = "TG4GeometryManager::UseG3TMLimits: \n"; |
887 | text = text + " It is too late to set G3 defaults. \n"; |
888 | text = text + " Some media has been already processed."; |
889 | TG4Globals::Exception(text); |
890 | } |
891 | } |
892 | |
893 | |
894 | void TG4GeometryManager::ClearG3Tables() |
895 | { |
896 | // Clears G3 volumes, materials, rotations(?) tables |
897 | // and sensitive volumes vector. |
898 | // The top volume is kept in the vol table. |
899 | // --- |
900 | |
901 | // clear volume table |
902 | // but keep the top volume in the table |
903 | G3VolTableEntry* top = G3Vol.GetFirstVTE(); |
904 | G4String name = top->GetName(); |
905 | G4String shape = top->GetShape(); |
906 | G3VolTableEntry* keep |
907 | = new G3VolTableEntry(name, shape, top->GetRpar(), top->GetNpar(), |
908 | top->GetNmed(), top->GetSolid(), false); |
909 | keep->SetLV(top->GetLV()); |
910 | G3Vol.Clear(); |
911 | G3Vol.PutVTE(keep); |
912 | |
913 | // clear other tables |
914 | G3Mat.Clear(); |
915 | //G3Rot.Clear(); |
916 | G3SensVol.clear(); |
917 | } |
918 | |
919 | |
920 | void TG4GeometryManager::ClearG3TablesFinal() |
921 | { |
922 | // Clears G3 medias and volumes tables |
923 | // (the top volume is removed from the vol table) |
924 | // --- |
925 | |
2817d3e2 |
926 | G3Med.Clear(); |
927 | G3Vol.Clear(); |
928 | |
929 | // reset medium counter |
930 | //fMaterialCounter = 0; |
931 | fMediumCounter = 0; |
932 | } |
933 | |
934 | |
935 | void TG4GeometryManager::OpenOutFile(G4String filePath) |
936 | { |
937 | // Opens output file. |
938 | // --- |
939 | |
940 | fOutputManager->OpenFile(filePath); |
941 | } |
942 | |
943 | |
08b8559d |
944 | void TG4GeometryManager::CloseOutFile() |
945 | { |
946 | // Closes output file. |
947 | // --- |
948 | |
949 | fOutputManager->CloseFile(); |
950 | } |
951 | |
952 | |
2817d3e2 |
953 | void TG4GeometryManager::PrintNameMap() |
954 | { |
955 | // Prints the map of volumes names to second names. |
956 | // --- |
957 | |
958 | fNameMap.PrintAll(); |
959 | } |
960 | |
961 | |
962 | void TG4GeometryManager::SetWriteGeometry(G4bool writeGeometry) |
963 | { |
964 | // Controls geometry output. |
965 | // --- |
966 | |
967 | fWriteGeometry = writeGeometry; |
968 | } |
969 | |
970 | |
971 | void TG4GeometryManager::SetMapSecond(const G4String& name) |
972 | { |
973 | // Sets the second name for the map of volumes names. |
974 | // --- |
975 | |
976 | fNameMap.SetSecond(name); |
977 | } |