Corrected indices. (E. Futo)
[u/mrichter/AliRoot.git] / TFluka / TFluka.cxx
index b439dc5742f6690d101b077c724aed0da938893f..e8aa67a429d2b07c3818e5732d4b7689747657d4 100644 (file)
 
 /*
 $Log$
+Revision 1.9  2002/12/06 12:41:29  morsch
+Mess from last merge cleaned up.
+
+Revision 1.8  2002/12/06 12:28:44  morsch
+Region to media mapping corrected and improved.
+
+Revision 1.7  2002/12/06 12:21:32  morsch
+User stepping methods added (E. Futo)
+
 Revision 1.6  2002/11/21 18:40:06  iglez2
 Media handling added
 
@@ -63,6 +72,7 @@ First commit of Fluka interface.
 
 #include <Riostream.h>
 
+#include "TClonesArray.h"
 #include "TFluka.h"
 #include "TCallf77.h"      //For the fortran calls
 #include "Fdblprc.h"       //(DBLPRC) fluka common
@@ -72,6 +82,7 @@ First commit of Fluka interface.
 #include "Fpaprop.h"       //(PAPROP) fluka common
 #include "Fpart.h"         //(PART)   fluka common
 #include "Ftrackr.h"       //(TRACKR) fluka common
+#include "Fpaprop.h"       //(PAPROP) fluka common
 #include "Ffheavy.h"       //(FHEAVY) fluka common
 
 #include "TVirtualMC.h"
@@ -80,6 +91,7 @@ First commit of Fluka interface.
 
 #include "FGeometryInit.hh"
 #include "TLorentzVector.h"
+#include "FlukaVolume.h"
 
 // Fluka methods that may be needed.
 #ifndef WIN32 
@@ -158,6 +170,10 @@ TFluka::TFluka(const char *title, Int_t verbosity)
 
   if (fVerbosityLevel >=3)
     cout << "<== TFluka::TFluka(" << title << ") constructor called." << endl;
+
+  fVolumeMediaMap = new TClonesArray("FlukaVolume",1000);
+  fNVolumes      = 0;
+  fMediaByRegion = 0;
 }
 
 TFluka::~TFluka() {
@@ -165,6 +181,9 @@ TFluka::~TFluka() {
     cout << "==> TFluka::~TFluka() destructor called." << endl;
 
   delete fGeometryManager;
+  fVolumeMediaMap->Delete();
+  delete  fVolumeMediaMap;
+  
 
   if (fVerbosityLevel >=3)
     cout << "<== TFluka::~TFluka() destructor called." << endl;
@@ -199,22 +218,36 @@ void TFluka::Init() {
   if (fVerbosityLevel >=3)
     cout << "<== TFluka::Init() called." << endl;
 
+  FinishGeometry();
+
 }
 
 void TFluka::FinishGeometry() {
+//
+// Build-up table with region to medium correspondance
+//
+    char tmp[5];
+    
   if (fVerbosityLevel >=3)
     cout << "==> TFluka::FinishGeometry() called." << endl;
 
-  fGeometryManager->Ggclos();
+//  fGeometryManager->Ggclos();
 
-  FGeometryInit* flugg = FGeometryInit::GetInstance();
-  map<TString, Int_t, less<TString> >::iterator i;
-  for (fVolumeMediaMap.begin(); i != fVolumeMediaMap.end(); i++) {
-    TString volName = (*i).first;
-    Int_t   media   = (*i).second;
-    Int_t   region  = flugg->GetRegionFromName(volName);
-    fMediaByRegion[region] = media;
+  FGeometryInit* flugg = FGeometryInit::GetInstance();  
+  
+  fMediaByRegion = new Int_t[fNVolumes+2];
+  for (Int_t i = 0; i < fNVolumes; i++)
+  {
+      FlukaVolume* vol = dynamic_cast<FlukaVolume*>((*fVolumeMediaMap)[i]);
+      TString volName = vol->GetName();
+      Int_t   media   = vol->GetMedium();
+      printf("Finish Geometry: volName, media %d %s %d \n", i, volName.Data(), media);
+      strcpy(tmp, volName.Data());
+      tmp[4] = '\0';
+      flugg->SetMediumFromName(tmp, media);
   }
+
+  flugg->BuildMediaMap();
   
   if (fVerbosityLevel >=3)
     cout << "<== TFluka::FinishGeometry() called." << endl;
@@ -339,37 +372,53 @@ void TFluka::Gstpar(Int_t itmed, const char *param, Double_t parval) {
 Int_t TFluka::Gsvolu(const char *name, const char *shape, Int_t nmed,  
                     Float_t *upar, Int_t np)  {
 //
-  fVolumeMediaMap[TString(name)] = nmed;
-  return fGeometryManager->Gsvolu(name, shape, nmed, upar, np); 
+//  fVolumeMediaMap[TString(name)] = nmed;
+    TClonesArray &lvols = *fVolumeMediaMap;
+    new(lvols[fNVolumes++]) 
+        FlukaVolume(name, nmed);
+    return fGeometryManager->Gsvolu(name, shape, nmed, upar, np); 
 }
 Int_t TFluka::Gsvolu(const char *name, const char *shape, Int_t nmed,  
                     Double_t *upar, Int_t np)  {
 //
-  return fGeometryManager->Gsvolu(name, shape, nmed, upar, np); 
+    TClonesArray &lvols = *fVolumeMediaMap;
+    new(lvols[fNVolumes++]) 
+        FlukaVolume(name, nmed);
+
+    return fGeometryManager->Gsvolu(name, shape, nmed, upar, np); 
 }
  
 void TFluka::Gsdvn(const char *name, const char *mother, Int_t ndiv, 
                   Int_t iaxis) {
 //
-  fGeometryManager->Gsdvn(name, mother, ndiv, iaxis); 
+    fGeometryManager->Gsdvn(name, mother, ndiv, iaxis); 
 } 
 
 void TFluka::Gsdvn2(const char *name, const char *mother, Int_t ndiv, 
                    Int_t iaxis, Double_t c0i, Int_t numed) {
 //
-  fGeometryManager->Gsdvn2(name, mother, ndiv, iaxis, c0i, numed); 
+    TClonesArray &lvols = *fVolumeMediaMap;
+    new(lvols[fNVolumes++]) 
+        FlukaVolume(name, numed);
+    fGeometryManager->Gsdvn2(name, mother, ndiv, iaxis, c0i, numed); 
 } 
 
 void TFluka::Gsdvt(const char *name, const char *mother, Double_t step, 
                   Int_t iaxis, Int_t numed, Int_t ndvmx) {
-//                     
-  fGeometryManager->Gsdvt(name, mother, step, iaxis, numed, ndvmx); 
+//     
+    TClonesArray &lvols = *fVolumeMediaMap;
+    new(lvols[fNVolumes++]) 
+        FlukaVolume(name, numed);              
+    fGeometryManager->Gsdvt(name, mother, step, iaxis, numed, ndvmx); 
 } 
 
 void TFluka::Gsdvt2(const char *name, const char *mother, Double_t step, 
                    Int_t iaxis, Double_t c0, Int_t numed, Int_t ndvmx) { 
 //
-  fGeometryManager->Gsdvt2(name, mother, step, iaxis, c0, numed, ndvmx); 
+    TClonesArray &lvols = *fVolumeMediaMap;
+    new(lvols[fNVolumes++]) 
+        FlukaVolume(name, numed);
+    fGeometryManager->Gsdvt2(name, mother, step, iaxis, c0, numed, ndvmx); 
 } 
 
 void TFluka::Gsord(const char *name, Int_t iax) {
@@ -425,8 +474,10 @@ void TFluka::WriteEuclid(const char* fileName, const char* topVol,
 //_____________________________________________________________________________
 // methods needed by the stepping
 //____________________________________________________________________________ 
+
 Int_t TFluka::GetMedium() const {
-  return fMediaByRegion[fCurrentFlukaRegion];
+    FGeometryInit* flugg = FGeometryInit::GetInstance();  
+    return flugg->GetMedium(fCurrentFlukaRegion);
 }
 
 
@@ -454,14 +505,32 @@ Int_t TFluka::PDGFromId(Int_t id) const
   Int_t intfluka = GetFlukaIPTOKP(id);
   //MPKDHA() goes from internal to PDG
   return mpdgha(intfluka);
-  
 }
 
-
-
 //_____________________________________________________________________________
 // methods for step management
 //____________________________________________________________________________ 
+//
+// set methods
+//
+void TFluka::SetMaxStep(Double_t)
+{
+// SetMaxStep is dummy procedure in TFluka !
+  cout << "SetMaxStep is dummy procedure in TFluka !" << endl;
+}
+
+void TFluka::SetMaxNStep(Int_t)
+{
+// SetMaxNStep is dummy procedure in TFluka !
+  cout << "SetMaxNStep is dummy procedure in TFluka !" << endl;
+}
+
+void TFluka::SetUserDecay(Int_t)
+{
+// SetUserDecay is dummy procedure in TFluka !
+  cout << "SetUserDecay is dummy procedure in TFluka !" << endl;
+}
+
 //
 // dynamic properties
 //
@@ -497,7 +566,7 @@ void TFluka::TrackMomentum(TLorentzVector& momentum) const
     return;
   }
   else {
-    Double_t p = sqrt(TRACKR.etrack*TRACKR.etrack - PAPROP.am[TRACKR.jtrack]*PAPROP.am[TRACKR.jtrack]);
+    Double_t p = sqrt(TRACKR.etrack*TRACKR.etrack - PAPROP.am[TRACKR.jtrack+6]*PAPROP.am[TRACKR.jtrack+6]);
     momentum.SetPx(p*TRACKR.cxtrck);
     momentum.SetPy(p*TRACKR.cytrck);
     momentum.SetPz(p*TRACKR.cztrck);
@@ -515,10 +584,17 @@ Double_t TFluka::TrackStep() const
 
 Double_t TFluka::TrackLength() const
 {
-// It is wrong
-// should be the sum of all steps starting from the beginning of the track
+// Still wrong !!!
+// This is the sum of substeps !!!
+// TRACKR.ctrack = total curved path of the current step
+// Sum of the substeps is identical to TRACKR.ctrack if the is no mag. field
+// The sum of all step length starting from the beginning of the track
 // for the time being returns only the length in centimeters of the current step
-    return TRACKR.ctrack;
+    Double_t sum = 0;
+    for ( Int_t j=0;j<TRACKR.ntrack;j++) {
+      sum +=TRACKR.ttrack[j];
+    }
+    return sum;
 }
 
 Double_t TFluka::TrackTime() const
@@ -561,12 +637,14 @@ 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
   return PAPROP.ichrge[TRACKR.jtrack+6];
 }
 
 Double_t TFluka::TrackMass() const
 {
 // PAPROP.am = particle mass in GeV
+// TRACKR.jtrack = identity number of the particle
   return PAPROP.am[TRACKR.jtrack+6];
 }
 
@@ -700,65 +778,117 @@ Bool_t   TFluka::IsTrackAlive() const
 
 Int_t TFluka::NSecondaries() const
 // Number of secondary particles generated in the current step
-// fIcode = 100 = elastic interaction
-// fIcode = 101 = inelastic interaction
-// fIcode = 102 = particle decay
-// fIcode = 103 = delta ray
-// fIcode = 104 = pair production
-// fIcode = 105 = bremsstrahlung
+// FINUC.np = number of secondaries except light and heavy ions
+// FHEAVY.npheav = number of secondaries for light and heavy secondary ions
 {
-  if (fIcode >= 100 && fIcode <= 105)
-    return FINUC.np + FHEAVY.npheav;
-  else 
-    return -1;
+  return FINUC.np + FHEAVY.npheav;
 }
 
 void     TFluka::GetSecondary(Int_t isec, Int_t& particleId,
                TLorentzVector& position, TLorentzVector& momentum)
-// 
-// fIcode = 100 = elastic interaction
-// fIcode = 101 = inelastic interaction
-// fIcode = 102 = particle decay
-// fIcode = 103 = delta ray
-// fIcode = 104 = pair production
-// fIcode = 105 = bremsstrahlung
 {
-  if (fIcode >= 100 && fIcode <= 105) {
-    if (isec >= 0 && isec < FINUC.np) {
-      particleId = PDGFromId(FINUC.kpart[isec]);
-      position.SetX(fXsco);
-      position.SetY(fYsco);
-      position.SetZ(fZsco);
-      position.SetT(FINUC.agesec[isec]);
-      momentum.SetPx(FINUC.plr[isec]*FINUC.cxr[isec]);
-      momentum.SetPy(FINUC.plr[isec]*FINUC.cyr[isec]);
-      momentum.SetPz(FINUC.plr[isec]*FINUC.czr[isec]);
-      momentum.SetE(FINUC.tki[isec] + PAPROP.am[FINUC.kpart[isec]+6]);
-    }
-    if (isec >= FINUC.np && isec < FINUC.np + FHEAVY.npheav) {
-      Int_t jsec = isec - FINUC.np;
-      particleId = FHEAVY.kheavy[jsec]; // this is Fluka id !!!
-      position.SetX(fXsco);
-      position.SetY(fYsco);
-      position.SetZ(fZsco);
-      position.SetT(FHEAVY.agheav[jsec]);
-      momentum.SetPx(FHEAVY.pheavy[jsec]*FHEAVY.cxheav[jsec]);
-      momentum.SetPy(FHEAVY.pheavy[jsec]*FHEAVY.cyheav[jsec]);
-      momentum.SetPz(FHEAVY.pheavy[jsec]*FHEAVY.czheav[jsec]);
-      if (FHEAVY.tkheav[jsec] >= 3 && FHEAVY.tkheav[jsec] <= 6) 
-        momentum.SetE(FHEAVY.tkheav[jsec] + PAPROP.am[jsec+6]);
-      else if (FHEAVY.tkheav[jsec] > 6)
-        momentum.SetE(FHEAVY.tkheav[jsec] + FHEAVY.amnhea[jsec]); // to be checked !!!
-    }
+  if (isec >= 0 && isec < FINUC.np) {
+         // more fine condition depending on icode
+         // icode = 100 ?
+         // icode = 101 OK
+         // icode = 102 OK
+         // icode = 103 ?
+         // icode = 104 ?
+         // icode = 105 ?
+         // icode = 208 ?
+         // icode = 210 ?
+         // icode = 212 ?
+         // icode = 214 OK
+         // icode = 215 OK
+         // icode = 219 ?
+         // icode = 221 OK
+         // icode = 225 ?
+         // icode = 300 ?
+         // icode = 400 ?
+         
+    particleId = PDGFromId(FINUC.kpart[isec]);
+    position.SetX(fXsco);
+    position.SetY(fYsco);
+    position.SetZ(fZsco);
+    position.SetT(TRACKR.atrack);
+//  position.SetT(TRACKR.atrack+FINUC.agesec[isec]); //not yet implem.
+    momentum.SetPx(FINUC.plr[isec]*FINUC.cxr[isec]);
+    momentum.SetPy(FINUC.plr[isec]*FINUC.cyr[isec]);
+    momentum.SetPz(FINUC.plr[isec]*FINUC.czr[isec]);
+    momentum.SetE(FINUC.tki[isec] + PAPROP.am[FINUC.kpart[isec]+6]);
   }
+  if (isec >= FINUC.np && isec < FINUC.np + FHEAVY.npheav) {
+    Int_t jsec = isec - FINUC.np;
+    particleId = FHEAVY.kheavy[jsec]; // this is Fluka id !!!
+    position.SetX(fXsco);
+    position.SetY(fYsco);
+    position.SetZ(fZsco);
+    position.SetT(TRACKR.atrack);
+//  position.SetT(TRACKR.atrack+FHEAVY.agheav[jsec]); //not yet implem.
+    momentum.SetPx(FHEAVY.pheavy[jsec]*FHEAVY.cxheav[jsec]);
+    momentum.SetPy(FHEAVY.pheavy[jsec]*FHEAVY.cyheav[jsec]);
+    momentum.SetPz(FHEAVY.pheavy[jsec]*FHEAVY.czheav[jsec]);
+    if (FHEAVY.tkheav[jsec] >= 3 && FHEAVY.tkheav[jsec] <= 6) 
+      momentum.SetE(FHEAVY.tkheav[jsec] + PAPROP.am[jsec+6]);
+    else if (FHEAVY.tkheav[jsec] > 6)
+      momentum.SetE(FHEAVY.tkheav[jsec] + FHEAVY.amnhea[jsec]); // to be checked !!!
+    }
 }
 
-//TMCProcess ProdProcess(Int_t isec) const
+TMCProcess TFluka::ProdProcess(Int_t isec) const
 // Name of the process that has produced the secondary particles
 // in the current step
-//{
-// will come from FINUC when called from USDRAW
-//}
+{
+  const TMCProcess kIpNoProc = kPNoProcess;
+  const TMCProcess kIpPDecay = kPDecay;
+  const TMCProcess kIpPPair = kPPair;
+//const TMCProcess kIpPPairFromPhoton = kPPairFromPhoton;
+//const TMCProcess kIpPPairFromVirtualPhoton = kPPairFromVirtualPhoton;
+  const TMCProcess kIpPCompton = kPCompton;
+  const TMCProcess kIpPPhotoelectric = kPPhotoelectric;
+  const TMCProcess kIpPBrem = kPBrem;
+//const TMCProcess kIpPBremFromHeavy = kPBremFromHeavy;
+//const TMCProcess kIpPBremFromElectronOrPositron = kPBremFromElectronOrPositron;
+  const TMCProcess kIpPDeltaRay = kPDeltaRay;
+//const TMCProcess kIpPMoller = kPMoller;
+//const TMCProcess kIpPBhabha = kPBhabha;
+  const TMCProcess kIpPAnnihilation = kPAnnihilation;
+//const TMCProcess kIpPAnnihilInFlight = kPAnnihilInFlight;
+//const TMCProcess kIpPAnnihilAtRest = kPAnnihilAtRest;
+  const TMCProcess kIpPHadronic = kPHadronic;
+  const TMCProcess kIpPMuonNuclear = kPMuonNuclear;
+  const TMCProcess kIpPPhotoFission = kPPhotoFission;
+  const TMCProcess kIpPRayleigh = kPRayleigh;
+  const TMCProcess kIpPCerenkov = kPCerenkov;
+  const TMCProcess kIpPSynchrotron = kPSynchrotron;
+
+  Int_t mugamma = TRACKR.jtrack == 7 || TRACKR.jtrack == 10 || TRACKR.jtrack == 11;
+  if (fIcode == 102) return kIpPDecay;
+  else if (fIcode == 104 || fIcode == 217) return kIpPPair;
+//else if (fIcode == 104) return kIpPairFromPhoton;
+//else if (fIcode == 217) return kIpPPairFromVirtualPhoton;
+  else if (fIcode == 219) return kIpPCompton;
+  else if (fIcode == 221) return kIpPPhotoelectric;
+  else if (fIcode == 105 || fIcode == 208) return kIpPBrem;
+//else if (fIcode == 105) return kIpPBremFromHeavy;
+//else if (fIcode == 208) return kPBremFromElectronOrPositron;
+  else if (fIcode == 103 || fIcode == 400) return kIpPDeltaRay;
+  else if (fIcode == 210 || fIcode == 212) return kIpPDeltaRay;
+//else if (fIcode == 210) return kIpPMoller;
+//else if (fIcode == 212) return kIpPBhabha;
+  else if (fIcode == 214 || fIcode == 215) return kIpPAnnihilation;
+//else if (fIcode == 214) return kIpPAnnihilInFlight;
+//else if (fIcode == 215) return kIpPAnnihilAtRest;
+  else if (fIcode == 101) return kIpPHadronic;
+  else if (fIcode == 101) {
+    if (!mugamma) return kIpPHadronic;
+    else if (TRACKR.jtrack == 7) return kIpPPhotoFission;
+    else return kIpPMuonNuclear;
+  }
+  else if (fIcode == 225) return kIpPRayleigh;
+// Fluka codes 100, 300 and 400 still to be investigasted
+  else return kIpNoProc;
+}
 
 //Int_t StepProcesses(TArrayI &proc) const
 // Return processes active in the current step
@@ -883,8 +1013,6 @@ void TFluka::FutoTest()
     cout << "TrackPid=" << TrackPid() << endl;
     cout << "NSecondaries=" << NSecondaries() << endl;
     for (Int_t isec=0; isec< NSecondaries(); isec++) {
-//void     TFluka::GetSecondary(Int_t isec, Int_t& particleId,
-//                 TLorentzVector& position, TLorentzVector& momentum)
       TFluka::GetSecondary(isec, particleId, position, momentum);
       cout << "TLorentzVector positionX=" << position.X()
            << "positionY=" << position.Y()
@@ -925,4 +1053,3 @@ void TFluka::FutoTest()
   
 
 } // end of FutoTest
-