]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TGeant4/TG4GeometryManager.cxx
new method SetUserLimits() added
[u/mrichter/AliRoot.git] / TGeant4 / TG4GeometryManager.cxx
CommitLineData
2817d3e2 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"
154fc5a5 13#include "TG4GeometryServices.h"
2817d3e2 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
2817d3e2 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
2817d3e2 36// extern global method from g3tog4
37void G3CLRead(G4String &, char *);
38
39TG4GeometryManager* TG4GeometryManager::fgInstance = 0;
40
41TG4GeometryManager::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
154fc5a5 56 fGeometryServices = new TG4GeometryServices(&fMediumIdVector, &fNameMap);
57
2817d3e2 58 fgInstance = this;
59
60 // instantiate the default element table
61 //TG4ElementTable::Instance();
62}
63
64TG4GeometryManager::TG4GeometryManager(const TG4GeometryManager& right) {
65//
66 TG4Globals::Exception(
67 "Attempt to copy TG4GeometryManager singleton.");
68}
69
70
71TG4GeometryManager::~TG4GeometryManager() {
72//
73 delete fOutputManager;
154fc5a5 74 delete fGeometryServices;
2817d3e2 75}
76
77//==================================================================== =========
78//
79// operators
80//
81//==================================================================== =========
82
83TG4GeometryManager&
84TG4GeometryManager::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
2817d3e2 103void 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 "
3c7cd15a 131 << itmed << " has been created." << G4endl;
2817d3e2 132 }
133 // set parameter
134 tg4Limits->SetG3Cut(par, parval*GeV);
135}
136
137
138void 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 "
3c7cd15a 166 << itmed << " has been created." << G4endl;
2817d3e2 167 }
168 // set parameter
169 tg4Limits->SetG3Flag(par, parval);
170}
171
172
173void 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
3c7cd15a 200 G4cout << "Total nof materials: " << nofMaterials << G4endl;
201 G4cout << "Total nof tracking medias: " << fMediumCounter << G4endl;
2817d3e2 202}
203
204
205//=============================================================================
206//
207// public methods - AliMC implementation
208//
209//=============================================================================
210
211
212void 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;
154fc5a5 223 G4double* bufin = fGeometryServices->CreateG4doubleArray(buf, nwbuf);
2817d3e2 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
244void 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);
154fc5a5 254 G4double *ain = fGeometryServices->CreateG4doubleArray(a, npar);
255 G4double *zin = fGeometryServices->CreateG4doubleArray(z, npar);
256 G4double *wmatin = fGeometryServices->CreateG4doubleArray(wmat, npar);
2817d3e2 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
280void 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
335void 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
2817d3e2 351void 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
367void 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;
154fc5a5 383 a = fGeometryServices->GetEffA(material);
384 z = fGeometryServices->GetEffZ(material);
2817d3e2 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
404void 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
154fc5a5 441 G4String name = fGeometryServices->CutName(param);
2817d3e2 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
ad390979 463void TG4GeometryManager::SetCerenkov(Int_t itmed, Int_t npckov,
464 Float_t* ppckov, Float_t* absco, Float_t* effic,
465 Float_t* rindex)
2817d3e2 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
154fc5a5 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);
2817d3e2 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) {
ad390979 510 G4String text = "TG4GeometryManager::SetCerenkov: \n";
2817d3e2 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 "
3c7cd15a 520 << material->GetName() << G4endl;
2817d3e2 521 for (i=0; i<npckov; i++)
3c7cd15a 522 G4cout << ppckovDbl[i] << " " << rindexDbl[i] << G4endl;
2817d3e2 523
524 delete ppckovDbl;
525 delete abscoDbl;
526 delete efficDbl;
527 delete rindexDbl;
528}
529
530
531void 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
154fc5a5 549 G4gsdvn(fGeometryServices->CutName(name),
550 fGeometryServices->CutName(mother), ndiv, iaxis);
2817d3e2 551
552 // register name in name map
154fc5a5 553 fNameMap.AddName(fGeometryServices->CutName(name));
2817d3e2 554}
555
556
557void 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
154fc5a5 571 G4gsdvn2(fGeometryServices->CutName(name),
572 fGeometryServices->CutName(mother), ndiv, iaxis, c0i, numed);
2817d3e2 573
574 // register name in name map
154fc5a5 575 fNameMap.AddName(fGeometryServices->CutName(name));
2817d3e2 576}
577
578
579void 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
154fc5a5 597 G4gsdvt(fGeometryServices->CutName(name),
598 fGeometryServices->CutName(mother), step, iaxis, numed, ndvmx);
2817d3e2 599
600 // register name in name map
154fc5a5 601 fNameMap.AddName(fGeometryServices->CutName(name));
2817d3e2 602}
603
604
605void 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
154fc5a5 625 G4gsdvt2(fGeometryServices->CutName(name),
626 fGeometryServices->CutName(mother), step, iaxis, c0, numed, ndvmx);
2817d3e2 627
628 // register name in name map
154fc5a5 629 fNameMap.AddName(fGeometryServices->CutName(name));
2817d3e2 630}
631
632
633void 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
656void 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
154fc5a5 680 G4gspos(fGeometryServices->CutName(vname), num,
681 fGeometryServices->CutName(vmoth), x, y, z, irot, vonly);
2817d3e2 682
683 // register name in name map
154fc5a5 684 fNameMap.AddName(fGeometryServices->CutName(vname));
2817d3e2 685}
686
687
688void 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
154fc5a5 698 G4double* parin = fGeometryServices->CreateG4doubleArray(upar, np);
2817d3e2 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
154fc5a5 704 G4gsposp(fGeometryServices->CutName(name), nr,
705 fGeometryServices->CutName(mother), x, y, z, irot, konly,
2817d3e2 706 parin, np);
707
708 delete [] parin;
709
710 // register name in name map
154fc5a5 711 fNameMap.AddName(fGeometryServices->CutName(name));
2817d3e2 712}
713
714
715Int_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
154fc5a5 729 G4double* parin = fGeometryServices->CreateG4doubleArray(upar, npar);
2817d3e2 730
731 // write token to the output file
732 if (fWriteGeometry)
733 fOutputManager->WriteGsvolu(name, shape, nmed, parin, npar);
734
154fc5a5 735 G4gsvolu(fGeometryServices->CutName(name),
736 fGeometryServices->CutName(shape), nmed, parin, npar);
2817d3e2 737
738 delete [] parin;
739
740 // register name in name map
154fc5a5 741 fNameMap.AddName(fGeometryServices->CutName(name));
2817d3e2 742
743 return 0;
744}
745
746
57f88f6f 747void TG4GeometryManager::WriteEuclid(const char* fileName,
748 const char* topVolName, Int_t number, Int_t nlevel)
2817d3e2 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
782Int_t TG4GeometryManager::VolId(const Text_t* volName) const
783{
784// Returns the sensitive detector identifier.
2817d3e2 785// ---
786
154fc5a5 787 return fGeometryServices->GetVolumeID(volName);
2817d3e2 788}
789
790
791const char* TG4GeometryManager::VolName(Int_t id) const
792{
793// Returns the name of the sensitive detector with the given identifier.
2817d3e2 794// ---
795
154fc5a5 796 return fGeometryServices->GetVolumeName(id);
2817d3e2 797}
798
799
800Int_t TG4GeometryManager::NofVolumes() const
801{
802// Returns the total number of sensitive detectors.
803// ---
804
154fc5a5 805 return fGeometryServices->NofSensitiveDetectors();
2817d3e2 806}
807
808
154fc5a5 809Int_t TG4GeometryManager::VolId2Mate(Int_t volumeId) const
2817d3e2 810{
154fc5a5 811// Return the material number for a given volume id
2817d3e2 812// ---
813
154fc5a5 814 return fGeometryServices->GetMediumId(volumeId);
2817d3e2 815}
2817d3e2 816
154fc5a5 817
2817d3e2 818//=============================================================================
819//
820// public methods - Geant4 only
821//
822//=============================================================================
823
824
825G4VPhysicalVolume* 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();
2817d3e2 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 "
154fc5a5 844 << fGeometryServices->NofG4LogicalVolumes()
845 << " logical volumes \n"
2817d3e2 846 << " "
154fc5a5 847 << fGeometryServices->NofG4PhysicalVolumes()
848 << " physical volumes" << G4endl;
2817d3e2 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
154fc5a5 862void 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
2817d3e2 874void 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
893void 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
919void TG4GeometryManager::ClearG3TablesFinal()
920{
921// Clears G3 medias and volumes tables
922// (the top volume is removed from the vol table)
923// ---
924
2817d3e2 925 G3Med.Clear();
926 G3Vol.Clear();
927
928 // reset medium counter
929 //fMaterialCounter = 0;
930 fMediumCounter = 0;
931}
932
933
934void TG4GeometryManager::OpenOutFile(G4String filePath)
935{
936// Opens output file.
937// ---
938
939 fOutputManager->OpenFile(filePath);
940}
941
942
08b8559d 943void TG4GeometryManager::CloseOutFile()
944{
945// Closes output file.
946// ---
947
948 fOutputManager->CloseFile();
949}
950
951
2817d3e2 952void TG4GeometryManager::PrintNameMap()
953{
954// Prints the map of volumes names to second names.
955// ---
956
957 fNameMap.PrintAll();
958}
959
960
961void TG4GeometryManager::SetWriteGeometry(G4bool writeGeometry)
962{
963// Controls geometry output.
964// ---
965
966 fWriteGeometry = writeGeometry;
967}
968
969
970void TG4GeometryManager::SetMapSecond(const G4String& name)
971{
972// Sets the second name for the map of volumes names.
973// ---
974
975 fNameMap.SetSecond(name);
976}