Import Geant4 3.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-08 15:55:53 +02:00
parent e7d7193284
commit cfcb558cfe
3050 changed files with 91703 additions and 48310 deletions
+38
View File
@@ -0,0 +1,38 @@
# $Id: GNUmakefile,v 1.1 2000/11/14 16:15:01 gcosmo Exp $
# ---------------------------------------------------------------
# GNUmakefile for parameterisations library. G.Cosmo, 14/11/2000
# ---------------------------------------------------------------
name := G4parmodels
ifndef G4INSTALL
G4INSTALL = ../..
endif
include $(G4INSTALL)/config/architecture.gmk
CPPFLAGS += -I$(G4BASE)/global/management/include \
-I$(G4BASE)/global/HEPRandom/include \
-I$(G4BASE)/global/HEPGeometry/include \
-I$(G4BASE)/global/HEPNumerics/include \
-I$(G4BASE)/geometry/management/include \
-I$(G4BASE)/geometry/volumes/include \
-I$(G4BASE)/track/include \
-I$(G4BASE)/materials/include \
-I$(G4BASE)/processes/management/include \
-I$(G4BASE)/processes/parameterisation/include \
-I$(G4BASE)/processes/electromagnetic/standard/include \
-I$(G4BASE)/processes/electromagnetic/utils/include \
-I$(G4BASE)/particles/management/include \
-I$(G4BASE)/particles/bosons/include \
-I$(G4BASE)/particles/hadrons/include \
-I$(G4BASE)/particles/hadrons/barions/include \
-I$(G4BASE)/particles/leptons/include \
-I$(G4BASE)/digits+hits/detector/include \
-I$(G4BASE)/digits+hits/hits/include
include $(G4INSTALL)/config/common.gmk
.PHONY: global
global: lib
+22
View File
@@ -0,0 +1,22 @@
$Id: History,v 1.1 2000/11/14 16:15:01 gcosmo Exp $
-------------------------------------------------------------------
=========================================================
Geant4 - an Object-Oriented Toolkit for Simulation in HEP
=========================================================
Category History file
---------------------
This file should be used by G4 developers and category coordinators
to briefly summarize all major modifications introduced in the code
and keep track of all category-tags.
It DOES NOT substitute the CVS log-message one should put at every
committal in the CVS repository !
----------------------------------------------------------
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
Nov 14th, 2000 G.Cosmo - (parmodels-V02-00-00)
----------------------
- Created.
@@ -0,0 +1,47 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4FoamXrayTRmodel.hh,v 1.1 2000/11/14 16:05:14 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
//
///////////////////////////////////////////////////////////////////////////
//
// Rough model describing a radiator of X-ray transition radiation.
// Thicknesses of plates and gas gaps are exponentially distributed.
// We suppose that:
// formation zone ~ mean thickness << absorption length
// for each material and in the range 1-100 keV. This allows us to simplify
// interference effects in radiator stack (GetStackFactor method).
//
//
// History:
// 09.02.00 V. Grichine, first version
//
#ifndef G4FoamXrayTRmodel_h
#define G4FoamXrayTRmodel_h 1
#include "G4VFastSimulationModel.hh"
// #include "G4ForwardXrayTR.hh"
#include "G4VXrayTRmodel.hh"
class G4FoamXrayTRmodel : public G4VXrayTRmodel
{
public:
G4FoamXrayTRmodel (G4LogicalVolume *anEnvelope,G4double,G4double);
~G4FoamXrayTRmodel ();
// Pure virtual function from base class
G4double GetStackFactor( G4double energy, G4double gamma, G4double varAngle);
};
#endif
@@ -0,0 +1,60 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4GamDistrXrayTRmodel.hh,v 1.1 2000/11/14 16:05:31 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
//
///////////////////////////////////////////////////////////////////////////
//
// Rough model describing a radiator of X-ray transition radiation.
// Thicknesses of plates and gas gaps are distributed according to gamma
// distribution. x are thicknesses of plates or gas gaps:
//
// p(x) = (alpha/<x>)^alpha * x^(alpha-1) * exp(-alpha*x/<x>) / G(alpha)
//
// G(alpha) is Euler's gamma function.
// Plates have mean <x> = fPlateThick > 0 and power alpha = fAlphaPlate > 0 :
// Gas gaps have mean <x> = fGasThick > 0 and power alpha = fAlphaGas > 0 :
// We suppose that:
// formation zone ~ mean thickness << absorption length
// for each material and in the range 1-100 keV. This allows us to simplify
// interference effects in radiator stack (GetStackFactor method).
//
//
// History:
// 11.02.00 V. Grichine, first version
//
#ifndef G4GamDistrXrayTRmodel_h
#define G4GamDistrXrayTRmodel_h 1
#include "G4VFastSimulationModel.hh"
// #include "G4ForwardXrayTR.hh"
#include "G4VXrayTRmodel.hh"
class G4GamDistrXrayTRmodel : public G4VXrayTRmodel
{
public:
G4GamDistrXrayTRmodel (G4LogicalVolume *anEnvelope,
G4double,G4double,
G4double,G4double );
~G4GamDistrXrayTRmodel ();
// Pure virtual function from base class
G4double GetStackFactor( G4double energy, G4double gamma, G4double varAngle);
private:
G4double fAlphaPlate, fAlphaGas ;
};
#endif
@@ -0,0 +1,49 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4IrregularXrayTRmodel.hh,v 1.1 2000/11/14 16:05:46 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
//
///////////////////////////////////////////////////////////////////////////
//
// Very rough model describing a radiator of X-ray transition radiation.
// Thicknesses of plates and gas gaps are exponentially distributed.
// We suppose that:
// formation zone << mean thickness << absorption length
// for each material and in the range 1-100 keV. This allows us to simplify
// essentially interference effects in radiator stack (GetStackFactor method).
// The price is decreasing of X-ray TR photon yield.
//
// History:
// 23.01.00 V. Grichine first version based on ExN05PiModel class
// 08.02.00 V. Grichine, DoIt was placed in base class
//
#ifndef G4IrregularXrayTRmodel_h
#define G4IrregularXrayTRmodel_h 1
#include "G4VFastSimulationModel.hh"
// #include "G4ForwardXrayTR.hh"
#include "G4VXrayTRmodel.hh"
class G4IrregularXrayTRmodel : public G4VXrayTRmodel
{
public:
G4IrregularXrayTRmodel (G4LogicalVolume *anEnvelope,G4double,G4double);
~G4IrregularXrayTRmodel ();
// Pure virtual function from base class
// void DoIt(const G4FastTrack&, G4FastStep&);
G4double GetStackFactor( G4double energy, G4double gamma, G4double varAngle);
};
#endif
@@ -0,0 +1,58 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4PAIclusterModel.hh,v 1.1 2000/11/14 16:06:00 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
//
///////////////////////////////////////////////////////////////////////////
//
// Class for 'fast' parametrisation model describing PAI ionisation clusters
// created in some G4Envelope.
//
// History:
// 14.07.00 V. Grichine first version
//
#ifndef G4PAIclusterModel_h
#define G4PAIclusterModel_h 1
#include "globals.hh"
#include "templates.hh"
#include "G4PAIonisation.hh"
#include "G4VClusterModel.hh"
#include "G4Step.hh"
#include "G4VTouchable.hh"
#include "G4TouchableHistory.hh"
#include <g4rw/tvordvec.h>
class G4PAIclusterModel : public G4VClusterModel
{
public:
G4PAIclusterModel (G4LogicalVolume* anEnvelope);
~G4PAIclusterModel ();
// Pure virtual functions from base class
G4bool IsApplicable(const G4ParticleDefinition&);
G4bool ModelTrigger(const G4FastTrack &);
void DoIt(const G4FastTrack&, G4FastStep&) ;
private:
G4PAIonisation* fPAIonisation ;
};
#endif
@@ -0,0 +1,72 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4PhotoClusterModel.hh,v 1.1 2000/11/14 16:06:17 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
//
///////////////////////////////////////////////////////////////////////////
//
// Class for 'fast' parametrisation model describing X-ray ionisation clusters
// created in some G4Envelope.
//
// History:
// 14.07.00 V. Grichine first version
//
#ifndef G4PhotoClusterModel_h
#define G4PhotoClusterModel_h 1
#include "globals.hh"
#include "templates.hh"
#include "G4PAIonisation.hh"
#include "G4VClusterModel.hh"
#include "G4Step.hh"
#include "G4VTouchable.hh"
#include "G4TouchableHistory.hh"
#include <g4rw/tvordvec.h>
class G4PhotoClusterModel : public G4VClusterModel
{
public:
G4PhotoClusterModel (G4LogicalVolume* anEnvelope);
~G4PhotoClusterModel ();
// Pure virtual functions from base class
G4bool IsApplicable(const G4ParticleDefinition&);
G4bool ModelTrigger(const G4FastTrack &);
void DoIt(const G4FastTrack&, G4FastStep&) ;
protected:
void ComputePhotoAbsCof() ;
G4double GetLinearPhotoAbs(G4double) ;
private:
G4int fMatIndex ;
G4double** fPhotoAbsCof ;
G4int fIntervalNumber ;
};
#endif
@@ -0,0 +1,47 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4PlateIrrGasXrayTRmodel.hh,v 1.1 2000/11/14 16:06:32 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
//
///////////////////////////////////////////////////////////////////////////
//
// Model describing a radiator of X-ray transition radiation.
// Thicknesses of plates is fixed while gas gaps are fully irregular.
// We suppose that:
// formation zone ~ mean thickness << absorption length
// for each material and in the range 1-100 keV. This allows us to simplify
// interference effects in radiator stack (GetStackFactor method).
//
//
// History:
// 10.02.00 V. Grichine, first version
//
#ifndef G4PlateIrrGasXrayTRmodel_h
#define G4PlateIrrGasXrayTRmodel_h 1
#include "G4VFastSimulationModel.hh"
// #include "G4ForwardXrayTR.hh"
#include "G4VXrayTRmodel.hh"
class G4PlateIrrGasXrayTRmodel : public G4VXrayTRmodel
{
public:
G4PlateIrrGasXrayTRmodel (G4LogicalVolume *anEnvelope,G4double,G4double);
~G4PlateIrrGasXrayTRmodel ();
// Pure virtual function from base class
G4double GetStackFactor( G4double energy, G4double gamma, G4double varAngle);
};
#endif
@@ -0,0 +1,47 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4RegularXrayTRmodel.hh,v 1.1 2000/11/14 16:06:47 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
//
///////////////////////////////////////////////////////////////////////////
//
// Model describing a radiator of X-ray transition radiation.
// Thicknesses of plates and gas gaps are fixed.
// We suppose that:
// formation zone ~ mean thickness << absorption length
// for each material and in the range 1-100 keV. This allows us to simplify
// interference effects in radiator stack (GetStackFactor method).
//
//
// History:
// 10.02.00 V. Grichine, first version
//
#ifndef G4RegularXrayTRmodel_h
#define G4RegularXrayTRmodel_h 1
#include "G4VFastSimulationModel.hh"
// #include "G4ForwardXrayTR.hh"
#include "G4VXrayTRmodel.hh"
class G4RegularXrayTRmodel : public G4VXrayTRmodel
{
public:
G4RegularXrayTRmodel (G4LogicalVolume *anEnvelope,G4double,G4double);
~G4RegularXrayTRmodel ();
// Pure virtual function from base class
G4double GetStackFactor( G4double energy, G4double gamma, G4double varAngle);
};
#endif
@@ -0,0 +1,73 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VClusterModel.hh,v 1.1 2000/11/14 16:07:02 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
//
///////////////////////////////////////////////////////////////////////////
//
// Base class for 'fast' parametrisation models describing ionisation clusters
// created in some G4Envelope.
//
// History:
// 14.07.00 V. Grichine first version
//
#ifndef G4VClusterModel_h
#define G4VClusterModel_h 1
#include "globals.hh"
#include "templates.hh"
#include "G4PAIonisation.hh"
#include "G4VFastSimulationModel.hh"
#include "G4Step.hh"
#include "G4VTouchable.hh"
#include "G4TouchableHistory.hh"
#include <g4rw/tvordvec.h>
class G4VClusterModel : public G4VFastSimulationModel
{
public:
G4VClusterModel (const G4String& modelName,G4LogicalVolume* anEnvelope);
virtual ~G4VClusterModel ();
// Pure virtual functions from base class
virtual G4bool IsApplicable(const G4ParticleDefinition&) = 0 ;
virtual G4bool ModelTrigger(const G4FastTrack &) = 0 ;
virtual void DoIt(const G4FastTrack&, G4FastStep&) = 0 ;
protected:
void BuildDetectorResponse();
void AssignClusterHit(const G4ThreeVector& position, G4double energy) ;
void FillFakeStep(const G4ThreeVector& position, G4double energy) ;
protected:
G4Step* fFakeStep ;
G4StepPoint* fFakePreStepPoint ;
G4StepPoint* fFakePostStepPoint ;
G4VTouchable* fTouchable ;
G4Navigator* fNavigator ;
G4bool fNavigatorSetup ;
G4RWTValOrderedVector<G4ThreeVector> fClusterPositionVector ;
G4RWTValOrderedVector<G4double> fClusterEnergyVector ;
};
#endif
@@ -0,0 +1,146 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VXrayTRmodel.hh,v 1.1 2000/11/14 16:07:15 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
//
///////////////////////////////////////////////////////////////////////////
//
// base class for 'fast' parametrisation model describing X-ray transition
// created in some G4Envelope. Anglur distribuiton is very rough !!! (see DoIt
// method
//
// History:
// 23.01.00 V. Grichine first version
// 09.02.00 V. Grichine, DoIt was transformed from virtual
//
#ifndef G4VXrayTRmodel_h
#define G4VXrayTRmodel_h 1
#include "globals.hh"
#include "templates.hh"
#include "G4PhysicsTable.hh"
#include "G4PhysicsLogVector.hh"
#include "G4Gamma.hh"
#include "G4VFastSimulationModel.hh"
// #include "G4ForwardXrayTR.hh"
class G4VXrayTRmodel : public G4VFastSimulationModel
// , public G4ForwardXrayTR
{
public:
G4VXrayTRmodel (G4LogicalVolume *anEnvelope,G4double,G4double);
virtual ~G4VXrayTRmodel ();
// Pure virtual functions from base class
G4bool IsApplicable(const G4ParticleDefinition&);
G4bool ModelTrigger(const G4FastTrack &);
// Pure virtuals must be implemented in inherited particular TR radiators
void DoIt(const G4FastTrack&, G4FastStep&) ;
virtual G4double GetStackFactor( G4double energy, G4double gamma,
G4double varAngle ) = 0 ;
G4double OneBoundaryXTRNdensity( G4double energy,
G4double gamma,
G4double varAngle ) const ;
void BuildTable() ;
void BuildEnergyTable() ;
void BuildAngleTable() ;
// for photon energy distribution tables
G4double XTRNSpectralAngleDensity(G4double varAngle) ;
G4double XTRNSpectralDensity(G4double energy) ;
// for photon angle distribution tables
G4double XTRNAngleSpectralDensity(G4double energy) ;
G4double XTRNAngleDensity(G4double varAngle) ;
void GetNumberOfPhotons() ;
void ExampleDoIt(const G4FastTrack&, G4FastStep&) ;
// Auxiliary functions for plate/gas material parameters
G4double GetPlateFormationZone(G4double,G4double,G4double) ;
void ComputePlatePhotoAbsCof() ;
G4double GetPlateLinearPhotoAbs(G4double) ;
void GetPlateZmuProduct() ;
G4double GetPlateZmuProduct(G4double,G4double,G4double) ;
G4double GetGasFormationZone(G4double,G4double,G4double) ;
void ComputeGasPhotoAbsCof() ;
G4double GetGasLinearPhotoAbs(G4double) ;
void GetGasZmuProduct() ;
G4double GetGasZmuProduct(G4double,G4double,G4double) ;
G4double GetXTRrandomEnergy( G4double scaledTkin, G4int iTkin ) ;
G4double GetXTRenergy( G4int iPlace, G4double position, G4int iTransfer ) ;
protected:
G4Gamma* fPtrGamma ; // pointer to TR photon
G4double* fGammaCutInKineticEnergy ; // TR photon cut in energy array
G4double fGammaTkinCut ; // Tkin cut of TR photon in current mat.
G4PhysicsTable* fAngleDistrTable ;
G4PhysicsTable* fEnergyDistrTable ;
static G4PhysicsLogVector* fProtonEnergyVector ;
static G4double fTheMinEnergyTR ; // static min TR energy
static G4double fTheMaxEnergyTR ; // static max TR energy
G4double fMinEnergyTR ; // min TR energy in material
G4double fMaxEnergyTR ; // max TR energy in material
static G4double fTheMaxAngle ; // max theta of TR quanta
static G4double fTheMinAngle ; // max theta of TR quanta
G4double fMaxThetaTR ; // max theta of TR quanta
static G4int fBinTR ; // number of bins in TR vectors
static G4double fMinProtonTkin ; // min Tkin of proton in tables
static G4double fMaxProtonTkin ; // max Tkin of proton in tables
static G4int fTotBin ; // number of bins in log scale
G4double fGamma ; // current Lorentz factor
G4double fEnergy ; // energy and
G4double fVarAngle ; // angle squared
static G4double fPlasmaCof ; // physical consts for plasma energy
static G4double fCofTR ;
G4double fSigma1, fSigma2 ; // plasma energy Sq of matter1/2
G4int fMatIndex1, fMatIndex2 ;
G4int fPlateNumber ;
G4double** fPlatePhotoAbsCof ;
G4int fPlateIntervalNumber ;
G4double fPlateThick ;
G4double** fGasPhotoAbsCof ;
G4int fGasIntervalNumber ;
G4double fGasThick ;
};
#endif
@@ -0,0 +1,101 @@
// This code implementation is the intellectual property of
// the GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4FoamXrayTRmodel.cc,v 1.1 2000/11/14 16:07:37 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
#include "g4std/complex"
#include "G4FoamXrayTRmodel.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4FoamXrayTRmodel::G4FoamXrayTRmodel(G4Envelope *anEnvelope,
G4double a, G4double b) :
G4VXrayTRmodel(anEnvelope,a,b)
{
G4cout<<"Foam X-ray TR radiator model is called"<<G4endl ;
// Build energy and angular integral spectra of X-ray TR photons from
// a radiator
BuildTable() ;
}
///////////////////////////////////////////////////////////////////////////
G4FoamXrayTRmodel::~G4FoamXrayTRmodel()
{
;
}
///////////////////////////////////////////////////////////////////////////
//
// Rough approximation for radiator interference factor for the case of
// fully Foam radiator. The plate and gas gap thicknesses are distributed
// according to exponent. The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in coresponding material.
G4double
G4FoamXrayTRmodel::GetStackFactor( G4double energy,
G4double gamma, G4double varAngle )
{
G4double result, Qa, Qb, Q, Za, Zb, Ma, Mb ;
Za = GetPlateFormationZone(energy,gamma,varAngle) ;
Zb = GetGasFormationZone(energy,gamma,varAngle) ;
Ma = GetPlateLinearPhotoAbs(energy) ;
Mb = GetGasLinearPhotoAbs(energy) ;
Qa = 1.0/( 1.0 + fPlateThick*Ma ) ;
Qb = 1.0/( 1.0 + fGasThick*Mb ) ;
Q = Qa*Qb ;
G4complex Ca(1.0+0.5*fPlateThick*Ma,fPlateThick/Za) ;
G4complex Cb(1.0+0.5*fGasThick*Mb,fGasThick/Zb) ;
G4complex Ha = 1.0/Ca ;
G4complex Hb = 1.0/Cb ;
G4complex H = Ha*Hb ;
G4complex F1 = ( 0.5*(1+Qa)*(1.0+H) - Ha - Qa*Hb )/(1.0-H) ;
G4complex F2 = (1.0-Ha)*(Qa-Ha)*Hb/(1.0-H)/(Q-H) ;
F2 *= pow(Q,G4double(fPlateNumber)) - G4std::pow(H,fPlateNumber) ;
result = ( 1 - pow(Q,G4double(fPlateNumber)) )/( 1 - Q ) ;
result *= 2.0*G4std::real(F1) ;
result += 2.0*G4std::real(F2) ;
return result ;
}
//
//
////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,108 @@
// This code implementation is the intellectual property of
// the GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4GamDistrXrayTRmodel.cc,v 1.1 2000/11/14 16:07:53 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
#include "g4std/complex"
#include "G4GamDistrXrayTRmodel.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4GamDistrXrayTRmodel::G4GamDistrXrayTRmodel(G4Envelope *anEnvelope,
G4double a, G4double alphaPlate,
G4double b, G4double alphaGas) :
G4VXrayTRmodel(anEnvelope,a,b)
{
G4cout<<"Gammma distributed X-ray TR radiator model is called"<<G4endl ;
// Build energy and angular integral spectra of X-ray TR photons from
// a radiator
fAlphaPlate = alphaPlate ;
fAlphaGas = alphaGas ;
G4cout<<"fAlphaPlate = "<<fAlphaPlate<<" ; fAlphaGas = "<<fAlphaGas<<G4endl ;
BuildTable() ;
}
///////////////////////////////////////////////////////////////////////////
G4GamDistrXrayTRmodel::~G4GamDistrXrayTRmodel()
{
;
}
///////////////////////////////////////////////////////////////////////////
//
// Rough approximation for radiator interference factor for the case of
// fully GamDistr radiator. The plate and gas gap thicknesses are distributed
// according to exponent. The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in coresponding material.
G4double
G4GamDistrXrayTRmodel::GetStackFactor( G4double energy,
G4double gamma, G4double varAngle )
{
G4double result, Qa, Qb, Q, Za, Zb, Ma, Mb ;
Za = GetPlateFormationZone(energy,gamma,varAngle) ;
Zb = GetGasFormationZone(energy,gamma,varAngle) ;
Ma = GetPlateLinearPhotoAbs(energy) ;
Mb = GetGasLinearPhotoAbs(energy) ;
Qa = ( 1.0 + fPlateThick*Ma/fAlphaPlate ) ;
Qa = pow(Qa,-fAlphaPlate) ;
Qb = ( 1.0 + fGasThick*Mb/fAlphaGas ) ;
Qb = pow(Qb,-fAlphaGas) ;
Q = Qa*Qb ;
G4complex Ca(1.0+0.5*fPlateThick*Ma/fAlphaPlate,fPlateThick/Za/fAlphaPlate) ;
G4complex Cb(1.0+0.5*fGasThick*Mb/fAlphaGas,fGasThick/Zb/fAlphaGas) ;
G4complex Ha = G4std::pow(Ca,-fAlphaPlate) ;
G4complex Hb = G4std::pow(Cb,-fAlphaGas) ;
G4complex H = Ha*Hb ;
G4complex F1 = ( 0.5*(1+Qa)*(1.0+H) - Ha - Qa*Hb )/(1.0-H) ;
G4complex F2 = (1.0-Ha)*(Qa-Ha)*Hb/(1.0-H)/(Q-H) ;
F2 *= pow(Q,G4double(fPlateNumber)) - G4std::pow(H,fPlateNumber) ;
result = ( 1 - pow(Q,G4double(fPlateNumber)) )/( 1 - Q ) ;
result *= 2.0*G4std::real(F1) ;
result += 2.0*G4std::real(F2) ;
return result ;
}
//
//
////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,229 @@
// This code implementation is the intellectual property of
// the GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4IrregularXrayTRmodel.cc,v 1.1 2000/11/14 16:08:07 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
#include "G4IrregularXrayTRmodel.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4IrregularXrayTRmodel::G4IrregularXrayTRmodel(G4Envelope *anEnvelope,
G4double a, G4double b) :
G4VXrayTRmodel(anEnvelope,a,b)
{
G4cout<<"Irregular X-ray TR model is called"<<G4endl ;
// Build energy and angular integral spectra of X-ray TR photons from
// a radiator
BuildTable() ;
}
///////////////////////////////////////////////////////////////////////////
G4IrregularXrayTRmodel::~G4IrregularXrayTRmodel()
{
;
}
//////////////////////////////////////////////////////////////////////////
//
// User method to code the parameterisation properly
// said.
//
/* *******************************************************
void G4IrregularXrayTRmodel::DoIt( const G4FastTrack& fastTrack ,
G4FastStep& fastStep )
{
G4int iTkin, iPlace, numOfTR, iTR, iTransfer ;
G4double energyPos, energyTR, theta, phi, dirX, dirY, dirZ ;
G4double W, W1, W2, E1, E2 ;
G4double charge = fastTrack.GetPrimaryTrack()->GetDefinition()->GetPDGCharge() ;
// Now we are ready to Generate TR photons
G4double chargeSq = charge*charge ;
G4double kinEnergy = fastTrack.GetPrimaryTrack()->GetKineticEnergy() ;
G4double mass = fastTrack.GetPrimaryTrack()->GetDefinition()->GetPDGMass() ;
G4double gamma = 1.0 + kinEnergy/mass ;
// G4cout<<"gamma = "<<gamma<<G4endl ;
G4double massRatio = proton_mass_c2/mass ;
G4double TkinScaled = kinEnergy*massRatio ;
G4ParticleMomentum direction(fastTrack.GetPrimaryTrackLocalDirection());
G4double distance = fastTrack.GetEnvelopeSolid()->
DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(),
direction) ;
G4ThreeVector position = fastTrack.GetPrimaryTrackLocalPosition() +
distance*direction ;
// Set final position:
fastStep.SetPrimaryTrackFinalPosition(position);
for(iTkin=0;iTkin<fTotBin;iTkin++)
{
if(TkinScaled < fProtonEnergyVector->GetLowEdgeEnergy(iTkin)) break ;
}
iPlace = iTkin - 1 ;
G4ParticleMomentum particleDir = fastTrack.GetPrimaryTrack()->
GetMomentumDirection() ;
if(iTkin == 0) // Tkin is too small, neglect of TR photon generation
{
return ;
}
else // general case: Tkin between two vectors of the material
{
if(iTkin == fTotBin)
{
numOfTR = RandPoisson::shoot( (*(*fEnergyDistrTable)(iPlace))(0)*chargeSq ) ;
}
else
{
E1 = fProtonEnergyVector->GetLowEdgeEnergy(iTkin - 1) ;
E2 = fProtonEnergyVector->GetLowEdgeEnergy(iTkin) ;
W = 1.0/(E2 - E1) ;
W1 = (E2 - TkinScaled)*W ;
W2 = (TkinScaled - E1)*W ;
numOfTR = RandPoisson::shoot( ( (*(*fEnergyDistrTable)(iPlace))(0)*W1+
(*(*fEnergyDistrTable)(iPlace+1))(0)*W2 )
*chargeSq ) ;
}
// G4cout<<iTkin<<" mean TR number = "<<(((*(*fEnergyDistrTable)(iPlace))(0)+
// (*(*fAngleDistrTable)(iPlace))(0))*W1 +
// ((*(*fEnergyDistrTable)(iPlace + 1))(0)+
// (*(*fAngleDistrTable)(iPlace + 1))(0))*W2)
// *chargeSq*0.5<<endl ;
if( numOfTR == 0 ) // no change, return
{
return ;
}
else
{
// G4cout<<"Number of X-ray TR photons = "<<numOfTR<<endl ;
fastStep.SetNumberOfSecondaries(numOfTR);
G4double sumEnergyTR = 0.0 ;
for(iTR=0;iTR<numOfTR;iTR++)
{
energyPos = ((*(*fEnergyDistrTable)(iPlace))(0)*W1+
(*(*fEnergyDistrTable)(iPlace + 1))(0)*W2)*G4UniformRand() ;
for(iTransfer=0;iTransfer<fBinTR-1;iTransfer++)
{
if(energyPos >= ((*(*fEnergyDistrTable)(iPlace))(iTransfer)*W1+
(*(*fEnergyDistrTable)(iPlace + 1))(iTransfer)*W2)) break ;
}
energyTR = ((*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer))*W1+
((*fEnergyDistrTable)(iPlace + 1)->GetLowEdgeEnergy(iTransfer))*W2 ;
// G4cout<<"energyTR = "<<energyTR/keV<<"keV"<<endl ;
sumEnergyTR += energyTR ;
theta = abs(G4RandGauss::shoot(0.0,pi/gamma)) ;
if( theta >= 0.1 ) theta = 0.1 ;
// G4cout<<" : theta = "<<theta<<endl ;
phi = twopi*G4UniformRand() ;
dirX = sin(theta)*cos(phi) ;
dirY = sin(theta)*sin(phi) ;
dirZ = cos(theta) ;
G4ThreeVector directionTR(dirX,dirY,dirZ) ;
directionTR.rotateUz(particleDir) ;
directionTR.unit() ;
G4DynamicParticle aPhotonTR(G4Gamma::Gamma(),directionTR,energyTR) ;
G4ThreeVector positionTR = fastTrack.GetPrimaryTrackLocalPosition() +
G4UniformRand()*distance*direction ;
G4double distanceTR = fastTrack.GetEnvelopeSolid()->
DistanceToOut(positionTR,directionTR) ;
positionTR = positionTR + distanceTR*directionTR ;
fastStep.CreateSecondaryTrack( aPhotonTR,
positionTR,
fastTrack.GetPrimaryTrack()->
GetGlobalTime() ) ;
}
kinEnergy -= sumEnergyTR ;
fastStep.SetPrimaryTrackFinalKineticEnergy(kinEnergy) ;
}
}
return ;
}
***************************************************** */
///////////////////////////////////////////////////////////////////////////
//
// Very rough approximation for radiator interference factor for the case of
// fully irregular radiator. The plate and gas gap thicknesses are distributed
// according to exponent. The mean values of the plate and gas gap thicknesses
// are supposed to be much more than XTR formation zones but much less than
// mean absorption length of XTR photons in coresponding material.
G4double
G4IrregularXrayTRmodel::GetStackFactor( G4double energy,
G4double gamma, G4double varAngle )
{
G4double result, plateFactor, gasFactor, factor ;
plateFactor = 1.0/( 1.0 + fPlateThick*GetPlateLinearPhotoAbs(energy) ) ;
gasFactor = 1.0/( 1.0 + fGasThick*GetGasLinearPhotoAbs(energy) ) ;
factor = plateFactor*gasFactor ;
result = ( 1 - pow(factor,fPlateNumber) )/( 1 - factor ) ;
result *= 1 + plateFactor ;
return result ;
}
//
//
////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,154 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4PAIclusterModel.cc,v 1.1 2000/11/14 16:08:23 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
#include "G4Timer.hh"
#include "G4PAIclusterModel.hh"
#include "Randomize.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
#include "globals.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
#include "G4Gamma.hh"
#include "G4TransportationManager.hh"
#include "G4VSensitiveDetector.hh"
#include "G4VTouchable.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4PAIclusterModel::G4PAIclusterModel(G4Envelope *anEnvelope) :
G4VClusterModel("G4PAIclusterModel",anEnvelope)
{
fPAIonisation = new G4PAIonisation(anEnvelope->GetMaterial()->GetName()) ;
}
///////////////////////////////////////////////////////////////////////////
G4PAIclusterModel::~G4PAIclusterModel()
{
delete fPAIonisation ;
}
///////////////////////////////////////////////////////////////////////////////
//
// Returns condition for application of the model depending on particle type
G4bool G4PAIclusterModel::IsApplicable(const G4ParticleDefinition& particle)
{
return ( particle.GetPDGCharge() != 0.0 ) ;
}
/////////////////////////////////////////////////////////////////////
//
// UserTrigger() method: method which has to decide if
// the parameterisation has to be applied.
// Here ModelTrigger() asks the user (ie you) a 0/1 answer.
//
// Note that quantities like the local/global position/direction etc..
// are available at this level via the fastTrack parameter (allowing
// to check distance from boundaries, see below to allow the decision)
//
G4bool G4PAIclusterModel::ModelTrigger(const G4FastTrack& fastTrack)
{
// if (gamma >= 100.0) return true ;
// else return false ;
return true ;
}
//////////////////////////////////////////////////////////////////////////////
//
//
void G4PAIclusterModel::DoIt( const G4FastTrack& fastTrack ,
G4FastStep& fastStep )
{
G4double charge, charge2, kinEnergy, mass, massRatio, scaledTkin ;
G4double distance, energyTransfer, energyLoss, lambda, step, stepSum = 0.0 ;
G4ThreeVector clusterPosition ;
charge = fastTrack.GetPrimaryTrack()->GetDefinition()->GetPDGCharge() ;
charge2 = charge*charge ;
kinEnergy = fastTrack.GetPrimaryTrack()->GetKineticEnergy() ;
mass = fastTrack.GetPrimaryTrack()->GetDefinition()->GetPDGMass() ;
massRatio = proton_mass_c2/mass ;
scaledTkin = kinEnergy*massRatio ;
G4ParticleMomentum direction(fastTrack.GetPrimaryTrackLocalDirection());
distance = fastTrack.GetEnvelopeSolid()->
DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(),direction) ;
G4ThreeVector position = fastTrack.GetPrimaryTrackLocalPosition() +
distance*direction ;
// Set final position:
fastStep.SetPrimaryTrackFinalPosition(position);
// Cluster counting loop
lambda = fPAIonisation->GetFreePath( scaledTkin, charge2 ) ;
step = RandExponential::shoot(lambda) ;
// if (step < 0.0) step = 0.0 ;
stepSum += step ;
distance -= stepSum ;
if(distance < 0.0) // no change, return
{
return ;
}
else
{
G4ThreeVector globalStartPosition = fastTrack.GetPrimaryTrack()->
GetPosition() ;
G4ParticleMomentum globalDirection = fastTrack.GetPrimaryTrack()->
GetMomentumDirection() ;
while(distance >= 0.0) // global (or local ?) cluster coordinates
{
// clusterPosition = fastTrack.GetPrimaryTrackLocalPosition() +
// stepSum*direction ;
clusterPosition = globalStartPosition + stepSum*globalDirection ;
energyTransfer = fPAIonisation->GetRandomEnergyTransfer(scaledTkin) ;
fClusterPositionVector.insert(clusterPosition) ;
fClusterEnergyVector.insert(energyTransfer) ;
step = RandExponential::shoot(lambda) ;
// if (step < 0.0) step = 0.0 ;
stepSum += step ;
distance -= step ;
energyLoss += energyTransfer ;
}
kinEnergy -= energyLoss ;
fastStep.SetPrimaryTrackFinalKineticEnergy(kinEnergy) ;
// fastStep.SetTotalEnergyDeposited(energyLoss);
BuildDetectorResponse() ;
}
return ;
}
//
//
///////////////////////////////////////////////////////////////////////
@@ -0,0 +1,223 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4PhotoClusterModel.cc,v 1.1 2000/11/14 16:08:37 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
#include "G4Timer.hh"
#include "G4PhotoClusterModel.hh"
#include "Randomize.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
#include "globals.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
#include "G4Gamma.hh"
#include "G4TransportationManager.hh"
#include "G4VSensitiveDetector.hh"
#include "G4VTouchable.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4PhotoClusterModel::G4PhotoClusterModel(G4Envelope *anEnvelope) :
G4VClusterModel("G4PhotoClusterModel",anEnvelope)
{
fMatIndex = anEnvelope->GetMaterial()->GetIndex() ;
ComputePhotoAbsCof() ;
}
///////////////////////////////////////////////////////////////////////////
G4PhotoClusterModel::~G4PhotoClusterModel()
{
for(G4int i=0;i<fIntervalNumber;i++)
{
delete[] fPhotoAbsCof[i] ;
}
delete[] fPhotoAbsCof ;
}
///////////////////////////////////////////////////////////////////////////////
//
// Returns condition for application of the model depending on particle type
G4bool G4PhotoClusterModel::IsApplicable(const G4ParticleDefinition& particle)
{
return &particle == G4Gamma::GammaDefinition() ;
}
/////////////////////////////////////////////////////////////////////
//
// UserTrigger() method: method which has to decide if
// the parameterisation has to be applied.
// Here ModelTrigger() asks the user (ie you) a 0/1 answer.
//
// Note that quantities like the local/global position/direction etc..
// are available at this level via the fastTrack parameter (allowing
// to check distance from boundaries, see below to allow the decision)
//
G4bool G4PhotoClusterModel::ModelTrigger(const G4FastTrack& fastTrack)
{
return ( fastTrack.GetPrimaryTrack()->GetKineticEnergy() > 1*keV &&
fastTrack.GetPrimaryTrack()->GetKineticEnergy() < 40*keV ) ;
}
//////////////////////////////////////////////////////////////////////////////
//
//
void G4PhotoClusterModel::DoIt( const G4FastTrack& fastTrack ,
G4FastStep& fastStep )
{
G4double energy ;
G4double distance, lambda, step ;
G4ThreeVector clusterPosition ;
energy = fastTrack.GetPrimaryTrack()->GetKineticEnergy() ;
G4ParticleMomentum direction(fastTrack.GetPrimaryTrackLocalDirection());
distance = fastTrack.GetEnvelopeSolid()->
DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(),direction) ;
G4ThreeVector position = fastTrack.GetPrimaryTrackLocalPosition() +
distance*direction ;
// Set final position:
fastStep.SetPrimaryTrackFinalPosition(position);
// Cluster counting loop
lambda = 1.0/GetLinearPhotoAbs(energy) ;
step = RandExponential::shoot(lambda) ;
if(step > distance) // no change, return
{
return ;
}
else
{
G4ThreeVector globalStartPosition = fastTrack.GetPrimaryTrack()->
GetPosition() ;
G4ParticleMomentum globalDirection = fastTrack.GetPrimaryTrack()->
GetMomentumDirection() ;
// global (or local ?) cluster coordinates
// clusterPosition = fastTrack.GetPrimaryTrackLocalPosition() +
// stepSum*direction ;
clusterPosition = globalStartPosition + step*globalDirection ;
fClusterPositionVector.insert(clusterPosition) ;
fClusterEnergyVector.insert(energy) ;
fastStep.KillPrimaryTrack();
fastStep.SetPrimaryTrackPathLength(step);
fastStep.SetTotalEnergyDeposited(energy);
BuildDetectorResponse() ;
}
return ;
}
////////////////////////////////////////////////////////////////////////
//
// Computes matrix of Sandia photo absorption cross section coefficients for
// G4Envelope material
void G4PhotoClusterModel::ComputePhotoAbsCof()
{
G4int i, j, numberOfElements ;
static const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
G4SandiaTable thisMaterialSandiaTable(fMatIndex) ;
numberOfElements = (*theMaterialTable)[fMatIndex]->GetNumberOfElements() ;
G4int* thisMaterialZ = new G4int[numberOfElements] ;
for(i=0;i<numberOfElements;i++)
{
thisMaterialZ[i] = (G4int)(*theMaterialTable)[fMatIndex]->
GetElement(i)->GetZ() ;
}
fIntervalNumber = thisMaterialSandiaTable.SandiaIntervals
(thisMaterialZ,numberOfElements) ;
fIntervalNumber = thisMaterialSandiaTable.SandiaMixing
( thisMaterialZ ,
(*theMaterialTable)[fMatIndex]->GetFractionVector() ,
numberOfElements,fIntervalNumber) ;
fPhotoAbsCof = new G4double*[fIntervalNumber] ;
for(i=0;i<fIntervalNumber;i++) fPhotoAbsCof[i] = new G4double[5] ;
for(i=0;i<fIntervalNumber;i++)
{
fPhotoAbsCof[i][0] = thisMaterialSandiaTable.
GetPhotoAbsorpCof(i+1,0) ;
for(j=1;j<5;j++)
{
fPhotoAbsCof[i][j] = thisMaterialSandiaTable.
GetPhotoAbsorpCof(i+1,j)*
(*theMaterialTable)[fMatIndex]->GetDensity() ;
}
}
delete[] thisMaterialZ ;
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Returns the value of linear photo absorption coefficient (in reciprocal
// length) for G4Envelope material
G4double G4PhotoClusterModel::GetLinearPhotoAbs(G4double omega)
{
G4int i ;
G4double omega2, omega3, omega4 ;
omega2 = omega*omega ;
omega3 = omega2*omega ;
omega4 = omega2*omega2 ;
for(i=0;i<fIntervalNumber;i++)
{
if( omega < fPhotoAbsCof[i][0] ) break ;
}
if( i == 0 )
{
G4Exception("Invalid (<I1) energy in G4PhotoClusterModel::GetLinearPhotoAbs");
}
else i-- ;
return fPhotoAbsCof[i][1]/omega + fPhotoAbsCof[i][2]/omega2 +
fPhotoAbsCof[i][3]/omega3 + fPhotoAbsCof[i][4]/omega4 ;
}
//
//
///////////////////////////////////////////////////////////////////////
@@ -0,0 +1,112 @@
// This code implementation is the intellectual property of
// the GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4PlateIrrGasXrayTRmodel.cc,v 1.1 2000/11/14 16:08:52 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
#include "g4std/complex"
#include "G4PlateIrrGasXrayTRmodel.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4PlateIrrGasXrayTRmodel::G4PlateIrrGasXrayTRmodel(G4Envelope *anEnvelope,
G4double a, G4double b) :
G4VXrayTRmodel(anEnvelope,a,b)
{
G4cout<<"PlateIrrGas X-ray TR radiator model is called"<<G4endl ;
// Build energy and angular integral spectra of X-ray TR photons from
// a radiator
BuildTable() ;
}
///////////////////////////////////////////////////////////////////////////
G4PlateIrrGasXrayTRmodel::~G4PlateIrrGasXrayTRmodel()
{
;
}
///////////////////////////////////////////////////////////////////////////
//
// Approximation for radiator interference factor for the case of
// fully PlateIrrGas radiator. The plate and gas gap thicknesses are fixed .
// The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in coresponding material.
G4double
G4PlateIrrGasXrayTRmodel::GetStackFactor( G4double energy,
G4double gamma, G4double varAngle )
{
G4double result, Qa, Qb, Q, Za, Zb, Ma, Mb ;
Za = GetPlateFormationZone(energy,gamma,varAngle) ;
// Zb = GetGasFormationZone(energy,gamma,varAngle) ;
Ma = GetPlateLinearPhotoAbs(energy) ;
Mb = GetGasLinearPhotoAbs(energy) ;
Qa = exp(-fPlateThick*Ma) ;
Qb = exp(-fGasThick*Mb) ;
Q = Qa*Qb ;
/* *****************************************************
// G4complex Ca(1.0+0.5*fPlateThick*Ma,fPlateThick/Za) ;
// G4complex Cb(1.0+0.5*fGasThick*Mb,fGasThick/Zb) ;
G4complex Ha( exp(-0.5*fPlateThick*Ma)*cos(fPlateThick/Za),
-exp(-0.5*fPlateThick*Ma)*sin(fPlateThick/Za) ) ;
G4complex Hb( exp(-0.5*fGasThick*Mb)*cos(fGasThick/Zb),
-exp(-0.5*fGasThick*Mb)*sin(fGasThick/Za) ) ;
G4complex H = Ha*Hb ;
G4complex F1 = ( 0.5*(1+Qa)*(1+H) - Ha - Qa*Hb )/(1-H) ;
G4complex F2 = (1-Ha)*(Qa-Ha)*Hb/(1-H)/(Q-H) ;
F2 *= pow(Q,G4double(fPlateNumber)) - G4std::pow(H,fPlateNumber) ;
result = ( 1 - pow(Q,G4double(fPlateNumber)) )/( 1 - Q ) ;
result *= 2.0*G4std::real(F1) ;
result += 2.0*G4std::real(F2) ;
***************************************************************** */
result = ( 1 - pow(Q,G4double(fPlateNumber)) )/( 1 - Q ) ;
result *= 1 + Qa -2*sqrt(Qa)*cos(fPlateThick/Za) ;
return result ;
}
//
//
////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,118 @@
// This code implementation is the intellectual property of
// the GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4RegularXrayTRmodel.cc,v 1.1 2000/11/14 16:09:07 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
#include "g4std/complex"
#include "G4RegularXrayTRmodel.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4RegularXrayTRmodel::G4RegularXrayTRmodel(G4Envelope *anEnvelope,
G4double a, G4double b) :
G4VXrayTRmodel(anEnvelope,a,b)
{
G4cout<<"Regular X-ray TR radiator model is called"<<G4endl ;
// Build energy and angular integral spectra of X-ray TR photons from
// a radiator
BuildTable() ;
}
///////////////////////////////////////////////////////////////////////////
G4RegularXrayTRmodel::~G4RegularXrayTRmodel()
{
;
}
///////////////////////////////////////////////////////////////////////////
//
// Approximation for radiator interference factor for the case of
// fully Regular radiator. The plate and gas gap thicknesses are fixed .
// The mean values of the plate and gas gap thicknesses
// are supposed to be about XTR formation zones but much less than
// mean absorption length of XTR photons in coresponding material.
G4double
G4RegularXrayTRmodel::GetStackFactor( G4double energy,
G4double gamma, G4double varAngle )
{
G4double result, Qa, Qb, Q, aZa, bZb, aMa, bMb, I2 ;
aZa = fPlateThick/GetPlateFormationZone(energy,gamma,varAngle) ;
bZb = fGasThick/GetGasFormationZone(energy,gamma,varAngle) ;
aMa = fPlateThick*GetPlateLinearPhotoAbs(energy) ;
bMb = fGasThick*GetGasLinearPhotoAbs(energy) ;
Qa = exp(-aMa) ;
Qb = exp(-bMb) ;
Q = Qa*Qb ;
// G4complex Ca(1.0+0.5*fPlateThick*Ma,fPlateThick/Za) ;
// G4complex Cb(1.0+0.5*fGasThick*Mb,fGasThick/Zb) ;
G4complex Ha( exp(-0.5*aMa)*cos(aZa),
-exp(-0.5*aMa)*sin(aZa) ) ;
G4complex Hb( exp(-0.5*bMb)*cos(bZb),
-exp(-0.5*bMb)*sin(bZb) ) ;
G4complex H = Ha*Hb ;
G4complex Hs = G4std::conj(H) ;
// G4complex F1 = ( 0.5*(1+Qa)*(1+H) - Ha - Qa*Hb )/(1-H) ;
G4complex F2 = (1.0-Ha)*(Qa-Ha)*Hb*(1.0-Hs)*(Q-Hs) ;
F2 *= pow(Q,G4double(fPlateNumber)) - G4std::pow(H,fPlateNumber) ;
result = ( 1 - pow(Q,G4double(fPlateNumber)) )/( 1 - Q ) ;
result *= (1 - Qa)*(1 + Qa - 2*sqrt(Qa)*cos(aZa)) ;
result /= (1 - sqrt(Q))*(1 - sqrt(Q)) +
4*sqrt(Q)*sin(0.5*(aZa+bZb))*sin(0.5*(aZa+bZb)) ;
I2 = 2.0*G4std::real(F2) ;
I2 /= (1 - sqrt(Q))*(1 - sqrt(Q)) +
4*sqrt(Q)*sin(0.5*(aZa+bZb))*sin(0.5*(aZa+bZb)) ;
I2 /= Q*( (sqrt(Q)-cos(aZa+bZb))*(sqrt(Q)-cos(aZa+bZb)) +
sin(aZa+bZb)*sin(aZa+bZb) ) ;
result += I2 ;
return result ;
}
//
//
////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,138 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VClusterModel.cc,v 1.1 2000/11/14 16:09:21 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
#include "G4Timer.hh"
#include "G4VClusterModel.hh"
#include "Randomize.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
#include "globals.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
#include "G4Gamma.hh"
#include "G4TransportationManager.hh"
#include "G4VSensitiveDetector.hh"
#include "G4VTouchable.hh"
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4VClusterModel::G4VClusterModel(const G4String& modelName,G4Envelope *anEnvelope) :
G4VFastSimulationModel(modelName,anEnvelope)
{
fFakeStep = new G4Step() ;
fFakePreStepPoint = fFakeStep->GetPreStepPoint() ;
fFakePostStepPoint = fFakeStep->GetPostStepPoint() ;
fTouchable = new G4TouchableHistory ;
fNavigator = new G4Navigator ;
fNavigatorSetup = false ;
}
///////////////////////////////////////////////////////////////////////////
G4VClusterModel::~G4VClusterModel()
{
delete fFakeStep ;
delete fTouchable ;
delete fNavigator ;
}
//////////////////////////////////////////////////////////////////////////////
//
//
void G4VClusterModel::BuildDetectorResponse()
{
for( G4int i = 0 ; i < fClusterEnergyVector.entries() ; i++ )
{
AssignClusterHit(fClusterPositionVector[i],fClusterEnergyVector[i]) ;
}
fClusterPositionVector.clear() ;
fClusterEnergyVector.clear() ;
}
//////////////////////////////////////////////////////////////////////////////
//
//
void G4VClusterModel::AssignClusterHit(const G4ThreeVector& position,
G4double energy )
{
// "converts" the energy spot into the fake
// G4Step to pass to sensitive detector:
FillFakeStep(position,energy) ;
// call sensitive part: taken/adapted from the stepping:
// Send G4Step information to Hit/Dig if the volume is sensitive
G4VPhysicalVolume* pCurrentVolume = fFakeStep->GetPreStepPoint()->
GetPhysicalVolume() ;
G4VSensitiveDetector* pSensitive ;
if( pCurrentVolume != 0 )
{
pSensitive = pCurrentVolume->GetLogicalVolume()->GetSensitiveDetector() ;
if( pSensitive != 0 ) pSensitive->Hit(fFakeStep) ;
}
}
//////////////////////////////////////////////////////////////////////////////
//
//
void G4VClusterModel::FillFakeStep(const G4ThreeVector& position,
G4double energy )
{
// find in which volume the spot is.
if (!fNavigatorSetup)
{
fNavigator->SetWorldVolume(G4TransportationManager::GetTransportationManager()->
GetNavigatorForTracking()->GetWorldVolume()) ;
fNavigator->LocateGlobalPointAndUpdateTouchable(position,fTouchable,false);
fNavigatorSetup = true;
}
else
{
fNavigator->LocateGlobalPointAndUpdateTouchable(position,fTouchable);
}
// Fills attribute of the G4Step needed
// by our sensitive detector:
//
// set touchable volume at PreStepPoint:
fFakePreStepPoint->SetTouchable(fTouchable) ;
// set total energy deposit:
fFakeStep->SetTotalEnergyDeposit(energy) ;
return ;
}
//
//
///////////////////////////////////////////////////////////////////////
@@ -0,0 +1,915 @@
// This code implementation is the intellectual property of
// the GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VXrayTRmodel.cc,v 1.1 2000/11/14 16:09:34 gcosmo Exp $
// GEANT4 tag $Name: geant4-03-00 $
//
#include "G4Timer.hh"
#include "G4VXrayTRmodel.hh"
#include "Randomize.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
#include "globals.hh"
#include "G4PhysicsTable.hh"
#include "G4PhysicsVector.hh"
#include "G4PhysicsLinearVector.hh"
#include "G4PhysicsLogVector.hh"
#include "G4Integrator.hh"
#include "G4Gamma.hh"
// Initialization of local constants
G4double G4VXrayTRmodel::fTheMinEnergyTR = 1.0*keV ;
G4double G4VXrayTRmodel::fTheMaxEnergyTR = 100.0*keV ;
G4double G4VXrayTRmodel::fTheMaxAngle = 1.0e-3 ;
G4double G4VXrayTRmodel::fTheMinAngle = 5.0e-6 ;
G4int G4VXrayTRmodel::fBinTR = 50 ;
G4double G4VXrayTRmodel::fMinProtonTkin = 100.0*GeV ;
G4double G4VXrayTRmodel::fMaxProtonTkin = 100.0*TeV ;
G4int G4VXrayTRmodel::fTotBin = 50 ;
// Proton energy vector initialization
G4PhysicsLogVector* G4VXrayTRmodel::
fProtonEnergyVector = new G4PhysicsLogVector(fMinProtonTkin,
fMaxProtonTkin,
fTotBin ) ;
G4double G4VXrayTRmodel::fPlasmaCof = 4.0*pi*fine_structure_const*
hbarc*hbarc*hbarc/electron_mass_c2 ;
G4double G4VXrayTRmodel::fCofTR = fine_structure_const/pi ;
////////////////////////////////////////////////////////////////////////////
//
// Constructor, destructor
G4VXrayTRmodel::G4VXrayTRmodel(G4Envelope *anEnvelope, G4double a, G4double b) :
G4VFastSimulationModel("G4VXrayTRmodel",anEnvelope)
// , G4ForwardXrayTR("G4VXrayTRmodel")
{
fPlateNumber = anEnvelope->GetNoDaughters() ;
G4cout<<"the number of TR radiator plates = "<<fPlateNumber<<G4endl ;
if(fPlateNumber == 0)
{
G4Exception("No plates in X-ray TR radiator") ;
}
// Mean thicknesses of plates and gas gaps
fPlateThick = a ;
fGasThick = b ;
// index of plate material
fMatIndex1 = anEnvelope->GetDaughter(0)->GetLogicalVolume()->
GetMaterial()->GetIndex() ;
// index of gas material
fMatIndex2 = anEnvelope->GetMaterial()->GetIndex() ;
// plasma energy squared for plate material
fSigma1 = fPlasmaCof*anEnvelope->GetDaughter(0)->GetLogicalVolume()->
GetMaterial()->GetElectronDensity() ;
// fSigma1 = (20.9*eV)*(20.9*eV) ;
G4cout<<"plate plasma energy = "<<sqrt(fSigma1)/eV<<" eV"<<G4endl ;
// plasma energy squared for gas material
fSigma2 = fPlasmaCof*anEnvelope->GetMaterial()->GetElectronDensity() ;
G4cout<<"gas plasma energy = "<<sqrt(fSigma2)/eV<<" eV"<<G4endl ;
// Compute cofs for preparation of linear photo absorption
ComputePlatePhotoAbsCof() ;
ComputeGasPhotoAbsCof() ;
}
///////////////////////////////////////////////////////////////////////////
G4VXrayTRmodel::~G4VXrayTRmodel()
{
G4int i ;
for(i=0;i<fGasIntervalNumber;i++)
{
delete[] fGasPhotoAbsCof[i] ;
}
delete[] fGasPhotoAbsCof ;
for(i=0;i<fPlateIntervalNumber;i++)
{
delete[] fPlatePhotoAbsCof[i] ;
}
delete[] fPlatePhotoAbsCof ;
}
///////////////////////////////////////////////////////////////////////////////
//
// Returns condition for application of the model depending on particle type
G4bool G4VXrayTRmodel::IsApplicable(const G4ParticleDefinition& particle)
{
return ( particle.GetPDGCharge() != 0.0 ) ;
}
/////////////////////////////////////////////////////////////////////
//
// UserTrigger() method: method which has to decide if
// the parameterisation has to be applied.
// Here ModelTrigger() asks the user (ie you) a 0/1 answer.
//
// Note that quantities like the local/global position/direction etc..
// are available at this level via the fastTrack parameter (allowing
// to check distance from boundaries, see below to allow the decision)
//
G4bool G4VXrayTRmodel::ModelTrigger(const G4FastTrack& fastTrack)
{
// G4double mass = fastTrack.GetPrimaryTrack()->GetDefinition()->GetPDGMass() ;
// G4double kinEnergy = fastTrack.GetPrimaryTrack()->GetKineticEnergy() ;
// G4double gamma = 1.0 + kinEnergy/mass ; // Lorentz factor
// G4cout << "gamma = " << gamma << G4endl ;
// if (gamma >= 100.0) return true ;
// else return false ;
return true ;
}
//////////////////////////////////////////////////////////////////////////////
//
//
void G4VXrayTRmodel::DoIt( const G4FastTrack& fastTrack ,
G4FastStep& fastStep )
{
G4int iTkin, iPlace, numOfTR, iTR, iTransfer ;
G4double energyPos, energyTR, theta, phi, dirX, dirY, dirZ ;
G4double W, W1, W2, E1, E2 ;
G4double charge = fastTrack.GetPrimaryTrack()->GetDefinition()->GetPDGCharge() ;
// Now we are ready to Generate TR photons
G4double chargeSq = charge*charge ;
G4double kinEnergy = fastTrack.GetPrimaryTrack()->GetKineticEnergy() ;
G4double mass = fastTrack.GetPrimaryTrack()->GetDefinition()->GetPDGMass() ;
G4double gamma = 1.0 + kinEnergy/mass ;
// G4cout<<"gamma = "<<gamma<<G4endl ;
G4double massRatio = proton_mass_c2/mass ;
G4double TkinScaled = kinEnergy*massRatio ;
G4ParticleMomentum direction(fastTrack.GetPrimaryTrackLocalDirection());
G4double distance = fastTrack.GetEnvelopeSolid()->
DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(),
direction) ;
G4ThreeVector position = fastTrack.GetPrimaryTrackLocalPosition() +
distance*direction ;
// Set final position:
fastStep.SetPrimaryTrackFinalPosition(position);
for(iTkin=0;iTkin<fTotBin;iTkin++)
{
if(TkinScaled < fProtonEnergyVector->GetLowEdgeEnergy(iTkin)) break ;
}
iPlace = iTkin - 1 ;
// G4ParticleMomentum particleDir = fastTrack.GetPrimaryTrack()->
// GetMomentumDirection() ;
if(iTkin == 0) // Tkin is too small, neglect of TR photon generation
{
return ;
}
else // general case: Tkin between two vectors of the material
{
if(iTkin == fTotBin)
{
numOfTR = RandPoisson::shoot( (*(*fEnergyDistrTable)(iPlace))(0)*chargeSq ) ;
}
else
{
E1 = fProtonEnergyVector->GetLowEdgeEnergy(iTkin - 1) ;
E2 = fProtonEnergyVector->GetLowEdgeEnergy(iTkin) ;
W = 1.0/(E2 - E1) ;
W1 = (E2 - TkinScaled)*W ;
W2 = (TkinScaled - E1)*W ;
numOfTR = RandPoisson::shoot( ( (*(*fEnergyDistrTable)(iPlace))(0)*W1+
(*(*fEnergyDistrTable)(iPlace+1))(0)*W2 )
*chargeSq ) ;
}
// G4cout<<iTkin<<" mean TR number = "<<(((*(*fEnergyDistrTable)(iPlace))(0)+
// (*(*fAngleDistrTable)(iPlace))(0))*W1 +
// ((*(*fEnergyDistrTable)(iPlace + 1))(0)+
// (*(*fAngleDistrTable)(iPlace + 1))(0))*W2)
// *chargeSq*0.5<<endl ;
if( numOfTR == 0 ) // no change, return
{
return ;
}
else
{
// G4cout<<"Number of X-ray TR photons = "<<numOfTR<<endl ;
fastStep.SetNumberOfSecondaries(numOfTR);
G4double sumEnergyTR = 0.0 ;
for(iTR=0;iTR<numOfTR;iTR++)
{
// energyPos = ((*(*fEnergyDistrTable)(iPlace))(0)*W1+
// (*(*fEnergyDistrTable)(iPlace + 1))(0)*W2)*G4UniformRand() ;
// for(iTransfer=0;iTransfer<fBinTR-1;iTransfer++)
// {
// if(energyPos >= ((*(*fEnergyDistrTable)(iPlace))(iTransfer)*W1+
// (*(*fEnergyDistrTable)(iPlace + 1))(iTransfer)*W2)) break ;
// }
// energyTR = ((*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer))*W1+
// ((*fEnergyDistrTable)(iPlace + 1)->GetLowEdgeEnergy(iTransfer))*W2 ;
energyTR = GetXTRrandomEnergy(TkinScaled,iTkin) ;
// G4cout<<"energyTR = "<<energyTR/keV<<"keV"<<endl ;
sumEnergyTR += energyTR ;
theta = abs(G4RandGauss::shoot(0.0,pi/gamma)) ;
if( theta >= 0.1 ) theta = 0.1 ;
// G4cout<<" : theta = "<<theta<<endl ;
phi = twopi*G4UniformRand() ;
dirX = sin(theta)*cos(phi) ;
dirY = sin(theta)*sin(phi) ;
dirZ = cos(theta) ;
G4ThreeVector directionTR(dirX,dirY,dirZ) ;
directionTR.rotateUz(direction) ;
directionTR.unit() ;
G4DynamicParticle aPhotonTR(G4Gamma::Gamma(),directionTR,energyTR) ;
G4ThreeVector positionTR = fastTrack.GetPrimaryTrackLocalPosition() +
G4UniformRand()*distance*direction ;
G4double distanceTR = fastTrack.GetEnvelopeSolid()->
DistanceToOut(positionTR,directionTR) ;
positionTR = positionTR + distanceTR*directionTR ;
fastStep.CreateSecondaryTrack( aPhotonTR,
positionTR,
fastTrack.GetPrimaryTrack()->
GetGlobalTime() ) ;
}
kinEnergy -= sumEnergyTR ;
fastStep.SetPrimaryTrackFinalKineticEnergy(kinEnergy) ;
}
}
return ;
}
//////////////////////////////////////////////////////////////////////////
//
// User method to code the parameterisation properly
// said. This is simple example of creation of one X-ray photon with the
// energy in the range of around 5 keV produced by relativistic charged
// particle
//
void G4VXrayTRmodel::ExampleDoIt( const G4FastTrack& fastTrack ,
G4FastStep& fastStep )
{
// The primary track continues along its direction.
// One secondary (a photon) is added:
// G4cout << " TR `model' applied \n " << endl;
// Primary: idem as in "DefaultModel":
//
G4double distance = fastTrack.GetEnvelopeSolid()->
DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(),
fastTrack.GetPrimaryTrackLocalDirection()) ;
G4ThreeVector position = fastTrack.GetPrimaryTrackLocalPosition() +
distance*fastTrack.GetPrimaryTrackLocalDirection() ;
// Set final position:
fastStep.SetPrimaryTrackFinalPosition(position);
//---------------------------
// Secondary: Adds one "secondary":
//
// First, user has to say how many secondaries will be created:
fastStep.SetNumberOfSecondaryTracks(1);
// Build the secondary direction:
G4ParticleMomentum direction(fastTrack.GetPrimaryTrackLocalDirection());
// direction.setZ(direction.z()*0.5);
// direction.setY(direction.y()+direction.z()*0.1);
direction = direction.unit(); // necessary !?
// Dynamics (Note that many constructors exists for G4DynamicParticle
G4double gammaEnergy = 3.0*keV + G4UniformRand()*2*keV ;
G4DynamicParticle dynamique(G4Gamma::GammaDefinition(),
direction,
// fastTrack.GetPrimaryTrack()->GetKineticEnergy()/2.
gammaEnergy );
// -- position:
G4double Dist = fastTrack.GetEnvelopeSolid()->
DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(),direction) ;
G4ThreeVector posi = fastTrack.GetPrimaryTrackLocalPosition() + Dist*direction ;
// Creation of the secondary Track:
fastStep.CreateSecondaryTrack( dynamique,
posi,
fastTrack.GetPrimaryTrack()->GetGlobalTime());
}
//////////////////////////////////////////////////////////////////////
//
// Calculates formation zone for plates. Omega is energy !!!
G4double G4VXrayTRmodel::GetPlateFormationZone( G4double omega ,
G4double gamma ,
G4double varAngle )
{
G4double cof, lambda ;
lambda = 1.0/gamma/gamma + varAngle + fSigma1/omega/omega ;
cof = 2.0*hbarc/omega/lambda ;
return cof ;
}
////////////////////////////////////////////////////////////////////////
//
// Computes matrix of Sandia photo absorption cross section coefficients for
// plate material
void G4VXrayTRmodel::ComputePlatePhotoAbsCof()
{
G4int i, j, numberOfElements ;
static const G4MaterialTable*
theMaterialTable = G4Material::GetMaterialTable();
G4SandiaTable thisMaterialSandiaTable(fMatIndex1) ;
numberOfElements = (*theMaterialTable)[fMatIndex1]->GetNumberOfElements() ;
G4int* thisMaterialZ = new G4int[numberOfElements] ;
for(i=0;i<numberOfElements;i++)
{
thisMaterialZ[i] = (G4int)(*theMaterialTable)[fMatIndex1]->
GetElement(i)->GetZ() ;
}
fPlateIntervalNumber = thisMaterialSandiaTable.SandiaIntervals
(thisMaterialZ,numberOfElements) ;
fPlateIntervalNumber = thisMaterialSandiaTable.SandiaMixing
( thisMaterialZ ,
(*theMaterialTable)[fMatIndex1]->GetFractionVector() ,
numberOfElements,fPlateIntervalNumber) ;
fPlatePhotoAbsCof = new G4double*[fPlateIntervalNumber] ;
for(i=0;i<fPlateIntervalNumber;i++)
{
fPlatePhotoAbsCof[i] = new G4double[5] ;
}
for(i=0;i<fPlateIntervalNumber;i++)
{
fPlatePhotoAbsCof[i][0] = thisMaterialSandiaTable.
GetPhotoAbsorpCof(i+1,0) ;
for(j=1;j<5;j++)
{
fPlatePhotoAbsCof[i][j] = thisMaterialSandiaTable.
GetPhotoAbsorpCof(i+1,j)*
(*theMaterialTable)[fMatIndex1]->GetDensity() ;
}
}
delete[] thisMaterialZ ;
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Returns the value of linear photo absorption coefficient (in reciprocal
// length) for plate for given energy of X-ray photon omega
G4double G4VXrayTRmodel::GetPlateLinearPhotoAbs(G4double omega)
{
G4int i ;
G4double omega2, omega3, omega4 ;
omega2 = omega*omega ;
omega3 = omega2*omega ;
omega4 = omega2*omega2 ;
for(i=0;i<fPlateIntervalNumber;i++)
{
if( omega < fPlatePhotoAbsCof[i][0] ) break ;
}
if( i == 0 )
{
G4Exception("Invalid (<I1) energy in G4VXrayTRmodel::GetPlateLinearPhotoAbs");
}
else i-- ;
return fPlatePhotoAbsCof[i][1]/omega + fPlatePhotoAbsCof[i][2]/omega2 +
fPlatePhotoAbsCof[i][3]/omega3 + fPlatePhotoAbsCof[i][4]/omega4 ;
}
//////////////////////////////////////////////////////////////////////
//
// Calculates formation zone for gas. Omega is energy !!!
G4double G4VXrayTRmodel::GetGasFormationZone( G4double omega ,
G4double gamma ,
G4double varAngle )
{
G4double cof, lambda ;
lambda = 1.0/gamma/gamma + varAngle + fSigma2/omega/omega ;
cof = 2.0*hbarc/omega/lambda ;
return cof ;
}
////////////////////////////////////////////////////////////////////////
//
// Computes matrix of Sandia photo absorption cross section coefficients for
// gas material
void G4VXrayTRmodel::ComputeGasPhotoAbsCof()
{
G4int i, j, numberOfElements ;
static const G4MaterialTable*
theMaterialTable = G4Material::GetMaterialTable();
G4SandiaTable thisMaterialSandiaTable(fMatIndex2) ;
numberOfElements = (*theMaterialTable)[fMatIndex2]->GetNumberOfElements() ;
G4int* thisMaterialZ = new G4int[numberOfElements] ;
for(i=0;i<numberOfElements;i++)
{
thisMaterialZ[i] = (G4int)(*theMaterialTable)[fMatIndex2]->
GetElement(i)->GetZ() ;
}
fGasIntervalNumber = thisMaterialSandiaTable.SandiaIntervals
(thisMaterialZ,numberOfElements) ;
fGasIntervalNumber = thisMaterialSandiaTable.SandiaMixing
( thisMaterialZ ,
(*theMaterialTable)[fMatIndex2]->GetFractionVector() ,
numberOfElements,fGasIntervalNumber) ;
fGasPhotoAbsCof = new G4double*[fGasIntervalNumber] ;
for(i=0;i<fGasIntervalNumber;i++)
{
fGasPhotoAbsCof[i] = new G4double[5] ;
}
for(i=0;i<fGasIntervalNumber;i++)
{
fGasPhotoAbsCof[i][0] = thisMaterialSandiaTable.
GetPhotoAbsorpCof(i+1,0) ;
for(j=1;j<5;j++)
{
fGasPhotoAbsCof[i][j] = thisMaterialSandiaTable.
GetPhotoAbsorpCof(i+1,j)*
(*theMaterialTable)[fMatIndex2]->GetDensity() ;
}
}
delete[] thisMaterialZ ;
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Returns the value of linear photo absorption coefficient (in reciprocal
// length) for gas
G4double G4VXrayTRmodel::GetGasLinearPhotoAbs(G4double omega)
{
G4int i ;
G4double omega2, omega3, omega4 ;
omega2 = omega*omega ;
omega3 = omega2*omega ;
omega4 = omega2*omega2 ;
for(i=0;i<fGasIntervalNumber;i++)
{
if( omega < fGasPhotoAbsCof[i][0] ) break ;
}
if( i == 0 )
{
G4Exception("Invalid (<I1) energy in G4VXrayTRmodel::GetGasLinearPhotoAbs");
}
else i-- ;
return fGasPhotoAbsCof[i][1]/omega + fGasPhotoAbsCof[i][2]/omega2 +
fGasPhotoAbsCof[i][3]/omega3 + fGasPhotoAbsCof[i][4]/omega4 ;
}
//////////////////////////////////////////////////////////////////////
//
// Calculates the product of linear cof by formation zone for plate.
// Omega is energy !!!
G4double G4VXrayTRmodel::GetPlateZmuProduct( G4double omega ,
G4double gamma ,
G4double varAngle )
{
return GetPlateFormationZone(omega,gamma,varAngle)*GetPlateLinearPhotoAbs(omega) ;
}
//////////////////////////////////////////////////////////////////////
//
// Calculates the product of linear cof by formation zone for plate.
// G4cout and output in file in some energy range.
void G4VXrayTRmodel::GetPlateZmuProduct()
{
G4std::ofstream outPlate("plateZmu.dat", G4std::ios::out ) ;
outPlate.setf( G4std::ios::scientific, G4std::ios::floatfield );
G4int i ;
G4double omega, varAngle, gamma, result ;
gamma = 10000. ;
varAngle = 1/gamma/gamma ;
G4cout<<"energy, keV"<<"\t"<<"Zmu for plate"<<G4endl ;
for(i=0;i<100;i++)
{
omega = (1.0 + i)*keV ;
G4cout<<omega/keV<<"\t"<<GetPlateZmuProduct(omega,gamma,varAngle)<<"\t" ;
outPlate<<omega/keV<<"\t\t"<<GetPlateZmuProduct(omega,gamma,varAngle)<<G4endl ;
}
return ;
}
//////////////////////////////////////////////////////////////////////
//
// Calculates the product of linear cof by formation zone for gas.
// Omega is energy !!!
G4double G4VXrayTRmodel::GetGasZmuProduct( G4double omega ,
G4double gamma ,
G4double varAngle )
{
return GetGasFormationZone(omega,gamma,varAngle)*GetGasLinearPhotoAbs(omega) ;
}
//////////////////////////////////////////////////////////////////////
//
// Calculates the product of linear cof byformation zone for gas.
// G4cout and output in file in some energy range.
void G4VXrayTRmodel::GetGasZmuProduct()
{
G4std::ofstream outGas("gasZmu.dat", G4std::ios::out ) ;
outGas.setf( G4std::ios::scientific, G4std::ios::floatfield );
G4int i ;
G4double omega, varAngle, gamma, result ;
gamma = 10000. ;
varAngle = 1/gamma/gamma ;
G4cout<<"energy, keV"<<"\t"<<"Zmu for gas"<<G4endl ;
for(i=0;i<100;i++)
{
omega = (1.0 + i)*keV ;
G4cout<<omega/keV<<"\t"<<GetGasZmuProduct(omega,gamma,varAngle)<<"\t" ;
outGas<<omega/keV<<"\t\t"<<GetGasZmuProduct(omega,gamma,varAngle)<<G4endl ;
}
return ;
}
///////////////////////////////////////////////////////////////////////
//
// This function returns the spectral and angle density of TR quanta
// in X-ray energy region generated forward when a relativistic
// charged particle crosses interface between two materials.
// The high energy small theta approximation is applied.
// (matter1 -> matter2, or 2->1)
// varAngle =2* (1 - cos(theta)) or approximately = theta*theta
//
G4double
G4VXrayTRmodel::OneBoundaryXTRNdensity( G4double energy,G4double gamma,
G4double varAngle ) const
{
G4double formationLength1, formationLength2 ;
formationLength1 = 1.0/
(1.0/(gamma*gamma)
+ fSigma1/(energy*energy)
+ varAngle) ;
formationLength2 = 1.0/
(1.0/(gamma*gamma)
+ fSigma2/(energy*energy)
+ varAngle) ;
return (varAngle/energy)*(formationLength1 - formationLength2)
*(formationLength1 - formationLength2) ;
}
//////////////////////////////////////////////////////////////////////////
//
//
void G4VXrayTRmodel::BuildTable()
{
G4int iMat, jMat, iTkin, iTR, iPlace ;
G4double radiatorCof = 1.0 ; // for tuning of XTR yield
// fAngleDistrTable = new G4PhysicsTable(fTotBin) ;
fEnergyDistrTable = new G4PhysicsTable(fTotBin) ;
fGammaTkinCut = 0.0 ;
// setting of min/max TR energies
if(fGammaTkinCut > fTheMinEnergyTR) fMinEnergyTR = fGammaTkinCut ;
else fMinEnergyTR = fTheMinEnergyTR ;
if(fGammaTkinCut > fTheMaxEnergyTR) fMaxEnergyTR = 2.0*fGammaTkinCut ;
else fMaxEnergyTR = fTheMaxEnergyTR ;
G4cout.precision(4) ;
G4Timer timer ;
timer.Start() ;
for(iTkin=0;iTkin<fTotBin;iTkin++) // Lorentz factor loop
{
G4PhysicsLogVector* energyVector = new G4PhysicsLogVector( fMinEnergyTR,
fMaxEnergyTR,
fBinTR ) ;
fGamma = 1.0 + (fProtonEnergyVector->
GetLowEdgeEnergy(iTkin)/proton_mass_c2) ;
fMaxThetaTR = 25.0/(fGamma*fGamma) ; // theta^2
fTheMinAngle = 1.0e-6 ; // was 5.e-6, e-5, e-4
if( fMaxThetaTR > fTheMaxAngle ) fMaxThetaTR = fTheMaxAngle ;
else
{
if( fMaxThetaTR < fTheMinAngle ) fMaxThetaTR = fTheMinAngle ;
}
G4PhysicsLinearVector* angleVector = new G4PhysicsLinearVector( 0.0,
fMaxThetaTR,
fBinTR ) ;
G4double energySum = 0.0 ;
G4double angleSum = 0.0 ;
G4Integrator<G4VXrayTRmodel,G4double(G4VXrayTRmodel::*)(G4double)> integral ;
energyVector->PutValue(fBinTR-1,energySum) ;
angleVector->PutValue(fBinTR-1,angleSum) ;
for(iTR=fBinTR-2;iTR>=0;iTR--)
{
energySum += radiatorCof*fCofTR*integral.Legendre10(
this,&G4VXrayTRmodel::XTRNSpectralDensity,
energyVector->GetLowEdgeEnergy(iTR),
energyVector->GetLowEdgeEnergy(iTR+1) ) ;
// angleSum += fCofTR*integral.Legendre96(
// this,&G4VXrayTRmodel::XTRNSpectralDensity,
// angleVector->GetLowEdgeEnergy(iTR),
// angleVector->GetLowEdgeEnergy(iTR+1) ) ;
energyVector->PutValue(iTR,energySum) ;
// angleVector ->PutValue(iTR,angleSum) ;
}
G4cout<<iTkin<<"\t"
<<"fGamma = "<<fGamma<<"\t" // <<" fMaxThetaTR = "<<fMaxThetaTR
<<"sumE = "<<energySum // <<" ; sumA = "<<angleSum
<<G4endl ;
iPlace = iTkin ;
fEnergyDistrTable->insertAt(iPlace,energyVector) ;
// fAngleDistrTable->insertAt(iPlace,angleVector) ;
}
timer.Stop() ;
G4cout.precision(6) ;
G4cout<<G4endl ;
G4cout<<"total time for build X-ray TR tables = "
<<timer.GetUserElapsed()<<" s"<<G4endl ;
return ;
}
//////////////////////////////////////////////////////////////////////////
//
//
void G4VXrayTRmodel::BuildEnergyTable()
{
return ;
}
////////////////////////////////////////////////////////////////////////
//
//
void G4VXrayTRmodel::BuildAngleTable()
{
return ;
}
//////////////////////////////////////////////////////////////////////////////
//
// For photon energy distribution tables. Integrate first over angle
//
G4double G4VXrayTRmodel::XTRNSpectralAngleDensity(G4double varAngle)
{
return OneBoundaryXTRNdensity(fEnergy,fGamma,varAngle)*
GetStackFactor(fEnergy,fGamma,varAngle) ;
}
/////////////////////////////////////////////////////////////////////////
//
// For second integration over energy
G4double G4VXrayTRmodel::XTRNSpectralDensity(G4double energy)
{
fEnergy = energy ;
G4Integrator<G4VXrayTRmodel,G4double(G4VXrayTRmodel::*)(G4double)> integral ;
return integral.Legendre96(this,&G4VXrayTRmodel::XTRNSpectralAngleDensity,
0.0,0.2*fMaxThetaTR) +
integral.Legendre10(this,&G4VXrayTRmodel::XTRNSpectralAngleDensity,
0.2*fMaxThetaTR,fMaxThetaTR) ;
}
//////////////////////////////////////////////////////////////////////////
//
// for photon angle distribution tables
//
G4double G4VXrayTRmodel::XTRNAngleSpectralDensity(G4double energy)
{
return OneBoundaryXTRNdensity(energy,fGamma,fVarAngle)*
GetStackFactor(energy,fGamma,fVarAngle) ;
}
///////////////////////////////////////////////////////////////////////////
//
//
G4double G4VXrayTRmodel::XTRNAngleDensity(G4double varAngle)
{
fVarAngle = varAngle ;
G4Integrator<G4VXrayTRmodel,G4double(G4VXrayTRmodel::*)(G4double)> integral ;
return integral.Legendre96(this,&G4VXrayTRmodel::XTRNAngleSpectralDensity,
fMinEnergyTR,fMaxEnergyTR) ;
}
//////////////////////////////////////////////////////////////////////////////
//
// Check number of photons for a range of Lorentz factors from both energy
// and angular tables
void G4VXrayTRmodel::GetNumberOfPhotons()
{
G4int iTkin ;
G4double gamma, numberE, numberA ;
G4std::ofstream outEn("numberE.dat", G4std::ios::out ) ;
outEn.setf( G4std::ios::scientific, G4std::ios::floatfield );
G4std::ofstream outAng("numberAng.dat", G4std::ios::out ) ;
outAng.setf( G4std::ios::scientific, G4std::ios::floatfield );
for(iTkin=0;iTkin<fTotBin;iTkin++) // Lorentz factor loop
{
gamma = 1.0 + (fProtonEnergyVector->
GetLowEdgeEnergy(iTkin)/proton_mass_c2) ;
numberE = (*(*fEnergyDistrTable)(iTkin))(0) ;
// numberA = (*(*fAngleDistrTable)(iTkin))(0) ;
G4cout<<gamma<<"\t\t"<<numberE<<"\t" // <<numberA
<<G4endl ;
outEn<<gamma<<"\t\t"<<numberE<<G4endl ;
// outAng<<gamma<<"\t\t"<<numberA<<G4endl ;
}
return ;
}
/////////////////////////////////////////////////////////////////////////
//
// Returns randon energy of a X-ray TR photon for given scaled kinetic energy
// of a charged particle
G4double G4VXrayTRmodel::GetXTRrandomEnergy( G4double scaledTkin, G4int iTkin )
{
G4int iTransfer, iPlace ;
G4double transfer = 0.0, position, E1, E2, W1, W2, W ;
iPlace = iTkin - 1 ;
// G4cout<<"iPlace = "<<iPlace<<endl ;
if(iTkin == fTotBin) // relativistic plato, try from left
{
position = (*(*fEnergyDistrTable)(iPlace))(0)*G4UniformRand() ;
for(iTransfer=0;;iTransfer++)
{
if(position >= (*(*fEnergyDistrTable)(iPlace))(iTransfer)) break ;
}
transfer = GetXTRenergy(iPlace,position,iTransfer);
}
else
{
E1 = fProtonEnergyVector->GetLowEdgeEnergy(iTkin - 1) ;
E2 = fProtonEnergyVector->GetLowEdgeEnergy(iTkin) ;
W = 1.0/(E2 - E1) ;
W1 = (E2 - scaledTkin)*W ;
W2 = (scaledTkin - E1)*W ;
position =( (*(*fEnergyDistrTable)(iPlace))(0)*W1 +
(*(*fEnergyDistrTable)(iPlace+1))(0)*W2 )*G4UniformRand() ;
// G4cout<<position<<"\t" ;
for(iTransfer=0;;iTransfer++)
{
if( position >=
( (*(*fEnergyDistrTable)(iPlace))(iTransfer)*W1 +
(*(*fEnergyDistrTable)(iPlace+1))(iTransfer)*W2) ) break ;
}
transfer = GetXTRenergy(iPlace,position,iTransfer);
}
// G4cout<<"XTR transfer = "<<transfer/keV<<" keV"<<endl ;
if(transfer < 0.0 ) transfer = 0.0 ;
return transfer ;
}
////////////////////////////////////////////////////////////////////////
//
// Returns approximate position of X-ray photon energy during random sampling
// over integral energy distribution
G4double G4VXrayTRmodel::GetXTRenergy( G4int iPlace,
G4double position,
G4int iTransfer )
{
G4double x1, x2, y1, y2, result ;
if(iTransfer == 0)
{
result = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
}
else
{
y1 = (*(*fEnergyDistrTable)(iPlace))(iTransfer-1) ;
y2 = (*(*fEnergyDistrTable)(iPlace))(iTransfer) ;
x1 = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer-1) ;
x2 = (*fEnergyDistrTable)(iPlace)->GetLowEdgeEnergy(iTransfer) ;
if ( x1 == x2 ) result = x2 ;
else
{
if ( y1 == y2 ) result = x1 + (x2 - x1)*G4UniformRand() ;
else
{
result = x1 + (position - y1)*(x2 - x1)/(y2 - y1) ;
}
}
}
return result ;
}
//
//
///////////////////////////////////////////////////////////////////////