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