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