]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TFluka/TFluka.cxx
Primary ionisation electrons come now correctly ordered from FLUKA.
[u/mrichter/AliRoot.git] / TFluka / TFluka.cxx
index cd7a3d0490d3bb7a2bfb560d6c1fd7903951003e..1c3a90f0fda5a30f7bffaf531116b0048eb88010 100644 (file)
@@ -30,6 +30,7 @@
 //
 
 #include <Riostream.h>
+#include <TList.h>
 
 #include "TFluka.h"
 #include "TFlukaCodes.h"
@@ -137,6 +138,7 @@ TFluka::TFluka()
    fStopped(kFALSE),
    fStopEvent(kFALSE),
    fStopRun(kFALSE),
+   fPrimaryElectronIndex(-1),
    fMaterials(0),
    fNVolumes(0),
    fCurrentFlukaRegion(-1),
@@ -174,6 +176,7 @@ TFluka::TFluka(const char *title, Int_t verbosity, Bool_t isRootGeometrySupporte
    fStopped(kFALSE),
    fStopEvent(kFALSE),
    fStopRun(kFALSE),
+   fPrimaryElectronIndex(-1),
    fMaterials(0),
    fNVolumes(0),
    fCurrentFlukaRegion(-1),
@@ -247,11 +250,12 @@ void TFluka::Init() {
     }
 
     fApplication->InitGeometry();
-
+    fApplication->ConstructOpGeometry();
     //
     // Add ions to PDG Data base
     //
      AddParticlesToPdgDataBase();
+     //
 }
 
 
@@ -262,9 +266,10 @@ void TFluka::FinishGeometry() {
 //
   if (fVerbosityLevel >=3) {
     cout << "==> TFluka::FinishGeometry() called." << endl;
-    printf("----FinishGeometry - nothing to do with TGeo\n");
+    printf("----FinishGeometry - applying misalignment if any\n");
     cout << "<== TFluka::FinishGeometry() called." << endl;
   }  
+  TVirtualMCApplication::Instance()->MisalignGeometry();
 } 
 
 //______________________________________________________________________________ 
@@ -983,7 +988,7 @@ Int_t TFluka::PDGFromId(Int_t id) const
   //
   // Return PDG code and pseudo ENDF code from Fluka code
   //                      Alpha     He3       Triton    Deuteron  gen. ion  opt. photon   
-    Int_t idSpecial[6] = {10020040, 10020030, 10010030, 10010020, 10000000, 50000050};
+    Int_t idSpecial[6] = {GetIonPdg(2,4), GetIonPdg(2, 3), GetIonPdg(1,3), GetIonPdg(1,2), GetIonPdg(0,0), 50000050};
   // IPTOKP array goes from official to internal
 
     if (id == kFLUKAoptical) {
@@ -995,7 +1000,7 @@ Int_t TFluka::PDGFromId(Int_t id) const
 // Error id    
     if (id == 0 || id < kFLUKAcodemin || id > kFLUKAcodemax) {
         if (fVerbosityLevel >= 3)
-            printf("PDGFromId: Error id = 0\n");
+            printf("PDGFromId: Error id = 0 %5d %5d\n", id, fCaller);
         return -1;
     }
 // Good id    
@@ -1116,21 +1121,22 @@ Bool_t TFluka::SetCut(const char* cutName, Double_t cutValue)
 }
 
 
-void TFluka::SetUserScoring(const char* option, Int_t npr, char* outfile, Float_t* what)
+void TFluka::SetUserScoring(const char* option, const char* sdum, Int_t npr, char* outfile, Float_t* what)
 {
 //
 // Adds a user scoring option to the list
 //
-    TFlukaScoringOption* opt = new TFlukaScoringOption(option, "User Scoring", npr,outfile,what);
+    TFlukaScoringOption* opt = new TFlukaScoringOption(option, sdum, npr,outfile,what);
     fUserScore->Add(opt);
 }
 //______________________________________________________________________________
-void TFluka::SetUserScoring(const char* option, Int_t npr, char* outfile, Float_t* what, const char* det1, const char* det2, const char* det3)
+void TFluka::SetUserScoring(const char* option, const char* sdum, Int_t npr, char* outfile, Float_t* what, 
+                           const char* det1, const char* det2, const char* det3)
 {
 //
 // Adds a user scoring option to the list
 //
-    TFlukaScoringOption* opt = new TFlukaScoringOption(option, "User Scoring", npr, outfile, what, det1, det2, det3);
+    TFlukaScoringOption* opt = new TFlukaScoringOption(option, sdum, npr, outfile, what, det1, det2, det3);
     fUserScore->Add(opt);
 }
 
@@ -1212,7 +1218,7 @@ void TFluka::InitPhysics()
 // Process Fluka specific scoring options
 //
     TFlukaScoringOption::SetStaticInfo(pFlukaVmcInp, fGeom);
-    Float_t loginp        = 49.0;
+    Float_t loginp        = -49.0;
     Int_t inp             = 0;
     Int_t nscore          = fUserScore->GetEntries();
     
@@ -1266,7 +1272,7 @@ void TFluka::InitPhysics()
 // Initialisation needed for Cerenkov photon production and transport
     TObjArray *matList = GetFlukaMaterials();
     Int_t nmaterial =  matList->GetEntriesFast();
-    fMaterials = new Int_t[nmaterial+3];
+    fMaterials = new Int_t[nmaterial+25];
     
     for (Int_t im = 0; im < nmaterial; im++)
     {
@@ -1335,11 +1341,22 @@ void TFluka::TrackPosition(TLorentzVector& position) const
     position.SetZ(GetZsco());
     position.SetT(TRACKR.atrack);
   }
-  else if (caller == kMGDRAW) { 
-    position.SetX(TRACKR.xtrack[TRACKR.ntrack]);
-    position.SetY(TRACKR.ytrack[TRACKR.ntrack]);
-    position.SetZ(TRACKR.ztrack[TRACKR.ntrack]);
-    position.SetT(TRACKR.atrack);
+  else if (caller == kMGDRAW) {
+      Int_t i = -1;
+      if ((i = fPrimaryElectronIndex) > -1) {
+         // Primary Electron Ionisation
+         Double_t x, y, z;
+         GetPrimaryElectronPosition(i, x, y, z);
+         position.SetX(x);
+         position.SetY(y);
+         position.SetZ(z);
+         position.SetT(TRACKR.atrack);
+      } else {
+         position.SetX(TRACKR.xtrack[TRACKR.ntrack]);
+         position.SetY(TRACKR.ytrack[TRACKR.ntrack]);
+         position.SetZ(TRACKR.ztrack[TRACKR.ntrack]);
+         position.SetT(TRACKR.atrack);
+      }
   }
   else if (caller == kSODRAW) { 
     position.SetX(TRACKR.xtrack[TRACKR.ntrack]);
@@ -1369,14 +1386,19 @@ void TFluka::TrackPosition(Double_t& x, Double_t& y, Double_t& z) const
   if (caller == kENDRAW    || caller == kUSDRAW || 
       caller == kBXExiting || caller == kBXEntering || 
       caller == kUSTCKV) { 
-    x = GetXsco();
-    y = GetYsco();
-    z = GetZsco();
+      x = GetXsco();
+      y = GetYsco();
+      z = GetZsco();
   }
   else if (caller == kMGDRAW || caller == kSODRAW) { 
-    x = TRACKR.xtrack[TRACKR.ntrack];
-    y = TRACKR.ytrack[TRACKR.ntrack];
-    z = TRACKR.ztrack[TRACKR.ntrack];
+      Int_t i = -1;
+      if ((i = fPrimaryElectronIndex) > -1) {
+         GetPrimaryElectronPosition(i, x, y, z);
+      } else {
+         x = TRACKR.xtrack[TRACKR.ntrack];
+         y = TRACKR.ytrack[TRACKR.ntrack];
+         z = TRACKR.ztrack[TRACKR.ntrack];
+      }
   }
   else if (caller == kMGResumedTrack) {
     x = TRACKR.spausr[0];
@@ -1550,18 +1572,34 @@ Double_t TFluka::Edep() const
   // If coming from usdraw we just signal particle production - no edep
   // If just first time after resuming, no edep for the primary
   FlukaCallerCode_t caller = GetCaller();
+    
   if (caller == kBXExiting || caller == kBXEntering || 
       caller == kUSDRAW    || caller == kMGResumedTrack) return 0.0;
   Double_t sum = 0;
-  if (TRACKR.mtrack > 1) printf("Edep: %6d\n", TRACKR.mtrack);
+  Int_t i = -1;
   
-  for ( Int_t j=0;j<TRACKR.mtrack;j++) {
-      sum +=TRACKR.dtrack[j];  
-  }
-  if (TRACKR.ntrack == 0 && TRACKR.mtrack == 0)
-      return fRull + sum;
-  else {
+  // Material with primary ionisation activated but number of primary electrons nprim = 0
+  if (fPrimaryElectronIndex == -2) return 0.0;
+  // nprim > 0
+  if ((i = fPrimaryElectronIndex) > -1) {
+      // Primary ionisation
+      sum = GetPrimaryElectronKineticEnergy(i);
+      if (sum > 100.) {
+         printf("edep > 100. %d %d %f \n", i, ALLDLT.nalldl, sum);
+      }
       return sum;
+  } else {
+      // Normal ionisation
+      if (TRACKR.mtrack > 1) printf("Edep: %6d\n", TRACKR.mtrack);
+      
+      for ( Int_t j=0;j<TRACKR.mtrack;j++) {
+         sum +=TRACKR.dtrack[j];  
+      }
+      if (TRACKR.ntrack == 0 && TRACKR.mtrack == 0)
+         return fRull + sum;
+      else {
+         return sum;
+      }
   }
 }
 
@@ -1572,7 +1610,8 @@ Int_t TFluka::CorrectFlukaId() const
    // and there is a call to endraw for energy deposition for each of them
    // and they have the track number of their parent, but different identity (pdg)
    // so we want to assign also their parent identity.
-   if( (IsTrackStop() )
+
+   if( (IsTrackStop())
         && TRACKR.ispusr[mkbmx2 - 4] == TRACKR.ispusr[mkbmx2 - 1]
         && TRACKR.jtrack != TRACKR.ispusr[mkbmx2 - 3] ) {
       if (fVerbosityLevel >=3)
@@ -1582,7 +1621,11 @@ Int_t TFluka::CorrectFlukaId() const
                << " assign parent PDG=" << PDGFromId(TRACKR.ispusr[mkbmx2 - 3]) << endl;
       return TRACKR.ispusr[mkbmx2 - 3]; // assign parent identity
    }
-   return TRACKR.jtrack;
+   if (TRACKR.jtrack <= 64){
+       return TRACKR.jtrack;
+   } else {
+       return TRACKR.j0trck;
+   }
 }
 
 
@@ -1605,6 +1648,7 @@ Double_t TFluka::TrackCharge() const
 // Return charge of the track currently transported
 // PAPROP.ichrge = electric charge of the particle
 // TRACKR.jtrack = identity number of the particle
+    
   FlukaCallerCode_t caller = GetCaller();
   if (caller != kEEDRAW) 
      return PAPROP.ichrge[CorrectFlukaId()+6];
@@ -1900,7 +1944,7 @@ Int_t TFluka::StepProcesses(TArrayI &proc) const
         break;
     case kKASOPHrefraction:
         iproc = kPLightRefraction;
-    case kEMSCOlocaledep : 
+    case kEMFSCOlocaldep : 
         iproc = kPPhotoelectric;
         break;
     default:
@@ -2256,8 +2300,6 @@ void TFluka::AddParticlesToPdgDataBase() const
 
     TDatabasePDG *pdgDB = TDatabasePDG::Instance();
 
-    const Int_t kion=10000000;
-
     const Double_t kAu2Gev   = 0.9314943228;
     const Double_t khSlash   = 1.0545726663e-27;
     const Double_t kErg2Gev  = 1/1.6021773349e-3;
@@ -2266,15 +2308,14 @@ void TFluka::AddParticlesToPdgDataBase() const
 //
 // Ions
 //
-
   pdgDB->AddParticle("Deuteron","Deuteron",2*kAu2Gev+8.071e-3,kTRUE,
-                     0,3,"Ion",kion+10020);
+                     0,3,"Ion",GetIonPdg(1,2));
   pdgDB->AddParticle("Triton","Triton",3*kAu2Gev+14.931e-3,kFALSE,
-                     khShGev/(12.33*kYear2Sec),3,"Ion",kion+10030);
+                     khShGev/(12.33*kYear2Sec),3,"Ion",GetIonPdg(1,3));
   pdgDB->AddParticle("Alpha","Alpha",4*kAu2Gev+2.424e-3,kTRUE,
-                     khShGev/(12.33*kYear2Sec),6,"Ion",kion+20040);
+                     khShGev/(12.33*kYear2Sec),6,"Ion",GetIonPdg(2,4));
   pdgDB->AddParticle("HE3","HE3",3*kAu2Gev+14.931e-3,kFALSE,
-                     0,6,"Ion",kion+20030);
+                     0,6,"Ion",GetIonPdg(2,3));
 }
 
 //
@@ -2289,10 +2330,12 @@ Int_t TFluka::GetNPrimaryElectrons()
 }
 
 //______________________________________________________________________________
-Double_t TFluka::GetPrimaryElectronKineticEnergy(Int_t i)
+Double_t TFluka::GetPrimaryElectronKineticEnergy(Int_t i) const
 {
-    Double_t ekin = -1.;
     // Returns kinetic energy of primary electron i
+
+    Double_t ekin = -1.;
+    
     if (i >= 0 && i < ALLDLT.nalldl) {
         ekin =  ALLDLT.talldl[i];
     } else {
@@ -2302,3 +2345,51 @@ Double_t TFluka::GetPrimaryElectronKineticEnergy(Int_t i)
     }
     return ekin;
 }
+
+void TFluka::GetPrimaryElectronPosition(Int_t i, Double_t& x, Double_t& y, Double_t& z) const
+{
+    // Returns position  of primary electron i
+        if (i >= 0 && i < ALLDLT.nalldl) {
+           x = ALLDLT.xalldl[i];
+           y = ALLDLT.yalldl[i];
+           z = ALLDLT.zalldl[i];
+           return;
+       } else {
+           Warning("GetPrimaryElectronPosition",
+                   "Primary electron index out of range %d %d \n",
+                   i, ALLDLT.nalldl);
+           return;
+       }
+       return;
+}
+
+Int_t TFluka::GetIonPdg(Int_t z, Int_t a, Int_t i) const
+{
+// Acording to
+// http://cepa.fnal.gov/psm/stdhep/pdg/montecarlorpp-2006.pdf
+
+  return 1000000000 + 10*1000*z + 10*a + i;
+}  
+     
+void  TFluka::PrimaryIonisationStepping(Int_t nprim)
+{
+// Call Stepping for primary ionisation electrons
+    Int_t i;
+// Protection against nprim > mxalld
+
+// Multiple steps for nprim > 0
+    if (nprim > 0) {
+       for (i = 0; i < nprim; i++) {
+           SetCurrentPrimaryElectronIndex(i);
+           (TVirtualMCApplication::Instance())->Stepping();
+           if (i == 0) SetTrackIsNew(kFALSE);
+       }       
+    } else {
+       // No primary electron ionisation
+       // Call Stepping anyway but flag nprim = 0 as index = -2
+       SetCurrentPrimaryElectronIndex(-2);
+       (TVirtualMCApplication::Instance())->Stepping();
+    }
+    // Reset the index
+    SetCurrentPrimaryElectronIndex(-1);
+}