usage of TG4PhysicsManager changed to TG3PhysicsManager only; updated to renaming...
[u/mrichter/AliRoot.git] / TGeant4 / TG4GeometryManager.cxx
CommitLineData
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
37void G3CLRead(G4String &, char *);
38
39TG4GeometryManager* TG4GeometryManager::fgInstance = 0;
40
41TG4GeometryManager::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
64TG4GeometryManager::TG4GeometryManager(const TG4GeometryManager& right) {
65//
66 TG4Globals::Exception(
67 "Attempt to copy TG4GeometryManager singleton.");
68}
69
70
71TG4GeometryManager::~TG4GeometryManager() {
72//
73 delete fOutputManager;
154fc5a5 74 delete fGeometryServices;
2817d3e2 75}
76
77//==================================================================== =========
78//
79// operators
80//
81//==================================================================== =========
82
83TG4GeometryManager&
84TG4GeometryManager::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 103void 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 139void 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
176void 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
215void 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
247void 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
283void 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
338void 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 354void 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
370void 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
407void 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 464void 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
532void 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
558void 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
580void 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
606void 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
634void 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
657void 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
689void 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
716Int_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 748void 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
783Int_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
792const 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
801Int_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 810Int_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
826G4VPhysicalVolume* 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 863void 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 875void 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
894void 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
920void 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
935void TG4GeometryManager::OpenOutFile(G4String filePath)
936{
937// Opens output file.
938// ---
939
940 fOutputManager->OpenFile(filePath);
941}
942
943
08b8559d 944void TG4GeometryManager::CloseOutFile()
945{
946// Closes output file.
947// ---
948
949 fOutputManager->CloseFile();
950}
951
952
2817d3e2 953void TG4GeometryManager::PrintNameMap()
954{
955// Prints the map of volumes names to second names.
956// ---
957
958 fNameMap.PrintAll();
959}
960
961
962void TG4GeometryManager::SetWriteGeometry(G4bool writeGeometry)
963{
964// Controls geometry output.
965// ---
966
967 fWriteGeometry = writeGeometry;
968}
969
970
971void TG4GeometryManager::SetMapSecond(const G4String& name)
972{
973// Sets the second name for the map of volumes names.
974// ---
975
976 fNameMap.SetSecond(name);
977}