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