Import Geant4 9.1.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 15:37:50 +02:00
parent a8e9364cea
commit 96c8bcd0af
6923 changed files with 198390 additions and 41849 deletions
@@ -25,7 +25,7 @@
//
//
// $Id: G4Chips.hh,v 1.19 2006/06/29 20:05:53 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4Chips ----------------
// by Mikhail Kossov, September 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QBesIKJY.hh,v 1.2 2006/06/29 20:05:55 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QBesIKJY ----------------
// by Mikhail Kossov, Sept 2000.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QCHIPSWorld.hh,v 1.25 2006/06/29 20:05:57 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCHIPSWorld ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QCandidate.hh,v 1.28 2006/06/29 20:05:59 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCandidate ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QCandidateVector.hh,v 1.21 2006/06/29 20:06:01 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCandidateVector ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QChipolino.hh,v 1.23 2006/06/29 20:06:03 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QChipolino ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QContent.hh,v 1.28 2006/06/29 20:06:05 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QContent ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QDecayChan.hh,v 1.23 2006/06/29 20:06:07 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QDecayChan ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QDecayChanVector.hh,v 1.19 2006/06/29 20:06:09 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCandidateVector ----------------
// by Mikhail Kossov, Sept 1999.
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4QEnvironment.hh,v 1.28 2007/02/28 14:26:25 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4QEnvironment.hh,v 1.32 2007/10/07 13:31:41 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QEnvironment ----------------
// by Mikhail Kossov, August 2000.
@@ -40,6 +40,7 @@
class G4QEnvironment
{
public:
G4QEnvironment(const G4QNucleus theEnv); // Create Env and add Quasmons later
G4QEnvironment(const G4QHadronVector& projHadrons, const G4int targPDG);
G4QEnvironment(const G4QEnvironment& right); // copy QEnvironment by value
G4QEnvironment(G4QEnvironment* right); // copy QEnvironment by pointer
@@ -57,6 +58,7 @@ public:
G4QHadronVector* GetProjectiles(); // User is responsible for Destroy/Clear/Delete
// Modifiers
void AddQuasmon(G4Quasmon* Q); // Add aQuasmon to theEnvironment
G4QHadronVector* Fragment(); // User must clear and destroy the G4QHadronVec
// Static functions
@@ -77,15 +79,8 @@ private:
void InitClustersVector(G4int maxC, G4int maxA);//Init.NucClust's for 1st int
void CleanUp(); // Makes theEnvironment=vacuum & kill Quasmons
void PrepareInteractionProbabilities(const G4QContent& projQC, G4double AP);
void EvaporateResidual(G4QHadron* evap, G4bool corFlag=false);// Final Evap.
void EvaporateResidual(G4QHadron* h);// Final Evaporation of a nucl. fragment
void DecayBaryon(G4QHadron* dB); // Decay baryon (gamma+N or Delta->N+Pi)
void DecayDibaryon(G4QHadron* dB); // Decay di-baryon (deuteron is kept)
void DecayIsonucleus(G4QHadron* dB); // Decay nP+(Pi+) or nN+(Pi-) system
void DecayMultyBaryon(G4QHadron* dB);// Decay of Ap, An or AL states
void DecayAntiStrange(G4QHadron* dB);// Decay nuclei containing K+/K0
void DecayAlphaBar(G4QHadron* dB); // Decay of alpha+p or alpha+n states
void DecayAlphaDiN(G4QHadron* dB); // Decay of alpha+p+p states
void DecayAlphaAlpha(G4QHadron* dB); // Decay of alpha+alpha state
G4bool CheckGroundState(G4Quasmon* quasm,G4bool corFlag=false);//as G4Q for QHV
G4bool DecayInEnvQ(G4Quasmon* quasm); // Use befor evaporation in PANIC case
@@ -25,7 +25,7 @@
//
//
// $Id: G4QException.hh,v 1.10 2006/06/29 20:06:13 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QException ----------------
// by Mikhail Kossov, November 2003.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QFragmentation.hh,v 1.2 2006/12/12 11:02:22 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// -----------------------------------------------------------------------------
// GEANT 4 class header file
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4QHadron.hh,v 1.34 2006/11/20 16:29:11 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4QHadron.hh,v 1.35 2007/08/28 15:42:32 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QHadron ----------------
// by Mikhail Kossov, Sept 1999.
@@ -111,8 +111,14 @@ public:
G4bool CorMDecayIn2(G4double corM, G4LorentzVector& fr4Mom);// This(newMass corM)+fr4Mom
G4bool CorEDecayIn2(G4double corE, G4LorentzVector& fr4Mom);// This(E+=cE,P)+f(fE-=cE,fP)
G4bool RelDecayIn2(G4LorentzVector& f4Mom, G4LorentzVector& s4Mom, G4LorentzVector& dir,
G4double maxCost = 1., G4double minCost = -1.);
G4double maxCost = 1., G4double minCost = -1.);
G4bool CopDecayIn2(G4LorentzVector& f4Mom, G4LorentzVector& s4Mom, G4LorentzVector& dir,
G4double cop);
G4bool DecayIn3(G4LorentzVector& f4Mom, G4LorentzVector& s4Mom, G4LorentzVector& t4Mom);
G4bool RelDecayIn3(G4LorentzVector& fh4M, G4LorentzVector& sh4M, G4LorentzVector& th4Mom,
G4LorentzVector& dir, G4double maxCost = 1., G4double minCost = -1.);
G4bool CopDecayIn3(G4LorentzVector& fh4M, G4LorentzVector& sh4M, G4LorentzVector& th4Mom,
G4LorentzVector& dir, G4double cosp);
void Init3D(); // Initializes 3D nucleus with (Pos,4M)nucleons
private:
@@ -25,7 +25,7 @@
//
//
// $Id: G4QHadronBuilder.hh,v 1.2 2006/12/12 11:02:22 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// -----------------------------------------------------------------------------
// GEANT 4 class header file
@@ -25,7 +25,7 @@
//
//
// $Id: G4QHadronVector.hh,v 1.22 2006/11/16 11:36:09 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCandidateVector ----------------
// by Mikhail Kossov, Sept 1999.
@@ -36,7 +36,7 @@
#define G4QHadronVector_h 1
//
// $Id: G4QHadronVector.hh,v 1.22 2006/11/16 11:36:09 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ------------------------------------------------------------
// GEANT 4 class implementation file
@@ -25,7 +25,7 @@
//
//
// $Id: G4QInteraction.hh,v 1.2 2006/12/12 11:02:22 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
#ifndef G4QInteraction_h
@@ -25,7 +25,7 @@
//
//
// $Id: G4QInteractionVector.hh,v 1.1 2006/10/30 10:40:34 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCandidateVector ----------------
// by Mikhail Kossov, Sept 1999.
@@ -37,7 +37,7 @@
//
// $Id: G4QInteractionVector.hh,v 1.1 2006/10/30 10:40:34 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ------------------------------------------------------------------
// GEANT 4 class implementation file
@@ -25,7 +25,7 @@
//
//
// $Id: G4QIsotope.hh,v 1.5 2006/06/29 20:06:19 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// ---------------- G4QIsotope header ----------------
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4QNucleus.hh,v 1.31 2006/10/27 16:47:34 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4QNucleus.hh,v 1.33 2007/10/31 13:23:07 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QNucleus ----------------
// by Mikhail Kossov, Sept 1999.
@@ -37,6 +37,7 @@
#include "G4QCandidateVector.hh"
#include "G4QHadronVector.hh"
#include "G4QChipolino.hh"
#include <utility>
#include <vector>
#include "globals.hh"
@@ -51,7 +52,7 @@ public:
G4QNucleus(G4QContent nucQC, G4LorentzVector p); // Full QuarkCont-Constructor
G4QNucleus(G4int z, G4int n, G4int s=0); // At Rest ZNS-Constructor
G4QNucleus(G4int z, G4int n, G4int s, G4LorentzVector p);// Full ZNS-Constructor
G4QNucleus(const G4QNucleus& right); // Copy Constructor by value
//G4QNucleus(const G4QNucleus& right); // Copy Constructor by value
G4QNucleus(G4QNucleus* right); // Copy Constructor by pointer
~G4QNucleus(); // Public Destructor
// Overloaded Operators
@@ -93,10 +94,20 @@ public:
}
G4QHadron* GetNextNucleon()
{return (currentNucleon>=0&&currentNucleon<GetA()) ? theNucleons[currentNucleon++] :0;}
std::vector<G4double>* GetBThickness() const {return Tb;} // T(b) function, step .1 fm
//std::vector<G4double>* GetBThickness() const {return Tb;} // T(b) function, step .1 fm
std::vector<G4double> const* GetBThickness() {return &Tb;} // T(b) function, step .1 fm
// Specific Modifiers
G4bool EvaporateBaryon(G4QHadron* h1,G4QHadron* h2); // Evaporate Baryon from Nucleus
void EvaporateNucleus(G4QHadron* hA, G4QHadronVector* oHV);// Evaporate Nucleus
//void DecayBaryon(G4QHadron* dB, G4QHadronVector* oHV); // gamma+N or Delt->N+Pi @@later
void DecayDibaryon(G4QHadron* dB, G4QHadronVector* oHV); // deuteron is kept
void DecayIsonucleus(G4QHadron* dB, G4QHadronVector* oHV); // nP+(Pi+) or nN+(Pi-)
void DecayMultyBaryon(G4QHadron* dB, G4QHadronVector* oHV);// A*p, A*n or A*L
void DecayAntiStrange(G4QHadron* dB, G4QHadronVector* oHV);// nuclei with K+/K0
void DecayAlphaBar(G4QHadron* dB, G4QHadronVector* oHV); // alpha+p or alpha+n
void DecayAlphaDiN(G4QHadron* dB, G4QHadronVector* oHV); // alpha+p+p
void DecayAlphaAlpha(G4QHadron* dB, G4QHadronVector* oHV); // alpha+alpha
G4int SplitBaryon(); // Is it possible to split baryon/alpha
G4int HadrToNucPDG(G4int hPDG); // Converts hadronic PDGCode to nuclear
G4int NucToHadrPDG(G4int nPDG); // Converts nuclear PDGCode to hadronic
@@ -180,7 +191,8 @@ private:
G4int currentNucleon; // Current nucleon for the NextNucleon (? M.K.)
G4double rho0; // Normalazation density
G4double radius; // Nuclear radius
std::vector<G4double>* Tb; // T(b) function with step .1 fm (@@ make .1 a parameter)
//std::vector<G4double>* Tb; // T(b) function with step .1 fm (@@ make .1 a parameter)
std::vector<G4double> Tb; // T(b) function with step .1 fm (@@ make .1 a parameter)
};
std::ostream& operator<<(std::ostream& lhs, G4QNucleus& rhs);
@@ -25,7 +25,7 @@
//
//
// $Id: G4QPDGCode.hh,v 1.26 2006/06/29 20:06:23 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QPDGCode ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QPDGCodeVector.hh,v 1.19 2006/06/29 20:06:25 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCandidateVector ----------------
// by Mikhail Kossov, Sept 1999.
@@ -24,7 +24,7 @@
// ********************************************************************
//
// $Id: G4QPDGToG4Particle.hh,v 1.4 2006/06/29 20:06:27 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QPDGToG4Particle header ----------------
// by Mikhail Kossov, December 2003.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QParentCluster.hh,v 1.23 2006/06/29 20:06:29 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QParentCluster ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QParentClusterVector.hh,v 1.18 2006/06/29 20:06:31 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCandidateVector ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QParticle.hh,v 1.24 2006/06/29 20:06:33 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QParticle ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QParticleVector.hh,v 1.19 2006/06/29 20:06:35 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCandidateVector ----------------
// by Mikhail Kossov, Sept 1999.
@@ -28,7 +28,7 @@
#define G4QParton_h 1
// $Id: G4QParton.hh,v 1.2 2006/12/12 11:02:22 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ------------------------------------------------------------
// GEANT 4 class header file
@@ -27,7 +27,7 @@
#define G4QPartonPair_h 1
//
// $Id: G4QPartonPair.hh,v 1.1 2006/10/30 10:40:34 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ------------------------------------------------------------
// GEANT 4 class implementation file
@@ -25,7 +25,7 @@
//
//
// $Id: G4QPartonPairVector.hh,v 1.1 2006/11/16 11:36:09 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCandidateVector ----------------
// by Mikhail Kossov, October 2006.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QPartonVector.hh,v 1.1 2006/10/30 10:40:34 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCandidateVector ----------------
// by Mikhail Kossov, Oct 2006.
@@ -36,7 +36,7 @@
#define G4QPartonVector_h 1
//
// $Id: G4QPartonVector.hh,v 1.1 2006/10/30 10:40:34 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ------------------------------------------------------------
// GEANT 4 class implementation file
@@ -27,7 +27,7 @@
#define G4QPomeron_h 1
//
// $Id: G4QPomeron.hh,v 1.2 2006/12/12 11:02:22 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ------------------------------------------------------------
// GEANT 4 class implementation file
@@ -25,7 +25,7 @@
//
//
// $Id: G4QSplitter.hh,v 1.2 2006/06/29 20:06:37 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QSplitter ----------------
// by Mikhail Kossov, Avgust 2005.
@@ -26,7 +26,7 @@
//
//
// $Id: G4QString.hh,v 1.2 2006/12/12 11:02:22 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
#ifndef G4QString_h
#define G4QString_h 1
@@ -25,7 +25,7 @@
//
//
// $Id: G4QStringVector.hh,v 1.1 2006/10/30 10:40:35 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QStringVector ----------------
// by Mikhail Kossov, October 2006.
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4Quasmon.hh,v 1.38 2006/06/29 20:06:39 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4Quasmon.hh,v 1.39 2007/08/09 13:07:47 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4Quasmon ----------------
// by Mikhail Kossov, July 1999.
@@ -100,8 +100,8 @@ private:
G4double GetRandomMass(G4int PDGCode, G4double maxM);
void ModifyInMatterCandidates();
void CalculateHadronizationProbabilities(G4double excE, G4double kQ,
G4LorentzVector k4M,
G4bool piF, G4bool gaF);
G4LorentzVector k4M, G4bool piF,
G4bool gaF, G4bool first=false);
void FillHadronVector(G4QHadron* qHadron);
G4int RandomPoisson(G4double meanValue);
G4double GetQPartonMomentum(G4double mMinResidual2, G4double mCandidate2);
@@ -25,7 +25,7 @@
//
//
// $Id: G4QuasmonString.hh,v 1.4 2006/06/29 20:06:41 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QuasmonString ----------------
// by Mikhail Kossov, October 2004.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QuasmonVector.hh,v 1.19 2006/06/29 20:06:43 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QuasmonVector ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QBesIKJY.cc,v 1.2 2006/06/29 20:06:45 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QBesIKJY ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QCHIPSWorld.cc,v 1.32 2006/06/29 20:06:47 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCHIPSWorld ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QCandidate.cc,v 1.34 2006/11/27 10:44:53 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCandidate ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QChipolino.cc,v 1.32 2006/11/27 10:44:53 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QChipolino ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QContent.cc,v 1.43 2006/11/27 10:44:53 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QContent ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QDecayChan.cc,v 1.27 2006/11/27 10:44:54 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QDecayChan ----------------
// by Mikhail Kossov, Sept 1999.
File diff suppressed because it is too large Load Diff
@@ -25,7 +25,7 @@
//
//
// $Id: G4QException.cc,v 1.9 2006/06/29 20:06:59 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QException ----------------
// by Mikhail Kossov, November 2003.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QFragmentation.cc,v 1.3 2007/05/02 14:59:55 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// -----------------------------------------------------------------------------
// GEANT 4 class header file
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4QHadron.cc,v 1.48 2007/05/03 07:54:58 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4QHadron.cc,v 1.51 2007/11/15 09:33:22 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QHadron ----------------
// by Mikhail Kossov, Sept 1999.
@@ -50,17 +50,17 @@ G4double G4QHadron::widthOfPtSquare = 0.01*GeV*GeV; // ? M.K.
G4double G4QHadron::minTransverseMass = 1.*keV; // ? M.K.
G4QHadron::G4QHadron() : theQPDG(0),theMomentum(0.,0.,0.,0.),valQ(0,0,0,0,0,0),nFragm(0),
thePosition(0.,0.,0.),theCollisionCount(0),isSplit(false),Direction(true),bindE(0.),
formTime(0.) {}
thePosition(0.,0.,0.),theCollisionCount(0),isSplit(false),Direction(true),
Color(),AntiColor(),bindE(0.),formTime(0.) {}
G4QHadron::G4QHadron(G4LorentzVector p) : theQPDG(0),theMomentum(p),valQ(0,0,0,0,0,0),
nFragm(0),thePosition(0.,0.,0.),theCollisionCount(0),isSplit(false),Direction(true),
bindE(0.),formTime(0.) {}
Color(),AntiColor(),bindE(0.),formTime(0.) {}
// For Chipolino or Quasmon doesn't make any sense
G4QHadron::G4QHadron(G4int PDGCode, G4LorentzVector p) : theQPDG(PDGCode),theMomentum(p),
nFragm(0),thePosition(0.,0.,0.),theCollisionCount(0),isSplit(false),Direction(true),
bindE(0.),formTime(0.)
Color(),AntiColor(),bindE(0.),formTime(0.)
{
#ifdef debug
G4cout<<"G4QHadron must be created with PDG="<<PDGCode<<", 4M="<<p<<G4endl;
@@ -80,7 +80,7 @@ G4QHadron::G4QHadron(G4int PDGCode, G4LorentzVector p) : theQPDG(PDGCode),theMom
// For Chipolino or Quasmon doesn't make any sense
G4QHadron::G4QHadron(G4QPDGCode QPDG, G4LorentzVector p) : theQPDG(QPDG),theMomentum(p),
nFragm(0),thePosition(0.,0.,0.),theCollisionCount(0),isSplit(false),Direction(true),
bindE(0.),formTime(0.)
Color(),AntiColor(),bindE(0.),formTime(0.)
{
if(theQPDG.GetQCode()>-1)
{
@@ -98,7 +98,7 @@ G4QHadron::G4QHadron(G4QPDGCode QPDG, G4LorentzVector p) : theQPDG(QPDG),theMome
// Make sense Chipolino or Quasmon
G4QHadron::G4QHadron(G4QContent QC, G4LorentzVector p): theQPDG(0),theMomentum(p),valQ(QC),
nFragm(0),thePosition(0.,0.,0.),theCollisionCount(0),isSplit(false),Direction(true),
bindE(0.),formTime(0.)
Color(),AntiColor(),bindE(0.),formTime(0.)
{
G4int curPDG=valQ.GetSPDGCode();
if(curPDG==10&&valQ.GetBaryonNumber()>0) curPDG=valQ.GetZNSPDGCode();
@@ -108,27 +108,32 @@ G4QHadron::G4QHadron(G4QContent QC, G4LorentzVector p): theQPDG(0),theMomentum(p
G4QHadron::G4QHadron(G4int PDGCode, G4double aMass, G4QContent QC) :
theQPDG(PDGCode),theMomentum(0.,0.,0., aMass),valQ(QC),nFragm(0),thePosition(0.,0.,0.),
theCollisionCount(0),isSplit(false),Direction(true),bindE(0.),formTime(0.)
theCollisionCount(0),isSplit(false),Direction(true),Color(),AntiColor(),bindE(0.),
formTime(0.)
{}
G4QHadron::G4QHadron(G4QPDGCode QPDG, G4double aMass, G4QContent QC) :
theQPDG(QPDG),theMomentum(0.,0.,0., aMass),valQ(QC),nFragm(0),thePosition(0.,0.,0.),
theCollisionCount(0),isSplit(false),Direction(true),bindE(0.),formTime(0.)
theCollisionCount(0),isSplit(false),Direction(true),Color(),AntiColor(),bindE(0.),
formTime(0.)
{}
G4QHadron::G4QHadron(G4int PDGCode, G4LorentzVector p, G4QContent QC) :
theQPDG(PDGCode),theMomentum(p),valQ(QC),nFragm(0),thePosition(0.,0.,0.),
theCollisionCount(0),isSplit(false),Direction(true),bindE(0.),formTime(0.)
theCollisionCount(0),isSplit(false),Direction(true),Color(),AntiColor(),bindE(0.),
formTime(0.)
{}
G4QHadron::G4QHadron(G4QPDGCode QPDG, G4LorentzVector p, G4QContent QC) :
theQPDG(QPDG),theMomentum(p),valQ(QC),nFragm(0),thePosition(0.,0.,0.),
theCollisionCount(0),isSplit(false),Direction(true),bindE(0.),formTime(0.)
theCollisionCount(0),isSplit(false),Direction(true),Color(),AntiColor(),bindE(0.),
formTime(0.)
{}
G4QHadron::G4QHadron(G4QParticle* pPart, G4double maxM) :
theQPDG(pPart->GetQPDG()),theMomentum(0.,0.,0.,0.),nFragm(0),thePosition(0.,0.,0.),
theCollisionCount(0),isSplit(false),Direction(true),bindE(0.),formTime(0.)
theCollisionCount(0),isSplit(false),Direction(true),Color(),AntiColor(),bindE(0.),
formTime(0.)
{
#ifdef debug
G4cout<<"G4QHadron is created & randomized with maxM="<<maxM<<G4endl;
@@ -198,7 +203,14 @@ const G4QHadron& G4QHadron::operator=(const G4QHadron &right)
return *this;
}
G4QHadron::~G4QHadron() {}
G4QHadron::~G4QHadron()
{
std::deque<G4QParton*>::iterator pos;
for(pos=Color.begin(); pos<Color.end(); pos++) {delete [] *pos;}
Color.clear();
for(pos=AntiColor.begin(); pos<AntiColor.end(); pos++) {delete [] *pos;}
AntiColor.clear();
}
// Define quark content of the particle with a particular PDG Code
void G4QHadron::DefineQC(G4int PDGCode)
@@ -395,6 +407,130 @@ G4bool G4QHadron::RelDecayIn2(G4LorentzVector& f4Mom, G4LorentzVector& s4Mom,
return true;
} // End of "RelDecayIn2"
// Decay of Hadron In2Particles f&s, f w/r/to dN/dO [cp>0: ~cost^cp, cp<0: ~(1-cost)^(-cp)]
G4bool G4QHadron::CopDecayIn2(G4LorentzVector& f4Mom, G4LorentzVector& s4Mom,
G4LorentzVector& dir, G4double cosp)
{// ===================================================================
G4double fM2 = f4Mom.m2();
G4double fM = sqrt(fM2); // Mass of the 1st Hadron
G4double sM2 = s4Mom.m2();
G4double sM = sqrt(sM2); // Mass of the 2nd Hadron
G4double iM2 = theMomentum.m2();
G4double iM = sqrt(iM2); // Mass of the decaying hadron
G4double vP = theMomentum.rho(); // Momentum of the decaying hadron
G4double dE = theMomentum.e(); // Energy of the decaying hadron
G4bool neg=false; // Negative (backward) distribution of t
if(cosp<0)
{
cosp=-cosp;
neg=true;
}
if(dE<vP)
{
G4cerr<<"***G4QHad::CopDecIn2: Tachionic 4-mom="<<theMomentum<<", E-p="<<dE-vP<<G4endl;
G4double accuracy=.000001*vP;
G4double emodif=std::fabs(dE-vP);
//if(emodif<accuracy)
//{
G4cerr<<"G4QHadron::CopDecIn2: *Boost* E-p shift is corrected to "<<emodif<<G4endl;
theMomentum.setE(vP+emodif+.01*accuracy);
//}
}
G4ThreeVector ltb = theMomentum.boostVector();// Boost vector for backward Lorentz Trans.
G4ThreeVector ltf = -ltb; // Boost vector for forward Lorentz Trans.
G4LorentzVector cdir = dir; // A copy to make a transformation to CMS
#ifdef ppdebug
if(cdir.e()+.001<cdir.rho()) G4cerr<<"*G4QH::RDIn2:*Boost* cd4M="<<cdir<<",e-p="
<<cdir.e()-cdir.rho()<<G4endl;
#endif
cdir.boost(ltf); // Direction transpormed to CMS of the Momentum
G4ThreeVector vdir = cdir.vect(); // 3-Vector of the direction-particle
#ifdef ppdebug
G4cout<<"G4QHad::CopDI2:dir="<<dir<<",ltf="<<ltf<<",cdir="<<cdir<<",vdir="<<vdir<<G4endl;
#endif
G4ThreeVector vx(0.,0.,1.); // Ort in the direction of the reference particle
G4ThreeVector vy(0.,1.,0.); // First ort orthogonal to the direction
G4ThreeVector vz(1.,0.,0.); // Second ort orthoganal to the direction
if(vdir.mag2() > 0.) // the refference particle isn't at rest in CMS
{
vx = vdir.unit(); // Ort in the direction of the reference particle
#ifdef ppdebug
G4cout<<"G4QH::CopDecIn2:Vx="<<vx<<",M="<<theMomentum<<",d="<<dir<<",c="<<cdir<<G4endl;
#endif
G4ThreeVector vv= vx.orthogonal(); // Not normed orthogonal vector (!)
vy = vv.unit(); // First ort orthogonal to the direction
vz = vx.cross(vy); // Second ort orthoganal to the direction
}
#ifdef ppdebug
G4cout<<"G4QHad::CopDecIn2:iM="<<iM<<"=>fM="<<fM<<"+sM="<<sM<<",ob="<<vx<<vy<<vz<<G4endl;
#endif
if(fabs(iM-fM-sM)<.00000001)
{
G4double fR=fM/iM;
G4double sR=sM/iM;
f4Mom=fR*theMomentum;
s4Mom=sR*theMomentum;
return true;
}
else if (iM+.001<fM+sM || iM==0.)
{//@@ Later on make a quark content check for the decay
G4cerr<<"***G4QH::CopDecIn2: fM="<<fM<<"+sM="<<sM<<">iM="<<iM<<",d="<<iM-fM-sM<<G4endl;
return false;
}
G4double d2 = iM2-fM2-sM2;
G4double p2 = (d2*d2/4.-fM2*sM2)/iM2; // Decay momentum(^2) in CMS of Quasmon
if(p2<0.)
{
#ifdef ppdebug
G4cout<<"*G4QH:CopDI2:p2="<<p2<<"<0,d4/4="<<d2*d2/4.<<"<4*fM2*sM2="<<4*fM2*sM2<<G4endl;
#endif
p2=0.;
}
G4double p = sqrt(p2);
G4double ct = 0;
G4double rn = pow(G4UniformRand(),cosp+1.);
if(neg) ct = rn+rn-1.; // More backward than forward
else ct = 1.-rn-rn; // More forward than backward
//
G4double phi= twopi*G4UniformRand(); // @@ Change 360.*deg to M_TWOPI (?)
G4double ps=0.;
if(fabs(ct)<1.) ps = p * sqrt(1.-ct*ct);
else
{
#ifdef ppdebug
G4cout<<"**G4QH::CopDecayIn2:ct="<<ct<<",mac="<<maxCost<<",mic="<<minCost<<G4endl;
//throw G4QException("***G4QHadron::RDIn2: bad cos(theta)");
#endif
if(ct>1.) ct=1.;
if(ct<-1.) ct=-1.;
}
G4ThreeVector pVect=(ps*sin(phi))*vz+(ps*cos(phi))*vy+p*ct*vx;
#ifdef ppdebug
G4cout<<"G4QH::CopDIn2:ct="<<ct<<",p="<<p<<",ps="<<ps<<",ph="<<phi<<",v="<<pVect<<G4endl;
#endif
f4Mom.setVect(pVect);
f4Mom.setE(sqrt(fM2+p2));
s4Mom.setVect((-1)*pVect);
s4Mom.setE(sqrt(sM2+p2));
#ifdef ppdebug
G4cout<<"G4QHadr::CopDecIn2:p2="<<p2<<",v="<<ltb<<",f4M="<<f4Mom<<" + s4M="<<s4Mom<<" = "
<<f4Mom+s4Mom<<", M="<<iM<<G4endl;
#endif
if(f4Mom.e()+.001<f4Mom.rho())G4cerr<<"*G4QH::RDIn2:*Boost* f4M="<<f4Mom<<",e-p="
<<f4Mom.e()-f4Mom.rho()<<G4endl;
f4Mom.boost(ltb); // Lor.Trans. of 1st hadron back to LS
if(s4Mom.e()+.001<s4Mom.rho())G4cerr<<"*G4QH::RDIn2:*Boost* s4M="<<s4Mom<<",e-p="
<<s4Mom.e()-s4Mom.rho()<<G4endl;
s4Mom.boost(ltb); // Lor.Trans. of 2nd hadron back to LS
#ifdef ppdebug
G4cout<<"G4QHadron::CopDecayIn2:Output, f4Mom="<<f4Mom<<" + s4Mom="<<s4Mom<<" = "
<<f4Mom+s4Mom<<", d4M="<<theMomentum-f4Mom-s4Mom<<G4endl;
#endif
return true;
} // End of "CopDecayIn2"
// Decay of the Hadron in 2 particles (f + s)
G4bool G4QHadron::DecayIn2(G4LorentzVector& f4Mom, G4LorentzVector& s4Mom)
{// ===================================================================
@@ -713,7 +849,176 @@ G4bool G4QHadron::DecayIn3
return false;
}
return true;
}
} // End of DecayIn3
// Relative Decay of the hadron in 3 particles i=>f+s+t (t is with respect to minC<ct<maxC)
G4bool G4QHadron::RelDecayIn3(G4LorentzVector& f4Mom, G4LorentzVector& s4Mom,
G4LorentzVector& t4Mom, G4LorentzVector& dir,
G4double maxCost, G4double minCost)
{// ====================================================================================
#ifdef debug
G4cout<<"G4QH::RelDIn3:"<<theMomentum<<"=>f="<<f4Mom<<"+s="<<s4Mom<<"+t="<<t4Mom<<G4endl;
#endif
G4double iM = theMomentum.m(); // Mass of the decaying hadron
G4double fM = f4Mom.m(); // Mass of the 1st hadron
G4double sM = s4Mom.m(); // Mass of the 2nd hadron
G4double tM = t4Mom.m(); // Mass of the 3rd hadron
G4double eps = 0.001; // Accuracy of the split condition
if (fabs(iM-fM-sM-tM)<=eps)
{
G4double fR=fM/iM;
G4double sR=sM/iM;
G4double tR=tM/iM;
f4Mom=fR*theMomentum;
s4Mom=sR*theMomentum;
t4Mom=tR*theMomentum;
return true;
}
if (iM+eps<fM+sM+tM)
{
G4cout<<"***G4QHadron::RelDecayIn3:fM="<<fM<<" + sM="<<sM<<" + tM="<<tM<<" > iM="<<iM
<<",d="<<iM-fM-sM-tM<<G4endl;
return false;
}
G4double fM2 = fM*fM;
G4double sM2 = sM*sM;
G4double tM2 = tM*tM;
G4double iM2 = iM*iM;
G4double m13sBase=(iM-sM)*(iM-sM)-(fM+tM)*(fM+tM);
G4double m12sMin =(fM+sM)*(fM+sM);
G4double m12sBase=(iM-tM)*(iM-tM)-m12sMin;
G4double rR = 0.;
G4double rnd= 1.;
#ifdef debug
G4int tr = 0; //@@ Comment if "cout" below is skiped @@
#endif
G4double m12s = 0.; // Fake definition before the Loop
while (rnd > rR)
{
m12s = m12sMin + m12sBase*G4UniformRand();
G4double e1=m12s+fM2-sM2;
G4double e2=iM2-m12s-tM2;
G4double four12=4*m12s;
G4double m13sRange=0.;
G4double dif=(e1*e1-four12*fM2)*(e2*e2-four12*tM2);
if(dif<0.)
{
#ifdef debug
if(dif<-.01) G4cerr<<"G4QHadron::RelDecayIn3:iM="<<iM<<",tM="<<tM<<",sM="<<sM<<",fM="
<<fM<<",m12(s+f)="<<sqrt(m12s)<<", d="<<iM-fM-sM-tM<<G4endl;
#endif
}
else m13sRange=sqrt(dif)/m12s;
rR = m13sRange/m13sBase;
rnd= G4UniformRand();
#ifdef debug
G4cout<<"G4QHadron::RelDecayIn3: try decay #"<<++tr<<", rR="<<rR<<",rnd="<<rnd<<G4endl;
#endif
}
G4double m12 = sqrt(m12s); // Mass of the H1+H2 system
G4LorentzVector dh4Mom(0.,0.,0.,m12);
if(!RelDecayIn2(t4Mom,dh4Mom,dir,maxCost,minCost))
{
G4cerr<<"***G4QHadron::RelDecayIn3: Exception1"<<G4endl;
//throw G4QException("G4QHadron::DecayIn3(): DecayIn2 did not succeed");
return false;
}
#ifdef debug
G4cout<<"G4QHadron::RelDecayIn3: Now the last decay of m12="<<dh4Mom.m()<<G4endl;
#endif
if(!G4QHadron(dh4Mom).DecayIn2(f4Mom,s4Mom))
{
G4cerr<<"***G4QHadron::RelDecayIn3: Error in DecayIn2 -> Exception2"<<G4endl;
//throw G4QException("G4QHadron::DecayIn3(): DecayIn2 did not succeed");
return false;
}
return true;
} // End of RelDecayIn3
// Relative Decay of hadron in 3: i=>f+s+t. dN/dO [cp>0:~cost^cp, cp<0:~(1-cost)^(-cp)]
G4bool G4QHadron::CopDecayIn3(G4LorentzVector& f4Mom, G4LorentzVector& s4Mom,
G4LorentzVector& t4Mom, G4LorentzVector& dir, G4double cosp)
{// ====================================================================================
#ifdef debug
G4cout<<"G4QH::CopDIn3:"<<theMomentum<<"=>f="<<f4Mom<<"+s="<<s4Mom<<"+t="<<t4Mom<<G4endl;
#endif
G4double iM = theMomentum.m(); // Mass of the decaying hadron
G4double fM = f4Mom.m(); // Mass of the 1st hadron
G4double sM = s4Mom.m(); // Mass of the 2nd hadron
G4double tM = t4Mom.m(); // Mass of the 3rd hadron
G4double eps = 0.001; // Accuracy of the split condition
if (fabs(iM-fM-sM-tM)<=eps)
{
G4double fR=fM/iM;
G4double sR=sM/iM;
G4double tR=tM/iM;
f4Mom=fR*theMomentum;
s4Mom=sR*theMomentum;
t4Mom=tR*theMomentum;
return true;
}
if (iM+eps<fM+sM+tM)
{
G4cout<<"***G4QHadron::CopDecayIn3:fM="<<fM<<" + sM="<<sM<<" + tM="<<tM<<" > iM="<<iM
<<",d="<<iM-fM-sM-tM<<G4endl;
return false;
}
G4double fM2 = fM*fM;
G4double sM2 = sM*sM;
G4double tM2 = tM*tM;
G4double iM2 = iM*iM;
G4double m13sBase=(iM-sM)*(iM-sM)-(fM+tM)*(fM+tM);
G4double m12sMin =(fM+sM)*(fM+sM);
G4double m12sBase=(iM-tM)*(iM-tM)-m12sMin;
G4double rR = 0.;
G4double rnd= 1.;
#ifdef debug
G4int tr = 0; //@@ Comment if "cout" below is skiped @@
#endif
G4double m12s = 0.; // Fake definition before the Loop
while (rnd > rR)
{
m12s = m12sMin + m12sBase*G4UniformRand();
G4double e1=m12s+fM2-sM2;
G4double e2=iM2-m12s-tM2;
G4double four12=4*m12s;
G4double m13sRange=0.;
G4double dif=(e1*e1-four12*fM2)*(e2*e2-four12*tM2);
if(dif<0.)
{
#ifdef debug
if(dif<-.01) G4cerr<<"G4QHadron::CopDecayIn3:iM="<<iM<<",tM="<<tM<<",sM="<<sM<<",fM="
<<fM<<",m12(s+f)="<<sqrt(m12s)<<", d="<<iM-fM-sM-tM<<G4endl;
#endif
}
else m13sRange=sqrt(dif)/m12s;
rR = m13sRange/m13sBase;
rnd= G4UniformRand();
#ifdef debug
G4cout<<"G4QHadron::CopDecayIn3: try decay #"<<++tr<<", rR="<<rR<<",rnd="<<rnd<<G4endl;
#endif
}
G4double m12 = sqrt(m12s); // Mass of the H1+H2 system
G4LorentzVector dh4Mom(0.,0.,0.,m12);
if(!CopDecayIn2(t4Mom,dh4Mom,dir,cosp))
{
G4cerr<<"***G4QHadron::CopDecayIn3: Exception1"<<G4endl;
//throw G4QException("G4QHadron::DecayIn3(): DecayIn2 did not succeed");
return false;
}
#ifdef debug
G4cout<<"G4QHadron::DecayIn3: Now the last decay of m12="<<dh4Mom.m()<<G4endl;
#endif
if(!G4QHadron(dh4Mom).DecayIn2(f4Mom,s4Mom))
{
G4cerr<<"***G4QHadron::CopDecayIn3: Error in DecayIn2 -> Exception2"<<G4endl;
//throw G4QException("G4QHadron::DecayIn3(): DecayIn2 did not succeed");
return false;
}
return true;
} // End of CopDecayIn3
// Randomize particle mass taking into account the width
G4double G4QHadron::RandomizeMass(G4QParticle* pPart, G4double maxM)
@@ -25,7 +25,7 @@
//
//
// $Id: G4QHadronBuilder.cc,v 1.2 2006/12/12 11:02:22 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// -----------------------------------------------------------------------------
// GEANT4 class implementation file
@@ -25,7 +25,7 @@
//
//
// $Id: G4QInteraction.cc,v 1.2 2006/12/12 11:02:22 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ------------------------------------------------------------------
// GEANT 4 class implementation file
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4QIsotope.cc,v 1.9 2006/12/07 19:25:49 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4QIsotope.cc,v 1.10 2007/11/28 14:14:36 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QIsotope class ----------------
// by Mikhail Kossov, December 2003.
@@ -656,6 +656,7 @@ G4QIsotope::G4QIsotope()
#ifdef cdebug
G4cout<<"G4QIsotope::Constructor: natIsoCrosS is filled"<<G4endl;
#endif
delete is;
}
#ifdef cdebug
G4cout<<"G4QIsotope::Constructor: is finished"<<G4endl;
@@ -667,7 +668,7 @@ G4QIsotope::~G4QIsotope() // The QIsotopes are destructed only in theEn
#ifdef debug
G4cout<<"G4QIsotope::Destructor is called"<<G4endl;
#endif
G4int uP=natElements.size(); // uP, nP, and sP must be the same
G4int uP=natElements.size();
if(uP) for(G4int i=0; i<uP; i++)
{
vector<pair<G4int,G4double>*>* curA=natElements[i];
File diff suppressed because it is too large Load Diff
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4QPDGCode.cc,v 1.53 2006/11/27 10:44:55 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4QPDGCode.cc,v 1.55 2007/10/07 13:31:42 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QPDGCode ----------------
// by Mikhail Kossov, Sept 1999.
@@ -1733,12 +1733,12 @@ G4double G4QPDGCode::CalculateNuclMass(G4int z, G4int n, G4int s)
}
else if(Bn==3)
{
if(!S) return mT; // Bn=3
if(!S) // Bn=3
{
if (Z==1 && N== 2) return mT; // tritium
else if(Z==2 && N== 1) return mHe3; // hetrium
}
if(S== 1 && Z==-1 && N== 3) return dnS; // nnSig-
if(S== 1 && Z==-1 && N== 3) // nnSig-
{
if (Z==-1 && N== 3) return dnS; // nnSig-
else if(Z== 3 && N==-1) return dpS; // ppSig+
@@ -1974,9 +1974,9 @@ G4double G4QPDGCode::CalculateNuclMass(G4int z, G4int n, G4int s)
if(S>0)
{
G4double bs=0.;
if (S==2) bs=a2;
else if(S==3) bs=a3;
else if(S>3) bs=b7*exp(-b8/(A+1.));
if (A==2) bs=a2;
else if(A==3) bs=a3;
else if(A>3) bs=b7*exp(-b8/(A+1.));
m+=S*(mL-bs);
}
#ifdef debug
@@ -2305,47 +2305,33 @@ void G4QPDGCode::ConvertPDGToZNS(G4int nucPDG, G4int& z, G4int& n, G4int& s)
{// =======================================================================
if(nucPDG>80000000&&nucPDG<100000000) // Condition of conversion
{
G4int r=nucPDG-90000000;
if(!r)
{
z=0;
n=0;
s=0;
return;
}
// Antinucleus extraction
if(r<-200000) // Negative -> anLambdas
z=0;
n=0;
s=0;
G4int r=nucPDG;
if(r==90000000) return;
G4int cn =r%1000; // candidate to #of neutrons
if(cn)
{
G4int ns=(-r-200000)/1000000+1;
r+=ns*1000000; // Get out aL from PDG
s=-ns; // Remember aLambdas
if(cn>500) cn-=1000; // AntiNeutrons
n=cn; // Increment neutrons
r-=cn; // Subtract them from the residual
if(r==90000000) return;
}
if(r<-200) // Negative -> aProtons
G4int cz =r%1000000; // candidate to #of neutrons
if(cz)
{
G4int nz=(-r-200)/1000+1;
r+=nz*1000; // Get out aP from PDG
z=-nz; // Remember aProtons
if(cz>500000) cz-=1000000; // AntiProtons
z=cz/1000; // Number of protons
r-=cz; // Subtract them from the residual
if(r==90000000) return;
}
if(r<0) // Negative -> aNeutrons
G4int cs =r%10000000; // candidate to #of neutrons
if(cs)
{
G4int nn=-r;
r=0; // Get out aN from PDG
n=-nn; // Remember aNeutrons
if(cs>5000000) cs-=10000000; // AntiLambda
s=cs/1000000; // Number of Lambdas
}
G4int sz =r/1000; // Residual to analize
n+=r%1000; // A#of Neutrons
if(n>700) // AntiNutrons
{
n-=1000;
z++;
}
z+=sz%1000; // A#of Protons
if(z>700) // AntiProtons
{
z-=1000;
s++;
}
s+=sz/1000; // A#of Lambdas
}
return;
}
@@ -24,7 +24,7 @@
// ********************************************************************
//
// $Id: G4QPDGToG4Particle.cc,v 1.5 2006/06/29 20:07:09 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QG4ToG4Particle singletone class ------------------
// by Mikhail Kossov, December 2003.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QParentCluster.cc,v 1.25 2006/11/27 10:44:55 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QParentCluster ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QParticle.cc,v 1.33 2006/11/27 10:44:55 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QParticle ----------------
// by Mikhail Kossov, Sept 1999.
@@ -25,7 +25,7 @@
//
//
// $Id: G4QParton.cc,v 1.3 2006/12/12 11:02:22 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ------------------------------------------------------------
// GEANT 4 class implementation file
@@ -26,7 +26,7 @@
#include "G4QPartonPair.hh"
//
// $Id: G4QPartonPair.cc,v 1.1 2006/10/30 10:40:36 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ------------------------------------------------------------
// GEANT 4 class implementation file
@@ -25,7 +25,7 @@
//
//
// $Id: G4QPomeron.cc,v 1.2 2006/12/12 11:02:22 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ------------------------------------------------------------
// GEANT 4 class implementation file
@@ -28,7 +28,7 @@
//
//
// $Id: G4QSplitter.cc,v 1.6 2006/11/27 10:44:55 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QSplitter ----------------
// by Mikhail Kossov, August 2005.
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4QString.cc,v 1.3 2006/12/12 11:02:22 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4QString.cc,v 1.4 2007/07/06 07:38:36 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ------------------------------------------------------------
// GEANT 4 class implementation file
@@ -409,15 +409,14 @@ G4QHadronVector* G4QString::FragmentString(G4bool QL)
// Creates a string, using only the end-partons of the string
G4QString* G4QString::CPExcited()
{
G4QParton* Left = new G4QParton(GetLeftParton());
G4QParton* Right= new G4QParton(GetRightParton());
return new G4QString(Left,Right,GetDirection());
G4QParton* LeftParton = new G4QParton(GetLeftParton());
G4QParton* RightParton= new G4QParton(GetRightParton());
return new G4QString(LeftParton,RightParton,GetDirection());
} // End of CPExcited
// Simple decay of the string
G4QHadronVector* G4QString::LightFragmentationTest()
{
static const G4double MassCut = 0.35*GeV;
// Check string decay threshold
G4QHadronVector* result=0; // return 0 when string exceeds the mass cut
File diff suppressed because it is too large Load Diff
@@ -28,7 +28,7 @@
//
//
// $Id: G4QuasmonString.cc,v 1.7 2006/11/27 10:44:55 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QuasmonString ----------------
// by Mikhail Kossov, August 2000.
@@ -26,7 +26,7 @@
//
//
// $Id: G4ElectroNuclearReaction.hh,v 1.23 2006/06/29 20:07:46 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4ElectroNuclearReaction -- header file
@@ -25,7 +25,7 @@
//
//
// $Id: G4GammaNuclearReaction.hh,v 1.13 2006/06/29 20:07:48 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4GammaNuclearReaction -- header file
@@ -0,0 +1,109 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id: G4QANuANuNuclearCrossSection.hh,v 1.1 2007/11/01 16:09:38 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QANuANuNuclearCrossSection -- header file
// M.V. Kossov, CERN-ITEP(Moscow), 20-DEC-2005
// The last update: M.V. Kossov, CERN/ITEP (Moscow) 20-DEC-2005
//
// Short description: this G4 singletone class calculates (nu_mu,mu) Nuclear cross section
// (Energy limit: E<320GeV->badExtrapolation) for a particular isotope (proportional to A)
// ****************************************************************************************
#ifndef G4QANuANuNuclearCrossSection_h
#define G4QANuANuNuclearCrossSection_h 1
#include "G4ParticleTable.hh"
#include "G4NucleiProperties.hh"
#include "G4NucleiPropertiesTable.hh"
#include <vector>
#include "Randomize.hh"
#include "G4MuonPlus.hh"
#include "G4MuonMinus.hh"
#include "G4VQCrossSection.hh"
class G4QANuANuNuclearCrossSection : public G4VQCrossSection
{
protected:
G4QANuANuNuclearCrossSection() {};
public:
~G4QANuANuNuclearCrossSection() {};
static G4VQCrossSection* GetPointer(); // Gives a pointer to this singletone
G4double ThresholdEnergy(G4int Z, G4int N, G4int PDG=-14);
// At present momentum (pMom) must be in GeV (@@ Units)
virtual G4double GetCrossSection(G4bool fCS, G4double pMom, G4int tgZ, G4int tgN,
G4int pPDG=0);
G4double CalculateCrossSection(G4bool CS, G4int F, G4int I, G4int PDG, G4int Z,
G4int N, G4double Momentum);
G4int GetExchangePDGCode();
G4double GetDirectPart(G4double Q2);
G4double GetNPartons(G4double Q2);
G4double GetQEL_ExchangeQ2();
G4double GetNQE_ExchangeQ2();
// Get static members
G4double GetLastTOTCS() {return lastSig;}
G4double GetLastQELCS() {return lastQEL;}
private:
G4int GetFunctions(G4int z, G4int n, G4double* t, G4double* q, G4double* e);
G4double HighEnergyTX(G4double lE);
G4double HighEnergyQE(G4double lE);
// Body
private:
static G4bool onlyCS; // flag to calculate only CS (not QE)
static G4double lastSig; // Last calculated total cross section
static G4double lastQEL; // Last calculated quasi-elastic cross section
static G4int lastL; // Last bin used in the cross section TheLastBin
static G4double lastE; // Last energy used in the cross section Energy
static G4double* lastEN; // Pointer to the last array of the energy axis
static G4double* lastTX; // Pointer to the last array of the total CS function
static G4double* lastQE; // Pointer to the last array of the QE CS function
static G4int lastPDG; // The last projectile PDG
static G4int lastN; // The last N of calculated nucleus
static G4int lastZ; // The last Z of calculated nucleus
static G4double lastP; // Last used in the cross section Momentum
static G4double lastTH; // Last value of the Momentum Threshold
static G4double lastCS; // Last value of the Cross Section
static G4int lastI; // The last position in the DAMDB
};
#endif
@@ -0,0 +1,109 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id: G4QANuENuclearCrossSection.hh,v 1.1 2007/10/02 10:00:37 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QANuENuclearCrossSection -- header file
// M.V. Kossov, CERN-ITEP(Moscow), 20-SEP-2007
// The last update: M.V. Kossov, CERN/ITEP (Moscow) 20-SEP-2007
//
// Short description: this G4 singletone class calculates (nu_e,e) Nuclear cross section
// (Energy limit: E<320GeV->badExtrapolation) for a particular isotope (proportional to A)
// ****************************************************************************************
#ifndef G4QANuENuclearCrossSection_h
#define G4QANuENuclearCrossSection_h 1
#include "G4ParticleTable.hh"
#include "G4NucleiProperties.hh"
#include "G4NucleiPropertiesTable.hh"
#include <vector>
#include "Randomize.hh"
#include "G4MuonPlus.hh"
#include "G4MuonMinus.hh"
#include "G4VQCrossSection.hh"
class G4QANuENuclearCrossSection : public G4VQCrossSection
{
protected:
G4QANuENuclearCrossSection() {};
public:
~G4QANuENuclearCrossSection() {};
static G4VQCrossSection* GetPointer(); // Gives a pointer to this singletone
G4double ThresholdEnergy(G4int Z, G4int N, G4int PDG=-12);
// At present momentum (pMom) must be in GeV (@@ Units)
virtual G4double GetCrossSection(G4bool fCS, G4double pMom, G4int tgZ, G4int tgN,
G4int pPDG=0);
G4double CalculateCrossSection(G4bool CS, G4int F, G4int I, G4int PDG, G4int Z,
G4int N, G4double Momentum);
G4int GetExchangePDGCode();
G4double GetDirectPart(G4double Q2);
G4double GetNPartons(G4double Q2);
G4double GetQEL_ExchangeQ2();
G4double GetNQE_ExchangeQ2();
// Get static members
G4double GetLastTOTCS() {return lastSig;}
G4double GetLastQELCS() {return lastQEL;}
private:
G4int GetFunctions(G4int z, G4int n, G4double* t, G4double* q, G4double* e);
G4double HighEnergyTX(G4double lE);
G4double HighEnergyQE(G4double lE);
// Body
private:
static G4bool onlyCS; // flag to calculate only CS (not QE)
static G4double lastSig; // Last calculated total cross section
static G4double lastQEL; // Last calculated quasi-elastic cross section
static G4int lastL; // Last bin used in the cross section TheLastBin
static G4double lastE; // Last energy used in the cross section Energy
static G4double* lastEN; // Pointer to the last array of the energy axis
static G4double* lastTX; // Pointer to the last array of the total CS function
static G4double* lastQE; // Pointer to the last array of the QE CS function
static G4int lastPDG; // The last projectile PDG
static G4int lastN; // The last N of calculated nucleus
static G4int lastZ; // The last Z of calculated nucleus
static G4double lastP; // Last used in the cross section Momentum
static G4double lastTH; // Last value of the Momentum Threshold
static G4double lastCS; // Last value of the Cross Section
static G4int lastI; // The last position in the DAMDB
};
#endif
@@ -25,7 +25,7 @@
//
//
// $Id: G4QANuMuNuclearCrossSection.hh,v 1.6 2006/12/01 10:57:46 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QANuMuNuclearCrossSection -- header file
@@ -24,7 +24,7 @@
// ********************************************************************
//
// $Id: G4QAtomicElectronScattering.hh,v 1.2 2006/12/13 15:45:16 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QAtomicElectronScattering header ----------------
// by Mikhail Kossov, December 2003.
@@ -24,7 +24,7 @@
// ********************************************************************
//
// $Id: G4QCaptureAtRest.hh,v 1.3 2007/02/09 09:33:28 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCaptureAtRest header ----------------
// by Mikhail Kossov, December 2003.
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4QCoherentChargeExchange.hh,v 1.3 2007/05/23 15:14:25 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4QCoherentChargeExchange.hh,v 1.4 2007/08/09 13:04:37 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCoherentChargeExchange header ----------------
// by Mikhail Kossov, December 2003.
@@ -57,6 +57,7 @@
#include "G4LorentzVector.hh"
// CHIPS Headers
#include "G4QuasiFreeRatios.hh"
#include "G4QElasticCrossSection.hh"
#include "G4QIsotope.hh"
#include "G4QPDGToG4Particle.hh"
@@ -107,9 +108,6 @@ private:
// Calculate XS/t: oxs=true - only CS; xst=true - calculate XS, xst=false(oxs=f/t) - t/tm
G4double CalculateXSt(G4bool oxs, G4bool xst, G4double p, G4int Z, G4int N, G4int pPDG);
// Calculate ChEx/El suppression coefficient
G4double ChExElCoef(G4double p, G4int Z, G4int N, G4int pPDG);
// BODY
// Static Parameters --------------------------------------------------------------------
static G4int nPartCWorld; // The#of particles for hadronization (limit of A of fragm.)
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4QCollision.hh,v 1.7 2006/10/30 10:33:36 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4QCollision.hh,v 1.10 2007/11/01 16:09:38 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCollision header ----------------
// by Mikhail Kossov, December 2003.
@@ -96,7 +96,12 @@
#include "G4QTauNuclearCrossSection.hh"
#include "G4QNuMuNuclearCrossSection.hh"
#include "G4QANuMuNuclearCrossSection.hh"
#include "G4QNuENuclearCrossSection.hh"
#include "G4QANuENuclearCrossSection.hh"
#include "G4QNuNuNuclearCrossSection.hh"
#include "G4QANuANuNuclearCrossSection.hh"
//#include "G4QuasmonString.hh"
#include "G4QuasiFreeRatios.hh"
#include "G4QPDGToG4Particle.hh"
#include <vector>
@@ -160,6 +165,9 @@ private:
// Copy constructor
G4QCollision(const G4QCollision&);
// Random direction in two dimentions pair(first=sin(phi), second=cos(phi))
std::pair<G4double,G4double> Random2DDirection();
// BODY
// Static Parameters --------------------------------------------------------------------
static G4bool manualFlag; // If false then standard parameters are used
@@ -0,0 +1,127 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4QDiffraction.hh,v 1.1 2007/08/23 15:58:43 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QDiffraction header ----------------
// by Mikhail Kossov, Aug 2007.
// Header of G4QDiffraction class (hadron+A) of the CHIPS Simulation Branch in GEANT4
// -------------------------------------------------------------------------------
// This is a unique CHIPS class for the Hadron-Nuclear Diffractive Interaction Prosesses
// -------------------------------------------------------------------------------
// At present (Aug-07) it is based on the G4QDiffractionRatio class and is not tested.
// The normalization is based on the temporary G4QProtonNuclearCrossSection class
// -------------------------------------------------------------------------------
#ifndef G4QDiffraction_hh
#define G4QDiffraction_hh
// GEANT4 Headers
#include "globals.hh"
#include "G4ios.hh"
#include "Randomize.hh"
#include "G4VDiscreteProcess.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ParticleTypes.hh"
#include "G4VParticleChange.hh"
#include "G4ParticleDefinition.hh"
#include "G4DynamicParticle.hh"
#include "G4NucleiPropertiesTable.hh"
#include "G4ThreeVector.hh"
#include "G4LorentzVector.hh"
// CHIPS Headers
#include "G4QDiffractionRatio.hh"
#include "G4QProtonNuclearCrossSection.hh"
#include "G4QIsotope.hh"
#include "G4QPDGToG4Particle.hh"
#include "G4QCHIPSWorld.hh"
#include "G4QHadronVector.hh"
#include <vector>
class G4QDiffraction : public G4VDiscreteProcess
{
public:
// Constructor
G4QDiffraction(const G4String& processName ="CHIPS_DiffractiveInteraction");
// Destructor
~G4QDiffraction();
G4bool IsApplicable(const G4ParticleDefinition& particle);
G4double GetMeanFreePath(const G4Track& aTrack, G4double previousStepSize,
G4ForceCondition* condition);
// It returns the MeanFreePath of the process for the current track :
// (energy, material)
// The previousStepSize and G4ForceCondition* are not used.
// This function overloads a virtual function of the base class.
// It is invoked by the ProcessManager of the Particle.
G4VParticleChange* PostStepDoIt(const G4Track& aTrack, const G4Step& aStep);
// It computes the final state of the process (at end of step),
// returned as a ParticleChange object.
// This function overloads a virtual function of the base class.
// It is invoked by the ProcessManager of the Particle.
G4LorentzVector GetEnegryMomentumConservation();
G4int GetNumberOfNeutronsInTarget();
private:
// Hide assignment operator as private
G4QDiffraction& operator=(const G4QDiffraction &right);
// Copy constructor
G4QDiffraction(const G4QDiffraction&);
// Calculate Cross-Section of the Diffraction Reaction (p is in GeV @@ units)
G4double CalculateXS(G4double p, G4int Z, G4int N, G4int pPDG);
// BODY
// Static Parameters --------------------------------------------------------------------
static G4int nPartCWorld; // The#of particles for hadronization (limit of A of fragm.)
//--------------------------------- End of static parameters ---------------------------
// Working parameters
G4VQCrossSection* theCS;
G4LorentzVector EnMomConservation; // Residual of Energy/Momentum Cons.
G4int nOfNeutrons; // #of neutrons in the target nucleus
// Modifires for the reaction
G4double Time; // Time shift of the capture reaction
G4double EnergyDeposition; // Energy deposited in the reaction
static std::vector <G4int> ElementZ; // Z of the element(i) in theLastCalc
static std::vector <G4double> ElProbInMat; // SumProbabilityElements in Material
static std::vector <std::vector<G4int>*> ElIsoN; // N of isotope(j) of Element(i)
static std::vector <std::vector<G4double>*> IsoProbInEl;// SumProbabIsotopes in Element i
};
#endif
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QDiffractionRatio -- header file
@@ -45,6 +45,7 @@
//#include "G4NucleiProperties.hh"
//#include "G4NucleiPropertiesTable.hh"
#include "G4QPDGCode.hh"
#include "G4QEnvironment.hh"
#include "G4Quasmon.hh"
#include "G4QHadronVector.hh"
#include "G4VCrossSectionDataSet.hh"
@@ -67,10 +68,18 @@ class G4QDiffractionRatio
// Diffraction/Prodaction Ratio (Production=Inelastic-QuasiElastic)
G4double GetRatio(G4double pIU, G4int prPDG, G4int tgZ, G4int tgN);
// ==> The following ill be a protected function for internal CHIPS usage
// Fragment(pPDG,p4M) on a nucleus (tgZ, tgN), result: Vector of secondary hadrons
// Whoeve uses this member function is responsible for DEL/DESTROY of the G4QHadronVector
G4QHadronVector* Fragment(G4int pPDG, G4LorentzVector p4M, G4int tgZ, G4int tgN);
// ==> The following will be a protected function for internal CHIPS usage
// ProjFragment(pPDG,p4M) on a nucleus (tgZ, tgN), result: Vector of secondary hadrons
// Whoever uses this member function is responsible for DEL/DESTROY of G4QHadronVector
G4QHadronVector* ProjFragment(G4int pPDG, G4LorentzVector p4M, G4int tgZ, G4int tgN);
// ==> The following will be a protected function for internal CHIPS usage
// TargFragment(pPDG,p4M) on a nucleus (tgZ, tgN), result: Vector of secondary hadrons
// Whoever uses this member function is responsible for DEL/DESTROY of G4QHadronVector
G4QHadronVector* TargFragment(G4int pPDG, G4LorentzVector p4M, G4int tgZ, G4int tgN);
// Single Diffraction Target Excitation Cross-Section (independent Units)
G4double GetTargSingDiffXS(G4double pIU, G4int prPDG, G4int tgZ, G4int tgN);
private:
// These working member functions are in CHIPS units and must not be used externally
@@ -0,0 +1,102 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4QDiscProcessMixer.hh,v 1.2 2007/08/31 09:36:57 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QDiscProcessMixer header ----------------
// by Mikhail Kossov, Aug 2007.
// Header of G4QDiscProcessMixer class (hadron+A) of the CHIPS Simulation Branch in GEANT4
// -------------------------------------------------------------------------------
// This is a unique CHIPS class for the Hadron-Nuclear Diffractive Interaction Prosesses
// -------------------------------------------------------------------------------
// At present (Aug-07) it is not tested.
// The normalization is based on the temporary G4QIonIonCrossSection class
// -------------------------------------------------------------------------------
#ifndef G4QDiscProcessMixer_hh
#define G4QDiscProcessMixer_hh
// GEANT4 Headers
#include "globals.hh"
#include "G4ios.hh"
#include "Randomize.hh"
#include "G4VDiscreteProcess.hh"
#include "G4Track.hh"
#include "G4Step.hh"
//#include "G4ParticleTypes.hh"
//#include "G4VParticleChange.hh"
//#include "G4ParticleDefinition.hh"
#include "G4ParticleDefinition.hh"
#include "G4Gamma.hh"
#include "G4DynamicParticle.hh"
#include "G4QDiscreteProcessVector.hh"
//#include "G4NucleiPropertiesTable.hh"
//#include "G4ThreeVector.hh"
//#include "G4LorentzVector.hh"
#include <vector>
class G4QDiscProcessMixer : public G4VDiscreteProcess
{
public:
// Constructor
G4QDiscProcessMixer(const G4String& processName = "Mixed Discrete Process",
const G4ParticleDefinition* proj = G4Gamma::Gamma(),
G4ProcessType pType = fNotDefined );
// Destructor
~G4QDiscProcessMixer();
G4bool IsApplicable(const G4ParticleDefinition& particle);
G4double PostStepGetPhysicalInteractionLength(const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition);
G4VParticleChange* PostStepDoIt(const G4Track& aTrack, const G4Step& aStep);
void AddDiscreteProcess(G4VDiscreteProcess* DP, G4double ME);
//G4LorentzVector GetEnegryMomentumConservation();
//G4int GetNumberOfNeutronsInTarget();
private:
// Hide assignment operator as private
G4QDiscProcessMixer& operator=(const G4QDiscProcessMixer &right);
// Copy constructor
G4QDiscProcessMixer(const G4QDiscProcessMixer& DPM);
// BODY
const G4ParticleDefinition* DPParticle; // Particle for DiscreteProc mixture
G4QDiscreteProcessVector theDPVector; // Vector of Discrete Processes
//G4LorentzVector EnMomConservation; // Residual of Energy/Momentum Cons.
//G4int nOfNeutrons; // #of neutrons in the target nucleus
};
#endif
@@ -0,0 +1,45 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id: G4QDiscreteProcessVector.hh,v 1.1 2007/08/28 15:48:15 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QDiscreteProcessVector ----------------
// by Mikhail Kossov, Aug 2007.
// Type defenition for Vectors of DiscreteProcesses (G4VDiscreteProcess)
// ---------------------------------------------------------------------
#ifndef G4QDiscreteProcessVector_h
#define G4QDiscreteProcessVector_h 1
#include "G4VDiscreteProcess.hh"
#include <vector>
typedef std::vector<std::pair<G4VDiscreteProcess*, G4double>*> G4QDiscreteProcessVector;
struct DeleteDiscreteProcess { void operator()(std::pair<G4VDiscreteProcess*,G4double>* DP)
{delete DP->first; delete DP;} };
#endif
@@ -24,7 +24,7 @@
// ********************************************************************
//
// $Id: G4QElastic.hh,v 1.3 2007/05/23 15:14:25 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QElastic header ----------------
// by Mikhail Kossov, December 2003.
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QElasticCrossSection -- header file
@@ -51,6 +51,7 @@
#include "G4QElastic.hh"
#include "G4QCoherentChargeExchange.hh"
#include "G4QuasiFreeRatios.hh"
#include "G4QIonIonCrossSection.hh"
class G4QElasticCrossSection : public G4VQCrossSection
{
@@ -64,7 +65,7 @@ public:
static G4VQCrossSection* GetPointer(); // Gives a pointer to this singletone
// At present momentum (pMom) must be in GeV (@@ Units)
// Cross-section is mb. At present momentum (pMom) is in MeV=IU (@@ make Indep. Units)
virtual G4double GetCrossSection(G4bool fCS, G4double pMom, G4int tgZ, G4int tgN,
G4int pPDG=0);
@@ -74,6 +75,8 @@ protected:
friend class G4QElastic;
friend class G4QCoherentChargeExchange;
friend class G4QuasiFreeRatios;
friend class G4QIonIonCrossSection;
G4double GetSlope(G4int tZ, G4int tN, G4int pPDG); // Slope of the 1st diff. maximum
G4double GetExchangeT(G4int tZ, G4int tN, G4int pPDG); // Randomizes -t=Q2 (in IU=MeV^2)
G4double GetHMaxT(); // Currrent Max(-t=Q2)/2. (in IU=MeV^2)
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QElectronNuclearCrossSection -- header file
@@ -24,7 +24,7 @@
// ********************************************************************
//
// $Id: G4QGluonString.hh,v 1.1 2006/10/30 10:33:38 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QGluonString header ----------------
// by Mikhail Kossov, October 2006.
@@ -0,0 +1,104 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QIonIonCrossSection -- header file
// Created: M.V. Kossov, CERN/ITEP(Moscow), 19-Aug-07
// The last update: M.V. Kossov, CERN/ITEP (Moscow) 19-Aug-07
//-----------------------------------------------------------------------------------------
// In this class, just as an experiment the real PDG codes (not CHIPS) are used
//-----------------------------------------------------------------------------------------
//
// ****************************************************************************************
// ********* This HEADER is temporary moved from the chips/interface directory *********
// ******* DO NOT MAKE ANY CHANGE! With time it'll move back to photolepton...(M.K.) ******
// ****************************************************************************************
#ifndef G4QIonIonCrossSection_h
#define G4QIonIonCrossSection_h 1
#include "G4ParticleTable.hh"
#include "G4NucleiProperties.hh"
#include "G4NucleiPropertiesTable.hh"
#include <vector>
#include "G4VQCrossSection.hh"
#include "G4QPDGCode.hh"
#include "G4QElasticCrossSection.hh"
#include "G4QProtonNuclearCrossSection.hh"
#include "G4QNeutronNuclearCrossSection.hh"
class G4QIonIonCrossSection : public G4VQCrossSection
{
protected:
G4QIonIonCrossSection() {}
public:
~G4QIonIonCrossSection() {}
static G4VQCrossSection* GetPointer(); // Gives a pointer to this singletone
// At present momentum (pMom) must be in GeV(@@ Units),fCS=true:Inelastic, =false:Elastic
virtual G4double GetCrossSection(G4bool fCS, G4double pMom, G4int Z, G4int N, G4int PDG);
// Momentum=p/A (MeV/c)
G4double CalculateCrossSection(G4bool fCS, G4int F, G4int I, G4int PDG,
G4int tZ, G4int tN, G4double Momentum);
G4double ThresholdMomentum(G4int pZ, G4int pN, G4int tZ, G4int tN);// P-Threshold(MeV/c)
private:
G4int GetFunctions(G4int pZ, G4int pN, G4int tZ, G4int tN,
G4double* LI, G4double* HI, // Inelastic
G4double* LE, G4double* HE); // Elastic
G4double CalculateTotal(G4double pA, G4double tA, G4double Momentum);
G4double CalculateElTot(G4double pA, G4double tA, G4double Momentum);
// Momentum=p/A (MeV/c), first=InelasticCS, second=elasticCS (mb)
std::pair<G4double,G4double> CalculateXS(G4int pZ,G4int pN,G4int tZ,G4int tN,G4double P);
// Body
private:
static G4double* lastLENI;// Pointer to the last array of LowEnergy Inel cross sections
static G4double* lastHENI;// Pointer to the last array of HighEnergy Inel cross sections
static G4double* lastLENE;// Pointer to the last array of LowEnergy Elast cross sections
static G4double* lastHENE;// Pointer to the last array of HighEnergy Elast cross sections
static G4double lastE; // Last used in the cross section Energy
static G4int lastPDG; // The last projectile PDG
static G4int lastN; // The last N of calculated nucleus
static G4int lastZ; // The last Z of calculated nucleus
static G4double lastP; // Last used in the cross section Momentum
static G4double lastTH; // Last value of the Momentum Threshold
static G4double lastICS; // Last value of the Inelastic Cross Section
static G4double lastECS; // Last value of the Elastic Cross Section
static G4int lastI; // The last position in the DAMDB
};
#endif
@@ -0,0 +1,131 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4QLowEnergy.hh,v 1.3 2007/11/15 09:36:43 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QLowEnergy header ----------------
// by Mikhail Kossov, Aug 2007.
// Header of G4QLowEnergy class (A+A) of the CHIPS Simulation Branch in GEANT4
// -------------------------------------------------------------------------------
// This is a unique CHIPS class for the Ion-Ion Low Energy Inelastic Interaction Prosesses
// -------------------------------------------------------------------------------
// At present (Aug-07) it is not tested.
// The normalization is based on the temporary G4QIonIonCrossSection class
// -------------------------------------------------------------------------------
#ifndef G4QLowEnergy_hh
#define G4QLowEnergy_hh
// GEANT4 Headers
#include "globals.hh"
#include "G4ios.hh"
#include "Randomize.hh"
#include "G4VDiscreteProcess.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ParticleTypes.hh"
#include "G4ParticleTable.hh"
#include "G4VParticleChange.hh"
#include "G4ParticleDefinition.hh"
#include "G4DynamicParticle.hh"
#include "G4NucleiPropertiesTable.hh"
#include "G4ThreeVector.hh"
#include "G4LorentzVector.hh"
// CHIPS Headers
#include "G4QNucleus.hh"
#include "G4QIonIonCrossSection.hh"
#include "G4QIsotope.hh"
#include "G4QPDGToG4Particle.hh"
#include "G4QCHIPSWorld.hh"
#include "G4QHadronVector.hh"
#include <vector>
class G4QLowEnergy : public G4VDiscreteProcess
{
public:
// Constructor
G4QLowEnergy(const G4String& processName ="CHIPS_LowEnergyIonIonInelastic");
// Destructor
~G4QLowEnergy();
G4bool IsApplicable(const G4ParticleDefinition& particle);
G4double GetMeanFreePath(const G4Track& aTrack, G4double previousStepSize,
G4ForceCondition* condition);
// It returns the MeanFreePath of the process for the current track :
// (energy, material)
// The previousStepSize and G4ForceCondition* are not used.
// This function overloads a virtual function of the base class.
// It is invoked by the ProcessManager of the Particle.
G4VParticleChange* PostStepDoIt(const G4Track& aTrack, const G4Step& aStep);
// It computes the final state of the process (at end of step),
// returned as a ParticleChange object.
// This function overloads a virtual function of the base class.
// It is invoked by the ProcessManager of the Particle.
G4LorentzVector GetEnegryMomentumConservation();
G4int GetNumberOfNeutronsInTarget();
void SwitchOnEvaporation() {evaporate=true;} // Evaporation instead of gammas (default)
void SwitchOffEvaporation() {evaporate=false;} // Gammas instead of evaporation
private:
// Hide assignment operator as private
G4QLowEnergy& operator=(const G4QLowEnergy &right);
// Copy constructor
G4QLowEnergy(const G4QLowEnergy&);
// Calculate Cross-Section of the Diffraction Reaction (p is in GeV @@ units)
G4double CalculateXS(G4double p, G4int Z, G4int N, G4int pPDG);
// BODY
// Static Parameters --------------------------------------------------------------------
static G4int nPartCWorld; // The#of particles for hadronization (limit of A of fragm.)
//--------------------------------- End of static parameters ---------------------------
// Working parameters
G4bool evaporate;
G4VQCrossSection* theCS;
G4LorentzVector EnMomConservation; // Residual of Energy/Momentum Cons.
G4int nOfNeutrons; // #of neutrons in the target nucleus
// Modifires for the reaction
G4double Time; // Time shift of the capture reaction
G4double EnergyDeposition; // Energy deposited in the reaction
static std::vector <G4int> ElementZ; // Z of the element(i) in theLastCalc
static std::vector <G4double> ElProbInMat; // SumProbabilityElements in Material
static std::vector <std::vector<G4int>*> ElIsoN; // N of isotope(j) of Element(i)
static std::vector <std::vector<G4double>*> IsoProbInEl;// SumProbabIsotopes in Element i
};
#endif
@@ -25,7 +25,7 @@
//
//
// $Id: G4QMuonNuclearCrossSection.hh,v 1.5 2006/12/01 10:57:46 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QMuonNuclearCrossSection -- header file
@@ -0,0 +1,89 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QNeutronNuclearCrossSection -- header file
// Created: M.V. Kossov, CERN/ITEP(Moscow), 20-Dec-01
// The last update: M.V. Kossov, CERN/ITEP (Moscow) 17-May-02
//
// ****************************************************************************************
// ********* This HEADER is temporary moved from the photolepton_hadron directory *********
// ******* DO NOT MAKE ANY CHANGE! With time it'll move back to photolepton...(M.K.) ******
// ****************************************************************************************
#ifndef G4QNeutronNuclearCrossSection_h
#define G4QNeutronNuclearCrossSection_h 1
#include "G4ParticleTable.hh"
#include "G4NucleiProperties.hh"
#include "G4NucleiPropertiesTable.hh"
#include <vector>
#include "G4VQCrossSection.hh"
#include "G4QPDGCode.hh"
class G4QNeutronNuclearCrossSection : public G4VQCrossSection
{
protected:
G4QNeutronNuclearCrossSection() {}
public:
~G4QNeutronNuclearCrossSection() {}
static G4VQCrossSection* GetPointer(); // Gives a pointer to this singletone
// At present momentum (pMom) in MeV/c, CS is in mb (@@ Units)
virtual G4double GetCrossSection(G4bool fCS, G4double pMom, G4int tgZ, G4int tgN,
G4int pPDG=2112);
G4double CalculateCrossSection(G4bool CS, G4int F, G4int I, G4int PDG, G4int Z,
G4int N, G4double Momentum);
private:
G4int GetFunctions(G4int tZ, G4int tN, G4double* y, G4double* z); // y&z=ArrayPointers
G4double CrossSectionLin(G4int targZ, G4int targN, G4double P);
G4double CrossSectionLog(G4int targZ, G4int targN, G4double lP);
G4double CrossSectionFormula(G4int targZ, G4int targN, G4double P, G4double lP);
G4double ThresholdMomentum(G4int targZ, G4int targN); // Threshold of pA reaction (MeV/c)
// Body
private:
static G4double lastSig; // Last value of the Cross Section
static G4double* lastLEN; // Pointer to the last array of LowEnergy cross sections
static G4double* lastHEN; // Pointer to the last array of HighEnergy cross sections
static G4double lastE; // Last used in the cross section Energy
static G4int lastPDG; // The last projectile PDG
static G4int lastN; // The last N of calculated nucleus
static G4int lastZ; // The last Z of calculated nucleus
static G4double lastP; // Last used in the cross section Momentum
static G4double lastTH; // Last value of the Momentum Threshold
static G4double lastCS; // Last value of the Cross Section
static G4int lastI; // The last position in the DAMDB
};
#endif
@@ -0,0 +1,110 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id: G4QNuENuclearCrossSection.hh,v 1.1 2007/10/02 10:00:37 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QNuENuclearCrossSection -- header file
// M.V. Kossov, CERN-ITEP(Moscow), 20-SEP-2007
// The last update: M.V. Kossov, CERN/ITEP (Moscow) 20-SEP-2007
//
// Short description: this G4 singletone class calculates (nu_e,e) Nuclear cross section
// (Energy limit: E<320GeV->badExtrapolation) for a particular isotope (proportional to A)
// ****************************************************************************************
#ifndef G4QNuENuclearCrossSection_h
#define G4QNuENuclearCrossSection_h 1
#include "G4ParticleTable.hh"
#include "G4NucleiProperties.hh"
#include "G4NucleiPropertiesTable.hh"
#include <vector>
#include "Randomize.hh"
#include "G4MuonPlus.hh"
#include "G4MuonMinus.hh"
#include "G4VQCrossSection.hh"
class G4QNuENuclearCrossSection : public G4VQCrossSection
{
protected:
G4QNuENuclearCrossSection() {};
public:
~G4QNuENuclearCrossSection() {};
static G4VQCrossSection* GetPointer(); // Gives a pointer to this singletone
G4double ThresholdEnergy(G4int Z, G4int N, G4int PDG=12);
// At present momentum (pMom) must be in GeV (@@ Units)
virtual G4double GetCrossSection(G4bool fCS, G4double pMom, G4int tgZ, G4int tgN,
G4int pPDG=0);
G4double CalculateCrossSection(G4bool CS, G4int F, G4int I, G4int PDG, G4int Z,
G4int N, G4double Momentum);
G4int GetExchangePDGCode();
G4double GetDirectPart(G4double Q2);
G4double GetNPartons(G4double Q2);
G4double GetQEL_ExchangeQ2();
G4double GetNQE_ExchangeQ2();
// Get static members
G4double GetLastTOTCS() {return lastSig;}
G4double GetLastQELCS() {return lastQEL;}
private:
G4int GetFunctions(G4int z, G4int n, G4double* t, G4double* q, G4double* e);
G4double HighEnergyTX(G4double lE);
G4double HighEnergyQE(G4double lE);
// Body
private:
static G4bool onlyCS; // flag to calculate only CS (not TX & QE)
static G4double lastSig; // Last calculated total cross section
static G4double lastQEL; // Last calculated quasi-elastic cross section
static G4int lastL; // Last bin used in the cross section TheLastBin
static G4double lastE; // Last energy used in the cross section Energy
static G4double* lastEN; // Pointer to the last array of the energy axis
static G4double* lastTX; // Pointer to the last array of the total CS function
static G4double* lastQE; // Pointer to the last array of the QE CS function
static G4int lastPDG; // The last projectile PDG
static G4int lastN; // The last N of calculated nucleus
static G4int lastZ; // The last Z of calculated nucleus
static G4double lastP; // Last used in the cross section Momentum
static G4double lastTH; // Last value of the Momentum Threshold
static G4double lastCS; // Last value of the Cross Section
static G4int lastI; // The last position in the DAMDB
};
#endif
@@ -25,7 +25,7 @@
//
//
// $Id: G4QNuMuNuclearCrossSection.hh,v 1.6 2006/12/01 10:57:46 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QNuMuNuclearCrossSection -- header file
@@ -0,0 +1,110 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id: G4QNuNuNuclearCrossSection.hh,v 1.1 2007/11/01 16:09:38 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QNuNuNuclearCrossSection -- header file
// M.V. Kossov, CERN-ITEP(Moscow), 20-DEC-2005
// The last update: M.V. Kossov, CERN/ITEP (Moscow) 20-DEC-2005
//
// Short description: this G4 singletone class calculates (nu_mu,mu) Nuclear cross section
// (Energy limit: E<320GeV->badExtrapolation) for a particular isotope (proportional to A)
// ****************************************************************************************
#ifndef G4QNuNuNuclearCrossSection_h
#define G4QNuNuNuclearCrossSection_h 1
#include "G4ParticleTable.hh"
#include "G4NucleiProperties.hh"
#include "G4NucleiPropertiesTable.hh"
#include <vector>
#include "Randomize.hh"
#include "G4MuonPlus.hh"
#include "G4MuonMinus.hh"
#include "G4VQCrossSection.hh"
class G4QNuNuNuclearCrossSection : public G4VQCrossSection
{
protected:
G4QNuNuNuclearCrossSection() {};
public:
~G4QNuNuNuclearCrossSection() {};
static G4VQCrossSection* GetPointer(); // Gives a pointer to this singletone
G4double ThresholdEnergy(G4int Z, G4int N, G4int PDG=14);
// At present momentum (pMom) must be in GeV (@@ Units)
virtual G4double GetCrossSection(G4bool fCS, G4double pMom, G4int tgZ, G4int tgN,
G4int pPDG=0);
G4double CalculateCrossSection(G4bool CS, G4int F, G4int I, G4int PDG, G4int Z,
G4int N, G4double Momentum);
G4int GetExchangePDGCode();
G4double GetDirectPart(G4double Q2);
G4double GetNPartons(G4double Q2);
G4double GetQEL_ExchangeQ2();
G4double GetNQE_ExchangeQ2();
// Get static members
G4double GetLastTOTCS() {return lastSig;}
G4double GetLastQELCS() {return lastQEL;}
private:
G4int GetFunctions(G4int z, G4int n, G4double* t, G4double* q, G4double* e);
G4double HighEnergyTX(G4double lE);
G4double HighEnergyQE(G4double lE);
// Body
private:
static G4bool onlyCS; // flag to calculate only CS (not TX & QE)
static G4double lastSig; // Last calculated total cross section
static G4double lastQEL; // Last calculated quasi-elastic cross section
static G4int lastL; // Last bin used in the cross section TheLastBin
static G4double lastE; // Last energy used in the cross section Energy
static G4double* lastEN; // Pointer to the last array of the energy axis
static G4double* lastTX; // Pointer to the last array of the total CS function
static G4double* lastQE; // Pointer to the last array of the QE CS function
static G4int lastPDG; // The last projectile PDG
static G4int lastN; // The last N of calculated nucleus
static G4int lastZ; // The last Z of calculated nucleus
static G4double lastP; // Last used in the cross section Momentum
static G4double lastTH; // Last value of the Momentum Threshold
static G4double lastCS; // Last value of the Cross Section
static G4int lastI; // The last position in the DAMDB
};
#endif
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QPhotonNuclearCrossSection -- header file
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QProtonNuclearCrossSection -- header file
@@ -44,6 +44,7 @@
#include "G4NucleiPropertiesTable.hh"
#include <vector>
#include "G4VQCrossSection.hh"
#include "G4QPDGCode.hh"
class G4QProtonNuclearCrossSection : public G4VQCrossSection
{
@@ -57,30 +58,32 @@ public:
static G4VQCrossSection* GetPointer(); // Gives a pointer to this singletone
// At present momentum (pMom) must be in GeV (@@ Units)
// At present momentum (pMom) in MeV/c, CS in mb (@@ Units)
virtual G4double GetCrossSection(G4bool fCS, G4double pMom, G4int tgZ, G4int tgN,
G4int pPDG=0);
G4int pPDG=2212);
G4double CalculateCrossSection(G4bool CS, G4int F, G4int I, G4int PDG, G4int Z,
G4int N, G4double Momentum);
private:
G4int GetFunctions(G4double A, G4double* y, G4double* z);// y&z are pointers to arrays
G4int GetFunctions(G4int tZ, G4int tN, G4double* y, G4double* z); // y&z=ArrayPointers
G4double CrossSectionLin(G4int targZ, G4int targN, G4double P);
G4double CrossSectionLog(G4int targZ, G4int targN, G4double lP);
G4double CrossSectionFormula(G4int targZ, G4int targN, G4double P, G4double lP);
G4double ThresholdMomentum(G4int targZ, G4int targN); // Threshold of pA reaction (MeV/c)
// Body
private:
static G4double lastSig; // Last value of the Cross Section
static G4double* lastLEN; // Pointer to the last array of LowEnergy cross sections
static G4double* lastHEN; // Pointer to the last array of HighEnergy cross sections
static G4double lastE; // Last used in the cross section Energy
static G4double lastSP; // Last value of the ShadowingPomeron (A-dependent)
static G4int lastPDG; // The last projectile PDG
static G4int lastN; // The last N of calculated nucleus
static G4int lastZ; // The last Z of calculated nucleus
static G4double lastP; // Last used in the cross section Momentum
static G4double lastTH; // Last value of the Momentum Threshold
static G4double lastCS; // Last value of the Cross Section
static G4int lastI; // The last position in the DAMDB
static G4int lastPDG; // The last projectile PDG
static G4int lastN; // The last N of calculated nucleus
static G4int lastZ; // The last Z of calculated nucleus
static G4double lastP; // Last used in the cross section Momentum
static G4double lastTH; // Last value of the Momentum Threshold
static G4double lastCS; // Last value of the Cross Section
static G4int lastI; // The last position in the DAMDB
};
#endif
@@ -25,7 +25,7 @@
//
//
// $Id: G4QTauNuclearCrossSection.hh,v 1.5 2006/12/01 10:57:46 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QTauNuclearCrossSection -- header file
@@ -24,7 +24,7 @@
// ********************************************************************
//
//
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 physics class: G4QuasiFreeRatios -- header file
@@ -80,6 +80,9 @@ class G4QuasiFreeRatios
// Mean hN El and Tot XS(IU) for the isotopic (Z,N): on p -> (Z=1,N=0), on n -> (Z=0,N=1)
std::pair<G4double,G4double> GetElTot(G4double pIU, G4int hPDG, G4int Z, G4int N); //(IU)
// Calculate ChEx/El ratio coefficient (p is in independent units, (Z,N) is a target)
G4double ChExElCoef(G4double p, G4int Z, G4int N, G4int pPDG);
private:
// These working member functions are in CHIPS units and must not be used externally
G4double GetQF2IN_Ratio(G4double TotCS_mb, G4int A); // QuasiFree/Inelastic (fast)
@@ -89,7 +92,6 @@ class G4QuasiFreeRatios
// Body
private:
static std::vector<G4double*> vE; // Vector of ElastPointers to LogTable
static std::vector<G4double*> vT; // Vector of pointers to LinTable
static std::vector<G4double*> vL; // Vector of pointers to LogTable
static std::vector<std::pair<G4double,G4double>*> vX; // Vector of ETPointers to LogTable
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4VQCrossSection.hh,v 1.8 2006/12/09 14:33:35 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4VQCrossSection.hh,v 1.9 2007/11/15 09:36:43 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// GEANT4 virtual class: G4VQCrossSection -- header file
@@ -119,6 +119,8 @@ public:
virtual G4double GetExchangeT(G4int tZ, G4int tN, G4int pPDG); // -t=Q2 for hadronic
virtual G4double GetSlope(G4int tZ, G4int tN, G4int pPDG); // B-slope of the maim maximum
virtual G4double GetHMaxT(); // max(-t=Q2)/2 for hadronic (MeV^2)
virtual G4double GetExchangeQ2(G4double nu=0); // Q2 for lepto-nuclear reactions
@@ -0,0 +1,730 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id: G4QANuANuNuclearCrossSection.cc,v 1.2 2007/11/02 15:57:16 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// G4 Physics class: G4QANuANuNuclearCrossSection for gamma+A cross sections
// Created: M.V. Kossov, CERN/ITEP(Moscow), 10-OCT-01
// The last update: M.V. Kossov, CERN/ITEP (Moscow) 17-Oct-03
//
// ****************************************************************************************
// ********** This CLASS is temporary moved from the photolepton_hadron directory *********
// ******* DO NOT MAKE ANY CHANGE! With time it'll move back to photolepton...(M.K.) ******
// ****************************************************************************************
//===============================================================================================
//#define debug
//#define edebug
//#define pdebug
//#define ppdebug
//#define tdebug
//#define sdebug
#include "G4QANuANuNuclearCrossSection.hh"
// Initialization of the
G4bool G4QANuANuNuclearCrossSection::onlyCS=true;//Flag to calculate only CS (not QE)
G4double G4QANuANuNuclearCrossSection::lastSig=0.;//Last calculated total cross section
G4double G4QANuANuNuclearCrossSection::lastQEL=0.;//Last calculated quasi-el cross section
G4int G4QANuANuNuclearCrossSection::lastL=0; //Last used in cross section TheLastBin
G4double G4QANuANuNuclearCrossSection::lastE=0.; //Last used in cross section TheEnergy
G4double* G4QANuANuNuclearCrossSection::lastEN=0; //Pointer to theEnergy Scale of TX & QE
G4double* G4QANuANuNuclearCrossSection::lastTX=0; //Pointer to theLastArray of TX function
G4double* G4QANuANuNuclearCrossSection::lastQE=0; //Pointer to theLastArray of QE function
G4int G4QANuANuNuclearCrossSection::lastPDG=0; // The last PDG code of the projectile
G4int G4QANuANuNuclearCrossSection::lastN=0; // The last N of calculated nucleus
G4int G4QANuANuNuclearCrossSection::lastZ=0; // The last Z of calculated nucleus
G4double G4QANuANuNuclearCrossSection::lastP=0.; // Last used in cross section Momentum
G4double G4QANuANuNuclearCrossSection::lastTH=0.; // Last threshold momentum
G4double G4QANuANuNuclearCrossSection::lastCS=0.; // Last value of the Cross Section
G4int G4QANuANuNuclearCrossSection::lastI=0; // The last position in the DAMDB
// Returns Pointer to the G4VQCrossSection class
G4VQCrossSection* G4QANuANuNuclearCrossSection::GetPointer()
{
static G4QANuANuNuclearCrossSection theCrossSection; //*Static body of the Cross Section*
return &theCrossSection;
}
// The main member function giving the collision cross section (P is in IU, CS is in mb)
// Make pMom in independent units ! (Now it is MeV)
G4double G4QANuANuNuclearCrossSection::GetCrossSection(G4bool fCS, G4double pMom,
G4int tgZ, G4int tgN, G4int pPDG)
{
static G4int j; // A#0f records found in DB for this projectile
static std::vector <G4int> colPDG;// Vector of the projectile PDG code
static std::vector <G4int> colN; // Vector of N for calculated nuclei (isotops)
static std::vector <G4int> colZ; // Vector of Z for calculated nuclei (isotops)
static std::vector <G4double> colP; // Vector of last momenta for the reaction
static std::vector <G4double> colTH; // Vector of energy thresholds for the reaction
static std::vector <G4double> colCS; // Vector of last cross sections for the reaction
// ***---*** End of the mandatory Static Definitions of the Associative Memory ***---***
G4double pEn=pMom;
#ifdef debug
G4cout<<"G4QAMNCS::GetCS:>> f="<<fCS<<", p="<<pMom<<", Z="<<tgZ<<"("<<lastZ<<") ,N="<<tgN
<<"("<<lastN<<"),PDG="<<pPDG<<"("<<lastPDG<<"), T="<<pEn<<"("<<lastTH<<")"<<",Sz="
<<colN.size()<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
if(pPDG!=-14)
{
#ifdef debug
G4cout<<"G4QAMNCS::GetCS: *** Found pPDG="<<pPDG<<" ====> CS=0"<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
return 0.; // projectile PDG=0 is a mistake (?!) @@
}
G4bool in=false; // By default the isotope must be found in the AMDB
if(tgN!=lastN || tgZ!=lastZ || pPDG!=lastPDG)// The nucleus was not the last used isotope
{
in = false; // By default the isotope haven't be found in AMDB
lastP = 0.; // New momentum history (nothing to compare with)
lastPDG = pPDG; // The last PDG of the projectile
lastN = tgN; // The last N of the calculated nucleus
lastZ = tgZ; // The last Z of the calculated nucleus
lastI = colN.size(); // Size of the Associative Memory DB in the heap
j = 0; // A#0f records found in DB for this projectile
if(lastI) for(G4int i=0; i<lastI; i++) if(colPDG[i]==pPDG) // The partType is found
{ // The nucleus with projPDG is found in AMDB
if(colN[i]==tgN && colZ[i]==tgZ)
{
lastI=i;
lastTH =colTH[i]; // Last THreshold (A-dependent)
#ifdef pdebug
G4cout<<"G4QAMNCS::GetCS:*Found*P="<<pMom<<",Threshold="<<lastTH<<",j="<<j<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
if(pEn<=lastTH)
{
#ifdef pdebug
G4cout<<"G4QAMNCS::GetCS:Found T="<<pEn<<" < Threshold="<<lastTH<<",X=0"<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
return 0.; // Energy is below the Threshold value
}
lastP =colP [i]; // Last Momentum (A-dependent)
lastCS =colCS[i]; // Last CrossSect (A-dependent)
if(std::fabs(lastP/pMom-1.)<tolerance)
{
#ifdef pdebug
G4cout<<"G4QAMNCS::GetCS:P="<<pMom<<",CS="<<lastCS*millibarn<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
return lastCS*millibarn; // Use theLastCS
}
in = true; // This is the case when the isotop is found in DB
// Momentum pMom is in IU ! @@ Units
#ifdef pdebug
G4cout<<"G4QAMNCS::G:UpdaDB P="<<pMom<<",f="<<fCS<<",lI="<<lastI<<",j="<<j<<G4endl;
#endif
lastCS=CalculateCrossSection(fCS,-1,j,lastPDG,lastZ,lastN,pMom); // read & update
#ifdef pdebug
G4cout<<"G4QAMNCS::GetCrosSec: *****> New (inDB) Calculated CS="<<lastCS<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
if(lastCS<=0. && pEn>lastTH) // Correct the threshold
{
#ifdef pdebug
G4cout<<"G4QAMNCS::GetCS: New T="<<pEn<<"(CS=0) > Threshold="<<lastTH<<G4endl;
#endif
lastTH=pEn;
}
break; // Go out of the LOOP
}
#ifdef pdebug
G4cout<<"---G4QAMNCrossSec::GetCrosSec:pPDG="<<pPDG<<",j="<<j<<",N="<<colN[i]
<<",Z["<<i<<"]="<<colZ[i]<<",cPDG="<<colPDG[i]<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
j++; // Increment a#0f records found in DB for this pPDG
}
if(!in) // This nucleus has not been calculated previously
{
#ifdef pdebug
G4cout<<"G4QAMNCS::GetCrosSec:CalcNew P="<<pMom<<",f="<<fCS<<",lstI="<<lastI<<G4endl;
#endif
//!!The slave functions must provide cross-sections in millibarns (mb) !! (not in IU)
lastCS=CalculateCrossSection(fCS,0,j,lastPDG,lastZ,lastN,pMom); //calculate & create
if(lastCS<=0.)
{
lastTH = ThresholdEnergy(tgZ, tgN); // The Threshold Energy which is now the last
#ifdef pdebug
G4cout<<"G4QAMNCrossSection::GetCrossSect: NewThresh="<<lastTH<<",T="<<pEn<<G4endl;
#endif
if(pEn>lastTH)
{
#ifdef pdebug
G4cout<<"G4QAMNCS::GetCS: First T="<<pEn<<"(CS=0) > Threshold="<<lastTH<<G4endl;
#endif
lastTH=pEn;
}
}
#ifdef pdebug
G4cout<<"G4QAMNCS::GetCrosSec:New CS="<<lastCS<<",lZ="<<lastN<<",lN="<<lastZ<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
colN.push_back(tgN);
colZ.push_back(tgZ);
colPDG.push_back(pPDG);
colP.push_back(pMom);
colTH.push_back(lastTH);
colCS.push_back(lastCS);
#ifdef pdebug
G4cout<<"G4QAMNCS::GetCS:1st,P="<<pMom<<"(MeV),X="<<lastCS*millibarn<<"(mb)"<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
return lastCS*millibarn;
} // End of creation of the new set of parameters
else
{
#ifdef pdebug
G4cout<<"G4QAMNCS::GetCS: Update lastI="<<lastI<<",j="<<j<<G4endl;
#endif
colP[lastI]=pMom;
colPDG[lastI]=pPDG;
colCS[lastI]=lastCS;
}
} // End of parameters udate
else if(pEn<=lastTH)
{
#ifdef pdebug
G4cout<<"G4QAMNCS::GetCS: Current T="<<pEn<<" < Threshold="<<lastTH<<", CS=0"<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
return 0.; // Momentum is below the Threshold Value -> CS=0
}
else if(std::fabs(lastP/pMom-1.)<tolerance)
{
#ifdef pdebug
G4cout<<"G4QAMNCS::GetCS:OldCur P="<<pMom<<"="<<pMom<<",CS="<<lastCS*millibarn<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
return lastCS*millibarn; // Use theLastCS
}
else
{
#ifdef pdebug
G4cout<<"G4QAMNCS::GetCS:UpdaCur P="<<pMom<<",f="<<fCS<<",I="<<lastI<<",j="<<j<<G4endl;
#endif
lastCS=CalculateCrossSection(fCS,1,j,lastPDG,lastZ,lastN,pMom); // Only UpdateDB
lastP=pMom;
}
#ifdef pdebug
G4cout<<"G4QAMNCS::GetCrSec:End,P="<<pMom<<"(MeV),CS="<<lastCS*millibarn<<"(mb)"<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
return lastCS*millibarn;
}
// Gives the threshold energy = the same for all nuclei (@@ can be reduced for hevy nuclei)
G4double G4QANuANuNuclearCrossSection::ThresholdEnergy(G4int, G4int, G4int) {return 0.;}
// The main member function giving the gamma-A cross section (E_kin in MeV, CS in mb)
G4double G4QANuANuNuclearCrossSection::CalculateCrossSection(G4bool CS, G4int F, G4int I,
G4int , G4int targZ, G4int targN, G4double Momentum)
{
static const G4double mb38=1.E-11;// Conversion 10^-38 cm^2 to mb=10^-27 cm^2
static const G4int nE=65; // !! If change this, change it in GetFunctions() (*.hh) !!
static const G4int mL=nE-1;
static const G4double EMi=0.; // Universal threshold of the reaction in GeV
static const G4double EMa=300.; // Maximum tabulated Energy of nu_mu in GeV
// *** Begin of the Associative memory for acceleration of the cross section calculations
static std::vector <G4double> colH; //?? Vector of HighEnergyCoefficients (functional)
static std::vector <G4double*> TX; // Vector of pointers to the TX tabulated functions
static std::vector <G4double*> QE; // Vector of pointers to the QE tabulated functions
static G4bool first=true; // Flag of initialization of the energy axis
// *** End of Static Definitions (Associative Memory) ***
//const G4double Energy = aPart->GetKineticEnergy()/MeV; // Energy of the Muon
//G4double TotEnergy2=Momentum;
onlyCS=CS; // Flag to calculate only CS (not TX & QE)
lastE=Momentum/GeV; // Kinetic energy of the muon neutrino (in GeV!)
if (lastE<=EMi) // Energy is below the minimum energy in the table
{
lastE=0.;
lastSig=0.;
return 0.;
}
G4int Z=targZ; // New Z, which can change the sign
if(F<=0) // This isotope was not the last used isotop
{
if(F<0) // This isotope was found in DAMDB =========> RETRIEVE
{
lastTX =TX[I]; // Pointer to the prepared TX function (same isotope)
lastQE =QE[I]; // Pointer to the prepared QE function (same isotope)
}
else // This isotope wasn't calculated previously => CREATE
{
if(first)
{
lastEN = new G4double[nE]; // This must be done only once!
Z=-Z; // To explain GetFunctions that E-axis must be filled
first=false; // To make it only once
}
lastTX = new G4double[nE]; // Allocate memory for the new TX function
lastQE = new G4double[nE]; // Allocate memory for the new QE function
G4int res=GetFunctions(Z,targN,lastTX,lastQE,lastEN);//@@analize(0=first,-1=bad,1=OK)
if(res<0) G4cerr<<"*W*G4NuMuNuclearCS::CalcCrossSect:Bad Function Retrieve"<<G4endl;
// *** The synchronization check ***
G4int sync=TX.size();
if(sync!=I) G4cerr<<"***G4NuMuNuclearCS::CalcCrossSect:Sync.="<<sync<<"#"<<I<<G4endl;
TX.push_back(lastTX);
QE.push_back(lastQE);
} // End of creation of the new set of parameters
} // End of parameters udate
// ============================== NOW Calculate the Cross Section =====================
if (lastE<=EMi) // Check that antiNuEnergy is higher than ThreshE
{
lastE=0.;
lastSig=0.;
return 0.;
}
if(lastE<EMa) // Linear fit is made explicitly to fix the last bin for the randomization
{
G4int chk=1;
G4int ran=mL/2;
G4int sep=ran; // as a result = an index of the left edge of the interval
while(ran>=2)
{
G4int newran=ran/2;
if(lastE<=lastEN[sep]) sep-=newran;
else sep+=newran;
ran=newran;
chk=chk+chk;
}
if(chk+chk!=mL) G4cerr<<"*Warn*G4NuMuNuclearCS::CalcCS:Table! mL="<<mL<<G4endl;
G4double lowE=lastEN[sep];
G4double highE=lastEN[sep+1];
G4double lowTX=lastTX[sep];
if(lastE<lowE||sep>=mL||lastE>highE)
G4cerr<<"*Warn*G4NuMuNuclearCS::CalcCS:Bin! "<<lowE<<" < "<<lastE<<" < "<<highE
<<", sep="<<sep<<", mL="<<mL<<G4endl;
lastSig=lastE*(lastE-lowE)*(lastTX[sep+1]-lowTX)/(highE-lowE)+lowTX; // Recover *E
if(!onlyCS) // Skip the differential cross-section parameters
{
G4double lowQE=lastQE[sep];
lastQEL=(lastE-lowE)*(lastQE[sep+1]-lowQE)/(highE-lowE)+lowQE;
#ifdef pdebug
G4cout<<"G4NuMuNuclearCS::CalcCS: T="<<lastSig<<",Q="<<lastQEL<<",E="<<lastE<<G4endl;
#endif
}
}
else
{
lastSig=lastTX[mL]; // @@ No extrapolation, just a const, while it looks shrinking...
lastQEL=lastQE[mL];
}
if(lastQEL<0.) lastQEL = 0.;
if(lastSig<0.) lastSig = 0.;
// The cross-sections are expected to be in mb
lastSig*=mb38;
if(!onlyCS) lastQEL*=mb38;
return lastSig;
}
// Calculate the cros-section functions
// ****************************************************************************************
// *** This tables are the same for all lepto-nuclear reactions, only mass is different ***
// ***@@ IT'S REASONABLE TO MAKE ADDiTIONAL VIRTUAL CLASS FOR LEPTO-NUCLEAR WITH THIS@@ ***
// ****************************************************************************************
G4int G4QANuANuNuclearCrossSection::GetFunctions (G4int z, G4int n,
G4double* t, G4double* q, G4double* e)
{
static const G4int nE=65; // !! If change this, change it in GetCrossSection() (*.cc) !!
static const G4double nuEn[nE]={0.,
1.00463e-5,1.05336e-5,1.10692e-5,1.16592e-5,1.23109e-5,1.30323e-5,1.38331e-5,1.47245e-5,
1.57194e-5,1.68335e-5,1.80848e-5,1.94948e-5,2.10894e-5,2.28991e-5,2.49608e-5,2.73189e-5,
3.00273e-5,3.31516e-5,3.67722e-5,4.09881e-5,4.59217e-5,5.17255e-5,5.85908e-5,6.67583e-5,
7.65338e-5,8.83078e-5,.000102583,.000120011,.000141441,.000167995,.000201160,.000242926,
.000295985,.000364008,.000452051,.000567152,.000719210,.000922307,.001196710,.001571930,
.002091530,.002820590,.003857810,.005354930,.007548840,.010815300,.015760100,.023376900,
.035325600,.054430800,.085595700,.137508000,.225898000,.379892000,.654712000,1.15767000,
2.10277000,3.92843000,7.55861000,14.9991000,30.7412000,65.1734000,143.155000,326.326000};
static const G4double TOTX[nE]={0.,
3.63538e-5,3.81165e-5,4.00539e-5,4.21884e-5,4.45454e-5,4.71548e-5,5.00511e-5,5.32747e-5,
5.68730e-5,6.09016e-5,6.54261e-5,7.05246e-5,7.62894e-5,8.28315e-5,9.02838e-5,9.88066e-5,
.000108594,.000119884,.000132964,.000148191,.000166007,.000186959,.000211736,.000241202,
.000276453,.000318890,.000370311,.000433042,.000510116,.000605516,.000724514,.000874144,
.001063870,.001306520,.001619660,.002027520,.002563780,.003275710,.004230080,.005521890,
.007286920,.009719890,.013099700,.018695100,.029208400,.042095000,.059253700,.082373900,
.113071000,.151041000,.191803000,.224208000,.234187000,.217774000,.187139000,.157818000,
.137494000,.125872000,.120462000,.119148000,.120418000,.123027000,.126408000,.129071000};
static const G4double QELX[nE]={0.,
.365220e-9,.401502e-9,.443364e-9,.491885e-9,.548393e-9,.614536e-9,.692362e-9,.784441e-9,
.894012e-9,1.02519e-9,1.18322e-9,1.37487e-9,1.60890e-9,1.89677e-9,2.25355e-9,2.69928e-9,
3.26079e-9,3.97433e-9,4.88937e-9,6.07407e-9,7.62331e-9,9.67058e-9,1.24058e-8,1.61022e-8,
2.11580e-8,2.81605e-8,3.79876e-8,5.19696e-8,7.21515e-8,1.01724e-7,1.45743e-7,2.12353e-7,
3.14890e-7,4.75585e-7,7.32171e-7,1.14991e-6,1.84390e-6,3.02121e-6,5.06217e-6,8.68002e-6,
1.52408e-5,2.74159e-5,5.05363e-5,.000100111,.000220489,.000455269,.000933841,.001925650,
.003994300,.008221270,.016417600,.030830400,.052902400,.082519200,.115560000,.149598000,
.184112000,.215102000,.238253000,.252949000,.261267000,.265626000,.267782000,.268791000};
// --------------------------------
G4int first=0;
if(z<0.)
{
first=1;
z=-z;
}
if(z<1 || z>92) // neutron & plutonium are forbidden
{
G4cout<<"*G4QANuANuNuclearCrossSection::GetFunctions:Z="<<z<<".No CS returned"<<G4endl;
return -1;
}
for(G4int k=0; k<nE; k++)
{
G4double a=n+z;
G4double za=z+a;
G4double dz=z+z;
G4double da=a+a;
G4double ta=da+a;
if(first) e[k]=nuEn[k]; // Energy of neutrino E (first bin k=0 can be modified)
t[k]=TOTX[k]*nuEn[k]*(za+za)/ta+QELX[k]*(dz+dz-da)/ta; // TotalCrossSection
q[k]=QELX[k]*dz/a; // QuasiElasticCrossSection
}
return first;
}
// Randomize Q2 from neutrino to the scattered muon when the scattering is quasi-elastic
G4double G4QANuANuNuclearCrossSection::GetQEL_ExchangeQ2()
{
static const double MN=.931494043; // Nucleon mass (inside nucleus, atomicMassUnit,GeV)
static const G4double power=-3.5; // direct power for the magic variable
static const G4double pconv=1./power;// conversion power for the magic variable
static const G4int nQ2=101; // #Of point in the Q2l table (in GeV^2)
static const G4int lQ2=nQ2-1; // index of the last in the Q2l table
static const G4int bQ2=lQ2-1; // index of the before last in the Q2 ltable
// Reversed table
static const G4double Xl[nQ2]={5.20224e-16,
.006125,.0137008,.0218166,.0302652,.0389497,.0478144,.0568228,.0659497,.0751768,.0844898,
.093878, .103332, .112844, .122410, .132023, .141680, .151376, .161109, .170875, .180672,
.190499, .200352, .210230, .220131, .230055, .239999, .249963, .259945, .269944, .279960,
.289992, .300039, .310099, .320173, .330260, .340359, .350470, .360592, .370724, .380867,
.391019, .401181, .411352, .421531, .431719, .441915, .452118, .462329, .472547, .482771,
.493003, .503240, .513484, .523734, .533989, .544250, .554517, .564788, .575065, .585346,
.595632, .605923, .616218, .626517, .636820, .647127, .657438, .667753, .678072, .688394,
.698719, .709048, .719380, .729715, .740053, .750394, .760738, .771085, .781434, .791786,
.802140, .812497, .822857, .833219, .843582, .853949, .864317, .874687, .885060, .895434,
.905810, .916188, .926568, .936950, .947333, .957719, .968105, .978493, .988883, .999275};
// Direct table
static const G4double Xmax=Xl[lQ2];
static const G4double Xmin=Xl[0];
static const G4double dX=(Xmax-Xmin)/lQ2; // step in X(Q2, GeV^2)
static const G4double inl[nQ2]={0,
1.52225, 2.77846, 3.96651, 5.11612, 6.23990, 7.34467, 8.43466, 9.51272, 10.5809, 11.6406,
12.6932, 13.7394, 14.7801, 15.8158, 16.8471, 17.8743, 18.8979, 19.9181, 20.9353, 21.9496,
22.9614, 23.9707, 24.9777, 25.9826, 26.9855, 27.9866, 28.9860, 29.9837, 30.9798, 31.9745,
32.9678, 33.9598, 34.9505, 35.9400, 36.9284, 37.9158, 38.9021, 39.8874, 40.8718, 41.8553,
42.8379, 43.8197, 44.8007, 45.7810, 46.7605, 47.7393, 48.7174, 49.6950, 50.6718, 51.6481,
52.6238, 53.5990, 54.5736, 55.5476, 56.5212, 57.4943, 58.4670, 59.4391, 60.4109, 61.3822,
62.3531, 63.3236, 64.2937, 65.2635, 66.2329, 67.2019, 68.1707, 69.1390, 70.1071, 71.0748,
72.0423, 73.0095, 73.9763, 74.9429, 75.9093, 76.8754, 77.8412, 78.8068, 79.7721, 80.7373,
81.7022, 82.6668, 83.6313, 84.5956, 85.5596, 86.5235, 87.4872, 88.4507, 89.4140, 90.3771,
91.3401, 92.3029, 93.2656, 94.2281, 95.1904, 96.1526, 97.1147, 98.0766, 99.0384, 100.000};
G4double Enu=lastE; // Get energy of the last calculated cross-section
G4double dEnu=Enu+Enu; // doubled energy of nu/anu
G4double Enu2=Enu*Enu; // squared energy of nu/anu
G4double ME=Enu*MN; // M*E
G4double dME=ME+ME; // 2*M*E
G4double dEMN=(dEnu+MN)*ME;
G4double sqE=Enu*ME;
G4double E2M=MN*Enu2;
G4double ymax=(E2M+sqE)/dEMN;
G4double Q2mi=0.; // Q2_min(E_nu)
G4double Q2ma=dME*ymax; // Q2_max(E_nu)
G4double Xma=std::pow((1.+Q2mi),power); // X_max(E_nu)
G4double Xmi=std::pow((1.+Q2ma),power); // X_min(E_nu)
// Find the integral values integ(Xmi) & integ(Xma) using the direct table
G4double rXi=(Xmi-Xmin)/dX;
G4int iXi=static_cast<int>(rXi);
if(iXi<0) iXi=0;
if(iXi>bQ2) iXi=bQ2;
G4double dXi=rXi-iXi;
G4double bnti=inl[iXi];
G4double inti=bnti+dXi*(inl[iXi+1]-bnti);
//
G4double rXa=(Xma-Xmin)/dX;
G4int iXa=static_cast<int>(rXa);
if(iXa<0) iXa=0;
if(iXa>bQ2) iXa=bQ2;
G4double dXa=rXa-iXa;
G4double bnta=inl[iXa];
G4double inta=bnta+dXa*(inl[iXa+1]-bnta);
// *** Find X using the reversed table ***
G4double intx=inti+(inta-inti)*G4UniformRand();
G4int intc=static_cast<int>(intx);
if(intc<0) intc=0;
if(intc>bQ2) intc=bQ2; // If it is more than max, then the BAD extrapolation
G4double dint=intx-intc;
G4double mX=Xl[intc];
G4double X=mX+dint*(Xl[intc+1]-mX);
G4double Q2=std::pow(X,pconv)-1.;
return Q2*GeV*GeV;
}
// Randomize Q2 from neutrino to the scattered muon when the scattering is not quasiElastic
G4double G4QANuANuNuclearCrossSection::GetNQE_ExchangeQ2()
{
static const double mpi=.13957018; // charged pi meson mass in GeV
static const double MN=.931494043; // Nucleon mass (inside nucleus,atomicMassUnit,GeV)
static const double dMN=MN+MN; // 2*M_N in GeV
static const double mcV=(dMN+mpi)*mpi;// constant of W>M+mc cut for Quasi-Elastic
static const G4int power=7; // direct power for the magic variable
static const G4double pconv=1./power; // conversion power for the magic variable
static const G4int nX=21; // #Of point in the Xl table (in GeV^2)
static const G4int lX=nX-1; // index of the last in the Xl table
static const G4int bX=lX-1; // @@ index of the before last in the Xl table
static const G4int nE=20; // #Of point in the El table (in GeV^2)
static const G4int bE=nE-1; // index of the last in the El table
static const G4int pE=bE-1; // index of the before last in the El table
// Reversed table
static const G4double X0[nX]={5.21412e-05,
.437860, .681908, .891529, 1.08434, 1.26751, 1.44494, 1.61915, 1.79198, 1.96493, 2.13937,
2.31664, 2.49816, 2.68559, 2.88097, 3.08705, 3.30774, 3.54917, 3.82233, 4.15131, 4.62182};
static const G4double X1[nX]={.00102591,
1.00443, 1.55828, 2.03126, 2.46406, 2.87311, 3.26723, 3.65199, 4.03134, 4.40835, 4.78561,
5.16549, 5.55031, 5.94252, 6.34484, 6.76049, 7.19349, 7.64917, 8.13502, 8.66246, 9.25086};
static const G4double X2[nX]={.0120304,
2.59903, 3.98637, 5.15131, 6.20159, 7.18024, 8.10986, 9.00426, 9.87265, 10.7217, 11.5564,
12.3808, 13.1983, 14.0116, 14.8234, 15.6359, 16.4515, 17.2723, 18.1006, 18.9386, 19.7892};
static const G4double X3[nX]={.060124,
5.73857, 8.62595, 10.9849, 13.0644, 14.9636, 16.7340, 18.4066, 20.0019, 21.5342, 23.0142,
24.4497, 25.8471, 27.2114, 28.5467, 29.8564, 31.1434, 32.4102, 33.6589, 34.8912, 36.1095};
static const G4double X4[nX]={.0992363,
8.23746, 12.1036, 15.1740, 17.8231, 20.1992, 22.3792, 24.4092, 26.3198, 28.1320, 29.8615,
31.5200, 33.1169, 34.6594, 36.1536, 37.6044, 39.0160, 40.3920, 41.7353, 43.0485, 44.3354};
static const G4double X5[nX]={.0561127,
7.33661, 10.5694, 13.0778, 15.2061, 17.0893, 18.7973, 20.3717, 21.8400, 23.2211, 24.5291,
25.7745, 26.9655, 28.1087, 29.2094, 30.2721, 31.3003, 32.2972, 33.2656, 34.2076, 35.1265};
static const G4double X6[nX]={.0145859,
4.81774, 6.83565, 8.37399, 9.66291, 10.7920, 11.8075, 12.7366, 13.5975, 14.4025, 15.1608,
15.8791, 16.5628, 17.2162, 17.8427, 18.4451, 19.0259, 19.5869, 20.1300, 20.6566, 21.1706};
static const G4double X7[nX]={.00241155,
2.87095, 4.02492, 4.89243, 5.61207, 6.23747, 6.79613, 7.30433, 7.77270, 8.20858, 8.61732,
9.00296, 9.36863, 9.71682, 10.0495, 10.3684, 10.6749, 10.9701, 11.2550, 11.5306, 11.7982};
static const G4double X8[nX]={.000316863,
1.76189, 2.44632, 2.95477, 3.37292, 3.73378, 4.05420, 4.34415, 4.61009, 4.85651, 5.08666,
5.30299, 5.50738, 5.70134, 5.88609, 6.06262, 6.23178, 6.39425, 6.55065, 6.70149, 6.84742};
static const G4double X9[nX]={3.73544e-05,
1.17106, 1.61289, 1.93763, 2.20259, 2.42976, 2.63034, 2.81094, 2.97582, 3.12796, 3.26949,
3.40202, 3.52680, 3.64482, 3.75687, 3.86360, 3.96557, 4.06323, 4.15697, 4.24713, 4.33413};
static const G4double XA[nX]={4.19131e-06,
.849573, 1.16208, 1.38955, 1.57379, 1.73079, 1.86867, 1.99221, 2.10451, 2.20770, 2.30332,
2.39252, 2.47622, 2.55511, 2.62977, 2.70066, 2.76818, 2.83265, 2.89437, 2.95355, 3.01051};
static const G4double XB[nX]={4.59981e-07,
.666131, .905836, 1.07880, 1.21796, 1.33587, 1.43890, 1.53080, 1.61399, 1.69011, 1.76040,
1.82573, 1.88682, 1.94421, 1.99834, 2.04959, 2.09824, 2.14457, 2.18878, 2.23107, 2.27162};
static const G4double XC[nX]={4.99861e-08,
.556280, .752730, .893387, 1.00587, 1.10070, 1.18317, 1.25643, 1.32247, 1.38269, 1.43809,
1.48941, 1.53724, 1.58203, 1.62416, 1.66391, 1.70155, 1.73728, 1.77128, 1.80371, 1.83473};
static const G4double XD[nX]={5.40832e-09,
.488069, .657650, .778236, .874148, .954621, 1.02432, 1.08599, 1.14138, 1.19172, 1.23787,
1.28049, 1.32008, 1.35705, 1.39172, 1.42434, 1.45514, 1.48429, 1.51197, 1.53829, 1.56339};
static const G4double XE[nX]={5.84029e-10,
.445057, .597434, .705099, .790298, .861468, .922865, .976982, 1.02542, 1.06930, 1.10939,
1.14630, 1.18050, 1.21233, 1.24208, 1.27001, 1.29630, 1.32113, 1.34462, 1.36691, 1.38812};
static const G4double XF[nX]={6.30137e-11,
.418735, .560003, .659168, .737230, .802138, .857898, .906854, .950515, .989915, 1.02580,
1.05873, 1.08913, 1.11734, 1.14364, 1.16824, 1.19133, 1.21306, 1.23358, 1.25298, 1.27139};
static const G4double XG[nX]={6.79627e-12,
.405286, .539651, .633227, .706417, .766929, .818642, .863824, .903931, .939963, .972639,
1.00250, 1.02995, 1.05532, 1.07887, 1.10082, 1.12134, 1.14058, 1.15867, 1.17572, 1.19183};
static const G4double XH[nX]={7.32882e-13,
.404391, .535199, .625259, .695036, .752243, .800752, .842823, .879906, .912994, .942802,
.969862, .994583, 1.01729, 1.03823, 1.05763, 1.07566, 1.09246, 1.10816, 1.12286, 1.13667};
static const G4double XI[nX]={7.90251e-14,
.418084, .548382, .636489, .703728, .758106, .803630, .842633, .876608, .906576, .933269,
.957233, .978886, .998556, 1.01651, 1.03295, 1.04807, 1.06201, 1.07489, 1.08683, 1.09792};
static const G4double XJ[nX]={8.52083e-15,
.447299, .579635, .666780, .731788, .783268, .825512, .861013, .891356, .917626, .940597,
.960842, .978802, .994820, 1.00917, 1.02208, 1.03373, 1.04427, 1.05383, 1.06253, 1.07046};
// Direct table
static const G4double Xmin[nE]={X0[0],X1[0],X2[0],X3[0],X4[0],X5[0],X6[0],X7[0],X8[0],
X9[0],XA[0],XB[0],XC[0],XD[0],XE[0],XF[0],XG[0],XH[0],XI[0],XJ[0]};
static const G4double dX[nE]={
(X0[lX]-X0[0])/lX, (X1[lX]-X1[0])/lX, (X2[lX]-X2[0])/lX, (X3[lX]-X3[0])/lX,
(X4[lX]-X4[0])/lX, (X5[lX]-X5[0])/lX, (X6[lX]-X6[0])/lX, (X7[lX]-X7[0])/lX,
(X8[lX]-X8[0])/lX, (X9[lX]-X9[0])/lX, (XA[lX]-XA[0])/lX, (XB[lX]-XB[0])/lX,
(XC[lX]-XC[0])/lX, (XD[lX]-XD[0])/lX, (XE[lX]-XE[0])/lX, (XF[lX]-XF[0])/lX,
(XG[lX]-XG[0])/lX, (XH[lX]-XH[0])/lX, (XI[lX]-XI[0])/lX, (XJ[lX]-XJ[0])/lX};
static const G4double* Xl[nE]=
{X0,X1,X2,X3,X4,X5,X6,X7,X8,X9,XA,XB,XC,XD,XE,XF,XG,XH,XI,XJ};
static const G4double I0[nX]={0,
.354631, 1.08972, 2.05138, 3.16564, 4.38343, 5.66828, 6.99127, 8.32858, 9.65998, 10.9680,
12.2371, 13.4536, 14.6050, 15.6802, 16.6686, 17.5609, 18.3482, 19.0221, 19.5752, 20.0000};
static const G4double I1[nX]={0,
.281625, .877354, 1.67084, 2.60566, 3.64420, 4.75838, 5.92589, 7.12829, 8.34989, 9.57708,
10.7978, 12.0014, 13.1781, 14.3190, 15.4162, 16.4620, 17.4496, 18.3724, 19.2245, 20.0000};
static const G4double I2[nX]={0,
.201909, .642991, 1.24946, 1.98463, 2.82370, 3.74802, 4.74263, 5.79509, 6.89474, 8.03228,
9.19947, 10.3889, 11.5938, 12.8082, 14.0262, 15.2427, 16.4527, 17.6518, 18.8356, 20.0000};
static const G4double I3[nX]={0,
.140937, .461189, .920216, 1.49706, 2.17728, 2.94985, 3.80580, 4.73758, 5.73867, 6.80331,
7.92637, 9.10316, 10.3294, 11.6013, 12.9150, 14.2672, 15.6548, 17.0746, 18.5239, 20.0000};
static const G4double I4[nX]={0,
.099161, .337358, .694560, 1.16037, 1.72761, 2.39078, 3.14540, 3.98768, 4.91433, 5.92245,
7.00942, 8.17287, 9.41060, 10.7206, 12.1010, 13.5500, 15.0659, 16.6472, 18.2924, 20.0000};
static const G4double I5[nX]={0,
.071131, .255084, .543312, .932025, 1.41892, 2.00243, 2.68144, 3.45512, 4.32283, 5.28411,
6.33859, 7.48602, 8.72621, 10.0590, 11.4844, 13.0023, 14.6128, 16.3158, 18.1115, 20.0000};
static const G4double I6[nX]={0,
.053692, .202354, .443946, .778765, 1.20774, 1.73208, 2.35319, 3.07256, 3.89177, 4.81249,
5.83641, 6.96528, 8.20092, 9.54516, 10.9999, 12.5670, 14.2486, 16.0466, 17.9630, 20.0000};
static const G4double I7[nX]={0,
.043065, .168099, .376879, .672273, 1.05738, 1.53543, 2.10973, 2.78364, 3.56065, 4.44429,
5.43819, 6.54610, 7.77186, 9.11940, 10.5928, 12.1963, 13.9342, 15.8110, 17.8313, 20.0000};
static const G4double I8[nX]={0,
.036051, .143997, .327877, .592202, .941572, 1.38068, 1.91433, 2.54746, 3.28517, 4.13277,
5.09574, 6.17984, 7.39106, 8.73568, 10.2203, 11.8519, 13.6377, 15.5854, 17.7033, 20.0000};
static const G4double I9[nX]={0,
.030977, .125727, .289605, .528146, .846967, 1.25183, 1.74871, 2.34384, 3.04376, 3.85535,
4.78594, 5.84329, 7.03567, 8.37194, 9.86163, 11.5150, 13.3430, 15.3576, 17.5719, 20.0000};
static const G4double IA[nX]={0,
.027129, .111420, .258935, .475812, .768320, 1.14297, 1.60661, 2.16648, 2.83034, 3.60650,
4.50394, 5.53238, 6.70244, 8.02569, 9.51488, 11.1841, 13.0488, 15.1264, 17.4362, 20.0000};
static const G4double IB[nX]={0,
.024170, .100153, .234345, .433198, .703363, 1.05184, 1.48607, 2.01409, 2.64459, 3.38708,
4.25198, 5.25084, 6.39647, 7.70319, 9.18708, 10.8663, 12.7617, 14.8968, 17.2990, 20.0000};
static const G4double IC[nX]={0,
.021877, .091263, .214670, .398677, .650133, .976322, 1.38510, 1.88504, 2.48555, 3.19709,
4.03129, 5.00127, 6.12184, 7.40989, 8.88482, 10.5690, 12.4888, 14.6748, 17.1638, 20.0000};
static const G4double ID[nX]={0,
.020062, .084127, .198702, .370384, .606100, .913288, 1.30006, 1.77535, 2.34912, 3.03253,
3.83822, 4.78063, 5.87634, 7.14459, 8.60791, 10.2929, 12.2315, 14.4621, 17.0320, 20.0000};
static const G4double IE[nX]={0,
.018547, .078104, .185102, .346090, .567998, .858331, 1.22535, 1.67824, 2.22735, 2.88443,
3.66294, 4.57845, 5.64911, 6.89637, 8.34578, 10.0282, 11.9812, 14.2519, 16.8993, 20.0000};
static const G4double IF[nX]={0,
.017143, .072466, .172271, .323007, .531545, .805393, 1.15288, 1.58338, 2.10754, 2.73758,
3.48769, 4.37450, 5.41770, 6.64092, 8.07288, 9.74894, 11.7135, 14.0232, 16.7522, 20.0000};
static const G4double IG[nX]={0,
.015618, .066285, .158094, .297316, .490692, .745653, 1.07053, 1.47479, 1.96931, 2.56677,
3.28205, 4.13289, 5.14068, 6.33158, 7.73808, 9.40133, 11.3745, 13.7279, 16.5577, 20.0000};
static const G4double IH[nX]={0,
.013702, .058434, .139923, .264115, .437466, .667179, .961433, 1.32965, 1.78283, 2.33399,
2.99871, 3.79596, 4.74916, 5.88771, 7.24937, 8.88367, 10.8576, 13.2646, 16.2417, 20.0000};
static const G4double II[nX]={0,
.011264, .048311, .116235, .220381, .366634, .561656, .813132, 1.13008, 1.52322, 2.00554,
2.59296, 3.30542, 4.16834, 5.21490, 6.48964, 8.05434, 9.99835, 12.4580, 15.6567, 20.0000};
static const G4double IJ[nX]={0,
.008628, .037206, .089928, .171242, .286114, .440251, .640343, .894382, 1.21208, 1.60544,
2.08962, 2.68414, 3.41486, 4.31700, 5.44048, 6.85936, 8.69067, 11.1358, 14.5885, 20.0000};
static const G4double* Il[nE]=
{I0,I1,I2,I3,I4,I5,I6,I7,I8,I9,IA,IB,IC,ID,IE,IF,IG,IH,II,IJ};
static const G4double lE[nE]={
-1.98842,-1.58049,-1.17256,-.764638,-.356711, .051215, .459141, .867068, 1.27499, 1.68292,
2.09085, 2.49877, 2.90670, 3.31463, 3.72255, 4.13048, 4.53840, 4.94633, 5.35426, 5.76218};
static const G4double lEmi=lE[0];
static const G4double lEma=lE[nE-1];
static const G4double dlE=(lEma-lEmi)/bE;
//***************************************************************************************
G4double Enu=lastE; // Get energy of the last calculated cross-section
G4double lEn=std::log(Enu); // log(E) for interpolation
G4double rE=(lEn-lEmi)/dlE; // Position of the energy
G4int fE=static_cast<int>(rE); // Left bin for interpolation
if(fE<0) fE=0;
if(fE>pE)fE=pE;
G4int sE=fE+1; // Right bin for interpolation
G4double dE=rE-fE; // relative log shift from the left bin
G4double dEnu=Enu+Enu; // doubled energy of nu/anu
G4double Enu2=Enu*Enu; // squared energy of nu/anu
G4double Emu=Enu; // Free Energy of neutrino/anti-neutrino
G4double ME=Enu*MN; // M*E
G4double dME=ME+ME; // 2*M*E
G4double dEMN=(dEnu+MN)*ME;
G4double sqE=Enu*ME;
G4double E2M=MN*Enu2;
G4double ymax=(E2M+sqE)/dEMN;
G4double Q2mi=0.; // Q2_min(E_nu)
G4double Q2ma=dME*ymax; // Q2_max(E_nu)
G4double Q2nq=Emu*dMN-mcV;
if(Q2ma>Q2nq) Q2ma=Q2nq; // Correction for Non Quasi Elastic
// --- now r_min=Q2mi/Q2ma and r_max=1.; when r is randomized -> Q2=r*Q2ma ---
G4double Rmi=Q2mi/Q2ma;
G4double shift=.875/(1.+.2977/Enu/Enu)/std::pow(Enu,.78);
// --- E-interpolation must be done in a log scale ---
G4double Xmi=std::pow((shift-Rmi),power);// X_min(E_nu)
G4double Xma=std::pow((shift-1.),power); // X_max(E_nu)
// Find the integral values integ(Xmi) & integ(Xma) using the direct table
G4double idX=dX[fE]+dE*(dX[sE]-dX[fE]); // interpolated X step
G4double iXmi=Xmin[fE]+dE*(Xmin[sE]-Xmin[fE]); // interpolated X minimum
G4double rXi=(Xmi-iXmi)/idX;
G4int iXi=static_cast<int>(rXi);
if(iXi<0) iXi=0;
if(iXi>bX) iXi=bX;
G4double dXi=rXi-iXi;
G4double bntil=Il[fE][iXi];
G4double intil=bntil+dXi*(Il[fE][iXi+1]-bntil);
G4double bntir=Il[sE][iXi];
G4double intir=bntir+dXi*(Il[sE][iXi+1]-bntir);
G4double inti=intil+dE*(intir-intil);// interpolated begin of the integral
//
G4double rXa=(Xma-iXmi)/idX;
G4int iXa=static_cast<int>(rXa);
if(iXa<0) iXa=0;
if(iXa>bX) iXa=bX;
G4double dXa=rXa-iXa;
G4double bntal=Il[fE][iXa];
G4double intal=bntal+dXa*(Il[fE][iXa+1]-bntal);
G4double bntar=Il[sE][iXa];
G4double intar=bntar+dXa*(Il[sE][iXa+1]-bntar);
G4double inta=intal+dE*(intar-intal);// interpolated end of the integral
//
// *** Find X using the reversed table ***
G4double intx=inti+(inta-inti)*G4UniformRand();
G4int intc=static_cast<int>(intx);
if(intc<0) intc=0;
if(intc>bX) intc=bX;
G4double dint=intx-intc;
G4double mXl=Xl[fE][intc];
G4double Xlb=mXl+dint*(Xl[fE][intc+1]-mXl);
G4double mXr=Xl[sE][intc];
G4double Xrb=mXr+dint*(Xl[sE][intc+1]-mXr);
G4double X=Xlb+dE*(Xrb-Xlb); // interpolated X value
G4double R=shift-std::pow(X,pconv);
G4double Q2=R*Q2ma;
return Q2*GeV*GeV;
}
// It returns a fraction of the direct interaction of the neutrino with quark-partons
G4double G4QANuANuNuclearCrossSection::GetDirectPart(G4double Q2)
{
G4double f=Q2/4.62;
G4double ff=f*f;
G4double r=ff*ff;
G4double s=std::pow((1.+.6/Q2),(-1.-(1.+r)/(12.5+r/.3)));
//@@ It is the same for nu/anu, but for nu it is a bit less, and for anu a bit more (par)
return 1.-s*(1.-s/2);
}
// #of quark-partons in the nonperturbative phase space is the same for neut and anti-neut
G4double G4QANuANuNuclearCrossSection::GetNPartons(G4double Q2)
{
return 3.+.3581*std::log(1.+Q2/.04); // a#of partons in the nonperturbative phase space
}
// This class can provide only virtual exchange pi+ (a substitute for W+ boson)
G4int G4QANuANuNuclearCrossSection::GetExchangePDGCode() {return 22;}
@@ -0,0 +1,775 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// $Id: G4QANuENuclearCrossSection.cc,v 1.2 2007/11/01 16:09:38 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// G4 Physics class: G4QANuENuclearCrossSection for (anti_ni_e,e+) cross sections
// Created: M.V. Kossov, CERN/ITEP(Moscow), 24-SEP-2007
// The last update: M.V. Kossov, CERN/ITEP (Moscow) 24-SEP-2007
//
// ****************************************************************************************
// ********** This CLASS is temporary moved from the photolepton_hadron directory *********
// ******* DO NOT MAKE ANY CHANGE! With time it'll move back to photolepton...(M.K.) ******
// ****************************************************************************************
//===============================================================================================
//#define debug
//#define edebug
//#define pdebug
//#define ppdebug
//#define tdebug
//#define sdebug
#include "G4QANuENuclearCrossSection.hh"
// Initialization of the
G4bool G4QANuENuclearCrossSection::onlyCS=true;//Flag to calculate only CS (not QE)
G4double G4QANuENuclearCrossSection::lastSig=0.;//Last calculated total cross section
G4double G4QANuENuclearCrossSection::lastQEL=0.;//Last calculated quasi-el. cross section
G4int G4QANuENuclearCrossSection::lastL=0; //Last used in cross section TheLastBin
G4double G4QANuENuclearCrossSection::lastE=0.; //Last used in cross section TheEnergy
G4double* G4QANuENuclearCrossSection::lastEN=0; //Pointer to the Energy Scale of TX & QE
G4double* G4QANuENuclearCrossSection::lastTX=0; //Pointer to the LastArray of TX function
G4double* G4QANuENuclearCrossSection::lastQE=0; //Pointer to the LastArray of QE function
G4int G4QANuENuclearCrossSection::lastPDG=0; // The last PDG code of the projectile
G4int G4QANuENuclearCrossSection::lastN=0; // The last N of calculated nucleus
G4int G4QANuENuclearCrossSection::lastZ=0; // The last Z of calculated nucleus
G4double G4QANuENuclearCrossSection::lastP=0.; // Last used in cross section Momentum
G4double G4QANuENuclearCrossSection::lastTH=0.; // Last threshold momentum
G4double G4QANuENuclearCrossSection::lastCS=0.; // Last value of the Cross Section
G4int G4QANuENuclearCrossSection::lastI=0; // The last position in the DAMDB
// Returns Pointer to the G4VQCrossSection class
G4VQCrossSection* G4QANuENuclearCrossSection::GetPointer()
{
static G4QANuENuclearCrossSection theCrossSection;//**Static body of the Cross Section**
return &theCrossSection;
}
// The main member function giving the collision cross section (P is in IU, CS is in mb)
// Make pMom in independent units ! (Now it is MeV)
G4double G4QANuENuclearCrossSection::GetCrossSection(G4bool fCS, G4double pMom,
G4int tgZ, G4int tgN, G4int pPDG)
{
static G4int j; // A#0f records found in DB for this projectile
static std::vector <G4int> colPDG;// Vector of the projectile PDG code
static std::vector <G4int> colN; // Vector of N for calculated nuclei (isotops)
static std::vector <G4int> colZ; // Vector of Z for calculated nuclei (isotops)
static std::vector <G4double> colP; // Vector of last momenta for the reaction
static std::vector <G4double> colTH; // Vector of energy thresholds for the reaction
static std::vector <G4double> colCS; // Vector of last cross sections for the reaction
// ***---*** End of the mandatory Static Definitions of the Associative Memory ***---***
G4double pEn=pMom;
#ifdef debug
G4cout<<"G4QAENCS::GetCS:>> f="<<fCS<<", p="<<pMom<<", Z="<<tgZ<<"("<<lastZ<<") ,N="<<tgN
<<"("<<lastN<<"),PDG="<<pPDG<<"("<<lastPDG<<"), T="<<pEn<<"("<<lastTH<<")"<<",Sz="
<<colN.size()<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
if(pPDG!=-12)
{
#ifdef debug
G4cout<<"G4QAENCS::GetCS: *** Found pPDG="<<pPDG<<" ====> CS=0"<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
return 0.; // projectile PDG=0 is a mistake (?!) @@
}
G4bool in=false; // By default the isotope must be found in the AMDB
if(tgN!=lastN || tgZ!=lastZ || pPDG!=lastPDG)// The nucleus was not the last used isotope
{
in = false; // By default the isotope haven't be found in AMDB
lastP = 0.; // New momentum history (nothing to compare with)
lastPDG = pPDG; // The last PDG of the projectile
lastN = tgN; // The last N of the calculated nucleus
lastZ = tgZ; // The last Z of the calculated nucleus
lastI = colN.size(); // Size of the Associative Memory DB in the heap
j = 0; // A#0f records found in DB for this projectile
if(lastI) for(G4int i=0; i<lastI; i++) if(colPDG[i]==pPDG) // The partType is found
{ // The nucleus with projPDG is found in AMDB
if(colN[i]==tgN && colZ[i]==tgZ)
{
lastI=i;
lastTH =colTH[i]; // Last THreshold (A-dependent)
#ifdef pdebug
G4cout<<"G4QAENCS::GetCS:*Found*P="<<pMom<<",Threshold="<<lastTH<<",j="<<j<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
if(pEn<=lastTH)
{
#ifdef pdebug
G4cout<<"G4QAENCS::GetCS:Found T="<<pEn<<" < Threshold="<<lastTH<<",X=0"<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
return 0.; // Energy is below the Threshold value
}
lastP =colP [i]; // Last Momentum (A-dependent)
lastCS =colCS[i]; // Last CrossSect (A-dependent)
if(std::fabs(lastP/pMom-1.)<tolerance)
{
#ifdef pdebug
G4cout<<"G4QAENCS::GetCS:P="<<pMom<<",CS="<<lastCS*millibarn<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
return lastCS*millibarn; // Use theLastCS
}
in = true; // This is the case when the isotop is found in DB
// Momentum pMom is in IU ! @@ Units
#ifdef pdebug
G4cout<<"G4QAENCS::G:UpdaDB P="<<pMom<<",f="<<fCS<<",lI="<<lastI<<",j="<<j<<G4endl;
#endif
lastCS=CalculateCrossSection(fCS,-1,j,lastPDG,lastZ,lastN,pMom); // read & update
#ifdef pdebug
G4cout<<"G4QAENCS::GetCrosSec: *****> New (inDB) Calculated CS="<<lastCS<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
if(lastCS<=0. && pEn>lastTH) // Correct the threshold
{
#ifdef pdebug
G4cout<<"G4QAENCS::GetCS: New T="<<pEn<<"(CS=0) > Threshold="<<lastTH<<G4endl;
#endif
lastTH=pEn;
}
break; // Go out of the LOOP
}
#ifdef pdebug
G4cout<<"---G4QAENCrossSec::GetCrosSec:pPDG="<<pPDG<<",j="<<j<<",N="<<colN[i]
<<",Z["<<i<<"]="<<colZ[i]<<",cPDG="<<colPDG[i]<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
j++; // Increment a#0f records found in DB for this pPDG
}
if(!in) // This nucleus has not been calculated previously
{
#ifdef pdebug
G4cout<<"G4QAENCS::GetCrosSec:CalcNew P="<<pMom<<",f="<<fCS<<",lstI="<<lastI<<G4endl;
#endif
//!!The slave functions must provide cross-sections in millibarns (mb) !! (not in IU)
lastCS=CalculateCrossSection(fCS,0,j,lastPDG,lastZ,lastN,pMom); //calculate & create
if(lastCS<=0.)
{
lastTH = ThresholdEnergy(tgZ, tgN); // The Threshold Energy which is now the last
#ifdef pdebug
G4cout<<"G4QAENCrossSection::GetCrossSect: NewThresh="<<lastTH<<",T="<<pEn<<G4endl;
#endif
if(pEn>lastTH)
{
#ifdef pdebug
G4cout<<"G4QAENCS::GetCS: First T="<<pEn<<"(CS=0) > Threshold="<<lastTH<<G4endl;
#endif
lastTH=pEn;
}
}
#ifdef pdebug
G4cout<<"G4QAENCS::GetCrosSec:New CS="<<lastCS<<",lZ="<<lastN<<",lN="<<lastZ<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
colN.push_back(tgN);
colZ.push_back(tgZ);
colPDG.push_back(pPDG);
colP.push_back(pMom);
colTH.push_back(lastTH);
colCS.push_back(lastCS);
#ifdef pdebug
G4cout<<"G4QAENCS::GetCS:1st,P="<<pMom<<"(MeV),X="<<lastCS*millibarn<<"(mb)"<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
return lastCS*millibarn;
} // End of creation of the new set of parameters
else
{
#ifdef pdebug
G4cout<<"G4QAENCS::GetCS: Update lastI="<<lastI<<",j="<<j<<G4endl;
#endif
colP[lastI]=pMom;
colPDG[lastI]=pPDG;
colCS[lastI]=lastCS;
}
} // End of parameters udate
else if(pEn<=lastTH)
{
#ifdef pdebug
G4cout<<"G4QAENCS::GetCS: Current T="<<pEn<<" < Threshold="<<lastTH<<", CS=0"<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
return 0.; // Momentum is below the Threshold Value -> CS=0
}
else if(std::fabs(lastP/pMom-1.)<tolerance)
{
#ifdef pdebug
G4cout<<"G4QAENCS::GetCS:OldCur P="<<pMom<<"="<<pMom<<",CS="<<lastCS*millibarn<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
return lastCS*millibarn; // Use theLastCS
}
else
{
#ifdef pdebug
G4cout<<"G4QAENCS::GetCS:UpdaCur P="<<pMom<<",f="<<fCS<<",I="<<lastI<<",j="<<j<<G4endl;
#endif
lastCS=CalculateCrossSection(fCS,1,j,lastPDG,lastZ,lastN,pMom); // Only UpdateDB
lastP=pMom;
}
#ifdef pdebug
G4cout<<"G4QAENCS::GetCrSec:End,P="<<pMom<<"(MeV),CS="<<lastCS*millibarn<<"(mb)"<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
return lastCS*millibarn;
}
// Gives the threshold energy = the same for all nuclei (@@ can be reduced for hevy nuclei)
G4double G4QANuENuclearCrossSection::ThresholdEnergy(G4int Z, G4int N, G4int)
{
//static const G4double mNeut = G4NucleiProperties::GetNuclearMass(1.,0.)/GeV;
//static const G4double mProt = G4NucleiProperties::GetNuclearMass(1.,1.)/GeV;
//static const G4double mDeut = G4NucleiProperties::GetNuclearMass(2.,1.)/GeV/2.;
static const G4double mN=.931494043;// Nucleon mass (inside nucleus, AtomicMassUnit, GeV)
static const G4double dmN=mN+mN; // Doubled nucleon mass (2*AtomicMassUnit, GeV)
static const G4double me=.00051099892; // electron mass in GeV
static const G4double me2=me*me; // Squared mass of an electron in GeV^2
static const G4double thresh=me+me2/dmN; // Universal threshold in GeV
// ---------
//static const G4double infEn = 9.e27;
G4double dN=0.;
if(Z>0||N>0) dN=thresh*GeV; // @@ if upgraded, change it in a total cross section
//@@ "dN=me+me2/G4NucleiProperties::GetNuclearMass(<G4double>(Z+N),<G4double>(Z)/GeV"
return dN;
}
// The main member function giving the gamma-A cross section (E_kin in MeV, CS in mb)
G4double G4QANuENuclearCrossSection::CalculateCrossSection(G4bool CS, G4int F, G4int I,
G4int , G4int targZ, G4int targN, G4double Momentum)
{
static const G4double mb38=1.E-11;// Conversion 10^-38 cm^2 to mb=10^-27 cm^2
static const G4int nE=65; // !! If change this, change it in GetFunctions() !!
static const G4int mL=nE-1;
static const G4double mN=.931494043;// Nucleon mass (inside nucleus, AtomicMassUnit, GeV)
static const G4double dmN=mN+mN; // Doubled nucleon mass (2*AtomicMassUnit, GeV)
static const G4double me=.00051099892;// electron mass in GeV
static const G4double me2=me*me; // Squared mass of an electron in GeV^2
static const G4double EMi=me+me2/dmN; // Universal threshold of the reaction in GeV
static const G4double EMa=300.; // Maximum tabulated Energy of nu_e in GeV
// *** Begin of the Associative memory for acceleration of the cross section calculations
static std::vector <G4double> colH; //?? Vector of HighEnergyCoefficients (functional)
static std::vector <G4double*> TX; // Vector of pointers to the TX tabulated functions
static std::vector <G4double*> QE; // Vector of pointers to the QE tabulated functions
static G4bool first=true; // Flag of initialization of the energy axis
// *** End of Static Definitions (Associative Memory) ***
//const G4double Energy = aPart->GetKineticEnergy()/MeV; // Energy of the Electron
//G4double TotEnergy2=Momentum;
onlyCS=CS; // Flag to calculate only CS (not TX & QE)
lastE=Momentum/GeV; // Kinetic energy of the electron neutrino (in GeV)
if (lastE<=EMi) // Energy is below the minimum energy in the table
{
lastE=0.;
lastSig=0.;
return 0.;
}
G4int Z=targZ; // New Z, which can change the sign
if(F<=0) // This isotope was not the last used isotop
{
if(F<0) // This isotope was found in DAMDB =========> RETRIEVE
{
lastTX =TX[I]; // Pointer to the prepared TX function (same isotope)
lastQE =QE[I]; // Pointer to the prepared QE function (same isotope)
}
else // This isotope wasn't calculated previously => CREATE
{
if(first)
{
lastEN = new G4double[nE]; // This must be done only once!
Z=-Z; // To explain GetFunctions that E-axis must be filled
first=false; // To make it only once
}
lastTX = new G4double[nE]; // Allocate memory for the new TX function
lastQE = new G4double[nE]; // Allocate memory for the new QE function
G4int res=GetFunctions(Z,targN,lastTX,lastQE,lastEN);//@@analize(0=first,-1=bad,1=OK)
if(res<0) G4cerr<<"*W*G4NuENuclearCS::CalcCrossSect:Bad Function Retrieve"<<G4endl;
// *** The synchronization check ***
G4int sync=TX.size();
if(sync!=I) G4cerr<<"***G4NuENuclearCS::CalcCrossSect:Sync.="<<sync<<"#"<<I<<G4endl;
TX.push_back(lastTX);
QE.push_back(lastQE);
} // End of creation of the new set of parameters
} // End of parameters udate
// ============================== NOW Calculate the Cross Section =====================
if (lastE<=EMi) // Check that antiNuEnergy is higher than ThreshE
{
lastE=0.;
lastSig=0.;
return 0.;
}
if(lastE<EMa) // Linear fit is made explicitly to fix the last bin for the randomization
{
G4int chk=1;
G4int ran=mL/2;
G4int sep=ran; // as a result = an index of the left edge of the interval
while(ran>=2)
{
G4int newran=ran/2;
G4double oldL=lastEN[sep];
if(lastE<=oldL) sep-=newran;
else sep+=newran;
#ifdef pdebug
G4cout<<"G4ANuE::CCS:n="<<newran<<",s="<<sep<<",E="<<lastE<<",oE="<<oldL<<G4endl;
#endif
ran=newran;
chk=chk+chk;
}
if(chk+chk!=mL) G4cerr<<"*Warn*G4NuENuclearCS::CalcCS:Table! mL="<<mL<<G4endl;
G4double lowE=lastEN[sep];
G4double highE=lastEN[sep+1];
G4double lowTX=lastTX[sep];
if(lastE<lowE||sep>=mL||lastE>highE)
G4cerr<<"*Warn*G4ANuENuclearCS::CalcCS:Bin! "<<lowE<<" < "<<lastE<<" < "<<highE
<<", sep="<<sep<<", mL="<<mL<<G4endl;
lastSig=lastE*(lastE-lowE)*(lastTX[sep+1]-lowTX)/(highE-lowE)+lowTX; // Recover *E
if(!onlyCS) // Skip the differential cross-section parameters
{
G4double lowQE=lastQE[sep];
lastQEL=(lastE-lowE)*(lastQE[sep+1]-lowQE)/(highE-lowE)+lowQE;
#ifdef pdebug
G4cout<<"G4ANuENuclearCS::CalcCS: T="<<lastSig<<",Q="<<lastQEL<<",E="<<lastE<<G4endl;
#endif
}
}
else
{
lastSig=lastTX[mL]; // @@ No extrapolation, just a const, while it looks shrinking...
lastQEL=lastQE[mL];
}
if(lastQEL<0.) lastQEL = 0.;
if(lastSig<0.) lastSig = 0.;
// The cross-sections are expected to be in mb
lastSig*=mb38;
if(!onlyCS) lastQEL*=mb38;
return lastSig;
}
// Calculate the cros-section functions
// ****************************************************************************************
// *** This tables are the same for all lepto-nuclear reactions, only mass is different ***
// ***@@ IT'S REASONABLE TO MAKE ADDiTIONAL VIRTUAL CLASS FOR LEPTO-NUCLEAR WITH THIS@@ ***
// ****************************************************************************************
G4int G4QANuENuclearCrossSection::GetFunctions (G4int z, G4int n,
G4double* t, G4double* q, G4double* e)
{
static const G4double mN=.931494043;// Nucleon mass (inside nucleus, AtomicMassUnit, GeV)
static const G4double dmN=mN+mN; // Doubled nucleon mass (2*AtomicMassUnit, GeV)
static const G4double me=.00051099892; // electron mass in GeV
static const G4double me2=me*me; // Squared mass of an electron in GeV^2
static const G4double thresh=me+me2/dmN; // Universal threshold in GeV
static const G4int nE=65; // !! If change this, change it in CalculateCrossSection() !!
static const G4double nuEn[nE]={thresh,
.00051331,.00053602,.00056078,.00058783,.00061743,.00064990,.00068559,.00072492,
.00076834,.00081641,.00086975,.00092912,.00099536,.00106950,.00115273,.00124646,
.00135235,.00147241,.00160901,.00176503,.00194392,.00214986,.00238797,.00266448,
.00298709,.00336531,.00381094,.00433879,.00496745,.00572047,.00662785,.00772806,
.00907075,.01072050,.01276190,.01530660,.01850330,.02255110,.02771990,.03437780,
.04303240,.05438970,.06944210,.08959920,.11688400,.15423600,.20597200,.27851200,
.38153100,.52979600,.74616300,1.0665200,1.5480900,2.2834800,3.4251100,5.2281000,
8.1270200,12.875900,20.808500,34.331200,57.877800,99.796200,176.16300,318.68200};
static const G4double TOTX[nE]={0.,
.00046923,.00160693,.00229560,.00288772,.00344344,.00398831,.00453725,.00510087,
.00568797,.00630663,.00696489,.00767121,.00843477,.00926586,.01017610,.01117910,
.01229040,.01352820,.01491430,.01647420,.01823820,.02024280,.02253130,.02515600,
.02818010,.03167950,.03574640,.04049260,.04605330,.05739330,.07028190,.08396290,
.09969400,.11756200,.13812500,.16207000,.19099600,.22447700,.26434900,.31051900,
.36357400,.42242900,.48500000,.54692800,.60140500,.63996800,.65519300,.64339200,
.60784300,.55734400,.50212600,.45116800,.40962600,.37854800,.35702100,.34330900,
.33576200,.33300100,.33387100,.33737700,.34235200,.34880100,.35507500,.35961200};
static const G4double QELX[nE]={0.,
2.40856e-7,8.61338e-7,1.28732e-6,1.69747e-6,2.12608e-6,2.59201e-6,3.11071e-6,3.69770e-6,
4.37028e-6,5.14877e-6,6.05773e-6,7.12746e-6,8.39567e-6,9.90987e-6,1.17304e-5,1.39343e-5,
1.66209e-5,1.99191e-5,2.39974e-5,2.90775e-5,3.54536e-5,4.35191e-5,5.38039e-5,6.70278e-5,
8.41765e-5,.000106611,.000136228,.000175689,.000228768,.000328317,.000465818,.000648870,
.000904299,.001260330,.001762740,.002480740,.003534040,.005062210,.007327720,.010675000,
.015645500,.022975800,.033679400,.049004300,.070294800,.098706100,.134951000,.179193000,
.231297000,.287287000,.344760000,.404397000,.465915000,.527060000,.584085000,.632748000,
.671346000,.699744000,.719355000,.732541000,.740996000,.746249000,.749265000,.751160000};
// --------------------------------
G4int first=0;
if(z<0.)
{
first=1;
z=-z;
}
if(z<1 || z>92) // neutron & plutonium are forbidden
{
G4cout<<"***G4QANuENuclearCrossSection::GetFunctions:Z="<<z<<".No CS returned"<<G4endl;
return -1;
}
for(G4int k=0; k<nE; k++)
{
G4double a=n+z;
G4double za=z+a;
G4double dz=z+z;
G4double da=a+a;
G4double ta=da+a;
if(first) e[k]=nuEn[k]; // Energy of neutrino E (first bin k=0 can be modified)
t[k]=TOTX[k]*nuEn[k]*(za+za)/ta+QELX[k]*(dz+dz-da)/ta; // TotalCrossSection
q[k]=QELX[k]*dz/a; // QuasiElasticCrossSection
}
return first;
}
// Randomize Q2 from neutrino to the scattered electron when scattering is quasi-elastic
G4double G4QANuENuclearCrossSection::GetQEL_ExchangeQ2()
{
static const G4double me=.00051099892; // electron mass in GeV
static const G4double me2=me*me; // Squared mass of an electron in GeV^2
static const G4double hme2=me2/2; // .5*m_e^2 in GeV^2
static const double MN=.931494043; // Nucleon mass (inside nucleus, atomicMassUnit,GeV)
static const double MN2=MN*MN; // M_N^2 in GeV^2
static const G4double power=-3.5; // direct power for the magic variable
static const G4double pconv=1./power;// conversion power for the magic variable
static const G4int nQ2=101; // #Of point in the Q2l table (in GeV^2)
static const G4int lQ2=nQ2-1; // index of the last in the Q2l table
static const G4int bQ2=lQ2-1; // index of the before last in the Q2 ltable
// Reversed table
static const G4double Xl[nQ2]={5.20224e-16,
.006125,.0137008,.0218166,.0302652,.0389497,.0478144,.0568228,.0659497,.0751768,.0844898,
.093878, .103332, .112844, .122410, .132023, .141680, .151376, .161109, .170875, .180672,
.190499, .200352, .210230, .220131, .230055, .239999, .249963, .259945, .269944, .279960,
.289992, .300039, .310099, .320173, .330260, .340359, .350470, .360592, .370724, .380867,
.391019, .401181, .411352, .421531, .431719, .441915, .452118, .462329, .472547, .482771,
.493003, .503240, .513484, .523734, .533989, .544250, .554517, .564788, .575065, .585346,
.595632, .605923, .616218, .626517, .636820, .647127, .657438, .667753, .678072, .688394,
.698719, .709048, .719380, .729715, .740053, .750394, .760738, .771085, .781434, .791786,
.802140, .812497, .822857, .833219, .843582, .853949, .864317, .874687, .885060, .895434,
.905810, .916188, .926568, .936950, .947333, .957719, .968105, .978493, .988883, .999275};
// Direct table
static const G4double Xmax=Xl[lQ2];
static const G4double Xmin=Xl[0];
static const G4double dX=(Xmax-Xmin)/lQ2; // step in X(Q2, GeV^2)
static const G4double inl[nQ2]={0,
1.52225, 2.77846, 3.96651, 5.11612, 6.23990, 7.34467, 8.43466, 9.51272, 10.5809, 11.6406,
12.6932, 13.7394, 14.7801, 15.8158, 16.8471, 17.8743, 18.8979, 19.9181, 20.9353, 21.9496,
22.9614, 23.9707, 24.9777, 25.9826, 26.9855, 27.9866, 28.9860, 29.9837, 30.9798, 31.9745,
32.9678, 33.9598, 34.9505, 35.9400, 36.9284, 37.9158, 38.9021, 39.8874, 40.8718, 41.8553,
42.8379, 43.8197, 44.8007, 45.7810, 46.7605, 47.7393, 48.7174, 49.6950, 50.6718, 51.6481,
52.6238, 53.5990, 54.5736, 55.5476, 56.5212, 57.4943, 58.4670, 59.4391, 60.4109, 61.3822,
62.3531, 63.3236, 64.2937, 65.2635, 66.2329, 67.2019, 68.1707, 69.1390, 70.1071, 71.0748,
72.0423, 73.0095, 73.9763, 74.9429, 75.9093, 76.8754, 77.8412, 78.8068, 79.7721, 80.7373,
81.7022, 82.6668, 83.6313, 84.5956, 85.5596, 86.5235, 87.4872, 88.4507, 89.4140, 90.3771,
91.3401, 92.3029, 93.2656, 94.2281, 95.1904, 96.1526, 97.1147, 98.0766, 99.0384, 100.000};
G4double Enu=lastE; // Get energy of the last calculated cross-section
G4double dEnu=Enu+Enu; // doubled energy of nu/anu
G4double Enu2=Enu*Enu; // squared energy of nu/anu
G4double ME=Enu*MN; // M*E
G4double dME=ME+ME; // 2*M*E
G4double dEMN=(dEnu+MN)*ME;
G4double MEm=ME-hme2;
G4double sqE=Enu*std::sqrt(MEm*MEm-me2*MN2);
G4double E2M=MN*Enu2-(Enu+MN)*hme2;
G4double ymax=(E2M+sqE)/dEMN;
G4double ymin=(E2M-sqE)/dEMN;
G4double rmin=1.-ymin;
G4double rhm2E=hme2/Enu2;
G4double Q2mi=(Enu2+Enu2)*(rmin-rhm2E-std::sqrt(rmin*rmin-rhm2E-rhm2E)); // Q2_min(E_nu)
G4double Q2ma=dME*ymax; // Q2_max(E_nu)
G4double Xma=std::pow((1.+Q2mi),power); // X_max(E_nu)
G4double Xmi=std::pow((1.+Q2ma),power); // X_min(E_nu)
// Find the integral values integ(Xmi) & integ(Xma) using the direct table
G4double rXi=(Xmi-Xmin)/dX;
G4int iXi=static_cast<int>(rXi);
if(iXi<0) iXi=0;
if(iXi>bQ2) iXi=bQ2;
G4double dXi=rXi-iXi;
G4double bnti=inl[iXi];
G4double inti=bnti+dXi*(inl[iXi+1]-bnti);
//
G4double rXa=(Xma-Xmin)/dX;
G4int iXa=static_cast<int>(rXa);
if(iXa<0) iXa=0;
if(iXa>bQ2) iXa=bQ2;
G4double dXa=rXa-iXa;
G4double bnta=inl[iXa];
G4double inta=bnta+dXa*(inl[iXa+1]-bnta);
// *** Find X using the reversed table ***
G4double intx=inti+(inta-inti)*G4UniformRand();
G4int intc=static_cast<int>(intx);
if(intc<0) intc=0;
if(intc>bQ2) intc=bQ2; // If it is more than max, then the BAD extrapolation
G4double dint=intx-intc;
G4double mX=Xl[intc];
G4double X=mX+dint*(Xl[intc+1]-mX);
G4double Q2=std::pow(X,pconv)-1.;
return Q2*GeV*GeV;
}
// Randomize Q2 from neutrino to the scattered electron when scattering is not quasiElastic
G4double G4QANuENuclearCrossSection::GetNQE_ExchangeQ2()
{
static const double mpi=.13957018; // charged pi meson mass in GeV
static const G4double me=.00051099892;// electron mass in GeV
static const G4double me2=me*me; // Squared mass of an electron in GeV^2
static const G4double hme2=me2/2; // .5*m_e^2 in GeV^2
static const double MN=.931494043; // Nucleon mass (inside nucleus,atomicMassUnit,GeV)
static const double MN2=MN*MN; // M_N^2 in GeV^2
static const double dMN=MN+MN; // 2*M_N in GeV
static const double mcV=(dMN+mpi)*mpi;// constant of W>M+mc cut for Quasi-Elastic
static const G4int power=7; // direct power for the magic variable
static const G4double pconv=1./power; // conversion power for the magic variable
static const G4int nX=21; // #Of point in the Xl table (in GeV^2)
static const G4int lX=nX-1; // index of the last in the Xl table
static const G4int bX=lX-1; // @@ index of the before last in the Xl table
static const G4int nE=20; // #Of point in the El table (in GeV^2)
static const G4int bE=nE-1; // index of the last in the El table
static const G4int pE=bE-1; // index of the before last in the El table
// Reversed table
static const G4double X0[nX]={5.21412e-05,
.437860, .681908, .891529, 1.08434, 1.26751, 1.44494, 1.61915, 1.79198, 1.96493, 2.13937,
2.31664, 2.49816, 2.68559, 2.88097, 3.08705, 3.30774, 3.54917, 3.82233, 4.15131, 4.62182};
static const G4double X1[nX]={.00102591,
1.00443, 1.55828, 2.03126, 2.46406, 2.87311, 3.26723, 3.65199, 4.03134, 4.40835, 4.78561,
5.16549, 5.55031, 5.94252, 6.34484, 6.76049, 7.19349, 7.64917, 8.13502, 8.66246, 9.25086};
static const G4double X2[nX]={.0120304,
2.59903, 3.98637, 5.15131, 6.20159, 7.18024, 8.10986, 9.00426, 9.87265, 10.7217, 11.5564,
12.3808, 13.1983, 14.0116, 14.8234, 15.6359, 16.4515, 17.2723, 18.1006, 18.9386, 19.7892};
static const G4double X3[nX]={.060124,
5.73857, 8.62595, 10.9849, 13.0644, 14.9636, 16.7340, 18.4066, 20.0019, 21.5342, 23.0142,
24.4497, 25.8471, 27.2114, 28.5467, 29.8564, 31.1434, 32.4102, 33.6589, 34.8912, 36.1095};
static const G4double X4[nX]={.0992363,
8.23746, 12.1036, 15.1740, 17.8231, 20.1992, 22.3792, 24.4092, 26.3198, 28.1320, 29.8615,
31.5200, 33.1169, 34.6594, 36.1536, 37.6044, 39.0160, 40.3920, 41.7353, 43.0485, 44.3354};
static const G4double X5[nX]={.0561127,
7.33661, 10.5694, 13.0778, 15.2061, 17.0893, 18.7973, 20.3717, 21.8400, 23.2211, 24.5291,
25.7745, 26.9655, 28.1087, 29.2094, 30.2721, 31.3003, 32.2972, 33.2656, 34.2076, 35.1265};
static const G4double X6[nX]={.0145859,
4.81774, 6.83565, 8.37399, 9.66291, 10.7920, 11.8075, 12.7366, 13.5975, 14.4025, 15.1608,
15.8791, 16.5628, 17.2162, 17.8427, 18.4451, 19.0259, 19.5869, 20.1300, 20.6566, 21.1706};
static const G4double X7[nX]={.00241155,
2.87095, 4.02492, 4.89243, 5.61207, 6.23747, 6.79613, 7.30433, 7.77270, 8.20858, 8.61732,
9.00296, 9.36863, 9.71682, 10.0495, 10.3684, 10.6749, 10.9701, 11.2550, 11.5306, 11.7982};
static const G4double X8[nX]={.000316863,
1.76189, 2.44632, 2.95477, 3.37292, 3.73378, 4.05420, 4.34415, 4.61009, 4.85651, 5.08666,
5.30299, 5.50738, 5.70134, 5.88609, 6.06262, 6.23178, 6.39425, 6.55065, 6.70149, 6.84742};
static const G4double X9[nX]={3.73544e-05,
1.17106, 1.61289, 1.93763, 2.20259, 2.42976, 2.63034, 2.81094, 2.97582, 3.12796, 3.26949,
3.40202, 3.52680, 3.64482, 3.75687, 3.86360, 3.96557, 4.06323, 4.15697, 4.24713, 4.33413};
static const G4double XA[nX]={4.19131e-06,
.849573, 1.16208, 1.38955, 1.57379, 1.73079, 1.86867, 1.99221, 2.10451, 2.20770, 2.30332,
2.39252, 2.47622, 2.55511, 2.62977, 2.70066, 2.76818, 2.83265, 2.89437, 2.95355, 3.01051};
static const G4double XB[nX]={4.59981e-07,
.666131, .905836, 1.07880, 1.21796, 1.33587, 1.43890, 1.53080, 1.61399, 1.69011, 1.76040,
1.82573, 1.88682, 1.94421, 1.99834, 2.04959, 2.09824, 2.14457, 2.18878, 2.23107, 2.27162};
static const G4double XC[nX]={4.99861e-08,
.556280, .752730, .893387, 1.00587, 1.10070, 1.18317, 1.25643, 1.32247, 1.38269, 1.43809,
1.48941, 1.53724, 1.58203, 1.62416, 1.66391, 1.70155, 1.73728, 1.77128, 1.80371, 1.83473};
static const G4double XD[nX]={5.40832e-09,
.488069, .657650, .778236, .874148, .954621, 1.02432, 1.08599, 1.14138, 1.19172, 1.23787,
1.28049, 1.32008, 1.35705, 1.39172, 1.42434, 1.45514, 1.48429, 1.51197, 1.53829, 1.56339};
static const G4double XE[nX]={5.84029e-10,
.445057, .597434, .705099, .790298, .861468, .922865, .976982, 1.02542, 1.06930, 1.10939,
1.14630, 1.18050, 1.21233, 1.24208, 1.27001, 1.29630, 1.32113, 1.34462, 1.36691, 1.38812};
static const G4double XF[nX]={6.30137e-11,
.418735, .560003, .659168, .737230, .802138, .857898, .906854, .950515, .989915, 1.02580,
1.05873, 1.08913, 1.11734, 1.14364, 1.16824, 1.19133, 1.21306, 1.23358, 1.25298, 1.27139};
static const G4double XG[nX]={6.79627e-12,
.405286, .539651, .633227, .706417, .766929, .818642, .863824, .903931, .939963, .972639,
1.00250, 1.02995, 1.05532, 1.07887, 1.10082, 1.12134, 1.14058, 1.15867, 1.17572, 1.19183};
static const G4double XH[nX]={7.32882e-13,
.404391, .535199, .625259, .695036, .752243, .800752, .842823, .879906, .912994, .942802,
.969862, .994583, 1.01729, 1.03823, 1.05763, 1.07566, 1.09246, 1.10816, 1.12286, 1.13667};
static const G4double XI[nX]={7.90251e-14,
.418084, .548382, .636489, .703728, .758106, .803630, .842633, .876608, .906576, .933269,
.957233, .978886, .998556, 1.01651, 1.03295, 1.04807, 1.06201, 1.07489, 1.08683, 1.09792};
static const G4double XJ[nX]={8.52083e-15,
.447299, .579635, .666780, .731788, .783268, .825512, .861013, .891356, .917626, .940597,
.960842, .978802, .994820, 1.00917, 1.02208, 1.03373, 1.04427, 1.05383, 1.06253, 1.07046};
// Direct table
static const G4double Xmin[nE]={X0[0],X1[0],X2[0],X3[0],X4[0],X5[0],X6[0],X7[0],X8[0],
X9[0],XA[0],XB[0],XC[0],XD[0],XE[0],XF[0],XG[0],XH[0],XI[0],XJ[0]};
static const G4double dX[nE]={
(X0[lX]-X0[0])/lX, (X1[lX]-X1[0])/lX, (X2[lX]-X2[0])/lX, (X3[lX]-X3[0])/lX,
(X4[lX]-X4[0])/lX, (X5[lX]-X5[0])/lX, (X6[lX]-X6[0])/lX, (X7[lX]-X7[0])/lX,
(X8[lX]-X8[0])/lX, (X9[lX]-X9[0])/lX, (XA[lX]-XA[0])/lX, (XB[lX]-XB[0])/lX,
(XC[lX]-XC[0])/lX, (XD[lX]-XD[0])/lX, (XE[lX]-XE[0])/lX, (XF[lX]-XF[0])/lX,
(XG[lX]-XG[0])/lX, (XH[lX]-XH[0])/lX, (XI[lX]-XI[0])/lX, (XJ[lX]-XJ[0])/lX};
static const G4double* Xl[nE]=
{X0,X1,X2,X3,X4,X5,X6,X7,X8,X9,XA,XB,XC,XD,XE,XF,XG,XH,XI,XJ};
static const G4double I0[nX]={0,
.354631, 1.08972, 2.05138, 3.16564, 4.38343, 5.66828, 6.99127, 8.32858, 9.65998, 10.9680,
12.2371, 13.4536, 14.6050, 15.6802, 16.6686, 17.5609, 18.3482, 19.0221, 19.5752, 20.0000};
static const G4double I1[nX]={0,
.281625, .877354, 1.67084, 2.60566, 3.64420, 4.75838, 5.92589, 7.12829, 8.34989, 9.57708,
10.7978, 12.0014, 13.1781, 14.3190, 15.4162, 16.4620, 17.4496, 18.3724, 19.2245, 20.0000};
static const G4double I2[nX]={0,
.201909, .642991, 1.24946, 1.98463, 2.82370, 3.74802, 4.74263, 5.79509, 6.89474, 8.03228,
9.19947, 10.3889, 11.5938, 12.8082, 14.0262, 15.2427, 16.4527, 17.6518, 18.8356, 20.0000};
static const G4double I3[nX]={0,
.140937, .461189, .920216, 1.49706, 2.17728, 2.94985, 3.80580, 4.73758, 5.73867, 6.80331,
7.92637, 9.10316, 10.3294, 11.6013, 12.9150, 14.2672, 15.6548, 17.0746, 18.5239, 20.0000};
static const G4double I4[nX]={0,
.099161, .337358, .694560, 1.16037, 1.72761, 2.39078, 3.14540, 3.98768, 4.91433, 5.92245,
7.00942, 8.17287, 9.41060, 10.7206, 12.1010, 13.5500, 15.0659, 16.6472, 18.2924, 20.0000};
static const G4double I5[nX]={0,
.071131, .255084, .543312, .932025, 1.41892, 2.00243, 2.68144, 3.45512, 4.32283, 5.28411,
6.33859, 7.48602, 8.72621, 10.0590, 11.4844, 13.0023, 14.6128, 16.3158, 18.1115, 20.0000};
static const G4double I6[nX]={0,
.053692, .202354, .443946, .778765, 1.20774, 1.73208, 2.35319, 3.07256, 3.89177, 4.81249,
5.83641, 6.96528, 8.20092, 9.54516, 10.9999, 12.5670, 14.2486, 16.0466, 17.9630, 20.0000};
static const G4double I7[nX]={0,
.043065, .168099, .376879, .672273, 1.05738, 1.53543, 2.10973, 2.78364, 3.56065, 4.44429,
5.43819, 6.54610, 7.77186, 9.11940, 10.5928, 12.1963, 13.9342, 15.8110, 17.8313, 20.0000};
static const G4double I8[nX]={0,
.036051, .143997, .327877, .592202, .941572, 1.38068, 1.91433, 2.54746, 3.28517, 4.13277,
5.09574, 6.17984, 7.39106, 8.73568, 10.2203, 11.8519, 13.6377, 15.5854, 17.7033, 20.0000};
static const G4double I9[nX]={0,
.030977, .125727, .289605, .528146, .846967, 1.25183, 1.74871, 2.34384, 3.04376, 3.85535,
4.78594, 5.84329, 7.03567, 8.37194, 9.86163, 11.5150, 13.3430, 15.3576, 17.5719, 20.0000};
static const G4double IA[nX]={0,
.027129, .111420, .258935, .475812, .768320, 1.14297, 1.60661, 2.16648, 2.83034, 3.60650,
4.50394, 5.53238, 6.70244, 8.02569, 9.51488, 11.1841, 13.0488, 15.1264, 17.4362, 20.0000};
static const G4double IB[nX]={0,
.024170, .100153, .234345, .433198, .703363, 1.05184, 1.48607, 2.01409, 2.64459, 3.38708,
4.25198, 5.25084, 6.39647, 7.70319, 9.18708, 10.8663, 12.7617, 14.8968, 17.2990, 20.0000};
static const G4double IC[nX]={0,
.021877, .091263, .214670, .398677, .650133, .976322, 1.38510, 1.88504, 2.48555, 3.19709,
4.03129, 5.00127, 6.12184, 7.40989, 8.88482, 10.5690, 12.4888, 14.6748, 17.1638, 20.0000};
static const G4double ID[nX]={0,
.020062, .084127, .198702, .370384, .606100, .913288, 1.30006, 1.77535, 2.34912, 3.03253,
3.83822, 4.78063, 5.87634, 7.14459, 8.60791, 10.2929, 12.2315, 14.4621, 17.0320, 20.0000};
static const G4double IE[nX]={0,
.018547, .078104, .185102, .346090, .567998, .858331, 1.22535, 1.67824, 2.22735, 2.88443,
3.66294, 4.57845, 5.64911, 6.89637, 8.34578, 10.0282, 11.9812, 14.2519, 16.8993, 20.0000};
static const G4double IF[nX]={0,
.017143, .072466, .172271, .323007, .531545, .805393, 1.15288, 1.58338, 2.10754, 2.73758,
3.48769, 4.37450, 5.41770, 6.64092, 8.07288, 9.74894, 11.7135, 14.0232, 16.7522, 20.0000};
static const G4double IG[nX]={0,
.015618, .066285, .158094, .297316, .490692, .745653, 1.07053, 1.47479, 1.96931, 2.56677,
3.28205, 4.13289, 5.14068, 6.33158, 7.73808, 9.40133, 11.3745, 13.7279, 16.5577, 20.0000};
static const G4double IH[nX]={0,
.013702, .058434, .139923, .264115, .437466, .667179, .961433, 1.32965, 1.78283, 2.33399,
2.99871, 3.79596, 4.74916, 5.88771, 7.24937, 8.88367, 10.8576, 13.2646, 16.2417, 20.0000};
static const G4double II[nX]={0,
.011264, .048311, .116235, .220381, .366634, .561656, .813132, 1.13008, 1.52322, 2.00554,
2.59296, 3.30542, 4.16834, 5.21490, 6.48964, 8.05434, 9.99835, 12.4580, 15.6567, 20.0000};
static const G4double IJ[nX]={0,
.008628, .037206, .089928, .171242, .286114, .440251, .640343, .894382, 1.21208, 1.60544,
2.08962, 2.68414, 3.41486, 4.31700, 5.44048, 6.85936, 8.69067, 11.1358, 14.5885, 20.0000};
static const G4double* Il[nE]=
{I0,I1,I2,I3,I4,I5,I6,I7,I8,I9,IA,IB,IC,ID,IE,IF,IG,IH,II,IJ};
static const G4double lE[nE]={
-1.98842,-1.58049,-1.17256,-.764638,-.356711, .051215, .459141, .867068, 1.27499, 1.68292,
2.09085, 2.49877, 2.90670, 3.31463, 3.72255, 4.13048, 4.53840, 4.94633, 5.35426, 5.76218};
static const G4double lEmi=lE[0];
static const G4double lEma=lE[nE-1];
static const G4double dlE=(lEma-lEmi)/bE;
//***************************************************************************************
G4double Enu=lastE; // Get energy of the last calculated cross-section
G4double lEn=std::log(Enu); // log(E) for interpolation
G4double rE=(lEn-lEmi)/dlE; // Position of the energy
G4int fE=static_cast<int>(rE); // Left bin for interpolation
if(fE<0) fE=0;
if(fE>pE)fE=pE;
G4int sE=fE+1; // Right bin for interpolation
G4double dE=rE-fE; // relative log shift from the left bin
G4double dEnu=Enu+Enu; // doubled energy of nu/anu
G4double Enu2=Enu*Enu; // squared energy of nu/anu
G4double Ee=Enu-me; // Free Energy of neutrino/anti-neutrino
G4double ME=Enu*MN; // M*E
G4double dME=ME+ME; // 2*M*E
G4double dEMN=(dEnu+MN)*ME;
G4double MEm=ME-hme2;
G4double sqE=Enu*std::sqrt(MEm*MEm-me2*MN2);
G4double E2M=MN*Enu2-(Enu+MN)*hme2;
G4double ymax=(E2M+sqE)/dEMN;
G4double ymin=(E2M-sqE)/dEMN;
G4double rmin=1.-ymin;
G4double rhm2E=hme2/Enu2;
G4double Q2mi=(Enu2+Enu2)*(rmin-rhm2E-std::sqrt(rmin*rmin-rhm2E-rhm2E)); // Q2_min(E_nu)
G4double Q2ma=dME*ymax; // Q2_max(E_nu)
G4double Q2nq=Ee*dMN-mcV;
if(Q2ma>Q2nq) Q2ma=Q2nq; // Correction for Non Quasi Elastic
// --- now r_min=Q2mi/Q2ma and r_max=1.; when r is randomized -> Q2=r*Q2ma ---
G4double Rmi=Q2mi/Q2ma;
G4double shift=.875/(1.+.2977/Enu/Enu)/std::pow(Enu,.78);
// --- E-interpolation must be done in a log scale ---
G4double Xmi=std::pow((shift-Rmi),power);// X_min(E_nu)
G4double Xma=std::pow((shift-1.),power); // X_max(E_nu)
// Find the integral values integ(Xmi) & integ(Xma) using the direct table
G4double idX=dX[fE]+dE*(dX[sE]-dX[fE]); // interpolated X step
G4double iXmi=Xmin[fE]+dE*(Xmin[sE]-Xmin[fE]); // interpolated X minimum
G4double rXi=(Xmi-iXmi)/idX;
G4int iXi=static_cast<int>(rXi);
if(iXi<0) iXi=0;
if(iXi>bX) iXi=bX;
G4double dXi=rXi-iXi;
G4double bntil=Il[fE][iXi];
G4double intil=bntil+dXi*(Il[fE][iXi+1]-bntil);
G4double bntir=Il[sE][iXi];
G4double intir=bntir+dXi*(Il[sE][iXi+1]-bntir);
G4double inti=intil+dE*(intir-intil);// interpolated begin of the integral
//
G4double rXa=(Xma-iXmi)/idX;
G4int iXa=static_cast<int>(rXa);
if(iXa<0) iXa=0;
if(iXa>bX) iXa=bX;
G4double dXa=rXa-iXa;
G4double bntal=Il[fE][iXa];
G4double intal=bntal+dXa*(Il[fE][iXa+1]-bntal);
G4double bntar=Il[sE][iXa];
G4double intar=bntar+dXa*(Il[sE][iXa+1]-bntar);
G4double inta=intal+dE*(intar-intal);// interpolated end of the integral
//
// *** Find X using the reversed table ***
G4double intx=inti+(inta-inti)*G4UniformRand();
G4int intc=static_cast<int>(intx);
if(intc<0) intc=0;
if(intc>bX) intc=bX;
G4double dint=intx-intc;
G4double mXl=Xl[fE][intc];
G4double Xlb=mXl+dint*(Xl[fE][intc+1]-mXl);
G4double mXr=Xl[sE][intc];
G4double Xrb=mXr+dint*(Xl[sE][intc+1]-mXr);
G4double X=Xlb+dE*(Xrb-Xlb); // interpolated X value
G4double R=shift-std::pow(X,pconv);
G4double Q2=R*Q2ma;
return Q2*GeV*GeV;
}
// It returns a fraction of the direct interaction of the neutrino with quark-partons
G4double G4QANuENuclearCrossSection::GetDirectPart(G4double Q2)
{
G4double f=Q2/4.62;
G4double ff=f*f;
G4double r=ff*ff;
G4double s=std::pow((1.+.6/Q2),(-1.-(1.+r)/(12.5+r/.3)));
//@@ It is the same for nu/anu, but for nu it is a bit less, and for anu a bit more (par)
return 1.-s*(1.-s/2);
}
// #of quark-partons in the nonperturbative phase space is the same for neut and anti-neut
G4double G4QANuENuclearCrossSection::GetNPartons(G4double Q2)
{
return 3.+.3581*std::log(1.+Q2/.04); // a#of partons in the nonperturbative phase space
}
// This class can provide only virtual exchange pi+ (a substitute for W+ boson)
G4int G4QANuENuclearCrossSection::GetExchangePDGCode() {return -211;}
@@ -24,8 +24,8 @@
// ********************************************************************
//
//
// $Id: G4QANuMuNuclearCrossSection.cc,v 1.9 2006/12/01 10:57:46 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4QANuMuNuclearCrossSection.cc,v 1.11 2007/11/01 16:09:38 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
//
// G4 Physics class: G4QANuMuNuclearCrossSection for gamma+A cross sections
@@ -38,8 +38,8 @@
// ****************************************************************************************
//===============================================================================================
///#define debug
#define edebug
//#define debug
//#define edebug
//#define pdebug
//#define ppdebug
//#define tdebug
@@ -85,7 +85,7 @@ G4double G4QANuMuNuclearCrossSection::GetCrossSection(G4bool fCS, G4double pMom,
static std::vector <G4double> colCS; // Vector of last cross sections for the reaction
// ***---*** End of the mandatory Static Definitions of the Associative Memory ***---***
G4double pEn=pMom;
#ifdef pdebug
#ifdef debug
G4cout<<"G4QAMNCS::GetCS:>> f="<<fCS<<", p="<<pMom<<", Z="<<tgZ<<"("<<lastZ<<") ,N="<<tgN
<<"("<<lastN<<"),PDG="<<pPDG<<"("<<lastPDG<<"), T="<<pEn<<"("<<lastTH<<")"<<",Sz="
<<colN.size()<<G4endl;
@@ -93,7 +93,7 @@ G4double G4QANuMuNuclearCrossSection::GetCrossSection(G4bool fCS, G4double pMom,
#endif
if(pPDG!=-14)
{
#ifdef pdebug
#ifdef debug
G4cout<<"G4QAMNCS::GetCS: *** Found pPDG="<<pPDG<<" ====> CS=0"<<G4endl;
//CalculateCrossSection(fCS,-27,j,lastPDG,lastZ,lastN,pMom); // DUMMY TEST
#endif
@@ -265,7 +265,7 @@ G4double G4QANuMuNuclearCrossSection::CalculateCrossSection(G4bool CS, G4int F,
G4int , G4int targZ, G4int targN, G4double Momentum)
{
static const G4double mb38=1.E-11;// Conversion 10^-38 cm^2 to mb=10^-27 cm^2
static const G4int nE=33; // !! If change this, change it in GetFunctions() (*.hh) !!
static const G4int nE=65; // !! If change this, change it in GetFunctions() (*.hh) !!
static const G4int mL=nE-1;
static const G4double mN=.931494043;// Nucleon mass (inside nucleus, AtomicMassUnit, GeV)
static const G4double dmN=mN+mN; // Doubled nucleon mass (2*AtomicMassUnit, GeV)
@@ -332,7 +332,7 @@ G4double G4QANuMuNuclearCrossSection::CalculateCrossSection(G4bool CS, G4int F,
{
G4int newran=ran/2;
if(lastE<=lastEN[sep]) sep-=newran;
else if(newran>1) sep+=newran;
else sep+=newran;
ran=newran;
chk=chk+chk;
}
@@ -379,22 +379,32 @@ G4int G4QANuMuNuclearCrossSection::GetFunctions (G4int z, G4int n,
static const G4double mmu=.105658369; // Mass of a muon in GeV
static const G4double mmu2=mmu*mmu; // Squared mass of a muon in GeV^2
static const G4double thresh=mmu+mmu2/dmN; // Universal threshold in GeV
static const G4int nE=33; // !! If change this, change it in GetCrossSection() (*.cc) !!
static const G4int nE=65; // !! If change this, change it in GetCrossSection() (*.cc) !!
static const G4double nuEn[nE]={thresh,
0.112443, 0.121027, 0.130968, 0.142546, 0.156109, 0.172102, 0.191090, 0.213802,
0.241183, 0.274476, 0.315330, 0.365955, 0.429353, 0.509647, 0.612580, 0.746264,
0.922326, 1.157700, 1.477470, 1.919460, 2.541810, 3.435700, 4.747300, 6.716420,
9.746220, 14.53270, 22.31170, 35.34420, 57.90250, 98.34160, 173.6130, 319.4900};
.112039,.116079,.120416,.125076,.130090,.135494,.141324,.147626,.154445,.161838,
.169864,.178594,.188105,.198485,.209836,.222272,.235923,.250941,.267497,.285789,
.306045,.328530,.353552,.381466,.412689,.447710,.487101,.531538,.581820,.638893,
.703886,.778147,.863293,.961275,1.07445,1.20567,1.35843,1.53701,1.74667,1.99390,
2.28679,2.63542,3.05245,3.55386,4.15990,4.89644,5.79665,6.90336,8.27224,9.97606,
12.1106,14.8029,18.2223,22.5968,28.2351,35.5587,45.1481,57.8086,74.6682,97.3201,
128.036,170.085,228.220,309.420};
static const G4double TOTX[nE]={0.,
0.084587, 0.288685, 0.410021, 0.511290, 0.602236, 0.686143, 0.764097, 0.836055,
0.901224, 0.958271, 1.005510, 1.041180, 1.063760, 1.072400, 1.067220, 1.049490,
1.021490, 0.986186, 0.946382, 0.905672, 0.866103, 0.828985, 0.795853, 0.766550,
0.740733, 0.717822, 0.697109, 0.677882, 0.659543, 0.641549, 0.622752, 0.603635};
.077498,.247583,.329691,.386384,.429087,.462699,.489899,.512316,.530996,.546614,
.559616,.570292,.578840,.585395,.590053,.593083,.594197,.593614,.591396,.587611,
.582335,.575653,.567667,.558490,.548417,.537270,.525352,.512825,.499857,.486620,
.473283,.460014,.446970,.434294,.422116,.410656,.399782,.389665,.380349,.371860,
.364207,.357387,.351388,.346192,.341778,.338122,.335198,.332980,.331439,.330544,
.330263,.330558,.331391,.332718,.334494,.336667,.339182,.341697,.344470,.348125,
.351322,.354481,.357507,.359239};
static const G4double QELX[nE]={0.,
.0095112, .0349388, .0536998, .0728821, .0940146, .1180870, .1460120, .1787500,
.2173600, .2627240, .3122570, .3633810, .4144780, .4639300, .5103820, .5520940,
.5873830, .6154440, .6358140, .6496310, .6580280, .6629570, .6655750, .6671860,
.6680500, .6687700, .6692590, .6694790, .6697380, .6699010, .6700020, .6699120};
.008683,.028739,.039700,.048327,.055820,.062693,.069235,.075631,.082010,.088463,
.095059,.101851,.108883,.116192,.123814,.131826,.140185,.148962,.158197,.167933,
.178221,.189119,.200700,.213045,.226326,.240454,.255277,.270612,.286388,.302608,
.319318,.336582,.354468,.373031,.392427,.412445,.433146,.454448,.476222,.498289,
.520430,.542558,.564130,.585003,.604928,.623680,.641266,.657255,.671704,.684586,
.696111,.706028,.714553,.721951,.728085,.733182,.737348,.740958,.743716,.746059,
.747806,.749129,.750331,.751100};
// --------------------------------
G4int first=0;
if(z<0.)
@@ -756,4 +766,4 @@ G4double G4QANuMuNuclearCrossSection::GetNPartons(G4double Q2)
}
// This class can provide only virtual exchange pi+ (a substitute for W+ boson)
G4int G4QANuMuNuclearCrossSection::GetExchangePDGCode() {return 211;}
G4int G4QANuMuNuclearCrossSection::GetExchangePDGCode() {return -211;}
@@ -24,7 +24,7 @@
// ********************************************************************
//
// $Id: G4QAtomicElectronScattering.cc,v 1.2 2006/12/13 15:45:19 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QAtomicElectronScattering class -----------------
// by Mikhail Kossov, December 2003.
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4QCaptureAtRest.cc,v 1.12 2007/04/20 15:50:56 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4QCaptureAtRest.cc,v 1.13 2007/10/02 10:00:37 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCaptureAtRest class -----------------
// by Mikhail Kossov, December 2003.
@@ -305,6 +305,7 @@ G4VParticleChange* G4QCaptureAtRest::AtRestDoIt(const G4Track& track, const G4St
#ifdef debug
G4cout<<"G4QCaptureAtRest::AtRestDoIt: projPDG="<<projPDG<<", targPDG="<<targPDG<<G4endl;
#endif
G4double weight = track.GetWeight();
G4double localtime = track.GetGlobalTime();
G4ThreeVector position = track.GetPosition();
#ifdef debug
@@ -497,6 +498,7 @@ G4VParticleChange* G4QCaptureAtRest::AtRestDoIt(const G4Track& track, const G4St
else theSec = new G4DynamicParticle(G4Gamma::Gamma(),RndmDir(),-ener);
totLV-=theSec->Get4Momentum();
G4Track* aNewTrack = new G4Track(theSec, localtime, position );
aNewTrack->SetWeight(weight); // weighted
aNewTrack->SetTouchableHandle(trTouchable);
cascT->push_back(aNewTrack);
}
@@ -697,6 +699,7 @@ G4VParticleChange* G4QCaptureAtRest::AtRestDoIt(const G4Track& track, const G4St
else theSec = new G4DynamicParticle(G4Gamma::Gamma(),RndmDir(),-ener);
projLV-=theSec->Get4Momentum();
G4Track* aNewTrack = new G4Track(theSec, localtime, position );
aNewTrack->SetWeight(weight); // weighted
aNewTrack->SetTouchableHandle(trTouchable);
cascT->push_back(aNewTrack);
}
@@ -867,6 +870,7 @@ G4VParticleChange* G4QCaptureAtRest::AtRestDoIt(const G4Track& track, const G4St
G4cout<<"G4QCapAtRest::AtRDoIt:p="<<curD<<curD.mag()<<",e="<<curE<<",m="<<curM<<G4endl;
#endif
G4Track* aNewTrack = new G4Track(theSec, localtime, position );
aNewTrack->SetWeight(weight); // weighted
aNewTrack->SetTouchableHandle(trTouchable);
aParticleChange.AddSecondary( aNewTrack );
#ifdef debug
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4QCoherentChargeExchange.cc,v 1.3 2007/05/23 15:14:25 mkossov Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4QCoherentChargeExchange.cc,v 1.5 2007/10/02 10:00:37 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCoherentChargeExchange class -----------------
// by Mikhail Kossov, December 2003.
@@ -408,8 +408,9 @@ G4VParticleChange* G4QCoherentChargeExchange::PostStepDoIt(const G4Track& track,
#ifdef debug
G4cout<<"G4QCoherentChargeExchange::PostStepDoIt: track is initialized"<<G4endl;
#endif
G4double localtime = track.GetGlobalTime();
G4ThreeVector position = track.GetPosition();
G4double weight = track.GetWeight();
G4double localtime = track.GetGlobalTime();
G4ThreeVector position = track.GetPosition();
#ifdef debug
G4cout<<"G4QCoherentChargeExchange::PostStepDoIt: before Touchable extraction"<<G4endl;
#endif
@@ -510,6 +511,7 @@ G4VParticleChange* G4QCoherentChargeExchange::PostStepDoIt(const G4Track& track,
EnMomConservation-=scat4M;
theSec->Set4Momentum(scat4M);
G4Track* aNewTrack = new G4Track(theSec, localtime, position );
aNewTrack->SetWeight(weight); // weighted
aNewTrack->SetTouchableHandle(trTouchable);
aParticleChange.AddSecondary( aNewTrack );
// Filling the recoil nucleus
@@ -537,6 +539,7 @@ G4VParticleChange* G4QCoherentChargeExchange::PostStepDoIt(const G4Track& track,
#endif
// Make a recoil nucleus
aNewTrack = new G4Track(theSec, localtime, position );
aNewTrack->SetWeight(weight); // weighted
aNewTrack->SetTouchableHandle(trTouchable);
aParticleChange.AddSecondary( aNewTrack );
#ifdef debug
@@ -551,6 +554,7 @@ G4double G4QCoherentChargeExchange::CalculateXSt(G4bool oxs, G4bool xst, G4doubl
static G4bool init=false;
static G4bool first=true;
static G4VQCrossSection* CSmanager;
G4QuasiFreeRatios* qfMan=G4QuasiFreeRatios::GetPointer();
if(first) // Connection with a singletone
{
CSmanager=G4QElasticCrossSection::GetPointer();
@@ -560,12 +564,12 @@ G4double G4QCoherentChargeExchange::CalculateXSt(G4bool oxs, G4bool xst, G4doubl
if(oxs && xst) // Only the Cross-Section can be returened
{
res=CSmanager->GetCrossSection(true, p, Z, N, pPDG); // XS for isotope
res*=ChExElCoef(p, Z, N, pPDG);
res*=qfMan->ChExElCoef(p*MeV, Z, N, pPDG);
}
else if(!oxs && xst) // Calculate Cross-Section & prepare differential
{
res=CSmanager->GetCrossSection(false, p, Z, N, pPDG);// XS for isotope + init t-distr.
res*=ChExElCoef(p, Z, N, pPDG); // @@ is that necessary?
res*=qfMan->ChExElCoef(p*MeV, Z, N, pPDG);
// The XS for the nucleus must be calculated the last
init=true;
}
@@ -577,23 +581,3 @@ G4double G4QCoherentChargeExchange::CalculateXSt(G4bool oxs, G4bool xst, G4doubl
else G4cout<<"*Warning*G4QCohChrgExchange::CalculateXSt: NotInitiatedScattering"<<G4endl;
return res;
}
G4double G4QCoherentChargeExchange::ChExElCoef(G4double p, G4int Z, G4int N, G4int pPDG)
{
G4double A=Z+N;
if(A<1.5) return 0.;
G4double C=0.;
if (pPDG==2212) C=N/A;
else if(pPDG==2112) C=Z/A;
else G4cout<<"*Warning*G4QCohChrgExchange::ChExElCoef: wrong PDG="<<pPDG<<G4endl;
C*=C; // Coherent processes squares the amplitude
// @@ This is true only for nucleons: other projectiles must be treated differently
G4double sp=std::sqrt(p);
G4double p2=p*p;
G4double p4=p2*p2;
G4double dl1=std::log(p)-5.;
G4double T=(6.75+.14*dl1*dl1+13./p)/(1.+.14/p4)+.6/(p4+.00013);
G4double U=(6.25+8.33e-5/p4/p)*(p*sp+.34)/p2/p;
G4double R=U/T;
return C*R*R;
}
@@ -23,8 +23,8 @@
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4QCollision.cc,v 1.19 2007/05/02 14:59:57 gunter Exp $
// GEANT4 tag $Name: geant4-09-00 $
// $Id: G4QCollision.cc,v 1.24 2007/11/01 16:09:38 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QCollision class -----------------
// by Mikhail Kossov, December 2003.
@@ -37,6 +37,7 @@
//#define debug
//#define pdebug
//#define ppdebug
//#define qedebug
#include "G4QCollision.hh"
@@ -156,6 +157,7 @@ G4double G4QCollision::GetMeanFreePath(const G4Track& aTrack,G4double,G4ForceCon
#endif
G4bool leptoNuc=false; // By default the reaction is not lepto-nuclear
G4VQCrossSection* CSmanager=0;
G4VQCrossSection* CSmanager2=0;
G4int pPDG=0;
if(incidentParticleDefinition == G4Proton::Proton())
{
@@ -191,15 +193,31 @@ G4double G4QCollision::GetMeanFreePath(const G4Track& aTrack,G4double,G4ForceCon
else if(incidentParticleDefinition == G4NeutrinoMu::NeutrinoMu() )
{
CSmanager=G4QNuMuNuclearCrossSection::GetPointer();
CSmanager2=G4QNuNuNuclearCrossSection::GetPointer();
leptoNuc=true;
pPDG=14;
}
else if(incidentParticleDefinition == G4AntiNeutrinoMu::AntiNeutrinoMu() )
{
CSmanager=G4QANuMuNuclearCrossSection::GetPointer();
CSmanager2=G4QANuANuNuclearCrossSection::GetPointer();
leptoNuc=true;
pPDG=-14;
}
else if(incidentParticleDefinition == G4NeutrinoE::NeutrinoE() )
{
CSmanager=G4QNuENuclearCrossSection::GetPointer();
CSmanager2=G4QNuNuNuclearCrossSection::GetPointer();
leptoNuc=true;
pPDG=12;
}
else if(incidentParticleDefinition == G4AntiNeutrinoE::AntiNeutrinoE() )
{
CSmanager=G4QANuENuclearCrossSection::GetPointer();
CSmanager2=G4QANuANuNuclearCrossSection::GetPointer();
leptoNuc=true;
pPDG=-12;
}
else G4cout<<"G4QCollision::GetMeanFreePath:Particle isn't implemented in CHIPS"<<G4endl;
G4QIsotope* Isotopes = G4QIsotope::Get(); // Pointer to the G4QIsotopes singleton
@@ -271,6 +289,7 @@ G4double G4QCollision::GetMeanFreePath(const G4Track& aTrack,G4double,G4ForceCon
G4int N=curIs->first; // #of Neuterons in the isotope j of El i
IsN->push_back(N); // Remember Min N for the Element
G4double CSI=CSmanager->GetCrossSection(true,Momentum,Z,N,pPDG);//CS(j,i) for isotope
if(CSmanager2)CSI+=CSmanager2->GetCrossSection(true,Momentum,Z,N,pPDG);//CS(j,i)nu,nu
#ifdef debug
G4cout<<"GQC::GMF:X="<<CSI<<",M="<<Momentum<<",Z="<<Z<<",N="<<N<<",P="<<pPDG<<G4endl;
#endif
@@ -293,7 +312,7 @@ G4double G4QCollision::GetMeanFreePath(const G4Track& aTrack,G4double,G4ForceCon
incidentParticleDefinition == G4TauMinus::TauMinus() ||
incidentParticleDefinition == G4TauPlus::TauPlus() )
sigma*=photNucBias;
if(photNucBias!=1.) if(incidentParticleDefinition==G4NeutrinoE::NeutrinoE() ||
if(weakNucBias!=1.) if(incidentParticleDefinition==G4NeutrinoE::NeutrinoE() ||
incidentParticleDefinition==G4AntiNeutrinoE::AntiNeutrinoE() ||
incidentParticleDefinition==G4NeutrinoTau::NeutrinoTau() ||
incidentParticleDefinition==G4AntiNeutrinoTau::AntiNeutrinoTau()||
@@ -314,9 +333,11 @@ G4bool G4QCollision::IsApplicable(const G4ParticleDefinition& particle)
else if (particle == *( G4Electron::Electron() )) return true;
else if (particle == *( G4Positron::Positron() )) return true;
else if (particle == *( G4Gamma::Gamma() )) return true;
//else if (particle == *( G4Proton::Proton() )) return true;
else if (particle == *( G4Proton::Proton() )) return true;
else if (particle == *( G4AntiNeutrinoE::AntiNeutrinoE() )) return true;
else if (particle == *( G4NeutrinoE::NeutrinoE() )) return true;
else if (particle == *(G4AntiNeutrinoMu::AntiNeutrinoMu())) return true;
else if (particle == *( G4NeutrinoMu::NeutrinoMu() )) return true;
else if (particle == *( G4NeutrinoMu::NeutrinoMu() )) return true;
//else if (particle == *( G4Neutron::Neutron() )) return true;
//else if (particle == *( G4PionMinus::PionMinus() )) return true;
//else if (particle == *( G4PionPlus::PionPlus() )) return true;
@@ -333,6 +354,8 @@ G4bool G4QCollision::IsApplicable(const G4ParticleDefinition& particle)
//else if (particle == *( G4OmegaMinus::OmegaMinus() )) return true;
//else if (particle == *( G4AntiNeutron::AntiNeutron() )) return true;
//else if (particle == *( G4AntiProton::AntiProton() )) return true;
//else if (particle == *(G4AntiNeutrinoTau::AntiNeutrinoTau())) return true;
//else if (particle == *( G4NeutrinoTau::NeutrinoTau() )) return true;
#ifdef debug
G4cout<<"***G4QCollision::IsApplicable: PDG="<<particle.GetPDGEncoding()<<G4endl;
#endif
@@ -351,33 +374,61 @@ G4VParticleChange* G4QCollision::PostStepDoIt(const G4Track& track, const G4Step
//static const G4double dpi=M_PI+M_PI; // 2*pi (for Phi distr.) ***changed to twopi***
static const G4double mNeut= G4QPDGCode(2112).GetMass();
static const G4double mNeut2= mNeut*mNeut;
static const G4double muN= mNeut+mu;
static const G4double muN2= muN*muN;
static const G4double fmuN= 4*mNeut2*mu2;
static const G4double musN= mNeut2+mu2;
static const G4double mProt= G4QPDGCode(2212).GetMass();
static const G4double mProt2= mProt*mProt;
static const G4double muP= mProt+mu;
static const G4double muP2= muP*muP;
static const G4double fmuP= 4*mProt2*mu2;
static const G4double musP= mProt2+mu2;
static const G4double dM=mProt+mNeut; // doubled nucleon mass
static const G4double mudM=mu2/dM; // for x limit
static const G4double hdM=dM/2.; // M of the "nucleon"
static const G4double hdM2=hdM*hdM; // M2 of the "nucleon"
static const G4double mPi0 = G4QPDGCode(111).GetMass();
static const G4double mPi0s= mPi0*mPi0;
//static const G4double mDeut= G4QPDGCode(2112).GetNuclMass(1,1,0);
static const G4double mDeut= G4QPDGCode(2112).GetNuclMass(1,1,0);// Mass of deuteron
static const G4double mTrit= G4QPDGCode(2112).GetNuclMass(1,2,0);// Mass of tritium
static const G4double mHel3= G4QPDGCode(2112).GetNuclMass(2,1,0);// Mass of Helium3
static const G4double mAlph= G4QPDGCode(2112).GetNuclMass(2,2,0);// Mass of alpha
static const G4double mPi = G4QPDGCode(211).GetMass();
static const G4double tmPi = mPi+mPi; // Doubled mass of the charged pion
static const G4double stmPi= tmPi*tmPi; // Squared Doubled mass of the charged pion
static const G4double mPPi = mPi+mProt; // Delta threshold
//static const G4double mPPi2= mPPi*mPPi; // Delta low threshold for W2
static const G4double mPPi2= mPPi*mPPi; // Delta low threshold for W2
//static const G4double mDel2= 1400*1400; // Delta up threshold for W2 (in MeV^2)
static const G4double muD = mPPi+mu; // Multiperipheral threshold
static const G4double muD2 = muD*muD;
// Static definitions for electrons (nu,e) -----------------------------------------
static const G4double meN = mNeut+me;
static const G4double meN2= meN*meN;
static const G4double fmeN= 4*mNeut2*me2;
static const G4double mesN= mNeut2+me2;
static const G4double meP = mProt+me;
static const G4double meP2= meP*meP;
static const G4double fmeP= 4*mProt2*me2;
static const G4double mesP= mProt2+me2;
static const G4double medM= me2/dM; // for x limit
static const G4double meD = mPPi+me; // Multiperipheral threshold
static const G4double meD2= meD*meD;
// Static definitions for muons (nu,mu) -----------------------------------------
static const G4double muN = mNeut+mu;
static const G4double muN2= muN*muN;
static const G4double fmuN= 4*mNeut2*mu2;
static const G4double musN= mNeut2+mu2;
static const G4double muP = mProt+mu;
static const G4double muP2= muP*muP; // +
static const G4double fmuP= 4*mProt2*mu2; // +
static const G4double musP= mProt2+mu2;
static const G4double mudM= mu2/dM; // for x limit
static const G4double muD = mPPi+mu; // Multiperipheral threshold
static const G4double muD2= muD*muD;
// Static definitions for muons (nu,nu) -----------------------------------------
//static const G4double nuN = mNeut;
//static const G4double nuN2= mNeut2;
//static const G4double fnuN= 0.;
//static const G4double nusN= mNeut2;
//static const G4double nuP = mProt;
//static const G4double nuP2= mProt2;
//static const G4double fnuP= 0.;
//static const G4double nusP= mProt2;
//static const G4double nudM= 0.; // for x limit
//static const G4double nuD = mPPi; // Multiperipheral threshold
//static const G4double nuD2= mPPi2;
//-------------------------------------------------------------------------------------
static G4bool CWinit = true; // CHIPS Warld needs to be initted
static G4bool CWinit = true; // CHIPS Warld needs to be initted
if(CWinit)
{
CWinit=false;
@@ -394,9 +445,9 @@ G4VParticleChange* G4QCollision::PostStepDoIt(const G4Track& track, const G4Step
#ifdef debug
G4cout<<"G4QCollision::PostStepDoIt: After the GetMeanFreePath is called"<<G4endl;
#endif
G4bool scat=false;
G4int scatPDG=0; // Must be filled if true
G4LorentzVector proj4M=projHadron->Get4Momentum();
G4bool scat=false; // No CHEX in proj scattering
G4int scatPDG=0; // Must be filled if true (CHEX)
G4LorentzVector proj4M=projHadron->Get4Momentum(); // 4-momentum of the projectile (IU?)
G4LorentzVector scat4M=proj4M; // Must be filled if true
G4double momentum = projHadron->GetTotalMomentum(); // 3-momentum of the Particle
G4double Momentum=proj4M.rho();
@@ -534,19 +585,23 @@ G4VParticleChange* G4QCollision::PostStepDoIt(const G4Track& track, const G4Step
return 0;
}
aParticleChange.Initialize(track);
G4double weight = track.GetWeight();
if(photNucBias!=1.) weight/=photNucBias;
else if(weakNucBias!=1.) weight/=weakNucBias;
G4double localtime = track.GetGlobalTime();
G4ThreeVector position = track.GetPosition();
G4TouchableHandle trTouchable = track.GetTouchableHandle();
//
G4int targPDG=90000000+Z*1000+N; // PDG Code of the target nucleus
G4QPDGCode targQPDG(targPDG);
G4double tM=targQPDG.GetMass(); // Target mass
G4double tgM=targQPDG.GetMass(); // Target mass
G4double tM=tgM; // Target mass (copy to be changed)
G4QHadronVector* output=new G4QHadronVector;// Prototype of EnvironOutput G4QHadronVector
G4double absMom = 0.; // Prototype of absorbed by nucleus Moment
G4QHadronVector* leadhs=new G4QHadronVector;// Prototype of QuasmOutput G4QHadronVectorum
G4LorentzVector lead4M(0.,0.,0.,0.); // Prototype of LeadingQ 4-momentum
if(aProjPDG==11 || aProjPDG==13 || aProjPDG==15) // leptons with photonuclear
{ // Lepto-nuclear case with the equivalent photon algorithm. @@InFuture + neutrino & QE
{ // Lepto-nuclear case with the equivalent photon algorithm. @@InFuture + NC (?)
#ifdef debug
G4cout<<"G4QCollision::PostStDoIt:startSt="<<aParticleChange.GetTrackStatus()<<G4endl;
#endif
@@ -738,27 +793,75 @@ G4VParticleChange* G4QCollision::PostStepDoIt(const G4Track& track, const G4Step
<<proj4M<<", lE="<<finE<<", lP="<<finP*findir<<", d="<<findir.mag2()<<G4endl;
#endif
}
else if(aProjPDG==14)// ** neutrino nuclear interactions (only nu_mu/anu_mu & only CC) **
else if(aProjPDG==12||aProjPDG==14) //neutrinoNuclear interactions
{
G4double kinEnergy= projHadron->GetKineticEnergy();// For neutrino this is total energy
G4double kinEnergy= projHadron->GetKineticEnergy()/MeV; // Total energy of the neutrino
G4double dKinE=kinEnergy+kinEnergy; // doubled energy for s calculation
#ifdef debug
G4cout<<"G4QCollision::PostStDoIt: 2*nuEnergy="<<dKinE<<"(MeV), PDG="<<projPDG<<G4endl;
#endif
G4ParticleMomentum dir = projHadron->GetMomentumDirection(); // unit vector
G4VQCrossSection* CSmanager=G4QNuMuNuclearCrossSection::GetPointer();
G4double ml = mu;
G4double ml2 = mu2;
//G4double mlN = muN;
G4double mlN2= muN2;
G4double fmlN= fmuN;
G4double mlsN= musN;
//G4double mlP = muP;
G4double mlP2= muP2;
G4double fmlP= fmuP;
G4double mlsP= musP;
G4double mldM= mudM;
//G4double mlD = muD;
G4double mlD2= muD2;
if(aProjPDG==12)
{
ml = me;
ml2 = me2;
//mlN = meN;
mlN2= meN2;
fmlN= fmeN;
mlsN= mesN;
//mlP = meP;
mlP2= meP2;
fmlP= fmeP;
mlsP= mesP;
mldM= medM;
//mlD = meD;
mlD2= meD2;
}
G4VQCrossSection* CSmanager =G4QNuMuNuclearCrossSection::GetPointer(); // (nu,l)
G4VQCrossSection* CSmanager2=G4QNuNuNuclearCrossSection::GetPointer(); // (nu,nu)
proj4M=G4LorentzVector(dir*kinEnergy,kinEnergy); // temporary
G4bool nuanu=true;
scatPDG=13; // Prototype = secondary scattered mu-
if(projPDG==-14)
{
nuanu=false;
CSmanager=G4QANuMuNuclearCrossSection::GetPointer(); // @@ open
nuanu=false; // Anti-neutrino
CSmanager=G4QANuMuNuclearCrossSection::GetPointer(); // (anu,mu+) CC @@ open
CSmanager=G4QANuANuNuclearCrossSection::GetPointer(); // (anu,anu) NC @@ open
scatPDG=-13; // secondary scattered mu+
}
else if(projPDG==12)
{
CSmanager=G4QNuENuclearCrossSection::GetPointer(); // @@ open (only CC is changed)
scatPDG=11; // secondary scattered e-
}
else if(projPDG==-12)
{
nuanu=false; // anti-neutrino
CSmanager=G4QANuENuclearCrossSection::GetPointer(); // (anu,e+) CC @@ open
CSmanager=G4QANuANuNuclearCrossSection::GetPointer(); // (anu,anu) NC @@ open
scatPDG=-11; // secondary scattered e+
}
// @@ Probably this is not necessary any more
G4double xSec=CSmanager->GetCrossSection(false,Momentum,Z,N,aProjPDG);//Recalculate XS
G4double xSec1=CSmanager->GetCrossSection(false,Momentum,Z,N,projPDG); //Recalculate XS
G4double xSec2=CSmanager2->GetCrossSection(false,Momentum,Z,N,projPDG);//Recalculate XS
G4double xSec=xSec1+xSec2;
// @@ check a possibility to separate p, n, or alpha (!)
if(xSec <= 0.) // The cross-section = 0 -> Do Nothing
{
G4cerr<<"-Warning-G4QCollision::PSDoIt: IsStillCalled nuE="<<kinEnergy<<G4endl;
G4cerr<<"G4QCollision::PSDoIt:nuE="<<kinEnergy<<",X1="<<xSec1<<",X2="<<xSec2<<G4endl;
//Do Nothing Action insead of the reaction
aParticleChange.ProposeEnergy(kinEnergy);
aParticleChange.ProposeLocalEnergyDeposit(0.);
@@ -766,115 +869,545 @@ G4VParticleChange* G4QCollision::PostStepDoIt(const G4Track& track, const G4Step
aParticleChange.ProposeTrackStatus(fAlive);
return G4VDiscreteProcess::PostStepDoIt(track,step);
}
scat=true; // event with changed scattered projectile
G4double totCS = CSmanager->GetLastTOTCS(); // the last total cross section (isotope?)
if(std::fabs(xSec-totCS)/xSec>.0001)
G4bool secnu=false;
if(xSec*G4UniformRand()>xSec1) // recover neutrino/antineutrino
{
if(scatPDG>0) scatPDG++;
else scatPDG--;
secnu=true;
}
scat=true; // event with changed scattered projectile
G4double totCS1 = CSmanager->GetLastTOTCS(); // the last total cross section1(isotope?)
G4double totCS2 = CSmanager2->GetLastTOTCS();// the last total cross section2(isotope?)
G4double totCS = totCS1+totCS2; // the last total cross section (isotope?)
if(std::fabs(xSec-totCS*millibarn)/xSec>.0001)
G4cout<<"-Warning-G4QCollision::PostStepDoIt: xS="<<xSec<<"# CS="<<totCS<<G4endl;
G4double qelCS = CSmanager->GetLastQELCS(); // the last total cross section
if(totCS - qelCS < 0.) totCS = qelCS; // only at low energies
// make different definitions for neutrino and antineutrino (inFuture for nue/anue too)
G4double mIN=mProt; // Just a prototype (for anu, Z=1, N=0)
G4double mOT=mNeut;
G4double OT=muN2;
G4double mOT2=mNeut2;
G4double muOT=fmuN;
G4double musOT=musN;
if(nuanu)
G4double qelCS1 = CSmanager->GetLastQELCS(); // the last quasi-elastic cross section1
G4double qelCS2 = CSmanager2->GetLastQELCS();// the last quasi-elastic cross section2
G4double qelCS = qelCS1+qelCS2; // the last quasi-elastic cross section
if(totCS - qelCS < 0.) // only at low energies
{
targPDG-=1;
totCS = qelCS;
totCS1 = qelCS1;
totCS2 = qelCS2;
}
// make different definitions for neutrino and antineutrino
G4double mIN=mProt; // Just a prototype (for anu, Z=1, N=0)
G4double mOT=mNeut;
G4double OT=mlN2;
G4double mOT2=mNeut2;
G4double mlOT=fmlN;
G4double mlsOT=mlsN;
if(secnu)
{
if(am*G4UniformRand()>Z) // Neutron target
{
targPDG-=1; // subtract neutron
projPDG=2112; // neutron is going out
mIN =mNeut;
OT =mNeut2;
mOT2=mNeut2;
mlOT=0.;
mlsOT=mNeut2;
}
else
{
targPDG-=1000; // subtract neutron
projPDG=2212; // neutron is going out
mOT =mProt;
OT =mProt2;
mOT2 =mProt2;
mlOT =0.;
mlsOT=mProt2;
}
ml=0.;
ml2=0.;
mldM=0.;
mlD2=mPPi2;
G4QPDGCode targQPDG(targPDG);
G4double rM=targQPDG.GetMass();
mIN=tM-rM; // bounded in-mass of the neutron
mIN=tM-rM; // bounded in-mass of the neutron
tM=rM;
}
else if(nuanu)
{
targPDG-=1; // Neutrino -> subtract neutron
G4QPDGCode targQPDG(targPDG);
G4double rM=targQPDG.GetMass();
mIN=tM-rM; // bounded in-mass of the neutron
tM=rM;
mOT=mProt;
OT=muP2;
OT=mlP2;
mOT2=mProt2;
muOT=fmuP;
musOT=musP;
projPDG=2212; // proton is going out
mlOT=fmlP;
mlsOT=mlsP;
projPDG=2212; // proton is going out
}
else
{
if(Z>1||N>0) // Calculate the splitted mass
if(Z>1||N>0) // Calculate the splitted mass
{
targPDG-=1000;
targPDG-=1000; // Anti-Neutrino -> subtract proton
G4QPDGCode targQPDG(targPDG);
G4double rM=targQPDG.GetMass();
mIN=tM-rM; // bounded in-mass of the proton
mIN=tM-rM; // bounded in-mass of the proton
tM=rM;
}
else targPDG=0;
projPDG=2112; // neutron is going out
else
{
targPDG=0;
mIN=tM;
tM=0.;
}
projPDG=2112; // neutron is going out
}
G4double s=mIN*(mIN+dKinE); // s=(M_cm)^2
if(s<=OT) // *** Do nothing solution ***
G4double s=mIN*(mIN+dKinE); // s=(M_cm)^2=m2+2mE (m=targetMass,E=E_nu)
#ifdef debug
G4cout<<"G4QCollision::PostStDoIt: s="<<s<<" >? OT="<<OT<<", mlD2="<<mlD2<<G4endl;
#endif
if(s<=OT) // *** Do nothing solution ***
{
//Do NothingToDo Action insead of the reaction (@@ Can we make it common?)
G4cout << "G4QCollision::PostStepDoIt: probability correction - DoNothing"<<G4endl;
G4cout<<"G4QCollision::PostStepDoIt: tooSmallFinalMassOfCompound: DoNothing"<<G4endl;
aParticleChange.ProposeEnergy(kinEnergy);
aParticleChange.ProposeLocalEnergyDeposit(0.);
aParticleChange.ProposeMomentumDirection(dir);
aParticleChange.ProposeTrackStatus(fAlive);
return G4VDiscreteProcess::PostStepDoIt(track,step);
}
if((!nuanu||N)&&totCS*G4UniformRand()<qelCS||s<muD2)// ****** Quasi-Elastic interaction
#ifdef debug
G4cout<<"G4QCollision::PostStDoIt: Stop and kill the projectile neutrino"<<G4endl;
#endif
aParticleChange.ProposeEnergy(0.);
aParticleChange.ProposeTrackStatus(fStopAndKill); // the initial neutrino is killed
// There is no way back from here
if((secnu||!nuanu||N)&&totCS*G4UniformRand()<qelCS||s<mlD2)// Quasi-Elastic interaction
{
G4double Q2=CSmanager->GetQEL_ExchangeQ2(); // OK, im MeV^2
G4double ds=s+s; // doubled s
G4double Q2=0.; // Simulate transferred momentum, in MeV^2
if(secnu) Q2=CSmanager2->GetQEL_ExchangeQ2();
else Q2=CSmanager->GetQEL_ExchangeQ2();
#ifdef debug
G4cout<<"G4QCollision::PostStDoIt:QuasiEl(nu="<<secnu<<"),s="<<s<<",Q2="<<Q2<<G4endl;
#endif
//G4double ds=s+s; // doubled s
G4double sqs=std::sqrt(s); // M_cm
G4double pi=(s-mIN*mIN)/(sqs+sqs); // initial momentum in CMS
G4double dsqs=sqs+sqs; // 2*M_cm
G4double pi=(s-mIN*mIN)/dsqs; // initial momentum in CMS (checked MK)
G4double dpi=pi+pi; // doubled initial momentum in CMS
G4double sd=s-musOT; // s-mu2-mOT2
G4double qo2=(sd*sd-muOT)/(ds+ds); // squared momentum of secondaries in CMS
G4double sd=s-mlsOT; // s-ml2-mOT2 (mlsOT=m^2_neut+m^2_lept)
G4double qo2=(sd*sd-mlOT)/dsqs; // squared momentum of secondaries in CMS
G4double qo=std::sqrt(qo2); // momentum of secondaries in CMS
G4double cost=(dpi*std::sqrt(qo2+mu2)-Q2-mu2)/dpi/qo; // cos(theta) in CMS
G4double cost=(dpi*std::sqrt(qo2+ml2)-Q2-ml2)/dpi/qo; // cos(theta) in CMS (chck MK)
G4LorentzVector t4M(0.,0.,0.,mIN); // 4mom of the effective target
G4LorentzVector c4M=t4M+proj4M; // 4mom of the compound system
t4M.setT(mOT); // now it is 4mom of the outgoing nucleon
scat4M=G4LorentzVector(0.,0.,0.,mu); // 4mom of the scattered muon
scat4M=G4LorentzVector(0.,0.,0.,ml); // 4mom of the scattered muon
if(!G4QHadron(c4M).RelDecayIn2(scat4M, t4M, proj4M, cost, cost))
{
G4cerr<<"G4QCol::PSD:c4M="<<c4M<<sqs<<",mM="<<mu<<",tM="<<mOT<<",c="<<cost<<G4endl;
throw G4QException("G4QCollision::HadronizeQuasm: Can't dec QE nu,mu Compound");
G4cerr<<"G4QCol::PSD:c4M="<<c4M<<sqs<<",mM="<<ml<<",tM="<<mOT<<",c="<<cost<<G4endl;
throw G4QException("G4QCollision::HadronizeQuasm: Can't dec QE nu,lept Compound");
}
proj4M=t4M; // 4mom of the new projectile nucleon
}
else // ***** Non Quasi Elastic interaction
{
G4double Q2=CSmanager->GetNQE_ExchangeQ2();
projPDG=CSmanager->GetExchangePDGCode();
if(secnu&&projPDG==2212||!secnu&&projPDG==2112) targPDG+=1; // Recover target PDG,
else if(secnu&&projPDG==2112||!secnu&&projPDG==2212) targPDG+=1000; // if not quasiEl
G4double Q2=0; // Simulate transferred momentum, in MeV^2
if(secnu) Q2=CSmanager->GetNQE_ExchangeQ2();
else Q2=CSmanager2->GetNQE_ExchangeQ2();
#ifdef debug
G4cout<<"G4QColl::PStDoIt: MultiPeriferal s="<<s<<",Q2="<<Q2<<",T="<<targPDG<<G4endl;
#endif
if(secnu) projPDG=CSmanager2->GetExchangePDGCode();// PDG Code of the effective gamma
else projPDG=CSmanager->GetExchangePDGCode(); // PDG Code of the effective pion
//@@ Temporary made only for direct interaction and for N=3 (good for small Q2)
//@@ inFuture use N=GetNPartons and directFraction=GetDirectPart, @@ W2...
G4double r=G4UniformRand();
G4double r1=0.5; // (1-x)
G4double r1=0.5; // (1-x)
if(r<0.5) r1=std::sqrt(r+r)*(.5+.1579*(r-.5));
else if(r>0.5) r1=1.-std::sqrt(2.-r-r)*(.5+.1579*(.5-r));
G4double xn=1.-mudM/Momentum; // Normalization of (1-x) [x>mudM/Mom]
G4double xn=1.-mldM/Momentum; // Normalization of (1-x) [x>mldM/Mom]
G4double x1=xn*r1; // (1-x)
G4double x=1.-x1; // x=2k/M
//G4double W2=(hdM2+Q2/x)*x1; // W2 candidate
G4double mx=hdM*x;
G4double we=(Q2/mx-mx)/2; // transfered energy
G4double muQ2=(mu2+Q2)/2;
G4double cost=(kinEnergy*we-muQ2)/kinEnergy/std::sqrt(we*we+Q2);
G4double mx=hdM*x; // Part of the target to interact with
G4double we=Q2/(mx+mx); // transfered energy
if(we>=kinEnergy-ml-.001) we=kinEnergy-ml-.0001; // safety to avoid nan=sqrt(neg)
G4double pot=kinEnergy-we; // energy of the secondary lepton
G4double mlQ2=ml2+Q2;
G4double cost=(pot-mlQ2/dKinE)/std::sqrt(pot*pot-ml2); // LS cos(theta)
if(std::fabs(cost)>1)
{
#ifdef debug
G4cout<<"*G4QCollision::PostStDoIt: cost="<<cost<<", Q2="<<Q2<<", nu="<<we<<", mx="
<<mx<<", pot="<<pot<<", 2KE="<<dKinE<<G4endl;
#endif
if(cost>1.) cost=1.;
else cost=-1.;
we=(muQ2*muQ2-kinEnergy*kinEnergy*Q2)/kinEnergy/(mu2+Q2); // minimum we
pot=mlQ2/dKinE+dKinE*ml2/mlQ2; // extreme output momentum
}
scat4M=G4LorentzVector(0.,0.,0.,mu); // 4mom of the scattered muon
G4LorentzVector t4M(0.,0.,0.,-Q2); // 4mom of the virtual W
G4LorentzVector dir4M=proj4M-G4LorentzVector(0.,0.,0.,proj4M.e()*.1);// projDirection
if(!G4QHadron(proj4M).RelDecayIn2(scat4M, t4M, dir4M, cost, cost))
G4double lEn=std::sqrt(pot*pot+ml2); // Lepton energy
G4double lPl=pot*cost; // Lepton longitudinal momentum
G4double lPt=pot*std::sqrt(1.-cost*cost); // Lepton transverse momentum
std::pair<G4double,G4double> d2d=Random2DDirection(); // Randomize phi
G4double lPx=lPt*d2d.first;
G4double lPy=lPt*d2d.second;
G4ThreeVector vdir=proj4M.vect(); // 3D momentum of the projectile
G4ThreeVector vz= vdir.unit(); // Ort in the direction of the projectile
G4ThreeVector vv= vz.orthogonal(); // Not normed orthogonal vector (!)
G4ThreeVector vx= vv.unit(); // First ort orthogonal to the direction
G4ThreeVector vy= vz.cross(vx); // Second ort orthoganal to the direction
G4ThreeVector lP= lPl*vz+lPx*vx+lPy*vy; // 3D momentum of the scattered lepton
scat4M=G4LorentzVector(lP,lEn); // 4mom of the scattered lepton
proj4M-=scat4M; // 4mom of the W/Z (effective pion/gamma)
#ifdef debug
G4cout<<"G4QCollision::PostStDoIt: proj4M="<<proj4M<<", ml="<<ml<<G4endl;
#endif
// Check that the en/mom transfer is possible, if not -> elastic
G4int fintPDG=targPDG; // Prototype for the compound nucleus
if(!secnu)
{
G4cerr<<"G4QCol::PSD:4M="<<proj4M<<",mM="<<mu<<",Q2="<<Q2<<",c="<<cost<<G4endl;
throw G4QException("G4Quasmon::HadronizeQuasm: Can't dec nu->mu+W");
if(projPDG<0) fintPDG-= 999;
else fintPDG+= 999;
}
G4double fM=G4QPDGCode(fintPDG).GetMass();// compound nucleus Mass (MeV)
G4double fM2=fM*fM;
G4LorentzVector tg4M=G4LorentzVector(0.,0.,0.,tgM);
G4LorentzVector c4M=tg4M+proj4M;
#ifdef debug
G4cout<<"G4QCol::PSDI:fM2="<<fM2<<" <? mc4M="<<c4M.m2()<<",dM="<<fM-tgM<<G4endl;
#endif
if(fM2>=c4M.m2()) // Elastic scattering should be done
{
G4LorentzVector tot4M=tg4M+proj4M+scat4M; // recover the total 4-momentum
s=tot4M.m2();
G4double fs=s-fM2-ml2;
G4double fMl=fM2*ml2;
G4double hQ2max=(fs*fs/2-fMl-fMl)/s; // Maximum possible Q2/2
G4double cost=1.-Q2/hQ2max; // cos(theta) in CMS (use MultProd Q2)
#ifdef debug
G4cout<<"G4QC::PSDI:ct="<<cost<<",Q2="<<Q2<<",hQ2="<<hQ2max<<",4M="<<tot4M<<G4endl;
#endif
G4double acost=std::fabs(cost);
if(acost>1.)
{
if(acost>1.001) G4cout<<"-Warning-G4QCollision::PostStDoIt: cost="<<cost<<G4endl;
if (cost> 1.) cost= 1.;
else if(cost<-1.) cost=-1.;
}
G4LorentzVector reco4M=G4LorentzVector(0.,0.,0.,fM); // 4mom of the recoilNucleus
scat4M=G4LorentzVector(0.,0.,0.,ml); // 4mom of the scatteredLepton
G4LorentzVector dir4M=tot4M-G4LorentzVector(0.,0.,0.,(tot4M.e()-ml)*.01);
if(!G4QHadron(tot4M).RelDecayIn2(scat4M, reco4M, dir4M, cost, cost))
{
G4cerr<<"G4QC::PSDI:t4M="<<tot4M<<",lM="<<ml<<",rM="<<fM<<",cost="<<cost<<G4endl;
//G4Exception("G4QCollision::PostStepDoIt:","027",FatalException,"ElasticDecay");
}
#ifdef debug
G4cout<<"G4QCol::PStDoI:l4M="<<scat4M<<"+r4M="<<reco4M<<"="<<scat4M+reco4M<<G4endl;
#endif
// ----------------------------------------------------
G4ParticleDefinition* theDefinition=0; // Prototype of a particle for E-Secondaries
// Fill scattered lepton
if (scatPDG==-11) theDefinition = G4Positron::Positron();
else if(scatPDG== 11) theDefinition = G4Electron::Electron();
else if(scatPDG== 13) theDefinition = G4MuonMinus::MuonMinus();
else if(scatPDG==-13) theDefinition = G4MuonPlus::MuonPlus();
//else if(scatPDG== 15) theDefinition = G4TauMinus::TauMinus();
//else if(scatPDG==-15) theDefinition = G4TauPlus::TauPlus();
if (scatPDG==-12) theDefinition = G4AntiNeutrinoE::AntiNeutrinoE();
else if(scatPDG== 12) theDefinition = G4NeutrinoE::NeutrinoE();
else if(scatPDG== 14) theDefinition = G4NeutrinoMu::NeutrinoMu();
else if(scatPDG==-14) theDefinition = G4AntiNeutrinoMu::AntiNeutrinoMu();
//else if(scatPDG== 16) theDefinition = G4NeutrinoTau::NeutrinoTau();
//else if(scatPDG==-16) theDefinition = G4AntiNeutrinoTau::AntiNeutrinoTau();
else G4cout<<"-Warning-G4QCollision::PostStDoIt: UnknownLepton="<<scatPDG<<G4endl;
G4DynamicParticle* theScL = new G4DynamicParticle(theDefinition,scat4M);
G4Track* scatLep = new G4Track(theScL, localtime, position ); // scattered
scatLep->SetWeight(weight); // weighted
scatLep->SetTouchableHandle(trTouchable); // residual
aParticleChange.AddSecondary(scatLep); // lepton
// Fill residual nucleus
if (fintPDG==90000001) theDefinition = G4Neutron::Neutron(); // neutron
else if(fintPDG==90001000) theDefinition = G4Proton::Proton(); // proton
else // ion
{
G4int fm=static_cast<G4int>(fintPDG/1000000); // Strange part
G4int ZN=fintPDG-1000000*fm;
G4int rZ=static_cast<G4int>(ZN/1000);
G4int rA=ZN-999*rZ;
theDefinition = G4ParticleTable::GetParticleTable()->FindIon(rZ,rA,0,rZ);
}
G4DynamicParticle* theReN = new G4DynamicParticle(theDefinition,reco4M);
G4Track* scatReN = new G4Track(theReN, localtime, position ); // scattered
scatReN->SetWeight(weight); // weighted
scatReN->SetTouchableHandle(trTouchable); // residual
aParticleChange.AddSecondary(scatReN); // nucleus
return G4VDiscreteProcess::PostStepDoIt(track, step);
}
proj4M=t4M; // 4m of the pion
}
aParticleChange.ProposeEnergy(0.) ;
aParticleChange.ProposeTrackStatus(fStopAndKill); // the initial neutrino is killed
}
else if(aProjPDG==2212 && Z>0 && N>0) // quasi-elastic for pA(Z,N)
//else if(2>3)
{
G4QuasiFreeRatios* qfMan=G4QuasiFreeRatios::GetPointer();
std::pair<G4double,G4double> fief=qfMan->GetRatios(momentum, aProjPDG, Z, N);
G4double qepart=fief.first*fief.second;
#ifdef qedebug
G4cout<<"G4QCol::PSD:QE[p("<<proj4M<<")+(Z="<<Z<<",N="<<N<<",)="<<qepart<<G4endl;
#endif
if(G4UniformRand()<qepart) // Make a quasi free scattering (out:A-1,h,N) @@ KinLim
{
// First decay a nucleus in a nucleon and a residual (A-1) nucleus
G4double dmom=91.; // Fermi momentum (proto default for a deuteron)
if(Z>1||N>1) dmom=286.2*std::pow(-std::log(G4UniformRand()),third);// p_max=250 MeV/c
// Calculate cluster probabilities (n,p,d,t,he3,he4 now only, can use UpdateClusters)
const G4int lCl=3; // The last clProb[lCl]==1. by definition, MUST be increasing
G4double clProb[lCl]={.6,.7,.8}; // N/P,D,t/He3,Al, integrated prob for .6,.1,.1,.2
G4double base=1.; // Base for randomization (can be reduced by totZ & totN)
G4int max=lCl; // Number of boundaries (can be reduced by totZ & totN)
// Take into account that at least one nucleon must be left !
G4int A=Z+N; // Baryon number of the nucleus
if(Z<2||N<2||A<5) base=clProb[max--]; // Alpha cluster is impossible
if(Z>1&&N<2||Z<2&&N>1) base=(clProb[max]+clProb[max-1])/2; // t or He3 is impossible
if(Z<2&&N<2||A<4) base=clProb[max--]; // Both He3 and t clusters are impossible
if(A<3) base=clProb[max--]; // Deuteron cluster is impossible
G4int cln=0; // Cluster#0 (Default for the selected nucleon)
if(max) // Not only nucleons are possible
//if(2>3)
{
G4double ran=base*G4UniformRand(); // Base can be reduced
G4int ic=0; // Start from the smallest cluster boundary
while(ic<max) if(ran>clProb[ic++]) cln=ic;
}
G4ParticleDefinition* theDefinition; // Prototype for qfNucleon
G4bool cp1 = cln+2==A; // A=ClusterBN+1 condition
// Values to be defined in the following IF/ELSE
G4LorentzVector r4M(0.,0.,0.,0.); // Prototype of 4mom of the residual nucleus
G4LorentzVector n4M(0.,0.,0.,0.); // Prototype of 4mom of the quasi-cluster
G4int nPDG=90000001; // Prototype for quasi-cluster mass calculation
G4int restPDG=targPDG; // Prototype should be reduced by quasi-cluster
G4int rA=Z+N-1; // Prototype for the residualNucl definition
G4int rZ=Z; // residZ: OK for the quasi-free neutron
G4int nA=1; // Prototype for the quasi-cluster definition
G4int nZ=0; // nA=1,nZ=0: OK for the quasi-free neutron
G4double qM=mNeut; // Free mass of the quasi-free cluster
if(!cln || cp1) // Split in nucleon + (A-1) with Fermi momentum
{
G4int nln=0;
if(cln==2) nln=1; // @@ only for cp1: t/He3 choice from A=4
// mass(A)=tM. Calculate masses of A-1 (rM) and mN (mNeut or mProt bounded mass)
if((!cln||cln==2)&&G4UniformRand()*(A-cln)>(N-nln) || (cln==3||cln==1)&&Z>N)
{
nPDG=90001000; // Update quasi-free nucleon PDGCode to P
nZ=1; // Change charge of the quasiFree nucleon
qM=mProt; // Update quasi-free nucleon mass
rZ--; // Reduce the residual Z
restPDG-=1000; // Reduce the residual PDGCode
}
else restPDG--;
G4LorentzVector t4M(0.,0.,0.,tM); // 4m of the target nucleus to be decayed
G4double rM=G4QPDGCode(restPDG).GetMass();// Mass of the residual nucleus
r4M=G4LorentzVector(0.,0.,0.,rM); // 4mom of the residual nucleus
G4double rM2=rM*rM;
G4double nM=std::sqrt(rM2+tM*tM-(tM+tM)*std::sqrt(rM2+dmom*dmom));// M of q-nucleon
n4M=G4LorentzVector(0.,0.,0.,nM); // 4mom of the quasi-nucleon
#ifdef qedebug
G4cout<<"G4QCollis::PStDoIt:QE,p="<<dmom<<",tM="<<tM<<",R="<<rM<<",N="<<nM<<G4endl;
#endif
if(!G4QHadron(t4M).DecayIn2(r4M, n4M))
{
G4cerr<<"G4QCol::PostStDoIt: M="<<tM<<"<rM="<<rM<<"+nM="<<nM<<"="<<rM+nM<<G4endl;
throw G4QException("G4QCollision::HadronizeQuasm:Can'tDec totNuc->QENuc+ResNuc");
}
#ifdef qedebug
G4cout<<"G4QCol::PStDoIt:QE-N,RA="<<r4M.rho()<<r4M<<",QN="<<n4M.rho()<<n4M<<G4endl;
#endif
if(cp1 && cln) // Quasi-cluster case: swap the output
{
qM=rM; // Scattering will be made on a cluster
nln=nPDG;
nPDG=restPDG;
restPDG=nln;
t4M=n4M;
n4M=r4M;
r4M=t4M;
nln=nZ;
nZ=rZ;
rZ=nln;
nln=nA;
nA=rA;
rA=nln;
}
}
else // Split a cluster (w or w/o "Fermi motion" and "Fermi decay")
{
if(cln==1)
{
nPDG=90001001; // Deuteron
qM=mDeut;
nA=2;
nZ=1;
restPDG-=1001;
}
else if(cln==2)
{
nA=3;
if(G4UniformRand()*(A-2)>(N-1)) // He3
{
nPDG=90002001;
qM=mHel3;
nZ=2;
restPDG-=2001;
}
else // tritium
{
nPDG=90001002;
qM=mTrit;
nZ=1;
restPDG-=1002;
}
}
else
{
nPDG=90002002; // Alpha
qM=mAlph;
nA=4;
nZ=2;
restPDG-=2002;
}
rA=A-nA;
rZ=Z-nZ;
// This is a simple case of cluster at rest
//G4double rM=G4QPDGCode(restPDG).GetMass();// Mass of the residual nucleus
//r4M=G4LorentzVector(0.,0.,0.,rM); // 4mom of the residual nucleus
//n4M=G4LorentzVector(0.,0.,0.,tM-rM); // 4mom of the quasi-free cluster
// --- End of the "simple case of cluster at rest"
// Make a fake quasi-Fermi distribution for clusters (clusters are not at rest)
G4LorentzVector t4M(0.,0.,0.,tM); // 4m of the target nucleus to be decayed
G4double rM=G4QPDGCode(restPDG).GetMass();// Mass of the residual nucleus
r4M=G4LorentzVector(0.,0.,0.,rM); // 4mom of the residual nucleus
G4double rM2=rM*rM;
G4double nM=std::sqrt(rM2+tM*tM-(tM+tM)*std::sqrt(rM2+dmom*dmom));// M of q-cluster
n4M=G4LorentzVector(0.,0.,0.,nM); // 4mom of the quasi-nucleon
#ifdef qedebug
G4cout<<"G4QCollis::PStDoIt:QEC,p="<<dmom<<",T="<<tM<<",R="<<rM<<",N="<<nM<<G4endl;
#endif
if(!G4QHadron(t4M).DecayIn2(r4M, n4M))
{
G4cerr<<"G4QCol::PostStDoIt: M="<<tM<<"<rM="<<rM<<"+cM="<<nM<<"="<<rM+nM<<G4endl;
throw G4QException("G4QCollision::HadronizeQuasm:Can'tDec totNuc->QEClu+ResNuc");
}
// --- End of the moving cluster implementation ---
#ifdef qedebug
G4cout<<"G4QCol::PStDoIt:QEC,RN="<<r4M.rho()<<r4M<<",QCl="<<n4M.rho()<<n4M<<G4endl;
#endif
}
G4LorentzVector s4M=n4M+proj4M; // Tot 4-momentum for scattering
G4double prjM2 = proj4M.m2();
G4double prjM = std::sqrt(prjM2); // @@ Get from pPDG (?)
G4double minM = prjM+qM; // Min mass sum for the final products
G4double cmM2 =s4M.m2();
if(cmM2>minM*minM)
{
#ifdef qedebug
G4cout<<"G4QCol::PStDoIt:***Enter***,cmM2="<<cmM2<<" > minM2="<<minM*minM<<G4endl;
#endif
// Estimate and randomize charge-exchange with quasi-free cluster
G4bool chex=false; // Flag of the charge exchange scattering
G4ParticleDefinition* projpt=G4Proton::Proton(); // Prototype, only for chex=true
//if(cln&&!cp1 &&(projPDG==2212&&rA>rZ || projPDG==2112&&rZ>1))// @@ Use proj chex
if(2>3)
{
#ifdef qedebug
G4cout<<"G4QCol::PStDoIt:-Enter,P="<<projPDG<<",cln="<<cln<<",cp1="<<cp1<<G4endl;
#endif
G4double tprM=mProt;
G4double tprM2=mProt2;
G4int tprPDG=2212;
G4int tresPDG=restPDG+999;
if(projPDG==2212)
{
projpt=G4Neutron::Neutron();
tprM=mNeut;
tprM2=mNeut2;
tprPDG=2112;
tresPDG=restPDG-999;
}
minM=tprM+qM;
G4double efE=(cmM2-tprM2-qM*qM)/(qM+qM);
G4double efP=std::sqrt(efE*efE-tprM2);
G4double chl=qfMan->ChExElCoef(efP*MeV, nZ, nA-nZ, projPDG); // ChEx/Elast(pPDG!)
#ifdef qedebug
G4cout<<"G4QCol::PStDoIt:chl="<<chl<<",P="<<efP<<",nZ="<<nZ<<",nA="<<nA<<G4endl;
#endif
if(chl>0.&&cmM2>minM*minM&&G4UniformRand()<chl/(1.+chl)) // minM is redefined
{
projPDG=tprPDG;
prjM=tprM;
G4double rM=G4QPDGCode(tresPDG).GetMass();// Mass of the residual nucleus
r4M=G4LorentzVector(0.,0.,0.,rM); // 4mom of the residual nucleus
n4M=G4LorentzVector(0.,0.,0.,tM-rM); // 4mom of the quasi-free cluster
chex=true; // Confirm charge exchange scattering
}
}
//
std::pair<G4LorentzVector,G4LorentzVector> sctout=qfMan->Scatter(nPDG, n4M,
projPDG, proj4M);
#ifdef qedebug
G4cout<<"G4QCollis::PStDoIt:QElS,proj="<<prjM<<sctout.second<<",qfCl="<<qM
<<sctout.first<<",chex="<<chex<<",nA="<<nA<<",nZ="<<nZ<<G4endl;
#endif
aParticleChange.ProposeLocalEnergyDeposit(0.); // Everything is in particles
// @@ @@ @@ Coulomb barriers must be checked !! @@ @@ @@ Skip if not
if(chex) // ==> Projectile is changed: fill everything to secondaries
{
aParticleChange.ProposeEnergy(0.); // @@ ??
aParticleChange.ProposeTrackStatus(fStopAndKill); // projectile nucleon is killed
aParticleChange.SetNumberOfSecondaries(3);
G4DynamicParticle* thePrH = new G4DynamicParticle(projpt,sctout.second);
G4Track* scatPrH = new G4Track(thePrH, localtime, position ); // scattered & chex
scatPrH->SetWeight(weight); // weighted
scatPrH->SetTouchableHandle(trTouchable); // projectile
aParticleChange.AddSecondary(scatPrH); // hadron
}
else // ==> The leading particle is filled to the updated projectilee
{
aParticleChange.SetNumberOfSecondaries(2); // @@ if proj=leading
G4double ldT=(sctout.second).e()-prjM; // kin Energy of scat project.
aParticleChange.ProposeEnergy(ldT); // Change the kin Energy
G4ThreeVector ldV=(sctout.second).vect(); // Change momentum direction
aParticleChange.ProposeMomentumDirection(ldV/ldV.mag());
aParticleChange.ProposeTrackStatus(fAlive);
}
// ---------------------------------------------------------
// Fill scattered quasi-free nucleon
if (nPDG==90000001) theDefinition = G4Neutron::Neutron();
else if(nPDG==90001000) theDefinition = G4Proton::Proton();
else theDefinition = G4ParticleTable::GetParticleTable()->FindIon(nZ,nA,0,nZ);//ion
G4DynamicParticle* theQFN = new G4DynamicParticle(theDefinition,sctout.first);
G4Track* scatQFN = new G4Track(theQFN, localtime, position ); // scattered
scatQFN->SetWeight(weight); // weighted
scatQFN->SetTouchableHandle(trTouchable); // quasi-free
aParticleChange.AddSecondary(scatQFN); // nucleon/cluster
// ----------------------------------------------------
// Fill residual nucleus
if (restPDG==90000001) theDefinition = G4Neutron::Neutron();
else if(restPDG==90001000) theDefinition = G4Proton::Proton();
else theDefinition = G4ParticleTable::GetParticleTable()->FindIon(rZ,rA,0,rZ);//ion
G4DynamicParticle* theReN = new G4DynamicParticle(theDefinition,r4M);
G4Track* scatReN = new G4Track(theReN, localtime, position ); // scattered
scatReN->SetWeight(weight); // weighted
scatReN->SetTouchableHandle(trTouchable); // residual
aParticleChange.AddSecondary(scatReN); // nucleus
return G4VDiscreteProcess::PostStepDoIt(track, step);
}
#ifdef qedebug
else G4cout<<"G4QCol::PSD: OUT, M2="<<s4M.m2()<<"<"<<minM*minM<<", N="<<nPDG<<G4endl;
#endif
}
}
EnMomConservation=proj4M+G4LorentzVector(0.,0.,0.,tM); // Total 4-mom of the reaction
if(absMom) EnMomConservation+=lead4M; // Add E/M of leading System
@@ -897,7 +1430,7 @@ G4VParticleChange* G4QCollision::PostStepDoIt(const G4Track& track, const G4Step
std::for_each(projHV.begin(), projHV.end(), DeleteQHadron()); // <---<------<---+-+-+
projHV.clear(); // <------------<---------------<-------------------<-----------+-+ .
#ifdef debug
G4cout<<"G4QCollision::PostStepDoIt:pPDG="<<projPDG<<",4M="<<proj4M<<G4endl; // | .
G4cout<<"G4QCol::PStDoIt:Proj="<<projPDG<<proj4M<<",Targ="<<targPDG<<G4endl; // | .
#endif
try // | .
{ // | .
@@ -988,8 +1521,8 @@ G4VParticleChange* G4QCollision::PostStepDoIt(const G4Track& track, const G4Step
}
if(tNH==2&&2!=nOut) G4cout<<"--Warning--G4QCollision::PostStepDoIt: 2 # "<<nOut<<G4endl;
// Deal with ParticleChange final state interface to GEANT4 output of the process
//if(tNH==2) for(i=0; i<tNH; i++) // @@ Temporary tNH==2 instead of just tNH
if(tNH) for(i=0; i<tNH; i++) // @@ Temporary tNH==2 instead of just tNH
//if(tNH==2) for(i=0; i<tNH; i++) // @@ Temporary tNH==2 instead of just tNH
if(tNH) for(i=0; i<tNH; i++) // @@ Temporary tNH==2 instead of just tNH
{
// Note that one still has to take care of Hypernuclei (with Lambda or Sigma inside)
// Hypernucleus mass calculation and ion-table interface upgrade => work for Hisaya @@
@@ -1001,7 +1534,7 @@ G4VParticleChange* G4QCollision::PostStepDoIt(const G4Track& track, const G4Step
G4cout<<"G4QCollision::PostStepDoIt: H#"<<i<<",PDG="<<PDGCode<<",nF="<<nFrag
<<", 4Mom="<<hadr->Get4Momentum()<<G4endl;
#endif
if(nFrag) // Skip intermediate (decayed) hadrons
if(nFrag) // Skip intermediate (decayed) hadrons
{
#ifdef debug
G4cout<<"G4QCollision::PostStepDoIt: Intermediate particle is found i="<<i<<G4endl;
@@ -1009,7 +1542,7 @@ G4VParticleChange* G4QCollision::PostStepDoIt(const G4Track& track, const G4Step
delete hadr;
continue;
}
G4DynamicParticle* theSec = new G4DynamicParticle;
G4DynamicParticle* theSec = new G4DynamicParticle;
G4ParticleDefinition* theDefinition;
if (PDGCode==90000001) theDefinition = G4Neutron::Neutron();
else if(PDGCode==90001000) theDefinition = G4Proton::Proton();//While it can be in ions
@@ -1073,6 +1606,7 @@ G4VParticleChange* G4QCollision::PostStepDoIt(const G4Track& track, const G4Step
G4cout<<"G4QCollis::PSDoIt:p="<<curD<<curD.mag()<<",e="<<curE<<",m="<<curM<<G4endl;// |
#endif
G4Track* aNewTrack = new G4Track(theSec, localtime, position ); // ^
aNewTrack->SetWeight(weight); // weighted |
aNewTrack->SetTouchableHandle(trTouchable); // |
aParticleChange.AddSecondary( aNewTrack ); // |
#ifdef debug
@@ -1096,3 +1630,20 @@ G4VParticleChange* G4QCollision::PostStepDoIt(const G4Track& track, const G4Step
#endif
return G4VDiscreteProcess::PostStepDoIt(track, step);
}
std::pair<G4double,G4double> G4QCollision::Random2DDirection()
{
G4double sp=0; // sin(phi)
G4double cp=1.; // cos(phi)
G4double r2=2.; // to enter the loop
while(r2>1. || r2<.0001) // pi/4 efficiency
{
G4double s=G4UniformRand();
G4double c=G4UniformRand();
sp=1.-s-s;
cp=1.-c-c;
r2=sp*sp+cp*cp;
}
G4double norm=std::sqrt(r2);
return std::make_pair(sp/norm,cp/norm);
}
@@ -0,0 +1,572 @@
//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4QDiffraction.cc,v 1.3 2007/10/02 10:00:37 mkossov Exp $
// GEANT4 tag $Name: geant4-09-01 $
//
// ---------------- G4QDiffraction class -----------------
// by Mikhail Kossov, Aug 2007.
// G4QDiffraction class of the CHIPS Simulation Branch in GEANT4
// ---------------------------------------------------------------
// ****************************************************************************************
// ********** This CLASS is temporary moved from the "chips/interface" directory *********
// ****************************************************************************************
//#define debug
//#define pdebug
//#define tdebug
//#define nandebug
//#define ppdebug
#include "G4QDiffraction.hh"
// Initialization of static vectors
G4int G4QDiffraction::nPartCWorld=152; // #of particles initialized in CHIPS
std::vector<G4int> G4QDiffraction::ElementZ; // Z of element(i) in theLastCalc
std::vector<G4double> G4QDiffraction::ElProbInMat; // SumProbOfElem in Material
std::vector<std::vector<G4int>*> G4QDiffraction::ElIsoN;// N of isotope(j), E(i)
std::vector<std::vector<G4double>*>G4QDiffraction::IsoProbInEl;//SumProbIsotE(i)
// Constructor
G4QDiffraction::G4QDiffraction(const G4String& processName):G4VDiscreteProcess(processName)
{
#ifdef debug
G4cout<<"G4QDiffraction::Constructor is called processName="<<processName<<G4endl;
#endif
if (verboseLevel>0) G4cout << GetProcessName() << " process is created "<< G4endl;
G4QCHIPSWorld::Get()->GetParticles(nPartCWorld); // Create CHIPS World (234 part. max)
}
// Destructor
G4QDiffraction::~G4QDiffraction() {}
G4LorentzVector G4QDiffraction::GetEnegryMomentumConservation(){return EnMomConservation;}
G4int G4QDiffraction::GetNumberOfNeutronsInTarget() {return nOfNeutrons;}
// output of the function must be in units of length! L=1/sig_V,sig_V=SUM(n(j,i)*sig(j,i)),
// where n(i,j) is a number of nuclei of the isotop j of the element i in V=1(lengtUnit^3)
// ********** All CHIPS cross sections are calculated in the surface units ************
G4double G4QDiffraction::GetMeanFreePath(const G4Track&Track,G4double Q,G4ForceCondition*F)
{
*F = NotForced;
const G4DynamicParticle* incidentParticle = Track.GetDynamicParticle();
G4ParticleDefinition* incidentParticleDefinition=incidentParticle->GetDefinition();
if( !IsApplicable(*incidentParticleDefinition))
G4cout<<"-Warning-G4QDiffraction::GetMeanFreePath for notImplemented Particle"<<G4endl;
// Calculate the mean Cross Section for the set of Elements(*Isotopes) in the Material
G4double Momentum = incidentParticle->GetTotalMomentum(); // 3-momentum of the Particle
#ifdef debug
G4double KinEn = incidentParticle->GetKineticEnergy();
G4cout<<"G4QDiffraction::GetMeanFreePath:Prpj, kinE="<<KinEn<<", Mom="<<Momentum<<G4endl;
#endif
const G4Material* material = Track.GetMaterial(); // Get the current material
const G4double* NOfNucPerVolume = material->GetVecNbOfAtomsPerVolume();
const G4ElementVector* theElementVector = material->GetElementVector();
G4int nE=material->GetNumberOfElements();
#ifdef debug
G4cout<<"G4QDiffraction::GetMeanFreePath:"<<nE<<" Elems in Material="<<*material<<G4endl;
#endif
G4int pPDG=0;
// @@ At present it is made only for n & p, but can be extended if inXS are available
if (incidentParticleDefinition == G4Proton::Proton() ) pPDG=2212;
else if(incidentParticleDefinition == G4Neutron::Neutron()) pPDG=2112;
else G4cout<<"G4QDiffraction::GetMeanFreePath: only nA & pA are implemented"<<G4endl;
G4QIsotope* Isotopes = G4QIsotope::Get(); // Pointer to the G4QIsotopes singleton
G4double sigma=0.; // Sums over elements for the material
G4int IPIE=IsoProbInEl.size(); // How many old elements?
if(IPIE) for(G4int ip=0; ip<IPIE; ++ip) // Clean up the SumProb's of Isotopes (SPI)
{
std::vector<G4double>* SPI=IsoProbInEl[ip]; // Pointer to the SPI vector
SPI->clear();
delete SPI;
std::vector<G4int>* IsN=ElIsoN[ip]; // Pointer to the N vector
IsN->clear();
delete IsN;
}
ElProbInMat.clear(); // Clean up the SumProb's of Elements (SPE)
ElementZ.clear(); // Clear the body vector for Z of Elements
IsoProbInEl.clear(); // Clear the body vector for SPI
ElIsoN.clear(); // Clear the body vector for N of Isotopes
for(G4int i=0; i<nE; ++i)
{
G4Element* pElement=(*theElementVector)[i]; // Pointer to the current element
G4int Z = static_cast<G4int>(pElement->GetZ()); // Z of the Element
ElementZ.push_back(Z); // Remember Z of the Element
G4int isoSize=0; // The default for the isoVectorLength is 0
G4int indEl=0; // Index of non-natural element or 0(default)
G4IsotopeVector* isoVector=pElement->GetIsotopeVector(); // Get the predefined IsoVect
if(isoVector) isoSize=isoVector->size();// Get size of the existing isotopeVector
#ifdef debug
G4cout<<"G4QDiffraction::GetMeanFreePath: isovector Length="<<isoSize<<G4endl;
#endif
if(isoSize) // The Element has non-trivial abundance set
{
indEl=pElement->GetIndex()+1; // Index of the non-trivial element is an order
#ifdef debug
G4cout<<"G4QDiffr::GetMFP:iE="<<indEl<<",def="<<Isotopes->IsDefined(Z,indEl)<<G4endl;
#endif
if(!Isotopes->IsDefined(Z,indEl)) // This index is not defined for this Z: define
{
std::vector<std::pair<G4int,G4double>*>* newAbund =
new std::vector<std::pair<G4int,G4double>*>;
G4double* abuVector=pElement->GetRelativeAbundanceVector();
for(G4int j=0; j<isoSize; j++) // Calculation of abundance vector for isotopes
{
G4int N=pElement->GetIsotope(j)->GetN()-Z; // N means A=N+Z !
if(pElement->GetIsotope(j)->GetZ()!=Z)G4cerr<<"G4QDiffract::GetMeanFreePath: Z="
<<pElement->GetIsotope(j)->GetZ()<<"#"<<Z<<G4endl;
G4double abund=abuVector[j];
std::pair<G4int,G4double>* pr= new std::pair<G4int,G4double>(N,abund);
#ifdef debug
G4cout<<"G4QDiffract::GetMeanFreePath:pair#"<<j<<",N="<<N<<",ab="<<abund<<G4endl;
#endif
newAbund->push_back(pr);
}
#ifdef debug
G4cout<<"G4QDiffract::GetMeanFreePath:pairVectorLength="<<newAbund->size()<<G4endl;
#endif
indEl=G4QIsotope::Get()->InitElement(Z,indEl,newAbund); // definition of the newInd
for(G4int k=0; k<isoSize; k++) delete (*newAbund)[k]; // Cleaning temporary
delete newAbund; // Was "new" in the beginning of the name space
}
}
std::vector<std::pair<G4int,G4double>*>* cs= Isotopes->GetCSVector(Z,indEl);//CSPointer
std::vector<G4double>* SPI = new std::vector<G4double>; // Pointer to the SPI vector
IsoProbInEl.push_back(SPI);
std::vector<G4int>* IsN = new std::vector<G4int>; // Pointer to the N vector
ElIsoN.push_back(IsN);
G4int nIs=cs->size(); // A#Of Isotopes in the Element
#ifdef debug
G4cout<<"G4QDiffract::GetMFP:=***=>,#isot="<<nIs<<", Z="<<Z<<", indEl="<<indEl<<G4endl;
#endif
G4double susi=0.; // sum of CS over isotopes
if(nIs) for(G4int j=0; j<nIs; j++) // Calculate CS for eachIsotope of El
{
std::pair<G4int,G4double>* curIs=(*cs)[j]; // A pointer, which is used twice
G4int N=curIs->first; // #of Neuterons in the isotope j of El i
IsN->push_back(N); // Remember Min N for the Element
#ifdef debug
G4cout<<"G4QDiff::GMFP:true,P="<<Momentum<<",Z="<<Z<<",N="<<N<<",PDG="<<pPDG<<G4endl;
#endif
G4bool ccsf=true;
if(Q==-27.) ccsf=false;
#ifdef debug
G4cout<<"G4QDiffraction::GMFP: GetCS #1 j="<<j<<G4endl;
#endif
G4double CSI=CalculateXS(Momentum, Z, N, pPDG); // XS(j,i) for theIsotope
#ifdef debug
G4cout<<"G4QDiffraction::GetMeanFreePath: jI="<<j<<", Zt="<<Z<<", Nt="<<N<<", Mom="
<<Momentu<<", XSec="<<CSI/millibarn<<G4endl;
#endif
curIs->second = CSI;
susi+=CSI; // Make a sum per isotopes
SPI->push_back(susi); // Remember summed cross-section
} // End of temporary initialization of the cross sections in the G4QIsotope singeltone
sigma+=Isotopes->GetMeanCrossSection(Z,indEl)*NOfNucPerVolume[i];//SUM(MeanCS*NOfNperV)
#ifdef debug
G4cout<<"G4QDiffraction::GetMeanFreePath:<XS>="<<Isotopes->GetMeanCrossSection(Z,indEl)
<<",AddSigm="<<Isotopes->GetMeanCrossSection(Z,indEl)*NOfNucPerVolume[i]<<G4endl;
#endif
ElProbInMat.push_back(sigma);
} // End of LOOP over Elements
// Check that cross section is not zero and return the mean free path
#ifdef debug
G4cout<<"G4QDiffraction::GetMeanFreePath: MeanFreePath="<<1./sigma<<G4endl;
#endif
if(sigma > 0.) return 1./sigma; // Mean path [distance]
return DBL_MAX;
}
G4bool G4QDiffraction::IsApplicable(const G4ParticleDefinition& particle)
{
if (particle == *( G4Proton::Proton() )) return true;
else if (particle == *( G4Neutron::Neutron() )) return true;
//else if (particle == *( G4MuonMinus::MuonMinus() )) return true;
//else if (particle == *( G4TauPlus::TauPlus() )) return true;
//else if (particle == *( G4TauMinus::TauMinus() )) return true;
//else if (particle == *( G4Electron::Electron() )) return true;
//else if (particle == *( G4Positron::Positron() )) return true;
//else if (particle == *( G4Gamma::Gamma() )) return true;
//else if (particle == *( G4MuonPlus::MuonPlus() )) return true;
//else if (particle == *(G4AntiNeutrinoMu::AntiNeutrinoMu())) return true;
//else if (particle == *( G4NeutrinoMu::NeutrinoMu() )) return true;
//else if (particle == *( G4PionMinus::PionMinus() )) return true;
//else if (particle == *( G4PionPlus::PionPlus() )) return true;
//else if (particle == *( G4KaonPlus::KaonPlus() )) return true;
//else if (particle == *( G4KaonMinus::KaonMinus() )) return true;
//else if (particle == *( G4KaonZeroLong::KaonZeroLong() )) return true;
//else if (particle == *( G4KaonZeroShort::KaonZeroShort() )) return true;
//else if (particle == *( G4Lambda::Lambda() )) return true;
//else if (particle == *( G4SigmaPlus::SigmaPlus() )) return true;
//else if (particle == *( G4SigmaMinus::SigmaMinus() )) return true;
//else if (particle == *( G4SigmaZero::SigmaZero() )) return true;
//else if (particle == *( G4XiMinus::XiMinus() )) return true;
//else if (particle == *( G4XiZero::XiZero() )) return true;
//else if (particle == *( G4OmegaMinus::OmegaMinus() )) return true;
//else if (particle == *( G4AntiNeutron::AntiNeutron() )) return true;
//else if (particle == *( G4AntiProton::AntiProton() )) return true;
#ifdef debug
G4cout<<"***>>G4QDiffraction::IsApplicable: projPDG="<<particle.GetPDGEncoding()<<G4endl;
#endif
return false;
}
G4VParticleChange* G4QDiffraction::PostStepDoIt(const G4Track& track, const G4Step& step)
{
static const G4double mProt= G4QPDGCode(2212).GetMass(); // CHIPS proton Mass in MeV
static const G4double mNeut= G4QPDGCode(2112).GetMass(); // CHIPS neutron Mass in MeV
static const G4double mPion= G4QPDGCode(111).GetMass(); // CHIPS Pi0 Mass in MeV
static G4QDiffractionRatio* diffRatio;
//
//-------------------------------------------------------------------------------------
static G4bool CWinit = true; // CHIPS Warld needs to be initted
if(CWinit)
{
CWinit=false;
G4QCHIPSWorld::Get()->GetParticles(nPartCWorld); // Create CHIPS World (234 part.max)
diffRatio=G4QDiffractionRatio::GetPointer();
}
//-------------------------------------------------------------------------------------
const G4DynamicParticle* projHadron = track.GetDynamicParticle();
const G4ParticleDefinition* particle=projHadron->GetDefinition();
#ifdef debug
G4cout<<"G4QDiffraction::PostStepDoIt: Before the GetMeanFreePath is called In4M="
<<projHadron->Get4Momentum()<<" of PDG="<<particle->GetPDGEncoding()<<", Type="
<<particle->GetParticleType()<<",SubType="<<particle->GetParticleSubType()<<G4endl;
#endif
G4ForceCondition cond=NotForced;
GetMeanFreePath(track, -27., &cond); // @@ ?? jus to update parameters?
#ifdef debug
G4cout<<"G4QDiffraction::PostStepDoIt: After GetMeanFreePath is called"<<G4endl;
#endif
G4LorentzVector proj4M=(projHadron->Get4Momentum())/MeV; // Convert to MeV!
G4double momentum = projHadron->GetTotalMomentum()/MeV; // 3-momentum of the Proj in MeV
G4double Momentum = proj4M.rho(); // @@ Just for the test purposes
if(std::fabs(Momentum-momentum)>.000001)
G4cerr<<"-Warning-G4QDiffraction::PostStepDoIt:P_IU="<<Momentum<<"#"<<momentum<<G4endl;
#ifdef pdebug
G4cout<<"G4QDiffraction::PostStepDoIt: pP(IU)="<<Momentum<<"="<<momentum
<<",proj4M="<<proj4M<<", projM="<<proj4M.m()<<G4endl;
#endif
if (!IsApplicable(*particle)) // Check applicability
{
G4cerr<<"G4QDiffraction::PostStepDoIt: Only NA is implemented."<<G4endl;
return 0;
}
const G4Material* material = track.GetMaterial(); // Get the current material
G4int Z=0;
const G4ElementVector* theElementVector = material->GetElementVector();
G4int nE=material->GetNumberOfElements();
#ifdef debug
G4cout<<"G4QDiffraction::PostStepDoIt: "<<nE<<" elements in the material."<<G4endl;
#endif
G4int projPDG=0; // PDG Code prototype for the captured hadron
// Not all these particles are implemented yet (see Is Applicable)
if (particle == G4Proton::Proton() ) projPDG= 2212;
else if (particle == G4Neutron::Neutron() ) projPDG= 2112;
//else if (particle == G4PionMinus::PionMinus() ) projPDG= -211;
//else if (particle == G4PionPlus::PionPlus() ) projPDG= 211;
//else if (particle == G4KaonPlus::KaonPlus() ) projPDG= 321;
//else if (particle == G4KaonMinus::KaonMinus() ) projPDG= -321;
//else if (particle == G4KaonZeroLong::KaonZeroLong() ) projPDG= 130;
//else if (particle == G4KaonZeroShort::KaonZeroShort() ) projPDG= 310;
//else if (particle == G4MuonPlus::MuonPlus() ) projPDG= -13;
//else if (particle == G4MuonMinus::MuonMinus() ) projPDG= 13;
//else if (particle == G4NeutrinoMu::NeutrinoMu() ) projPDG= 14;
//else if (particle == G4AntiNeutrinoMu::AntiNeutrinoMu() ) projPDG= -14;
//else if (particle == G4Electron::Electron() ) projPDG= 11;
//else if (particle == G4Positron::Positron() ) projPDG= -11;
//else if (particle == G4NeutrinoE::NeutrinoE() ) projPDG= 12;
//else if (particle == G4AntiNeutrinoE::AntiNeutrinoE() ) projPDG= -12;
//else if (particle == G4Gamma::Gamma() ) projPDG= 22;
//else if (particle == G4TauPlus::TauPlus() ) projPDG= -15;
//else if (particle == G4TauMinus::TauMinus() ) projPDG= 15;
//else if (particle == G4NeutrinoTau::NeutrinoTau() ) projPDG= 16;
//else if (particle == G4AntiNeutrinoTau::AntiNeutrinoTau()) projPDG= -16;
//else if (particle == G4Lambda::Lambda() ) projPDG= 3122;
//else if (particle == G4SigmaPlus::SigmaPlus() ) projPDG= 3222;
//else if (particle == G4SigmaMinus::SigmaMinus() ) projPDG= 3112;
//else if (particle == G4SigmaZero::SigmaZero() ) projPDG= 3212;
//else if (particle == G4XiMinus::XiMinus() ) projPDG= 3312;
//else if (particle == G4XiZero::XiZero() ) projPDG= 3322;
//else if (particle == G4OmegaMinus::OmegaMinus() ) projPDG= 3334;
//else if (particle == G4AntiNeutron::AntiNeutron() ) projPDG=-2112;
//else if (particle == G4AntiProton::AntiProton() ) projPDG=-2212;
#ifdef debug
G4int prPDG=particle->GetPDGEncoding();
G4cout<<"G4QDiffraction::PostStepDoIt: projPDG="<<projPDG<<", stPDG="<<prPDG<<G4endl;
#endif
if(!projPDG)
{
G4cerr<<"-Warning-G4QDiffraction::PostStepDoIt:UndefProjHadron(PDG=0) ->ret 0"<<G4endl;
return 0;
}
//G4double pM2=proj4M.m2(); // in MeV^2
//G4double pM=std::sqrt(pM2); // in MeV
G4double pM=mNeut;
G4int fPDG=2112;
if(projPDG==2112)
{
pM=mProt;
fPDG=2212;
}
// Element treatment
G4int EPIM=ElProbInMat.size();
#ifdef debug
G4cout<<"G4QDiffra::PostStDoIt: m="<<EPIM<<",n="<<nE<<",T="<<ElProbInMat[EPIM-1]<<G4endl;
#endif
G4int i=0;
if(EPIM>1)
{
G4double rnd = ElProbInMat[EPIM-1]*G4UniformRand();
for(i=0; i<nE; ++i)
{
#ifdef debug
G4cout<<"G4QDiffra::PostStepDoIt: EPM["<<i<<"]="<<ElProbInMat[i]<<",r="<<rnd<<G4endl;
#endif
if (rnd<ElProbInMat[i]) break;
}
if(i>=nE) i=nE-1; // Top limit for the Element
}
G4Element* pElement=(*theElementVector)[i];
Z=static_cast<G4int>(pElement->GetZ());
#ifdef debug
G4cout<<"G4QDiffraction::PostStepDoIt: i="<<i<<", Z(element)="<<Z<<G4endl;
#endif
if(Z<=0)
{
G4cerr<<"-Warning-G4QDiffraction::PostStepDoIt: Element with Z="<<Z<<G4endl;
if(Z<0) return 0;
}
std::vector<G4double>* SPI = IsoProbInEl[i];// Vector of summedProbabilities for isotopes
std::vector<G4int>* IsN = ElIsoN[i]; // Vector of "#of neutrons" in the isotope El[i]
G4int nofIsot=SPI->size(); // #of isotopes in the element i
#ifdef debug
G4cout<<"G4QDiffraction::PostStepDoIt: nI="<<nofIsot<<", T="<<(*SPI)[nofIsot-1]<<G4endl;
#endif
G4int j=0;
if(nofIsot>1)
{
G4double rndI=(*SPI)[nofIsot-1]*G4UniformRand(); // Randomize the isotop of the Element
for(j=0; j<nofIsot; ++j)
{
#ifdef debug
G4cout<<"G4QDiffraction::PostStepDoIt: SP["<<j<<"]="<<(*SPI)[j]<<",r="<<rndI<<G4endl;
#endif
if(rndI < (*SPI)[j]) break;
}
if(j>=nofIsot) j=nofIsot-1; // Top limit for the isotope
}
G4int N =(*IsN)[j]; ; // Randomized number of neutrons
#ifdef debug
G4cout<<"G4QDiffraction::PostStepDoIt: j="<<i<<", N(isotope)="<<N<<", MeV="<<MeV<<G4endl;
#endif
if(N<0)
{
G4cerr<<"-Warning-G4QDiffraction::PostStepDoIt: Isotope Z="<<Z<<" has 0>N="<<N<<G4endl;
return 0;
}
nOfNeutrons=N; // Remember it for the energy-momentum check
#ifdef debug
G4cout<<"G4QDiffraction::PostStepDoIt: N="<<N<<" for element with Z="<<Z<<G4endl;
#endif
if(N<0)
{
G4cerr<<"*Warning*G4QDiffraction::PostStepDoIt:Element with N="<<N<< G4endl;
return 0;
}
aParticleChange.Initialize(track);
#ifdef debug
G4cout<<"G4QDiffraction::PostStepDoIt: track is initialized"<<G4endl;
#endif
G4double weight = track.GetWeight();
G4double localtime = track.GetGlobalTime();
G4ThreeVector position = track.GetPosition();
#ifdef debug
G4cout<<"G4QDiffraction::PostStepDoIt: before Touchable extraction"<<G4endl;
#endif
G4TouchableHandle trTouchable = track.GetTouchableHandle();
#ifdef debug
G4cout<<"G4QDiffraction::PostStepDoIt: Touchable is extracted"<<G4endl;
#endif
G4int targPDG=90000000+Z*1000+N; // CHIPS PDG Code of the target nucleus
G4QPDGCode targQPDG(targPDG); // @@ use G4Ion and get rid of CHIPS World
G4double tM=targQPDG.GetMass(); // CHIPS final nucleus mass in MeV
G4double kinEnergy= projHadron->GetKineticEnergy()*MeV; // Kin energy in MeV (Is *MeV n?)
G4ParticleMomentum dir = projHadron->GetMomentumDirection();// It is a unit three-vector
G4LorentzVector tot4M=proj4M+G4LorentzVector(0.,0.,0.,tM); // Total 4-mom of the reaction
#ifdef debug
G4cout<<"G4QDiffraction::PostStepDoIt: tM="<<tM<<",p4M="<<proj4M<<",t4M="<<tot4M<<G4endl;
#endif
EnMomConservation=tot4M; // Total 4-mom of reaction for E/M conservation
// @@ Probably this is not necessary any more
#ifdef debug
G4cout<<"G4QDiff::PSDI:false,P="<<Momentum<<",Z="<<Z<<",N="<<N<<",PDG="<<projPDG<<G4endl;
#endif
G4double xSec=CalculateXS(Momentum, Z, N, projPDG); // Recalculate CrossSection
#ifdef debug
G4cout<<"G4QDiffra::PSDI:PDG="<<projPDG<<",P="<<Momentum<<",XS="<<xSec/millibarn<<G4endl;
#endif
#ifdef nandebug
if(xSec>0. || xSec<0. || xSec==0);
else G4cout<<"-Warning-G4QDiffraction::PostSDI: *NAN* xSec="<<xSec/millibarn<<G4endl;
#endif
// @@ check a possibility to separate p, n, or alpha (!)
if(xSec <= 0.) // The cross-section iz 0 -> Do Nothing
{
#ifdef pdebug
G4cerr<<"*Warning*G4QDiffraction::PSDoIt:*Zero cross-section* PDG="<<projPDG
<<",tPDG="<<targPDG<<",P="<<Momentum<<G4endl;
#endif
//Do Nothing Action insead of the reaction
aParticleChange.ProposeEnergy(kinEnergy);
aParticleChange.ProposeLocalEnergyDeposit(0.);
aParticleChange.ProposeMomentumDirection(dir) ;
return G4VDiscreteProcess::PostStepDoIt(track,step);
}
G4double totCMMass=tot4M.m(); // Total CM mass, pM=projectileMass, tM=targetMass
if(totCMMass < mPion+pM+tM) // The diffraction reaction is impossible -> Do Nothing
{
#ifdef pdebug
G4cerr<<"*Warning*G4QDiffraction::PSDoIt:*Below Diffraction Threshold* cmM="<<totCMMass
<<">pM="<<pM<<"+tM="<<tM<<"+pi0="<<mPion<<"=="<<pM+tM+mPion<<G4endl;
#endif
//Do Nothing Action insead of the reaction
aParticleChange.ProposeEnergy(kinEnergy);
aParticleChange.ProposeLocalEnergyDeposit(0.);
aParticleChange.ProposeMomentumDirection(dir) ;
return G4VDiscreteProcess::PostStepDoIt(track,step);
}
// Kill interacting hadron
aParticleChange.ProposeTrackStatus(fStopAndKill);
G4QHadronVector* out=diffRatio->TargFragment(projPDG, proj4M, Z, N);
G4int nSec=out->size(); // #of secondaries in the diffraction reaction
G4DynamicParticle* theSec=0; // A prototype for secondary for the secondary
G4LorentzVector dif4M(0.,0.,0.,0.); // Prototype for the secondary 4-momentum
G4int difPDG=0; // PDG code of the secondary
G4QHadron* difQH=0; // Prototype for a Q-secondary
#ifdef pdebug
G4cout<<"G4QDiffraction::PostStepDoIt: =====found===== nSecondaries="<<nSec<<G4endl;
#endif
for(G4int i=0; i<nSec; i++)
{
difQH = (*out)[i];
difPDG= difQH->GetPDGCode();
G4ParticleDefinition* theDefinition=0;
if (difPDG==2212 || difPDG==90001000) theDefinition=G4Proton::Proton();
else if(difPDG==2112 || difPDG==90000001) theDefinition=G4Neutron::Neutron();
else if(difPDG== 22) theDefinition=G4Gamma::Gamma();
else if(difPDG== 111) theDefinition=G4PionZero::PionZero();
else if(difPDG==-211 || difPDG==89999001) theDefinition=G4PionMinus::PionMinus();
else if(difPDG== 211 || difPDG==90000999) theDefinition=G4PionPlus::PionPlus();
else if(difPDG== 321 || difPDG==89001000) theDefinition=G4KaonPlus::KaonPlus();
else if(difPDG==-321 || difPDG==90999000) theDefinition=G4KaonMinus::KaonMinus();
else if(difPDG== 130 || difPDG==-311 || difPDG==89000001)
theDefinition=G4KaonZeroLong::KaonZeroLong();
else if(difPDG== 310 || difPDG== 311 || difPDG==90999999)
theDefinition=G4KaonZeroShort::KaonZeroShort();
else if(difPDG==3122 || difPDG==91000000) theDefinition=G4Lambda::Lambda();
else if(difPDG== 3222) theDefinition=G4SigmaPlus::SigmaPlus();
else if(difPDG== 3112) theDefinition=G4SigmaMinus::SigmaMinus();
else if(difPDG== 3212) theDefinition=G4SigmaZero::SigmaZero();
else if(difPDG== 3312) theDefinition=G4XiMinus::XiMinus();
else if(difPDG== 3322) theDefinition=G4XiZero::XiZero();
else if(difPDG== 3334) theDefinition=G4OmegaMinus::OmegaMinus();
else if(difPDG==-2112) theDefinition=G4AntiNeutron::AntiNeutron();
else if(difPDG==-2212) theDefinition=G4AntiProton::AntiProton();
else if(difPDG==-3122) theDefinition=G4AntiLambda::AntiLambda();
else if(difPDG==-3222) theDefinition=G4AntiSigmaPlus::AntiSigmaPlus();
else if(difPDG==-3112) theDefinition=G4AntiSigmaMinus::AntiSigmaMinus();
else if(difPDG==-3212) theDefinition=G4AntiSigmaZero::AntiSigmaZero();
else if(difPDG==-3312) theDefinition=G4AntiXiMinus::AntiXiMinus();
else if(difPDG==-3322) theDefinition=G4AntiXiZero::AntiXiZero();
else if(difPDG==-3334) theDefinition=G4AntiOmegaMinus::AntiOmegaMinus();
else if(difPDG== -11) theDefinition=G4Electron::Electron();
else if(difPDG== -13) theDefinition=G4MuonMinus::MuonMinus();
else if(difPDG== 11) theDefinition=G4Positron::Positron();
else if(difPDG== 13) theDefinition=G4MuonPlus::MuonPlus();
else
{
G4int Z = difQH->GetCharge();
G4int B = difQH->GetBaryonNumber();
G4int S = difQH->GetStrangeness();
if(S||Z>B||Z<0)G4cout<<"-Warning-G4QDif::PoStDoIt:Z="<<Z<<",A="<<B<<",S="<<S<<G4endl;
theDefinition = G4ParticleTable::GetParticleTable()->FindIon(Z,B,0,0);
#ifdef pdebug
G4cout<<"G4QDiffraction::PoStDoIt:Ion,Z="<<Z<<",A="<<B<<",D="<<theDefinition<<G4endl;
#endif
}
if(theDefinition)
{
theSec = new G4DynamicParticle; // A secondary for the recoil hadron
theSec->SetDefinition(theDefinition);
dif4M = difQH->Get4Momentum();
EnMomConservation-=dif4M;
theSec->Set4Momentum(dif4M);
G4Track* aNewTrack = new G4Track(theSec, localtime, position );
aNewTrack->SetWeight(weight); // weighted
aNewTrack->SetTouchableHandle(trTouchable);
aParticleChange.AddSecondary( aNewTrack );
#ifdef pdebug
G4cout<<"G4QDiffraction::PostStepDoIt: Filled 4M="<<dif4M<<", PDG="<<difPDG<<G4endl;
#endif
}
else G4cout<<"-Warning-G4QDif::PSDI: Lost PDG="<<difPDG<<", Z="<<difQH->GetCharge()
<<", A="<<difQH->GetBaryonNumber()<<",S ="<<difQH->GetStrangeness()<<G4endl;
delete difQH; // Clean up the output QHadrons
}
delete out; // Delete the output QHadron-vector
#ifdef debug
G4cout<<"G4QDiffraction::PostStepDoIt:*** PostStepDoIt is done ***"<<G4endl;
#endif
return G4VDiscreteProcess::PostStepDoIt(track, step);
}
G4double G4QDiffraction::CalculateXS(G4double p, G4int Z, G4int N, G4int PDG)
{
static G4bool first=true;
static G4VQCrossSection* CSmanager;
static G4QDiffractionRatio* diffRatio;
if(first) // Connection with a singletone
{
CSmanager=G4QProtonNuclearCrossSection::GetPointer();
diffRatio=G4QDiffractionRatio::GetPointer();
first=false;
}
//G4double x=CSmanager->GetCrossSection(true, p, Z, N, PDG); // inelastic XS
//G4double pIU=p*GeV; // IndependentUnistMomentum
//G4double r=diffRatio->GetRatio(pIU, PDG, Z, N); // Proj. Diffraction Part
//G4double s=x*r; // XS for proj. diffraction
G4double s=diffRatio->GetTargSingDiffXS(p, PDG, Z, N); // XS for target diffraction
#ifdef debug
G4cout<<"G4QDiff::CXS:p="<<p<<",Z="<<Z<<",N="<<N<<",C="<<PDG<<",XS="<<s<<G4endl;
#endif
return s;
}

Some files were not shown because too many files have changed in this diff Show More