]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TFluka/TFlukaMCGeometry.cxx
Check first if a material (element) has been predefined by FLUKA.
[u/mrichter/AliRoot.git] / TFluka / TFlukaMCGeometry.cxx
index d57facbe23c12a9f11ff9c25cc4e67a8a99aea4e..1199d3cf89de1b5615922d88916ec9d4d7990652 100644 (file)
@@ -27,6 +27,7 @@
 #include "TList.h"
 #include "TCallf77.h"
 #include "TFluka.h"
+#include "TSystem.h"
 #include "TFlukaMCGeometry.h"
 #include "TFlukaConfigOption.h"
 #include "TGeoManager.h" 
@@ -576,8 +577,7 @@ void TFlukaMCGeometry::CreateFlukaMatFile(const char *fname)
   // program load the right cross sections, and equal to the names included in
   // the .pemf. Otherwise the user must define the LOW-MAT CARDS, and make his
   // own .pemf, in order to get the right cross sections loaded in memory.
-
-
+  // Materials defined by FLUKA
    TString sname;
    gGeoManager->Export("flgeom.root");
    if (fname) sname = fname;
@@ -599,15 +599,13 @@ void TFlukaMCGeometry::CreateFlukaMatFile(const char *fname)
    element->SetTitle("ALUMINUM"); // this is how FLUKA likes it ...
    element = table->GetElement(15);
    element->SetTitle("PHOSPHO");  // same story ...
-//   element = table->GetElement(10);
-//   element->SetTitle("ARGON");  // NEON not in neutron xsec table
    Int_t nelements = table->GetNelements();
    TList *matlist = gGeoManager->GetListOfMaterials();
-//   TList *medlist = gGeoManager->GetListOfMedia();
-//   Int_t nmed = medlist->GetSize();
    TIter next(matlist);
    Int_t nmater = matlist->GetSize();
-   Int_t nfmater = 0;
+   Int_t nfmater =  0;
+   Int_t newind  = 26;  // here non predefined materials start
+   
    TGeoMaterial *mat;
    TGeoMixture *mix = 0;
    TString matname;
@@ -622,7 +620,14 @@ void TFlukaMCGeometry::CreateFlukaMatFile(const char *fname)
       rho = 0.999;
 
       mat = new TGeoMaterial(matname, element->A(), element->Z(), rho);
-      mat->SetIndex(nfmater+3);
+      // Check if the element has been predefined by FLUKA
+      Int_t pmid = GetPredefinedMaterialId(Int_t(element->Z()));
+      if (pmid > 0) {
+         mat->SetIndex(pmid);
+      } else {
+         mat->SetIndex(newind++);
+      }
+      
       mat->SetUsed(kTRUE);
       fMatList->Add(mat);
       objstr = new TObjString(matname.Data());
@@ -631,7 +636,6 @@ void TFlukaMCGeometry::CreateFlukaMatFile(const char *fname)
    }
    
    fIndmat = nfmater;
-//   TGeoMedium *med;
    // Adjust material names and add them to FLUKA list
    for (i=0; i<nmater; i++) {
       mat = (TGeoMaterial*)matlist->At(i);
@@ -646,7 +650,7 @@ void TFlukaMCGeometry::CreateFlukaMatFile(const char *fname)
       matname = mat->GetName();
       FlukaMatName(matname);
 
-      mat->SetIndex(nfmater+3);
+      mat->SetIndex(newind++);
       objstr = new TObjString(matname.Data());
       fMatList->Add(mat);
       fMatNames->Add(objstr);
@@ -1246,6 +1250,7 @@ void TFlukaMCGeometry::SetMreg(Int_t mreg, Int_t lttc)
    Int_t crtlttc = gGeoManager->GetCurrentNodeId()+1;
    if (crtlttc == lttc) return;
    gGeoManager->CdNode(lttc-1);
+   while (gGeoManager->GetCurrentVolume()->IsAssembly()) gGeoManager->CdUp();
 }
 
 //_____________________________________________________________________________
@@ -1349,8 +1354,33 @@ Int_t TFlukaMCGeometry::GetNstep()
    return gNstep;
 }
 
-// FLUKA GEOMETRY WRAPPERS - to replace FLUGG wrappers
 
+Int_t TFlukaMCGeometry::GetPredefinedMaterialId(Int_t z) const
+{
+// Get predifined material id from Z if present in list
+    const Int_t kMax = 25;
+    
+    static Int_t idFluka[kMax] =       
+       {-1, -1,  1,  2,  4,  6,  7,  8,  12,  13, 
+        26, 29, 47, 14, 79, 80, 82, 73,  11,  18, 
+        20, 50, 74, 22, 28};
+    
+    Int_t id = -1;
+
+    for (Int_t i = 0; i < kMax; i++)
+    {
+       if (z == idFluka[i]) {
+           id = i + 1;
+           break;
+       }
+
+  }
+  
+    return id;
+}
+
+// FLUKA GEOMETRY WRAPPERS - to replace FLUGG wrappers
+//
 //_____________________________________________________________________________
 Int_t idnrwr(const Int_t & /*nreg*/, const Int_t & /*mlat*/)
 {
@@ -1374,13 +1404,9 @@ void g1wr(Double_t &pSx, Double_t &pSy, Double_t &pSz,
 
 {
    // Initialize FLUKa point and direction;
+   static Int_t ierr = 0;
    gNstep++;
-
-//   if( (gNstep > 43912170 && gNstep < 43912196 ) ||
-//       (gNstep > 47424560 && gNstep < 47424581  ) ||
-//       (gNstep > 54388266 && gNstep < 54388319 )
-//       ) gMCGeom->SetDebugMode();
-//   else gMCGeom->SetDebugMode(kFALSE);
+//      gMCGeom->SetDebugMode(kTRUE);
    
    NORLAT.xn[0] = pSx;
    NORLAT.xn[1] = pSy;
@@ -1393,11 +1419,15 @@ void g1wr(Double_t &pSx, Double_t &pSy, Double_t &pSz,
       oldReg = gGeoManager->GetCurrentVolume()->GetNumber();
    }
 
-   if (gMCGeom->IsDebugging()) cout << "g1wr gNstep=" << gNstep
-                                    << " oldReg="<< oldReg <<" olttc="<< olttc
-                                    << " track=" << TRACKR.ispusr[mkbmx2-1] << endl;
-
-   Int_t ccreg,cclat;
+   if (gMCGeom->IsDebugging()) {
+      cout << "g1wr gNstep=" << gNstep << " oldReg="<< oldReg <<" olttc="<< olttc
+           << " track=" << TRACKR.ispusr[mkbmx2-1] << endl;
+      cout << " point: (" << pSx << ", " << pSy << ", " << pSz << ")  dir: ("
+           << pV[0] << ", " << pV[1] << ", " << pV[2] << ")" << endl;
+   }        
+           
+
+   Int_t ccreg=0,cclat=0;
    gMCGeom->GetCurrentRegion(ccreg,cclat);
    Bool_t crossed = (ccreg==oldReg && cclat==olttc)?kFALSE:kTRUE;
 
@@ -1444,21 +1474,68 @@ void g1wr(Double_t &pSx, Double_t &pSy, Double_t &pSz,
 
    gGeoManager->SetCurrentPoint(pSx, pSy, pSz);
    gGeoManager->SetCurrentDirection(pV);
-
+   Double_t pt[3], local[3], ldir[3];
+   Int_t pid = TRACKR.jtrack;
+   pt[0] = pSx;
+   pt[1] = pSy;
+   pt[2] = pSz;
+   gGeoManager->MasterToLocal(pt,local);
+   gGeoManager->MasterToLocalVect(pV,ldir);
+/*
+   Bool_t valid = gGeoManager->GetCurrentVolume()->Contains(local);
+   if (!valid) {
+      printf("location not valid in %s pid=%i\n", gGeoManager->GetPath(),pid);
+      printf("local:(%f, %f, %f)  ldir:(%f, %f, %f)\n", local[0],local[1],local[2],ldir[0],ldir[1],ldir[2]);
+//      gGeoManager->FindNode();
+//      printf("   -> actual location: %s\n", gGeoManager->GetPath());
+   }   
+*/
+   Double_t pstep = propStep;
+   Double_t snext = propStep;
+   const Double_t epsil = 0.9999999 * TGeoShape::Tolerance();
+   // This should never happen !!!
+   if (pstep<TGeoShape::Tolerance()) {
+      printf("Proposed step is 0 !!!\n");
+      pstep = 2.*TGeoShape::Tolerance();
+   }   
    if (crossed) {
-      gGeoManager->FindNextBoundaryAndStep(propStep);
-      saf = 0.0;
+      gGeoManager->FindNextBoundaryAndStep(pstep);
+      snext = gGeoManager->GetStep();
+      saf = 0.;
+      if (snext <= TGeoShape::Tolerance()) {
+//         printf("FLUKA crossed boundary but snext=%g\n", snext);
+         ierr++;
+         snext = epsil;
+      } else {
+         snext += TGeoShape::Tolerance();
+         ierr = 0;
+      }     
    } else {
-      gGeoManager->FindNextBoundaryAndStep(propStep, kTRUE);
+      gGeoManager->FindNextBoundaryAndStep(pstep, kTRUE);
+      snext = gGeoManager->GetStep();
       saf = gGeoManager->GetSafeDistance();
-      if (saf<0) saf=0.0;
+      if (snext <= TGeoShape::Tolerance()) {
+//         printf("FLUKA put particle on bondary without crossing\n");
+         ierr++;
+         snext = epsil;
+         saf = 0.;
+      } else {
+         snext += TGeoShape::Tolerance();
+         ierr = 0;
+      }      
+      if (saf<0) saf=0.;
       saf -= saf*3.0e-09;
    }
-
-   Double_t snext = gGeoManager->GetStep();
-
-   if (snext<=0.0) snext = TGeoShape::Tolerance();
-
+//   if (ierr>1) {
+//      printf("%d snext=%g\n", ierr, snext);
+//   }   
+   if (ierr == 10) {
+//      printf("Too many null steps - sending error code -33...\n");
+      newReg = -33;   // Error code
+      ierr = 0;
+      return;
+   }   
+   
    PAREM.dist = snext;
    NORLAT.distn = snext;
    NORLAT.xn[0] += snext*pV[0];
@@ -1480,7 +1557,6 @@ void g1wr(Double_t &pSx, Double_t &pSy, Double_t &pSz,
    // We really crossed the boundary, but is it the same region ?
    gMCGeom->SetNextRegion(newReg, newLttc);
 
-   Int_t pid = TRACKR.jtrack;
    if ( ((newReg==oldReg && newLttc!=olttc) || (oldReg!=newReg && olttc==newLttc) ) && pid!=-1) {
       // Virtual boundary between replicants
       newReg  = gFluka->GetDummyRegion();
@@ -1603,7 +1679,8 @@ void lkwr(Double_t &pSx, Double_t &pSy, Double_t &pSz,
       printf("   in: oldReg=%i oldLttc=%i\n", oldReg, oldLttc);
    }   
    flagErr = 0;
-   TGeoNode *node = gGeoManager->FindNode(pSx, pSy, pSz);
+   Double_t epsil = 1000.*TGeoShape::Tolerance();
+   TGeoNode *node = gGeoManager->FindNode(pSx+epsil*pV[0], pSy+epsil*pV[1], pSz+epsil*pV[2]);
    if (gGeoManager->IsOutside()) {
       newReg = gMCGeom->NofVolumes()+2;
       newLttc = TFlukaMCGeometry::kLttcOutside;
@@ -1637,8 +1714,8 @@ void lkwr(Double_t &pSx, Double_t &pSy, Double_t &pSz,
 
    if( oldReg!=newReg && oldLttc==newLttc ) {
       // this should not happen!! ??? Ernesto
-       cout << "  lkwr      oldReg!=newReg ("<< oldReg <<"!="<< newReg
-            << ") && oldLttc==newLttc ("<< newLttc <<") !!!!!!!!!!!!!!!!!" << endl;
+//       cout << "  lkwr      oldReg!=newReg ("<< oldReg <<"!="<< newReg
+//            << ") && oldLttc==newLttc ("<< newLttc <<") !!!!!!!!!!!!!!!!!" << endl;
       newReg  = dummy;
       newLttc = TFlukaMCGeometry::kLttcVirtual;
       flagErr = newReg;