From 3337cfe73ec814fc03cb0f18951ce26910a4f221 Mon Sep 17 00:00:00 2001
From: matta <matta@npt>
Date: Fri, 13 Nov 2009 00:42:11 +0000
Subject: [PATCH] * Now interaction coordinate and Energy loss of the beam are
 compute using a target method, called in the different event generator 
 - Some test have been done, results are OK 	- Simulation is slightly slow
 done by this process of slowing done the beam, mainly because an Energy loss
 table is called every events...

---
 .../DetectorConfiguration/Riken_65mm.detector |   7 +-
 Inputs/DetectorConfiguration/e530.detector    |   1 +
 NPSimulation/include/Target.hh                |  58 +++++---
 NPSimulation/include/VEventGenerator.hh       |  11 +-
 NPSimulation/src/EventGeneratorBeam.cc        |  23 +--
 NPSimulation/src/EventGeneratorTransfert.cc   |  50 +++----
 .../src/EventGeneratorTransfertToResonance.cc |  39 ++++--
 NPSimulation/src/Target.cc                    | 132 +++++++++++++++---
 NPSimulation/src/VEventGenerator.cc           |  99 -------------
 9 files changed, 212 insertions(+), 208 deletions(-)

diff --git a/Inputs/DetectorConfiguration/Riken_65mm.detector b/Inputs/DetectorConfiguration/Riken_65mm.detector
index 31d9cbda5..a0e5ee510 100644
--- a/Inputs/DetectorConfiguration/Riken_65mm.detector
+++ b/Inputs/DetectorConfiguration/Riken_65mm.detector
@@ -7,15 +7,16 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 GeneralTarget
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%Target
-	THICKNESS= 1
+Target
+	THICKNESS= 10000
 	RADIUS=	45
 	MATERIAL= CD2
+	ANGLE= 45
 	X= 0
 	Y= 0
 	Z= 0
 	
-CryoTarget
+%CryoTarget
 	THICKNESS= 3000
 	RADIUS=	45
 	TEMPERATURE= 26
diff --git a/Inputs/DetectorConfiguration/e530.detector b/Inputs/DetectorConfiguration/e530.detector
index 444075b0c..fbe124019 100644
--- a/Inputs/DetectorConfiguration/e530.detector
+++ b/Inputs/DetectorConfiguration/e530.detector
@@ -22,6 +22,7 @@ Target
 	THICKNESS= 309.278350515
 	RADIUS=	7.5
 	MATERIAL= CD2
+	ANGLE= 45
 	X= 0
 	Y= 0
 	Z= 40
diff --git a/NPSimulation/include/Target.hh b/NPSimulation/include/Target.hh
index f34c7677e..3b24daf07 100644
--- a/NPSimulation/include/Target.hh
+++ b/NPSimulation/include/Target.hh
@@ -52,29 +52,41 @@ public:
 
 
 public:
-   // Read stream at Configfile to pick-up parameters of detector (Position,...)
-   // Called in DetecorConstruction::ReadDetextorConfiguration Method
-   void ReadConfiguration(string Path);
+  //	Read stream at Configfile to pick-up parameters of detector (Position,...)
+  //	Called in DetecorConstruction::ReadDetextorConfiguration Method
+  void ReadConfiguration(string Path);
 
-   // Construct detector and inialise sensitive part.
-   // Called After DetecorConstruction::AddDetector Method
-   void ConstructDetector(G4LogicalVolume* world);
+  //	Construct detector and inialise sensitive part.
+  //	Called After DetecorConstruction::AddDetector Method
+  void ConstructDetector(G4LogicalVolume* world);
 
-   // Add Detector branch to the EventTree.
-   // Called After DetecorConstruction::AddDetector Method
-   void InitializeRootOutput();
-
-   // Read sensitive part and fill the Root tree.
-   // Called at in the EventAction::EndOfEventAvtion
-   void ReadSensitive(const G4Event* event);
+  //	Add Detector branch to the EventTree.
+  //	Called After DetecorConstruction::AddDetector Method
+  void InitializeRootOutput();
 
+  //	Read sensitive part and fill the Root tree.
+  //	Called at in the EventAction::EndOfEventAvtion
+  void ReadSensitive(const G4Event* event);
 
 public:
-   // method for debug purpose (still to be implemented)
-   // This method should check if the results of the beam interaction within the target
-   // (interaction coordinates) are well located inside the target volume
-   bool IsInsideTarget() {return false;};
-
+	//	method for debug purpose (still to be implemented)
+	//	This method should check if the results of the beam interaction within the target
+	//	(interaction coordinates) are well located inside the target volume
+	bool IsInsideTarget() {return false;};
+
+   // Used to calculate the incident beam direction (taking into account
+   // the emittance) and the vertex of interaction in target
+   // Also compute the energy lost by the beam in the target before interacting
+   void CalculateBeamInteraction(double MeanPosX, double SigmaPosX, double MeanPosTheta, double SigmaPosTheta,
+                                 double MeanPosY, double SigmaPosY, double MeanPosPhi,   double SigmaPosPhi,
+                                 double IncidentBeamEnergy,
+                                 G4ParticleDefinition* BeamName,
+                                 G4ThreeVector &InterCoord, double &AngleEmittanceTheta, double &AngleEmittancePhi,
+                                 double &AngleIncidentTheta, double &AngleIncidentPhi,
+                                 double &FinalBeamEnergy);
+	                                
+	// Used to simulate beam emmitance effect
+	void RandomGaussian2D(double MeanX, double MeanY, double SigmaX, double SigmaY, double &X, double &Y, double NumberOfSigma = 10000);
 
 public:
    G4Material* GetMaterialFromLibrary(G4String MaterialName, G4double Temperature = 0, G4double Pressure = 0);
@@ -83,11 +95,11 @@ public:
 public:
    G4double    GetTargetThickness()	{return m_TargetThickness;}
    G4Material* GetTargetMaterial()	{return m_TargetMaterial;}
-   G4double    GetTargetRadius()	{return m_TargetRadius;}
-   G4double    GetTargetAngle()		{return m_TargetAngle;}
-   G4double    GetTargetX()		{return m_TargetX;}
-   G4double    GetTargetY()		{return m_TargetY;}
-   G4double    GetTargetZ()		{return m_TargetZ;}
+   G4double    GetTargetRadius()		{return m_TargetRadius;}
+   G4double    GetTargetAngle()			{return m_TargetAngle;}
+   G4double    GetTargetX()					{return m_TargetX;}
+   G4double    GetTargetY()					{return m_TargetY;}
+   G4double    GetTargetZ()					{return m_TargetZ;}
    G4int       GetTargetNbLayers()	{return m_TargetNbLayers;}
 
 
diff --git a/NPSimulation/include/VEventGenerator.hh b/NPSimulation/include/VEventGenerator.hh
index f5d040a10..59bbd3bca 100644
--- a/NPSimulation/include/VEventGenerator.hh
+++ b/NPSimulation/include/VEventGenerator.hh
@@ -59,16 +59,7 @@ public:
 
    // Used in some case to generate event inside the target
    virtual void SetTarget(Target*) {};
-
-   // Used to calculate the incident beam direction (taking into account
-   // the emittance) and the vertex of interaction in target
-   void CalculateBeamInteraction(double MeanPosX, double SigmaPosX, double MeanPosTheta, double SigmaPosTheta,
-                                 double MeanPosY, double SigmaPosY, double MeanPosPhi,   double SigmaPosPhi,
-                                 Target* target,
-                                 G4ThreeVector &InterCoord, double &AngleEmittanceTheta, double &AngleEmittancePhi,
-                                 double &AngleIncidentTheta, double &AngleIncidentPhi,
-                                 double &EffectiveTargetThicknessBeforeInteraction);
-
+   
    // Used to simulate beam emmitance effect
    void RandomGaussian2D(double MeanX, double MeanY, double SigmaX, double SigmaY, double &X, double &Y, double NumberOfSigma = 10000);
 };
diff --git a/NPSimulation/src/EventGeneratorBeam.cc b/NPSimulation/src/EventGeneratorBeam.cc
index 7388505fa..604ce59f8 100644
--- a/NPSimulation/src/EventGeneratorBeam.cc
+++ b/NPSimulation/src/EventGeneratorBeam.cc
@@ -179,19 +179,24 @@ void EventGeneratorBeam::GenerateEvent(G4Event* anEvent, G4ParticleGun* particle
    
    ///////////////////////////////////////////////////////////////////////
    ///// Calculate the incident beam direction as well as the vertex /////
-   ///// of interaction in target                                    /////
+   ///// of interaction in target and Energy Loss of the beam within /////
+   ///// the target.                                                 /////
    ///////////////////////////////////////////////////////////////////////
    G4ThreeVector InterCoord;
+   
    G4double Beam_thetaX = 0, Beam_phiY = 0;
    G4double Beam_theta  = 0, Beam_phi  = 0;
-   G4double EffectiveThickness = 0;
-   CalculateBeamInteraction(0, m_SigmaX, 0, m_SigmaThetaX,
-                            0, m_SigmaY, 0, m_SigmaPhiY,
-                            m_Target,
-                            InterCoord, Beam_thetaX, Beam_phiY,
-                            Beam_theta, Beam_phi,
-                            EffectiveThickness);
-
+   G4double FinalBeamEnergy = 0 ;
+   G4double InitialBeamEnergy = RandGauss::shoot(m_BeamEnergy, m_BeamEnergySpread);
+   
+	m_Target->CalculateBeamInteraction(	0, m_SigmaX, 0, m_SigmaThetaX,
+                            					0, m_SigmaY, 0, m_SigmaPhiY,
+				                            	InitialBeamEnergy,
+				                            	m_particle,
+				                           	 	InterCoord, Beam_thetaX, Beam_phiY,
+                            					Beam_theta, Beam_phi,
+				                           	 	FinalBeamEnergy);
+				                           	 	
    // write vertex position to ROOT file
    G4double x0 = InterCoord.x();
    G4double y0 = InterCoord.y();
diff --git a/NPSimulation/src/EventGeneratorTransfert.cc b/NPSimulation/src/EventGeneratorTransfert.cc
index 0f7e15c94..af94442fb 100644
--- a/NPSimulation/src/EventGeneratorTransfert.cc
+++ b/NPSimulation/src/EventGeneratorTransfert.cc
@@ -31,7 +31,6 @@
 
 // G4 headers
 #include "G4ParticleTable.hh"
-#include "G4EmCalculator.hh"
 #include "G4ParticleGun.hh"
 #include "G4RotationMatrix.hh"
 
@@ -343,19 +342,27 @@ void EventGeneratorTransfert::GenerateEvent(G4Event* anEvent , G4ParticleGun* pa
 
    ///////////////////////////////////////////////////////////////////////
    ///// Calculate the incident beam direction as well as the vertex /////
-   ///// of interaction in target                                    /////
+   ///// of interaction in target and Energy Loss of the beam within /////
+   ///// the target.                                                 /////
    ///////////////////////////////////////////////////////////////////////
    G4ThreeVector InterCoord;
+   
    G4double Beam_thetaX = 0, Beam_phiY = 0;
    G4double Beam_theta  = 0, Beam_phi  = 0;
-   G4double EffectiveThickness = 0;
-   CalculateBeamInteraction(0, m_SigmaX, 0, m_SigmaThetaX,
-                            0, m_SigmaY, 0, m_SigmaPhiY,
-                            m_Target,
-                            InterCoord, Beam_thetaX, Beam_phiY,
-                            Beam_theta, Beam_phi,
-                            EffectiveThickness);
-
+   G4double FinalBeamEnergy = 0 ;
+   G4double InitialBeamEnergy = RandGauss::shoot(m_BeamEnergy, m_BeamEnergySpread);
+   
+	m_Target->CalculateBeamInteraction(	0, m_SigmaX, 0, m_SigmaThetaX,
+                            					0, m_SigmaY, 0, m_SigmaPhiY,
+				                            	InitialBeamEnergy,
+				                            	BeamName,
+				                           	 	InterCoord, Beam_thetaX, Beam_phiY,
+                            					Beam_theta, Beam_phi,
+				                           	 	FinalBeamEnergy);
+				                           	 	
+	m_Reaction->SetBeamEnergy(FinalBeamEnergy);
+  m_InitConditions->SetICIncidentEnergy(FinalBeamEnergy / MeV);
+  
    // write vertex position to ROOT file
    G4double x0 = InterCoord.x();
    G4double y0 = InterCoord.y();
@@ -391,21 +398,7 @@ void EventGeneratorTransfert::GenerateEvent(G4Event* anEvent , G4ParticleGun* pa
    ///// Angles for emitted particles following Cross Section //////
    ///// Angles are in the beam frame                         //////
    /////////////////////////////////////////////////////////////////
-   // Beam nominal incident energy before interaction with the target
-   G4double NominalBeamEnergy = m_BeamEnergy;
-   G4double IncidentBeamEnergy = RandGauss::shoot(NominalBeamEnergy, m_BeamEnergySpread / 2.35);
-   // Slowing down the beam to the interaction layer in the target
-   // Number of Layers
-   G4int NbLayers = m_Target->GetTargetNbLayers();
-   G4EmCalculator emCalculator;
-   for (G4int i = 0; i < NbLayers; i++) {
-//      G4double dedx = emCalculator.GetDEDX(IncidentBeamEnergy, BeamName, m_Target->GetTargetMaterial());
-      G4double dedx = emCalculator.ComputeTotalDEDX(IncidentBeamEnergy, BeamName, m_Target->GetTargetMaterial());
-      G4double de   = dedx * EffectiveThickness / NbLayers;
-      IncidentBeamEnergy -= de;
-   }
-   m_Reaction->SetBeamEnergy(IncidentBeamEnergy);
-   m_InitConditions->SetICIncidentEnergy(IncidentBeamEnergy / MeV);
+
    // Angles
    RandGeneral CrossSectionShoot(m_Reaction->GetCrossSection(), m_Reaction->GetCrossSectionSize());
    G4double ThetaCM = CrossSectionShoot.shoot() * (180*deg);
@@ -458,16 +451,13 @@ void EventGeneratorTransfert::GenerateEvent(G4Event* anEvent , G4ParticleGun* pa
       // write angles in ROOT file
       m_InitConditions->SetICEmittedAngleThetaLabWorldFrame(theta_world / deg);
       m_InitConditions->SetICEmittedAnglePhiWorldFrame(phi_world / deg);
-      // tests
-//      G4cout << "XXXXXXXXXXXXXXXXXXXXXXXXXXXX" << G4endl;
-//      G4cout << "cinematique dans ref world : " << G4endl;
-//      G4cout << "\t" << momentum_kine_world << G4endl;
+      
       //Set the gun to shoot
       particleGun->SetParticleMomentumDirection(momentum_kine_world);
       //Shoot the light particle
       particleGun->GeneratePrimaryVertex(anEvent);
    }
-   if (m_ShootHeavy) { // Case of recoil particle
+   if (m_ShootHeavy) { // Case of heavy particle
       // Particle type
       particleGun->SetParticleDefinition(HeavyName);
       // Particle energy
diff --git a/NPSimulation/src/EventGeneratorTransfertToResonance.cc b/NPSimulation/src/EventGeneratorTransfertToResonance.cc
index f513b2cb0..c12b8b13f 100644
--- a/NPSimulation/src/EventGeneratorTransfertToResonance.cc
+++ b/NPSimulation/src/EventGeneratorTransfertToResonance.cc
@@ -371,18 +371,25 @@ void EventGeneratorTransfertToResonance::GenerateEvent(G4Event* anEvent , G4Part
    //////////////////////////////////////////////////
    //////Define the kind of particle to shoot////////
    //////////////////////////////////////////////////
+   // Light
    G4int LightZ = m_Reaction->GetNucleus3()->GetZ() ;
    G4int LightA = m_Reaction->GetNucleus3()->GetA() ;
 
    G4ParticleDefinition* LightName
    = G4ParticleTable::GetParticleTable()->GetIon(LightZ, LightA, 0.);
 
+   // Recoil
    G4int HeavyZ = m_Reaction->GetNucleus4()->GetZ() ;
    G4int HeavyA = m_Reaction->GetNucleus4()->GetA() ;
 
    G4ParticleDefinition* HeavyName
    = G4ParticleTable::GetParticleTable()->GetIon(HeavyZ, HeavyA, m_Reaction->GetExcitation()*MeV);
 
+   // Beam
+   G4int BeamZ = m_Reaction->GetNucleus1()->GetZ();
+   G4int BeamA = m_Reaction->GetNucleus1()->GetA();
+   G4ParticleDefinition* BeamName = G4ParticleTable::GetParticleTable()->GetIon(BeamZ, BeamA, 0);
+
    // Shoot the Resonance energy following the mean and width value
    double EXX = -10 ;
    
@@ -391,27 +398,29 @@ void EventGeneratorTransfertToResonance::GenerateEvent(G4Event* anEvent , G4Part
 
 	m_Reaction->SetExcitation( EXX  );
 
-   ///////////////////////////////////////////////////////////////////////
+	 ///////////////////////////////////////////////////////////////////////
    ///// Calculate the incident beam direction as well as the vertex /////
-   ///// of interaction in target                                    /////
+   ///// of interaction in target and Energy Loss of the beam within /////
+   ///// the target.                                                 /////
    ///////////////////////////////////////////////////////////////////////
    G4ThreeVector InterCoord;
+   
    G4double Beam_thetaX = 0, Beam_phiY = 0;
    G4double Beam_theta  = 0, Beam_phi  = 0;
-   G4double EffectiveThickness = 0;
-   
-   	if(m_SigmaX==0 && m_SigmaY==0 && m_SigmaThetaX == 0 && m_SigmaPhiY==0) InterCoord = G4ThreeVector(0,0,0);
+   G4double FinalBeamEnergy = 0 ;
+   G4double InitialBeamEnergy = RandGauss::shoot(m_BeamEnergy, m_BeamEnergySpread);
    
-	else if( m_Target !=0)   
-  	 CalculateBeamInteraction(	0, m_SigmaX, 0, m_SigmaThetaX,
-                           	 	0, m_SigmaY, 0, m_SigmaPhiY,
-                            	m_Target,
-                            	InterCoord, Beam_thetaX, Beam_phiY,
-                            	Beam_theta, Beam_phi,
-                                EffectiveThickness);
-                            	
-	else 
-		InterCoord = G4ThreeVector(0,0,0);
+	m_Target->CalculateBeamInteraction(	0, m_SigmaX, 0, m_SigmaThetaX,
+                            					0, m_SigmaY, 0, m_SigmaPhiY,
+				                            	InitialBeamEnergy,
+				                            	BeamName,
+				                           	 	InterCoord, Beam_thetaX, Beam_phiY,
+                            					Beam_theta, Beam_phi,
+				                           	 	FinalBeamEnergy);
+				                           	 	
+	m_Reaction->SetBeamEnergy(FinalBeamEnergy);
+  m_InitConditions->SetICIncidentEnergy(FinalBeamEnergy / MeV);
+  
 
    // write vertex position to ROOT file
    G4double x0 = InterCoord.x();
diff --git a/NPSimulation/src/Target.cc b/NPSimulation/src/Target.cc
index 798c028ee..4dc4efa24 100644
--- a/NPSimulation/src/Target.cc
+++ b/NPSimulation/src/Target.cc
@@ -21,7 +21,7 @@
  *  + 16/09/2009: Add support for positioning the target with an angle with  *
  *                respect to the beam (N. de Sereville)                      *
  *  + 16/09/2009: Add CH2 material for targets (N. de Sereville)             *
- *  + 06/11/2009: Add new Token NBLAYERS defining the number of steps used   *
+ *  + 06/11/2009: Add new Token m_TargetNbLayers defining the number of steps used   *
  *                to slow down the beam in the target (N. de Sereville)      *
  *                                                                           *
  *****************************************************************************/
@@ -41,7 +41,9 @@
 #include "G4VPhysicalVolume.hh"
 #include "G4VisAttributes.hh"
 #include "G4Colour.hh"
-
+#include "G4EmCalculator.hh"
+#include "Randomize.hh"
+using namespace CLHEP ;
 // NPTool header
 #include"Target.hh"
 
@@ -212,7 +214,7 @@ void Target::ReadConfiguration(string Path)
    bool check_X = false ;
    bool check_Y = false ;
    bool check_Z = false ;
-   bool check_NbLayers = false;
+   bool check_m_TargetNbLayers = false;
 
    bool check_Temperature = false ;
    bool check_Pressure = false ;
@@ -287,8 +289,8 @@ void Target::ReadConfiguration(string Path)
 	            cout  << m_TargetZ / mm << " )" << endl ;           
 	         }
 
-	        else if (DataBuffer.compare(0, 9, "NBLAYERS=") == 0) {
-	        	check_NbLayers = true ;
+	        else if (DataBuffer.compare(0, 9, "NbLayers=") == 0) {
+	        	check_m_TargetNbLayers = true ;
 	            ConfigFile >> DataBuffer;
 	            m_TargetNbLayers = atoi(DataBuffer.c_str());
 	            cout  << "Number of steps for slowing down the beam in target: " << m_TargetNbLayers << endl;
@@ -381,8 +383,8 @@ void Target::ReadConfiguration(string Path)
 	            cout << m_TargetZ / mm << " )" << endl ;
 	         }
 
-	        else if (DataBuffer.compare(0, 9, "NBLAYERS=") == 0) {
-	        	check_NbLayers = true ;
+	        else if (DataBuffer.compare(0, 9, "m_TargetNbLayers=") == 0) {
+	        	check_m_TargetNbLayers = true ;
 	            ConfigFile >> DataBuffer;
 	            m_TargetNbLayers = atoi(DataBuffer.c_str());
 	            cout  << "Number of steps for slowing down the beam in target: " << m_TargetNbLayers << endl;
@@ -457,20 +459,20 @@ void Target::ConstructDetector(G4LogicalVolume* world)
          G4LogicalVolume*   logicWindowsB = new G4LogicalVolume(solidWindowsB, m_WindowsMaterial, "logicTargetWindowsB");
 
          PVPBuffer =
-            new G4PVPlacement(0                                                           ,
-                  TargetPos + G4ThreeVector(0., 0., 0.5*(m_TargetThickness + m_WindowsThickness))      ,
-                  logicWindowsF                                                  ,
-                  "Target Window Front"                                             ,
-                  world                                                       ,
-                  false, 0);
+            new G4PVPlacement(	0                                                           										,
+                  							TargetPos + G4ThreeVector(0., 0., 0.5*(m_TargetThickness + m_WindowsThickness)) ,
+                  							logicWindowsF                                                  									,
+                 							 	"Target Window Front"                                            							 	,
+                 	 							world                                                       										,
+                 	 							false, 0																																				);
 
          PVPBuffer =
-            new G4PVPlacement(0                                                           ,
-                  TargetPos + G4ThreeVector(0., 0., -0.5*(m_TargetThickness + m_WindowsThickness))  ,
-                  logicWindowsB                                                  ,
-                  "Target Window Back"                                           ,
-                  world                                                       ,
-                  false, 0);
+            new G4PVPlacement(	0                                                           											,
+							                  TargetPos + G4ThreeVector(0., 0., -0.5*(m_TargetThickness + m_WindowsThickness))  ,
+							                  logicWindowsB                                                  										,
+							                  "Target Window Back"                                           										,
+							                  world                                                       											,
+							                  false, 0																																					);
 
          G4VisAttributes* WindowsVisAtt = new G4VisAttributes(G4Colour(0.5, 1., 0.5));
          logicWindowsF->SetVisAttributes(WindowsVisAtt);
@@ -489,4 +491,96 @@ void Target::InitializeRootOutput()
 // Called at in the EventAction::EndOfEventAvtion
 void Target::ReadSensitive(const G4Event*)
 {}
+	
+void Target::CalculateBeamInteraction(	double MeanPosX, double SigmaPosX, double MeanPosTheta, double SigmaPosTheta,
+				                                double MeanPosY, double SigmaPosY, double MeanPosPhi,   double SigmaPosPhi,
+				                                double IncidentBeamEnergy,
+                                 				G4ParticleDefinition* BeamName,
+				                                G4ThreeVector &InterCoord, double &AngleEmittanceTheta, double &AngleEmittancePhi,
+				                                double &AngleIncidentTheta, double &AngleIncidentPhi,
+				                                double &FinalBeamEnergy)
+{
+
+      // target parameters
+			G4ThreeVector TargetNormal = G4ThreeVector(		sin(m_TargetAngle)		,
+      																							0											,
+      																							cos(m_TargetAngle)		);
+			
+      // beam interaction parameters
+      double x0 = 1000 * cm;
+      double y0 = 1000 * cm;
+      double z0 =    0 * cm;
+      double dz =    0 * cm;
+
+      // calculate emittance parameters (x,theta) and (y,phi)
+      if (m_TargetRadius != 0) {	// case of finite target dimensions
+         while (sqrt(x0*x0 + y0*y0) > m_TargetRadius) {
+            RandomGaussian2D(MeanPosX, MeanPosTheta, SigmaPosX, SigmaPosTheta, x0, AngleEmittanceTheta);
+            RandomGaussian2D(MeanPosY, MeanPosPhi,   SigmaPosY, SigmaPosPhi,   y0, AngleEmittancePhi);
+         }
+         // in case target is tilted, correct the z-position of interaction
+         // x is the vertical axis
+         dz = x0 * tan(m_TargetAngle);
+      }
+      else {			// if no target radius is given consider a point-like target
+         RandomGaussian2D(0, 0, 0, SigmaPosTheta, x0, AngleEmittanceTheta);
+         RandomGaussian2D(0, 0, 0, SigmaPosPhi,   y0, AngleEmittancePhi);
+      }
+
+      // Calculate incident angle in spherical coordinate, passing by the direction vector dir      
+      double Xdir = sin(AngleEmittanceTheta);
+      double Ydir = sin(AngleEmittancePhi);
+      double Zdir = cos(AngleEmittanceTheta) + cos(AngleEmittancePhi);
+			G4ThreeVector BeamDir = G4ThreeVector(Xdir,Ydir,Zdir)	;
+			
+      AngleIncidentTheta = BeamDir.theta() 	;
+      AngleIncidentPhi   = BeamDir.phi()		;
+      if (AngleIncidentPhi   < 0)    AngleIncidentPhi += 2*pi	;
+      if (AngleIncidentTheta < 1e-6) AngleIncidentPhi  = 0		;
+
+      // Calculation of effective target thickness and z-position of interaction
+      // when the target is tilted wrt the beam axis
+      double EffectiveThickness = m_TargetThickness / (BeamDir.unit()).dot(TargetNormal.unit());
+      double uniform = RandFlat::shoot();
+      z0 = dz + (-m_TargetThickness / 2 + uniform * m_TargetThickness);
+
+      // Calculate the effective thickness before interaction in target
+      // This is useful to slow down the beam
+      double EffectiveTargetThicknessBeforeInteraction = m_TargetThickness  * uniform / cos(AngleIncidentTheta);
+
+      // Move to the target position
+      x0 += m_TargetX;
+      y0 += m_TargetY;
+      z0 += m_TargetZ;
+      InterCoord = G4ThreeVector(x0, y0, z0);
+
+		G4EmCalculator emCalculator;
+		for (G4int i = 0; i < m_TargetNbLayers; i++) 
+			{
+				G4double dedx = emCalculator.ComputeTotalDEDX(IncidentBeamEnergy, BeamName, m_TargetMaterial);
+				G4double de   = dedx * EffectiveTargetThicknessBeforeInteraction / m_TargetNbLayers;
+				IncidentBeamEnergy -= de;
+			}
+FinalBeamEnergy=IncidentBeamEnergy;
+}
 
+
+
+void Target::RandomGaussian2D(double MeanX, double MeanY, double SigmaX, double SigmaY, double &X, double &Y, double NumberOfSigma)
+{
+   if (SigmaX != 0) {
+      X = 2 * NumberOfSigma*SigmaX;
+      while (X > NumberOfSigma*SigmaX) X = RandGauss::shoot(MeanX, SigmaX);
+
+      double a = NumberOfSigma * SigmaX/2;
+      double b = NumberOfSigma * SigmaY/2;
+      double SigmaYPrim = b * sqrt(1 - X*X / (a*a));
+
+      SigmaYPrim = 2*SigmaYPrim / NumberOfSigma;
+      Y = RandGauss::shoot(MeanY, SigmaYPrim);
+   }
+   else {
+      X = MeanX;
+      Y = RandGauss::shoot(MeanY, SigmaY);
+   }
+}
diff --git a/NPSimulation/src/VEventGenerator.cc b/NPSimulation/src/VEventGenerator.cc
index a1f0acb26..bf2b8e82b 100644
--- a/NPSimulation/src/VEventGenerator.cc
+++ b/NPSimulation/src/VEventGenerator.cc
@@ -47,102 +47,3 @@ VEventGenerator::~VEventGenerator()
 {
 }
 
-
-
-void VEventGenerator::CalculateBeamInteraction(double MeanPosX, double SigmaPosX, double MeanPosTheta, double SigmaPosTheta,
-                                               double MeanPosY, double SigmaPosY, double MeanPosPhi,   double SigmaPosPhi,
-                                               Target* target,
-                                               G4ThreeVector &InterCoord, double &AngleEmittanceTheta, double &AngleEmittancePhi,
-                                               double &AngleIncidentTheta, double &AngleIncidentPhi,
-                                               double &EffectiveTargetThicknessBeforeInteraction)
-{
-   if (target != 0) {
-      // target parameters
-      double TargetThickness = target->GetTargetThickness();
-      double TargetRadius    = target->GetTargetRadius();
-      double TargetAngle     = target->GetTargetAngle();
-
-      // beam interaction parameters
-      double x0 = 1000 * cm;
-      double y0 = 1000 * cm;
-      double z0 =    0 * cm;
-      double dz =    0 * cm;
-
-      // calculate emittance parameters (x,theta) and (y,phi)
-      if (TargetRadius != 0) {	// case of finite target dimensions
-         while (sqrt(x0*x0 + y0*y0) > TargetRadius) {
-            RandomGaussian2D(MeanPosX, MeanPosTheta, SigmaPosX, SigmaPosTheta, x0, AngleEmittanceTheta);
-            RandomGaussian2D(MeanPosY, MeanPosPhi,   SigmaPosY, SigmaPosPhi,   y0, AngleEmittancePhi);
-         }
-         // in case target is tilted, correct the z-position of interaction
-         // x is the vertical axis
-         dz = x0 * tan(TargetAngle);
-      }
-      else {			// if no target radius is given consider a point-like target
-         RandomGaussian2D(0, 0, 0, SigmaPosTheta, x0, AngleEmittanceTheta);
-         RandomGaussian2D(0, 0, 0, SigmaPosPhi,   y0, AngleEmittancePhi);
-      }
-
-      // Calculate incident angle in spherical coordinate, passing by the direction vector dir      
-      double Xdir = sin(AngleEmittanceTheta);
-      double Ydir = sin(AngleEmittancePhi);
-      double Zdir = cos(AngleEmittanceTheta) + cos(AngleEmittancePhi);
-
-      AngleIncidentTheta = acos(Zdir / sqrt(Xdir*Xdir + Ydir*Ydir + Zdir*Zdir)) * rad;
-      AngleIncidentPhi   = atan2(Ydir, Xdir) * rad;
-      if (AngleIncidentPhi   < 0)    AngleIncidentPhi += 2*pi;
-      if (AngleIncidentTheta < 1e-6) AngleIncidentPhi  = 0;
-
-      // Calculation of effective target thickness and z-position of interaction
-      // when the target is tilted wrt the beam axis
-      //   * exact if target is perpendicular to the beam axis (target not tilted)
-      //     in any case of beam emittance
-      //   * exact if target is tilted wrt the beam axis and the beam is parallel
-      //     (no beam divergence)
-      //   * wrong if target is tilted and for general case of beam emittance
-      //     (should be fixed in next release). For small beam divergence this
-      //     should not be such a big problem
-      TargetThickness /= cos(TargetAngle);
-      double uniform = RandFlat::shoot();
-      z0 = dz + (-TargetThickness / 2 + uniform * TargetThickness);
-
-      // Calculate the effective thickness before interaction in target
-      // This is useful to slow down the beam
-      EffectiveTargetThicknessBeforeInteraction = TargetThickness  * uniform / cos(AngleIncidentTheta);
-
-      // Move to the target position
-      x0 += target->GetTargetX();
-      y0 += target->GetTargetY();
-      z0 += target->GetTargetZ();
-      InterCoord = G4ThreeVector(x0, y0, z0);
-
-   } // end if target
-   else {
-      InterCoord = G4ThreeVector(0, 0, 0);
-      AngleEmittanceTheta = 0;
-      AngleEmittancePhi   = 0;
-      AngleIncidentTheta  = 0; 
-      AngleIncidentPhi    = 0;
-   }
-}
-
-
-
-void VEventGenerator::RandomGaussian2D(double MeanX, double MeanY, double SigmaX, double SigmaY, double &X, double &Y, double NumberOfSigma)
-{
-   if (SigmaX != 0) {
-      X = 2 * NumberOfSigma*SigmaX;
-      while (X > NumberOfSigma*SigmaX) X = RandGauss::shoot(MeanX, SigmaX);
-
-      double a = NumberOfSigma * SigmaX/2;
-      double b = NumberOfSigma * SigmaY/2;
-      double SigmaYPrim = b * sqrt(1 - X*X / (a*a));
-
-      SigmaYPrim = 2*SigmaYPrim / NumberOfSigma;
-      Y = RandGauss::shoot(MeanY, SigmaYPrim);
-   }
-   else {
-      X = MeanX;
-      Y = RandGauss::shoot(MeanY, SigmaY);
-   }
-}
-- 
GitLab