]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TGeant4/TG4GeometryManager.cxx
set of methods moved to a new class TG4GeometryServices; added fGeometryServices...
[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::Gsckov(Int_t itmed, Int_t npckov, Float_t* ppckov,
464                          Float_t* absco, Float_t* effic, Float_t* rindex)
465 {
466 //
467 //  Geant3 desription:
468 //  ==================
469 //
470 //    Stores the tables for UV photon tracking in medium ITMED 
471 //    Please note that it is the user's responsability to 
472 //    provide all the coefficients:
473 //
474 //
475 //       ITMED       Tracking medium number
476 //       NPCKOV      Number of bins of each table
477 //       PPCKOV      Value of photon momentum (in GeV)
478 //       ABSCO       Absorbtion coefficients 
479 //                   dielectric: absorbtion length in cm
480 //                   metals    : absorbtion fraction (0<=x<=1)
481 //       EFFIC       Detection efficiency for UV photons 
482 //       RINDEX      Refraction index (if=0 metal)
483 // ---
484
485   G4double* ppckovDbl = fGeometryServices->CreateG4doubleArray(ppckov, npckov); 
486   G4double* abscoDbl  = fGeometryServices->CreateG4doubleArray(absco, npckov); 
487   G4double* efficDbl  = fGeometryServices->CreateG4doubleArray(effic, npckov); 
488   G4double* rindexDbl = fGeometryServices->CreateG4doubleArray(rindex, npckov); 
489   
490   // add units
491   G4int i;
492   for (i=0; i<npckov; i++) {
493     ppckovDbl[i] = ppckovDbl[i]*TG3Units::Energy();
494     abscoDbl[i]  = abscoDbl[i]*TG3Units::Length();
495   }  
496
497   // create material properties table
498   G4MaterialPropertiesTable* table = new G4MaterialPropertiesTable(); 
499   table->AddProperty("ABSLENGTH", ppckovDbl, abscoDbl, npckov);
500                     // used in G4OpAbsorption process
501   table->AddProperty("EFFICIENCY", ppckovDbl, efficDbl, npckov);
502                     // used in G4OpBoundary process
503   table->AddProperty("RINDEX", ppckovDbl, rindexDbl, npckov);
504                     // used in G4Cerenkov, G4OpRayleigh, G4OpBoundary
505
506   // get material of medium from table
507   G3MedTableEntry* medium = G3Med.get(itmed);
508   if (!medium) {
509     G4String text = "TG4GeometryManager::Gsckov: \n";
510     text = text + "    Medium not found."; 
511     G4Exception(text);
512   }  
513   G4Material* material = medium->GetMaterial();
514   
515   // set material properties table 
516   material->SetMaterialPropertiesTable(table);
517
518   G4cout << "The tables for UV photon tracking set for "
519          << material->GetName() << G4endl;
520   for (i=0; i<npckov; i++)
521     G4cout << ppckovDbl[i] << " " << rindexDbl[i] << G4endl;
522          
523   delete ppckovDbl;
524   delete abscoDbl;
525   delete efficDbl;
526   delete rindexDbl;      
527 }                        
528
529  
530 void  TG4GeometryManager::Gsdvn(const char *name, const char *mother, 
531            Int_t ndiv, Int_t iaxis) 
532
533 //  Geant3 desription:
534 //  ==================
535 //  NAME   Volume name
536 //  MOTHER Mother volume name
537 //  NDIV   Number of divisions
538 //  IAXIS  Axis value
539 //
540 //  X,Y,Z of CAXIS will be translated to 1,2,3 for IAXIS.
541 //  It divides a previously defined volume.
542 //  ---
543
544     // write token to the output file
545     if (fWriteGeometry) 
546       fOutputManager->WriteGsdvn(name, mother, ndiv, iaxis);
547
548     G4gsdvn(fGeometryServices->CutName(name), 
549             fGeometryServices->CutName(mother), ndiv, iaxis);
550
551     // register name in name map
552     fNameMap.AddName(fGeometryServices->CutName(name));
553
554  
555  
556 void  TG4GeometryManager::Gsdvn2(const char *name, const char *mother, 
557            Int_t ndiv, Int_t iaxis, Float_t c0i, Int_t numed) 
558
559 //  Geant3 desription:
560 //  ==================
561 //  DIVIDES MOTHER INTO NDIV DIVISIONS CALLED NAME
562 //  ALONG AXIS IAXIS STARTING AT COORDINATE VALUE C0.
563 //  THE NEW VOLUME CREATED WILL BE MEDIUM NUMBER NUMED.
564 // ---
565
566     // write token to the output file
567     if (fWriteGeometry) 
568       fOutputManager->WriteGsdvn2(name, mother, ndiv, iaxis, c0i, numed);
569
570     G4gsdvn2(fGeometryServices->CutName(name),
571              fGeometryServices->CutName(mother), ndiv, iaxis, c0i, numed);
572
573     // register name in name map
574     fNameMap.AddName(fGeometryServices->CutName(name));
575
576  
577  
578 void  TG4GeometryManager::Gsdvt(const char *name, const char *mother, 
579            Float_t step, Int_t iaxis, Int_t numed, Int_t ndvmx)
580
581 //  Geant3 desription:
582 //  ==================
583 //       Divides MOTHER into divisions called NAME along
584 //       axis IAXIS in steps of STEP. If not exactly divisible 
585 //       will make as many as possible and will centre them 
586 //       with respect to the mother. Divisions will have medium 
587 //       number NUMED. If NUMED is 0, NUMED of MOTHER is taken.
588 //       NDVMX is the expected maximum number of divisions
589 //          (If 0, no protection tests are performed) 
590 // ---
591
592     // write token to the output file
593     if (fWriteGeometry) 
594       fOutputManager->WriteGsdvt(name, mother, step, iaxis, numed, ndvmx);
595
596     G4gsdvt(fGeometryServices->CutName(name), 
597             fGeometryServices->CutName(mother), step, iaxis, numed, ndvmx);
598
599     // register name in name map
600     fNameMap.AddName(fGeometryServices->CutName(name));
601
602  
603  
604 void  TG4GeometryManager::Gsdvt2(const char *name, const char *mother, 
605            Float_t step, Int_t iaxis, Float_t c0, Int_t numed, Int_t ndvmx)
606
607 //  Geant3 desription:
608 //  ==================
609 // Create a new volume by dividing an existing one
610 //                                                                    
611 //           Divides MOTHER into divisions called NAME along          
612 //            axis IAXIS starting at coordinate value C0 with step    
613 //            size STEP.                                              
614 //           The new volume created will have medium number NUMED.    
615 //           If NUMED is 0, NUMED of mother is taken.                 
616 //           NDVMX is the expected maximum number of divisions        
617 //             (If 0, no protection tests are performed)              
618 // ---
619
620     // write token to the output file
621     if (fWriteGeometry) 
622       fOutputManager->WriteGsdvt2(name, mother, step, iaxis, c0, numed, ndvmx);
623
624     G4gsdvt2(fGeometryServices->CutName(name), 
625              fGeometryServices->CutName(mother), step, iaxis, c0, numed, ndvmx);
626
627     // register name in name map
628     fNameMap.AddName(fGeometryServices->CutName(name));
629
630  
631  
632 void  TG4GeometryManager::Gsord(const char *name, Int_t iax) 
633
634 // No corresponding action in G4.
635 //
636 //  Geant3 desription:
637 //  ==================
638 //    Flags volume CHNAME whose contents will have to be ordered 
639 //    along axis IAX, by setting the search flag to -IAX
640 //           IAX = 1    X axis 
641 //           IAX = 2    Y axis 
642 //           IAX = 3    Z axis 
643 //           IAX = 4    Rxy (static ordering only  -> GTMEDI)
644 //           IAX = 14   Rxy (also dynamic ordering -> GTNEXT)
645 //           IAX = 5    Rxyz (static ordering only -> GTMEDI)
646 //           IAX = 15   Rxyz (also dynamic ordering -> GTNEXT)
647 //           IAX = 6    PHI   (PHI=0 => X axis)
648 //           IAX = 7    THETA (THETA=0 => Z axis)
649 // ---
650
651   TG4Globals::Warning("TG4GeometryManager::Gsord: dummy method.");
652
653  
654  
655 void  TG4GeometryManager::Gspos(const char *vname, Int_t num, 
656           const char *vmoth, Float_t x, Float_t y, Float_t z, Int_t irot, 
657           const char *vonly) 
658
659 //  Geant3 desription:
660 //  ==================
661 // Position a volume into an existing one
662 //
663 //  NAME   Volume name
664 //  NUMBER Copy number of the volume
665 //  MOTHER Mother volume name
666 //  X      X coord. of the volume in mother ref. sys.
667 //  Y      Y coord. of the volume in mother ref. sys.
668 //  Z      Z coord. of the volume in mother ref. sys.
669 //  IROT   Rotation matrix number w.r.t. mother ref. sys.
670 //  ONLY   ONLY/MANY flag
671 //
672 //  It positions a previously defined volume in the mother.
673 // ---  
674
675    // write token to the output file
676    if (fWriteGeometry) 
677      fOutputManager->WriteGspos(vname, num, vmoth, x, y, z, irot, vonly);
678
679    G4gspos(fGeometryServices->CutName(vname), num,
680            fGeometryServices->CutName(vmoth), x, y, z, irot, vonly);
681
682    // register name in name map
683    fNameMap.AddName(fGeometryServices->CutName(vname));
684
685  
686  
687 void  TG4GeometryManager::Gsposp(const char *name, Int_t nr, 
688            const char *mother, Float_t x, Float_t y, Float_t z, Int_t irot, 
689            const char *konly, Float_t *upar, Int_t np ) 
690
691 //  Geant3 desription:
692 //  ==================
693 //      Place a copy of generic volume NAME with user number
694 //      NR inside MOTHER, with its parameters UPAR(1..NP)
695 // ---
696
697    G4double* parin = fGeometryServices->CreateG4doubleArray(upar, np); 
698
699    // write token to the output file
700    if (fWriteGeometry) 
701      fOutputManager->WriteGsposp(name, nr, mother, x, y, z, irot, konly, parin, np);
702
703    G4gsposp(fGeometryServices->CutName(name), nr, 
704             fGeometryServices->CutName(mother), x, y, z, irot, konly, 
705              parin, np);
706
707    delete [] parin;
708
709    // register name in name map
710    fNameMap.AddName(fGeometryServices->CutName(name));
711
712  
713  
714 Int_t TG4GeometryManager::Gsvolu(const char *name, const char *shape, 
715           Int_t nmed, Float_t *upar, Int_t npar) 
716
717 //  Geant3 desription:
718 //  ==================
719 //  NAME   Volume name
720 //  SHAPE  Volume type
721 //  NUMED  Tracking medium number
722 //  NPAR   Number of shape parameters
723 //  UPAR   Vector containing shape parameters
724 //
725 //  It creates a new volume in the JVOLUM data structure.
726 // ---  
727
728   G4double* parin = fGeometryServices->CreateG4doubleArray(upar, npar); 
729
730   // write token to the output file
731   if (fWriteGeometry) 
732     fOutputManager->WriteGsvolu(name, shape, nmed, parin, npar);    
733
734   G4gsvolu(fGeometryServices->CutName(name), 
735            fGeometryServices->CutName(shape), nmed, parin, npar);
736
737   delete [] parin;
738   
739   // register name in name map
740   fNameMap.AddName(fGeometryServices->CutName(name));
741
742   return 0;
743
744
745
746 void TG4GeometryManager::WriteEuclid(const char* fileName, 
747           const char* topVolName, Int_t number, Int_t nlevel)
748 {
749 //  Geant3 desription:
750 //  ==================
751 //
752 //     ******************************************************************
753 //     *                                                                *
754 //     *  Write out the geometry of the detector in EUCLID file format  *
755 //     *                                                                *
756 //     *       filnam : will be with the extension .euc                 *
757 //     *       topvol : volume name of the starting node                *
758 //     *       number : copy number of topvol (relevant for gsposp)     *
759 //     *       nlevel : number of  levels in the tree structure         *
760 //     *                to be written out, starting from topvol         *
761 //     *                                                                *
762 //     *       Author : M. Maire                                        *
763 //     *                                                                *
764 //     ******************************************************************
765 //
766 //     File filnam.tme is written out with the definitions of tracking
767 //     medias and materials.
768 //     As to restore original numbers for materials and medias, program
769 //     searches in the file euc_medi.dat and comparing main parameters of
770 //     the mat. defined inside geant and the one in file recognizes them
771 //     and is able to take number from file. If for any material or medium,
772 //     this procedure fails, ordering starts from 1.
773 //     Arrays IOTMED and IOMATE are used for this procedure
774 // ---
775
776   TG4Globals::Warning(
777     "TG4GeometryManager::WriteEuclid(..) is not yet implemented.");
778 }
779
780  
781 Int_t TG4GeometryManager::VolId(const Text_t* volName) const
782
783 // Returns the sensitive detector identifier.
784 // ---
785
786   return fGeometryServices->GetVolumeID(volName);
787 }
788
789
790 const char* TG4GeometryManager::VolName(Int_t id) const
791 {
792 // Returns the name of the sensitive detector with the given identifier.
793 // ---
794
795   return fGeometryServices->GetVolumeName(id);
796 }
797
798
799 Int_t TG4GeometryManager::NofVolumes() const
800 {
801 // Returns the total number of sensitive detectors.
802 // ---
803
804   return fGeometryServices->NofSensitiveDetectors();
805 }
806
807  
808 Int_t TG4GeometryManager::VolId2Mate(Int_t volumeId)  const
809 {
810 // Return the material number for a given volume id
811 // ---
812
813   return fGeometryServices->GetMediumId(volumeId);                       
814 }
815  
816
817 //=============================================================================
818 //
819 // public methods - Geant4 only
820 //
821 //=============================================================================
822
823  
824 G4VPhysicalVolume* TG4GeometryManager::CreateG4Geometry()
825 {
826 // Creates G4 geometry objects according to the G3VolTable 
827 // and returns the top physical volume in case it was created
828 // (return zero otherwise).
829 // ---
830
831   // set the first entry in the G3Vol table
832   Ggclos();
833   G3VolTableEntry* first = G3Vol.GetFirstVTE();
834
835   // create G4 geometry
836   G3toG4BuildTree(first,0);  
837
838   // print G3 volume table statistics
839   G3Vol.VTEStat();
840
841   // print G4 geometry statistics
842   G4cout << "G4 Stat: instantiated " 
843          << fGeometryServices->NofG4LogicalVolumes()  
844          << " logical volumes \n"
845          << "                      " 
846          << fGeometryServices->NofG4PhysicalVolumes() 
847          << " physical volumes" << G4endl;
848
849   // position the first entry 
850   // (in Geant3 the top volume cannot be positioned)
851   // 
852   G4VPhysicalVolume* top = 0;
853   if (first->GetLV()->GetNoDaughters() == 0) {
854     top = new G4PVPlacement(0, G4ThreeVector(), first->GetName(), 
855                             first->GetLV(), 0, false, 0);
856   }
857   return top;                 
858 }
859
860  
861 void TG4GeometryManager::ReadG3Geometry(G4String filePath)
862 {
863 // Processes g3calls.dat file and fills G3 tables.
864 // ---
865
866   // add verbose
867   G4cout << "Reading the call list file " << filePath << "..." << G4endl;
868   G3CLRead(filePath, NULL);
869   G4cout << "Call list file read completed. Build geometry" << G4endl;
870 }
871
872  
873 void TG4GeometryManager::UseG3TrackingMediaLimits()
874 {
875 // Sets fUseG3TMLimits option.
876 // !! This method has to be called only before starting
877 // creating geometry.
878 // ---
879
880   if (fMediumCounter == 0) {
881     fUseG3TMLimits = true;
882   }
883   else {
884     G4String text = "TG4GeometryManager::UseG3TMLimits: \n";
885     text = text + "    It is too late to set G3 defaults. \n";
886     text = text + "    Some media has been already processed.";
887     TG4Globals::Exception(text);
888   }
889 }
890
891  
892 void TG4GeometryManager::ClearG3Tables()
893
894 // Clears G3 volumes, materials, rotations(?) tables
895 // and sensitive volumes vector.
896 // The top volume is kept in the vol table.
897 // ---
898
899   // clear volume table 
900   // but keep the top volume in the table 
901   G3VolTableEntry* top = G3Vol.GetFirstVTE();
902   G4String name = top->GetName();
903   G4String shape = top->GetShape(); 
904   G3VolTableEntry* keep 
905     = new G3VolTableEntry(name, shape, top->GetRpar(), top->GetNpar(), 
906                            top->GetNmed(), top->GetSolid(), false);
907   keep->SetLV(top->GetLV());
908   G3Vol.Clear();  
909   G3Vol.PutVTE(keep);
910   
911   // clear other tables
912   G3Mat.Clear();
913   //G3Rot.Clear();
914   G3SensVol.clear(); 
915 }
916
917  
918 void TG4GeometryManager::ClearG3TablesFinal()
919 {
920 // Clears G3 medias and volumes tables
921 // (the top volume is removed from the vol table)
922 // ---
923
924   G3Med.Clear();
925   G3Vol.Clear();  
926
927   // reset medium counter
928   //fMaterialCounter = 0;
929   fMediumCounter = 0;  
930 }
931
932  
933 void TG4GeometryManager::OpenOutFile(G4String filePath)
934
935 // Opens output file.
936 // ---
937
938   fOutputManager->OpenFile(filePath);
939 }
940
941  
942 void TG4GeometryManager::CloseOutFile()
943
944 // Closes output file.
945 // ---
946
947   fOutputManager->CloseFile();
948 }
949
950  
951 void TG4GeometryManager::PrintNameMap()
952 {
953 // Prints the map of volumes names to second names.
954 // ---
955
956   fNameMap.PrintAll();
957 }
958
959  
960 void TG4GeometryManager::SetWriteGeometry(G4bool writeGeometry)
961
962 // Controls geometry output.
963 // ---
964
965   fWriteGeometry = writeGeometry; 
966 }
967
968  
969 void TG4GeometryManager::SetMapSecond(const G4String& name)
970 {
971 // Sets the second name for the map of volumes names.
972 // ---
973
974   fNameMap.SetSecond(name);
975 }