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