3 // modified 17/06/02: by I. Gonzalez. STL migration
7 #include "FGeometryInit.hh"
8 #include "FluggNavigator.hh"
9 #include "WrapUtils.hh"
11 FGeometryInit * FGeometryInit::flagInstance=0;
13 FGeometryInit* FGeometryInit::GetInstance() {
14 #ifdef G4GEOMETRY_DEBUG
15 G4cout << "==> Flugg::FGeometryInit::GetInstance(), instance="
16 << flagInstance << G4endl;
19 flagInstance = new FGeometryInit();
21 #ifdef G4GEOMETRY_DEBUG
22 G4cout << "<== Flugg::FGeometryInit::GetInstance(), instance="
23 << flagInstance << G4endl;
29 FGeometryInit::FGeometryInit():
32 fTransportationManager(G4TransportationManager::GetTransportationManager()),
42 #ifdef G4GEOMETRY_DEBUG
43 G4cout << "==> Flugg FGeometryInit::FGeometryInit()" << G4endl;
44 G4cout << "\t+ Changing the G4Navigator for FluggNavigator..." << G4endl;
46 G4Navigator* actualnav = fTransportationManager->GetNavigatorForTracking();
48 FluggNavigator* newnav = new FluggNavigator();
49 fTransportationManager->SetNavigatorForTracking(newnav);
52 G4cerr << "ERROR: Could not find the actual G4Navigator" << G4endl;
57 #ifdef G4GEOMETRY_DEBUG
58 G4cout << "<== Flugg FGeometryInit::FGeometryInit()" << G4endl;
64 FGeometryInit::~FGeometryInit() {
65 G4cout << "==> Flugg FGeometryInit::~FGeometryInit()" << G4endl;
67 ptrGeoMan->OpenGeometry();
68 if (fTransportationManager)
69 delete fTransportationManager;
71 delete[] ptrJrLtGeant;
74 //keep ATTENTION: never delete a pointer twice!
75 G4cout << "<== Flugg FGeometryInit::FGeometryInit()" << G4endl;
79 void FGeometryInit::closeGeometry() {
80 #ifdef G4GEOMETRY_DEBUG
81 G4cout << "==> Flugg FGeometryInit::closeGeometry()" << G4endl;
84 ptrGeoMan = G4GeometryManager::GetInstance();
86 ptrGeoMan->OpenGeometry();
88 //true argoment allows voxel construction; if false voxels are built
89 //only for replicated volumes
90 ptrGeoMan->CloseGeometry(true);
93 G4cerr << "ERROR in FLUGG: Could not get G4GeometryManager instance"
95 G4cerr << " in FGeometryInit::closeGeometry. Exiting!!!"
99 #ifdef G4GEOMETRY_DEBUG
100 G4cout << "<== Flugg FGeometryInit::closeGeometry()" << G4endl;
104 //*************************************************************************
106 void FGeometryInit::InitHistArray() {
107 #ifdef G4GEOMETRY_DEBUG
108 G4cout << "==> Flugg FGeometryInit::InitHistArray()" << G4endl;
110 ptrArray = new G4int[1000000];
111 for(G4int i=0;i<1000000;i++)
113 #ifdef G4GEOMETRY_DEBUG
114 G4cout << "<== Flugg FGeometryInit::InitHistArray()" << G4endl;
120 //*************************************************************************
121 //jrLtGeant stores all crossed lattice volume histories.
123 void FGeometryInit::InitJrLtGeantArray() {
124 #ifdef G4GEOMETRY_DEBUG
125 G4cout << "==> Flugg FGeometryInit::InitJrLtGeantArray()" << G4endl;
126 G4cout << "Initializing JrLtGeant array" << G4endl;
128 ptrJrLtGeant = new G4int[10000];
129 for(G4int x=0;x<10000;x++)
132 #ifdef G4GEOMETRY_DEBUG
133 G4cout << "<== Flugg FGeometryInit::InitJrLtGeantArray()" << G4endl;
138 void FGeometryInit::SetLttcFlagGeant(G4int newFlagLttc) {
139 #ifdef G4GEOMETRY_DEBUG
140 G4cout << "==> Flugg FGeometryInit::SetLttcFlagGeant()" << G4endl;
142 // Added by A.Solodkov
143 if (newFlagLttc >= 10000) {
144 G4cout << "Problems in FGeometryInit::SetLttcFlagGeant" << G4endl;
145 G4cout << "Index newFlagLttc=" << newFlagLttc << " is outside array bounds"
147 G4cout << "Better to stop immediately !" << G4endl;
150 flagLttcGeant = newFlagLttc;
151 #ifdef G4GEOMETRY_DEBUG
152 G4cout << "<== Flugg FGeometryInit::SetLttcFlagGeant()" << G4endl;
156 void FGeometryInit::PrintJrLtGeant() {
157 #ifdef G4GEOMETRY_DEBUG
158 //G4cout << "jrLtGeant:" << G4endl;
159 //for(G4int y=0;y<=flagLttcGeant;y++)
161 // G4cout << "jrLtGeant[" << y << "]=" << ptrJrLtGeant[y] << G4endl;
165 //**************************************************************************
167 void FGeometryInit::PrintHistories() {
169 #ifdef G4GEOMETRY_DEBUG
170 G4cout << "Touch hist:" << G4endl;
171 G4cout << *(ptrTouchHist->GetHistory()) << G4endl;
172 G4cout << "Tmp hist:" << G4endl;
173 G4cout << *(ptrTempNavHist->GetHistory()) << G4endl;
174 G4cout << "Old hist:" << G4endl;
175 G4cout << *(ptrOldNavHist->GetHistory()) << G4endl;
182 void FGeometryInit::InitHistories() {
183 #ifdef G4GEOMETRY_DEBUG
184 G4cout << "==> Flugg FGeometryInit::InitHistories()" << G4endl;
186 //init utility histories with navigator history
188 fTransportationManager->GetNavigatorForTracking()->CreateTouchableHistory();
190 fTransportationManager->GetNavigatorForTracking()->CreateTouchableHistory();
191 ptrOldNavHist = new G4TouchableHistory();
192 #ifdef G4GEOMETRY_DEBUG
193 G4cout << "<== Flugg FGeometryInit::InitHistories()" << G4endl;
197 void FGeometryInit::DeleteHistories() {
198 #ifdef G4GEOMETRY_DEBUG
199 G4cout << "==> Flugg FGeometryInit::DeleteHistories()" << G4endl;
203 delete ptrOldNavHist;
204 delete ptrTempNavHist;
206 #ifdef G4GEOMETRY_DEBUG
207 G4cout << "Deleting step-history objects at end of run!" << G4endl;
208 G4cout << "<== Flugg FGeometryInit::DeleteHistories()" << G4endl;
213 void FGeometryInit::UpdateHistories(const G4NavigationHistory * history,
215 #ifdef G4GEOMETRY_DEBUG
216 G4cout << "==> Flugg FGeometryInit::UpdateHistories()" << G4endl;
220 #ifdef G4GEOMETRY_DEBUG
221 G4cout << "...updating histories!" << G4endl;
224 G4VPhysicalVolume * pPhysVol = history->GetTopVolume();
228 //this is the case when a new history is given to the
229 //navigator and old history has to be resetted
230 //touchable history has not been updated jet, so:
232 ptrTouchHist->UpdateYourself(pPhysVol,history);
233 ptrTempNavHist->UpdateYourself(pPhysVol,history);
234 G4NavigationHistory * ptrOldNavHistNotConst =
235 const_cast<G4NavigationHistory * >(ptrOldNavHist->GetHistory());
236 ptrOldNavHistNotConst->Reset();
237 ptrOldNavHistNotConst->Clear();
243 //this is the case when a new history is given to the
244 //navigator but old history has to be kept (e.g. LOOKZ
245 //is call during an event);
246 //touchable history has not been updated jet, so:
248 ptrTouchHist->UpdateYourself(pPhysVol,history);
249 ptrTempNavHist->UpdateYourself(pPhysVol,history);
255 //this is the case when the touchable history has been
256 //updated by a LocateGlobalPointAndUpdateTouchable call
258 G4VPhysicalVolume * pPhysVolTemp = ptrTempNavHist->GetVolume();
259 ptrOldNavHist->UpdateYourself(pPhysVolTemp,
260 ptrTempNavHist->GetHistory());
262 ptrTempNavHist->UpdateYourself(pPhysVol,history);
268 G4cout <<" ERROR in updating step-histories!" << G4endl;
273 #ifdef G4GEOMETRY_DEBUG
274 G4cout << "<== Flugg FGeometryInit::UpdateHistories()" << G4endl;
278 //*****************************************************************************
281 void FGeometryInit::createFlukaMatFile() {
282 // last modification Sara Vanini 1/III/99
283 // NAMES OF ELEMENTS AND COMPOUNDS: the names must be written in upper case,
284 // according to the fluka standard. In addition,. they must be equal to the
285 // names of the fluka materials - see fluka manual - in order that the
286 // program load the right cross sections, and equal to the names included in
287 // the .pemf. Otherwise the user must define the LOW-MAT CARDS, and make his
288 // own .pemf, in order to get the right cross sections loaded in memory.
290 #ifdef G4GEOMETRY_DEBUG
291 G4cout << "==> Flugg FGeometryInit::createFlukaMatFile()" << G4endl;
292 G4cout << "================== FILEWR =================" << G4endl;
295 //open file for output
296 G4std::ofstream fout("flukaMat.inp");
298 //PhysicalVolumeStore, Volume and MaterialTable pointers
299 G4PhysicalVolumeStore * pVolStore = G4PhysicalVolumeStore::GetInstance();
300 unsigned int numVol = pVolStore->size();
302 G4int* indexMatFluka = 0;
303 static G4Material * ptrMat = 0;
306 //Find a volume with a material associated
307 while(!ptrMat && x<numVol) {
308 G4VPhysicalVolume * ptrVol = (*pVolStore)[x];
309 G4LogicalVolume * ptrLogVol = ptrVol->GetLogicalVolume();
310 ptrMat = ptrLogVol->GetMaterial();
315 static const G4MaterialTable * ptrMatTab = G4Material::GetMaterialTable();
317 //number of materials, elements, variable initialisations
318 static size_t totNumMat = G4Material::GetNumberOfMaterials();
319 #ifdef G4GEOMETRY_DEBUG
320 G4cout << "Number of materials: " << totNumMat << G4endl;
323 static size_t totNumElem = G4Element::GetNumberOfElements();
324 #ifdef G4GEOMETRY_DEBUG
325 G4cout << "Number of elements: " << totNumMat << G4endl;
329 G4int * elemIndexInMATcard = new G4int[totNumElem];
330 for(unsigned int t=0; t<totNumElem; t++)
331 elemIndexInMATcard[t] = 0;
332 static const G4IsotopeTable * ptrIsotTab = 0;
334 static size_t totNumIsot;
335 G4int* isotIndexInMATcard = 0;
336 G4int isotPresence = 0;
340 PrintHeader(fout,"GEANT4 ELEMENTS AND COMPOUNDS");
342 // *** loop over G4Materials to assign Fluka index
343 G4int indexCount = 3;
344 indexMatFluka = new G4int[totNumMat];
345 for(unsigned int i=0; i<totNumMat; i++) {
346 //pointer material, state
347 ptrMat = (*ptrMatTab)[i];
348 G4double denMat = ptrMat->GetDensity();
349 G4String nameMat = ptrMat->GetName();
350 // Fluka index: bh=1, vacuum=2, others=3,4..
351 if(denMat<=1.00e-10*g/cm3)
352 //N.B. fluka density limit decided on XI-`98
355 indexMatFluka[i]=indexCount;
359 // *** write single-element material MATERIAL card
360 size_t numElem = ptrMat->GetNumberOfElements();
362 G4int index = indexMatFluka[i];
363 const G4Element * ptrElem = ptrMat->GetElement(0);
364 size_t indElemTab = ptrElem->GetIndex();
365 size_t numIsot = ptrElem->GetNumberOfIsotopes();
366 G4double A = (ptrElem->GetA())/(g);
368 if(index!=2 && !elemIndexInMATcard[indElemTab]) {
369 G4double Z = ptrElem->GetZ();
370 elemIndexInMATcard[indElemTab] = index;
371 G4String nameEl = ptrElem->GetName();
374 //write on file MATERIAL card of element
375 PrintMaterial(fout, "MATERIAL ",
385 const G4Isotope* ptrIsot = ptrElem->GetIsotope(0);
386 size_t indIsotTab = ptrIsot->GetIndex();
387 //initialize variables
389 totNumIsot = ptrIsot->GetNumberOfIsotopes();
390 ptrIsotTab = ptrIsot->GetIsotopeTable();
391 isotIndexInMATcard = new G4int[totNumIsot];
392 for(unsigned int t=0; t<totNumIsot; t++)
393 isotIndexInMATcard[t] = 0;
396 if(!isotIndexInMATcard[indIsotTab]) {
397 //compute physical data and counters
398 G4int ZIs = ptrIsot->GetZ();
399 G4double AIs = (ptrIsot->GetA())/(g);
400 G4int NIs = ptrIsot->GetN();
401 G4String nameIsot = ptrIsot->GetName();
403 isotIndexInMATcard[indIsotTab] = index;
405 //write on file MATERIAL card of isotope
406 PrintMaterial(fout, "MATERIAL ",
414 }// end if(numIsot==1)
415 }// end if(numElem==1)
419 // *** material definitions: elements, compound made of G4Elements
420 // or made of G4Materials
421 for(unsigned int j=0; j<totNumMat; j++) {
422 //pointer material, and material data
423 ptrMat = (*ptrMatTab)[j];
424 size_t numElem = ptrMat->GetNumberOfElements();
425 G4double densityMat = (ptrMat->GetDensity())/(g/cm3);
426 G4String nameMat = ptrMat->GetName();
430 //fraction vector of compounds of the material
431 const G4double* ptrFracVect = ptrMat->GetFractionVector();
433 //loop on elements of the material
434 for(unsigned int el=0; el<numElem; el++) {
435 //compute physical data, initialize variables
436 const G4Element * ptrElem = ptrMat->GetElement(el);
437 size_t indElemTab = ptrElem->GetIndex();
438 G4String nameElem = ptrElem->GetName();
440 size_t numIsot = ptrElem->GetNumberOfIsotopes();
441 G4double A = (ptrElem->GetA())/(g);
444 if(!elemIndexInMATcard[indElemTab]) {
445 G4double Z = ptrElem->GetZ();
446 G4double density = ptrFracVect[el]*densityMat;
447 elemIndexInMATcard[indElemTab] = indexCount;
449 //write on file MATERIAL card of element
450 PrintMaterial(fout, "MATERIAL ",
453 G4double(indexCount),
463 for(unsigned int nis=0; nis<numIsot; nis++) {
465 const G4Isotope* ptrIsot = ptrElem->GetIsotope(nis);
466 size_t indIsotTab = ptrIsot->GetIndex();
467 //initialize variables
469 totNumIsot = ptrIsot->GetNumberOfIsotopes();
470 ptrIsotTab = ptrIsot->GetIsotopeTable();
471 isotIndexInMATcard = new G4int[totNumIsot];
472 for(unsigned int t=0; t<totNumIsot; t++)
473 isotIndexInMATcard[t] = 0;
476 if(!isotIndexInMATcard[indIsotTab]) {
477 //compute physical data and counters
478 G4int ZIs = ptrIsot->GetZ();
479 G4double AIs = (ptrIsot->GetA())/(g);
480 G4int NIs = ptrIsot->GetN();
481 G4String nameIsot = ptrIsot->GetName();
483 G4double* ptrRelAbVect = ptrElem->GetRelativeAbundanceVector();
485 ptrFracVect[el]*densityMat*ptrRelAbVect[nis]*AIs/A;
486 G4int index = indexCount;
487 isotIndexInMATcard[indIsotTab] = indexCount;
490 //write on file MATERIAL card of isotope
491 PrintMaterial(fout, "MATERIAL ",
503 if(numElem>1 || isotPresence==1) {
504 // write MATERIAL+COMPOUND card specifing the compound
506 //flags for writing COMPOUND card
509 //make MATERIAL card for compound, start COMPOUND card
511 fout <<"* Define GEANT4 compound " << nameMat << G4endl;
512 PrintMaterial(fout, "MATERIAL ",
515 G4double(indexMatFluka[j]),
518 fout << setw10 << "COMPOUND ";
521 //write elements in COMPOUND card
522 for(unsigned int h=0; h<numElem; h++) {
523 const G4Element * ptrElemMat = ptrMat->GetElement(h);
524 size_t indexElemMat = ptrElemMat->GetIndex();
525 size_t numIsotElem = ptrElemMat->GetNumberOfIsotopes();
527 PrintCompound(fout, "COMPOUND ",
531 G4double(elemIndexInMATcard[indexElemMat]));
538 G4double * ptrIsotAbbVect =
539 ptrElemMat->GetRelativeAbundanceVector();
541 for(unsigned int iso=0; iso<numIsotElem; iso++) {
542 const G4Isotope * ptrIsotElem =ptrElemMat->GetIsotope(iso);
543 size_t indexIsotMat = ptrIsotElem->GetIndex();
544 G4double isotAbundPerVol =
545 ptrIsotAbbVect[iso]*Avogadro*densityMat*
546 ptrFracVect[h]/(ptrElemMat->GetA()/(g));
548 PrintCompound(fout, "COMPOUND ",
552 G4double(isotIndexInMATcard[indexIsotMat]));
562 fout << setw10 << " " << setw10 << " "
563 << setw10 << " " << setw10 << " "
564 << nameMat << G4endl;
566 fout << setw10 << " " << setw10 << " "
567 << nameMat << G4endl;
569 fout << nameMat << G4endl;
570 fout << "*" << G4endl;
575 delete elemIndexInMATcard;
577 delete isotIndexInMATcard;
581 // *** material-volume correspondence
582 PrintHeader(fout,"GEANT4 MATERIAL ASSIGNMENTS");
585 G4int indexMatOld = 0;
586 G4int indexRegFlukaFrom = 0;
587 G4int indexRegFlukaTo = 0;
590 G4int lastFlagField = 0;
592 //open file for volume-index correspondence
593 G4std::ofstream vout("Volumes_index.inp");
595 //... and write title
596 vout << "*" << G4endl;
597 vout << "******************** GEANT4 VOLUMES *******************\n";
598 vout << "*" << G4endl;
600 //loop over all volumes...
601 for(unsigned int l=0;l<numVol;l++) {
602 //index of the region
603 G4VPhysicalVolume * ptrVol = (*pVolStore)[l];
604 G4LogicalVolume * ptrLogVol = ptrVol->GetLogicalVolume();
605 G4int indexRegFluka = l+1;
608 //write index volume and name on file Volumes_index.inp
609 vout.setf(G4std::ios::left,G4std::ios::adjustfield);
610 vout << setw10 << indexRegFluka;
611 vout << G4std::setw(20) << ptrVol->GetName() << G4std::setw(20) << "";
612 if(ptrVol->IsReplicated()) {
618 ptrVol->GetReplicationData(axis,nRep,width,offset,consum);
619 vout.setf(G4std::ios::left,G4std::ios::adjustfield);
620 vout << setw10 << "Repetion Nb: " << G4std::setw(3) << nRep;
624 //check if Magnetic Field is present in the region
625 G4FieldManager * pMagFieldMan = ptrLogVol->GetFieldManager();
626 const G4Field * pMagField = 0;
628 pMagField = pMagFieldMan->GetDetectorField();
635 //index of material in the region
636 G4Material * ptrMat = ptrLogVol->GetMaterial();
639 size_t indexMatGeant = ptrMat->GetIndex();
640 indexMat = indexMatFluka[indexMatGeant];
645 //if materials are repeated
646 if(indexMat==indexMatOld && flagField==lastFlagField) {
647 indexRegFlukaTo=indexRegFluka;
650 fout << setw10 << G4double(indexRegFlukaTo);
651 fout << setw10 << "0.0";
652 fout << setw10 << G4double(flagField);
653 fout << setw10 << "0.0" << G4endl;
658 //write on file ASSIGNMAT card
660 //first complete last material card
663 fout << setw10 << "0.0";
664 fout << setw10 << "0.0";
665 fout << setw10 << G4double(lastFlagField);
666 fout << setw10 << "0.0" << G4endl;
670 fout << setw10 << G4double(indexRegFlukaTo);
671 fout << setw10 << "0.0";
672 fout << setw10 << G4double(lastFlagField);
673 fout << setw10 << "0.0" << G4endl;
676 // begin material card
677 fout << setw10 << "ASSIGNMAT ";
678 fout.setf(static_cast<G4std::ios::fmtflags>(0),G4std::ios::floatfield);
679 fout << setw10 << setfixed
680 << G4std::setprecision(1) << G4double(indexMat);
681 fout << setw10 << G4double(indexRegFluka);
684 indexRegFlukaFrom=indexRegFluka;
687 fout << setw10 << "0.0";
688 fout << setw10 << "0.0";
689 fout << setw10 << G4double(flagField);
690 fout << setw10 << "0.0" << G4endl;
693 lastFlagField = flagField;
694 indexMatOld = indexMat;
697 //assign material 1 to black-hole=n.vol+1
698 fout << setw10 << "ASSIGNMAT ";
699 fout << setw10 << "1.0";
700 fout << setw10 << G4double(numVol+1);
701 fout << setw10 << "0.0";
702 fout << setw10 << "0.0";
703 fout << setw10 << "0.0";
704 fout << setw10 << "0.0" << G4endl;
706 // *** magnetic field ***
707 if(fTransportationManager->GetFieldManager()->DoesFieldExist()) {
708 PrintHeader(fout,"GEANT4 MAGNETIC FIELD");
710 //get magnetic field pointer
711 const G4Field * pMagField =
712 fTransportationManager->GetFieldManager()->GetDetectorField();
714 //if uniform magnetic field, get value
720 //G4ThreeVector* Field = new G4ThreeVector(1.,2.,3.);
721 const G4UniformMagField *pUnifMagField =
722 dynamic_cast<const G4UniformMagField*>(pMagField);
724 G4double *pFieldValue = 0;
725 G4double *point = new G4double[3];
729 pUnifMagField->GetFieldValue(point,pFieldValue);
730 //non capisco perche' l'instruzione seguente non fa linkare. Indaga!!
731 //per ora posso usare GetFieldValue: va bene lo stesso.
732 //G4ThreeVector FieldValue = pUnifMagField->GetConstantFieldValue();
740 //write MGNFIELD card
741 fout << setw10 << "MGNFIELD ";
742 fout << setw10 << "";
743 fout << setw10 << "";
744 fout << setw10 << "";
745 fout.setf(static_cast<G4std::ios::fmtflags>(0),G4std::ios::floatfield);
746 fout << setw10 << setfixed
747 << G4std::setprecision(4) << Bx
751 } // end if magnetic field
755 delete [] indexMatFluka;
756 #ifdef G4GEOMETRY_DEBUG
757 G4cout << "<== Flugg FGeometryInit::createFlukaMatFile()" << G4endl;