4 // C++ interface to Geant3 basic routines
5 // for building Geant4 geometry
7 // by V. Berejnoi, 25.2.1999
8 // materials, tracking media support
9 // added by I.Hrivnacova, 27.5.1999
11 #include "TG4GeometryManager.h"
12 #include "TG4GeometryOutputManager.h"
13 #include "TG4PhysicsManager.h"
14 #include "TG4VSensitiveDetector.h"
15 #include "TG4Limits.h"
16 #include "TG4Globals.h"
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>
28 #include <G4SDManager.hh>
29 #include <G4VSensitiveDetector.hh>
30 #include <G4LogicalVolumeStore.hh>
31 #include <G4PVPlacement.hh>
32 #include <G4Material.hh>
33 #include <G4MaterialPropertiesTable.hh>
34 #include <G4Element.hh>
39 // extern global method from g3tog4
40 void G3CLRead(G4String &, char *);
42 TG4GeometryManager* TG4GeometryManager::fgInstance = 0;
44 TG4GeometryManager::TG4GeometryManager()
48 fUseG3TMLimits(false),
53 TG4Globals::Exception(
54 "TG4GeometryManager: attempt to create two instances of singleton.");
57 fOutputManager = new TG4GeometryOutputManager();
61 // instantiate the default element table
62 //TG4ElementTable::Instance();
65 TG4GeometryManager::TG4GeometryManager(const TG4GeometryManager& right) {
67 TG4Globals::Exception(
68 "Attempt to copy TG4GeometryManager singleton.");
72 TG4GeometryManager::~TG4GeometryManager() {
74 delete fOutputManager;
77 //==================================================================== =========
81 //==================================================================== =========
84 TG4GeometryManager::operator=(const TG4GeometryManager& right)
86 // check assignement to self
87 if (this == &right) return *this;
89 TG4Globals::Exception(
90 "Attempt to assign TG4GeometryManager singleton.");
96 //=============================================================================
100 //=============================================================================
103 G4double* TG4GeometryManager::CreateG4doubleArray(Float_t* array,
106 // Converts Float_t* array to G4double*,
107 // !! The new array has to be deleted by user.
110 G4double* doubleArray;
112 doubleArray = new G4double[size];
113 for (G4int i=0; i<size; i++) doubleArray[i] = array[i];
122 G4String TG4GeometryManager::CutName(const char* name) const
124 // Removes spaces after the name if present.
127 G4String cutName = name;
128 G4int i = cutName.length();
129 while (cutName(--i) == ' ') cutName = cutName(0,i);
135 void TG4GeometryManager::GstparCut(G4int itmed, TG3Cut par, G4double parval)
137 // Sets special tracking medium parameter.
138 // It is applied to all logical volumes that use the specified
142 // get medium from table
143 G3MedTableEntry* medium = G3Med.get(itmed);
145 G4String text = "TG4GeometryManager::GstparCut: \n";
146 text = text + " Medium not found.";
150 // get/create user limits
151 G4UserLimits* limits = medium->GetLimits();
152 TG4Limits* tg4Limits;
154 tg4Limits = dynamic_cast<TG4Limits*> (limits);
156 G4Exception("TG4GeometryManager::GstparCut: Wrong limits type.");
159 tg4Limits = new TG4Limits();
160 medium->SetLimits(tg4Limits);
162 G4cout << "TG4GeometryManager::GstparCut: new TG4Limits() for medium "
163 << itmed << " has been created." << endl;
166 tg4Limits->SetG3Cut(par, parval*GeV);
170 void TG4GeometryManager::GstparFlag(G4int itmed, TG3Flag par, G4double parval)
172 // Sets special tracking medium parameter.
173 // It is applied to all logical volumes that use the specified
177 // get medium from table
178 G3MedTableEntry* medium = G3Med.get(itmed);
180 G4String text = "TG4GeometryManager::GstparFlag: \n";
181 text = text + " Medium not found.";
185 // get/create user limits
186 G4UserLimits* limits = medium->GetLimits();
187 TG4Limits* tg4Limits;
189 tg4Limits = dynamic_cast<TG4Limits*> (limits);
191 G4Exception("TG4GeometryManager::GstparFlag: Wrong limits type.");
194 tg4Limits = new TG4Limits();
195 medium->SetLimits(tg4Limits);
197 G4cout << "TG4GeometryManager::GstparFlag: new TG4Limits() for medium "
198 << itmed << " has been created." << endl;
201 tg4Limits->SetG3Flag(par, parval);
205 void TG4GeometryManager::FillMediumIdVector()
207 // The second index for materials (having its origin in
208 // G4 tracking media concept) is stored in a vector of G4int
209 // parallel to G4MaterialTable.
213 G4int nofMaterials = G4Material::GetNumberOfMaterials();
215 for (i=0; i<nofMaterials; i++)
216 fMediumIdVector.push_back(0);
219 for (i=0; i<fMediumCounter; i++) {
220 // material index (index in G4Material table)
221 G3MedTableEntry* mte = G3Med.get(i+1);
222 G4int materialIndex = mte->GetMaterial()->GetIndex();
224 // medium index (ID of G3MedTableEntry)
225 G4int mediumIndex = mte->GetID();
227 // store medium index in the vector
228 fMediumIdVector[materialIndex] = mediumIndex;
232 G4cout << "Total nof materials: " << nofMaterials << endl;
233 G4cout << "Total nof tracking medias: " << fMediumCounter << endl;
237 //=============================================================================
239 // public methods - AliMC implementation
241 //=============================================================================
244 void TG4GeometryManager::Material(Int_t& kmat, const char* name, Float_t a,
245 Float_t z, Float_t dens, Float_t radl, Float_t absl, Float_t* buf,
248 // Creates G4Material.
249 // !! Parameters radl, absl, buf, nwbuf are ignored in G4gsmate
251 // absl - this parameter is ignored by GEANT3, too
254 kmat = ++fMaterialCounter;
255 G4double* bufin = CreateG4doubleArray(buf, nwbuf);
257 // write token to the output file
259 fOutputManager->WriteGsmate(kmat, name, a, z, dens, radl, nwbuf, bufin);
261 G4gsmate(kmat, name, a, z, dens, radl, nwbuf, bufin);
266 G4String matName = name;
268 = "TG4GeometryManager: user defined parameters for material ";
269 text = text + matName;
270 text = text + " are ignored by Geant4.";
271 TG4Globals::Warning(text);
276 void TG4GeometryManager::Mixture(Int_t& kmat, const char *name, Float_t *a,
277 Float_t *z, Float_t dens, Int_t nlmat, Float_t *wmat)
279 // Creates G4Material composed of more elements.
280 // !! Parameters radl, absl, buf, nwbuf are ignored in G4gsmate
282 // absl - this parameter is ignored by GEANT3, too
285 Int_t npar = abs(nlmat);
286 G4double *ain = CreateG4doubleArray(a, npar);
287 G4double *zin = CreateG4doubleArray(z, npar);
288 G4double *wmatin = CreateG4doubleArray(wmat, npar);
290 kmat = ++fMaterialCounter;
292 // write token to the output file
294 fOutputManager->WriteGsmixt(kmat, name, ain, zin, dens, nlmat, wmatin);
296 G4gsmixt(kmat, name, ain, zin, dens, nlmat, wmatin);
299 // After a call with ratios by number (negative number of elements),
300 // the ratio array is changed to the ratio by weight, so all successive
301 // calls with the same array must specify the number of elements as
304 // wmatin may be modified
305 for (G4int i=0; i<npar; i++) wmat[i] = wmatin[i];
312 void TG4GeometryManager::Medium(Int_t& kmed, const char *name, Int_t nmat,
313 Int_t isvol, Int_t ifield, Float_t fieldm, Float_t tmaxfd,
314 Float_t stemax, Float_t deemax, Float_t epsil,
315 Float_t stmin, Float_t* ubuf, Int_t nbuf)
317 // Creates a temporary "medium" that is used for
318 // assigning corresponding parameters to G4 objects:
319 // NTMED is stored as a second material index;
320 // ISVOL is used for builing TG3SensVolVector;
321 // STEMAX is passed in TG4Limits (if fUseG3TMLimits is set true);
322 // !! The other parameters (IFIELD, FIELDM, TMAXFD, DEEMAX, EPSIL, STMIN)
323 // are ignored by Geant4.
326 // Geant3 desription:
327 // ==================
328 // NTMED Tracking medium number
329 // NAME Tracking medium name
330 // NMAT Material number
331 // ISVOL Sensitive volume flag
332 // IFIELD Magnetic field
333 // FIELDM Max. field value (Kilogauss)
334 // TMAXFD Max. angle due to field (deg/step)
335 // STEMAX Max. step allowed
336 // DEEMAX Max. fraction of energy lost in a step
337 // EPSIL Tracking precision (cm)
338 // STMIN Min. step due to continuos processes (cm)
340 // IFIELD = 0 if no magnetic field; IFIELD = -1 if user decision in GUSWIM;
341 // IFIELD = 1 if tracking performed with GRKUTA; IFIELD = 2 if tracking
342 // performed with GHELIX; IFIELD = 3 if tracking performed with GHELX3.
345 kmed = ++fMediumCounter;
347 // write token to the output file
349 fOutputManager->WriteGstmed(kmed, name, nmat, isvol, ifield, fieldm, tmaxfd,
350 stemax, deemax, epsil, stmin, 0, 0);
352 G4gstmed(kmed, name, nmat, isvol, ifield, fieldm, tmaxfd, stemax, deemax,
353 epsil, stmin, 0, fUseG3TMLimits);
354 // !! instead of the nbuf argument the bool fIsG3Default is passed
357 G4String medName = name;
359 = "TG4GeometryManager: user defined parameters for medium ";
360 text = text + medName;
361 text = text + " are ignored by Geant4.";
362 TG4Globals::Warning(text);
367 void TG4GeometryManager::Matrix(Int_t& krot, Float_t thetaX, Float_t phiX,
368 Float_t thetaY, Float_t phiY, Float_t thetaZ, Float_t phiZ)
370 // Creates G4RotationMatrix.
373 krot = ++fMatrixCounter;
375 // write token to the output file
377 fOutputManager->WriteGsrotm(krot, thetaX, phiX, thetaY, phiY, thetaZ, phiZ);
379 G4gsrotm(krot, thetaX, phiX, thetaY, phiY, thetaZ, phiZ);
383 G4Material* TG4GeometryManager::MixMaterials(G4String name, G4double density,
384 TG4StringVector* matNames, TG4doubleVector* matWeights)
386 // Creates a mixture of selected materials
389 // number of materials to be mixed
390 G4int nofMaterials = matNames->entries();
391 if (nofMaterials != matWeights->entries()) {
392 G4String text = "TG4GeometryManager::MixMaterials: ";
393 text = text + "different number of material names and weigths.";
394 TG4Globals::Exception(text);
397 // G4cout << "Nof of materials to be mixed: " << nofMaterials << endl;
399 // fill vector of materials
400 TG4MaterialVector matVector;
402 for (im=0; im< nofMaterials; im++) {
404 G4Material* material = G4Material::GetMaterial((*matNames)[im]);
405 matVector.insert(material);
408 // create the mixed material
409 G4Material* mixture = new G4Material(name, density, nofMaterials);
410 for (im=0; im< nofMaterials; im++) {
411 G4Material* material = matVector[im];
412 G4double fraction = (*matWeights)[im];
413 mixture->AddMaterial(material, fraction);
420 void TG4GeometryManager::Ggclos()
422 // Sets the top VTE in temporary G3 volume table.
423 // Close geometry output file (if fWriteGeometry is set true).
425 // Geant3 desription:
426 // ==================
427 // close out the geometry
430 if (fWriteGeometry) fOutputManager->WriteGgclos();
436 void TG4GeometryManager::Gfmate(Int_t imat, char *name, Float_t &a,
437 Float_t &z, Float_t &dens, Float_t &radl, Float_t &absl,
438 Float_t* ubuf, Int_t& nbuf)
440 // Geant3 desription:
441 // ==================
442 // Return parameters for material IMAT
445 G4Material* material = G3Mat.get(imat);
448 // to do: change this correctly
449 // !! unsafe conversion
450 const char* chName = material->GetName();
451 name = (char*)chName;
452 a = GetEffA(material);
453 z = GetEffZ(material);
455 dens = material->GetDensity();
456 dens /= TG3Units::MassDensity();
458 radl = material->GetRadlen();
459 radl /= TG3Units::Length();
461 // the following parameters are not defined in Geant4
467 TG4Globals::Exception(
468 "TG4GeometryManager::Gfmate: material has not been found.");
473 void TG4GeometryManager::Gstpar(Int_t itmed, const char *param,
476 // Passes the tracking medium parameter to TG4Limits.
477 // The tracking medium parameter is set only in case
478 // its value is different from the "global" physics setup.
479 // (If: CheckCut/FlagWithG3Defaults is used checking
480 // is performed with respect to G3 default values.)
481 // When any cut/flag parameter is set in limits
482 // the physics manager is locked and the physics setup
483 // cannot be changed.
484 // Applying this TG4Limits to particles and physical
485 // processes is still in development.
487 // Geant3 desription:
488 // ==================
489 // To change the value of cut or mechanism "CHPAR"
490 // to a new value PARVAL for tracking medium ITMED
491 // The data structure JTMED contains the standard tracking
492 // parameters (CUTS and flags to control the physics processes) which
493 // are used by default for all tracking media. It is possible to
494 // redefine individually with GSTPAR any of these parameters for a
495 // given tracking medium.
496 // ITMED tracking medium number
497 // CHPAR is a character string (variable name)
498 // PARVAL must be given as a floating point.
501 // write token to the output file
503 fOutputManager->WriteGstpar(itmed, param, parval);
506 TG4PhysicsManager* physicsManager = TG4PhysicsManager::Instance();
507 //TG4CutVector* cutVector = physicsManager->GetCutVector();
508 //TG4FlagVector* flagVector = physicsManager->GetFlagVector();
510 G4String name = CutName(param);
512 if (physicsManager->CheckCutWithCutVector(name, parval, g3Cut)) {
513 GstparCut(itmed, g3Cut, parval);
514 physicsManager->Lock();
518 if (physicsManager->CheckFlagWithFlagVector(name, parval, g3Flag)) {
519 GstparFlag(itmed, g3Flag, parval);
520 physicsManager->Lock();
522 else if (g3Cut==kNoG3Cuts && g3Flag==kNoG3Flags) {
523 G4String text = "TG4GeometryManager::Gstpar:";
525 text = text + " parameter is not yet implemented.";
526 TG4Globals::Warning(text);
532 void TG4GeometryManager::Gsckov(Int_t itmed, Int_t npckov, Float_t* ppckov,
533 Float_t* absco, Float_t* effic, Float_t* rindex)
536 // Geant3 desription:
537 // ==================
539 // Stores the tables for UV photon tracking in medium ITMED
540 // Please note that it is the user's responsability to
541 // provide all the coefficients:
544 // ITMED Tracking medium number
545 // NPCKOV Number of bins of each table
546 // PPCKOV Value of photon momentum (in GeV)
547 // ABSCO Absorbtion coefficients
548 // dielectric: absorbtion length in cm
549 // metals : absorbtion fraction (0<=x<=1)
550 // EFFIC Detection efficiency for UV photons
551 // RINDEX Refraction index (if=0 metal)
554 G4double* ppckovDbl = CreateG4doubleArray(ppckov, npckov);
555 G4double* abscoDbl = CreateG4doubleArray(absco, npckov);
556 G4double* efficDbl = CreateG4doubleArray(effic, npckov);
557 G4double* rindexDbl = CreateG4doubleArray(rindex, npckov);
561 for (i=0; i<npckov; i++) {
562 ppckovDbl[i] = ppckovDbl[i]*TG3Units::Energy();
563 abscoDbl[i] = abscoDbl[i]*TG3Units::Length();
566 // create material properties table
567 G4MaterialPropertiesTable* table = new G4MaterialPropertiesTable();
568 table->AddProperty("ABSLENGTH", ppckovDbl, abscoDbl, npckov);
569 // used in G4OpAbsorption process
570 table->AddProperty("EFFICIENCY", ppckovDbl, efficDbl, npckov);
571 // used in G4OpBoundary process
572 table->AddProperty("RINDEX", ppckovDbl, rindexDbl, npckov);
573 // used in G4Cerenkov, G4OpRayleigh, G4OpBoundary
575 // get material of medium from table
576 G3MedTableEntry* medium = G3Med.get(itmed);
578 G4String text = "TG4GeometryManager::Gsckov: \n";
579 text = text + " Medium not found.";
582 G4Material* material = medium->GetMaterial();
584 // set material properties table
585 material->SetMaterialPropertiesTable(table);
587 G4cout << "The tables for UV photon tracking set for "
588 << material->GetName() << endl;
589 for (i=0; i<npckov; i++)
590 G4cout << ppckovDbl[i] << " " << rindexDbl[i] << endl;
599 void TG4GeometryManager::Gsdvn(const char *name, const char *mother,
600 Int_t ndiv, Int_t iaxis)
602 // Geant3 desription:
603 // ==================
605 // MOTHER Mother volume name
606 // NDIV Number of divisions
609 // X,Y,Z of CAXIS will be translated to 1,2,3 for IAXIS.
610 // It divides a previously defined volume.
613 // write token to the output file
615 fOutputManager->WriteGsdvn(name, mother, ndiv, iaxis);
617 G4gsdvn(CutName(name), CutName(mother), ndiv, iaxis);
619 // register name in name map
620 fNameMap.AddName(CutName(name));
624 void TG4GeometryManager::Gsdvn2(const char *name, const char *mother,
625 Int_t ndiv, Int_t iaxis, Float_t c0i, Int_t numed)
627 // Geant3 desription:
628 // ==================
629 // DIVIDES MOTHER INTO NDIV DIVISIONS CALLED NAME
630 // ALONG AXIS IAXIS STARTING AT COORDINATE VALUE C0.
631 // THE NEW VOLUME CREATED WILL BE MEDIUM NUMBER NUMED.
634 // write token to the output file
636 fOutputManager->WriteGsdvn2(name, mother, ndiv, iaxis, c0i, numed);
638 G4gsdvn2(CutName(name),CutName(mother), ndiv, iaxis, c0i, numed);
640 // register name in name map
641 fNameMap.AddName(CutName(name));
645 void TG4GeometryManager::Gsdvt(const char *name, const char *mother,
646 Float_t step, Int_t iaxis, Int_t numed, Int_t ndvmx)
648 // Geant3 desription:
649 // ==================
650 // Divides MOTHER into divisions called NAME along
651 // axis IAXIS in steps of STEP. If not exactly divisible
652 // will make as many as possible and will centre them
653 // with respect to the mother. Divisions will have medium
654 // number NUMED. If NUMED is 0, NUMED of MOTHER is taken.
655 // NDVMX is the expected maximum number of divisions
656 // (If 0, no protection tests are performed)
659 // write token to the output file
661 fOutputManager->WriteGsdvt(name, mother, step, iaxis, numed, ndvmx);
663 G4gsdvt(CutName(name), CutName(mother), step, iaxis, numed, ndvmx);
665 // register name in name map
666 fNameMap.AddName(CutName(name));
670 void TG4GeometryManager::Gsdvt2(const char *name, const char *mother,
671 Float_t step, Int_t iaxis, Float_t c0, Int_t numed, Int_t ndvmx)
673 // Geant3 desription:
674 // ==================
675 // Create a new volume by dividing an existing one
677 // Divides MOTHER into divisions called NAME along
678 // axis IAXIS starting at coordinate value C0 with step
680 // The new volume created will have medium number NUMED.
681 // If NUMED is 0, NUMED of mother is taken.
682 // NDVMX is the expected maximum number of divisions
683 // (If 0, no protection tests are performed)
686 // write token to the output file
688 fOutputManager->WriteGsdvt2(name, mother, step, iaxis, c0, numed, ndvmx);
690 G4gsdvt2(CutName(name), CutName(mother), step, iaxis, c0, numed, ndvmx);
692 // register name in name map
693 fNameMap.AddName(CutName(name));
697 void TG4GeometryManager::Gsord(const char *name, Int_t iax)
699 // No corresponding action in G4.
701 // Geant3 desription:
702 // ==================
703 // Flags volume CHNAME whose contents will have to be ordered
704 // along axis IAX, by setting the search flag to -IAX
708 // IAX = 4 Rxy (static ordering only -> GTMEDI)
709 // IAX = 14 Rxy (also dynamic ordering -> GTNEXT)
710 // IAX = 5 Rxyz (static ordering only -> GTMEDI)
711 // IAX = 15 Rxyz (also dynamic ordering -> GTNEXT)
712 // IAX = 6 PHI (PHI=0 => X axis)
713 // IAX = 7 THETA (THETA=0 => Z axis)
716 TG4Globals::Warning("TG4GeometryManager::Gsord: dummy method.");
720 void TG4GeometryManager::Gspos(const char *vname, Int_t num,
721 const char *vmoth, Float_t x, Float_t y, Float_t z, Int_t irot,
724 // Geant3 desription:
725 // ==================
726 // Position a volume into an existing one
729 // NUMBER Copy number of the volume
730 // MOTHER Mother volume name
731 // X X coord. of the volume in mother ref. sys.
732 // Y Y coord. of the volume in mother ref. sys.
733 // Z Z coord. of the volume in mother ref. sys.
734 // IROT Rotation matrix number w.r.t. mother ref. sys.
735 // ONLY ONLY/MANY flag
737 // It positions a previously defined volume in the mother.
740 // write token to the output file
742 fOutputManager->WriteGspos(vname, num, vmoth, x, y, z, irot, vonly);
744 G4gspos(CutName(vname), num, CutName(vmoth), x, y, z, irot, vonly);
746 // register name in name map
747 fNameMap.AddName(CutName(vname));
751 void TG4GeometryManager::Gsposp(const char *name, Int_t nr,
752 const char *mother, Float_t x, Float_t y, Float_t z, Int_t irot,
753 const char *konly, Float_t *upar, Int_t np )
755 // Geant3 desription:
756 // ==================
757 // Place a copy of generic volume NAME with user number
758 // NR inside MOTHER, with its parameters UPAR(1..NP)
761 G4double* parin = CreateG4doubleArray(upar, np);
763 // write token to the output file
765 fOutputManager->WriteGsposp(name, nr, mother, x, y, z, irot, konly, parin, np);
767 G4gsposp(CutName(name), nr, CutName(mother), x, y, z, irot, konly,
772 // register name in name map
773 fNameMap.AddName(CutName(name));
777 Int_t TG4GeometryManager::Gsvolu(const char *name, const char *shape,
778 Int_t nmed, Float_t *upar, Int_t npar)
780 // Geant3 desription:
781 // ==================
784 // NUMED Tracking medium number
785 // NPAR Number of shape parameters
786 // UPAR Vector containing shape parameters
788 // It creates a new volume in the JVOLUM data structure.
791 G4double* parin = CreateG4doubleArray(upar, npar);
793 // write token to the output file
795 fOutputManager->WriteGsvolu(name, shape, nmed, parin, npar);
797 G4gsvolu(CutName(name), CutName(shape), nmed, parin, npar);
801 // register name in name map
802 fNameMap.AddName(CutName(name));
808 void TG4GeometryManager::WriteEuclid(const char* fileName,
809 const char* topVolName, Int_t number, Int_t nlevel)
811 // Geant3 desription:
812 // ==================
814 // ******************************************************************
816 // * Write out the geometry of the detector in EUCLID file format *
818 // * filnam : will be with the extension .euc *
819 // * topvol : volume name of the starting node *
820 // * number : copy number of topvol (relevant for gsposp) *
821 // * nlevel : number of levels in the tree structure *
822 // * to be written out, starting from topvol *
824 // * Author : M. Maire *
826 // ******************************************************************
828 // File filnam.tme is written out with the definitions of tracking
829 // medias and materials.
830 // As to restore original numbers for materials and medias, program
831 // searches in the file euc_medi.dat and comparing main parameters of
832 // the mat. defined inside geant and the one in file recognizes them
833 // and is able to take number from file. If for any material or medium,
834 // this procedure fails, ordering starts from 1.
835 // Arrays IOTMED and IOMATE are used for this procedure
839 "TG4GeometryManager::WriteEuclid(..) is not yet implemented.");
843 Int_t TG4GeometryManager::VolId(const Text_t* volName) const
845 // Returns the sensitive detector identifier.
846 // !! Gives exception in case logical volume is not associated with
847 // a sensitive detector.
850 G4String g4VolName = CutName(volName);
851 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
853 for (G4int i=0; i<pLVStore->entries(); i++) {
854 G4LogicalVolume* lv = pLVStore->at(i);
855 G4VSensitiveDetector* sd = lv->GetSensitiveDetector();
857 if ((sd) && (sd->GetName()==g4VolName)) {
858 TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
862 TG4Globals::Exception(
863 "TG4GeometryManager::VolId: Unknown sensitive detector type");
869 G4String text = "TG4GeometryManager::VolId: Sensitive detector ";
870 text = text + g4VolName;
871 text = text + " is not defined.\n";
872 text = text + " Set /alDet/setAllSensitive true in PreInit.";
873 TG4Globals::Exception(text);
878 const char* TG4GeometryManager::VolName(Int_t id) const
880 // Returns the name of the sensitive detector with the given identifier.
881 // !! Gives exception in case logical volume is not associated with
882 // a sensitive detector.
885 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
887 for (G4int i=0; i<pLVStore->entries(); i++) {
888 G4LogicalVolume* lv = pLVStore->at(i);
889 G4VSensitiveDetector* sd = lv->GetSensitiveDetector();
893 TG4VSensitiveDetector* tsd = dynamic_cast<TG4VSensitiveDetector*>(sd);
897 TG4Globals::Exception(
898 "TG4GeometryManager::VolId: Unknown sensitive detector type");
901 if (sdID == id) return sd->GetName();
905 G4String text = "TG4GeometryManager::VolName:\n";
906 text = text + " Sensitive detector with given id is not defined. \n";
907 text = text + " Set /alDet/setAllSensitive true in PreInit.";
908 TG4Globals::Exception(text);
913 Int_t TG4GeometryManager::NofVolumes() const
915 // Returns the total number of sensitive detectors.
918 return NofSensitiveDetectors();
922 void TG4GeometryManager::ReadG3Geometry(G4String filePath)
924 // Processes g3calls.dat file and fills G3 tables.
928 G4cout << "Reading the call list file " << filePath << "..." << endl;
929 G3CLRead(filePath, NULL);
930 G4cout << "Call list file read completed. Build geometry" << endl;
934 //=============================================================================
936 // public methods - Geant4 only
938 //=============================================================================
941 G4VPhysicalVolume* TG4GeometryManager::CreateG4Geometry()
943 // Creates G4 geometry objects according to the G3VolTable
944 // and returns the top physical volume in case it was created
945 // (return zero otherwise).
948 // set the first entry in the G3Vol table
950 G3VolTableEntry* first = G3Vol.GetFirstVTE();
953 if (fWriteGeometry) fOutputManager->CloseFile();
955 // create G4 geometry
956 G3toG4BuildTree(first,0);
958 // print G3 volume table statistics
961 // print G4 geometry statistics
962 G4cout << "G4 Stat: instantiated "
963 << NofG4LogicalVolumes() << " logical volumes \n"
965 << NofG4PhysicalVolumes() << " physical volumes" << endl;
967 // position the first entry
968 // (in Geant3 the top volume cannot be positioned)
970 G4VPhysicalVolume* top = 0;
971 if (first->GetLV()->GetNoDaughters() == 0) {
972 top = new G4PVPlacement(0, G4ThreeVector(), first->GetName(),
973 first->GetLV(), 0, false, 0);
979 void TG4GeometryManager::UseG3TrackingMediaLimits()
981 // Sets fUseG3TMLimits option.
982 // !! This method has to be called only before starting
983 // creating geometry.
986 if (fMediumCounter == 0) {
987 fUseG3TMLimits = true;
990 G4String text = "TG4GeometryManager::UseG3TMLimits: \n";
991 text = text + " It is too late to set G3 defaults. \n";
992 text = text + " Some media has been already processed.";
993 TG4Globals::Exception(text);
998 void TG4GeometryManager::ClearG3Tables()
1000 // Clears G3 volumes, materials, rotations(?) tables
1001 // and sensitive volumes vector.
1002 // The top volume is kept in the vol table.
1005 // clear volume table
1006 // but keep the top volume in the table
1007 G3VolTableEntry* top = G3Vol.GetFirstVTE();
1008 G4String name = top->GetName();
1009 G4String shape = top->GetShape();
1010 G3VolTableEntry* keep
1011 = new G3VolTableEntry(name, shape, top->GetRpar(), top->GetNpar(),
1012 top->GetNmed(), top->GetSolid(), false);
1013 keep->SetLV(top->GetLV());
1017 // clear other tables
1024 void TG4GeometryManager::ClearG3TablesFinal()
1026 // Clears G3 medias and volumes tables
1027 // (the top volume is removed from the vol table)
1030 // fill medium id vector
1031 FillMediumIdVector();
1036 // reset medium counter
1037 //fMaterialCounter = 0;
1042 void TG4GeometryManager::OpenOutFile(G4String filePath)
1044 // Opens output file.
1047 fOutputManager->OpenFile(filePath);
1051 void TG4GeometryManager::PrintNameMap()
1053 // Prints the map of volumes names to second names.
1056 fNameMap.PrintAll();
1060 void TG4GeometryManager::SetWriteGeometry(G4bool writeGeometry)
1062 // Controls geometry output.
1065 fWriteGeometry = writeGeometry;
1069 void TG4GeometryManager::SetMapSecond(const G4String& name)
1071 // Sets the second name for the map of volumes names.
1074 fNameMap.SetSecond(name);
1078 Int_t TG4GeometryManager::NofG3Volumes() const
1080 // Returns the total number of logical volumes corresponding
1082 // The logical volume that were created by Gsposp method
1083 // with a generic name (name_copyNo) are NOT included.
1086 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
1089 for (G4int i=0; i<pLVStore->entries(); i++) {
1090 G4LogicalVolume* lv = (*pLVStore)[i];
1091 if (IsG3Volume(lv->GetName())) counter++;
1098 Int_t TG4GeometryManager::NofG4LogicalVolumes() const
1100 // Returns the total number of logical volumes in the geometry.
1103 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
1104 return pLVStore->entries();
1108 Int_t TG4GeometryManager::NofG4PhysicalVolumes() const
1110 // Returns the total number of physical volumes in the geometry.
1113 G4LogicalVolumeStore* pLVStore = G4LogicalVolumeStore::GetInstance();
1116 for (G4int i=0; i<pLVStore->entries(); i++) {
1117 counter += ((*pLVStore)[i])->GetNoDaughters();
1124 Int_t TG4GeometryManager::NofSensitiveDetectors() const
1126 // Returns the total number of sensitive detectors.
1129 return TG4VSensitiveDetector::GetTotalNofSensitiveDetectors();
1133 G4bool TG4GeometryManager::IsG3Volume(G4String lvName) const
1135 // Returns true if the logical volume of given volumeName
1136 // was not created by Gsposp method with a generic name
1140 if (lvName.contains(gSeparator))
1147 void TG4GeometryManager::G4ToG3VolumeName(G4String& name) const
1149 // Cuts _copyNo extension added to logical volume name in case
1150 // the logical volume was created by Gsposp method.
1153 if (name.contains(gSeparator))
1154 name = name(0,name.first(gSeparator));
1158 const G4String& TG4GeometryManager::GetMapSecond(const G4String& name)
1160 // Returns the second string associated with the name in
1164 return fNameMap.GetSecond(name);
1168 G4int TG4GeometryManager::GetMediumId(G4Material* material) const
1170 // Returns the second index for materials (having its origin in
1171 // G4 tracking media concept)
1174 return fMediumIdVector[material->GetIndex()];
1178 G4double TG4GeometryManager::GetEffA(G4Material* material) const
1180 // Returns A or effective A=sum(pi*Ai) (if compound/mixture)
1181 // of given material.
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);
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());
1199 a = material->GetA();
1200 a /= TG3Units::AtomicWeight();
1206 G4double TG4GeometryManager::GetEffZ(G4Material* material) const
1208 // Returns Z or effective Z=sum(pi*Zi) (if compound/mixture)
1209 // of given material.
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);
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;
1227 z = material->GetZ();