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