From ae4a521be158a871010841a61169cc4e92dfbc4f Mon Sep 17 00:00:00 2001
From: matta <matta@npt>
Date: Tue, 17 Jul 2012 14:22:18 +0000
Subject: [PATCH] Gamma and Particle Decay working

---
 Inputs/EventGenerator/10He.reaction           |  31 +-
 .../include/EventGeneratorGammaDecay.hh       |  77 ++++
 .../include/EventGeneratorParticleDecay.hh    |  89 ++++
 .../include/PrimaryGeneratorAction.hh         |   5 +-
 NPSimulation/include/VEventGenerator.hh       |   3 +-
 NPSimulation/src/EventGeneratorGammaDecay.cc  | 398 ++++++++++++++++
 .../src/EventGeneratorParticleDecay.cc        | 434 ++++++++++++++++++
 NPSimulation/src/EventGeneratorTransfert.cc   |  13 +-
 NPSimulation/src/PrimaryGeneratorAction.cc    | 247 +++++-----
 9 files changed, 1171 insertions(+), 126 deletions(-)
 create mode 100644 NPSimulation/include/EventGeneratorGammaDecay.hh
 create mode 100644 NPSimulation/include/EventGeneratorParticleDecay.hh
 create mode 100644 NPSimulation/src/EventGeneratorGammaDecay.cc
 create mode 100644 NPSimulation/src/EventGeneratorParticleDecay.cc

diff --git a/Inputs/EventGenerator/10He.reaction b/Inputs/EventGenerator/10He.reaction
index fd541ea4a..95cc7b9f6 100644
--- a/Inputs/EventGenerator/10He.reaction
+++ b/Inputs/EventGenerator/10He.reaction
@@ -2,25 +2,42 @@
 %%%%%%%%% Reaction file for 11Li(d,3He)10He reaction %%%%%%%%%
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%Beam energy given in MeV ; Excitation in MeV
-TransfertToResonance
+Transfert
 	Beam= 11Li
 	Target= 2H
 	Light= 3He
 	Heavy= 10He
 	ExcitationEnergyLight= 0.0
-	ExcitationEnergyHeavy= 1.0
+	ExcitationEnergyHeavy= 10.0
 	BeamEnergy= 550
 	BeamEnergySpread= 0
 	SigmaThetaX= 0.01
 	SigmaPhiY= 0.01
 	SigmaX= 0.01
 	SigmaY= 0.01
-	ResonanceWidth= 0
-	ResonanceDecayZ= 2
-	ResonanceDecayA= 8
 	CrossSectionPath= 11Li(d,3He)10He.txt	
 	ShootLight= 1
-	ShootHeavy= 0
-	ShootDecayProduct= 0
+	ShootHeavy= 1
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+    
+ParticleDecay 10He
+    Daughter= 9He n
+    ExcitationEnergy= 0.5 0
+    DifferentialCrossSection= flat.txt
+    shoot= 1 1
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+GammaDecay 9He
+    Cascade
+        BranchingRatio= 30
+        Energies= 0.1
+        DifferentialCrossSection= flat.txt
+    Cascade
+        BranchingRatio= 70
+        Energies= 0.2 0.3
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+ParticleDecay 9He
+    Daughter= 8He n
+    DifferentialCrossSection= flat.txt
+    shoot= 1 1
\ No newline at end of file
diff --git a/NPSimulation/include/EventGeneratorGammaDecay.hh b/NPSimulation/include/EventGeneratorGammaDecay.hh
new file mode 100644
index 000000000..ae030178e
--- /dev/null
+++ b/NPSimulation/include/EventGeneratorGammaDecay.hh
@@ -0,0 +1,77 @@
+#ifndef EventGeneratorGammaDecay_H
+#define EventGeneratorGammaDecay_H
+/*****************************************************************************
+ * Copyright (C) 2009-2010   this file is part of the NPTool Project         *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Adrien MATTA  contact address: matta@ipno.in2p3.fr       *
+ *                                                                           *
+ * Creation Date  : May 2012                                                 *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This event Generator is used to simulated a gamma decay of nuclei genera-*
+ * ted by previous event generator. Multiple cases are supported:            *
+ *  - Only one gamma is emmited, in this case a Cross section can be given   *
+ *  - A cascade decay, in this case the CS is ignore                         *
+ *  - If more than one cascade are given, Branching Ratio could be given     *
+ *                                                                           *
+ *  Using the "Source Token" the class can be used to simulate gamma ray sou-*
+ * rce and Doppler shifted gamma rays.                                       *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *                                                                           *
+ *                                                                           *
+ *****************************************************************************/
+
+// STL
+#include <string>
+#include <iostream>
+using namespace std;
+
+// NPSimulation
+#include "VEventGenerator.hh"
+#include "Target.hh"
+#include "ParticleStack.hh"
+
+class EventGeneratorGammaDecay : public VEventGenerator
+{
+    public: // Constructor and destructor
+        EventGeneratorGammaDecay();
+        ~EventGeneratorGammaDecay();
+    
+    public: // Inherit from VEventGenerator class
+        void ReadConfiguration(string,int);
+        void GenerateEvent(G4Event*);
+        void SetTarget(Target* Target) ;
+    
+    private: // Target Parameter
+        Target* m_Target;
+
+
+    private: // The decaying nuclei
+        string m_NucleiName;
+    private: // the gamma rays property 
+        vector<double>  m_BranchingRatio;
+        vector<string>  m_CrossSectionPath;
+        vector<double*> m_CrossSectionArray;
+        vector<double>  m_CrossSectionThetaMin;
+        vector<double>  m_CrossSectionThetaMax;
+        vector<double>  m_CrossSectionSize;
+        vector<double>  m_CascadeTotalEnergy;
+        vector< vector<double> > m_Energies;
+        
+    private: // Pointer to the Particle stack for faster acces
+        ParticleStack* m_ParticleStack;
+    public: // Managing the different cascade
+        // Add a new cascade
+        void AddCascade(vector<double> Energies, double BranchingRatio=-1, string CrossSectionPath="_void_");
+        // Read all the added cscade en instentiate every thing that is needed
+        void PrepareCascade();
+};
+#endif
\ No newline at end of file
diff --git a/NPSimulation/include/EventGeneratorParticleDecay.hh b/NPSimulation/include/EventGeneratorParticleDecay.hh
new file mode 100644
index 000000000..2c344524a
--- /dev/null
+++ b/NPSimulation/include/EventGeneratorParticleDecay.hh
@@ -0,0 +1,89 @@
+#ifndef EventGeneratorParticleDecay_H
+#define EventGeneratorParticleDecay_H
+/*****************************************************************************
+ * Copyright (C) 2009-2010   this file is part of the NPTool Project         *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Adrien MATTA  contact address: matta@ipno.in2p3.fr       *
+ *                                                                           *
+ * Creation Date  : May 2012                                                 *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This event Generator is used to simulated the particle decay of nuclei   *
+ * generated by previous event generator. Multiple cases are supported:      *
+ *  - Only one particle is emmited, in this case a Cross section can be given*
+ *  - If Multiple particle are emitted, a Phase Space generator is used      *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *                                                                           *
+ *                                                                           *
+ *****************************************************************************/
+
+// STL
+#include <string>
+#include <iostream>
+using namespace std;
+
+// ROOT
+#include "TGenPhaseSpace.h"
+
+// G4 headers including CLHEP headers
+// for generating random numbers
+#include "Randomize.hh"
+
+// NPSimulation
+#include "VEventGenerator.hh"
+#include "Target.hh"
+#include "ParticleStack.hh"
+
+// Geant4
+#include "G4ParticleDefinition.hh"
+
+class EventGeneratorParticleDecay : public VEventGenerator
+{
+    public: // Constructor and destructor
+        EventGeneratorParticleDecay();
+        ~EventGeneratorParticleDecay();
+    
+    public: // Inherit from VEventGenerator class
+        void ReadConfiguration(string,int);
+        void GenerateEvent(G4Event*);
+        void SetTarget(Target* Target) ;
+    
+    private: // Target Parameter
+        Target* m_Target;
+
+    private: // The decaying nuclei
+        // General used 
+        string m_MotherNucleiName;
+        vector<G4ParticleDefinition*> m_DaughterNuclei;
+        vector<string> m_DaughterName;
+        vector<double> m_ExcitationEnergy;
+        vector<bool>   m_shoot;
+    
+        // Used for cross section
+        string  m_DifferentialCrossSection;
+        double* m_CrossSectionArray;
+        double  m_CrossSectionThetaMin;
+        double  m_CrossSectionThetaMax;
+        double  m_CrossSectionSize;
+        RandGeneral* m_CrossSectionShoot;
+    
+        // Used for the phase space
+        TGenPhaseSpace m_TPhaseSpace ;
+        double* m_Masses;
+    
+    private: // Pointer to the Particle stack for faster acces
+        ParticleStack* m_ParticleStack;
+    public: // Managing the decay
+        // Set everything for the decay
+        void SetDecay(vector<string> DaughterName, vector<bool> shoot, vector<double> ExcitationEnergy, string CSPath);
+};
+#endif
\ No newline at end of file
diff --git a/NPSimulation/include/PrimaryGeneratorAction.hh b/NPSimulation/include/PrimaryGeneratorAction.hh
index dfc2cce7e..0313fa172 100644
--- a/NPSimulation/include/PrimaryGeneratorAction.hh
+++ b/NPSimulation/include/PrimaryGeneratorAction.hh
@@ -27,7 +27,6 @@
 
 // G4 headers
 #include "G4VUserPrimaryGeneratorAction.hh"
-#include "G4ParticleGun.hh"
 #include "G4Event.hh"
 
 // NPTool headers
@@ -46,15 +45,13 @@ public:
 
 public:
    void GeneratePrimaries(G4Event*);
-   G4ParticleGun* GetParticleGun()   {return m_particleGun;}
 
 public:
    void ReadEventGeneratorFile(string Path);
 
 private:
-   G4ParticleGun*        m_particleGun;
    DetectorConstruction* m_detector;
-   VEventGenerator*      m_EventGenerator;
+   vector<VEventGenerator*>      m_EventGenerator;
 };
 
 #endif
diff --git a/NPSimulation/include/VEventGenerator.hh b/NPSimulation/include/VEventGenerator.hh
index b158b6ae8..f65a0b019 100644
--- a/NPSimulation/include/VEventGenerator.hh
+++ b/NPSimulation/include/VEventGenerator.hh
@@ -54,7 +54,8 @@ public:
 
 public:
    virtual void ReadConfiguration(string) {};
-   virtual void GenerateEvent(G4Event*, G4ParticleGun*) {};
+   virtual void ReadConfiguration(string,int) {};
+   virtual void GenerateEvent(G4Event*) {};
    virtual void InitializeRootOutput() {};
 
    // Used in some case to generate event inside the target
diff --git a/NPSimulation/src/EventGeneratorGammaDecay.cc b/NPSimulation/src/EventGeneratorGammaDecay.cc
new file mode 100644
index 000000000..788c90fd5
--- /dev/null
+++ b/NPSimulation/src/EventGeneratorGammaDecay.cc
@@ -0,0 +1,398 @@
+/*****************************************************************************
+ * Copyright (C) 2009-2010   this file is part of the NPTool Project         *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Adrien MATTA  contact address: matta@ipno.in2p3.fr       *
+ *                                                                           *
+ * Creation Date  : May 2012                                                 *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This event Generator is used to simulated a gamma decay of nuclei genera-*
+ * ted by previous event generator. Multiple cases are supported:            *
+ *  - Only one gamma is emmited, in this case a Cross section can be given   *
+ *  - A cascade decay, in this case the CS is ignore                         *
+ *  - If more than one cascade are given, Branching Ratio could be given     *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *                                                                           *
+ *                                                                           *
+ *****************************************************************************/
+
+#include "EventGeneratorGammaDecay.hh"
+
+// NPS
+#include "Particle.hh"
+
+// G4 headers including CLHEP headers
+// for generating random numbers
+#include "Randomize.hh"
+
+// G4
+#include "G4ParticleTable.hh"
+
+// ROOT
+#include "TLorentzVector.h"
+#include "TVector3.h"
+EventGeneratorGammaDecay::EventGeneratorGammaDecay(){
+    m_ParticleStack = ParticleStack::getInstance();
+}
+
+EventGeneratorGammaDecay::~EventGeneratorGammaDecay(){
+    
+}
+
+void EventGeneratorGammaDecay::ReadConfiguration(string Path, int Occurence){
+    ////////General Reading needs////////
+    string LineBuffer;
+    string DataBuffer;
+    istringstream LineStream;
+    int TokenOccurence = 0 ;
+    //////// Setting needs///////
+    unsigned int NumberOfCascade = 0;
+    bool ReadingStatusGammaDecay  = false ;
+    bool CascadeStatus = false ;
+    
+    bool check_E = false;
+    bool check_BranchingRatio = false;
+    bool check_CSPath = false ;
+    bool check_created = false;
+    
+    //////////////////////////////////////////////////////////////////////////////////////////
+    ifstream InputFile;
+    InputFile.open(Path.c_str());
+    
+    if (InputFile.is_open()) {} else {
+        return;
+    }
+    
+    while (!InputFile.eof() && !check_created) {
+        //Pick-up next line
+        getline(InputFile, LineBuffer);
+        
+        if (LineBuffer.compare(0, 10, "GammaDecay") == 0) { 
+            TokenOccurence++;
+            if (TokenOccurence == Occurence) {
+                ReadingStatusGammaDecay = true ;
+                G4cout << "///////////////////////////////////////// " << G4endl;
+                // Get the nuclei name
+                LineStream.clear();
+                LineStream.str(LineBuffer);
+                LineStream >> DataBuffer;
+                DataBuffer.erase();
+                LineStream >> DataBuffer;
+                m_NucleiName = DataBuffer ;
+                G4cout << "Gamma Decay for " << m_NucleiName << G4endl;
+            }
+        }
+        
+        ///////////////////////////////
+        /// Gamma Decay case
+        while(ReadingStatusGammaDecay){
+            InputFile >> DataBuffer;
+            //Search for comment Symbol %
+            if (DataBuffer.compare(0, 1, "%") == 0) {   InputFile.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );}
+            
+            else if (DataBuffer == "Cascade") {
+                CascadeStatus = true ;
+                NumberOfCascade++;
+                G4cout << "  Cascade " << NumberOfCascade << G4endl;
+                
+                LineStream.clear();
+                LineStream.str(LineBuffer);
+                
+                // Instantiate new variable for the up coming cascade
+                check_E = false;
+                check_BranchingRatio = false;
+                check_CSPath = false ;
+                
+                double BranchingRatio = -1;
+                vector<double> E ;
+                string CSPath;
+                
+                while (CascadeStatus) {
+                    getline(InputFile, LineBuffer);
+                    LineStream.clear();
+                    LineStream.str(LineBuffer);
+                    LineStream >> DataBuffer ;
+                      
+                    // G4cout << DataBuffer << G4endl;
+                    
+                    //Search for comment Symbol %
+                    if (DataBuffer.compare(0, 1, "%") == 0) {   InputFile.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );}
+                    
+                    else if(DataBuffer == "BranchingRatio=") {
+                        check_BranchingRatio = true;
+                        LineStream.clear();
+                        LineStream.str(LineBuffer);
+                        LineStream >> DataBuffer ;
+                        LineStream >> DataBuffer ;
+                        BranchingRatio = atof(DataBuffer.c_str());
+                        G4cout << "    Branching Ratio: " << atof(DataBuffer.c_str()) << G4endl;
+                        
+                    }
+                    
+                    else if(DataBuffer == "Energies=") {
+                        check_E = true;
+                        G4cout << "    Energies: " ;
+                        LineStream.clear();
+                        LineStream.str(LineBuffer);
+                        LineStream >> DataBuffer;
+                        while(LineStream >> DataBuffer){
+                            E.push_back(atof(DataBuffer.c_str()));
+                            G4cout << atof(DataBuffer.c_str()) << " ";    
+                            
+                        }
+                        G4cout << G4endl;
+                    }
+                    
+                    else if(DataBuffer == "DifferentialCrossSection="){
+                        LineStream.clear();
+                        LineStream.str(LineBuffer);
+                        LineStream >> DataBuffer >> DataBuffer ;
+                        CSPath = DataBuffer;
+                        G4cout << "    Cross Section Path: " << DataBuffer << G4endl;
+                        check_CSPath = true;
+                    }
+                    
+                    // Cascade ended
+                    if(check_E && check_BranchingRatio && E.size()>1){
+                        AddCascade(E, BranchingRatio, "_void_");
+                        CascadeStatus = false;
+                    }
+                    
+                    if(check_E && check_BranchingRatio && (E.size()<2 && check_CSPath)){                        AddCascade(E, BranchingRatio, CSPath);
+                        CascadeStatus = false;
+                    }
+
+                }
+                
+            }
+            
+            //////////////////////////////////////////////////////
+            // If no Token and no comment, toggle out //
+            //  else 
+            //   {ReadingStatusGammaDecay = false; G4cout << "WARNING : Wrong Token Sequence: Getting out " << G4endl ;}
+         
+            
+            if(InputFile.eof()) {ReadingStatusGammaDecay=false;check_created=true;}
+        }
+    }
+    G4cout << "///////////////////////////////////////// " << G4endl;
+    InputFile.close();
+    PrepareCascade();
+}
+
+
+void EventGeneratorGammaDecay::GenerateEvent(G4Event*){
+    // Choose a Cascade to follow
+    int ChoosenCascade = -1;
+    double RandomNumber = RandFlat::shoot();
+    
+    for (unsigned int i = 1; i<m_BranchingRatio.size(); i++) {
+        if(RandomNumber > m_BranchingRatio[i-1] && RandomNumber< m_BranchingRatio[i])
+            ChoosenCascade=i;
+    }  
+    
+    if (ChoosenCascade==-1) ChoosenCascade=0;
+    
+    // Look for the decaying nucleus
+    Particle decayingParticle = m_ParticleStack->SearchAndRemoveParticle(m_NucleiName);
+
+    if(decayingParticle.GetParticleDefinition()==NULL){
+        G4cout << "Gamma Decay Warning: The decaying particle " << m_NucleiName
+        << " was not found in the particle stack " << G4endl;
+        return ;   
+    }
+    // Check for energies conservation (i.e: Cascade Energies lower than Excitation energie)
+    string ExcitationString = decayingParticle.GetParticleDefinition()->GetParticleName();
+    ExcitationString.erase(0,m_NucleiName.length()+1);
+    ExcitationString.erase(ExcitationString.length()-1,ExcitationString.length());
+    double ExcitationEnergy = atof(ExcitationString.c_str())*keV;
+    
+    // Compute the final excitation energy of the decaying nuclei
+    double FinalExcitationEnergy = ExcitationEnergy-m_CascadeTotalEnergy[ChoosenCascade];
+    if(FinalExcitationEnergy<0){
+        G4cout << "Gamma Decay Warning: The cascade energy exceed the excitation energy of the decaying nuclei: " 
+        << G4endl << " Excitation Energy : " << ExcitationEnergy
+        << G4endl << " Cascade Energy : "    <<    m_CascadeTotalEnergy[ChoosenCascade] << G4endl;
+        FinalExcitationEnergy=0;
+    }
+    
+    // Put back the decaying nucleus with its new excitation energy
+    G4ParticleDefinition* FinalParticleDefition
+    = G4ParticleTable::GetParticleTable()->GetIon(decayingParticle.GetParticleDefinition()->GetAtomicNumber(), decayingParticle.GetParticleDefinition()->GetAtomicMass(), FinalExcitationEnergy*MeV);
+    
+    Particle FinalParticle = Particle(  FinalParticleDefition,
+                                        decayingParticle.GetParticleKineticEnergy(),
+                                        decayingParticle.GetParticleMomentumDirection(),
+                                        decayingParticle.GetParticlePosition(),
+                                        decayingParticle.GetShootStatus());
+    
+    m_ParticleStack->AddParticleToStack(FinalParticle);
+    
+    // Instantiate and add the gamma to the particle stack
+    for (unsigned int i = 0; i < m_Energies[ChoosenCascade].size(); i++) {
+        G4ParticleDefinition* gammaDefinition = G4ParticleTable::GetParticleTable()->FindParticle("gamma");
+        G4ThreeVector gammaDirection;
+        double theta=0;
+        double phi=0;
+        // If more than one gamma shoot no cross section to follow
+        if(m_Energies[ChoosenCascade].size()>1){
+            
+            // Shoot flat in cos(theta) and Phi to have isotropic emission
+            double cos_theta = RandFlat::shoot();
+            theta = acos(cos_theta);
+            phi = RandFlat::shoot()*2.*pi;
+                
+            gammaDirection= G4ThreeVector(  cos(phi)*sin(theta),
+                                            sin(phi)*sin(theta),
+                                            cos(theta));
+        }
+        
+        // Only one gamma to shoot, use the given cross section
+        else{ 
+            RandGeneral CrossSectionShoot(m_CrossSectionArray[ChoosenCascade], m_CrossSectionSize[ChoosenCascade]);
+            theta = (   m_CrossSectionThetaMin[ChoosenCascade] 
+                        + CrossSectionShoot.shoot() 
+                        * ( m_CrossSectionThetaMax[ChoosenCascade] - m_CrossSectionThetaMin[ChoosenCascade]) ) * deg;
+            phi   = RandFlat::shoot() * 2. *pi;     
+            gammaDirection= G4ThreeVector(  cos(phi)*sin(theta),
+                                            sin(phi)*sin(theta),
+                                            cos(theta));
+        }
+        
+        // Doppler shifted gamma emission
+        decayingParticle.GetParticleMomentumDirection();
+        double gammaEnergy = m_Energies[ChoosenCascade][i];
+        TLorentzVector GammaLV( gammaEnergy*cos(phi)*sin(theta),
+                                gammaEnergy*sin(phi)*sin(theta),
+                                gammaEnergy*cos(theta),
+                                gammaEnergy);
+        
+        double NucleiEnergy= decayingParticle.GetParticleKineticEnergy()+FinalParticleDefition->GetPDGMass();
+        double NucleiMomentum= sqrt(NucleiEnergy*NucleiEnergy-FinalParticleDefition->GetPDGMass()*FinalParticleDefition->GetPDGMass());
+        TLorentzVector NuvleiLV( NucleiMomentum*decayingParticle.GetParticleMomentumDirection().x(),
+                                 NucleiMomentum*decayingParticle.GetParticleMomentumDirection().y(),
+                                 NucleiMomentum*decayingParticle.GetParticleMomentumDirection().z(),
+                                 NucleiEnergy);
+        
+        GammaLV.Boost(NuvleiLV.BoostVector());
+        gammaDirection= G4ThreeVector(  GammaLV.Px(),
+                                        GammaLV.Py(),
+                                        GammaLV.Pz());
+        // Add the gamma to the stack
+        Particle gammaParticle(gammaDefinition,GammaLV.E(),gammaDirection, decayingParticle.GetParticlePosition());
+        m_ParticleStack->AddParticleToStack(gammaParticle);
+    }
+}
+
+
+void EventGeneratorGammaDecay::SetTarget(Target* Target){
+    m_Target = Target;
+}
+
+void EventGeneratorGammaDecay::AddCascade(vector<double> Energies, double BranchingRatio, string CrossSectionPath){
+    m_BranchingRatio.push_back(BranchingRatio);
+    m_CrossSectionPath.push_back(CrossSectionPath);
+    m_Energies.push_back(Energies);
+}
+
+void EventGeneratorGammaDecay::PrepareCascade(){
+    // Change the given branching ratio so total is one (always have a decay during the event)
+    double TotalRatio=0;
+    for (unsigned int i = 0; i < m_BranchingRatio.size(); i++) {
+        TotalRatio+=m_BranchingRatio[i]/100.;
+    }
+    
+    // Check that the total ratio is not over 100% (below is allowed)
+    if(TotalRatio>1) {
+        G4cout << "Gamma Decay Error: Sum of branching ratio is over 100%" << endl;
+        exit(1);
+    }
+    
+    for (unsigned int i = 0; i < m_BranchingRatio.size(); i++) {
+        m_BranchingRatio[i]=(m_BranchingRatio[i]/TotalRatio)/100.;
+    }
+    
+    // Shift the Branching ratio for faster shooting during event generation
+    for (unsigned int i = 1; i < m_BranchingRatio.size(); i++) {
+        m_BranchingRatio[i]=m_BranchingRatio[i-1]+m_BranchingRatio[i];
+    }
+    
+    // Compute the total energy of the cascade
+    double TotalEnergy=0;
+    for (unsigned int i = 0 ; i < m_Energies.size(); i++) {
+        TotalEnergy=0;
+        for (unsigned int j = 0; j < m_Energies[i].size(); j++) {
+            TotalEnergy+=m_Energies[i][j];
+        }
+        m_CascadeTotalEnergy.push_back(TotalEnergy);
+    }
+    
+    // Transform the particle name to G4 standard: i.e: 10He -> He10
+    m_NucleiName = m_ParticleStack->ChangeNameToG4Standard(m_NucleiName);
+         if (m_NucleiName=="proton"   || 
+             m_NucleiName=="deuteron" || 
+             m_NucleiName=="triton"   || 
+             m_NucleiName=="3He"      || 
+             m_NucleiName=="alpha"    ){
+                G4cout << "Gamma Decay Error: Gamma Decay not allowed for light particles" << endl;
+                exit(1);
+             }
+    
+    /// Load the differential cross section
+    for (unsigned int i = 0; i < m_BranchingRatio.size(); i++) {
+        unsigned int CrossSectionSize = 0;
+        double* CrossSection = new double[CrossSectionSize] ;
+        double thetamin = 0;
+        double thetamax = 0;
+        
+        if(m_CrossSectionPath[i]!="_void_"){
+            string GlobalPath = getenv("NPTOOL");
+            string StandardPath = GlobalPath + "/Inputs/CrossSection/" + m_CrossSectionPath[i];
+            ifstream CSFile;
+            CSFile.open( StandardPath.c_str() );
+            
+            if(CSFile.is_open()) cout << "Reading Cross Section File " << m_CrossSectionPath[i] << endl;
+            
+            // In case the file is not found in the standard path, the programm try to interpret the file name as an absolute or relative file path.
+            else{
+                CSFile.open( m_CrossSectionPath[i].c_str() );
+                if(CSFile.is_open()) { cout << "Reading Cross Section File " << m_CrossSectionPath[i] << endl;}
+                
+                else {cout << "Cross Section File " << m_CrossSectionPath[i] << " not found" << endl;return;}
+            }
+            
+            double CSBuffer,AngleBuffer;
+            vector<double> CrossSectionBuffer;
+            thetamin = 200;
+            thetamax = -10;
+            while(!CSFile.eof()) {
+                CSFile >> AngleBuffer;
+                CSFile >> CSBuffer;   
+                double CSFinal = CSBuffer*sin(AngleBuffer*deg);
+                CrossSectionBuffer.push_back(CSFinal);
+                if (AngleBuffer < thetamin) thetamin = AngleBuffer;
+                if (AngleBuffer > thetamax) thetamax = AngleBuffer;
+            }
+            
+            CSFile.close();
+            CrossSectionSize = CrossSectionBuffer.size();
+            delete CrossSection;
+            CrossSection = new double[CrossSectionSize] ;
+            for(unsigned int i = 0 ; i <CrossSectionSize ; i++ )   CrossSection[i] = CrossSectionBuffer[i];
+        }
+        m_CrossSectionArray.push_back(CrossSection);
+        m_CrossSectionSize.push_back(CrossSectionSize);
+        m_CrossSectionThetaMax.push_back(thetamax);
+        m_CrossSectionThetaMin.push_back(thetamin);
+    }
+}
+
diff --git a/NPSimulation/src/EventGeneratorParticleDecay.cc b/NPSimulation/src/EventGeneratorParticleDecay.cc
new file mode 100644
index 000000000..813d00211
--- /dev/null
+++ b/NPSimulation/src/EventGeneratorParticleDecay.cc
@@ -0,0 +1,434 @@
+/*****************************************************************************
+ * Copyright (C) 2009-2010   this file is part of the NPTool Project         *
+ *                                                                           *
+ * For the licensing terms see $NPTOOL/Licence/NPTool_Licence                *
+ * For the list of contributors see $NPTOOL/Licence/Contributors             *
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Original Author: Adrien MATTA  contact address: matta@ipno.in2p3.fr       *
+ *                                                                           *
+ * Creation Date  : May 2012                                                 *
+ * Last update    :                                                          *
+ *---------------------------------------------------------------------------*
+ * Decription:                                                               *
+ *  This event Generator is used to simulated the particle decay of nuclei   *
+ * generated by previous event generator. Multiple cases are supported:      *
+ *  - Only one particle is emmited, in this case a Cross section can be given*
+ *  - If Multiple particle are emitted, a Phase Space generator is used      *
+ *                                                                           *
+ *---------------------------------------------------------------------------*
+ * Comment:                                                                  *
+ *                                                                           *
+ *                                                                           *
+ *                                                                           *
+ *****************************************************************************/
+
+#include "EventGeneratorParticleDecay.hh"
+
+// NPS
+#include "Particle.hh"
+
+// G4
+#include "G4ParticleTable.hh"
+
+// NPL
+#include "NPNucleus.h"
+using namespace NPL;
+
+// ROOT
+#include "TLorentzVector.h"
+#include "TVector3.h"
+EventGeneratorParticleDecay::EventGeneratorParticleDecay(){
+    m_ParticleStack = ParticleStack::getInstance();
+}
+
+EventGeneratorParticleDecay::~EventGeneratorParticleDecay(){
+    
+}
+
+void EventGeneratorParticleDecay::ReadConfiguration(string Path,int Occurence){
+    ////////General Reading needs////////
+    string LineBuffer;
+    string DataBuffer;
+    istringstream LineStream;
+    int TokkenOccurence = 0;
+    //////// Setting needs///////
+    bool ReadingStatusParticleDecay  = false ;
+    
+    bool check_Daughter = false ;
+    bool check_CrossSection = false ;
+    bool check_ExcitationEnergy = false ;
+    bool check_shoot = false ;
+    bool check_created = false ;
+    
+    // Instantiate new variable for the up coming Particle
+    vector<string> DaughterName;
+    vector<double> ExcitationEnergy;
+    vector<bool>   shoot;
+    string CSPath = "TGenPhaseSpace";
+    
+    //////////////////////////////////////////////////////////////////////////////////////////
+    ifstream InputFile;
+    InputFile.open(Path.c_str());
+    
+    if (InputFile.is_open()) {} 
+    
+    else {
+        return;
+    }
+    
+    while (!InputFile.eof()&& !check_created) {
+        //Pick-up next line
+        getline(InputFile, LineBuffer);
+        
+        if (LineBuffer.compare(0, 13, "ParticleDecay") == 0) { 
+            TokkenOccurence++;
+            if(TokkenOccurence==Occurence){
+                ReadingStatusParticleDecay = true ;
+                G4cout << "///////////////////////////////////////// " << G4endl;
+                // Get the nuclei name
+                LineStream.clear();
+                LineStream.str(LineBuffer);
+                LineStream >> DataBuffer;
+                DataBuffer.erase();
+                LineStream >> DataBuffer;
+                m_MotherNucleiName = DataBuffer ;
+                G4cout << "Particle Decay for " << m_MotherNucleiName << G4endl;
+            }
+        }
+        
+        ///////////////////////////////
+        /// Gamma Decay case
+        while(ReadingStatusParticleDecay){
+            
+            InputFile >> DataBuffer;
+            //Search for comment Symbol %
+            if (DataBuffer.compare(0, 1, "%") == 0) {   
+                InputFile.ignore ( std::numeric_limits<std::streamsize>::max(), '\n' );
+            }
+            
+            else if (DataBuffer == "Daughter=") {
+                check_Daughter = true ;
+                LineStream.clear();
+                LineStream.str(LineBuffer);
+                
+                getline(InputFile, LineBuffer);
+                LineStream.clear();
+                LineStream.str(LineBuffer);
+                G4cout << "    Daughter: " ;
+                while(LineStream >> DataBuffer){
+                    DaughterName.push_back(DataBuffer);
+                    G4cout << DataBuffer << " " ;
+                }
+        
+                G4cout << G4endl;
+                       
+            } 
+                    
+            else if(DataBuffer == "ExcitationEnergy=") {
+                check_ExcitationEnergy = true;
+                LineStream.clear();
+                LineStream.str(LineBuffer);
+                
+                getline(InputFile, LineBuffer);
+                LineStream.clear();
+                LineStream.str(LineBuffer);
+                G4cout << "    Excitation Energy: " ;
+                while(LineStream >> DataBuffer){
+                    ExcitationEnergy.push_back( atof(DataBuffer.c_str()) );
+                    G4cout << DataBuffer << " " ;
+                }
+                
+                G4cout << G4endl;
+            }
+            
+            else if(DataBuffer == "DifferentialCrossSection=") {
+                check_CrossSection = true;
+                InputFile >> CSPath ;
+                G4cout << "    Cross Section: " << CSPath << G4endl;
+            }
+            
+            else if(DataBuffer == "shoot=") {
+                check_shoot = true;
+                LineStream.clear();
+                LineStream.str(LineBuffer);
+                
+                getline(InputFile, LineBuffer);
+                LineStream.clear();
+                LineStream.str(LineBuffer);
+                G4cout << "    Shoot Particle: " ;
+                while(LineStream >> DataBuffer){
+                    shoot.push_back( atof(DataBuffer.c_str()) );
+                    G4cout << DataBuffer << " " ;
+                }
+                
+                G4cout << G4endl;
+            }
+            
+            
+            
+            //////////////////////////////////////////////////////
+            // If no Token and no comment, toggle out //
+            else 
+                {ReadingStatusParticleDecay = false; G4cout << "ERROR : Wrong Token Sequence: Getting out " << G4endl ;
+                    exit(1);
+                }
+
+            // Decay ended
+            if(check_Daughter && check_shoot){
+                SetDecay(DaughterName,shoot,ExcitationEnergy,CSPath);
+                ReadingStatusParticleDecay = false;
+                check_created=true;
+            }
+        }
+    }
+    
+    G4cout << "///////////////////////////////////////// " << G4endl;
+    InputFile.close();
+}
+
+
+void EventGeneratorParticleDecay::GenerateEvent(G4Event* anEvent){
+    // Look for the decaying nucleus
+    Particle decayingParticle = m_ParticleStack->SearchAndRemoveParticle(m_MotherNucleiName);
+    if(decayingParticle.GetParticleDefinition()==NULL){
+        G4cout << "Gamma Decay Warning: The decaying particle " << m_MotherNucleiName
+        << " was not found in the particle stack " << G4endl;
+        return ;   
+    }
+    
+    G4ParticleDefinition* decayingParticleDefinition = decayingParticle.GetParticleDefinition();
+    // Build the decaying particle four momenta vector:
+
+    double NucleiEnergy= decayingParticle.GetParticleKineticEnergy()+decayingParticleDefinition->GetPDGMass();
+    
+    double NucleiMomentum=sqrt(NucleiEnergy*NucleiEnergy -
+                            decayingParticleDefinition->GetPDGMass()*decayingParticleDefinition->GetPDGMass());
+    
+    G4ThreeVector Momentum = decayingParticle.GetParticleMomentumDirection().unit();
+    
+    // Case of one particle decaying with a user given cross section
+    if(m_DifferentialCrossSection!="TGenPhaseSpace"){
+        TLorentzVector NucleiLV( NucleiMomentum*Momentum.x(),
+                                 NucleiMomentum*Momentum.y(),
+                                 NucleiMomentum*Momentum.z(),
+                                 NucleiEnergy);
+        // Shoot the angle in Center of Mass (CM) frame
+        G4double ThetaCM = (m_CrossSectionThetaMin + m_CrossSectionShoot->shoot() * (m_CrossSectionThetaMax - m_CrossSectionThetaMin)) * deg;
+        G4double phi     = RandFlat::shoot()*2.*pi;
+
+        // Build daughter particule CM LV
+        // Pre compute variable for the decay
+        double M  = decayingParticleDefinition->GetPDGMass();
+        double m1 = m_DaughterNuclei[0]->GetPDGMass();
+        double m2 = m_DaughterNuclei[1]->GetPDGMass();
+        
+        if(M<(m1+m2))
+            cout << "Warning: Particle Decay forbiden by kinematic, no particle emitted "<<endl;
+        
+        else {
+            double Energy = ( 1./(2.*M) )*( M*M + m1*m1 - m2*m2);
+            double Momentum = sqrt(Energy*Energy - m1*m1);
+            
+            TVector3 FirstDaughterMomentum = Momentum * TVector3( sin(ThetaCM) * cos(phi),
+                                                                  sin(ThetaCM) * sin(phi),
+                                                                  cos(ThetaCM));
+            
+            TLorentzVector FirstDaughterLV(FirstDaughterMomentum,Energy);
+            
+            FirstDaughterLV.Boost( NucleiLV.BoostVector() );
+            TLorentzVector SecondDaughterLV = NucleiLV - FirstDaughterLV;
+            
+            G4ThreeVector DaughterDirection = G4ThreeVector( FirstDaughterLV.X()   ,
+                                                             FirstDaughterLV.Y()   ,
+                                                             FirstDaughterLV.Z()   ); 
+            
+            Particle FirstDaughterParticle( m_DaughterNuclei[0],
+                                            FirstDaughterLV.E()-m_DaughterNuclei[0]->GetPDGMass(),
+                                            DaughterDirection.unit(), 
+                                            decayingParticle.GetParticlePosition(),
+                                            m_shoot[0]);
+            
+            DaughterDirection = G4ThreeVector( SecondDaughterLV.X()   ,
+                                               SecondDaughterLV.Y()   ,
+                                               SecondDaughterLV.Z()   ); 
+            
+            Particle SecondDaughterParticle( m_DaughterNuclei[1],
+                                             SecondDaughterLV.E()-m_DaughterNuclei[1]->GetPDGMass(),
+                                             DaughterDirection.unit(), 
+                                             decayingParticle.GetParticlePosition(),
+                                             m_shoot[1]);
+            
+            ParticleStack::getInstance()->AddParticleToStack(FirstDaughterParticle);
+            ParticleStack::getInstance()->AddParticleToStack(SecondDaughterParticle);
+        }
+    }
+    
+    // Case of a TGenPhaseSpace
+    else{
+        TLorentzVector NucleiLV( NucleiMomentum*Momentum.x()/GeV,
+                                 NucleiMomentum*Momentum.y()/GeV,
+                                 NucleiMomentum*Momentum.z()/GeV,
+                                 NucleiEnergy/GeV);
+        
+        if( !m_TPhaseSpace.SetDecay(NucleiLV, m_DaughterNuclei.size(), m_Masses) ) 
+            cout << "Warning: Phase Space Decay forbiden by kinematic, or more than 18 particles, no particle emitted "<<endl;
+        
+        else{  
+            m_TPhaseSpace.Generate();
+            
+            TLorentzVector* daughterLV ;
+            double KineticEnergy;
+            
+            for (unsigned int i = 0 ;  i < m_DaughterNuclei.size(); i++) {
+                
+                daughterLV = m_TPhaseSpace.GetDecay(i);
+                G4ThreeVector daughterDirection = G4ThreeVector( daughterLV->X()   ,
+                                                                 daughterLV->Y()   ,
+                                                                 daughterLV->Z()   );            
+                
+                KineticEnergy   = daughterLV->E()-m_Masses[i] ;
+                
+                Particle daughterParticle( m_DaughterNuclei[i],
+                                          KineticEnergy*GeV,
+                                          daughterDirection.unit(), 
+                                          decayingParticle.GetParticlePosition(),
+                                          m_shoot[i]);
+                ParticleStack::getInstance()->AddParticleToStack(daughterParticle);
+            }
+        }
+    }
+}
+
+
+void EventGeneratorParticleDecay::SetTarget(Target* Target){
+    m_Target = Target;
+}
+
+void EventGeneratorParticleDecay::SetDecay(vector<string> DaughterName, vector<bool> shoot, vector<double> ExcitationEnergy, string CSPath){
+    
+    // Check the validity of the given data:
+    if (DaughterName.size() != shoot.size() || (DaughterName.size() != ExcitationEnergy.size() && ExcitationEnergy.size()!=0) ) {
+        G4cout << "ERROR : Missmatching information: Getting out " << G4endl ;
+        exit(1);
+    }
+    
+    if ( DaughterName.size() != 2 && CSPath!="TGenPhaseSpace" ) {
+        G4cout << "ERROR 2: Missmatching information: Getting out " << G4endl ;
+        exit(1);
+    }
+    
+    m_shoot = shoot ;
+    m_ExcitationEnergy= ExcitationEnergy ;
+    
+    // If the Excitation Energy Token was omitted, then it is set to zero
+    if(m_ExcitationEnergy.size()==0)
+        for (unsigned int i = 0 ; i < DaughterName.size(); i++) {
+            m_ExcitationEnergy.push_back(0);
+        }
+    
+    // used check for mass and charge conservation
+    Nucleus*  myNucleus = new Nucleus(m_MotherNucleiName);
+    int InitialCharge = myNucleus->GetZ() ; int FinalCharge = 0 ;
+    int InitialMass   = myNucleus->GetA() ; int FinalMass   = 0 ;
+    delete myNucleus;
+    for (unsigned int i = 0 ; i< DaughterName.size(); i++) {
+        if(DaughterName[i] == "p"){
+            m_DaughterNuclei.push_back(G4ParticleTable::GetParticleTable()->FindParticle("proton"));
+            FinalMass++;FinalCharge++;
+        }
+        
+        else if (DaughterName[i] == "n"){
+            m_DaughterNuclei.push_back(G4ParticleTable::GetParticleTable()->FindParticle("neutron"));
+            FinalMass++;
+        }
+        
+        else{ 
+            Nucleus*  myNucleus = new Nucleus(DaughterName[i]);
+            m_DaughterNuclei.push_back(G4ParticleTable::GetParticleTable()->GetIon(myNucleus->GetZ(), 
+                                                                                   myNucleus->GetA(),
+                                                                                   m_ExcitationEnergy[i]*MeV));
+            FinalMass+=myNucleus->GetA();
+            FinalCharge+=myNucleus->GetZ();
+            delete myNucleus;
+        }
+    }
+    
+    // Check mass and charge conservation
+    if (InitialMass!=FinalMass || InitialCharge!=FinalCharge) {
+        G4cout << "ERROR: Mass and charge are not conserved." << G4endl;
+        exit(1);
+    }
+    
+    m_DaughterName = DaughterName;
+    
+    m_DifferentialCrossSection = CSPath;
+    if(CSPath!="TGenPhaseSpace") {
+        unsigned int CrossSectionSize = 0;
+        double* m_CrossSection = new double[CrossSectionSize] ;
+        double  m_CrossSectionThetaMin = 0;
+        double  m_CrossSectionThetaMax = 0;
+        
+        string GlobalPath = getenv("NPTOOL");
+        string StandardPath = GlobalPath + "/Inputs/CrossSection/" + m_DifferentialCrossSection;
+        ifstream CSFile;
+        CSFile.open( StandardPath.c_str() );
+        
+        if(CSFile.is_open()) cout << "Reading Cross Section File " << m_DifferentialCrossSection << endl;
+        
+        // In case the file is not found in the standard path, the programm try to interpret the file name as an absolute or relative file path.
+        else{
+            CSFile.open( m_DifferentialCrossSection.c_str() );
+            if(CSFile.is_open()) { 
+                cout << "Reading Cross Section File " << m_DifferentialCrossSection << endl;
+            }
+            
+            else {
+                cout << "ERROR : Cross Section File " << m_DifferentialCrossSection << " not found" << endl;
+                exit(1);
+            }
+        }
+        
+        double CSBuffer,AngleBuffer;
+        vector<double> CrossSectionBuffer;
+        m_CrossSectionThetaMin = 200;
+        m_CrossSectionThetaMax = -10;
+        while(!CSFile.eof()) {
+            CSFile >> AngleBuffer;
+            CSFile >> CSBuffer;   
+            double CSFinal = CSBuffer*sin(AngleBuffer*deg);
+            CrossSectionBuffer.push_back(CSFinal);
+            if (AngleBuffer < m_CrossSectionThetaMin) m_CrossSectionThetaMin = AngleBuffer;
+            if (AngleBuffer > m_CrossSectionThetaMax) m_CrossSectionThetaMax = AngleBuffer;
+        }
+        
+        CSFile.close();
+        
+        m_CrossSectionSize = CrossSectionBuffer.size();
+        m_CrossSectionArray = new double[CrossSectionBuffer.size()] ;
+        
+        for(unsigned int i = 0 ; i < m_CrossSectionSize ; i++ ) {  
+            m_CrossSectionArray[i] = CrossSectionBuffer[i];
+        }
+        
+        m_CrossSectionShoot = new RandGeneral(m_CrossSectionArray, m_CrossSectionSize);
+
+    }
+    
+    
+    else{
+        // Set up the array of masses
+        m_Masses = new double[m_DaughterNuclei.size()];
+        
+        // Mass of the daugther nuclei are set once
+        for (unsigned int i = 0 ; i < m_DaughterNuclei.size(); i++) {
+            m_Masses[i] = m_DaughterNuclei[i]->GetPDGMass()/GeV;
+        }
+        
+    }
+    
+    // Change the name of the decaying nucleus to G4 standard
+    m_MotherNucleiName = m_ParticleStack->ChangeNameToG4Standard(m_MotherNucleiName);
+    
+}
\ No newline at end of file
diff --git a/NPSimulation/src/EventGeneratorTransfert.cc b/NPSimulation/src/EventGeneratorTransfert.cc
index feb67d4bf..435b5f687 100644
--- a/NPSimulation/src/EventGeneratorTransfert.cc
+++ b/NPSimulation/src/EventGeneratorTransfert.cc
@@ -185,7 +185,11 @@ void EventGeneratorTransfert::ReadConfiguration(string Path)
 
       
 
-      if (LineBuffer.compare(0, 9, "Transfert") == 0) { ReadingStatus = true ;}
+      if (LineBuffer.compare(0, 9, "Transfert") == 0) { 
+          ReadingStatus = true ;
+      
+          G4cout << "////////// Transfert ///////////" << G4endl;
+      }
 
 
    while(ReadingStatus){
@@ -323,10 +327,11 @@ void EventGeneratorTransfert::ReadConfiguration(string Path)
       //   If all Token found toggle out
          if(check_Beam && check_Target && check_Light && check_Heavy && check_ExcitationEnergyLight && check_ExcitationEnergyHeavy 
             &&  check_BeamEnergy && check_BeamEnergySpread && check_FWHMX && check_FWHMY && check_EmmitanceTheta 
-            &&  check_EmmitancePhi && check_CrossSectionPath && check_ShootLight && check_ShootHeavy)
-            ReadingStatus = false ;   
-
+            &&  check_EmmitancePhi && check_CrossSectionPath && check_ShootLight && check_ShootHeavy){
+            ReadingStatus = false ;  
+            G4cout << "////////////////////////////////" << G4endl;
          }
+   }
            
 
    }
diff --git a/NPSimulation/src/PrimaryGeneratorAction.cc b/NPSimulation/src/PrimaryGeneratorAction.cc
index 50f0ae0df..20d7b1902 100644
--- a/NPSimulation/src/PrimaryGeneratorAction.cc
+++ b/NPSimulation/src/PrimaryGeneratorAction.cc
@@ -20,151 +20,178 @@
  * Comment:                                                                  *
  *                                                                           *
  *****************************************************************************/
+// STL
+#include "math.h"
+#include <cstdlib>
 
-#include "PrimaryGeneratorAction.hh"
-#include "PhysicsList.hh"
+// G4
 #include "G4ParticleTable.hh"
 #include "G4ParticleDefinition.hh"
+
+// NPL
+#include "PrimaryGeneratorAction.hh"
+#include "PhysicsList.hh"
 #include "Randomize.hh"
-#include "math.h"
+#include "ParticleStack.hh"
+
+// CLHEP
 #include "CLHEP/Random/RandGauss.h"
 #include "CLHEP/Random/RandGeneral.h"
 
 // Event Generator Class
 #include "EventGeneratorTransfert.hh"
-#include "EventGeneratorTransfertToResonance.hh"
 #include "EventGeneratorIsotropic.hh"
 #include "EventGeneratorBeam.hh"
 #include "EventGeneratorPhaseSpace.hh"
+#include "EventGeneratorGammaDecay.hh"
+#include "EventGeneratorParticleDecay.hh"
 
-#include <cstdlib>
 
 
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 PrimaryGeneratorAction::~PrimaryGeneratorAction()
 {
-   delete m_particleGun;
-   delete m_EventGenerator;
+    for (unsigned int i = 0 ; i < m_EventGenerator.size(); i++) {
+             delete m_EventGenerator[i];
+    }
+    m_EventGenerator.clear();
 }
 
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 PrimaryGeneratorAction::PrimaryGeneratorAction(DetectorConstruction* det)
       : m_detector(det)
 {
-   m_EventGenerator = NULL;
-
-   m_particleGun  = new G4ParticleGun(1);
-   G4ParticleDefinition* particle
-   = G4ParticleTable::GetParticleTable()->FindParticle("proton");
-   m_particleGun->SetParticleDefinition(particle);
-   m_particleGun->SetParticleEnergy(10*MeV);
 
-   m_particleGun->SetParticlePosition(G4ThreeVector(0., 0., 0.));
-   m_particleGun->SetParticleMomentumDirection(G4ThreeVector(0., 0., 1.));
 }
 
 
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 void PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
 {
-   if (m_EventGenerator != NULL)m_EventGenerator->GenerateEvent(anEvent, m_particleGun) ;
-   else {
-      G4cout << "No Event Generator!" << G4endl ;
-      return ;
-   }
+    for (unsigned int i = 0 ; i < m_EventGenerator.size(); i++) {
+        m_EventGenerator[i]->GenerateEvent(anEvent);
+    }
+    ParticleStack::getInstance()->ShootAllParticle(anEvent);
 }
 
 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
 void PrimaryGeneratorAction::ReadEventGeneratorFile(string Path)
 {
-   bool check_TransfertToResonance = false;
-   bool check_PhaseSpace           = false;
-   bool check_Isotropic            = false;
-   bool check_Transfert            = false;
-   bool check_Beam                 = false;
-
-   string LineBuffer;
-   ifstream EventGeneratorFile;
-   EventGeneratorFile.open(Path.c_str());
-
-   if (EventGeneratorFile.is_open()) { // should always be true
-      cout << "Event Generator file " << Path << " loading " << endl  ;
-   }
-   else {
-      cout << "Error, Event Generator file " << Path << " found" << endl;
-   }
-
-
-   while (!EventGeneratorFile.eof()) {
-      //Pick-up next line
-      getline(EventGeneratorFile, LineBuffer);
-
-      //Search for comment Symbol %
-      if (LineBuffer.compare(0, 1, "%") == 0) {   /*do nothing*/
-         ;
-      }
-
-
-      //Search for Isotropic source
-      else if (LineBuffer.compare(0, 9, "Isotropic") == 0  && !check_Isotropic) {
-         check_Isotropic = true;
-         VEventGenerator* myEventGenerator = new EventGeneratorIsotropic();
-         EventGeneratorFile.close();
-         myEventGenerator->ReadConfiguration(Path);
-         EventGeneratorFile.open(Path.c_str());
-         myEventGenerator->InitializeRootOutput();
-         m_EventGenerator = myEventGenerator;
-      }
-
-      //Search for Beam
-      else if (LineBuffer.compare(0, 4, "Beam") == 0  && !check_Beam) {
-         check_Beam = true;
-         VEventGenerator* myEventGenerator = new EventGeneratorBeam();
-         EventGeneratorFile.close();
-         myEventGenerator->ReadConfiguration(Path);
-         EventGeneratorFile.open(Path.c_str());
-         myEventGenerator->InitializeRootOutput();
-         myEventGenerator->SetTarget(m_detector->GetTarget());
-         m_EventGenerator = myEventGenerator;
-      }
-
-
-      //Search for Transfert
-      else if (LineBuffer.compare(0, 9, "Transfert") == 0 && !check_Transfert && LineBuffer.compare(0, 11, "TransfertTo") != 0) {
-         check_Transfert = true;
-         VEventGenerator* myEventGenerator = new EventGeneratorTransfert();
-         EventGeneratorFile.close();
-         myEventGenerator->ReadConfiguration(Path);
-         EventGeneratorFile.open(Path.c_str());
-         myEventGenerator->InitializeRootOutput();
-         myEventGenerator->SetTarget(m_detector->GetTarget());
-         m_EventGenerator = myEventGenerator;
-      }
-
-      //Search for Transfert To Resonance
-      else if (LineBuffer.compare(0, 21, "TransfertToResonance") == 0 && !check_TransfertToResonance) {
-         check_TransfertToResonance = true;
-         VEventGenerator* myEventGenerator = new EventGeneratorTransfertToResonance();
-         EventGeneratorFile.close();
-         myEventGenerator->ReadConfiguration(Path);
-         EventGeneratorFile.open(Path.c_str());
-         myEventGenerator->InitializeRootOutput();
-         myEventGenerator->SetTarget(m_detector->GetTarget());
-         m_EventGenerator = myEventGenerator;
-      }
-      
-      //Search for Transfert To Resonance
-      else if (LineBuffer.compare(0, 10, "PhaseSpace") == 0 && !check_PhaseSpace) {
-         check_PhaseSpace = true;
-         VEventGenerator* myEventGenerator = new EventGeneratorPhaseSpace();
-         EventGeneratorFile.close();
-         myEventGenerator->ReadConfiguration(Path);   
-         EventGeneratorFile.open(Path.c_str());
-         myEventGenerator->InitializeRootOutput();
-         myEventGenerator->SetTarget(m_detector->GetTarget());
-         m_EventGenerator = myEventGenerator;
-      }
-   }
-   EventGeneratorFile.close();
+    bool check_TransfertToResonance = false;
+    bool check_PhaseSpace           = false;
+    bool check_Isotropic            = false;
+    bool check_Transfert            = false;
+    bool check_Beam                 = false;
+    
+    // You can have more than one of those
+    int   alreadyiInstantiate_GammaDecay = 0;
+    int   seenToken_GammaDecay = 0;
+    int   alreadyiInstantiate_ParticleDecay = 0;
+    int   seenToken_ParticleDecay = 0;
+    
+    string LineBuffer;
+    ifstream EventGeneratorFile;
+    EventGeneratorFile.open(Path.c_str());
+    
+    if (EventGeneratorFile.is_open()) { // should always be true
+        cout << "Event Generator file " << Path << " loading " << endl  ;
+    }
+    else {
+        cout << "Error, Event Generator file " << Path << " found" << endl;
+    }
+    
+    
+    while (!EventGeneratorFile.eof()) {
+        //Pick-up next line
+        getline(EventGeneratorFile, LineBuffer);
+        
+        //Search for comment Symbol %
+        if (LineBuffer.compare(0, 1, "%") == 0) {   /*do nothing*/
+            ;
+        }
+        
+        
+        //Search for Isotropic source
+        else if (LineBuffer.compare(0, 9, "Isotropic") == 0  && !check_Isotropic) {
+            check_Isotropic = true;
+            VEventGenerator* myEventGenerator = new EventGeneratorIsotropic();
+            EventGeneratorFile.close();
+            myEventGenerator->ReadConfiguration(Path);
+            EventGeneratorFile.open(Path.c_str());
+            myEventGenerator->InitializeRootOutput();
+            m_EventGenerator.push_back(myEventGenerator);
+        }
+        
+        //Search for Beam
+        else if (LineBuffer.compare(0, 4, "Beam") == 0  && !check_Beam) {
+            check_Beam = true;
+            VEventGenerator* myEventGenerator = new EventGeneratorBeam();
+            EventGeneratorFile.close();
+            myEventGenerator->ReadConfiguration(Path);
+            EventGeneratorFile.open(Path.c_str());
+            myEventGenerator->InitializeRootOutput();
+            myEventGenerator->SetTarget(m_detector->GetTarget());
+            m_EventGenerator.push_back(myEventGenerator);
+        }
+        
+        //Search for Transfert
+        else if (LineBuffer.compare(0, 9, "Transfert") == 0 && !check_Transfert && LineBuffer.compare(0, 11, "TransfertTo") != 0) {
+            check_Transfert = true;
+            VEventGenerator* myEventGenerator = new EventGeneratorTransfert();
+            EventGeneratorFile.close();
+            myEventGenerator->ReadConfiguration(Path);
+            EventGeneratorFile.open(Path.c_str());
+            myEventGenerator->InitializeRootOutput();
+            myEventGenerator->SetTarget(m_detector->GetTarget());
+            m_EventGenerator.push_back(myEventGenerator);
+        }
+        
+        //Search for GammaDecay
+        else if ( LineBuffer.compare(0, 10, "GammaDecay") == 0 ) {
+            seenToken_GammaDecay++;
+            if (seenToken_GammaDecay>alreadyiInstantiate_GammaDecay) {
+                alreadyiInstantiate_GammaDecay++;
+                VEventGenerator* myEventGenerator = new EventGeneratorGammaDecay();
+                EventGeneratorFile.close();
+                myEventGenerator->ReadConfiguration(Path,alreadyiInstantiate_GammaDecay);
+                EventGeneratorFile.open(Path.c_str());
+                myEventGenerator->InitializeRootOutput();
+                myEventGenerator->SetTarget(m_detector->GetTarget());
+                m_EventGenerator.push_back(myEventGenerator);
+                seenToken_GammaDecay=0;
+            }
+            
+        }
+        
+        //Search for ParticleDecay
+        else if ( LineBuffer.compare(0, 13, "ParticleDecay") == 0 ) {
+            seenToken_ParticleDecay++;
+            if(seenToken_ParticleDecay>alreadyiInstantiate_ParticleDecay){
+                alreadyiInstantiate_ParticleDecay++;
+                VEventGenerator* myEventGenerator = new EventGeneratorParticleDecay();
+                EventGeneratorFile.close();
+                myEventGenerator->ReadConfiguration(Path,alreadyiInstantiate_ParticleDecay);
+                EventGeneratorFile.open(Path.c_str());
+                myEventGenerator->InitializeRootOutput();
+                myEventGenerator->SetTarget(m_detector->GetTarget());
+                m_EventGenerator.push_back(myEventGenerator);
+                seenToken_ParticleDecay=0;
+            }
+        }
+        
+        
+        //Search for Transfert To Resonance
+        else if (LineBuffer.compare(0, 10, "PhaseSpace") == 0 && !check_PhaseSpace) {
+            check_PhaseSpace = true;
+            VEventGenerator* myEventGenerator = new EventGeneratorPhaseSpace();
+            EventGeneratorFile.close();
+            myEventGenerator->ReadConfiguration(Path);   
+            EventGeneratorFile.open(Path.c_str());
+            myEventGenerator->InitializeRootOutput();
+            myEventGenerator->SetTarget(m_detector->GetTarget());
+            m_EventGenerator.push_back(myEventGenerator);
+        }
+    }
+    EventGeneratorFile.close();
 }
 
-- 
GitLab