]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TGeant4/TG4GeometryManager.cxx
dlsym not supported on HP, reverting to gcomad
[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"
13#include "TG4PhysicsManager.h"
14#include "TG4VSensitiveDetector.h"
15#include "TG4Limits.h"
16#include "TG4Globals.h"
17#include "TG3Units.h"
18
19#include <G3toG4.hh>
20#include <G3toG4BuildTree.hh>
21#include <G3VolTable.hh>
22#include <G3RotTable.hh>
23#include <G3EleTable.hh>
24#include <G3MatTable.hh>
25#include <G3MedTable.hh>
26#include <G3SensVolVector.hh>
27
2817d3e2 28#include <G4VSensitiveDetector.hh>
29#include <G4LogicalVolumeStore.hh>
30#include <G4PVPlacement.hh>
31#include <G4Material.hh>
32#include <G4MaterialPropertiesTable.hh>
33#include <G4Element.hh>
34
2817d3e2 35// extern global method from g3tog4
36void G3CLRead(G4String &, char *);
37
38TG4GeometryManager* TG4GeometryManager::fgInstance = 0;
39
40TG4GeometryManager::TG4GeometryManager()
41 : fMediumCounter(0),
42 fMaterialCounter(0),
43 fMatrixCounter(0),
44 fUseG3TMLimits(false),
45 fWriteGeometry(true)
46{
47//
48 if (fgInstance) {
49 TG4Globals::Exception(
50 "TG4GeometryManager: attempt to create two instances of singleton.");
51 }
52
53 fOutputManager = new TG4GeometryOutputManager();
54
55 fgInstance = this;
56
57 // instantiate the default element table
58 //TG4ElementTable::Instance();
59}
60
61TG4GeometryManager::TG4GeometryManager(const TG4GeometryManager& right) {
62//
63 TG4Globals::Exception(
64 "Attempt to copy TG4GeometryManager singleton.");
65}
66
67
68TG4GeometryManager::~TG4GeometryManager() {
69//
70 delete fOutputManager;
71}
72
73//==================================================================== =========
74//
75// operators
76//
77//==================================================================== =========
78
79TG4GeometryManager&
80TG4GeometryManager::operator=(const TG4GeometryManager& right)
81{
82 // check assignement to self
83 if (this == &right) return *this;
84
85 TG4Globals::Exception(
86 "Attempt to assign TG4GeometryManager singleton.");
87
88 return *this;
89}
90
91
92//=============================================================================
93//
94// private methods
95//
96//=============================================================================
97
98
99G4double* TG4GeometryManager::CreateG4doubleArray(Float_t* array,
100 G4int size) const
101{
102// Converts Float_t* array to G4double*,
103// !! The new array has to be deleted by user.
104// ---
105
106 G4double* doubleArray;
107 if (size>0) {
108 doubleArray = new G4double[size];
109 for (G4int i=0; i<size; i++) doubleArray[i] = array[i];
110 }
111 else {
112 doubleArray = 0;
113 }
114 return doubleArray;
115}
116
117
118G4String TG4GeometryManager::CutName(const char* name) const
119{
120// Removes spaces after the name if present.
121// ---
122
123 G4String cutName = name;
124 G4int i = cutName.length();
125 while (cutName(--i) == ' ') cutName = cutName(0,i);
126
127 return cutName;
128}
129
130
131void TG4GeometryManager::GstparCut(G4int itmed, TG3Cut par, G4double parval)
132{
133// Sets special tracking medium parameter.
134// It is applied to all logical volumes that use the specified
135// tracking medium.
136// ---
137
138 // get medium from table
139 G3MedTableEntry* medium = G3Med.get(itmed);
140 if (!medium) {
141 G4String text = "TG4GeometryManager::GstparCut: \n";
142 text = text + " Medium not found.";
143 G4Exception(text);
144 }
145
146 // get/create user limits
147 G4UserLimits* limits = medium->GetLimits();
148 TG4Limits* tg4Limits;
149 if (limits) {
150 tg4Limits = dynamic_cast<TG4Limits*> (limits);
151 if (!tg4Limits)
152 G4Exception("TG4GeometryManager::GstparCut: Wrong limits type.");
153 }
154 else {
155 tg4Limits = new TG4Limits();
156 medium->SetLimits(tg4Limits);
157 // add verbose
158 G4cout << "TG4GeometryManager::GstparCut: new TG4Limits() for medium "
3c7cd15a 159 << itmed << " has been created." << G4endl;
2817d3e2 160 }
161 // set parameter
162 tg4Limits->SetG3Cut(par, parval*GeV);
163}
164
165
166void TG4GeometryManager::GstparFlag(G4int itmed, TG3Flag par, G4double parval)
167{
168// Sets special tracking medium parameter.
169// It is applied to all logical volumes that use the specified
170// tracking medium.
171// ---
172
173 // get medium from table
174 G3MedTableEntry* medium = G3Med.get(itmed);
175 if (!medium) {
176 G4String text = "TG4GeometryManager::GstparFlag: \n";
177 text = text + " Medium not found.";
178 G4Exception(text);
179 }
180
181 // get/create user limits
182 G4UserLimits* limits = medium->GetLimits();
183 TG4Limits* tg4Limits;
184 if (limits) {
185 tg4Limits = dynamic_cast<TG4Limits*> (limits);
186 if (!tg4Limits)
187 G4Exception("TG4GeometryManager::GstparFlag: Wrong limits type.");
188 }
189 else {
190 tg4Limits = new TG4Limits();
191 medium->SetLimits(tg4Limits);
192 // add verbose
193 G4cout << "TG4GeometryManager::GstparFlag: new TG4Limits() for medium "
3c7cd15a 194 << itmed << " has been created." << G4endl;
2817d3e2 195 }
196 // set parameter
197 tg4Limits->SetG3Flag(par, parval);
198}
199
200
201void TG4GeometryManager::FillMediumIdVector()
202{
203// The second index for materials (having its origin in
204// G4 tracking media concept) is stored in a vector of G4int
205// parallel to G4MaterialTable.
206// ---
207
208 // initialize vector
209 G4int nofMaterials = G4Material::GetNumberOfMaterials();
210 G4int i;
211 for (i=0; i<nofMaterials; i++)
212 fMediumIdVector.push_back(0);
213
214 // fill vector
215 for (i=0; i<fMediumCounter; i++) {
216 // material index (index in G4Material table)
217 G3MedTableEntry* mte = G3Med.get(i+1);
218 G4int materialIndex = mte->GetMaterial()->GetIndex();
219
220 // medium index (ID of G3MedTableEntry)
221 G4int mediumIndex = mte->GetID();
222
223 // store medium index in the vector
224 fMediumIdVector[materialIndex] = mediumIndex;
225 }
226
227 // add verbose
3c7cd15a 228 G4cout << "Total nof materials: " << nofMaterials << G4endl;
229 G4cout << "Total nof tracking medias: " << fMediumCounter << G4endl;
2817d3e2 230}
231
232
233//=============================================================================
234//
235// public methods - AliMC implementation
236//
237//=============================================================================
238
239
240void TG4GeometryManager::Material(Int_t& kmat, const char* name, Float_t a,
241 Float_t z, Float_t dens, Float_t radl, Float_t absl, Float_t* buf,
242 Int_t nwbuf)
243{
244// Creates G4Material.
245// !! Parameters radl, absl, buf, nwbuf are ignored in G4gsmate
246// Comment:
247// absl - this parameter is ignored by GEANT3, too
248// ---
249
250 kmat = ++fMaterialCounter;
251 G4double* bufin = CreateG4doubleArray(buf, nwbuf);
252
253 // write token to the output file
254 if (fWriteGeometry)
255 fOutputManager->WriteGsmate(kmat, name, a, z, dens, radl, nwbuf, bufin);
256
257 G4gsmate(kmat, name, a, z, dens, radl, nwbuf, bufin);
258
259 delete [] bufin;
260
261 if (nwbuf > 0) {
262 G4String matName = name;
263 G4String text
264 = "TG4GeometryManager: user defined parameters for material ";
265 text = text + matName;
266 text = text + " are ignored by Geant4.";
267 TG4Globals::Warning(text);
268 }
269}
270
271
272void TG4GeometryManager::Mixture(Int_t& kmat, const char *name, Float_t *a,
273 Float_t *z, Float_t dens, Int_t nlmat, Float_t *wmat)
274{
275// Creates G4Material composed of more elements.
276// !! Parameters radl, absl, buf, nwbuf are ignored in G4gsmate
277// Comment:
278// absl - this parameter is ignored by GEANT3, too
279// ---
280
281 Int_t npar = abs(nlmat);
282 G4double *ain = CreateG4doubleArray(a, npar);
283 G4double *zin = CreateG4doubleArray(z, npar);
284 G4double *wmatin = CreateG4doubleArray(wmat, npar);
285
286 kmat = ++fMaterialCounter;
287
288 // write token to the output file
289 if (fWriteGeometry)
290 fOutputManager->WriteGsmixt(kmat, name, ain, zin, dens, nlmat, wmatin);
291
292 G4gsmixt(kmat, name, ain, zin, dens, nlmat, wmatin);
293
294 // !!! in Geant3:
295 // After a call with ratios by number (negative number of elements),
296 // the ratio array is changed to the ratio by weight, so all successive
297 // calls with the same array must specify the number of elements as
298 // positive
299
300 // wmatin may be modified
301 for (G4int i=0; i<npar; i++) wmat[i] = wmatin[i];
302
303 delete [] ain;
304 delete [] zin;
305 delete [] wmatin;
306}
307
308void TG4GeometryManager::Medium(Int_t& kmed, const char *name, Int_t nmat,
309 Int_t isvol, Int_t ifield, Float_t fieldm, Float_t tmaxfd,
310 Float_t stemax, Float_t deemax, Float_t epsil,
311 Float_t stmin, Float_t* ubuf, Int_t nbuf)
312{
313// Creates a temporary "medium" that is used for
314// assigning corresponding parameters to G4 objects:
315// NTMED is stored as a second material index;
316// ISVOL is used for builing TG3SensVolVector;
317// STEMAX is passed in TG4Limits (if fUseG3TMLimits is set true);
318// !! The other parameters (IFIELD, FIELDM, TMAXFD, DEEMAX, EPSIL, STMIN)
319// are ignored by Geant4.
320// ---
321
322// Geant3 desription:
323// ==================
324// NTMED Tracking medium number
325// NAME Tracking medium name
326// NMAT Material number
327// ISVOL Sensitive volume flag
328// IFIELD Magnetic field
329// FIELDM Max. field value (Kilogauss)
330// TMAXFD Max. angle due to field (deg/step)
331// STEMAX Max. step allowed
332// DEEMAX Max. fraction of energy lost in a step
333// EPSIL Tracking precision (cm)
334// STMIN Min. step due to continuos processes (cm)
335//
336// IFIELD = 0 if no magnetic field; IFIELD = -1 if user decision in GUSWIM;
337// IFIELD = 1 if tracking performed with GRKUTA; IFIELD = 2 if tracking
338// performed with GHELIX; IFIELD = 3 if tracking performed with GHELX3.
339// ---
340
341 kmed = ++fMediumCounter;
342
343 // write token to the output file
344 if (fWriteGeometry)
345 fOutputManager->WriteGstmed(kmed, name, nmat, isvol, ifield, fieldm, tmaxfd,
346 stemax, deemax, epsil, stmin, 0, 0);
347
348 G4gstmed(kmed, name, nmat, isvol, ifield, fieldm, tmaxfd, stemax, deemax,
349 epsil, stmin, 0, fUseG3TMLimits);
350 // !! instead of the nbuf argument the bool fIsG3Default is passed
351
352 if (nbuf > 0) {
353 G4String medName = name;
354 G4String text
355 = "TG4GeometryManager: user defined parameters for medium ";
356 text = text + medName;
357 text = text + " are ignored by Geant4.";
358 TG4Globals::Warning(text);
359 }
360}
361
362
363void TG4GeometryManager::Matrix(Int_t& krot, Float_t thetaX, Float_t phiX,
364 Float_t thetaY, Float_t phiY, Float_t thetaZ, Float_t phiZ)
365{
366// Creates G4RotationMatrix.
367// ---
368
369 krot = ++fMatrixCounter;
370
371 // write token to the output file
372 if (fWriteGeometry)
373 fOutputManager->WriteGsrotm(krot, thetaX, phiX, thetaY, phiY, thetaZ, phiZ);
374
375 G4gsrotm(krot, thetaX, phiX, thetaY, phiY, thetaZ, phiZ);
376}
377
378
379G4Material* TG4GeometryManager::MixMaterials(G4String name, G4double density,
380 TG4StringVector* matNames, TG4doubleVector* matWeights)
381{
382// Creates a mixture of selected materials
383// ---
384
385 // number of materials to be mixed
386 G4int nofMaterials = matNames->entries();
387 if (nofMaterials != matWeights->entries()) {
388 G4String text = "TG4GeometryManager::MixMaterials: ";
389 text = text + "different number of material names and weigths.";
390 TG4Globals::Exception(text);
391 }
392 // add verbose
3c7cd15a 393 // G4cout << "Nof of materials to be mixed: " << nofMaterials << G4endl;
2817d3e2 394
395 // fill vector of materials
396 TG4MaterialVector matVector;
397 G4int im;
398 for (im=0; im< nofMaterials; im++) {
399 // material
400 G4Material* material = G4Material::GetMaterial((*matNames)[im]);
401 matVector.insert(material);
402 }
403
404 // create the mixed material
405 G4Material* mixture = new G4Material(name, density, nofMaterials);
406 for (im=0; im< nofMaterials; im++) {
407 G4Material* material = matVector[im];
408 G4double fraction = (*matWeights)[im];
409 mixture->AddMaterial(material, fraction);
410 }
411
412 return mixture;
413}
414
415
416void TG4GeometryManager::Ggclos()
417{
418// Sets the top VTE in temporary G3 volume table.
419// Close geometry output file (if fWriteGeometry is set true).
420//
421// Geant3 desription:
422// ==================
423// close out the geometry
424// ---
425
426 if (fWriteGeometry) fOutputManager->WriteGgclos();
427
428 G4ggclos();
429}
430
431
432void TG4GeometryManager::Gfmate(Int_t imat, char *name, Float_t &a,
433 Float_t &z, Float_t &dens, Float_t &radl, Float_t &absl,
434 Float_t* ubuf, Int_t& nbuf)
435{
436// Geant3 desription:
437// ==================
438// Return parameters for material IMAT
439// ---
440
441 G4Material* material = G3Mat.get(imat);
442
443 if (material) {
444 // to do: change this correctly
445 // !! unsafe conversion
446 const char* chName = material->GetName();
447 name = (char*)chName;
448 a = GetEffA(material);
449 z = GetEffZ(material);
450
451 dens = material->GetDensity();
452 dens /= TG3Units::MassDensity();
453
454 radl = material->GetRadlen();
455 radl /= TG3Units::Length();
456
457 // the following parameters are not defined in Geant4
458 absl = 0.;
459 ubuf = 0;
460 nbuf = 0;
461 }
462 else {
463 TG4Globals::Exception(
464 "TG4GeometryManager::Gfmate: material has not been found.");
465 }
466}
467
468
469void TG4GeometryManager::Gstpar(Int_t itmed, const char *param,
470 Float_t parval)
471{
472// Passes the tracking medium parameter to TG4Limits.
473// The tracking medium parameter is set only in case
474// its value is different from the "global" physics setup.
475// (If: CheckCut/FlagWithG3Defaults is used checking
476// is performed with respect to G3 default values.)
477// When any cut/flag parameter is set in limits
478// the physics manager is locked and the physics setup
479// cannot be changed.
480// Applying this TG4Limits to particles and physical
481// processes is still in development.
482//
483// Geant3 desription:
484// ==================
485// To change the value of cut or mechanism "CHPAR"
486// to a new value PARVAL for tracking medium ITMED
487// The data structure JTMED contains the standard tracking
488// parameters (CUTS and flags to control the physics processes) which
489// are used by default for all tracking media. It is possible to
490// redefine individually with GSTPAR any of these parameters for a
491// given tracking medium.
492// ITMED tracking medium number
493// CHPAR is a character string (variable name)
494// PARVAL must be given as a floating point.
495// ---
496
497 // write token to the output file
498 if (fWriteGeometry)
499 fOutputManager->WriteGstpar(itmed, param, parval);
500
501 // get physics setup
502 TG4PhysicsManager* physicsManager = TG4PhysicsManager::Instance();
503 //TG4CutVector* cutVector = physicsManager->GetCutVector();
504 //TG4FlagVector* flagVector = physicsManager->GetFlagVector();
505
506 G4String name = CutName(param);
507 TG3Cut g3Cut;
508 if (physicsManager->CheckCutWithCutVector(name, parval, g3Cut)) {
509 GstparCut(itmed, g3Cut, parval);
510 physicsManager->Lock();
511 }
512 else {
513 TG3Flag g3Flag;
514 if (physicsManager->CheckFlagWithFlagVector(name, parval, g3Flag)) {
515 GstparFlag(itmed, g3Flag, parval);
516 physicsManager->Lock();
517 }
518 else if (g3Cut==kNoG3Cuts && g3Flag==kNoG3Flags) {
519 G4String text = "TG4GeometryManager::Gstpar:";
520 text = text + name;
521 text = text + " parameter is not yet implemented.";
522 TG4Globals::Warning(text);
523 }
524 }
525}
526
527
528void TG4GeometryManager::Gsckov(Int_t itmed, Int_t npckov, Float_t* ppckov,
529 Float_t* absco, Float_t* effic, Float_t* rindex)
530{
531//
532// Geant3 desription:
533// ==================
534//
535// Stores the tables for UV photon tracking in medium ITMED
536// Please note that it is the user's responsability to
537// provide all the coefficients:
538//
539//
540// ITMED Tracking medium number
541// NPCKOV Number of bins of each table
542// PPCKOV Value of photon momentum (in GeV)
543// ABSCO Absorbtion coefficients
544// dielectric: absorbtion length in cm
545// metals : absorbtion fraction (0<=x<=1)
546// EFFIC Detection efficiency for UV photons
547// RINDEX Refraction index (if=0 metal)
548// ---
549
550 G4double* ppckovDbl = CreateG4doubleArray(ppckov, npckov);
551 G4double* abscoDbl = CreateG4doubleArray(absco, npckov);
552 G4double* efficDbl = CreateG4doubleArray(effic, npckov);
553 G4double* rindexDbl = CreateG4doubleArray(rindex, npckov);
554
555 // add units
556 G4int i;
557 for (i=0; i<npckov; i++) {
558 ppckovDbl[i] = ppckovDbl[i]*TG3Units::Energy();
559 abscoDbl[i] = abscoDbl[i]*TG3Units::Length();
560 }
561
562 // create material properties table
563 G4MaterialPropertiesTable* table = new G4MaterialPropertiesTable();
564 table->AddProperty("ABSLENGTH", ppckovDbl, abscoDbl, npckov);
565 // used in G4OpAbsorption process
566 table->AddProperty("EFFICIENCY", ppckovDbl, efficDbl, npckov);
567 // used in G4OpBoundary process
568 table->AddProperty("RINDEX", ppckovDbl, rindexDbl, npckov);
569 // used in G4Cerenkov, G4OpRayleigh, G4OpBoundary
570
571 // get material of medium from table
572 G3MedTableEntry* medium = G3Med.get(itmed);
573 if (!medium) {
574 G4String text = "TG4GeometryManager::Gsckov: \n";
575 text = text + " Medium not found.";
576 G4Exception(text);
577 }
578 G4Material* material = medium->GetMaterial();
579
580 // set material properties table
581 material->SetMaterialPropertiesTable(table);
582
583 G4cout << "The tables for UV photon tracking set for "
3c7cd15a 584 << material->GetName() << G4endl;
2817d3e2 585 for (i=0; i<npckov; i++)
3c7cd15a 586 G4cout << ppckovDbl[i] << " " << rindexDbl[i] << G4endl;
2817d3e2 587
588 delete ppckovDbl;
589 delete abscoDbl;
590 delete efficDbl;
591 delete rindexDbl;
592}
593
594
595void TG4GeometryManager::Gsdvn(const char *name, const char *mother,
596 Int_t ndiv, Int_t iaxis)
597{
598// Geant3 desription:
599// ==================
600// NAME Volume name
601// MOTHER Mother volume name
602// NDIV Number of divisions
603// IAXIS Axis value
604//
605// X,Y,Z of CAXIS will be translated to 1,2,3 for IAXIS.
606// It divides a previously defined volume.
607// ---
608
609 // write token to the output file
610 if (fWriteGeometry)
611 fOutputManager->WriteGsdvn(name, mother, ndiv, iaxis);
612
613 G4gsdvn(CutName(name), CutName(mother), ndiv, iaxis);
614
615 // register name in name map
616 fNameMap.AddName(CutName(name));
617}
618
619
620void TG4GeometryManager::Gsdvn2(const char *name, const char *mother,
621 Int_t ndiv, Int_t iaxis, Float_t c0i, Int_t numed)
622{
623// Geant3 desription:
624// ==================
625// DIVIDES MOTHER INTO NDIV DIVISIONS CALLED NAME
626// ALONG AXIS IAXIS STARTING AT COORDINATE VALUE C0.
627// THE NEW VOLUME CREATED WILL BE MEDIUM NUMBER NUMED.
628// ---
629
630 // write token to the output file
631 if (fWriteGeometry)
632 fOutputManager->WriteGsdvn2(name, mother, ndiv, iaxis, c0i, numed);
633
634 G4gsdvn2(CutName(name),CutName(mother), ndiv, iaxis, c0i, numed);
635
636 // register name in name map
637 fNameMap.AddName(CutName(name));
638}
639
640
641void TG4GeometryManager::Gsdvt(const char *name, const char *mother,
642 Float_t step, Int_t iaxis, Int_t numed, Int_t ndvmx)
643{
644// Geant3 desription:
645// ==================
646// Divides MOTHER into divisions called NAME along
647// axis IAXIS in steps of STEP. If not exactly divisible
648// will make as many as possible and will centre them
649// with respect to the mother. Divisions will have medium
650// number NUMED. If NUMED is 0, NUMED of MOTHER is taken.
651// NDVMX is the expected maximum number of divisions
652// (If 0, no protection tests are performed)
653// ---
654
655 // write token to the output file
656 if (fWriteGeometry)
657 fOutputManager->WriteGsdvt(name, mother, step, iaxis, numed, ndvmx);
658
659 G4gsdvt(CutName(name), CutName(mother), step, iaxis, numed, ndvmx);
660
661 // register name in name map
662 fNameMap.AddName(CutName(name));
663}
664
665
666void TG4GeometryManager::Gsdvt2(const char *name, const char *mother,
667 Float_t step, Int_t iaxis, Float_t c0, Int_t numed, Int_t ndvmx)
668{
669// Geant3 desription:
670// ==================
671// Create a new volume by dividing an existing one
672//
673// Divides MOTHER into divisions called NAME along
674// axis IAXIS starting at coordinate value C0 with step
675// size STEP.
676// The new volume created will have medium number NUMED.
677// If NUMED is 0, NUMED of mother is taken.
678// NDVMX is the expected maximum number of divisions
679// (If 0, no protection tests are performed)
680// ---
681
682 // write token to the output file
683 if (fWriteGeometry)
684 fOutputManager->WriteGsdvt2(name, mother, step, iaxis, c0, numed, ndvmx);
685
686 G4gsdvt2(CutName(name), CutName(mother), step, iaxis, c0, numed, ndvmx);
687
688 // register name in name map
689 fNameMap.AddName(CutName(name));
690}
691
692
693void TG4GeometryManager::Gsord(const char *name, Int_t iax)
694{
695// No corresponding action in G4.
696//
697// Geant3 desription:
698// ==================
699// Flags volume CHNAME whose contents will have to be ordered
700// along axis IAX, by setting the search flag to -IAX
701// IAX = 1 X axis
702// IAX = 2 Y axis
703// IAX = 3 Z axis
704// IAX = 4 Rxy (static ordering only -> GTMEDI)
705// IAX = 14 Rxy (also dynamic ordering -> GTNEXT)
706// IAX = 5 Rxyz (static ordering only -> GTMEDI)
707// IAX = 15 Rxyz (also dynamic ordering -> GTNEXT)
708// IAX = 6 PHI (PHI=0 => X axis)
709// IAX = 7 THETA (THETA=0 => Z axis)
710// ---
711
712 TG4Globals::Warning("TG4GeometryManager::Gsord: dummy method.");
713}
714
715
716void TG4GeometryManager::Gspos(const char *vname, Int_t num,
717 const char *vmoth, Float_t x, Float_t y, Float_t z, Int_t irot,
718 const char *vonly)
719{
720// Geant3 desription:
721// ==================
722// Position a volume into an existing one
723//
724// NAME Volume name
725// NUMBER Copy number of the volume
726// MOTHER Mother volume name
727// X X coord. of the volume in mother ref. sys.
728// Y Y coord. of the volume in mother ref. sys.
729// Z Z coord. of the volume in mother ref. sys.
730// IROT Rotation matrix number w.r.t. mother ref. sys.
731// ONLY ONLY/MANY flag
732//
733// It positions a previously defined volume in the mother.
734// ---
735
736 // write token to the output file
737 if (fWriteGeometry)
738 fOutputManager->WriteGspos(vname, num, vmoth, x, y, z, irot, vonly);
739
740 G4gspos(CutName(vname), num, CutName(vmoth), x, y, z, irot, vonly);
741
742 // register name in name map
743 fNameMap.AddName(CutName(vname));
744}
745
746
747void TG4GeometryManager::Gsposp(const char *name, Int_t nr,
748 const char *mother, Float_t x, Float_t y, Float_t z, Int_t irot,
749 const char *konly, Float_t *upar, Int_t np )
750{
751// Geant3 desription:
752// ==================
753// Place a copy of generic volume NAME with user number
754// NR inside MOTHER, with its parameters UPAR(1..NP)
755// ---
756
757 G4double* parin = CreateG4doubleArray(upar, np);
758
759 // write token to the output file
760 if (fWriteGeometry)
761 fOutputManager->WriteGsposp(name, nr, mother, x, y, z, irot, konly, parin, np);
762
763 G4gsposp(CutName(name), nr, CutName(mother), x, y, z, irot, konly,
764 parin, np);
765
766 delete [] parin;
767
768 // register name in name map
769 fNameMap.AddName(CutName(name));
770}
771
772
773Int_t TG4GeometryManager::Gsvolu(const char *name, const char *shape,
774 Int_t nmed, Float_t *upar, Int_t npar)
775{
776// Geant3 desription:
777// ==================
778// NAME Volume name
779// SHAPE Volume type
780// NUMED Tracking medium number
781// NPAR Number of shape parameters
782// UPAR Vector containing shape parameters
783//
784// It creates a new volume in the JVOLUM data structure.
785// ---
786
787 G4double* parin = CreateG4doubleArray(upar, npar);
788
789 // write token to the output file
790 if (fWriteGeometry)
791 fOutputManager->WriteGsvolu(name, shape, nmed, parin, npar);
792
793 G4gsvolu(CutName(name), CutName(shape), nmed, parin, npar);
794
795 delete [] parin;
796
797 // register name in name map
798 fNameMap.AddName(CutName(name));
799
800 return 0;
801}
802
803
57f88f6f 804void TG4GeometryManager::WriteEuclid(const char* fileName,
805 const char* topVolName, Int_t number, Int_t nlevel)
2817d3e2 806{
807// Geant3 desription:
808// ==================
809//
810// ******************************************************************
811// * *
812// * Write out the geometry of the detector in EUCLID file format *
813// * *
814// * filnam : will be with the extension .euc *
815// * topvol : volume name of the starting node *
816// * number : copy number of topvol (relevant for gsposp) *
817// * nlevel : number of levels in the tree structure *
818// * to be written out, starting from topvol *
819// * *
820// * Author : M. Maire *
821// * *
822// ******************************************************************
823//
824// File filnam.tme is written out with the definitions of tracking
825// medias and materials.
826// As to restore original numbers for materials and medias, program
827// searches in the file euc_medi.dat and comparing main parameters of
828// the mat. defined inside geant and the one in file recognizes them
829// and is able to take number from file. If for any material or medium,
830// this procedure fails, ordering starts from 1.
831// Arrays IOTMED and IOMATE are used for this procedure
832// ---
833
834 TG4Globals::Warning(
835 "TG4GeometryManager::WriteEuclid(..) is not yet implemented.");
836}
837
838
839Int_t TG4GeometryManager::VolId(const Text_t* volName) const
840{
841// Returns the sensitive detector identifier.
842// !! Gives exception in case logical volume is not associated with
843// a sensitive detector.
844// ---
845
846 G4String g4VolName = CutName(volName);
847 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
848
849 for (G4int i=0; i<pLVStore->entries(); i++) {
850 G4LogicalVolume* lv = pLVStore->at(i);
851 G4VSensitiveDetector* sd = lv->GetSensitiveDetector();
852
853 if ((sd) && (sd->GetName()==g4VolName)) {
854 TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
855 if (tsd)
856 return tsd->GetID();
857 else {
858 TG4Globals::Exception(
859 "TG4GeometryManager::VolId: Unknown sensitive detector type");
860 return 0;
3c7cd15a 861 }
2817d3e2 862 }
863 }
864
865 G4String text = "TG4GeometryManager::VolId: Sensitive detector ";
866 text = text + g4VolName;
867 text = text + " is not defined.\n";
75dcb77f 868 TG4Globals::Warning(text);
2817d3e2 869 return 0;
870}
871
872
873const char* TG4GeometryManager::VolName(Int_t id) const
874{
875// Returns the name of the sensitive detector with the given identifier.
876// !! Gives exception in case logical volume is not associated with
877// a sensitive detector.
878// ---
879
880 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
881
882 for (G4int i=0; i<pLVStore->entries(); i++) {
883 G4LogicalVolume* lv = pLVStore->at(i);
884 G4VSensitiveDetector* sd = lv->GetSensitiveDetector();
885
886 if (sd) {
887 G4int sdID;
888 TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
889 if (tsd)
890 sdID = tsd->GetID();
891 else {
892 TG4Globals::Exception(
893 "TG4GeometryManager::VolId: Unknown sensitive detector type");
894 return 0;
3c7cd15a 895 }
2817d3e2 896 if (sdID == id) return sd->GetName();
897 }
898 }
899
900 G4String text = "TG4GeometryManager::VolName:\n";
901 text = text + " Sensitive detector with given id is not defined. \n";
75dcb77f 902 TG4Globals::Warning(text);
2817d3e2 903 return "";
904}
905
906
907Int_t TG4GeometryManager::NofVolumes() const
908{
909// Returns the total number of sensitive detectors.
910// ---
911
912 return NofSensitiveDetectors();
913}
914
915
916void TG4GeometryManager::ReadG3Geometry(G4String filePath)
917{
918// Processes g3calls.dat file and fills G3 tables.
919// ---
920
921 // add verbose
3c7cd15a 922 G4cout << "Reading the call list file " << filePath << "..." << G4endl;
2817d3e2 923 G3CLRead(filePath, NULL);
3c7cd15a 924 G4cout << "Call list file read completed. Build geometry" << G4endl;
2817d3e2 925}
926
927
928//=============================================================================
929//
930// public methods - Geant4 only
931//
932//=============================================================================
933
934
935G4VPhysicalVolume* TG4GeometryManager::CreateG4Geometry()
936{
937// Creates G4 geometry objects according to the G3VolTable
938// and returns the top physical volume in case it was created
939// (return zero otherwise).
940// ---
941
942 // set the first entry in the G3Vol table
943 Ggclos();
944 G3VolTableEntry* first = G3Vol.GetFirstVTE();
2817d3e2 945
946 // create G4 geometry
947 G3toG4BuildTree(first,0);
948
949 // print G3 volume table statistics
950 G3Vol.VTEStat();
951
952 // print G4 geometry statistics
953 G4cout << "G4 Stat: instantiated "
954 << NofG4LogicalVolumes() << " logical volumes \n"
955 << " "
3c7cd15a 956 << NofG4PhysicalVolumes() << " physical volumes" << G4endl;
2817d3e2 957
958 // position the first entry
959 // (in Geant3 the top volume cannot be positioned)
960 //
961 G4VPhysicalVolume* top = 0;
962 if (first->GetLV()->GetNoDaughters() == 0) {
963 top = new G4PVPlacement(0, G4ThreeVector(), first->GetName(),
964 first->GetLV(), 0, false, 0);
965 }
966 return top;
967}
968
969
970void TG4GeometryManager::UseG3TrackingMediaLimits()
971{
972// Sets fUseG3TMLimits option.
973// !! This method has to be called only before starting
974// creating geometry.
975// ---
976
977 if (fMediumCounter == 0) {
978 fUseG3TMLimits = true;
979 }
980 else {
981 G4String text = "TG4GeometryManager::UseG3TMLimits: \n";
982 text = text + " It is too late to set G3 defaults. \n";
983 text = text + " Some media has been already processed.";
984 TG4Globals::Exception(text);
985 }
986}
987
988
989void TG4GeometryManager::ClearG3Tables()
990{
991// Clears G3 volumes, materials, rotations(?) tables
992// and sensitive volumes vector.
993// The top volume is kept in the vol table.
994// ---
995
996 // clear volume table
997 // but keep the top volume in the table
998 G3VolTableEntry* top = G3Vol.GetFirstVTE();
999 G4String name = top->GetName();
1000 G4String shape = top->GetShape();
1001 G3VolTableEntry* keep
1002 = new G3VolTableEntry(name, shape, top->GetRpar(), top->GetNpar(),
1003 top->GetNmed(), top->GetSolid(), false);
1004 keep->SetLV(top->GetLV());
1005 G3Vol.Clear();
1006 G3Vol.PutVTE(keep);
1007
1008 // clear other tables
1009 G3Mat.Clear();
1010 //G3Rot.Clear();
1011 G3SensVol.clear();
1012}
1013
1014
1015void TG4GeometryManager::ClearG3TablesFinal()
1016{
1017// Clears G3 medias and volumes tables
1018// (the top volume is removed from the vol table)
1019// ---
1020
1021 // fill medium id vector
1022 FillMediumIdVector();
1023
1024 G3Med.Clear();
1025 G3Vol.Clear();
1026
1027 // reset medium counter
1028 //fMaterialCounter = 0;
1029 fMediumCounter = 0;
1030}
1031
1032
1033void TG4GeometryManager::OpenOutFile(G4String filePath)
1034{
1035// Opens output file.
1036// ---
1037
1038 fOutputManager->OpenFile(filePath);
1039}
1040
1041
08b8559d 1042void TG4GeometryManager::CloseOutFile()
1043{
1044// Closes output file.
1045// ---
1046
1047 fOutputManager->CloseFile();
1048}
1049
1050
2817d3e2 1051void TG4GeometryManager::PrintNameMap()
1052{
1053// Prints the map of volumes names to second names.
1054// ---
1055
1056 fNameMap.PrintAll();
1057}
1058
1059
1060void TG4GeometryManager::SetWriteGeometry(G4bool writeGeometry)
1061{
1062// Controls geometry output.
1063// ---
1064
1065 fWriteGeometry = writeGeometry;
1066}
1067
1068
1069void TG4GeometryManager::SetMapSecond(const G4String& name)
1070{
1071// Sets the second name for the map of volumes names.
1072// ---
1073
1074 fNameMap.SetSecond(name);
1075}
1076
1077
1078Int_t TG4GeometryManager::NofG3Volumes() const
1079{
1080// Returns the total number of logical volumes corresponding
1081// to G3 volumes. (
1082// The logical volume that were created by Gsposp method
1083// with a generic name (name_copyNo) are NOT included.
1084// ---
1085
1086 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
1087
1088 G4int counter = 0;
1089 for (G4int i=0; i<pLVStore->entries(); i++) {
1090 G4LogicalVolume* lv = (*pLVStore)[i];
1091 if (IsG3Volume(lv->GetName())) counter++;
1092 }
1093
1094 return counter;
1095}
1096
1097
1098Int_t TG4GeometryManager::NofG4LogicalVolumes() const
1099{
1100// Returns the total number of logical volumes in the geometry.
1101// ---
1102
1103 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
1104 return pLVStore->entries();
1105}
1106
1107
1108Int_t TG4GeometryManager::NofG4PhysicalVolumes() const
1109{
1110// Returns the total number of physical volumes in the geometry.
1111// ---
1112
1113 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
1114
1115 G4int counter = 0;
1116 for (G4int i=0; i<pLVStore->entries(); i++) {
1117 counter += ((*pLVStore)[i])->GetNoDaughters();
1118 }
1119
1120 return counter;
1121}
1122
1123
1124Int_t TG4GeometryManager::NofSensitiveDetectors() const
1125{
1126// Returns the total number of sensitive detectors.
1127// ---
1128
1129 return TG4VSensitiveDetector::GetTotalNofSensitiveDetectors();
1130}
1131
1132
1133G4bool TG4GeometryManager::IsG3Volume(G4String lvName) const
1134{
1135// Returns true if the logical volume of given volumeName
1136// was not created by Gsposp method with a generic name
1137// (name_copyNo).
1138// ---
1139
1140 if (lvName.contains(gSeparator))
1141 return false;
1142 else
1143 return true;
1144}
1145
1146
1147void TG4GeometryManager::G4ToG3VolumeName(G4String& name) const
1148{
1149// Cuts _copyNo extension added to logical volume name in case
1150// the logical volume was created by Gsposp method.
1151// ---
1152
1153 if (name.contains(gSeparator))
1154 name = name(0,name.first(gSeparator));
1155}
1156
1157
1158const G4String& TG4GeometryManager::GetMapSecond(const G4String& name)
1159{
1160// Returns the second string associated with the name in
1161// the name map.
1162// ---
1163
1164 return fNameMap.GetSecond(name);
1165}
1166
1167
1168G4int TG4GeometryManager::GetMediumId(G4Material* material) const
1169{
1170// Returns the second index for materials (having its origin in
1171// G4 tracking media concept)
1172// ---
1173
1174 return fMediumIdVector[material->GetIndex()];
1175}
1176
1177
1178G4double TG4GeometryManager::GetEffA(G4Material* material) const
1179{
1180// Returns A or effective A=sum(pi*Ai) (if compound/mixture)
1181// of given material.
1182// ---
1183
1184 G4double a = 0.;
1185 G4int nofElements = material->GetNumberOfElements();
1186 if (nofElements > 1) {
1187 G4String text = "Effective A for material mixture (";
1188 text = text + material->GetName();
1189 text = text + ") is used.";
1190 //TG4Globals::Warning(text);
1191
1192 for (G4int i=0; i<nofElements; i++) {
1193 G4double aOfElement = material->GetElement(i)->GetA();
1194 G4double massFraction = material->GetFractionVector()[i];
1195 a += aOfElement*massFraction /(TG3Units::AtomicWeight());
1196 }
1197 }
1198 else {
1199 a = material->GetA();
1200 a /= TG3Units::AtomicWeight();
1201 }
1202 return a;
1203}
1204
1205
1206G4double TG4GeometryManager::GetEffZ(G4Material* material) const
1207{
1208// Returns Z or effective Z=sum(pi*Zi) (if compound/mixture)
1209// of given material.
1210// ---
1211
1212 G4double z = 0.;
1213 G4int nofElements = material->GetNumberOfElements();
1214 if (nofElements > 1) {
1215 G4String text = "Effective Z for material mixture (";
1216 text = text + material->GetName();
1217 text = text + ") is used.";
1218 //TG4Globals::Warning(text);
1219
1220 for (G4int i=0; i<nofElements; i++) {
1221 G4double zOfElement = material->GetElement(i)->GetZ();
1222 G4double massFraction = material->GetFractionVector()[i];
1223 z += zOfElement*massFraction;
1224 }
1225 }
1226 else {
1227 z = material->GetZ();
1228 }
1229 return z;
1230}