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