Import Geant4 4.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-08 16:18:25 +02:00
parent 36c080dca6
commit 921d3b1cda
3990 changed files with 185376 additions and 82884 deletions
@@ -1,4 +1,4 @@
$Id: History,v 1.80 2001/06/18 12:58:43 pia Exp $
$Id: History,v 1.127 2001/11/15 15:56:21 pia Exp $
-------------------------------------------------------------------
=========================================================
@@ -17,6 +17,236 @@ committal in the CVS repository !
* Reverse chronological order (last date on top), please *
----------------------------------------------------------
15.11.2001 - MGP, tag emlowen-V03-02-45
Bug fix in G4FluoData
Physics improvement in Bremsstrahlung
Modified warning message in G4hLowEnergyIonisation
Goes with new database version G4EMLOW0.4
09.11.2001 - MGP, tag emlowen-V03-02-44
Example for using analysis in test/LowEnTest, based on
Ramon's XrayTel
09.11.2001 - MGP, tag emlowen-V03-02-43
Fixed name in test/processTest/GNUmakefile causing
problems with library map
08.11.2001 - MGP, tag emlowen-V03-02-42
Modifications to be compliant with the unsupported,
deprecated "cuts per material"
Added G4CutsPerMaterialWarning functor to warn users
WARNING: LowE processes are not supported if using different
cuts for different materials
06.11.2001 - MGP, tag emlowen-V03-02-41
Identical to emlowen-V03-02-40
Redone because the tag aborted before completion
06.11.2001 - MGP, tag emlowen-V03-02-40
Performance improvement in electron processes
Some clean up of code (include/forward class declarations,
coding style guidelines etc.)
First implementation of a generic unit test, with AIDA/Lizard
analysis in test/processTest
01.11.2001 - MGP, tag emlowen-V03-02-39
PIXE introduced in G4hLowEnergyIonisation
29.10.2001 - MGP, tag emlowen-V03-02-38
Bug fixes in new code
Generic unit test for e/photon processes in test/processTest
(analysis still to be added)
28.10.2001 - MGP, tag emlowen-V03-02-37
Fixed compilation warnings on Linux and HP
Improved code style
26.10.2001 - MGP, tag emlowen-V03-02-36
Bug and memory leak fixes in the new electron classes
26.10.2001 - MGP, tag emlowen-V03-02-35
Swapped old/new electron processes
25.10.2001 - MGP, tag emlowen-V03-02-34
Bug fixes in the new classes related to Bremsstrahlung and
e/h Ionisation
25.10.2001 - MGP, tag emlowen-V03-02-33
G4LowEnergyPolarizedCompton moved to new design
Many bug fixes in G4eIonisationParameters and G4BremsstrahlungParameters
New classes for shell cross sections for proton-induced fluorescence
Fluorescence introduced in temporary class G4hLowEnergyIonisation
Fluorescence introduced in the continuous part of electron
ionisation in G4eLowEnergyLoss and temporary G4LowEnergyIonisationVI
18.10.2001 - MGP, tag emlowen-V03-02-32
Same as previous one, with on top fixes to G4BremsstrahlungParameters.cc
and G4eIonisationParameters.cc by G. Cosmo for compatibility with
geant4-03-02-ref-06 in view of STL migration
18.10.2001 - MGP, tag emlowen-V03-02-31
Added member function in G4eLowEnergyLoss and G4VLowEnergyIonisationVI
for generation of atomic deexcitation products in the continuous part
18.10.2001 - MGP, tag emlowen-V03-02-30
Electron processes: contributions to the implementation by V.I.
revision of code quality and consistency
with design by MGP
18.10.2001 - MGP, tag emlowen-V03-02-29
Modification of G4hNuclearStoppingModel and
G4hParametrisedLossModel by G. Cosmo required for
compatibility with materials-V03-02-04
12.10.2001 - MGP, tag emlowen-V03-02-28
Cosmetics in the source code (FALSE/TRUE moved to false/true)
and update of all tests to new materials migrated to STL
11.10.2001 - MGP, tag emlowen-V03-02-27
Further revision of the new code in the previous tag
Restored G4LowEnergyIonisation and G4LowEnergyBremsstrahlung
as in emlowen-V03-02-25; new versions as in emlowen-V03-02-26
renamed temporarily to allow for parallel development
Removed references to Rogue Wave and STL interface from
test/LowEnTest/ and test/fluoTest/
10.10.2001 - MGP, tag emlowen-V03-02-26
Code for implementation of design iteration for electrons
by V. Ivanchenko
Major revision of new code to improve code quality and consistency
with design by MGP
Since the new code does not respect the design and broke system
test and user code, this tag is only for internal debugging
purpose and should not be used by developers
09.10.2001 - MGP, tag emlowen-V03-02-25
Identical to the previous one, but restored G4VDataSetAlgorithm
(corrupted in cvs update?)
08.10.2001 - MGP, tag emlowen-V03-02-24
Modified G4CrossSectionHandler to inherit from base class
Minor design iteration in G4VEMDataSet and G4VDataSetAlgorithm
Encapsulated range test to generate secondaries into a
strategy pattern; implemented in photon processes
04.10.2001 - MGP, tag emlowen-V03-02-23
Fluorescence according to the new design introduced
into e- ionisation (contribution to PostStepDoIt)
by E. Guardincerri
26.09.2001 - MGP, tag emlowen-V03-02-22
Workaround to support deficiencies of ObjectSpace in
implementation of STL pair
25.09.2001 - MGP, tag emlowen-V03-02-21
Workaround to support deficiencies of ObjectSpace in
implementation of STL pair (wrongly tagged)
24.09.2001 - MGP, tag emlowen-V03-02-20
Minor modifications to make the lowenergy category co-work
with both materials-V03-02-03 and materials as
in geant4-03-02-ref-03
23.09.2001 - MGP, tag emlowen-V03-02-19
Same as previous one + migration to materials-V03-02-03 (STL)
23.09.2001 - MGP, tag emlowen-V03-02-18
New class to generate shell vacancies in continuous part
of processes by E. Guardincerri
Renamed old photon processes (pre-design iteration) to
G4LowEnergyOld; to be kept for a limited period for convenience
of regression testing
Fixed various STL problems found with HP compiler
Added protection in G4LowEnergyPhotoElectric to avoid
generating photons causing negative energy balance
21.09.2001 - MGP, tag emlowen-V03-02-17
G4LowEnergyPhotoElectric moved to the implementation
according to the new fluo+data design
[Test version G4LowEnergyPhotoElectricMG removed]
Fixed warning for energy outside allowed range in G4EMDataSet
Update to test/GNUmakefile, G4ComptonTest.cc by A. Pfeiffer
Minor cosmetics
19.09.2001 - MGP, tag emlowen-V03-02-16
Same as previous one, but test/GNUmakefile, G4ComptonTest.cc
and G4ComptonTest.py for histograms and ntuples with Lizard
(by A. Pfeiffer)
19.09.2001 - MGP, tag emlowen-V03-02-15
Same as previous one, but test/fluoTest with Particle gun
19.09.2001 - MGP, tag emlowen-V03-02-14
Minor cosmetics w.r.t. the previous one (removed compilation
warnings)
test/fluoTest with GPS
16.09.2001 - MGP, tag emlowen-V03-02-13
Update to the fluorescence domain consistent with the
new design (development by E. Guardincerri)
Update to test/fluoTest (development by E. Guardincerri)
13.09.2001 - MGP, tag emlowen-V03-02-12
Fix in G4CrossSectionHandler::Clear to remove an infinite loop
occurring in test14
10.09.2001 - MGP, tag emlowen-V03-02-11
Identical to emlowen-V03-02-10
Restored a clean situation in the cvs head, removing all
the code inconsistent with the design present in
emlowen-after-chep2001, resulting from a fault in the
software process by a developer.
10.09.2001 - MGP, tag emlowen-after-chep2001
Junk found in the repository
Tagged as an aid in the procedure of restoring a reasonable
situation in the cvs head for future developments
29.08.2001 - MGP, tag emlowen-V03-02-10
Major revision of G4LowEnergyCompton, G4LowEnergyRayleigh and
G4LowEnergyGammaConversion: re-implementation according to
the design iteration in the data domain
Temporary re-implementation of G4LowEnergyPhotoElectricMG,
without fluorescence yet
29.08.2001 - MGP, tag emlowen-V03-02-09
Bug fix in G4CrossSectionHandler
29.08.2001 - MGP, tag emlowen-V03-02-08
Cleared compilation warnings in G4AtomicTransitionManager
28.08.2001 - G.Cosmo, tag emlowen-V03-02-07
Fixed mess with tag names
27.08.2001 - STT, tag emlowen-V03-02-06
20.08.2001 - MGP, tag emlowen-V03-02-05
Added files resulting from design iteration in the data domain
20.08.2001 - MGP, tag emlowen-V03-02-04
Same as emlowen-V03-02-02 + bug fix by V.I. described below
18.08.2001 - V.Ivanchenko fix energy conservation bugs for small
range cuts in G4LowEnergyIonisation.cc
30.07.2001 - MGP, tag emlowen-V03-02-03
First step of design iteration in fluorescence (files
contributed by E. Guardincerri, G4AtomicShell and
G4AtomicTransitionManager) + related unit test
30.07.2001 - MGP, tag emlowen-V03-02-02
Fix to GammaConversion by F. Longo
30.07.2001 - MGP, tag emlowen-V03-02-01
Added modifications by V.I. listed below (13.07.2001),
on top of previous tag
30.07.2001 - MGP, tag emlowen-V03-02-00
Same as emlowen-V03-01-19, with liability disclaimer added
13.07.2001 - V.Ivanchenko remove comments with Rogue Wave
fix a problem of continuity of ion effective charge
18.06.2001 - MGP, tag emlowen-V03-01-19
Same as emlowen-V03-01-18, with corrections by S. Chauvie
to recover from modifications listed below
@@ -0,0 +1,84 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4AtomicTransitionManager.hh,v 1.2 ????
// GEANT4 tag $Name: geant4-04-00 $
//
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
//
// History:
// -----------
//
// 16 Sept 2001 First committed to cvs
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics, management of atomic deexcitation
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4AtomicDeexcitation_h
#define G4AtomicDeexcitation_h 1
#include "globals.hh"
#include "g4std/vector"
#include "G4AtomicTransitionManager.hh"
#include "G4DynamicParticle.hh"
class G4AtomicDeexcitation {
public:
G4AtomicDeexcitation();
~G4AtomicDeexcitation();
// Returns a vector contains the photons generated by radiative transitions
// (non zero particles) or by non radiative transitions (zero particles)
G4std::vector<G4DynamicParticle*>* GenerateParticles(G4int Z, G4int shellId);
private:
// Decides wether a radiative transition is possible and, if it is,
// returns the identity of the starting shell for the transition
const G4int SelectTypeOfTransition(G4int Z, G4int shellId);
// Generates a particle from a radiative transition and returns it
G4DynamicParticle* GenerateFluorescence(G4int Z, G4int shellId,G4int provShellId);
// Dummy function: when invowed returns a null pointer
G4DynamicParticle* GenerateAuger(G4int Z, G4int shellId);
// Data member which stores the shells to be filled by
// the radiative transition
G4int newShellId;
};
#endif
@@ -0,0 +1,75 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4AtomicShell.hh,v 1.2 ????
// GEANT4 tag $Name: geant4-04-00 $
//
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
//
// History:
// -----------
//
// 16 Sept 2001 Modofied according to a design iteration in the
// LowEnergy category
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics, a data container
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4AtomicShell_h
#define G4AtomicShell_h 1
#include "globals.hh"
class G4AtomicShell {
public:
// The data and the methods of this class are relative to
// a given shell
G4AtomicShell(G4int,G4double);
~G4AtomicShell();
// Returns the binding energy of the shell
G4double BindingEnergy() const;
// Returns the id of the shell
G4int ShellId() const;
private:
G4int identifier;
G4double bindingEnergy;
};
#endif
@@ -0,0 +1,95 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4AtomicTransition.hh,v 1.2 ????
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
//
// History:
// -----------
// 16 Sept 2001 Modofied according to a design iteration in the
// LowEnergy category
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics, a data container
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4AtomicTransition_h
#define G4AtomicTransition_h 1
#include "G4DataVector.hh"
#include "globals.hh"
#include "g4std/vector"
class G4AtomicTransition {
public:
G4AtomicTransition(G4int,const G4std::vector<G4int>&,const G4DataVector&,
const G4DataVector&);
~G4AtomicTransition();
// All the data stored and provided by this class are relative to a
// given vacancy, whose identity is provided by the FinalShellId() method,
// in an atom of a given material
// Returns the identities of the originating shells for the transitions
const G4std::vector<G4int>& OriginatingShellIds() const;
// Return the energies of the transitions
const G4DataVector& TransitionEnergies() const;
// Return the probabilities of the transitions
const G4DataVector& TransitionProbabilities() const;
// Return the identity if the vacancy
const G4int FinalShellId() const;
// Given the index of the originating shells returns its identity
G4int OriginatingShellId(G4int index) const;
// Given the index of the originating shells returns the energy
// of the transition starting from it
G4double TransitionEnergy(G4int index) const;
// Given the index of the originating shells returns the probability
// of the transition starting from it
G4double TransitionProbability(G4int index) const;
private:
G4int finalShellId;
G4std::vector<G4int> originatingShellIds;
G4DataVector transitionEnergies;
G4DataVector transitionProbabilities;
};
#endif
@@ -0,0 +1,121 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4AtomicTransitionManager.hh,v 1.2 ????
// GEANT4 tag $Name: geant4-04-00 $
//
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
//
// History:
// -----------
//
// 16 Sept 2001 EG Modified according to a design iteration in the
// LowEnergy category
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics, fills and manages G4AtomicShell
// and G4AtomicTransition objects
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4AtomicTransitionManager_h
#define G4AtomicTransitionManager_h 1
#include "G4ShellData.hh"
#include "G4FluoData.hh"
#include "G4AtomicTransition.hh"
#include "G4AtomicShell.hh"
#include "g4std/map"
#include "g4std/vector"
#include "globals.hh"
// This class is a singleton
class G4AtomicTransitionManager {
public:
// The only way to get an instance of this class is to call the
// function Instance()
static G4AtomicTransitionManager* Instance();
// Z is the atomic number of the element, shellIndex is the
// index (in EADL) of the shell
const G4AtomicShell* Shell(G4int Z, size_t shellIndex);
// Z is the atomic number of the element, shellIndex is the
// index (in EADL) of the final shell for the transition
const G4AtomicTransition* ReachableShell(G4int Z, size_t shellIndex);
// This function returns the number of shells of the element
// whose atomic number is Z
G4int NumberOfShells(G4int Z);
// This function returns the number of those shells of the element
// whose atomic number is Z which are reachable through a radiative
// transition
G4int NumberOfReachableShells(G4int Z);
// Gives the sum of the probabilities of radiative transition towards the
// shell whose index is shellIndex
G4double TotalRadiativeTransitionProbability(G4int Z, size_t shellIndex);
// Gives the sum of the probabilities of non radiative transition from the
// shell whose index is shellIndex
G4double TotalNonRadiativeTransitionProbability(G4int Z, size_t shellIndex);
protected:
G4AtomicTransitionManager(G4int minZ = 1, G4int maxZ = 99,
G4int limitInfTable = 6, G4int limitSupTable=100 );
~G4AtomicTransitionManager();
private:
static G4AtomicTransitionManager* instance;
// the first element of the map is the atomic number Z.
// the second element is a vector of G4AtomicShell*.
G4std::map<G4int,G4std::vector<G4AtomicShell*>,G4std::less<G4int> > shellTable;
// the first element of the map is the atomic number Z.
// the second element is a vector of G4AtomicTransition*.
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> > transitionTable;
// Minimum and maximum Z in EADL table containing identities and binding
// energies of shells
G4int zMin;
G4int zMax;
// Minimum and maximum Z in EADL table containing identities, transition
// energies and transition probabilities of shells
G4int infTableLimit;
G4int supTableLimit;
};
#endif
@@ -0,0 +1,83 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4BremsstrahlungCrossSectionHandler
//
// Author: V.Ivanchenko (Vladimir.Ivanchenko@cern.ch)
//
// Creation date: 17 September 2001
//
// Modified:
//
// -------------------------------------------------------------------
// Class Description:
//
// Provides build cross sections with cut for LowEnergyBremsstrahlung
//
// Class Description: End
// -------------------------------------------------------------------
//
#ifndef G4BremsstrahlungCrossSectionHandler_h
#define G4BremsstrahlungCrossSectionHandler_h 1
#include "G4VCrossSectionHandler.hh"
#include "G4VEnergySpectrum.hh"
#include "globals.hh"
class G4DataVector;
class G4VEMDataSet;
class G4VDataSetAlgorithm;
class G4BremsstrahlungCrossSectionHandler : public G4VCrossSectionHandler
{
public:
G4BremsstrahlungCrossSectionHandler(const G4VEnergySpectrum* spectrum,
G4VDataSetAlgorithm* interpolation);
~G4BremsstrahlungCrossSectionHandler();
protected:
G4std::vector<G4VEMDataSet*>* BuildCrossSectionsForMaterials(const G4DataVector& energyVector,
const G4DataVector* energyCuts);
private:
const G4VEnergySpectrum* theBR;
G4VDataSetAlgorithm* interp;
};
#endif
@@ -0,0 +1,103 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4BremsstrahlungParameters.hh,v 1.6 2001/11/29 19:01:44 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
// V. Ivanchenko (Vladimir.Ivantchenko@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created
// Values of the parameters from A. Forti's fit
// 12.09.01 V.Ivanchenko Add activeZ and paramA
// 25.09.01 V.Ivanchenko Add parameter C and change interface to B
// 29.11.01 V.Ivanchenko Parametrisation is updated
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics
// Load and access to parameters for LowEnergyBremsstrahlung from EEDL
// database. Parametrisation is described in Physics Reference Manual
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4BREMSSTRAHLUNGPARAMETERS_HH
#define G4BREMSSTRAHLUNGPARAMETERS_HH 1
#include "globals.hh"
#include "G4DataVector.hh"
#include "g4std/map"
class G4VEMDataSet;
class G4VDataSetAlgorithm;
class G4BremsstrahlungParameters {
public:
G4BremsstrahlungParameters(G4int minZ = 1, G4int maxZ = 99);
~G4BremsstrahlungParameters();
G4double Parameter(G4int parameterIndex, G4int Z, G4double energy) const;
G4double ParameterC(G4int index) const;
void PrintData() const;
private:
// hide assignment operator
G4BremsstrahlungParameters(const G4BremsstrahlungParameters&);
G4BremsstrahlungParameters & operator=(const G4BremsstrahlungParameters &right);
void LoadData();
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> > param;
G4DataVector paramC;
G4DataVector activeZ;
G4int zMin;
G4int zMax;
size_t length;
};
#endif
@@ -0,0 +1,107 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4CompositeEMDataSet.hh,v 1.3 2001/10/08 15:27:01 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics
// Composite data set for an electromagnetic physics process
// A strategy pattern is used to encapsulate algorithms for data interpolation
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4COMPOSITEEMDATASET_HH
#define G4COMPOSITEEMDATASET_HH 1
#include "globals.hh"
#include "G4DataVector.hh"
#include "G4VEMDataSet.hh"
#include "g4std/vector"
class G4EMDataSet;
class G4VDataSetAlgorithm;
class G4CompositeEMDataSet : public G4VEMDataSet
{
public:
G4CompositeEMDataSet(G4VDataSetAlgorithm* interpolation,
G4double unitE = MeV, G4double unitData = barn,
G4int minZ = 1, G4int maxZ = 99);
G4CompositeEMDataSet(const G4String& dataFile,
G4VDataSetAlgorithm* interpolation,
G4double unitE = MeV, G4double unitData = barn,
G4int minZ = 1, G4int maxZ = 99);
~G4CompositeEMDataSet();
G4double FindValue(G4double e, G4int Z = 0) const;
const G4VEMDataSet* GetComponent(G4int i) const { return components[i]; }
void AddComponent(G4VEMDataSet* component);
size_t NumberOfComponents() const { return nComponents; }
void PrintData() const;
const G4DataVector& GetEnergies(G4int i) const;
const G4DataVector& GetData(G4int i) const;
private:
void LoadData(const G4String& fileName);
G4VDataSetAlgorithm* algorithm;
G4std::vector<G4VEMDataSet*> components;
size_t nComponents;
G4double unit1;
G4double unit2;
G4int zMin;
G4int zMax;
};
#endif
@@ -0,0 +1,89 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4CrossSectionHandler.hh,v 1.6 2001/10/05 18:25:19 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 1 Aug 2001 MGP Created
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics
// Data set manager for an electromagnetic physics process
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4CROSSSECTIONHANDLER_HH
#define G4CROSSSECTIONHANDLER_HH 1
#include "globals.hh"
#include "G4DataVector.hh"
#include "g4std/map"
#include "g4std/vector"
#include "G4VCrossSectionHandler.hh"
class G4VDataSetAlgorithm;
class G4VEMDataSet;
class G4Material;
class G4Element;
class G4CrossSectionHandler : public G4VCrossSectionHandler {
public:
G4CrossSectionHandler();
~G4CrossSectionHandler();
protected:
virtual G4std::vector<G4VEMDataSet*>* BuildCrossSectionsForMaterials(const G4DataVector& energyVector,
const G4DataVector* energyCuts = 0);
private:
// Hide copy constructor and assignment operator
G4CrossSectionHandler(const G4CrossSectionHandler&);
G4CrossSectionHandler & operator=(const G4CrossSectionHandler &right);
};
#endif
@@ -0,0 +1,76 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4CutsPerMaterialWarning.hh,v 1.1 2001/11/07 22:38:47 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 7 Nov 2001 MGP Created
//
// -------------------------------------------------------------------
// Class description:
// Functor class to print a warning if the deprecated, unsupported feature
// of having different range cuts for different materials is used
// Will be removed when properly designed "range cuts by region"
// will be available in Geant4
// Further documentation available from http://www.ge.infn.it/geant4/lowE/
// -------------------------------------------------------------------
#ifndef G4CUTSPERMATERIALWARNING_HH
#define G4CUTSPERMATERIALWARNING_HH 1
#include "globals.hh"
class G4ParticleDefinition;
class G4Material;
class G4CutsPerMaterialWarning
{
public:
G4CutsPerMaterialWarning() { }
~G4CutsPerMaterialWarning() { }
void PrintWarning(const G4ParticleDefinition* particle) const;
private:
};
#endif
@@ -0,0 +1,107 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4EMDataSet.hh,v 1.2 2001/10/08 07:45:32 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics
// Data set for an electromagnetic physics process
// A strategy pattern is used to encapsulate algorithms for data interpolation
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4EMDATASET_HH
#define G4EMDATASET_HH 1
#include "globals.hh"
#include "G4DataVector.hh"
#include "G4VEMDataSet.hh"
class G4VDataSetAlgorithm;
class G4EMDataSet : public G4VEMDataSet {
public:
G4EMDataSet(G4int Z,
G4DataVector* points,
G4DataVector* values,
G4VDataSetAlgorithm* interpolation,
G4double unitE = MeV, G4double unitData = barn);
G4EMDataSet(G4int Z,
const G4String& dataFile,
G4VDataSetAlgorithm* interpolation,
G4double unitE = MeV, G4double unitData = barn);
~G4EMDataSet();
G4double FindValue(G4double e, G4int id = 0) const;
void PrintData() const;
const G4DataVector& GetEnergies(G4int i) const { return *energies; }
const G4DataVector& GetData(G4int i) const { return *data; }
private:
void LoadData(const G4String& dataFile);
G4int FindBinLocation(G4double energy) const;
G4int z;
G4DataVector* energies; // Owned pointer
G4DataVector* data; // Owned pointer
G4VDataSetAlgorithm* algorithm; // Owned pointer
G4double unit1;
G4double unit2;
size_t numberOfBins;
};
#endif
@@ -0,0 +1,101 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4FluoData.hh,v 1.1 ?????
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
//
// History:
// -----------
// 16 Sept 2001 First committed to cvs
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics
// Fluorescence data set: shell identifiers, transition probabilities,
// transition energies
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4FLUODATA_HH
#define G4FLUODATA_HH 1
#include "globals.hh"
#include "g4std/vector"
#include "g4std/map"
class G4DataVector;
class G4FluoData
{
public:
G4FluoData();
~G4FluoData();
// The method returns the number of shells in wich a
// vacancy can be filled by a radiative transition
size_t NumberOfVacancies() const;
// Given the index of the vacancy returns its identity
G4int VacancyId(G4int vacancyIndex) const;
// Given the index of a vacancy returns the number of
//shells starting from wich an electrons can fill the vacancy
size_t NumberOfTransitions(G4int vacancyIndex) const;
// Given the indexes of the starting and final shells for the
// transition, returns the identity of the starting one
G4int StartShellId(G4int initIndex,G4int vacancyIndex);
// Given the indexes of the starting and final shells for the
// transition, returns the transition energy
G4double StartShellEnergy(G4int initIndex,G4int vacancyIndex);
// Given the indexes of the starting and final shells for the
// transition, returns the probability of this transition
G4double StartShellProb(G4int initIndex,G4int vacancyIndex);
void LoadData( G4int Z);
void PrintData();
private:
G4std::map<G4int,G4DataVector*,G4std::less<G4int> > idMap;
G4std::map<G4int,G4DataVector*,G4std::less<G4int> > energyMap;
G4std::map<G4int,G4DataVector*,G4std::less<G4int> > probabilityMap;
G4std::vector<G4int> nInitShells;
G4int numberOfVacancies;
};
#endif
@@ -0,0 +1,80 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4LinInterpolation.hh,v 1.1 2001/11/29 19:01:44 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created
//
// -------------------------------------------------------------------
// Class description:
// Log-Log interpolation of a data set
// Part of a strategy pattern to encapsulate algorithms for interpolation of data sets
// Further documentation available from http://www.ge.infn.it/geant4/lowE/index.html
// -------------------------------------------------------------------
#ifndef G4LININTERPOLATION_HH
#define G4LININTERPOLATION_HH 1
#include "globals.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4DataVector.hh"
class G4LinInterpolation : public G4VDataSetAlgorithm {
public:
G4LinInterpolation();
~G4LinInterpolation();
G4double Calculate(G4double point, G4int bin,
const G4DataVector& energies,
const G4DataVector& data) const;
virtual G4VDataSetAlgorithm* Clone() const { return new G4LinInterpolation; }
private:
// Hide copy constructor and assignment operator
};
#endif
@@ -0,0 +1,80 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4LogLogInterpolation.hh,v 1.2 2001/10/08 07:45:33 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created
//
// -------------------------------------------------------------------
// Class description:
// Log-Log interpolation of a data set
// Part of a strategy pattern to encapsulate algorithms for interpolation of data sets
// Further documentation available from http://www.ge.infn.it/geant4/lowE/index.html
// -------------------------------------------------------------------
#ifndef G4LOGLOGINTERPOLATION_HH
#define G4LOGLOGINTERPOLATION_HH 1
#include "globals.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4DataVector.hh"
class G4LogLogInterpolation : public G4VDataSetAlgorithm {
public:
G4LogLogInterpolation();
~G4LogLogInterpolation();
G4double Calculate(G4double point, G4int bin,
const G4DataVector& energies,
const G4DataVector& data) const;
virtual G4VDataSetAlgorithm* Clone() const { return new G4LogLogInterpolation; }
private:
// Hide copy constructor and assignment operator
};
#endif
@@ -20,36 +20,48 @@
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4LowEnergyBremsstrahlung.hh,v 1.16.2.2 2001/06/28 20:19:23 gunter Exp $
// GEANT4 tag $Name: $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
// CERN Geneva Switzerland
// -------------------------------------------------------------------
// $Id: G4LowEnergyBremsstrahlung.hh,v 1.28 2001/11/29 22:47:27 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// ------------ G4LowEnergyBremsstrahlung physics process ------
// by A.Forti 1999/03/27 19:18:13
//
// 18.04.2000 V.Lefebure
// - First implementation of continuous energy loss.
// Author: A. Forti
//
// History:
// -----------
// 02 Mar 1999 A. Forti 1st implementation
// 27 Sep 2001 V. Ivanchenko Major revision according to a design iteration
// 10 Oct 2001 M.G. Pia Revision to improve code quality
// and consistency with design
// 29 Nov 2001 V.Ivanchenko New parametrisation of EEDL data
//
// -------------------------------------------------------------------
// Class description:
// Low Energy electromagnetic process, Bremsstrahlung
// Low Energy electromagnetic process, electron Bremsstrahlung
// based on the data of the EEDL database. Details are described
// in the Physics Reference Manual.
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// ************************************************************
// --------------------------------------------------------------
#ifndef G4LowEnergyBremsstrahlung_h
#define G4LowEnergyBremsstrahlung_h 1
#ifndef G4LOWENERGYBREMSSTRAHLUNG_HH
#define G4LOWENERGYBREMSSTRAHLUNG_HH 1
#include "G4eLowEnergyLoss.hh"
#include "G4LowEnergyUtilities.hh"
#include "G4DataVector.hh"
class G4LowEnergyBremsstrahlung : public G4eLowEnergyLoss{
class G4Track;
class G4Step;
class G4ParticleDefinition;
class G4VParticleChange;
class G4VEMDataSet;
class G4VEnergySpectrum;
class G4VCrossSectionHandler;
class G4LowEnergyBremsstrahlung : public G4eLowEnergyLoss
{
public:
G4LowEnergyBremsstrahlung(const G4String& processName = "LowEnBrem");
@@ -57,80 +69,40 @@ public:
~G4LowEnergyBremsstrahlung();
G4bool IsApplicable(const G4ParticleDefinition&);
void SetCutForLowEnSecPhotons(G4double);
void BuildPhysicsTable(const G4ParticleDefinition& particleType);
G4VParticleChange* PostStepDoIt(const G4Track& track,
const G4Step& step);
void SetCutForLowEnSecPhotons(G4double cut);
void PrintInfoDefinition();
void BuildPhysicsTable(const G4ParticleDefinition& ParticleType);
void BuildLossTable(const G4ParticleDefinition& ParticleType);
protected:
G4double GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition );
G4VParticleChange* PostStepDoIt(const G4Track& track,
const G4Step& step);
G4double GetEnergyLossWithCut(const G4double AtomicNumber,
const G4double KineticEnergy,
const G4double Tcut) ;
private:
void BuildCrossSectionTable();
void BuildMeanFreePathTable();
void BuildATable();
void BuildBTable();
void BuildZVec();
void BuildLambdaTable(const G4ParticleDefinition& aParticleType);
void ComputepartialSumSigma(const G4double KineticEnergy,
const G4Material* aMaterial,
const G4double threshold);
// Hide copy constructor and assignment operator as private
G4LowEnergyBremsstrahlung(const G4LowEnergyBremsstrahlung& );
G4LowEnergyBremsstrahlung& operator = (const G4LowEnergyBremsstrahlung& right);
private:
void BuildLossTable(const G4ParticleDefinition& ParticleType);
G4double ComputeA(const G4int Z,const G4double ElectKinEnergy); // interpolation
G4double ComputeB(const G4int Z,const G4double ElectKinEnergy); // parametrized formula
G4double GetCrossSection(const G4double AtomicNumber,
const G4double KineticEnergy) ;
G4double GetCrossSectionWithCut(const G4double AtomIndex,
const G4double IncEnergy,
const G4double CutEnergy);
G4Element* SelectRandomAtom(G4Material* aMaterial) const;
G4LowEnergyBremsstrahlung & operator=(const G4LowEnergyBremsstrahlung &right);
G4LowEnergyBremsstrahlung(const G4LowEnergyBremsstrahlung&);
private:
G4SecondLevel* theCrossSectionTable ;
G4PhysicsTable* theMeanFreePathTable ;
G4SecondLevel* ATable;
G4FirstLevel* BTable;
G4DataVector* ZNumVec;
G4LowEnergyUtilities util;
// partial sum of total crosssection
G4OrderedTable partialSumSigma;
G4double lowestKineticEnergy;
G4double highestKineticEnergy;
G4double lowEnergyCut; // lower limit of the energy sampling formula
G4int totBin; // number of bins in the tables
G4double cutForLowEnergySecondaryPhotons;
G4VCrossSectionHandler* crossSectionHandler;
G4VEMDataSet* theMeanFreePath;
G4VEnergySpectrum* energySpectrum;
// Lower limit for generation of gamma in this model
G4DataVector cutForSecondaryPhotons;
G4double cutForPhotons;
};
#include "G4LowEnergyBremsstrahlung.icc"
#endif
@@ -1,143 +0,0 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4LowEnergyBremsstrahlung.icc,v 1.18.2.2 2001/06/28 20:19:23 gunter Exp $
// GEANT4 tag $Name: $
//
//
// ---------------------------------------------------------------
// GEANT 4 class inlined methods file
//
// ------------ G4LowEnergyBremsstrahlung physics process ---------
// by A.Forti 1999/03/27
//
// 18.04.2000 V.Lefebure
// - First implementation of continuous energy loss.
// - Return an infinite MeanfreePath when cross-section = 0.
// ***************************************************************
#include "G4Gamma.hh"
//
inline G4bool G4LowEnergyBremsstrahlung::IsApplicable(
const G4ParticleDefinition& particle)
{
return( (&particle == G4Electron::Electron())
/////////////||(&particle == G4Positron::Positron())
);
}
inline G4double G4LowEnergyBremsstrahlung::GetMeanFreePath(const G4Track& track,
G4double,
G4ForceCondition*)
// gives the MeanFreePath in GEANT4 internal units
{
const G4DynamicParticle* aDynamicParticle = track.GetDynamicParticle();
G4double KineticEnergy = aDynamicParticle->GetKineticEnergy();
G4Material* aMaterial = track.GetMaterial();
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
const G4double* theAtomicNumDensityVector = aMaterial->GetAtomicNumDensityVector();
const G4int NumberOfElements = aMaterial->GetNumberOfElements() ;
G4double* CutInKineticEnergy = G4Gamma::Gamma()->GetCutsInEnergy() ;
G4double Threshold = CutInKineticEnergy[aMaterial->GetIndex()] ;
G4double MeanFreePath;
// G4bool isOutRange ;
if (KineticEnergy < lowestKineticEnergy)
////MeanFreePath = DBL_MIN;
MeanFreePath = DBL_MAX;
else {
if (KineticEnergy > highestKineticEnergy) KineticEnergy = 0.99*highestKineticEnergy ;
///MeanFreePath = util.DataLogInterpolation(KineticEnergy, aMaterial->GetIndex(), theMeanFreePathTable);
/// MeanFreePath = (*theMeanFreePathTable)(aMaterial->GetIndex())->
//// GetValue( KineticEnergy, isOutRange );
G4double SIGMA = 0.;
G4int iel;
for (iel=0; iel<NumberOfElements; iel++ ){
SIGMA += theAtomicNumDensityVector[iel]*
GetCrossSectionWithCut( (*theElementVector)(iel)->GetZ(),
KineticEnergy,
Threshold);
}
MeanFreePath = SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX;
}
return MeanFreePath;
}
inline G4double G4LowEnergyBremsstrahlung::ComputeA(const G4int AtomicNumber,const G4double ElectronKinEnergy){
G4double aVal;
G4FirstLevel* oneAtomCoeff = (*ATable)[AtomicNumber-1];
G4DataVector* ElectEnVec = (*oneAtomCoeff)[0];
G4DataVector* AValueVec = (*oneAtomCoeff)[1];
aVal = util.DataLogInterpolation(ElectronKinEnergy, (*ElectEnVec), (*AValueVec));
if(AtomicNumber > 99){
aVal = 0;
}
return aVal;
}
inline G4double G4LowEnergyBremsstrahlung::ComputeB(const G4int AtomicNumber,const G4double ElectronKinEnergy){
G4double bVal;
G4double constTerm = (*(*BTable)[0])[AtomicNumber-1];
G4double linearTerm = (*(*BTable)[1])[AtomicNumber-1];
G4double logElectEn = log10(ElectronKinEnergy);
if(logElectEn > -5 && logElectEn < (-constTerm/linearTerm)){
bVal = linearTerm*logElectEn+constTerm;
}
else{
bVal = 0;
}
if(AtomicNumber > 99){
bVal = 0;
}
return bVal;
}
@@ -19,85 +19,86 @@
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
// $Id: G4LowEnergyCompton.hh,v 1.19 2001/12/13 12:04:13 gunter Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: A. Forti
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// $Id: G4LowEnergyCompton.hh,v 1.11.2.2 2001/06/28 20:19:23 gunter Exp $
// GEANT4 tag $Name: $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file --- Copyright CERN 1995
// CERN Geneva Switzerland
//
// ------------ G4LowEnergyCompton physics process ------
// by A.Forti 1999/03/02
// History:
// -----------
// 02 Mar 1999 A. Forti 1st implementation
// 1 Aug 2001 MGP Major revision according to a design iteration
//
// -------------------------------------------------------------------
// Class description:
// Low Energy electromagnetic process, Compton
// Low Energy Electromagnetic Physics, Compton Scattering
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// ************************************************************
// -------------------------------------------------------------------
#ifndef G4LowEnergyCompton_h
#define G4LowEnergyCompton_h
#ifndef G4LOWENERGYCOMPTON_HH
#define G4LOWENERGYCOMPTON_HH 1
// Base Class Headers
#include "globals.hh"
#include "G4VDiscreteProcess.hh"
// Contained Variables Headers
#include "G4LowEnergyUtilities.hh"
#include "G4Gamma.hh"
class G4Track;
class G4Step;
class G4ParticleDefinition;
class G4VParticleChange;
class G4VEMDataSet;
class G4VCrossSectionHandler;
class G4VRangeTest;
class G4LowEnergyCompton : public G4VDiscreteProcess{
class G4LowEnergyCompton : public G4VDiscreteProcess {
private:
// hide assignment operator as private
G4LowEnergyCompton& operator=(const G4LowEnergyCompton &right);
G4LowEnergyCompton(const G4LowEnergyCompton& );
public:
G4LowEnergyCompton(const G4String& processName ="LowEnCompton");
~G4LowEnergyCompton();
G4bool IsApplicable(const G4ParticleDefinition&);
G4bool IsApplicable(const G4ParticleDefinition& definition);
void BuildPhysicsTable(const G4ParticleDefinition& GammaType);
void BuildPhysicsTable(const G4ParticleDefinition& photon);
G4VParticleChange* PostStepDoIt(const G4Track& aTrack, const G4Step& aStep);
// For testing purpose only
G4double DumpMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition)
{ return GetMeanFreePath(aTrack, previousStepSize, condition); }
protected:
G4double GetMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition);
G4VParticleChange* PostStepDoIt(const G4Track& aTrack, const G4Step& aStep);
protected:
private:
void BuildScatteringFunctionTable();
void BuildCrossSectionTable();
void BuildMeanFreePathTable();
void BuildZVec();
// Hide copy constructor and assignment operator as private
G4LowEnergyCompton& operator=(const G4LowEnergyCompton& right);
G4LowEnergyCompton(const G4LowEnergyCompton& );
private:
G4double lowEnergyLimit; // low energy limit applied to the process
G4double highEnergyLimit; // high energy limit applied to the process
G4Element* SelectRandomAtom(const G4DynamicParticle*, G4Material*);
G4SecondLevel* theCrossSectionTable;
G4SecondLevel* theScatteringFunctionTable;
G4PhysicsTable* theMeanFreePathTable;
G4DataVector* ZNumVec;
G4VEMDataSet* meanFreePathTable;
G4VEMDataSet* scatterFunctionData;
G4double lowestEnergyLimit; // low energy limit of the crosssection data
G4double highestEnergyLimit; // high energy limit of the crosssection data
G4int numbBinTable; // number of bins in the data tables
G4VCrossSectionHandler* crossSectionHandler;
G4LowEnergyUtilities util;
G4VRangeTest* rangeTest;
const G4double intrinsicLowEnergyLimit; // intrinsic validity range
const G4double intrinsicHighEnergyLimit;
G4double meanFreePath; // actual Mean Free Path (current medium)
};
#include "G4LowEnergyCompton.icc"
#endif
@@ -1,72 +0,0 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4LowEnergyCompton.icc,v 1.13.2.2 2001/06/28 20:19:23 gunter Exp $
// GEANT4 tag $Name: $
//
//
// ---------------------------------------------------------------
// GEANT 4 class inlined methods file
//
// ------------ G4LowEnergyCompton physics process ---------
// by A.Forti 1999/03/02
// ***************************************************************
inline G4bool
G4LowEnergyCompton::IsApplicable(const G4ParticleDefinition& particle){
return ( &particle == G4Gamma::Gamma() );
}
inline G4double
G4LowEnergyCompton::GetMeanFreePath(const G4Track& aTrack, G4double, G4ForceCondition*){
// returns the gamma mean free path in GEANT4 internal units
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
G4Material* aMaterial = aTrack.GetMaterial();
// G4bool isOutRange ;
if (GammaEnergy > highestEnergyLimit){
meanFreePath = DBL_MAX;
}
else if(GammaEnergy < lowestEnergyLimit){
meanFreePath = DBL_MIN;
}
else {
meanFreePath = util.DataLogInterpolation(GammaEnergy,
aMaterial->GetIndex(),
theMeanFreePathTable);
}
return meanFreePath;
}
@@ -21,86 +21,92 @@
// ********************************************************************
//
//
// $Id: G4LowEnergyGammaConversion.hh,v 1.9.2.2 2001/06/28 20:19:23 gunter Exp $
// GEANT4 tag $Name: $
// $Id: G4LowEnergyGammaConversion.hh,v 1.14 2001/10/08 07:45:33 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
// CERN Geneva Switzerland
// Author: A. Forti
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// ------------ G4LowEnergyGammaConversion physics process ------
// by A.Forti 1999/03/02
// History:
// -----------
// 02 Mar 1999 A. Forti 1st implementation
// 14 Aug 2001 MGP Major revision according to a design iteration
//
// -------------------------------------------------------------------
// Class description:
// Low Energy process, Photon conversion
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// ************************************************************
// -------------------------------------------------------------------
#ifndef G4LOWENERGYGAMMACONVERSION_HH
#define G4LOWENERGYGAMMACONVERSION_HH 1
#ifndef G4LowEnergyGammaConversion_h
#define G4LowEnergyGammaConversion_h 1
// Base Class Headers
#include "G4VDiscreteProcess.hh"
// Contained Variables Headers
#include "G4LowEnergyUtilities.hh"
#include "G4Gamma.hh"
#include "globals.hh"
#include "G4VDiscreteProcess.hh"
class G4Track;
class G4Step;
class G4ParticleDefinition;
class G4VParticleChange;
class G4VEMDataSet;
class G4VCrossSectionHandler;
class G4VRangeTest;
class G4LowEnergyGammaConversion : public G4VDiscreteProcess {
class G4LowEnergyGammaConversion : public G4VDiscreteProcess
{
private:
// hide assignment operator as private
G4LowEnergyGammaConversion& operator=(const G4LowEnergyGammaConversion &right);
G4LowEnergyGammaConversion(const G4LowEnergyGammaConversion& );
public:
G4LowEnergyGammaConversion(const G4String& processName ="LowEnConversion");
~G4LowEnergyGammaConversion();
G4bool IsApplicable(const G4ParticleDefinition&);
G4bool IsApplicable(const G4ParticleDefinition& photon);
void BuildPhysicsTable(const G4ParticleDefinition& GammaType);
void BuildPhysicsTable(const G4ParticleDefinition& photon);
G4VParticleChange* PostStepDoIt(const G4Track& aTrack, const G4Step& aStep);
// For testing purpose only
G4double DumpMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition)
{ return GetMeanFreePath(aTrack, previousStepSize, condition); }
protected:
G4double GetMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition);
G4VParticleChange* PostStepDoIt(const G4Track& aTrack, const G4Step& aStep);
protected:
void BuildCrossSectionTable();
void BuildMeanFreePathTable();
void BuildZVec();
private:
G4Element* SelectRandomAtom(const G4DynamicParticle*, G4Material*);
static G4double ScreenFunction1(G4double ScreenVariable);
static G4double ScreenFunction2(G4double ScreenVariable);
private:
G4SecondLevel* theCrossSectionTable;
G4PhysicsTable* theMeanFreePathTable;
// Hide copy constructor and assignment operator as private
G4LowEnergyGammaConversion& operator=(const G4LowEnergyGammaConversion &right);
G4LowEnergyGammaConversion(const G4LowEnergyGammaConversion& );
G4DataVector* ZNumVec;
G4double ScreenFunction1(G4double screenVariable);
G4double ScreenFunction2(G4double screenVariable);
G4double lowEnergyLimit; // low energy limit applied to the process
G4double highEnergyLimit; // high energy limit applied to the process
G4double lowestEnergyLimit;
G4double highestEnergyLimit;
G4int NumbBinTable;
G4VEMDataSet* meanFreePathTable;
G4VCrossSectionHandler* crossSectionHandler;
G4VRangeTest* rangeTest;
const G4double intrinsicLowEnergyLimit; // intrinsic validity range
const G4double intrinsicHighEnergyLimit;
const G4double smallEnergy;
G4double MeanFreePath; // actual Mean Free Path (current medium)
G4LowEnergyUtilities util;
};
#include "G4LowEnergyGammaConversion.icc"
#endif
@@ -1,95 +0,0 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4LowEnergyGammaConversion.icc,v 1.11.2.2 2001/06/28 20:19:23 gunter Exp $
// GEANT4 tag $Name: $
//
//
// ---------------------------------------------------------------
// GEANT 4 class inlined methods file
//
// ------------ G4LowEnergyGammaConversion physics process ---------
// by A.Forti 1999/03/02
// ***************************************************************
inline G4bool G4LowEnergyGammaConversion::IsApplicable(const G4ParticleDefinition& particle)
{
return ( &particle == G4Gamma::Gamma() );
}
inline G4double
G4LowEnergyGammaConversion::GetMeanFreePath(const G4Track& aTrack, G4double, G4ForceCondition*){
// returns the gamma mean free path in GEANT4 internal units
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
G4Material* aMaterial = aTrack.GetMaterial();
// G4bool isOutRange ;
if (GammaEnergy < lowestEnergyLimit){
MeanFreePath = DBL_MAX;
}
else {
if(GammaEnergy > highestEnergyLimit) GammaEnergy = 0.99*highestEnergyLimit;
MeanFreePath = util.DataLogInterpolation(GammaEnergy, aMaterial->GetIndex(), theMeanFreePathTable);
}
return MeanFreePath;
}
inline G4double
G4LowEnergyGammaConversion::ScreenFunction1(G4double ScreenVariable)
// compute the value of the screening function 3*PHI1 - PHI2
{
G4double screenVal;
if (ScreenVariable > 1.)
screenVal = 42.24 - 8.368*log(ScreenVariable+0.952);
else
screenVal = 42.392 - ScreenVariable* (7.796 - 1.961*ScreenVariable);
return screenVal;
}
inline G4double
G4LowEnergyGammaConversion::ScreenFunction2(G4double ScreenVariable)
// compute the value of the screening function 1.5*PHI1 - 0.5*PHI2
{
G4double screenVal;
if (ScreenVariable > 1.)
screenVal = 42.24 - 8.368*log(ScreenVariable+0.952);
else
screenVal = 41.405 - ScreenVariable* (5.828 - 0.8945*ScreenVariable);
return screenVal;
}
@@ -20,154 +20,101 @@
// * statement, and all its terms. *
// ********************************************************************
//
// -------------------------------------------------------------------
// $Id: G4LowEnergyIonisation.hh,v 1.34 2001/11/29 22:47:27 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// $Id: G4LowEnergyIonisation.hh,v 1.20.2.2 2001/06/28 20:19:23 gunter Exp $
// GEANT4 tag $Name: $
// Author: A. Forti
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
//
// --- G4LowEnergyIonisation physics process for electrons
// by Alessandra Forti July 1999
// ************************************************************
//
// 07.04.2000 Veronique Lefebure + Laszlo Urban
// - First implemention of continuous energy loss
// 14/07/99: corrections , L.Urban
// 20/09/00 update fluctuations V.Ivanchenko
// History:
// -----------
// 02 Mar 1999 A. Forti 1st implementation
// 27 Sep 2001 V. Ivanchenko Major revision according to a design iteration
// 10 Oct 2001 M.G. Pia Revision to improve code quality and
// consistency with design
// 18 Oct 2001 M.G. Pia Revision to improve code quality and
// consistency with design
// 29 Nov 2001 V.Ivanchenko New parametrisation of EEDL data
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic process, electron Ionisation
// Low Energy electromagnetic process, electron Ionisation
// based on the data of the EEDL database. Details are described
// in the Physics Reference Manual.
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// ------------------------------------------------------------
#ifndef G4LowEnergyIonisation_h
#define G4LowEnergyIonisation_h 1
// --------------------------------------------------------------
#ifndef G4lOWENERGYIONISATION_HH
#define G4LOWENERGYIONISATION_HH 1
// Base Class Headers
#include "G4eLowEnergyLoss.hh"
#include "G4AtomicDeexcitation.hh"
// Contained Variables Headers
#include "G4LowEnergyUtilities.hh"
#include "G4Electron.hh"
#include "G4Positron.hh"
typedef G4FirstLevel oneShellTable;
typedef G4SecondLevel oneAtomTable;
typedef G4ThirdLevel allAtomTable;
class G4LowEnergyIonisation : public G4eLowEnergyLoss{
class G4Track;
class G4Step;
class G4ParticleDefinition;
class G4VParticleChange;
class G4VDataSetAlgorithm;
class G4ParticleChange;
class G4VEnergySpectrum;
class G4VCrossSectionHandler;
class G4ShellVacancy;
class G4VEMDataSet;
class G4LowEnergyIonisation : public G4eLowEnergyLoss
{
public:
G4LowEnergyIonisation(const G4String& processName = "LowEnergyIoni");
G4LowEnergyIonisation(const G4String& processName = "LowEnergyIoni");
~G4LowEnergyIonisation();
G4bool IsApplicable(const G4ParticleDefinition&);
void SetCutForLowEnSecPhotons(G4double);
void SetCutForLowEnSecElectrons(G4double);
void BuildPhysicsTable(const G4ParticleDefinition& aParticleType);
G4double GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition ) ;
inline G4double GetTransitionShell(G4int k){return(thePrimShVec[k]);};
G4VParticleChange *PostStepDoIt(const G4Track& track,
const G4Step& Step ) ;
G4bool IsApplicable(const G4ParticleDefinition&);
void PrintInfoDefinition();
void BuildPhysicsTable(const G4ParticleDefinition& ParticleType);
G4VParticleChange* PostStepDoIt(const G4Track& track,
const G4Step& step);
void SetCutForLowEnSecPhotons(G4double cut);
G4double GetShellCrossSection(const G4double AtomicNumber,
const G4int subshellindex,
const G4double KineticEnergy) ;
G4double GetShellCrossSectionwithCut(const G4double AtomicNumber,
const G4int subshellindex,
const G4double KineticEnergy,
const G4double Tcut) ;
G4double GetShellEnergyLosswithCut(const G4double AtomicNumber,
const G4int subshellindex,
const G4double KineticEnergy,
const G4double Tcut) ;
void SetLowEnergyLimit(G4double val) {if(val > 0.0) lEnergyLimit = val;};
private:
virtual G4double ComputeCrossSection(const G4double AtomicNumber,
const G4double IncEnergy);
G4double ComputeCrossSectionWithCut(const G4double AtomIndex,
const G4double IncEnergy,
const G4double CutEnergy);
G4double ComputeMicroscopicCrossSection(const G4double AtomIndex,
const G4double IncEnergy,
const G4double CutEnergy);
void BuildLossTable(const G4ParticleDefinition& aParticleType);
void BuildShellCrossSectionTable();
void BuildBindingEnergyTable();
void BuildFluorTransitionTable();
void BuildSamplingCoeffTable();
void BuildZVec();
void BuildLambdaTable(const G4ParticleDefinition& aParticleType);
void SetCutForLowEnSecElectrons(G4double cut);
protected:
G4double GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition* condition );
virtual G4std::vector<G4DynamicParticle*>* DeexciteAtom(const G4Material* material,
G4double incidentEnergy,
G4double eLoss);
private:
// Hide copy constructor and assignment operator as private
G4LowEnergyIonisation(const G4LowEnergyIonisation& );
G4LowEnergyIonisation& operator = (const G4LowEnergyIonisation& right);
// hide assignment operator
G4LowEnergyIonisation & operator=(const G4LowEnergyIonisation &right);
G4LowEnergyIonisation(const G4LowEnergyIonisation&);
void BuildLossTable(const G4ParticleDefinition& ParticleType);
private:
G4VCrossSectionHandler* crossSectionHandler;
G4VEMDataSet* theMeanFreePath;
G4VEnergySpectrum* energySpectrum;
// Lower limit for generation of gamma in this model
G4DataVector cutForDelta;
G4double cutForPhotons;
G4double cutForElectrons;
G4AtomicDeexcitation deexcitationManager;
G4ShellVacancy* shellVacancy;
G4int SelectRandomShell(const G4int AtomIndex
, const G4double IncEnergy
, const G4double CutEnergy);
G4Element* SelectRandomAtom(const G4DynamicParticle* aDynamicPhoton,
G4Material* aMaterial);
G4bool SelectRandomTransition(G4int, G4double*,
const oneAtomTable*);
G4double EnergySampling(const G4int AtomicNumber
, const G4int ShellIndex
, const G4double KinEn
, const G4double deltaRayMinE = 0.1*eV);
allAtomTable* allAtomShellCrossSec;
allAtomTable* theFluorTransitionTable;
allAtomTable* theSamplingCoeffTable;
G4SecondLevel* theBindingEnergyTable;
G4DataVector* ZNumVec;
G4DataVector* ZNumVecFluor;
G4PhysicsTable* theMeanFreePathTable;
G4double CutForLowEnergySecondaryPhotons;
G4double CutForLowEnergySecondaryElectrons;
G4double MeanFreePath;
G4double lowestKineticEnergy;
G4double highestKineticEnergy;
G4int TotBin;
G4LowEnergyUtilities util;
G4DataVector thePrimShVec;
G4double lEnergyLimit;
};
#include "G4LowEnergyIonisation.icc"
#endif
@@ -180,7 +127,3 @@ private:
@@ -1,87 +0,0 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4LowEnergyIonisation.icc,v 1.16.2.2 2001/06/28 20:19:24 gunter Exp $
//
//
// ---------------------------------------------------------------
// GEANT 4 class inlined methods file
//
// ------------ G4LowEnergyIonisation physics process ------------
//
// by Alessandra Forti , July 1999
// ***************************************************************
//
// 07.04.2000 Veronique Lefebure + Laszlo Urban
// - First implemention of continuous energy loss
// 14/07/99 corrections by L. Urban
// 16/05/01 V.Ivanchenko: cross section is taken from the table.
// 17/05/01 V.Ivanchenko: warning print out.
// 22/05/01 V.Ivanchenko: switch on using tables of cross sections.
// ---------------------------------------------------------------
//
inline G4bool G4LowEnergyIonisation::IsApplicable(
const G4ParticleDefinition& particle)
{
if(&particle == G4Positron::Positron()) {
G4cout << "WARNING: G4LowEnergyIonisation is not applicable"
<< " for positron yet!" << G4endl;
}
return( (&particle == G4Electron::Electron())
/////////////////||(&particle == G4Positron::Positron())
);
}
//
inline G4double G4LowEnergyIonisation::GetMeanFreePath(
const G4Track& track,
G4double,
G4ForceCondition*){
const G4DynamicParticle* aParticle = track.GetDynamicParticle();
G4double KineticEnergy = aParticle->GetKineticEnergy();
const G4Material* aMaterial = track.GetMaterial();
G4bool isOutRange = false;
if( KineticEnergy < lowestKineticEnergy ) MeanFreePath = DBL_MAX;
else {
if(KineticEnergy > highestKineticEnergy)
KineticEnergy = highestKineticEnergy;
MeanFreePath = ((*theMeanFreePathTable)(aMaterial->GetIndex()))->
GetValue( KineticEnergy, isOutRange);
}
return MeanFreePath ;
}
@@ -21,124 +21,93 @@
// ********************************************************************
//
//
// $Id: G4LowEnergyPhotoElectric.hh,v 1.18.2.2 2001/06/28 20:19:24 gunter Exp $
// GEANT4 tag $Name: $
// $Id: G4LowEnergyPhotoElectric.hh,v 1.23 2001/10/08 07:45:34 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
// CERN Geneva Switzerland
// Author: A. Forti
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// ------------ G4LowEnergyPhotoElectric physics process ------
// by A.Forti 1999/03/02
// History:
// -----------
// 02 Mar 1999 A. Forti 1st implementation
// 12 Aug 2001 MGP Major revision according to a design iteration
// 16 Sept 2001 E. Guardincerri Added fluorescence generation
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic process, Photoelectric effect
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// ************************************************************
// -------------------------------------------------------------------
#ifndef G4LowEnergyPhotoElectric_h
#define G4LowEnergyPhotoElectric_h 1
#ifndef G4LOWENERGYPHOTOELECTRIC_HH
#define G4LOWENERGYPHOTOELECTRIC_HH 1
// Base Class Headers
#include "globals.hh"
#include "G4VDiscreteProcess.hh"
#include "G4AtomicDeexcitation.hh"
// Contained Variables Headers
#include "G4LowEnergyUtilities.hh"
#include "G4Gamma.hh"
class G4Track;
class G4Step;
class G4ParticleDefinition;
class G4VParticleChange;
class G4VEMDataSet;
class G4VCrossSectionHandler;
class G4VRangeTest;
// ..
typedef G4FirstLevel oneShellTable;
typedef G4SecondLevel oneAtomTable;
typedef G4ThirdLevel allAtomTable;
// ..
class G4LowEnergyPhotoElectric : public G4VDiscreteProcess
{
class G4LowEnergyPhotoElectric : public G4VDiscreteProcess {
public:
G4LowEnergyPhotoElectric(const G4String& processName ="LowEnPhotoElec");
~G4LowEnergyPhotoElectric();
~G4LowEnergyPhotoElectric();
G4bool IsApplicable(const G4ParticleDefinition&);
void BuildPhysicsTable(const G4ParticleDefinition& photon);
G4VParticleChange* PostStepDoIt(const G4Track& aTrack, const G4Step& aStep);
void SetCutForLowEnSecPhotons(G4double);
// void SetCutForLowEnSecElectrons(G4double);
// For testing purpose only
G4double DumpMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition)
{ return GetMeanFreePath(aTrack, previousStepSize, condition); }
protected:
void BuildPhysicsTable(const G4ParticleDefinition& PhotonType);
G4double GetMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition);
G4double GetCrossSection(G4DynamicParticle* aDynamicGamma,
G4Element* anElement);
inline G4double GetTransitionShell(G4int k){return(thePrimShVec[k]);};
G4VParticleChange* PostStepDoIt(const G4Track& aTrack, const G4Step& aStep);
protected:
virtual G4double ComputeCrossSection(const G4double AtomicNumber,
const G4double IncEnergy);
void BuildCrossSectionTable();
void BuildShellCrossSectionTable();
void BuildBindingEnergyTable();
void BuildFluorTransitionTable();
void BuildMeanFreePathTable();
void BuildZVec();
private:
G4int SelectRandomShell(const G4int AtomIndex, const G4double IncEnergy);
G4Element* SelectRandomAtom(const G4DynamicParticle* aDynamicPhoton,
G4Material* aMaterial);
G4bool SelectRandomTransition(G4int, G4double*, const oneAtomTable*);
private:
// hide assignment operator as private
G4LowEnergyPhotoElectric& operator=(const G4LowEnergyPhotoElectric &right);
// Hide copy constructor and assignment operator as private
G4LowEnergyPhotoElectric& operator=(const G4LowEnergyPhotoElectric& right);
G4LowEnergyPhotoElectric(const G4LowEnergyPhotoElectric& );
private:
G4double lowestEnergyLimit;
G4double highestEnergyLimit;
G4double lowEnergyLimit; // low energy limit applied to the process
G4double highEnergyLimit; // high energy limit applied to the process
G4int NumbBinTable;
G4VEMDataSet* meanFreePathTable;
G4double CutForLowEnergySecondaryPhotons;
G4VCrossSectionHandler* crossSectionHandler;
G4VCrossSectionHandler* shellCrossSectionHandler;
G4SecondLevel* theCrossSectionTable;
G4PhysicsTable* theMeanFreePathTable;
G4VRangeTest* rangeTest;
allAtomTable* allAtomShellCrossSec;
allAtomTable* theFluorTransitionTable;
G4SecondLevel* theBindingEnergyTable;
G4DataVector* ZNumVec;
G4DataVector* ZNumVecFluor;
const G4double intrinsicLowEnergyLimit; // intrinsic validity range
const G4double intrinsicHighEnergyLimit;
G4DataVector thePrimShVec;
G4LowEnergyUtilities util;
G4double cutForLowEnergySecondaryPhotons;
G4double MeanFreePath;
G4AtomicDeexcitation deexcitationManager;
};
// ..
#include "G4LowEnergyPhotoElectric.icc"
#endif
@@ -1,104 +0,0 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4LowEnergyPhotoElectric.icc,v 1.18.2.2 2001/06/28 20:19:24 gunter Exp $
// GEANT4 tag $Name: $
//
//
// ---------------------------------------------------------------
// GEANT 4 class inlined methods file
//
// ------------ G4LowEnergyPhotoElectric physics process ---------
// by A.Forti 1999/03/02
//
// 10/05/2001 V.Ivanchenko Clean up againist Linux compilation with -Wall
//
// ***************************************************************
// ..
inline G4bool G4LowEnergyPhotoElectric::IsApplicable(const G4ParticleDefinition& particle)
{
return ( &particle == G4Gamma::Gamma() );
}
// ..
inline G4double
G4LowEnergyPhotoElectric::GetMeanFreePath(const G4Track& aTrack, G4double,
G4ForceCondition*)
{
// returns the gamma mean free path in GEANT4 internal units
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
G4Material* aMaterial = aTrack.GetMaterial();
// G4bool isOutRange ;
if (GammaEnergy > highestEnergyLimit){
MeanFreePath = DBL_MAX;
}
else if(GammaEnergy < lowestEnergyLimit){
MeanFreePath = DBL_MIN;
}
else {
MeanFreePath = util.DataLogInterpolation(GammaEnergy,
aMaterial->GetIndex(),
theMeanFreePathTable);
}
return MeanFreePath;
}
// ..
inline G4double G4LowEnergyPhotoElectric::GetCrossSection(G4DynamicParticle* aDynamicGamma,
G4Element* anElement)
// gives the microscopic total cross section in GEANT4 internal units
{
G4double crossSection;
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
if (GammaEnergy < lowestEnergyLimit || GammaEnergy > highestEnergyLimit)
crossSection = 0.;
else{
G4int elemZ = (G4int) anElement->GetZ();
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(elemZ)];
crossSection = util.DataLogInterpolation(GammaEnergy,
(*(*oneAtomCS)[0]), (*(*oneAtomCS)[1]))*barn;
}
return crossSection;
}
// ..
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4LowEnergyPolarizedCompton.hh,v 1.4.2.2 2001/06/28 20:19:24 gunter Exp $
// GEANT4 tag $Name: $
// $Id: G4LowEnergyPolarizedCompton.hh,v 1.7 2001/10/24 09:07:20 flongo Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// ------------------------------------------------------------
// GEANT 4 class header file
@@ -35,26 +35,27 @@
// 24 May 2001 - MGP Modified to inherit from G4VDiscreteProcess
// 25 May 2001 - MGP Added protections to avoid crashes
//
// 17 October 2001 - F.Longo Major revision according to design iteration
//
// Class description:
// Low Energy electromagnetic process, Polarised Compton scattering
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// ------------------------------------------------------------
#ifndef G4LowEnergyPolarizedCompton_h
#define G4LowEnergyPolarizedCompton_h 1
#ifndef G4LOWENERGYPOLARIZEDCOMPTON_H
#define G4LOWENERGYPOLARIZEDCOMPTON_H 1
#include "globals.hh"
#include "G4VDiscreteProcess.hh"
#include "G4LowEnergyUtilities.hh"
//#include "G4VParticleChange.hh"
class G4SecondLevel;
class G4PhysicsTable;
class G4DataVector;
class G4Track;
class G4Step;
class G4ParticleDefinition;
class G4VParticleChange;
class G4VEMDataSet;
class G4VCrossSectionHandler;
class G4VRangeTest;
class G4LowEnergyPolarizedCompton : public G4VDiscreteProcess
{
@@ -64,53 +65,60 @@ public:
~G4LowEnergyPolarizedCompton();
G4bool IsApplicable(const G4ParticleDefinition&);
G4bool IsApplicable(const G4ParticleDefinition& definition);
void BuildPhysicsTable(const G4ParticleDefinition& photon);
G4VParticleChange* PostStepDoIt(const G4Track& aTrack, const G4Step& aStep);
// For testing purpose only
G4double DumpMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition)
{ return GetMeanFreePath(aTrack, previousStepSize, condition); }
protected:
void BuildPhysicsTable(const G4ParticleDefinition& GammaType);
G4double GetMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition);
G4VParticleChange* PostStepDoIt(const G4Track& aTrack, const G4Step& aStep);
protected:
void BuildScatteringFunctionTable();
void BuildCrossSectionTable();
void BuildMeanFreePathTable();
void BuildZVec();
private:
// Hide copy constructor and assignment operator as private
G4LowEnergyPolarizedCompton& operator=(const G4LowEnergyPolarizedCompton&
right);
G4LowEnergyPolarizedCompton(const G4LowEnergyPolarizedCompton& );
G4Element* SelectRandomAtom(const G4DynamicParticle*, G4Material*);
G4double lowEnergyLimit; // low energy limit applied to the process
G4double highEnergyLimit; // high energy limit applied to the process
G4SecondLevel* theCrossSectionTable;
G4SecondLevel* theScatteringFunctionTable;
G4PhysicsTable* theMeanFreePathTable;
G4DataVector* ZNumVec;
G4VEMDataSet* meanFreePathTable;
G4VEMDataSet* scatterFunctionData;
G4double lowestEnergyLimit; // low energy limit of the crosssection data
G4double highestEnergyLimit; // high energy limit of the crosssection data
G4int numbBinTable; // number of bins in the data tables
G4VCrossSectionHandler* crossSectionHandler;
G4VRangeTest* rangeTest;
G4LowEnergyUtilities util;
G4double meanFreePath; // actual Mean Free Path (current medium)
const G4double intrinsicLowEnergyLimit; // intrinsic validity range
const G4double intrinsicHighEnergyLimit;
// specific methods for polarization
G4ThreeVector SetRandomPolarization(G4ThreeVector& direction0); // Random Polarization
G4ThreeVector SetPerpendicularVector(G4ThreeVector& a); // temporary
G4ThreeVector SetNewPolarization(G4double epsilon, G4double sinSqrTheta,
G4double phi, G4double cosTheta);
G4double SetPhi(G4double, G4double);
void SystemOfRefChange(G4ThreeVector& direction0, G4ThreeVector& direction1,
G4ThreeVector& polarization0, G4ThreeVector& polarization1);
// hide assignment operator as private
G4LowEnergyPolarizedCompton& operator=(const G4LowEnergyPolarizedCompton &right);
G4LowEnergyPolarizedCompton(const G4LowEnergyPolarizedCompton& );
};
#endif
@@ -21,41 +21,41 @@
// ********************************************************************
//
//
// $Id: G4LowEnergyRayleigh.hh,v 1.10.2.2 2001/06/28 20:19:24 gunter Exp $
// GEANT4 tag $Name: $
// $Id: G4LowEnergyRayleigh.hh,v 1.15 2001/10/08 07:45:35 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file --- Copyright CERN 1995
// CERN Geneva Switzerland
//
// ------------ G4LowEnergyRayleigh physics process ------
// by A.Forti 1999/03/02
// Author: A. Forti
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 02 Mar 1999 A. Forti 1st implementation
// 11 Aug 2001 MGP Major revision according to a design iteration
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic process, Rayleigh effect
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// ************************************************************
// -------------------------------------------------------------------
#ifndef G4LowEnergyRayleigh_h
#define G4LowEnergyRayleigh_h
#ifndef G4LOWENERGYRAYLEIGH_HH
#define G4LOWENERGYRAYLEIGH_HH 1
// Base Class Headers
#include "globals.hh"
#include "G4VDiscreteProcess.hh"
// Contained Variables Headers
#include "G4LowEnergyUtilities.hh"
#include "G4Gamma.hh"
class G4Track;
class G4Step;
class G4ParticleDefinition;
class G4VParticleChange;
class G4VEMDataSet;
class G4VCrossSectionHandler;
class G4LowEnergyRayleigh : public G4VDiscreteProcess {
private:
// hide assignment operator as private
G4LowEnergyRayleigh& operator=(const G4LowEnergyRayleigh &right);
G4LowEnergyRayleigh(const G4LowEnergyRayleigh& );
public:
G4LowEnergyRayleigh(const G4String& processName ="LowEnRayleigh");
@@ -64,42 +64,43 @@ public:
G4bool IsApplicable(const G4ParticleDefinition&);
void BuildPhysicsTable(const G4ParticleDefinition& GammaType);
void BuildPhysicsTable(const G4ParticleDefinition& photon);
G4VParticleChange* PostStepDoIt(const G4Track& aTrack, const G4Step& aStep);
// For testing purpose only
G4double DumpMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition)
{ return GetMeanFreePath(aTrack, previousStepSize, condition); }
protected:
G4double GetMeanFreePath(const G4Track& aTrack,
G4double previousStepSize,
G4ForceCondition* condition);
G4VParticleChange* PostStepDoIt(const G4Track&, const G4Step& aStep);
protected:
void BuildFormFactorTable();
void BuildCrossSectionTable();
void BuildMeanFreePathTable();
void BuildZVec();
private:
// Hide copy constructor and assignment operator as private
G4LowEnergyRayleigh& operator=(const G4LowEnergyRayleigh &right);
G4LowEnergyRayleigh(const G4LowEnergyRayleigh& );
G4Element* SelectRandomAtom(const G4DynamicParticle*, G4Material*);
G4double lowEnergyLimit; // low energy limit applied to the process
G4double highEnergyLimit; // high energy limit applied to the process
G4SecondLevel* theCrossSectionTable;
G4SecondLevel* theFormFactorTable;
G4PhysicsTable* theMeanFreePathTable;
G4DataVector* ZNumVec;
G4VEMDataSet* meanFreePathTable;
G4VEMDataSet* formFactorData;
G4double lowestEnergyLimit; // low energy limit of the crosssection formula
G4double highestEnergyLimit; // high energy limit of the crosssection formula
G4int NumbBinTable; // number of bins in the crossection table
G4VCrossSectionHandler* crossSectionHandler;
const G4double intrinsicLowEnergyLimit; // intrinsic validity range
const G4double intrinsicHighEnergyLimit;
G4LowEnergyUtilities util;
G4double MeanFreePath; // actual Mean Free Path (current medium)
};
#include "G4LowEnergyRayleigh.icc"
#endif
@@ -113,6 +114,3 @@ private:
@@ -1,68 +0,0 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4LowEnergyRayleigh.icc,v 1.12.2.2 2001/06/28 20:19:24 gunter Exp $
// GEANT4 tag $Name: $
//
//
// ---------------------------------------------------------------
// GEANT 4 class inlined methods file
//
// ------------ G4LowEnergyRayleigh physics process ---------
// by A.Forti 1999/03/02
// ***************************************************************
inline G4bool G4LowEnergyRayleigh::IsApplicable(const G4ParticleDefinition& particle){
return ( &particle == G4Gamma::Gamma() );
}
inline G4double G4LowEnergyRayleigh::GetMeanFreePath(const G4Track& aTrack, G4double, G4ForceCondition*){
// returns the gamma mean free path in GEANT4 internal units
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
G4Material* aMaterial = aTrack.GetMaterial();
// G4bool isOutRange ;
if (GammaEnergy > highestEnergyLimit){
MeanFreePath = DBL_MAX;
}
else if(GammaEnergy < lowestEnergyLimit){
MeanFreePath = DBL_MIN;
}
else {
MeanFreePath = util.DataLogInterpolation(GammaEnergy,
aMaterial->GetIndex(),
theMeanFreePathTable);
}
return MeanFreePath;
}
@@ -1,209 +0,0 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4LowEnergyUtilities.hh,v 1.8.2.2 2001/06/28 20:19:24 gunter Exp $
// GEANT4 tag $Name: $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
// CERN Geneva Switzerland
//
// ------------ G4LowEnergyPhotoElectric physics process ------
// by A.Forti 1999/06/28
//
// Class description:
// Class for the handling of the data libraries
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// ************************************************************
#ifndef G4LowEnergyUtilities_h
#define G4LowEnergyUtilities_h 1
//#include "G4FirstLevel.hh"
//#include "G4SecondLevel.hh"
#include "G4ThirdLevel.hh"
#include "G4PhysicsVector.hh"
#include "G4PhysicsTable.hh"
typedef G4FirstLevel oneShellTable;
typedef G4SecondLevel oneAtomTable;
typedef G4ThirdLevel allAtomTable;
class G4LowEnergyUtilities
{
public:
G4LowEnergyUtilities();
~G4LowEnergyUtilities();
G4FirstLevel* BuildFirstLevelTables(const G4int, const G4int, const char*);
G4SecondLevel* BuildSecondLevelTables(const G4int, const G4int, const char*);
//inline functions
G4int FindBinLocation(const G4double BinValue, const G4DataVector& arg);
G4int FindBinLocation(const G4double, const G4PhysicsVector*);
G4double DataLogInterpolation(const G4double,
const G4DataVector&,
const G4DataVector&);
G4double DataLogInterpolation(const G4double Argument,
const G4double AtomicNumber,
const G4PhysicsTable* Table);
G4double DataSemiLogInterpolation(const G4double,
const G4DataVector&,
const G4DataVector&);
};
inline G4int G4LowEnergyUtilities::FindBinLocation(const G4double arg, const G4DataVector& vec){
G4int numberOfBin = vec.size();
G4int lowerBound = 0;
G4int upperBound = numberOfBin-1;
do {
G4int midBin = (lowerBound + upperBound)/2;
if( arg < vec[midBin] )
upperBound = midBin-1;
else
lowerBound = midBin+1;
} while (lowerBound <= upperBound);
return upperBound;
}
inline G4double G4LowEnergyUtilities::DataLogInterpolation(const G4double Argument,
const G4DataVector& argVec,
const G4DataVector& valVec){
G4int theLoc = FindBinLocation(Argument, argVec);
G4int size = argVec.size()-1;
if(theLoc == size){
return valVec[theLoc];
}
G4double val1 = valVec[theLoc], val2 = valVec[theLoc+1];
G4double arg1 = argVec[theLoc], arg2 = argVec[theLoc+1];
if(arg1 == 0.0) arg1 = 1e-17; if(val1 == 0.0) val1 = 1e-17;
G4double theVal = (log10(val1)*log10(arg2/Argument)
+log10(val2)*log10(Argument/arg1))/log10(arg2/arg1);
theVal = pow(10,theVal);
return theVal;
}
inline G4int G4LowEnergyUtilities::FindBinLocation(const G4double arg,
const G4PhysicsVector* vec){
if(!vec){
G4Exception("G4LowEnergy: FindBinLocation: Vector Empty "
"probably the program hasn't found data files or data files are empty");
}
G4int numberOfBin = vec->GetVectorLength();
G4int lowerBound = 0;
G4int upperBound = numberOfBin-1;
do {
G4int midBin = (lowerBound + upperBound)/2;
if( arg < vec->GetLowEdgeEnergy(midBin) )
upperBound = midBin-1;
else
lowerBound = midBin+1;
} while (lowerBound <= upperBound);
return upperBound;
}
inline G4double G4LowEnergyUtilities::DataLogInterpolation(const G4double Argument,
const G4double TableIndex,
const G4PhysicsTable* Table){
G4PhysicsVector* theVec = 0;
theVec = (*Table)(TableIndex);
G4int theLoc = FindBinLocation(Argument, theVec);
G4double val1 = (*theVec)(theLoc), val2 = (*theVec)(theLoc+1);
G4double arg1 = theVec->GetLowEdgeEnergy(theLoc), arg2 = theVec->GetLowEdgeEnergy(theLoc+1);
G4double theVal = (log10(val1)*log10(arg2/Argument)
+log10(val2)*log10(Argument/arg1))/log10(arg2/arg1);
theVal = pow(10,theVal);
return theVal;
}
inline G4double G4LowEnergyUtilities::DataSemiLogInterpolation(const G4double Argument,
const G4DataVector& argVec,
const G4DataVector& valVec){
G4int theLoc = FindBinLocation(Argument, argVec);
G4int size = argVec.size()-1;
if (theLoc == size){
return valVec[theLoc];
}
G4double val1 = valVec[theLoc], val2 = valVec[theLoc+1];
G4double arg1 = argVec[theLoc], arg2 = argVec[theLoc+1];
G4double theVal = (val1*log10(arg2/Argument)
+val2*log10(Argument/arg1))/log10(arg2/arg1);
return theVal;
}
#endif
@@ -21,49 +21,55 @@
// ********************************************************************
//
//
// $Id: G4RangeNoTest.hh,v 1.1 2001/10/08 07:51:41 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 5 Oct 2001 MGP Created
//
// -------------------------------------------------------------------
// GEANT 4 class file
//
// CERN, Geneva, Switzerland
//
// File name: G4SecondLevel.hh
//
// Author: Alessandra Forti (Alessandra.Forti@cern.ch)
//
// Creation date: 1 Giugno 1999
//
// Modifications: 24.04.01 V.Ivanchenko remove RogueWave
//
// -------------------------------------------------------------------
// Class description:
// Utility for Low Energy electromagnetic e/photon processes
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// Class for a strategy pattern encapsulating algorithms to test the range
// of a particle: no test is performed
// Further documentation available from http://www.ge.infn.it/geant4/lowE/index.html
// -------------------------------------------------------------------
#ifndef G4SECONDLEVEL_HH
#define G4SECONDLEVEL_HH
#ifndef G4RANGENOTEST_HH
#define G4RANGENOTEST_HH 1
#include "G4FirstLevel.hh"
//#include "g4rw/tpordvec.h"
#include "globals.hh"
#include "G4VRangeTest.hh"
//class G4SecondLevel : public G4RWTPtrOrderedVector< G4FirstLevel >{
class G4SecondLevel : public G4std::vector< G4FirstLevel* >
{
class G4ParticleDefinition;
class G4Material;
class G4RangeNoTest : public G4VRangeTest {
public:
~G4SecondLevel();
G4RangeNoTest() { }
G4bool operator == (const G4SecondLevel& ) const;
virtual ~G4RangeNoTest() { }
virtual G4bool Escape(const G4ParticleDefinition* particle,
const G4Material* material,
G4double energy,
G4double safety) const { return true; }
G4bool operator < (const G4SecondLevel&) const;
private:
};
#endif
@@ -21,48 +21,55 @@
// ********************************************************************
//
//
// $Id: G4RangeTest.hh,v 1.1 2001/10/08 07:51:42 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 5 Oct 2001 MGP Created
//
// -------------------------------------------------------------------
// GEANT 4 class file
//
// CERN, Geneva, Switzerland
//
// File name: G4ThirdLevel.hh
//
// Author: Alessandra Forti (Alessandra.Forti@cern.ch)
//
// Creation date: 1 Giugno 1999
//
// Modifications: 24.04.01 V.Ivanchenko remove RogueWave
//
// -------------------------------------------------------------------
// Class description:
// Utility for Low Energy electromagnetic e/photon processes
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// Class for a strategy pattern encapsulating algorithms to test the range
// of a perticle: test range against cut and safety
// Further documentation available from http://www.ge.infn.it/geant4/lowE/index.html
// -------------------------------------------------------------------
#ifndef G4THIRDLEVEL_HH
#define G4THIRDLEVEL_HH
#ifndef G4RANGETEST_HH
#define G4RANGETEST_HH 1
#include "G4SecondLevel.hh"
//#include "g4rw/tpordvec.h"
#include "globals.hh"
#include "G4VRangeTest.hh"
//class G4ThirdLevel : public G4RWTPtrOrderedVector< G4SecondLevel >{
class G4ThirdLevel : public G4std::vector< G4SecondLevel* >
{
class G4ParticleDefinition;
class G4Material;
class G4RangeTest : public G4VRangeTest {
public:
virtual ~G4ThirdLevel();
G4RangeTest() { }
G4bool operator == (const G4ThirdLevel& ) const;
virtual ~G4RangeTest() { }
virtual G4bool Escape(const G4ParticleDefinition* particle,
const G4Material* material,
G4double energy,
G4double safety) const;
G4bool operator < (const G4ThirdLevel&) const;
private:
};
#endif
@@ -0,0 +1,80 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4SemiLogInterpolation.hh,v 1.2 2001/10/08 07:45:35 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created
//
// -------------------------------------------------------------------
// Class description:
// Log-Log interpolation of a data set
// Part of a strategy pattern to encapsulate algorithms for interpolation of data sets
// Further documentation available from http://www.ge.infn.it/geant4/lowE/index.html
// -------------------------------------------------------------------
#ifndef G4SEMILOGINTERPOLATION_HH
#define G4SEMILOGINTERPOLATION_HH 1
#include "globals.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4DataVector.hh"
class G4SemiLogInterpolation : public G4VDataSetAlgorithm {
public:
G4SemiLogInterpolation();
~G4SemiLogInterpolation();
G4double Calculate(G4double point, G4int bin,
const G4DataVector& energies,
const G4DataVector& data) const;
virtual G4VDataSetAlgorithm* Clone() const { return new G4SemiLogInterpolation; }
private:
// Hide copy constructor and assignment operator
};
#endif
@@ -0,0 +1,90 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4ShellData.hh,v 1.1 2001/08/20 16:36:01 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 6 Aug 2001 MGP Created
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics
// Shell data set: shell identifiers and binding energies
// -------------------------------------------------------------------
#ifndef G4SHELLDATA_HH
#define G4SHELLDATA_HH 1
#include "globals.hh"
#include "g4std/vector"
#include "g4std/map"
class G4DataVector;
class G4ShellData
{
public:
G4ShellData(G4int minZ = 1, G4int maxZ = 99);
~G4ShellData();
size_t NumberOfShells(G4int Z) const;
G4int ShellId(G4int Z, G4int shellIndex) const;
const G4DataVector& ShellIdVector(G4int Z) const;
G4double BindingEnergy(G4int Z, G4int shellIndex) const;
void LoadData(const G4String& fileName);
void PrintData() const;
private:
G4int zMin;
G4int zMax;
G4std::map<G4int,G4DataVector*,G4std::less<G4int> > idMap;
G4std::map<G4int,G4DataVector*,G4std::less<G4int> > bindingMap;
G4std::vector<G4int> nShells;
};
#endif
@@ -0,0 +1,107 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4ShellEMDataSet.hh,v 1.3 2001/09/10 18:05:16 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics
// Data set for an electromagnetic physics process
// A strategy pattern is used to encapsulate algorithms for data interpolation
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4SHELLEMDATASET_HH
#define G4SHELLEMDATASET_HH 1
#include "globals.hh"
#include "G4DataVector.hh"
#include "G4VEMDataSet.hh"
#include "g4std/vector"
class G4EMDataSet;
class G4VDataSetAlgorithm;
class G4ShellEMDataSet : public G4VEMDataSet
{
public:
G4ShellEMDataSet(G4int Z,
const G4VDataSetAlgorithm* interpolation,
G4double unitE = MeV, G4double unitData = barn);
G4ShellEMDataSet(G4int Z,
const G4String& dataFile,
const G4VDataSetAlgorithm* interpolation,
G4double unitE = MeV, G4double unitData = barn);
~G4ShellEMDataSet();
G4double FindValue(G4double e, G4int id = 0) const;
const G4VEMDataSet* GetComponent(G4int i) const { return components[i]; }
void AddComponent(G4VEMDataSet* component);
size_t NumberOfComponents() const { return nComponents; }
void PrintData() const;
const G4DataVector& GetEnergies(G4int i) const;
const G4DataVector& GetData(G4int i) const;
private:
void LoadData(const G4String& fileName);
G4int z;
const G4VDataSetAlgorithm* algorithm; // Not owned pointer
// G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> > componentsMap;
G4std::vector<G4VEMDataSet*> components;
size_t nComponents;
G4double unit1;
G4double unit2;
};
#endif
@@ -0,0 +1,80 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4ShellVacancy.hh
// GEANT4 tag $Name:
//
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
//
// History:
// -----------
// 21 Sept 2001 Elena Guardincerri Created
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics
// Fluorescence in along step do it: determinates the number of ionizations
// -------------------------------------------------------------------
#ifndef G4SHELLVACANCY_HH
#define G4SHELLVACANCY_HH 1
#include "globals.hh"
#include "g4std/vector"
//#include "g4std/map"
class G4VEMDataSet;
class G4Material;
class G4Element;
class G4ShellVacancy
{
public:
G4ShellVacancy();
~G4ShellVacancy();
G4std::vector<G4int> GenerateNumberOfIonisations(const G4Material* material,
G4double incidentEnergy,
G4double eLoss) const;
void AddXsiTable(G4VEMDataSet* set);
private:
G4int AverageNOfIonisations(const G4Material* material,
const G4Element* element,
G4double energy,
G4double eLoss) const;
G4std::vector<G4VEMDataSet*> xsis;
};
#endif
@@ -0,0 +1,152 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4VCrossSectionHandler.hh,v 1.9 2001/10/10 09:49:29 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 16 Sep 2001 MGP Created
// 26 Sep 2001 V.Ivanchenko Hide copy constructor and assignement operator
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics
// Base class for cross section manager for an electromagnetic physics process
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4VCROSSSECTIONHANDLER_HH
#define G4VCROSSSECTIONHANDLER_HH 1
#include "globals.hh"
#include "G4DataVector.hh"
#include "g4std/map"
#include "g4std/vector"
class G4VDataSetAlgorithm;
class G4VEMDataSet;
class G4Material;
class G4Element;
class G4VCrossSectionHandler {
public:
G4VCrossSectionHandler();
G4VCrossSectionHandler(G4VDataSetAlgorithm* interpolation,
G4double minE = 250*eV, G4double maxE = 100*GeV,
G4int nBins = 200,
G4double unitE = MeV, G4double unitData = barn,
G4int minZ = 1, G4int maxZ = 99);
virtual ~G4VCrossSectionHandler();
void Initialise(G4VDataSetAlgorithm* interpolation = 0,
G4double minE = 250*eV, G4double maxE = 100*GeV,
G4int numberOfBins = 200,
G4double unitE = MeV, G4double unitData = barn,
G4int minZ = 1, G4int maxZ = 99);
G4int SelectRandomAtom(const G4Material* material, G4double e) const;
const G4Element* SelectRandomElement(const G4Material* material,
G4double e) const;
G4int SelectRandomShell(G4int Z, G4double e) const;
G4VEMDataSet* BuildMeanFreePathForMaterials(const G4DataVector* energyCuts = 0);
G4double FindValue(G4int Z, G4double e) const;
G4double FindValue(G4int Z, G4double e, G4int shellIndex) const;
void LoadData(const G4String& dataFile);
void LoadShellData(const G4String& dataFile);
void PrintData() const;
void Clear();
protected:
G4int NumberOfComponents(G4int Z) const;
G4double ValueForMaterial(const G4Material* material, G4double e) const;
void ActiveElements();
// Factory method
virtual G4std::vector<G4VEMDataSet*>* BuildCrossSectionsForMaterials(
const G4DataVector& energyVector,
const G4DataVector* energyCuts = 0) = 0;
// Factory method
virtual G4VDataSetAlgorithm* CreateInterpolation();
G4VDataSetAlgorithm* GetInterpolation() const { return interpolation; }
private:
// Hide copy constructor and assignment operator
G4VCrossSectionHandler(const G4VCrossSectionHandler&);
G4VCrossSectionHandler & operator=(const G4VCrossSectionHandler &right);
G4VDataSetAlgorithm* interpolation;
G4double eMin;
G4double eMax;
G4int nBins;
G4double unit1;
G4double unit2;
G4int zMin;
G4int zMax;
G4DataVector activeZ;
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> > dataMap;
G4std::vector<G4VEMDataSet*>* crossSections;
};
#endif
@@ -0,0 +1,80 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4VDataSetAlgorithm.hh,v 1.5 2001/10/09 12:13:48 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created
//
// -------------------------------------------------------------------
// Class description:
// Base class for a strategy pattern to encapsulate algorithms for interpolation of a data set
// Further documentation available from http://www.ge.infn.it/geant4/lowE/index.html
// -------------------------------------------------------------------
#ifndef G4VDATASETALGORITHM_HH
#define G4VDATASETALGORITHM_HH 1
#include "globals.hh"
#include "G4DataVector.hh"
class G4VDataSetAlgorithm {
public:
G4VDataSetAlgorithm() { }
virtual ~G4VDataSetAlgorithm() { }
virtual G4double Calculate(G4double point, G4int bin,
const G4DataVector& energies,
const G4DataVector& data) const = 0;
virtual G4VDataSetAlgorithm* Clone() const = 0;
private:
// Hide copy constructor and assignment operator
G4VDataSetAlgorithm(const G4VDataSetAlgorithm&);
G4VDataSetAlgorithm & operator=(const G4VDataSetAlgorithm &right);
};
#endif
@@ -0,0 +1,93 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4VEMDataSet.hh,v 1.5 2001/10/04 14:03:57 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics
// Data set for an electromagnetic physics process
// A strategy pattern is used to encapsulate algorithms for data interpolation
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4VEMDATASET_HH
#define G4VEMDATASET_HH 1
#include "globals.hh"
#include "G4DataVector.hh"
class G4VDataSetAlgorithm;
class G4VEMDataSet
{
public:
G4VEMDataSet() { }
virtual ~G4VEMDataSet() { }
virtual G4double FindValue(G4double e, G4int id = 0) const = 0;
virtual void PrintData() const = 0;
virtual const G4VEMDataSet* GetComponent(G4int i) const { return 0; }
virtual void AddComponent(G4VEMDataSet* dataSet) { }
virtual size_t NumberOfComponents() const { return 0; }
virtual const G4DataVector& GetEnergies(G4int i) const = 0;
virtual const G4DataVector& GetData(G4int i) const = 0;
protected:
private:
// Hide copy constructor and assignment operator
G4VEMDataSet(const G4VEMDataSet&);
G4VEMDataSet & operator=(const G4VEMDataSet &right);
};
#endif
@@ -0,0 +1,106 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4VEnergySpectrum
//
// Author: V.Ivanchenko (Vladimir.Ivantchenko@cern.ch)
//
// Creation date: 29 September 2001
//
// Modifications:
//
// -------------------------------------------------------------------
// Class Description:
//
// Abstract interface for the energy spectrum of secondary particles in
// electromagnetic processes.
//
// Class Description: End
// -------------------------------------------------------------------
//
#ifndef G4VENERGYSPECTRUM_HH
#define G4VENERGYSPECTRUM_HH 1
#include "globals.hh"
class G4ParticleDefinition;
class G4VEnergySpectrum
{
public:
G4VEnergySpectrum() {};
virtual ~G4VEnergySpectrum() {};
virtual G4double Probability(G4int Z,
G4double minKineticEnergy,
G4double maxKineticEnergy,
G4double kineticEnergy,
G4int shell = 0,
const G4ParticleDefinition* pd = 0) const = 0;
virtual G4double AverageEnergy(G4int Z,
G4double minKineticEnergy,
G4double maxKineticEnergy,
G4double kineticEnergy,
G4int shell = 0,
const G4ParticleDefinition* pd = 0) const = 0;
virtual G4double SampleEnergy(G4int Z,
G4double minKineticEnergy,
G4double maxKineticEnergy,
G4double kineticEnergy,
G4int shell = 0,
const G4ParticleDefinition* pd = 0) const = 0;
virtual G4double MaxEnergyOfSecondaries(G4double kineticEnergy,
G4int Z = 0,
const G4ParticleDefinition* pd = 0) const = 0;
virtual G4double Excitation(G4int Z, G4double kineticEnergy) const
{return 0.0;};
virtual void PrintData() const = 0;
protected:
private:
// Hide copy constructor and assignment operator
G4VEnergySpectrum(const G4VEnergySpectrum&);
G4VEnergySpectrum & operator=(const G4VEnergySpectrum &right);
};
#endif
@@ -21,50 +21,53 @@
// ********************************************************************
//
//
// $Id: G4VRangeTest.hh,v 1.1 2001/10/08 07:51:42 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 5 Oct 2001 MGP Created
//
// -------------------------------------------------------------------
// GEANT 4 class file
//
// CERN, Geneva, Switzerland
//
// File name: G4FirstLevel.hh
//
// Author: Alessandra Forti (Alessandra.Forti@cern.ch)
//
// Creation date: 1 Giugno 1999
//
// Modifications: 24.04.01 V.Ivanchenko remove RogueWave
//
// -------------------------------------------------------------------
// Class description:
// Utility for Low Energy e.m. e/photon processes
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// Base class for a strategy pattern encapsulating algorithms to test the range
// of a particle
// Further documentation available from http://www.ge.infn.it/geant4/lowE/index.html
// -------------------------------------------------------------------
#ifndef G4FIRSTLEVEL_HH
#define G4FIRSTLEVEL_HH
#ifndef G4VRANGETEST_HH
#define G4VRANGETEST_HH 1
#include "G4DataVector.hh"
class G4FirstLevel : public G4std::vector< G4DataVector* >
{
#include "globals.hh"
class G4ParticleDefinition;
class G4Material;
class G4VRangeTest {
public:
// G4FirstLevel( G4FirstLevel& )
G4VRangeTest() { }
~G4FirstLevel();
virtual ~G4VRangeTest() { }
virtual G4bool Escape(const G4ParticleDefinition* particle,
const G4Material* material,
G4double energy,
G4double safety) const = 0;
G4bool operator == (const G4FirstLevel& ) const;
G4bool operator < (const G4FirstLevel&) const;
private:
};
#endif
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4VeLowEnergyLoss.hh,v 1.4.2.2 2001/06/28 20:19:25 gunter Exp $
// GEANT4 tag $Name: $
// $Id: G4VeLowEnergyLoss.hh,v 1.7 2001/11/23 11:45:20 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// 3.4.2000 Veronique Lefebure:
// Move utils/include/G4VEnergyLoss.hh to
@@ -49,7 +49,8 @@
// -----------------------------------------------------------
//
// Modifications:
// 20/09/00 update fluctuations V.Ivanchenko
// 20/09/00 V.Ivanchenko update fluctuations
// 23/11/01 V.Ivanchenko Move static member-functions from header to source
//
// Class description:
// Abstract class for Low Energy Electromagnetic electron energy loss
@@ -127,20 +128,15 @@ class G4VeLowEnergyLoss : public G4VContinuousDiscreteProcess
public: // With description
static void SetRndmStep (G4bool value) {rndmStepFlag = value;}
static void SetRndmStep (G4bool value);
// use / do not use randomisation in energy loss steplimit
// ( default = no randomisation)
static void SetEnlossFluc (G4bool value) {EnlossFlucFlag = value;}
static void SetEnlossFluc (G4bool value);
// compute energy loss with/without fluctuation
// ( default : with fluctuation)
static void SetStepFunction (G4double c1, G4double c2)
{dRoverRange = c1; finalRange = c2;
c1lim=dRoverRange ;
c2lim=2.*(1-dRoverRange)*finalRange;
c3lim=-(1.-dRoverRange)*finalRange*finalRange;
}
static void SetStepFunction (G4double c1, G4double c2);
// sets values for data members used to compute the step limit:
// dRoverRange : max. relative range change in one step,
// finalRange : if range <= finalRange --> last step for the particle.
@@ -0,0 +1,82 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4VhShellCrossSection
//
// Author: S. Dussoni and A. Mantero (Alfonso.Mantero@ge.infn.it)
//
// History:
// -----------
// 23 Oct 2001 A. Mantero 1st implementation
// 24 Oct 2001 MGP Cleaned up
// 29 Oct 2001 VI Add delta energy
//
// -------------------------------------------------------------------
// Class Description:
//
// Abstract class for models of shell cross sections in proton ionisation
// -------------------------------------------------------------------
//
#ifndef G4VHSHELLCROSSSECTION_HH
#define G4VHSHELLCROSSSECTION_HH 1
#include "globals.hh"
#include "g4std/vector"
class G4VhShellCrossSection
{
public:
G4VhShellCrossSection();
virtual ~G4VhShellCrossSection();
G4int SelectRandomShell(G4int Z,
G4double incidentEnergy,
G4double mass,
G4double deltaEnergy) const;
protected:
virtual G4std::vector<G4double> Probabilities(G4int Z,
G4double incidentEnergy,
G4double mass,
G4double deltaEnergy) const = 0;
private:
// Hide copy constructor and assignment operator
G4VhShellCrossSection(const G4VhShellCrossSection&);
G4VhShellCrossSection & operator=(const G4VhShellCrossSection &right);
};
#endif
@@ -0,0 +1,118 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4eBremsstrahlungSpectrum.hh,v 1.2 2001/11/29 19:01:45 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4EBremsstrahlungSpectrum
//
// Author: V.Ivanchenko (Vladimir.Ivantchenko@cern.ch)
//
// Creation date: 27 September 2001
//
// Modifications:
// 10.10.01 MGP Revision to improve code quality and consistency with design
// 29.11.01 V.Ivanchenko Parametrisation is updated
//
// -------------------------------------------------------------------
// Class Description:
// Provides various integration over gamma spectrum of e- Bremsstrahlung.
// Parametrisation is described in Physics Reference Manual based on
// data from EEDL database.
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4EBREMSSTRAHLUNGSPECTRUM_HH
#define G4EBREMSSTRAHLUNGSPECTRUM_HH 1
#include "globals.hh"
#include "G4DataVector.hh"
#include "G4VEnergySpectrum.hh"
class G4BremsstrahlungParameters;
class G4eBremsstrahlungSpectrum : public G4VEnergySpectrum
{
public:
G4eBremsstrahlungSpectrum();
~G4eBremsstrahlungSpectrum();
G4double Probability(G4int Z,
G4double tMin,
G4double tMax,
G4double kineticEnergy,
G4int shell=0,
const G4ParticleDefinition* pd=0) const;
G4double AverageEnergy(G4int Z,
G4double tMin,
G4double tMax,
G4double kineticEnergy,
G4int shell=0,
const G4ParticleDefinition* pd=0) const;
G4double SampleEnergy(G4int Z,
G4double tMin,
G4double tMax,
G4double kineticEnergy,
G4int shell=0,
const G4ParticleDefinition* pd=0) const;
G4double MaxEnergyOfSecondaries(G4double kineticEnergy,
G4int Z = 0,
const G4ParticleDefinition* pd=0) const
{ return kineticEnergy; }
void PrintData() const;
private:
G4double IntSpectrum(G4double xMin, G4double xMax,
const G4DataVector& p) const;
G4double AverageValue(G4double xMin, G4double xMax,
const G4DataVector& p) const;
G4double Function(G4double x, const G4DataVector& p) const;
// Hide copy constructor and assignment operator
G4eBremsstrahlungSpectrum(const G4eBremsstrahlungSpectrum&);
G4eBremsstrahlungSpectrum & operator = (const G4eBremsstrahlungSpectrum &right);
G4BremsstrahlungParameters* theBRparam;
G4double lowestE;
size_t length;
G4int verbose;
G4DataVector xp;
};
#endif
@@ -0,0 +1,87 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4eIonisationCrossSectionHandler.hh,v 1.2 2001/10/10 17:37:27 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4eIonisationCrossSectionHandler
//
// Author: V.Ivanchenko (Vladimir.Ivanchenko@cern.ch)
//
// Creation date: 17 September 2001
//
// Modified:
// 10 Oct 2001 M.G. Pia Revision to improve code quality and consistency with design
//
// -------------------------------------------------------------------
// Class description:
// Provides cross sections with cut for LowEnergyIonisation
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
//
#ifndef G4EIONISATIONCROSSSECTIONHANDLER_HH
#define GG4EIONISATIONCROSSSECTIONHANDLER_HH 1
#include "G4VCrossSectionHandler.hh"
#include "globals.hh"
class G4VEnergySpectrum;
class G4DataVector;
class G4VEMDataSet;
class G4VDataSetAlgorithm;
class G4eIonisationCrossSectionHandler : public G4VCrossSectionHandler
{
public:
G4eIonisationCrossSectionHandler(const G4VEnergySpectrum* spec,
G4VDataSetAlgorithm* alg,
G4double emin,
G4double emax,
G4int nbin);
~G4eIonisationCrossSectionHandler();
protected:
G4std::vector<G4VEMDataSet*>* BuildCrossSectionsForMaterials(
const G4DataVector& energyVector,
const G4DataVector* energyCuts);
private:
const G4VEnergySpectrum* theParam;
G4VDataSetAlgorithm* interp;
};
#endif
@@ -0,0 +1,94 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4eIonisationParameters.hh,v 1.6 2001/11/29 19:01:45 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
// V. Ivanchenko
// Values of the parameters from A. Forti's fit
//
// History:
// -----------
// 31 Jul 2001 MGP Created
// 12.09.01 V.Ivanchenko Add param and interpolation of parametersVI
// 10.10.2001 MGP Revision to improve code quality and
// consistency with design
// 29.11.01 V.Ivanchenko Parametrisation is updated
//
// -------------------------------------------------------------------
// Class description:
// Low Energy Electromagnetic Physics
// Set of parameters for LowEnergyIonisation described spectrum
// of delta-electrons retrieved from EEDL database.
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4IONISATIONPARAMETERS_HH
#define G4IONISATIONPARAMETERS_HH 1
#include "globals.hh"
#include "G4DataVector.hh"
#include "g4std/map"
class G4VDataSetAlgorithm;
class G4VEMDataSet;
class G4eIonisationParameters {
public:
G4eIonisationParameters(G4int minZ = 1, G4int maxZ = 99);
~G4eIonisationParameters();
G4double Parameter(G4int Z, G4int shellIndex,
G4int parameterIndex, G4double e) const;
G4double Excitation(G4int Z, G4double e) const;
void PrintData() const;
private:
// Hide copy constructor and assignment operator
G4eIonisationParameters(const G4eIonisationParameters&);
G4eIonisationParameters & operator=(const G4eIonisationParameters &right);
void LoadData();
G4int zMin;
G4int zMax;
G4DataVector activeZ;
// Parameters of the energy spectra
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> > param;
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> > excit;
size_t length;
};
#endif
@@ -0,0 +1,115 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4eIonisationSpectrum.hh,v 1.3 2001/11/29 19:01:45 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4eIonisationSpectrum
//
// Author: V.Ivanchenko (Vladimir.Ivantchenko@cern.ch)
//
// Creation date: 27 September 2001
//
// Modifications:
// 10.10.01 MGP Revision to improve code quality and
// consistency with design
// 29.11.01 V.Ivanchenko Parametrisation is updated
//
// -------------------------------------------------------------------
// Class Description:
// Provides various integration over delta-electron spectrum for e-
// ionisation process. Spectrum is parametrised accourding to
// EEDL database, details are described in the Physics Reference Manual
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
#ifndef G4EIONISATIONSPECTRUM_HH
#define GG4EIONISATIONSPECTRUM_HH 1
#include "G4VEnergySpectrum.hh"
class G4eIonisationParameters;
class G4DataVector;
class G4eIonisationSpectrum : public G4VEnergySpectrum
{
public:
G4eIonisationSpectrum();
~G4eIonisationSpectrum();
G4double Probability(G4int Z, G4double tMin, G4double tMax,
G4double kineticEnergy, G4int shell,
const G4ParticleDefinition* pd=0) const;
G4double AverageEnergy(G4int Z, G4double tMin, G4double tMax,
G4double kineticEnergy, G4int shell,
const G4ParticleDefinition* pd=0) const;
G4double SampleEnergy(G4int Z, G4double tMin, G4double tMax,
G4double kineticEnergy, G4int shell,
const G4ParticleDefinition* pd=0) const;
G4double MaxEnergyOfSecondaries(G4double kineticEnergy,
G4int Z = 0,
const G4ParticleDefinition* pd=0) const
{ return 0.5*kineticEnergy; };
G4double Excitation(G4int Z, G4double e) const;
void PrintData() const;
protected:
private:
G4double IntSpectrum(G4double xMin, G4double xMax,
const G4DataVector& p) const;
G4double AverageValue(G4double xMin, G4double xMax,
const G4DataVector& p) const;
G4double Function(G4double x, const G4DataVector& p) const;
// Hide copy constructor and assignment operator
G4eIonisationSpectrum(const G4eIonisationSpectrum&);
G4eIonisationSpectrum & operator = (const G4eIonisationSpectrum &right);
private:
G4eIonisationParameters* theParam;
G4double lowestE;
G4double factor;
G4int verbose;
};
#endif
@@ -21,11 +21,28 @@
// ********************************************************************
//
//
// $Id: G4eLowEnergyLoss.hh,v 1.1.4.2 2001/06/28 20:19:25 gunter Exp $
// GEANT4 tag $Name: $
// $Id: G4eLowEnergyLoss.hh,v 1.7 2001/11/23 11:45:20 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// ------------------------------------------------------------
// GEANT 4 class header file
// -------------------------------------------------------------------
// Class description:
// Low Energy electromagnetic process, electron energy loss
// Further documentation available from http://www.ge.infn.it/geant4/lowE
// -------------------------------------------------------------------
//
// This class is the implementation of the unified Energy Loss process.
// It calculates the continuous energy loss for e+/e-.
// The following processes give contributions to the continuous
// energy loss (by default) :
// --- ionisation (= cont.ion.loss + delta ray production)
// --- bremsstrahlung (= cont.loss due to soft brems+discrete bremsstrahlung)
// more can be added ..........
// This class creates static dE/dx and range tables for e+ and e-,
// which tables can be used by other processes , too.
// G4eLowEnergyLoss is the base class for the processes giving contribution
// to the (continuous) energy loss of e+/e- .
//
// History: first implementation, based on object model of
// 2nd December 1995, G.Cosmo
@@ -37,6 +54,8 @@
// 16.10.98 public method SetStepFunction() + messenger class
// 20.01.99 new data members , L.Urban
// 10.02.00 modifications, new e.m. structure , L.Urban
// 18.10.01 Revision to improve code quality and consistency with design
// 23.11.01 V.Ivanchenko Move static member-functions from header to source
// ------------------------------------------------------------
#ifndef G4eLowEnergyLoss_h
@@ -58,20 +77,6 @@
#include "G4PhysicsLinearVector.hh"
#include "G4EnergyLossTables.hh"
// Class description:
// This class is the implementation of the unified Energy Loss process.
// It calculates the continuous energy loss for e+/e-.
// The following processes give contributions to the continuous
// energy loss (by default) :
// --- ionisation (= cont.ion.loss + delta ray production)
// --- bremsstrahlung (= cont.loss due to soft brems+discrete bremsstrahlung)
// more can be added ..........
// This class creates static dE/dx and range tables for e+ and e-,
// which tables can be used by other processes , too.
// G4eLowEnergyLoss is the base class for the processes giving contribution
// to the (continuous) energy loss of e+/e- .
// Class description - end
class G4EnergyLossMessenger;
class G4eLowEnergyLoss : public G4VeLowEnergyLoss
@@ -83,8 +88,6 @@ class G4eLowEnergyLoss : public G4VeLowEnergyLoss
~G4eLowEnergyLoss();
public: // With description
G4bool IsApplicable(const G4ParticleDefinition&);
// true for e+/e- , false otherwise
@@ -110,22 +113,38 @@ class G4eLowEnergyLoss : public G4VeLowEnergyLoss
// ( ionisation and bremsstrahlung) .
virtual G4VParticleChange* PostStepDoIt(const G4Track& track,
const G4Step& Step) = 0;
const G4Step& step) = 0;
// Virtual function to be overridden in the derived classes
// ( ionisation and bremsstrahlung) .
static void SetNbOfProcesses(G4int nb);
// Sets number of processes giving contribution to the energy loss
static void PlusNbOfProcesses();
// Increases number of processes giving contribution to the energy loss
static void MinusNbOfProcesses();
// Decreases number of processes giving contribution to the energy loss
static G4int GetNbOfProcesses();
// Gets number of processes giving contribution to the energy loss
// ( default value = 2)
static void SetLowerBoundEloss(G4double val);
static void SetUpperBoundEloss(G4double val);
static void SetNbinEloss(G4int nb);
static G4double GetLowerBoundEloss();
static G4double GetUpperBoundEloss();
static G4int GetNbinEloss();
private:
G4double GetConstraints(const G4DynamicParticle* aParticle,
G4Material* aMaterial);
// hide assignment operator
G4eLowEnergyLoss (G4eLowEnergyLoss &);
G4eLowEnergyLoss & operator=(const G4eLowEnergyLoss &right);
protected:
virtual G4std::vector<G4DynamicParticle*>* DeexciteAtom(const G4Material* material,
G4double incidentEnergy,
G4double eLoss) { return 0; }
G4PhysicsTable* theLossTable;
G4double MinKineticEnergy ; // particle with kinetic energy
@@ -134,51 +153,6 @@ class G4eLowEnergyLoss : public G4VeLowEnergyLoss
G4double Charge,lastCharge ;
private:
G4PhysicsTable* theDEDXTable;
G4int CounterOfProcess;
G4PhysicsTable** RecorderOfProcess;
G4double fdEdx; // computed in GetConstraints
G4double fRangeNow; // computed in GetConstraints
G4double linLossLimit ; // used in AlongStepDoIt
//New ParticleChange
G4ParticleChangeForLoss fParticleChange ;
//
// static part of the class
//
public: // With description
static void SetNbOfProcesses(G4int nb) {NbOfProcesses=nb;};
// Sets number of processes giving contribution to the energy loss
static void PlusNbOfProcesses() {NbOfProcesses++ ;};
// Increases number of processes giving contribution to the energy loss
static void MinusNbOfProcesses() {NbOfProcesses-- ;};
// Decreases number of processes giving contribution to the energy loss
static G4int GetNbOfProcesses() {return NbOfProcesses;};
// Gets number of processes giving contribution to the energy loss
// ( default value = 2)
static void SetLowerBoundEloss(G4double val) {LowerBoundEloss=val;};
static void SetUpperBoundEloss(G4double val) {UpperBoundEloss=val;};
static void SetNbinEloss(G4int nb) {NbinEloss=nb;};
static G4double GetLowerBoundEloss() {return LowerBoundEloss;};
static G4double GetUpperBoundEloss() {return UpperBoundEloss;};
static G4int GetNbinEloss() {return NbinEloss;};
protected:
//basic DEDX and Range tables
static G4PhysicsTable* theDEDXElectronTable ;
static G4PhysicsTable* theDEDXPositronTable ;
@@ -205,7 +179,34 @@ class G4eLowEnergyLoss : public G4VeLowEnergyLoss
static G4PhysicsTable** RecorderOfElectronProcess;
static G4PhysicsTable** RecorderOfPositronProcess;
private:
G4double GetConstraints(const G4DynamicParticle* aParticle,
G4Material* aMaterial);
// hide assignment operator
G4eLowEnergyLoss (G4eLowEnergyLoss &);
G4eLowEnergyLoss & operator=(const G4eLowEnergyLoss &right);
G4PhysicsTable* theDEDXTable;
G4int CounterOfProcess;
G4PhysicsTable** RecorderOfProcess;
G4double fdEdx; // computed in GetConstraints
G4double fRangeNow; // computed in GetConstraints
G4double linLossLimit ; // used in AlongStepDoIt
//New ParticleChange
G4ParticleChangeForLoss fParticleChange ;
//
// static part of the class
//
static G4int NbinEloss; // number of bins in table,
// calculated in BuildPhysicTable
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4eLowEnergyLoss.icc,v 1.2.2.2 2001/06/28 20:19:25 gunter Exp $
// GEANT4 tag $Name: $
// $Id: G4eLowEnergyLoss.icc,v 1.3 2001/07/11 10:02:39 gunter Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// ---------------------------------------------------------------
// GEANT 4 class inlined methods file
@@ -46,8 +46,13 @@
#ifndef G4hBetheBlochModel_h
#define G4hBetheBlochModel_h 1
#include "globals.hh"
#include "G4VLowEnergyModel.hh"
class G4Material;
class G4ParticleDefinition;
class G4DynamicParticle;
class G4hBetheBlochModel : public G4VLowEnergyModel
{
@@ -47,8 +47,11 @@
#ifndef G4hICRU49He_h
#define G4hICRU49He_h 1
#include "globals.hh"
#include "G4VhElectronicStoppingPower.hh"
class G4Material;
class G4hICRU49He : public G4VhElectronicStoppingPower
{
@@ -48,6 +48,7 @@
#ifndef G4hICRU49Nuclear_h
#define G4hICRU49Nuclear_h 1
#include "globals.hh"
#include "G4VhNuclearStoppingPower.hh"
class G4hICRU49Nuclear : public G4VhNuclearStoppingPower
@@ -48,8 +48,11 @@
#ifndef G4hICRU49p_h
#define G4hICRU49p_h 1
#include "globals.hh"
#include "G4VhElectronicStoppingPower.hh"
class G4Material;
class G4hICRU49p : public G4VhElectronicStoppingPower
{
@@ -48,8 +48,13 @@
#ifndef G4hIonEffChargeSquare_h
#define G4hIonEffChargeSquare_h 1
#include "globals.hh"
#include "G4VLowEnergyModel.hh"
class G4Material;
class G4ParticleDefinition;
class G4DynamicParticle;
class G4hIonEffChargeSquare : public G4VLowEnergyModel
{
@@ -42,6 +42,8 @@
// 09 August 2000 V.Ivanchenko Add GetContinuousStepLimit
// 17 August 2000 V.Ivanchenko Add IonFluctuationModel
// 23 Oct 2000 V.Ivanchenko Renew comments
// 30 Oct 2001 V.Ivanchenko Add minGammaEnergy and minElectronEnergy
// 07 Dec 2001 V.Ivanchenko Add SetFluorescence method
// ------------------------------------------------------------
// Class Description:
@@ -64,6 +66,7 @@
#ifndef G4hLowEnergyIonisation_h
#define G4hLowEnergyIonisation_h 1
#include "globals.hh"
#include "G4hLowEnergyLoss.hh"
#include "G4VLowEnergyModel.hh"
#include "G4Track.hh"
@@ -78,6 +81,11 @@
#include "G4hIonEffChargeSquare.hh"
#include "G4IonChuFluctuationModel.hh"
#include "G4IonYangFluctuationModel.hh"
#include "G4AtomicDeexcitation.hh"
class G4VEMDataSet;
class G4ShellVacancy;
class G4VhShellCrossSection;
class G4hLowEnergyIonisation : public G4hLowEnergyLoss
{
@@ -155,7 +163,10 @@ public: // With description
void SetBarkasOff() {theBarkas = false;};
// This method switch off calculation of the Barkas and Bloch effects.
void SetFluorescence(const G4bool val) {theFluo = val;};
// This method switch on/off simulation of the fluorescence of the media.
G4VParticleChange* AlongStepDoIt(const G4Track& trackData ,
const G4Step& stepData ) ;
// Function to determine total energy deposition on the step
@@ -169,6 +180,13 @@ public: // With description
G4double kineticEnergy);
// This method returns electronic dE/dx for protons or antiproton.
void SetCutForSecondaryPhotons(G4double cut);
// Set threshold energy for fluorescence
void SetCutForAugerElectrons(G4double cut);
// Set threshold energy for Auger electron production
protected:
private:
@@ -177,9 +195,11 @@ private:
void InitializeParametrisation();
void BuildLossTable(const G4ParticleDefinition& aParticleType) ;
void BuildLossTable(const G4ParticleDefinition& aParticleType);
void BuildLambdaTable(const G4ParticleDefinition& aParticleType) ;
void BuildDataForFluorescence(const G4ParticleDefinition& aParticleType);
void BuildLambdaTable(const G4ParticleDefinition& aParticleType);
void SetProtonElectronicStoppingPowerModel(const G4String& dedxTable)
{theProtonTable = dedxTable ;};
@@ -224,6 +244,14 @@ private:
G4double meanLoss,
G4double step) const;
// Function to sample electronic losses
G4std::vector<G4DynamicParticle*>* DeexciteAtom(const G4Material* material,
G4double incidentEnergy,
G4double hMass,
G4double eLoss);
G4int SelectRandomAtom(const G4Material* material,
G4double kineticEnergy) const;
// hide assignment operator
G4hLowEnergyIonisation & operator=(const G4hLowEnergyIonisation &right);
@@ -254,7 +282,10 @@ private:
G4bool nStopping;
G4bool theBarkas;
G4double* deltaCutInKineticEnergy;
G4DataVector cutForDelta;
G4DataVector cutForGamma;
G4double minGammaEnergy;
G4double minElectronEnergy;
G4PhysicsTable* theMeanFreePathTable;
const G4double paramStepLimit; // parameter limits the step at low energy
@@ -264,13 +295,41 @@ private:
G4double charge; //
G4double chargeSquare; //
protected:
private:
G4AtomicDeexcitation deexcitationManager;
G4ShellVacancy* shellVacancy;
G4VhShellCrossSection* shellCS;
G4std::vector<G4VEMDataSet*> zFluoDataVector;
G4bool theFluo;
};
#include "G4hLowEnergyIonisation.icc"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4hLowEnergyIonisation::GetContinuousStepLimit(
const G4Track& track,
G4double,
G4double currentMinimumStep,
G4double&)
{
G4double Step =
GetConstraints(track.GetDynamicParticle(),track.GetMaterial()) ;
if((Step>0.0)&&(Step<currentMinimumStep))
currentMinimumStep = Step ;
return Step ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4bool G4hLowEnergyIonisation::IsApplicable(
const G4ParticleDefinition& particle)
{
return(particle.GetPDGCharge() != 0.0
&& particle.GetPDGMass() > proton_mass_c2*0.1);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
#endif
@@ -1,98 +0,0 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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. *
// ********************************************************************
//
//
// ---------------------------------------------------------------
// GEANT 4 class inlined methods file
//
// ------------ G4hLowEnergyIonisation physics process ------
// by Vladimir Ivanchenko, 27 July 1999
// was made on the base of G4hIonisation class
// developed by Laszlo Urban
// ************************************************************
// It is the extention of the ionisation process for the slow
// charged hadrons.
// ************************************************************
// 28 July 1999 V.Ivanchenko cleen up
// 09 Aug 2000 V.Ivanchenko add GetContinuousStepLimit
// 23 Oct 2000 V.Ivanchenko add control on particle mass
// ---------------------------------------------------------------
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4hLowEnergyIonisation::GetMeanFreePath(
const G4Track& trackData,
G4double previousStepSize,
enum G4ForceCondition* condition)
{
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle() ;
G4Material* aMaterial = trackData.GetMaterial() ;
G4double meanFreePath;
G4bool isOutRange ;
*condition = NotForced ;
G4double kineticEnergy = aParticle->GetKineticEnergy() ;
if(kineticEnergy < LowestKineticEnergy) meanFreePath = DBL_MAX;
else {
if(kineticEnergy > HighestKineticEnergy)
kineticEnergy = HighestKineticEnergy ;
meanFreePath = ((*theMeanFreePathTable)(aMaterial->GetIndex()))->
GetValue(kineticEnergy,isOutRange) ;
}
return meanFreePath ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4double G4hLowEnergyIonisation::GetContinuousStepLimit(
const G4Track& track,
G4double,
G4double currentMinimumStep,
G4double&)
{
G4double Step =
GetConstraints(track.GetDynamicParticle(),track.GetMaterial()) ;
if((Step>0.0)&&(Step<currentMinimumStep))
currentMinimumStep = Step ;
return Step ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
inline G4bool G4hLowEnergyIonisation::IsApplicable(
const G4ParticleDefinition& particle)
{
return(particle.GetPDGCharge() != 0.0
&& particle.GetPDGMass() > proton_mass_c2*0.1);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4hLowEnergyLoss.hh,v 1.10.2.2 2001/06/28 20:19:27 gunter Exp $
// GEANT4 tag $Name: $
// $Id: G4hLowEnergyLoss.hh,v 1.13 2001/11/23 11:45:20 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// $Id:
// ------------------------------------------------------------
@@ -49,6 +49,7 @@
// 02/02/99 L.Urban several bugs fixed
// 31/03/00 V.Ivanchenko rename to lowenergy as G4hLowEnergyLoss.hh
// 09/08/00 V.Ivanchenko remove GetContinuousStepLimit and IsApplicable
// 23/11/01 V.Ivanchenko Move static member-functions from header to source
//
// Class description:
// Class for Low Energy electromagnetic energy loss of hadrons
@@ -126,29 +127,21 @@ class G4hLowEnergyLoss : public G4VContinuousDiscreteProcess
public:
// get the number of processes contributing to the cont.energy loss
static G4int GetNumberOfProcesses() { return NumberOfProcesses; };
static G4int GetNumberOfProcesses();
// set the number of processes contributing to the cont.energy loss
static void SetNumberOfProcesses(G4int number)
{NumberOfProcesses=number ; };
static void SetNumberOfProcesses(G4int number);
// Increment the number of processes contributing to the cont.energy loss
static void PlusNumberOfProcesses()
{ NumberOfProcesses++ ; };
static void PlusNumberOfProcesses();
// decrement the number of processes contributing to the cont.energy loss
static void MinusNumberOfProcesses()
{ NumberOfProcesses-- ; };
static void MinusNumberOfProcesses();
static void SetdRoverRange(G4double value) {dRoverRange = value;}
static void SetRndmStep (G4bool value) {rndmStepFlag = value;}
static void SetEnlossFluc (G4bool value) {EnlossFlucFlag = value;}
static void SetStepFunction (G4double c1, G4double c2)
{dRoverRange = c1; finalRange = c2;
c1lim=dRoverRange ;
c2lim=2.*(1-dRoverRange)*finalRange;
c3lim=-(1.-dRoverRange)*finalRange*finalRange;
}
static void SetdRoverRange(G4double value);
static void SetRndmStep (G4bool value);
static void SetEnlossFluc (G4bool value);
static void SetStepFunction (G4double c1, G4double c2);
protected:
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4hLowEnergyLoss.icc,v 1.1.4.2 2001/06/28 20:19:27 gunter Exp $
// GEANT4 tag $Name: $
// $Id: G4hLowEnergyLoss.icc,v 1.2 2001/07/11 10:02:40 gunter Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// $Id:
// ---------------------------------------------------------------
@@ -46,9 +46,14 @@
#ifndef G4hNuclearStoppingModel_h
#define G4hNuclearStoppingModel_h 1
#include "globals.hh"
#include "G4VLowEnergyModel.hh"
#include "G4VhNuclearStoppingPower.hh"
class G4ParticleDefinition;
class G4Material;
class G4DynamicParticle;
class G4hNuclearStoppingModel : public G4VLowEnergyModel
{
@@ -46,9 +46,14 @@
#ifndef G4hParametrisedLossModel_h
#define G4hParametrisedLossModel_h 1
#include "globals.hh"
#include "G4VLowEnergyModel.hh"
#include "G4VhElectronicStoppingPower.hh"
class G4DynamicParticle;
class G4ParticleDefinition;
class G4Material;
class G4hParametrisedLossModel : public G4VLowEnergyModel
{
@@ -0,0 +1,74 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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. *
// ********************************************************************
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4hShellCrossSection
//
// Author: S. Dussoni and A. Mantero (Alfonso.Mantero@ge.infn.it)
//
// History:
// -----------
// 23 Oct 2001 A. Mantero 1st implementation
// 24 Oct 2001 MGP Cleaned up
// 29 Oct 2001 VI Add delta energy
//
// -------------------------------------------------------------------
// Class Description:
// Model for shell cross sections in proton ionisation
// -------------------------------------------------------------------
#ifndef G4HSHELLCROSSSECTION_HH
#define G4HSHELLCROSSSECTION_HH 1
#include "globals.hh"
#include "G4VhShellCrossSection.hh"
class G4hShellCrossSection : public G4VhShellCrossSection
{
public:
G4hShellCrossSection();
virtual ~G4hShellCrossSection();
protected:
virtual G4std::vector<G4double> Probabilities(G4int Z,
G4double incidentEnergy,
G4double mass,
G4double deltaEnergy) const;
private:
// Hide copy constructor and assignment operator
G4hShellCrossSection(const G4hShellCrossSection&);
G4hShellCrossSection & operator = (const G4hShellCrossSection &right);
};
#endif
@@ -48,8 +48,11 @@
#ifndef G4hZiegler1977He_h
#define G4hZiegler1977He_h 1
#include "globals.hh"
#include "G4VhElectronicStoppingPower.hh"
class G4Material;
class G4hZiegler1977He : public G4VhElectronicStoppingPower
{
@@ -48,6 +48,7 @@
#ifndef G4hZiegler1977Nuclear_h
#define G4hZiegler1977Nuclear_h 1
#include "globals.hh"
#include "G4VhNuclearStoppingPower.hh"
class G4hZiegler1977Nuclear : public G4VhNuclearStoppingPower
@@ -48,8 +48,11 @@
#ifndef G4hZiegler1977p_h
#define G4hZiegler1977p_h 1
#include "globals.hh"
#include "G4VhElectronicStoppingPower.hh"
class G4Material;
class G4hZiegler1977p : public G4VhElectronicStoppingPower
{
@@ -49,6 +49,7 @@
#ifndef G4hZiegler1985Nuclear_h
#define G4hZiegler1985Nuclear_h 1
#include "globals.hh"
#include "G4VhNuclearStoppingPower.hh"
class G4hZiegler1985Nuclear : public G4VhNuclearStoppingPower
@@ -48,8 +48,11 @@
#ifndef G4hZiegler1985p_h
#define G4hZiegler1985p_h 1
#include "globals.hh"
#include "G4VhElectronicStoppingPower.hh"
class G4Material;
class G4hZiegler1985p : public G4VhElectronicStoppingPower
{
@@ -0,0 +1,237 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4AtomicTransitionManager.hh,v 1.2 ????
// GEANT4 tag $Name: geant4-04-00 $
//
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
//
// History:
// -----------
//
// 16 Sept 2001 First committed to cvs
//
// -------------------------------------------------------------------
#include "G4AtomicDeexcitation.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
G4AtomicDeexcitation::G4AtomicDeexcitation()
{ }
G4AtomicDeexcitation::~G4AtomicDeexcitation()
{ }
G4std::vector<G4DynamicParticle*>* G4AtomicDeexcitation::GenerateParticles(G4int Z,G4int shellId)
{
G4std::vector<G4DynamicParticle*>* vectorOfParticles = new G4std::vector<G4DynamicParticle*>;
G4DynamicParticle* aParticle;
G4int provShellId = 0;
G4int counter = 0;
// The aim of this loop is to generate more than one fluorecence photon
// from the same ionizing event
while (provShellId >= 0)
{
if (counter == 0)
// First call to GenerateParticles(...):
// shellId is given by the process
{
provShellId = SelectTypeOfTransition(Z, shellId);
if ( provShellId >0)
{
aParticle = GenerateFluorescence(Z,shellId,provShellId);
}
else if ( provShellId ==-1)
{
aParticle = GenerateAuger(Z, shellId);
}
else
{
G4Exception("G4AtomicDeexcitation: starting shell uncorrect: check it");
}
}
else
// Following calls to GenerateParticles(...):
// newShellId is given by GenerateFluorescence(...)
{
provShellId = SelectTypeOfTransition(Z,newShellId);
if ( provShellId >0)
{
aParticle = GenerateFluorescence(Z,newShellId,provShellId);
}
else if ( provShellId ==-1)
{
aParticle = GenerateAuger(Z, newShellId);
}
else
{
G4Exception("G4AtomicDeexcitation: starting shell uncorrect: check it");
}
}
counter++;
vectorOfParticles->push_back(aParticle);
}
return vectorOfParticles;
}
const G4int G4AtomicDeexcitation::SelectTypeOfTransition(G4int Z, G4int shellId)
{
if (shellId <=0 )
{G4Exception("G4AtomicDeexcitation: zero or negative shellId");}
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
G4int provShellId = -1;
G4int shellNum = 0;
G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z);
const G4AtomicTransition* refShell = transitionManager->ReachableShell(Z,maxNumOfShells-1);
// This loop gives shellNum the value of the index of shellId
// in the vector storing the list of the shells reachable through
// a radiative transition
if ( shellId <= refShell->FinalShellId())
{
while (shellId != transitionManager->ReachableShell(Z,shellNum)->FinalShellId())
{
if(shellNum ==maxNumOfShells-1)
{
break;
}
shellNum++;
}
G4int transProb = 1;
G4double partialProb = G4UniformRand();
G4double partSum = 0;
const G4AtomicTransition* aShell = transitionManager->ReachableShell(Z,shellNum);
G4int trSize = (aShell->TransitionProbabilities()).size();
// Loop over the shells wich can provide an electron for a
// radiative transition towards shellId:
// in every loop the partial sum of the first transProb shells
// is calculated and compared with a random number [0,1].
// If the partial sum is greater the shell whose index transProb
// is chosen as the starting shell for a radiative transition
// and its identity is returned
// Else, terminateded the loop, -1 is returned
while(transProb < trSize){
partSum += aShell->TransitionProbability(transProb);
if(partialProb <= partSum)
{
provShellId = aShell->OriginatingShellId(transProb);
break;
}
transProb++;
}
}
else
{
provShellId = -1;
}
return provShellId;
}
G4DynamicParticle* G4AtomicDeexcitation::GenerateFluorescence(G4int Z,
G4int shellId,
G4int provShellId )
{
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
// G4int provenienceShell = provShellId;
//isotropic angular distribution for the outcoming photon
G4double newcosTh = 1.-2.*G4UniformRand();
G4double newsinTh = sqrt(1.-newcosTh*newcosTh);
G4double newPhi = twopi*G4UniformRand();
G4double xDir = newsinTh*sin(newPhi);
G4double yDir = newsinTh*cos(newPhi);
G4double zDir = newcosTh;
G4ThreeVector newGammaDirection(xDir,yDir,zDir);
G4int shellNum = 0;
G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z);
// find the index of the shell named shellId
while (shellId != transitionManager->
ReachableShell(Z,shellNum)->FinalShellId())
{
if(shellNum == maxNumOfShells-1)
{
break;
}
shellNum++;
}
// number of shell from wich an electron can reach shellId
size_t transitionSize = transitionManager->
ReachableShell(Z,shellNum)->OriginatingShellIds().size();
size_t index = 0;
// find the index of the shell named provShellId in the vector
// storing the shells from which shellId can be reached
while (provShellId != transitionManager->
ReachableShell(Z,shellNum)->OriginatingShellId(index))
{
if(index == transitionSize-1)
{
break;
}
index++;
}
// energy of the gamma leaving provShellId for shellId
G4double transitionEnergy = transitionManager->
ReachableShell(Z,shellNum)->TransitionEnergy(index);
// This is the shell where the new vacancy is: it is the same
// shell where the electron came from
newShellId = transitionManager->
ReachableShell(Z,shellNum)->OriginatingShellId(index);
G4DynamicParticle* newPart = new G4DynamicParticle(G4Gamma::Gamma(),
newGammaDirection,
transitionEnergy);
return newPart;
}
G4DynamicParticle* G4AtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId)
{
return 0;
}
@@ -21,42 +21,37 @@
// ********************************************************************
//
//
// -------------------------------------------------------------------
// GEANT 4 class file
// $Id: G4AtomicShell.cc,v 1.2 ????
// GEANT4 tag $Name: geant4-04-00 $
//
// CERN, Geneva, Switzerland
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
//
// File name: G4FirstLevel.hh
// History:
// -----------
// 16 Sept 2001 EG Modified according to a design iteration in the
// LowEnergy category
//
// Author: Alessandra Forti (Alessandra.Forti@cern.ch)
//
// Creation date: 1 Giugno 1999
//
// Modifications: 24.04.01 V.Ivanchenko remove RogueWave
//
// -------------------------------------------------------------------
#include "G4FirstLevel.hh"
#include "G4AtomicShell.hh"
G4AtomicShell::G4AtomicShell(G4int id, G4double energy)
{
identifier = id;
bindingEnergy = energy;
}
G4FirstLevel::~G4FirstLevel(){
G4AtomicShell::~G4AtomicShell()
{ }
//this->clearAndDestroy();
this->clear();
}
G4bool G4FirstLevel::operator == (const G4FirstLevel& input) const{
// return( this->entries() == input.entries());
return( this->size() == input.size());
}
G4bool G4FirstLevel::operator < (const G4FirstLevel& input) const{
// return(this->entries() < input.entries());
return(this->size() < input.size());
G4double G4AtomicShell::BindingEnergy() const {
return bindingEnergy;
}
G4int G4AtomicShell::ShellId() const{
return identifier;
}
@@ -0,0 +1,84 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4AtomicTransition.cc,v 1.2 ????
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
//
// History:
// -----------
// 16 Sept 2001 EG Modified according to a design iteration in the
// LowEnergy category
//
// -------------------------------------------------------------------
#include "G4AtomicTransition.hh"
G4AtomicTransition::G4AtomicTransition(G4int finalShell,
const G4std::vector<G4int>& ids,
const G4DataVector& energies,
const G4DataVector& prob)
{
finalShellId = finalShell;
originatingShellIds = ids;
transitionEnergies = energies;
transitionProbabilities = prob;
}
G4AtomicTransition::~G4AtomicTransition()
{ }
const G4std::vector<G4int>& G4AtomicTransition::OriginatingShellIds() const
{
return originatingShellIds;
}
const G4DataVector& G4AtomicTransition::TransitionEnergies() const
{
return transitionEnergies;
}
const G4DataVector& G4AtomicTransition::TransitionProbabilities() const
{
return transitionProbabilities;
}
const G4int G4AtomicTransition::FinalShellId() const
{
return finalShellId;
}
G4int G4AtomicTransition::OriginatingShellId(G4int index) const
{
return originatingShellIds[index];
}
G4double G4AtomicTransition::TransitionEnergy(G4int index) const
{
return transitionEnergies[index];
}
G4double G4AtomicTransition::TransitionProbability(G4int index) const
{
return transitionProbabilities[index];
}
@@ -0,0 +1,324 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4AtomicTransitionManager.cc,v 1.2 ????
// GEANT4 tag $Name: geant4-04-00 $
//
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
//
// History:
// -----------
// 16 Sep 2001 E. Guardincerri First Committed to cvs
//
// -------------------------------------------------------------------
#include "G4AtomicTransitionManager.hh"
G4AtomicTransitionManager::G4AtomicTransitionManager(G4int minZ, G4int maxZ, G4int limitInfTable,G4int limitSupTable)
:zMin(minZ), zMax(maxZ),infTableLimit(limitInfTable),supTableLimit(limitSupTable)
{
// infTableLimit is initialized to 6 because EADL lacks data for Z<=5
G4ShellData* shellManager = new G4ShellData;
shellManager->LoadData("/fluor/binding");
// Fills shellTable with the data from EADL, identities and binding
// energies of shells
for (G4int Z = zMin; Z<= zMax; Z++)
{
G4std::vector<G4AtomicShell*> vectorOfShells;
size_t numberOfShells=shellManager->NumberOfShells(Z);
for (size_t shellIndex = 0; shellIndex<numberOfShells; shellIndex++)
{
G4int shellId = shellManager->ShellId(Z,shellIndex);
G4double bindingEnergy = shellManager->BindingEnergy(Z,shellIndex);
G4AtomicShell * shell = new G4AtomicShell(shellId,bindingEnergy);
vectorOfShells.push_back(shell);
}
// shellTable.insert(G4std::make_pair(Z, vectorOfShells));
shellTable[Z] = vectorOfShells;
}
// Fills transitionTable with the data from EADL, identities, transition
// energies and transition probabilities
for (G4int Znum= infTableLimit; Znum<=supTableLimit; Znum++)
{ G4FluoData* fluoManager = new G4FluoData;
G4std::vector<G4AtomicTransition*> vectorOfTransitions;
fluoManager->LoadData(Znum);
size_t numberOfVacancies = fluoManager-> NumberOfVacancies();
for (size_t vacancyIndex = 0; vacancyIndex<numberOfVacancies; vacancyIndex++)
{
G4std::vector<G4int> vectorOfIds;
G4DataVector vectorOfEnergies;
G4DataVector vectorOfProbabilities;
G4int finalShell = fluoManager->VacancyId(vacancyIndex);
size_t numberOfTransitions = fluoManager->NumberOfTransitions(vacancyIndex);
for (size_t origShellIndex = 0; origShellIndex <= numberOfTransitions;origShellIndex++)
{
G4int originatingShellId = fluoManager->StartShellId(origShellIndex,vacancyIndex);
vectorOfIds.push_back(originatingShellId);
G4double transitionEnergy = fluoManager->StartShellEnergy(origShellIndex,vacancyIndex);
vectorOfEnergies.push_back(transitionEnergy);
G4double transitionProbability = fluoManager->StartShellProb(origShellIndex,vacancyIndex);
vectorOfProbabilities.push_back(transitionProbability);
}
G4AtomicTransition * transition = new G4AtomicTransition (finalShell,vectorOfIds,
vectorOfEnergies,vectorOfProbabilities);
vectorOfTransitions.push_back(transition);
}
// transitionTable.insert(G4std::make_pair(Znum, vectorOfTransitions));
transitionTable[Znum] = vectorOfTransitions;
delete fluoManager;
}
delete shellManager;
}
G4AtomicTransitionManager::~G4AtomicTransitionManager()
{ G4std::map<G4int,G4std::vector<G4AtomicShell*>,G4std::less<G4int> >::iterator pos;
for (pos = shellTable.begin(); pos != shellTable.end(); pos++){
G4std::vector< G4AtomicShell*>vec = (*pos).second;
G4int vecSize=vec.size();
for (G4int i=0; i< vecSize; i++){
delete vec[i];
}
}
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator ppos;
for (ppos = transitionTable.begin(); ppos != transitionTable.end(); ppos++){
G4std::vector< G4AtomicTransition*>vec = (*ppos).second;
G4int vecSize=vec.size();
for (G4int i=0; i< vecSize; i++){
delete vec[i];
}
}
}
G4AtomicTransitionManager* G4AtomicTransitionManager::instance = 0;
G4AtomicTransitionManager* G4AtomicTransitionManager::Instance()
{
if (instance==0)
{
instance = new G4AtomicTransitionManager;
}
return instance;
}
const G4AtomicShell* G4AtomicTransitionManager::Shell(G4int Z, size_t shellIndex)
{
G4std::map<G4int,G4std::vector<G4AtomicShell*>,G4std::less<G4int> >::iterator pos;
pos = shellTable.find(Z);
if (pos!= shellTable.end()){
G4std::vector<G4AtomicShell*> v = (*pos).second;
if (shellIndex<v.size()){
return(v[shellIndex]);
}
else {
G4Exception("G4AtomicTransitionManager:shell not found");
return 0;
}
}
else{
G4Exception("G4AtomicTransitionManager:Z not found");
return 0;
}
}
const G4AtomicTransition* G4AtomicTransitionManager:: ReachableShell(G4int Z,size_t shellIndex)
{
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator pos;
pos = transitionTable.find(Z);
if (pos!= transitionTable.end())
{
G4std::vector<G4AtomicTransition*> v = (*pos).second;
if (shellIndex < v.size()) return(v[shellIndex]);
else {
G4Exception("G4AtomicTransitionManager:reachable shell not found");
return 0;
}
}
else{
G4Exception("G4AtomicTransitionManager:Z not found");
return 0;
}
}
G4int G4AtomicTransitionManager::NumberOfShells (G4int Z)
{
G4std::map<G4int,G4std::vector<G4AtomicShell*>,G4std::less<G4int> >::iterator pos;
pos = shellTable.find(Z);
if (pos!= shellTable.end()){
G4std::vector<G4AtomicShell*> v = (*pos).second;
return v.size();
}
else{
G4Exception( "G4AtomicTransitionManager: Z not found" );
return 0;
}
}
G4int G4AtomicTransitionManager::NumberOfReachableShells(G4int Z)
{
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator pos;
pos = transitionTable.find(Z);
if (pos!= transitionTable.end())
{
G4std::vector<G4AtomicTransition*> v = (*pos).second;
return v.size();
}
else
{
G4Exception( "G4AtomicTransitionManager: Z not found" );
return 0;
}
}
G4double G4AtomicTransitionManager::TotalRadiativeTransitionProbability(G4int Z,
size_t shellIndex)
{
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator pos;
pos = transitionTable.find(Z);
if (pos!= transitionTable.end())
{
G4std::vector<G4AtomicTransition*> v = (*pos).second;
if (shellIndex < v.size())
{
G4AtomicTransition* transition = v[shellIndex];
G4DataVector transProb = transition->TransitionProbabilities();
G4double totalRadTransProb = 0;
for (size_t j = 1; j<transProb.size(); j++)
{
totalRadTransProb = totalRadTransProb + transProb[j];
}
return totalRadTransProb;
}
else {
G4Exception( "G4AtomicTransitionManager: shell not found" );
return 0;
}
}
else{
G4Exception( "G4AtomicTransitionManager: Z not found");
return 0;
}
}
G4double G4AtomicTransitionManager::TotalNonRadiativeTransitionProbability(G4int Z, size_t shellIndex)
{
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator pos;
pos = transitionTable.find(Z);
if (pos!= transitionTable.end()){
G4std::vector<G4AtomicTransition*> v = (*pos).second;
if (shellIndex<v.size()){
G4AtomicTransition* transition=v[shellIndex];
G4DataVector transProb = transition->TransitionProbabilities();
G4double totalRadTransProb = 0;
for(size_t j = 1; j<transProb.size(); j++)
{
totalRadTransProb = totalRadTransProb + transProb[j];
}
G4double totalNonRadTransProb= (1 - totalRadTransProb);
return totalNonRadTransProb; }
else {
G4Exception( "shell not found");
return 0;
}
}
else{
G4Exception("Z not found");
return 0;
}
}
@@ -0,0 +1,125 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4BremsstrahlungCrossSectionHandler.cc,v 1.5 2001/10/25 14:31:20 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4BremsstrahlungCrossSectionHandler
//
// Author: V.Ivanchenko (Vladimir.Ivanchenko@cern.ch)
//
// Creation date: 25 September 2001
//
// Modifications:
// 10.10.2001 MGP Revision to improve code quality and consistency with design
//
// -------------------------------------------------------------------
#include "G4BremsstrahlungCrossSectionHandler.hh"
#include "G4eBremsstrahlungSpectrum.hh"
#include "G4DataVector.hh"
#include "G4CompositeEMDataSet.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4SemiLogInterpolation.hh"
#include "G4VEMDataSet.hh"
#include "G4EMDataSet.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
G4BremsstrahlungCrossSectionHandler::G4BremsstrahlungCrossSectionHandler(const G4VEnergySpectrum* spec,
G4VDataSetAlgorithm* alg)
: theBR(spec)
{
interp = new G4SemiLogInterpolation();
}
G4BremsstrahlungCrossSectionHandler::~G4BremsstrahlungCrossSectionHandler()
{
delete interp;
}
G4std::vector<G4VEMDataSet*>*
G4BremsstrahlungCrossSectionHandler::BuildCrossSectionsForMaterials(const G4DataVector& energyVector,
const G4DataVector* energyCuts)
{
G4std::vector<G4VEMDataSet*>* set = new G4std::vector<G4VEMDataSet*>;
G4DataVector* energies;
G4DataVector* cs;
G4int nOfBins = energyVector.size();
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
if (materialTable == 0)
G4Exception("G4VCrossSectionHandler::G4VCrossSectionHandler - no MaterialTable found)");
G4int nMaterials = G4Material::GetNumberOfMaterials();
for (G4int m=0; m<nMaterials; m++) {
const G4Material* material = (*materialTable)[m];
const G4ElementVector* elementVector = material->GetElementVector();
const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
G4int nElements = material->GetNumberOfElements();
G4double tcut = (*energyCuts)[m];
G4VDataSetAlgorithm* algo = interp->Clone();
G4VEMDataSet* setForMat = new G4CompositeEMDataSet(algo,1.,1.);
for (G4int i=0; i<nElements; i++) {
G4int Z = (G4int) ((*elementVector)[i]->GetZ());
energies = new G4DataVector;
cs = new G4DataVector;
G4double density = nAtomsPerVolume[i];
for (G4int bin=0; bin<nOfBins; bin++) {
G4double e = energyVector[bin];
energies->push_back(e);
G4double value = 0.0;
if(e > tcut) {
G4double elemCs = FindValue(Z, e);
value = theBR->Probability(Z, tcut, e, e);
value *= elemCs*density;
}
cs->push_back(value);
}
G4VDataSetAlgorithm* algol = interp->Clone();
G4VEMDataSet* elSet = new G4EMDataSet(i,energies,cs,algol,1.,1.);
setForMat->AddComponent(elSet);
}
set->push_back(setForMat);
}
return set;
}
@@ -0,0 +1,295 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4BremsstrahlungParameters.cc,v 1.11 2001/11/29 22:59:56 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
// V.Ivanchenko (Vladimir.Ivantchenko@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created
// 12.09.01 V.Ivanchenko Add activeZ and paramA
// 25.09.01 V.Ivanchenko Add parameter C and change interface to B
// 29.11.01 V.Ivanchenko Update parametrisation
//
// -------------------------------------------------------------------
#include "G4BremsstrahlungParameters.hh"
#include "G4VEMDataSet.hh"
#include "G4EMDataSet.hh"
#include "G4LogLogInterpolation.hh"
#include "G4Material.hh"
#include "g4std/fstream"
#include "g4std/strstream"
G4BremsstrahlungParameters:: G4BremsstrahlungParameters(G4int minZ, G4int maxZ)
: zMin(minZ),
zMax(maxZ),
length(16)
{
LoadData();
}
G4BremsstrahlungParameters::~G4BremsstrahlungParameters()
{
// Reset the map of data sets: remove the data sets from the map
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::iterator pos;
for (pos = param.begin(); pos != param.end(); pos++)
{
G4VEMDataSet* dataSet = (*pos).second;
delete dataSet;
}
activeZ.clear();
paramC.clear();
}
G4double G4BremsstrahlungParameters::Parameter(G4int parameterIndex,
G4int Z,
G4double energy) const
{
G4double value = 0.;
G4int id = Z*20 + parameterIndex;
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
pos = param.find(id);
if (pos!= param.end()) {
G4VEMDataSet* dataSet = (*pos).second;
const G4DataVector ener = dataSet->GetEnergies(0);
G4double ee = G4std::max(ener.front(),G4std::min(ener.back(),energy));
value = dataSet->FindValue(ee);
} else {
G4cout << "WARNING: G4BremsstrahlungParameters::FindValue "
<< "did not find ID = "
<< id << G4endl;
}
return value;
}
void G4BremsstrahlungParameters::LoadData()
{
// Build the complete string identifying the file with the data set
// define active elements
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
if (materialTable == 0)
G4Exception("G4CrossSectionHandler: no MaterialTable found)");
G4int nMaterials = G4Material::GetNumberOfMaterials();
G4double x = 1.e-9;
for (G4int mm=0; mm<100; mm++) {
paramC.push_back(x);
}
for (G4int m=0; m<nMaterials; m++) {
const G4Material* material= (*materialTable)[m];
const G4ElementVector* elementVector = material->GetElementVector();
const G4int nElements = material->GetNumberOfElements();
for (G4int iEl=0; iEl<nElements; iEl++) {
G4Element* element = (*elementVector)[iEl];
G4double Z = element->GetZ();
G4int iz = (G4int)Z;
if(iz < 100)
paramC[iz] = 0.217635e-33*(material->GetTotNbOfElectPerVolume());
if (!(activeZ.contains(Z))) {
activeZ.push_back(Z);
}
}
}
// Read parameters
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = G4String("G4BremsstrahlungParameters - G4LEDATA")
+ G4String("environment variable not set");
G4Exception(excep);
}
G4String pathString_a(path);
G4String name_a = pathString_a + "/brem/br-sp.dat";
G4std::ifstream file_a(name_a);
G4std::filebuf* lsdp_a = file_a.rdbuf();
if (! (lsdp_a->is_open()) ) {
G4String excep = G4String("G4BremsstrahlungParameters: cannot open file ")
+ name_a;
G4Exception(excep);
}
// The file is organized into two columns:
// 1st column is the energy
// 2nd column is the corresponding value
// The file terminates with the pattern: -1 -1
// -2 -2
G4DataVector* energies;
G4DataVector* data;
G4double ener = 0.0;
G4double sum = 0.0;
energies = new G4DataVector();
data = new G4DataVector();
G4int z = 0;
G4bool used = false;
G4std::vector<G4DataVector*> a;
for (size_t j=0; j<length; j++) {
G4DataVector* aa = new G4DataVector();
a.push_back(aa);
}
G4DataVector e;
e.clear();
do {
file_a >> ener >> sum;
// End of file
if (ener == -2) {
break;
// End of next element
} else if (ener == -1) {
z++;
G4double Z = (G4double)z;
// fill map if Z is used
if (activeZ.contains(Z)) {
for (size_t k=0; k<length; k++) {
G4int id = z*20 + k;
G4VDataSetAlgorithm* inter = new G4LogLogInterpolation();
G4DataVector* eVector = new G4DataVector;
size_t eSize = e.size();
for (size_t s=0; s<eSize; s++) {
eVector->push_back(e[s]);
}
G4VEMDataSet* set = new G4EMDataSet(id,eVector,a[k],inter,1.,1.);
param[id] = set;
}
used = true;
a.clear();
for (size_t j=0; j<length; j++) {
G4DataVector* aa = new G4DataVector();
a.push_back(aa);
}
}
if(!used) {
for (size_t j=0; j<length; j++) {
a[j]->clear();
used = false;
}
}
e.clear();
} else {
if(ener > 1000.) ener = 1000.;
e.push_back(ener);
a[length-1]->push_back(sum);
for (size_t j=0; j<length-1; j++) {
G4double qRead;
file_a >> qRead;
/*
if(ener == 1000.) {
G4double x = 0.1*((G4double)j);
if(j == 0) x = 0.01;
if(j == 10) x = 0.95;
if(j == 11) x = 0.97;
if(j == 12) x = 0.99;
if(j == 13) x = 0.995;
if(j == 14) x = 1.0;
qRead = 1. - x + 0.75*x*x;
}
*/
a[j]->push_back(qRead);
}
}
} while (ener != -2);
file_a.close();
}
G4double G4BremsstrahlungParameters::ParameterC(G4int id) const
{
G4int n = paramC.size();
if (id < 0 || id >= n) {
G4String ex = "G4BremsstrahlungParameters::ParameterC - wrong id=" + id;
G4Exception(ex);
}
return paramC[id];
}
void G4BremsstrahlungParameters::PrintData() const
{
G4cout << G4endl;
G4cout << "===== G4BremsstrahlungParameters =====" << G4endl;
G4cout << G4endl;
G4cout << "===== Parameters =====" << G4endl;
G4cout << G4endl;
size_t nZ = activeZ.size();
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
for (size_t j=0; j<nZ; j++) {
G4int Z = (G4int)activeZ[j];
for (size_t i=0; i<length; i++) {
pos = param.find(Z*20 + i);
if (pos!= param.end()) {
G4cout << "===== Z= " << Z
<< " parameter[" << i << "] ====="
<< G4endl;
G4VEMDataSet* dataSet = (*pos).second;
dataSet->PrintData();
}
}
}
G4cout << "==========================================" << G4endl;
}
@@ -0,0 +1,188 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4CompositeEMDataSet.cc,v 1.5 2001/10/25 02:32:16 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 1 Aug 2001 MGP Created
//
// -------------------------------------------------------------------
#include "G4CompositeEMDataSet.hh"
#include "G4EMDataSet.hh"
#include "G4VDataSetAlgorithm.hh"
#include "g4std/fstream"
#include "g4std/strstream"
G4CompositeEMDataSet::G4CompositeEMDataSet(G4VDataSetAlgorithm* interpolation,
G4double unitE, G4double unitData,
G4int minZ, G4int maxZ)
:algorithm(interpolation), unit1(unitE), unit2(unitData), zMin(minZ), zMax(maxZ)
{
nComponents = 0;
}
G4CompositeEMDataSet::G4CompositeEMDataSet(const G4String& dataFile,
G4VDataSetAlgorithm* interpolation,
G4double unitE, G4double unitData,
G4int minZ, G4int maxZ)
: algorithm(interpolation), unit1(unitE), unit2(unitData), zMin(minZ), zMax(maxZ)
{
nComponents = 0;
LoadData(dataFile);
}
G4CompositeEMDataSet::~G4CompositeEMDataSet()
{
for (size_t i=0; i<nComponents; i++)
{
delete components[i];
}
delete algorithm;
}
G4double G4CompositeEMDataSet::FindValue(G4double e, G4int id) const
{
// Returns the value in component id corresponding to e
G4double value = 0.;
G4VEMDataSet* component = components[id];
if (component != 0)
{
value = component->FindValue(e);
}
else
{
G4cout << "WARNING - G4CompositeEMDataSet::FindValue - component "
<< id << " not found" << G4endl;
}
return value;
}
void G4CompositeEMDataSet::PrintData() const
{
G4cout << "The data set has " << nComponents << " components" << G4endl;
for (size_t i=0; i<nComponents; i++)
{
G4cout << "--- Component " << i << " ---" << G4endl;
G4VEMDataSet* component = components[i];
component->PrintData();
}
}
void G4CompositeEMDataSet::LoadData(const G4String& fileName)
{
for (G4int Z=zMin; Z<zMax; Z++)
{
// Build the complete string identifying the file with the data set
char nameChar[100] = {""};
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
ost << fileName << Z << ".dat";
G4String name(nameChar);
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = "G4CompositeEMDataSet - G4LEDATA environment variable not set";
G4Exception(excep);
}
G4String pathString(path);
G4String dirFile = pathString + "/" + name;
G4std::ifstream file(dirFile);
G4std::filebuf* lsdp = file.rdbuf();
if (! (lsdp->is_open()) )
{
G4String excep = "G4CompositeEMDataSet - data file: " + dirFile + " not found";
G4Exception(excep);
}
G4double a = 0;
G4int k = 1;
G4DataVector* energies = new G4DataVector;
G4DataVector* data = new G4DataVector;
do
{
file >> a;
G4int nColumns = 2;
// The file is organized into two columns:
// 1st column is the energy
// 2nd column is the corresponding value
// The file terminates with the pattern: -1 -1
// -2 -2
if (a == -1 || a == -2)
{
}
else
{
if (k%nColumns != 0)
{
G4double e = a * unit1;
energies->push_back(e);
k++;
}
else if (k%nColumns == 0)
{
G4double value = a * unit2;
data->push_back(value);
k = 1;
}
}
} while (a != -2); // end of file
file.close();
G4VDataSetAlgorithm* algo = algorithm->Clone();
G4VEMDataSet* dataSet = new G4EMDataSet(Z,energies,data,algo);
AddComponent(dataSet);
}
}
void G4CompositeEMDataSet::AddComponent(G4VEMDataSet* component)
{
components.push_back(component);
nComponents++;
}
const G4DataVector& G4CompositeEMDataSet::GetEnergies(G4int i) const
{
const G4VEMDataSet* component = GetComponent(i);
return (component->GetEnergies(i));
}
const G4DataVector& G4CompositeEMDataSet::GetData(G4int i) const
{
const G4VEMDataSet* component = GetComponent(i);
return (component->GetData(i));
}
@@ -0,0 +1,90 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4CrossSectionHandler.cc,v 1.12 2001/10/08 07:48:57 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 1 Aug 2001 MGP Created
//
// -------------------------------------------------------------------
#include "G4CrossSectionHandler.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4VEMDataSet.hh"
#include "G4EMDataSet.hh"
#include "G4CompositeEMDataSet.hh"
#include "G4ShellEMDataSet.hh"
#include "G4MaterialTable.hh"
#include "G4Material.hh"
#include "G4Element.hh"
#include "Randomize.hh"
#include "g4std/map"
#include "g4std/vector"
#include "g4std/fstream"
#include "g4std/strstream"
#include "G4LogLogInterpolation.hh"
G4CrossSectionHandler::G4CrossSectionHandler()
{ }
G4CrossSectionHandler::~G4CrossSectionHandler()
{ }
G4std::vector<G4VEMDataSet*>*
G4CrossSectionHandler::BuildCrossSectionsForMaterials(const G4DataVector& energyVector,
const G4DataVector* energyCuts)
{
G4DataVector* energies;
G4DataVector* data;
G4std::vector<G4VEMDataSet*>* matCrossSections = new G4std::vector<G4VEMDataSet*>;
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
G4int nMaterials = G4Material::GetNumberOfMaterials();
size_t nOfBins = energyVector.size();
for (G4int m=0; m<nMaterials; m++)
{
const G4Material* material= (*materialTable)[m];
energies = new G4DataVector;
data = new G4DataVector;
G4VDataSetAlgorithm* interpolationAlgo = CreateInterpolation();
for (size_t bin=0; bin<nOfBins; bin++)
{
G4double e = energyVector[bin];
energies->push_back(e);
G4double materialCrossSection = ValueForMaterial(material,e);
data->push_back(materialCrossSection);
}
G4VEMDataSet* dataSet = new G4EMDataSet(m,energies,data,interpolationAlgo,1.,1.);
matCrossSections->push_back(dataSet);
}
return matCrossSections;
}
@@ -0,0 +1,73 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4CutsPerMaterialWarning.cc,v 1.1 2001/11/07 22:39:02 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 05 Oct 2001 MGP Created
//
// -------------------------------------------------------------------
#include "G4CutsPerMaterialWarning.hh"
#include "G4ParticleDefinition.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
void G4CutsPerMaterialWarning::PrintWarning(const G4ParticleDefinition* particle) const
{
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
size_t nMaterials = materialTable->size();
if (nMaterials > 1)
{
G4Material* material = (*materialTable)[0];
G4double cut0 = particle->GetRangeThreshold(material);
G4double cut = cut0;
G4bool different = false;
size_t mat = 0;
while ((!different) && mat < (nMaterials-1))
{
mat++;
G4Material* material = (*materialTable)[mat];
cut = particle->GetRangeThreshold(material);
if (cut != cut0) different = true;
}
if (different)
{
G4cout << "========================== W A R N I N G ============================ " << G4endl
<< " " << G4endl
<< "You are using different range thresholds for different materials" << G4endl
<< "This is an UNSUPPORTED feature temporarily implemented in Geant4" << G4endl
<< "Geant4 Low Energy Electromagnetic Physics Processes are not supported," << G4endl
<< "if this feature is activated and you may get inconsistent results" << G4endl
<< "Please define the same range threshold for all materials" << G4endl
<< " " << G4endl
<< "========================== W A R N I N G ============================ " << G4endl;
}
}
}
@@ -0,0 +1,218 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4EMDataSet.cc,v 1.5 2001/10/08 07:48:57 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created
//
// -------------------------------------------------------------------
#include "G4EMDataSet.hh"
#include "G4VDataSetAlgorithm.hh"
#include "g4std/fstream"
#include "g4std/strstream"
// Constructor
G4EMDataSet::G4EMDataSet(G4int Z,
G4DataVector* points,
G4DataVector* values,
G4VDataSetAlgorithm* interpolation,
G4double unitE, G4double unitData)
:z(Z), energies(points), data(values), algorithm(interpolation)
{
numberOfBins = energies->size();
unit1 = unitE;
unit2 = unitData;
if (interpolation == 0)
G4Exception("G4EMDataSet::G4EMDataSet - interpolation algorithm = 0");
}
G4EMDataSet:: G4EMDataSet(G4int Z,
const G4String& dataFile,
G4VDataSetAlgorithm* interpolation,
G4double unitE, G4double unitData)
:z(Z), algorithm(interpolation)
{
energies = new G4DataVector;
data = new G4DataVector;
unit1 = unitE;
unit2 = unitData;
LoadData(dataFile);
numberOfBins = energies->size();
if (interpolation == 0)
G4Exception("G4EMDataSet::G4EMDataSet - interpolation algorithm = 0");
}
// Destructor
G4EMDataSet::~G4EMDataSet()
{
delete algorithm;
delete energies;
delete data;
}
G4double G4EMDataSet::FindValue(G4double e, G4int id) const
{
G4double value;
G4double e0 = (*energies)[0];
// Protections
size_t bin = FindBinLocation(e);
if (bin == numberOfBins)
{
// G4cout << "WARNING - G4EMDataSet::FindValue: energy outside upper boundary"
// << G4endl;
value = (*data)[bin];
}
else if (e <= e0)
{
// G4cout << "WARNING - G4EMDataSet::FindValue: energy outside lower boundary"
// << G4endl;
value = (*data)[0];
}
else
{
if (algorithm == 0)
G4Exception("G4EMDataSet::FindValue - interpolation algorithm = 0");
value = algorithm->Calculate(e,bin,*energies,*data);
}
return value;
}
G4int G4EMDataSet::FindBinLocation(G4double energy) const
{
// Protection against call outside allowed range
G4double e0 = (*energies)[0];
if (energy < e0)
{
// G4cout << z
// << " - WARNING - G4EMDataSet::FindBinLocation called with argument "
// << energy
// << " outside lower limit "
// << e0
// << "; replaced with lower limit"
// << G4endl;
energy = e0;
}
size_t lowerBound = 0;
size_t upperBound = numberOfBins - 1;
// Binary search
while (lowerBound <= upperBound)
{
size_t midBin = (lowerBound + upperBound)/2;
if ( energy < (*energies)[midBin] ) upperBound = midBin-1;
else lowerBound = midBin+1;
}
return upperBound;
}
void G4EMDataSet::LoadData(const G4String& fileName)
{
// Build the complete string identifying the file with the data set
char nameChar[100] = {""};
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
ost << fileName << z << ".dat";
G4String name(nameChar);
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = "G4EMDataSet - G4LEDATA environment variable not set";
G4Exception(excep);
}
G4String pathString(path);
G4String dirFile = pathString + "/" + name;
G4std::ifstream file(dirFile);
G4std::filebuf* lsdp = file.rdbuf();
if (! (lsdp->is_open()) )
{
G4String excep = "G4EMDataSet - data file: " + dirFile + " not found";
G4Exception(excep);
}
G4double a = 0;
G4int k = 1;
do
{
file >> a;
G4int nColumns = 2;
// The file is organized into two columns:
// 1st column is the energy
// 2nd column is the corresponding value
// The file terminates with the pattern: -1 -1
// -2 -2
if (a == -1 || a == -2)
{
}
else
{
if (k%nColumns != 0)
{
G4double e = a * unit1;
energies->push_back(e);
k++;
}
else if (k%nColumns == 0)
{
G4double value = a * unit2;
data->push_back(value);
k = 1;
}
}
} while (a != -2); // end of file
file.close();
}
void G4EMDataSet::PrintData() const
{
size_t size = numberOfBins;
for (size_t i=0; i<size; i++)
{
G4double e = (*energies)[i] / unit1;
G4double sigma = (*data)[i] / unit2 ;
G4cout << "Point: "
<< e
<< " - Data value : "
<< sigma
<< G4endl;
}
}
@@ -0,0 +1,319 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4FluoDataData.cc,v 1.2
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
//
// History:
// -----------
// 16 Sept 2001 First committed to cvs
//
// -------------------------------------------------------------------
#include "G4FluoData.hh"
#include "G4DataVector.hh"
#include "g4std/fstream"
#include "g4std/strstream"
G4FluoData::G4FluoData()
{
numberOfVacancies=0;
}
G4FluoData::~G4FluoData()
{
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::iterator pos;
for (pos = idMap.begin(); pos != idMap.end(); pos++)
{
G4DataVector* dataSet = (*pos).second;
delete dataSet;
}
for (pos = energyMap.begin(); pos != energyMap.end(); pos++)
{
G4DataVector* dataSet = (*pos).second;
delete dataSet;
}
for (pos = probabilityMap.begin(); pos != probabilityMap.end(); pos++)
{
G4DataVector* dataSet = (*pos).second;
delete dataSet;
}
}
size_t G4FluoData::NumberOfVacancies() const
{
return numberOfVacancies;
}
G4int G4FluoData::VacancyId(G4int vacancyIndex) const
{
G4int n = -1;
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies)
{G4Exception("G4FluoData::vacancyIndex outside boundaries");}
else
{
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator pos;
pos = idMap.find(vacancyIndex);
if (pos!= idMap.end())
{ G4DataVector dataSet = (*(*pos).second);
n = (G4int) dataSet[0];
}
}
return n;
}
size_t G4FluoData::NumberOfTransitions(G4int vacancyIndex) const
{
G4int n = 0;
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies)
{G4Exception("G4FluoData::vacancyIndex outside boundaries");}
else
{
n = nInitShells[vacancyIndex]-1;
//-1 is necessary because the elements of the vector nInitShells
//include also the vacancy shell:
// -1 subtracts this last one
}
return n;
}
G4int G4FluoData::StartShellId(G4int initIndex,G4int vacancyIndex)
{
G4int n = -1;
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies)
{G4Exception("G4FluoData::vacancyIndex outside boundaries");}
else
{
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator pos;
pos = idMap.find(vacancyIndex);
G4DataVector dataSet = *((*pos).second);
G4int nData = dataSet.size();
if (initIndex >= 0 && initIndex < nData)
{
n = (G4int) dataSet[initIndex];
}
}
return n;
}
G4double G4FluoData::StartShellEnergy(G4int initIndex,G4int vacancyIndex)
{
G4double n = -1;
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies)
{G4Exception("G4FluoData::vacancyIndex outside boundaries");}
else
{
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator pos;
pos = energyMap.find(vacancyIndex);
G4DataVector dataSet = *((*pos).second);
G4int nData = dataSet.size();
if (initIndex >= 0 && initIndex < nData)
{
n = dataSet[initIndex];
}
}
return n;
}
G4double G4FluoData::StartShellProb(G4int initIndex,G4int vacancyIndex)
{
G4double n = -1;
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies)
{G4Exception("G4FluoData::vacancyIndex outside boundaries");}
else
{
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator pos;
pos = probabilityMap.find(vacancyIndex);
G4DataVector dataSet = *((*pos).second);
G4int nData = dataSet.size();
if (initIndex >= 0 && initIndex < nData)
{
n = dataSet[initIndex];
}
}
return n;
}
void G4FluoData::LoadData(G4int Z)
{
// Build the complete string identifying the file with the data set
char nameChar[100] = {""};
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
if(Z != 0){
ost << "fl-tr-pr-"<< Z << ".dat";
}
else{
ost << "fl-tr-pr-"<<".dat";
}
G4String name(nameChar);
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = "G4EMDataSet - G4LEDATA environment variable not set";
G4Exception(excep);
}
G4String pathString(path);
G4String dirFile = pathString + "/fluor/" + name;
G4std::ifstream file(dirFile);
G4std::filebuf* lsdp = file.rdbuf();
if (! (lsdp->is_open()) )
{
G4String excep = "G4FluoData - data file: " + dirFile + " not found";
G4Exception(excep);
}
G4double a = 0;
G4int k = 1;
G4int s = 0;
G4int vacId = 0;
G4DataVector* initIds = new G4DataVector;
G4DataVector* transEnergies = new G4DataVector;
G4DataVector* transProbabilities = new G4DataVector;
do {
file >> a;
G4int nColumns = 3;
if (a == -1)
{
if (s == 0)
{
// End of a shell data set
idMap[vacId] = initIds;
energyMap[vacId] = transEnergies;
probabilityMap[vacId] = transProbabilities;
// G4double size=transProbabilities->size();
G4int n = initIds->size();
nInitShells.push_back(n);
numberOfVacancies++;
// Start of new shell data set
initIds = new G4DataVector;
transEnergies = new G4DataVector;
transProbabilities = new G4DataVector;
vacId++;
}
s++;
if (s == nColumns)
{
s = 0;
}
}
else if (a == -2)
{
// End of file; delete the empty vectors created
//when encountering the last -1 -1 row
delete initIds;
delete transEnergies;
delete transProbabilities;
}
else
{
if(k%nColumns == 2)
{
// 2nd column is transition probabilities
transProbabilities->push_back(a);
k++;
}
else if (k%nColumns == 1)
{
// 1st column is shell id
initIds->push_back(a);
k++;
}
else if (k%nColumns == 0)
{//third column is transition energies
G4double e = a * MeV;
transEnergies->push_back(e);
k=1;
}
}
}
while (a != -2); // end of file
file.close();
}
void G4FluoData::PrintData()
{
for (G4int i = 0; i <numberOfVacancies; i++)
{
G4cout << "---- TransitionData for the vacancy nb "
<<i
<<" ----- "
<<G4endl;
for (size_t k = 0; k<=NumberOfTransitions(i); k++)
{
G4int id = StartShellId(k,i);
G4double e = StartShellEnergy(k,i) /MeV;
G4double p = StartShellProb(k,i);
G4cout << k <<") Shell id: " << id <<G4endl;
G4cout << " - Transition energy = " << e << " MeV "<<G4endl;
G4cout << " - Transition probability = " << p <<G4endl;
}
G4cout << "-------------------------------------------------"
<< G4endl;
}
}
@@ -21,42 +21,52 @@
// ********************************************************************
//
//
// -------------------------------------------------------------------
// GEANT 4 class file
// $Id: G4LinInterpolation.cc,v 1.1 2001/11/29 19:01:36 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// CERN, Geneva, Switzerland
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// File name: G4SecondLevel.hh
// History:
// -----------
// 31 Jul 2001 MGP Created
//
// Author: Alessandra Forti (Alessandra.Forti@cern.ch)
//
// Creation date: 1 Giugno 1999
//
// Modifications: 24.04.01 V.Ivanchenko remove RogueWave
//
// -------------------------------------------------------------------
#include "G4SecondLevel.hh"
#include "G4LinInterpolation.hh"
// Constructor
G4LinInterpolation::G4LinInterpolation()
{ }
G4SecondLevel::~G4SecondLevel(){
// Destructor
// this->clearAndDestroy();
this->clear();
G4LinInterpolation::~G4LinInterpolation()
{ }
G4double G4LinInterpolation::Calculate(G4double x, G4int bin,
const G4DataVector& points,
const G4DataVector& data) const
{
G4int nBins = data.size() - 1;
G4double value = 0.;
if (x < points[0])
{
value = 0.;
}
else if (bin < nBins)
{
G4double e1 = points[bin];
G4double e2 = points[bin+1];
G4double d1 = data[bin];
G4double d2 = data[bin+1];
value = d1 + (d2 - d1)*(x - e1)/(e2 - e1);
}
else
{
value = data[nBins];
}
return value;
}
G4bool G4SecondLevel::operator == (const G4SecondLevel& input) const{
// return( this->entries() == input.entries());
return( this->size() == input.size());
}
G4bool G4SecondLevel::operator < (const G4SecondLevel& input) const{
// return(this->entries() < input.entries());
return(this->size() < input.size());
}
@@ -0,0 +1,74 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4LogLogInterpolation.cc,v 1.3 2001/09/10 18:07:35 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created
//
// -------------------------------------------------------------------
#include "G4LogLogInterpolation.hh"
// Constructor
G4LogLogInterpolation::G4LogLogInterpolation()
{ }
// Destructor
G4LogLogInterpolation::~G4LogLogInterpolation()
{ }
G4double G4LogLogInterpolation::Calculate(G4double x, G4int bin,
const G4DataVector& points,
const G4DataVector& data) const
{
G4int nBins = data.size() - 1;
G4double value = 0.;
if (x < points[0])
{
value = 0.;
}
else if (bin < nBins)
{
G4double e1 = points[bin];
G4double e2 = points[bin+1];
G4double d1 = data[bin];
G4double d2 = data[bin+1];
value = (log10(d1)*log10(e2/x) + log10(d2)*log10(x/e1)) / log10(e2/e1);
value = pow(10,value);
}
else
{
value = data[nBins];
}
return value;
}
@@ -20,22 +20,20 @@
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4LowEnergyBremsstrahlung.cc,v 1.34.2.2 2001/06/28 20:19:28 gunter Exp $
// GEANT4 tag $Name: $
//
// $Id: G4LowEnergyBremsstrahlung.cc,v 1.54 2001/11/29 19:01:36 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
// CERN Geneva Switzerland
//
// ------------ G4LowEnergyBremsstrahlung: low energy modifications --------
// by Alessandra Forti, March 1999
// File name: G4LowEnergyBremsstrahlung
//
// **************************************************************
// Author: Alessandra Forti, Vladimir Ivanchenko
//
// 18.04.2000 V.L.
// - First implementation of continuous energy loss.
// Creation date: March 1999
//
// Modifications:
// 18.04.2000 V.L.
// - First implementation of continuous energy loss.
// 17.02.2000 Veronique Lefebure
// - correct bug : the gamma energy was not deposited when the gamma was
// not produced when its energy was < cutForLowEnergySecondaryPhotons
@@ -47,198 +45,141 @@
// Added map of the elements A. Forti
// 20.09.00 update printout V.Ivanchenko
// 24.04.01 V.Ivanchenko remove RogueWave
// 29.09.2001 V.Ivanchenko: major revision based on design iteration
// 10.10.2001 MGP Revision to improve code quality and consistency with design
// 18.10.2001 MGP Revision to improve code quality
// 28.10.2001 VI Update printout
// 29.11.2001 VI New parametrisation
//
// --------------------------------------------------------------
#include "G4LowEnergyBremsstrahlung.hh"
#include "G4eBremsstrahlungSpectrum.hh"
#include "G4BremsstrahlungCrossSectionHandler.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4LogLogInterpolation.hh"
#include "G4VEMDataSet.hh"
#include "G4EnergyLossTables.hh"
#include "G4UnitsTable.hh"
#include "G4Electron.hh"
#include "G4Gamma.hh"
//
// constructor
G4LowEnergyBremsstrahlung::G4LowEnergyBremsstrahlung(const G4String& processName)
: G4eLowEnergyLoss(processName), // initialization
theCrossSectionTable(0),
theMeanFreePathTable(0),
ATable(0),
BTable(0),
ZNumVec(0),
lowEnergyCut(0.1*eV),
cutForLowEnergySecondaryPhotons(0.)
{
lowestKineticEnergy = GetLowerBoundEloss();
highestKineticEnergy = GetUpperBoundEloss();
totBin = GetNbinEloss();
#include "G4CutsPerMaterialWarning.hh"
G4LowEnergyBremsstrahlung::G4LowEnergyBremsstrahlung(const G4String& nam)
: G4eLowEnergyLoss(nam),
crossSectionHandler(0),
theMeanFreePath(0),
energySpectrum(0)
{
cutForPhotons = 0.;
verboseLevel = 0;
}
//
// destructor
G4LowEnergyBremsstrahlung::~G4LowEnergyBremsstrahlung()
{
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy();
delete theMeanFreePathTable;
}
if (theCrossSectionTable) {
delete theCrossSectionTable;
}
if(ZNumVec){
ZNumVec->clear();
delete ZNumVec;
}
if (ATable) {
delete ATable;
}
if (BTable) {
delete BTable;
}
if (&partialSumSigma) {
partialSumSigma.clearAndDestroy();
}
if(crossSectionHandler) delete crossSectionHandler;
if(energySpectrum) delete energySpectrum;
if(theMeanFreePath) delete theMeanFreePath;
}
//
// SET CUT FOR LOW ENERGY SECONDARY PHOTONS A. FORTI
void G4LowEnergyBremsstrahlung::SetCutForLowEnSecPhotons(G4double cut){
cutForLowEnergySecondaryPhotons = cut;
}
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE
void G4LowEnergyBremsstrahlung::BuildPhysicsTable(const G4ParticleDefinition& aParticleType)
{
BuildZVec();
// energy sampling formula coefficient
BuildATable();
BuildBTable();
BuildCrossSectionTable() ;
if(verboseLevel > 0) {
G4cout << "G4LowEnergyBremsstrahlung::BuildPhysicsTable start"
<< G4endl;
}
BuildLossTable(aParticleType) ;
G4CutsPerMaterialWarning warning;
warning.PrintWarning(&aParticleType);
cutForSecondaryPhotons.clear();
if (&aParticleType==G4Electron::Electron()){
// Create and fill BremsstrahlungParameters once
if( energySpectrum != 0 ) delete energySpectrum;
energySpectrum = new G4eBremsstrahlungSpectrum();
RecorderOfElectronProcess[CounterOfElectronProcess] = (*this).theLossTable ;
if(verboseLevel > 0) {
G4cout << "G4LowEnergyBremsstrahlungSpectrum is initialized"
<< G4endl;
}
// Create and fill G4CrossSectionHandler once
if( crossSectionHandler != 0 ) delete crossSectionHandler;
G4VDataSetAlgorithm* interpolation = new G4LogLogInterpolation();
G4double lowKineticEnergy = GetLowerBoundEloss();
G4double highKineticEnergy = GetUpperBoundEloss();
G4int totBin = GetNbinEloss();
crossSectionHandler = new G4BremsstrahlungCrossSectionHandler(energySpectrum, interpolation);
crossSectionHandler->Initialise(0,lowKineticEnergy, highKineticEnergy, totBin);
crossSectionHandler->LoadShellData("brem/br-cs-");
if (verboseLevel > 0) {
G4cout << GetProcessName()
<< " is created; Cross section data: "
<< G4endl;
crossSectionHandler->PrintData();
G4cout << "Parameters: "
<< G4endl;
energySpectrum->PrintData();
}
// Build loss table for Bremsstrahlung
BuildLossTable(aParticleType);
if(verboseLevel > 0) {
G4cout << "The loss table is built"
<< G4endl;
}
if (&aParticleType==G4Electron::Electron()) {
RecorderOfElectronProcess[CounterOfElectronProcess] = (*this).theLossTable;
CounterOfElectronProcess++;
PrintInfoDefinition();
}
else{
RecorderOfPositronProcess[CounterOfPositronProcess] = (*this).theLossTable ;
} else {
RecorderOfPositronProcess[CounterOfPositronProcess] = (*this).theLossTable;
CounterOfPositronProcess++;
}
BuildMeanFreePathTable() ;
BuildDEDXTable(aParticleType) ;
}
//
// CONSTRUCT THE CROSS SECTION TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC.
void G4LowEnergyBremsstrahlung::BuildCrossSectionTable(){
if (theCrossSectionTable) {
delete theCrossSectionTable;
}
theCrossSectionTable = new G4SecondLevel();
G4int dataNum = 2;
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
G4FirstLevel* oneAtomCS = util.BuildFirstLevelTables(AtomInd, dataNum, "brem/br-cs-");
// theCrossSectionTable->insert(oneAtomCS);
theCrossSectionTable->push_back(oneAtomCS);
}//end for on atoms
}
// Build mean free path data using cut values
// CONSTRUCT THE TABLE OF THE FIRST PARAMETER OF THE SAMPLING FORMULA
void G4LowEnergyBremsstrahlung::BuildATable(){
if( theMeanFreePath != 0 ) delete theMeanFreePath;
theMeanFreePath = crossSectionHandler->
BuildMeanFreePathForMaterials(&cutForSecondaryPhotons);
if (ATable) {
delete ATable;
}
G4int dataNum = 2;
ATable = util.BuildSecondLevelTables(0,dataNum,"brem/br-co-a");
}
// CONSTRUCT THE TABLE OF THE PARAMETERS OF THE FORMULA OF THE
// SECOND PARAMETER OF THE SAMPLING FORMULA
void G4LowEnergyBremsstrahlung::BuildBTable(){
if (BTable) {
delete BTable;
}
G4int dataNum = 2;
BTable = util.BuildFirstLevelTables(0, dataNum, "brem/br-co-b");
}
// Vector mapping the existing elements in the material table
// needed at initialization time to load only the necessary data
void G4LowEnergyBremsstrahlung::BuildZVec(){
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
if(ZNumVec){
ZNumVec->clear();
delete ZNumVec;
}
ZNumVec = new G4DataVector();
for (G4int J=0 ; J < numOfMaterials; J++){
const G4Material* material= (*theMaterialTable)[J];
const G4ElementVector* theElementVector = material->GetElementVector();
const G4int NumberOfElements = material->GetNumberOfElements() ;
for (G4int iel=0; iel<NumberOfElements; iel++ ){
G4double Zel = (*theElementVector)(iel)->GetZ();
if( !(ZNumVec->contains(Zel)) ) {
ZNumVec->push_back(Zel);
} else{
continue;
if(verboseLevel > 0) {
G4cout << "The MeanFreePath table is built"
<< G4endl;
}
}
}
// Build common DEDX table for all ionisation processes
BuildDEDXTable(aParticleType);
if(verboseLevel > 0) {
G4cout << "G4LowEnergyBremsstrahlung::BuildPhysicsTable end"
<< G4endl;
}
}
void G4LowEnergyBremsstrahlung::BuildLossTable(const G4ParticleDefinition& aParticleType)
{
// Build table for energy loss due to soft brems
// the tables are built for *MATERIALS*
// Build table for energy loss due to soft brems
// the tables are built for *MATERIALS* binning is taken from LowEnergyLoss
G4double lowKineticEnergy = GetLowerBoundEloss();
G4double highKineticEnergy = GetUpperBoundEloss();
size_t totBin = GetNbinEloss();
// create table
if (theLossTable) {
@@ -246,466 +187,176 @@ void G4LowEnergyBremsstrahlung::BuildLossTable(const G4ParticleDefinition& aPart
delete theLossTable;
}
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
const G4int numOfMaterials = theMaterialTable->length();
const size_t numOfMaterials = G4Material::GetNumberOfMaterials();
theLossTable = new G4PhysicsTable(numOfMaterials);
// loop for materials
// Clean up the vector of cuts
cutForSecondaryPhotons.clear();
// Loop for materials
for (G4int J=0; J<numOfMaterials; J++){
for (size_t j=0; j<numOfMaterials; j++) {
// create physics vector and fill it
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(lowestKineticEnergy,
highestKineticEnergy,
totBin);
// get material parameters needed for the energy loss calculation
const G4Material* material= (*theMaterialTable)[J];
// create physics vector and fill it
G4PhysicsLogVector* aVector = new G4PhysicsLogVector(lowKineticEnergy,
highKineticEnergy,
totBin);
const G4double Tcut = G4Gamma::Gamma()->GetCutsInEnergy()[material->GetIndex()] ;
G4cout<<"*** LE Bremsstrahlung using Gamma Tcut = "<<Tcut
<<" for material "<< material->GetName()
<<G4endl;
const G4ElementVector* theElementVector = material->GetElementVector();
const G4int NumberOfElements = material->GetNumberOfElements() ;
const G4double* theAtomicNumDensityVector = material->GetAtomicNumDensityVector();
// now comes the loop for the kinetic energy values
for (G4int i = 0 ; i < totBin ; i++){
// get material parameters needed for the energy loss calculation
const G4Material* material= (*theMaterialTable)[j];
const G4double LowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
G4double ionloss = 0.;
// loop for elements in the material
for (G4int iel=0; iel<NumberOfElements; iel++ ){
const G4double Z = (*theElementVector)(iel)->GetZ();
ionloss += GetEnergyLossWithCut(Z,LowEdgeEnergy,Tcut)*
theAtomicNumDensityVector[iel] ;
}
aVector->PutValue(i,ionloss) ;
// the cut cannot be below lowest limit
G4double tCut = G4std::min(highKineticEnergy,
((G4Gamma::Gamma())->GetEnergyThreshold(material)));
// ((G4Gamma::Gamma())->GetCutsInEnergy())[j]);
cutForSecondaryPhotons.push_back(tCut);
const G4ElementVector* theElementVector = material->GetElementVector();
size_t NumberOfElements = material->GetNumberOfElements() ;
const G4double* theAtomicNumDensityVector =
material->GetAtomicNumDensityVector();
if(verboseLevel > 1) {
G4cout << "Energy loss for material # " << j
<< " tCut(keV)= " << tCut/keV
<< G4endl;
}
theLossTable->insert(aVector);
}
}
//
// now comes the loop for the kinetic energy values
for (size_t i = 0; i<totBin; i++) {
//
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE MODIFIED TO USE
// LIVERMORE DATA (using log-log interpolation as reported in stepanek paper)
//
void G4LowEnergyBremsstrahlung::BuildMeanFreePathTable()
// Build mean free path tables for the gamma emission by e- or e+.
// tables are Build for MATERIALS. see GENERAL part of processes in GEANT4
// manual
{
G4double FixedEnergy = (lowestKineticEnergy + highestKineticEnergy)/2.;
//create table
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy();
delete theMeanFreePathTable;
}
G4double NumbOfMaterials = G4Material::GetNumberOfMaterials();
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
G4Material* material;
G4double* CutInKineticEnergy = G4Gamma::Gamma()->GetCutsInEnergy() ;
partialSumSigma.clearAndDestroy();
partialSumSigma.resize(NumbOfMaterials);
G4double LowEdgeEnergy , Value;
theMeanFreePathTable = new G4PhysicsTable(NumbOfMaterials);
G4PhysicsLogVector* ptrVector;
for ( G4int J=0 ; J < NumbOfMaterials; J++ ){
//create physics vector then fill it ....
ptrVector = new G4PhysicsLogVector(lowestKineticEnergy, highestKineticEnergy,
totBin ) ;
material= (*theMaterialTable)(J);
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
const G4double Threshold = CutInKineticEnergy[J] ;
for ( G4int i = 0 ; i < totBin ; i++ ){
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy( i ) ;
const G4double BigPath= DBL_MAX;
G4double SIGMA = 0 ;
for ( size_t k=0 ; k < material->GetNumberOfElements() ; k++ ){
G4int AtomIndex = (G4int) (*theElementVector)(k)->GetZ();
G4double interCrsSec = GetCrossSectionWithCut(AtomIndex, LowEdgeEnergy,Threshold);
SIGMA += theAtomNumDensityVector[k]*interCrsSec;
}
Value = SIGMA<=0.0 ? BigPath : 1./SIGMA ;
ptrVector->PutValue( i , Value ) ;
}
theMeanFreePathTable->insert( ptrVector );
// Compute the partialSumSigma table at a given fixed energy
ComputepartialSumSigma(FixedEnergy, material,Threshold) ;
}
G4double lowEdgeEnergy = aVector->GetLowEdgeEnergy(i);
G4double ionloss = 0.;
// loop for elements in the material
for (size_t iel=0; iel<NumberOfElements; iel++ ) {
G4int Z = (G4int)((*theElementVector)[iel]->GetZ());
G4double e = energySpectrum->AverageEnergy(Z, 0.0, tCut, lowEdgeEnergy);
G4double pro = energySpectrum->Probability(Z, 0.0, tCut, lowEdgeEnergy);
G4double cs= crossSectionHandler->FindValue(Z, lowEdgeEnergy);
ionloss += e * cs * pro * theAtomicNumDensityVector[iel];
if(verboseLevel > 1) {
G4cout << "Z= " << Z
<< "; tCut(keV)= " << tCut/keV
<< "; E(keV)= " << lowEdgeEnergy/keV
<< "; Eav(keV)= " << e/keV
<< "; pro= " << pro
<< "; cs= " << cs
<< "; loss= " << ionloss
<< G4endl;
}
}
aVector->PutValue(i,ionloss);
}
theLossTable->insert(aVector);
}
}
//
//
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE MODIFIED TO USE
// LIVERMORE DATA (using log-log interpolation as reported in stepanek paper)
//
void G4LowEnergyBremsstrahlung::ComputepartialSumSigma(const G4double KineticEnergy,
const G4Material* aMaterial,
const G4double Threshold)
// Build the table of cross section per element. The table is built for MATERIALS.
// This table is used by DoIt to select randomly an element in the material.
G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& track,
const G4Step& step)
{
G4int Imate = aMaterial->GetIndex();
G4int NbOfElements = aMaterial->GetNumberOfElements();
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
const G4double* theAtomNumDensityVector = aMaterial->GetAtomicNumDensityVector();
aParticleChange.Initialize(track);
partialSumSigma[Imate] = new G4DataVector();
const G4Material* material = track.GetMaterial();
G4double kineticEnergy = track.GetKineticEnergy();
G4int index = material->GetIndex();
G4double tCut = cutForSecondaryPhotons[index];
G4double SIGMA = 0. ;
// Control limits
if(tCut >= kineticEnergy)
return G4VContinuousDiscreteProcess::PostStepDoIt(track, step);
for ( G4int Ielem=0 ; Ielem < NbOfElements ; Ielem++ ){
G4int Z = crossSectionHandler->SelectRandomAtom(material, kineticEnergy);
G4int AtomIndex = (G4int) (*theElementVector)(Ielem)->GetZ();
G4double interCrsSec = GetCrossSectionWithCut(AtomIndex,KineticEnergy,Threshold);
SIGMA += theAtomNumDensityVector[Ielem]*interCrsSec;
partialSumSigma[Imate]->push_back(SIGMA);
}
}
G4double tGamma = energySpectrum->SampleEnergy(Z, tCut, kineticEnergy, kineticEnergy);
//
// Sample gamma angle (Z - axis along the parent particle).
// Universal distribution suggested by L. Urban (Geant3 manual (1993)
// Phys211) derived from Tsai distribution (Rev Mod Phys 49,421(1977))
G4VParticleChange* G4LowEnergyBremsstrahlung::PostStepDoIt(const G4Track& trackData,
const G4Step& stepData){
G4double totalEnergy = kineticEnergy + electron_mass_c2;
// This parametrization is derived from :
// Migdal corrections (dielectric suppression).
// Migdal: Phys Rev 103:1811 (1956); Messel & Crawford: Pergamon Press (1970)
//
aParticleChange.Initialize(trackData);
G4Material* aMaterial=trackData.GetMaterial() ;
const G4DynamicParticle* aDynamicParticle=trackData.GetDynamicParticle();
G4double charge = aDynamicParticle->GetDefinition()->GetPDGCharge();
G4double ElectKinEn = aDynamicParticle->GetKineticEnergy();
const G4double a1 = 0.625, a2 = 3.*a1, d = 27.;
G4double u = - log(G4UniformRand()*G4UniformRand());
// MGP debug
// G4cout << "G4LowEnergyBremsstrahlung::PostStepDoIt - ElectKinEn "
// << ElectKinEn/keV << " keV " << G4endl;
// MGP end
if(ElectKinEn <= lowestKineticEnergy){
if (9./(9.+d) > G4UniformRand()) u /= a1;
else u /= a2;
aParticleChange.SetStatusChange(fStopAndKill);
aParticleChange.SetEnergyChange(0.);
aParticleChange.SetLocalEnergyDeposit(ElectKinEn);
G4double theta = u*electron_mass_c2/totalEnergy;
G4double phi = twopi * G4UniformRand();
G4double dirZ = cos(theta);
G4double sinTheta = sqrt(1. - dirZ*dirZ);
G4double dirX = sinTheta*cos(phi);
G4double dirY = sinTheta*sin(phi);
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
}
G4ParticleMomentum ElectDirection = aDynamicParticle->GetMomentumDirection();
// Gamma production cut in this material
G4double GammaEnergyCut = (G4Gamma::GetCutsInEnergy())[aMaterial->GetIndex()];
// check against insufficient energy
if (ElectKinEn < GammaEnergyCut){
aParticleChange.SetEnergyChange(ElectKinEn);
aParticleChange.SetLocalEnergyDeposit(0.);
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
}
// select randomly one element constituing the material
G4Element* anElement = SelectRandomAtom(aMaterial);
// limits of the energy sampling
G4double TotalEnergy = ElectKinEn + electron_mass_c2;
// G4double TotalEnergysquare = TotalEnergy*TotalEnergy ;
G4ThreeVector gammaDirection (dirX, dirY, dirZ);
G4ThreeVector electronDirection = track.GetMomentumDirection();
gammaDirection.rotateUz(electronDirection);
//
// The emitted gamma energy is from EEDL data fitted with A/E+B function.
// Original formula A/E+B+C*E and sampling methods are reported by J. Stepanek
// formula has been modified by A. Forti and S. Giani.
//
// sample the energy of the emitted gamma
//
G4double p1 = 0, p2 = 0;
G4double coeffA = 0, coeffB = 0;
G4int AtomicNum = (G4int) anElement->GetZ();
coeffA = ComputeA(AtomicNum, ElectKinEn);
coeffB = ComputeB(AtomicNum, ElectKinEn);
//const G4double minEn = lowEnergyCut;
const G4double minEn = GammaEnergyCut;
p1 = coeffA*log(ElectKinEn/minEn);
p2 = coeffB*(ElectKinEn - minEn);
G4double IntegrProb = p1+p2;
G4double R1 = G4UniformRand()*IntegrProb;
G4double GammaEnergy = 0.;
if(R1 <= p1){
// Update the incident particle
//
G4double R2 = G4UniformRand();
GammaEnergy = ElectKinEn*pow((minEn/ElectKinEn),R2);
/// stepanek does: GammaEnergy = exp(R2*log(ElectKinEn/minEn)+log(ElectKinEn));
}
else if ((p1 < R1) && (R1 <= p1+p2)){
G4double finalEnergy = kineticEnergy - tGamma;
G4double R2 = G4UniformRand();
GammaEnergy = ElectKinEn - R2*(ElectKinEn - minEn);
// Kinematic problem
if (finalEnergy < 0.) {
tGamma += finalEnergy;
finalEnergy = 0.0;
}
// MGP debug
// if (GammaEnergy > 10*keV)
// G4cout << "MGP BremPostStepDoIt eGamma = " << GammaEnergy/keV << " keV" << G4endl;
G4double momentum = sqrt((totalEnergy + electron_mass_c2)*kineticEnergy);
/*
G4double R1 = minEn + G4UniformRand()*(ElectKinEn- minEn);
G4double Max = coeffA/minEn + coeffB;
G4double R2 = G4UniformRand()*Max;
while (coeffA/R1 + coeffB < R2){
R1 = minEn + G4UniformRand()*(ElectKinEn- minEn);
R2 = G4UniformRand()*Max;
}
G4double GammaEnergy = R1;
*/
//**********************//
// Angular distribution //
//**********************//
// angles of the emitted gamma. ( Z - axis along the parent particle)
// universal distribution suggested by L. Urban (Geant3 manual (1993) Phys211),
// derived from Tsai distribution (Rev Mod Phys 49,421(1977))
if(GammaEnergy < minEn){
G4cerr<<"Problem with bremsstrahlung gamma energy sampling: Energy<cut:"
<<GammaEnergy<<" < "<<minEn
<<G4endl;
}
G4double u;
const G4double a1 = 0.625 , a2 = 3.*a1 , d = 27. ;
if (9./(9.+d) > G4UniformRand()) u = - log(G4UniformRand()*G4UniformRand())/a1 ;
else u = - log(G4UniformRand()*G4UniformRand())/a2 ;
G4double Teta = u*electron_mass_c2/TotalEnergy ;
G4double Phi = twopi * G4UniformRand() ;
G4double dirx = sin(Teta)*cos(Phi) , diry = sin(Teta)*sin(Phi) , dirz = cos(Teta) ;
G4ThreeVector GammaDirection ( dirx, diry, dirz);
GammaDirection.rotateUz(ElectDirection);
//
// Update the incident particle
//
G4double NewKinEnergy = ElectKinEn - GammaEnergy;
//
///final state electron:
//
if (NewKinEnergy > 0.){
G4double finalX = momentum*electronDirection.x() - tGamma*gammaDirection.x();
G4double finalY = momentum*electronDirection.y() - tGamma*gammaDirection.y();
G4double finalZ = momentum*electronDirection.z() - tGamma*gammaDirection.z();
aParticleChange.SetMomentumChange( ElectDirection );
aParticleChange.SetEnergyChange( NewKinEnergy );
aParticleChange.SetNumberOfSecondaries(1);
G4double norm = 1./sqrt(finalX*finalX + finalY*finalY + finalZ*finalZ);
aParticleChange.SetMomentumChange(finalX*norm, finalY*norm, finalZ*norm);
aParticleChange.SetEnergyChange( finalEnergy );
}
else{
aParticleChange.SetEnergyChange( 0. );
if (charge<0.){
aParticleChange.SetStatusChange(fStopAndKill);
}
else{
aParticleChange.SetStatusChange(fStopButAlive);
}
}
//
///emitted photon:
//
if(GammaEnergy < GammaEnergyCut){
// create G4DynamicParticle object for the gamma
G4DynamicParticle* aGamma= new G4DynamicParticle (G4Gamma::Gamma(),
gammaDirection, tGamma);
aParticleChange.AddSecondary(aGamma);
aParticleChange.SetLocalEnergyDeposit(GammaEnergy);
}
else{
// create G4DynamicParticle object for the Gamma
G4DynamicParticle* aGamma= new G4DynamicParticle (G4Gamma::Gamma(),
GammaDirection, GammaEnergy);
aParticleChange.SetNumberOfSecondaries(1);
aParticleChange.AddSecondary(aGamma);
aParticleChange.SetLocalEnergyDeposit(0.);
}
#ifdef G4VERBOSE
if(verboseLevel > 15){
G4cout<<"LE Bremsstrahlung PostStepDoIt"<<G4endl;
}
#endif
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
return G4VContinuousDiscreteProcess::PostStepDoIt(track, step);
}
G4double G4LowEnergyBremsstrahlung::GetEnergyLossWithCut(const G4double AtomicNumber,
const G4double KineticEnergy,
const G4double Tcut){
const G4double minEn = lowEnergyCut ;
if(minEn == 0.) G4cerr<<"Minimum Gamma energy should be finite"<<G4endl;
// shortcut ..........................
if(Tcut <= minEn) return 0. ;
G4double CrossSection = GetCrossSection(AtomicNumber,KineticEnergy) ;
// shortcut ..........................
if(CrossSection <= 0.) return 0. ;
G4double loss = 0.;
//
// energy spectrum of the emitted gamma
//
G4double MeanTinc;
MeanTinc = KineticEnergy;
const G4double MeanCS = GetCrossSection(AtomicNumber,MeanTinc);
const G4double coeffA = ComputeA(AtomicNumber, MeanTinc);
const G4double coeffB = ComputeB(AtomicNumber, MeanTinc);
//
//integration of T*dSigma/dT between Tmin = minEn and Tcut
//
G4double Tmax;
//
//integration of T*dSigma/dT between Tmin = minEn and Tcut
//
Tmax = Tcut;
if(Tmax>MeanTinc) Tmax = MeanTinc;
G4double SmallLoss = 0.;
SmallLoss = 0.5*coeffB*(Tmax*Tmax - minEn*minEn) + coeffA*(Tmax-minEn);
if(SmallLoss < 0.) G4cerr<<"Problem with integration of gamma spectrum: SmallLoss = "<<SmallLoss<<G4endl;
//
//integration of dSigma/dT between Tmin = minEn and KineticEnergy
//
Tmax = MeanTinc;
G4double norm = coeffB*(Tmax-minEn) + coeffA*log(Tmax/minEn);
if(norm <= 0.) G4cerr<<"Problem with integration of gamma spectrum: norm = "<<norm<<G4endl;
SmallLoss *= MeanCS/norm ;
loss+=SmallLoss;
return loss ;
}
//
G4double G4LowEnergyBremsstrahlung::GetCrossSection(const G4double AtomicNumber,
const G4double KineticEnergy){
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(AtomicNumber)];
return util.DataLogInterpolation(KineticEnergy,
(*(*oneAtomCS)[0]),
(*(*oneAtomCS)[1]) )*barn;
}
G4double G4LowEnergyBremsstrahlung::GetCrossSectionWithCut(const G4double AtomicNumber,
const G4double KineticEnergy,
const G4double Tcut){
if(KineticEnergy<=Tcut) return 0.;
G4double Tmin = Tcut;
if(Tcut<lowEnergyCut) Tmin = lowEnergyCut;
G4double Tmax = KineticEnergy;
G4double CrossSection = GetCrossSection(AtomicNumber,KineticEnergy) ;
if(CrossSection <= 0.) return 0.;
const G4double coeffA = ComputeA(AtomicNumber, KineticEnergy);
const G4double coeffB = ComputeB(AtomicNumber, KineticEnergy);
G4double fraction = coeffB*(Tmax-Tmin) + coeffA*log(Tmax/Tmin);
if(fraction <= 0.) G4cerr<<"Problem with integration of gamma spectrum: fraction = "<<fraction<<G4endl;
G4double norm = coeffB*(Tmax-lowEnergyCut) + coeffA*log(Tmax/lowEnergyCut);
if(norm <= 0.) G4cerr<<"Problem with integration of gamma spectrum: norm = "<<norm<<G4endl;
fraction /= norm;
return CrossSection*fraction;
}
//
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE MODIFIED TO USE
// LIVERMORE DATA (using log-log interpolation as reported in stepanek paper)
G4Element* G4LowEnergyBremsstrahlung::SelectRandomAtom(G4Material* aMaterial) const
{
const G4int Index = aMaterial->GetIndex();
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
G4double rval = G4UniformRand()*((*partialSumSigma[Index])[NumberOfElements-1]);
for ( G4int i=0; i < NumberOfElements; i++ )
if (rval <= (*partialSumSigma[Index])[i]) return ((*theElementVector)(i));
return (*theElementVector)(0);
}
//
void G4LowEnergyBremsstrahlung::PrintInfoDefinition()
{
G4String comments = "Total cross sections from EEDL database,";
comments += "Gamma energy sampled from a parametrised formula.";
comments += "Implementation of the continuous dE/dx part.";
comments += "\n At present it can be used for electrons ";
comments += " in the energy range [250eV,100GeV]";
comments +=
"\n the process must work with G4LowEnergyIonisation";
G4cout << G4endl << GetProcessName() << ": " << comments<<G4endl;
G4String comments = "Total cross sections from EEDL database.";
comments += "\n Gamma energy sampled from a parameterised formula.";
comments += "\n Implementation of the continuous dE/dx part.";
comments += "\n At present it can be used for electrons ";
comments += "in the energy range [250eV,100GeV].";
comments += "\n The process must work with G4LowEnergyIonisation.";
G4cout << G4endl << GetProcessName() << ": " << comments << G4endl;
}
//
G4bool G4LowEnergyBremsstrahlung::IsApplicable(const G4ParticleDefinition& particle)
{
return ( (&particle == G4Electron::Electron()) );
}
G4double G4LowEnergyBremsstrahlung::GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition* cond)
{
*cond = NotForced;
G4int index = (track.GetMaterial())->GetIndex();
const G4VEMDataSet* data = theMeanFreePath->GetComponent(index);
G4double meanFreePath = data->FindValue(track.GetKineticEnergy());
return meanFreePath;
}
void G4LowEnergyBremsstrahlung::SetCutForLowEnSecPhotons(G4double cut)
{
cutForPhotons = cut;
}
@@ -20,416 +20,242 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4LowEnergyCompton.cc,v 1.33 2001/11/07 20:47:29 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// $Id: G4LowEnergyCompton.cc,v 1.25.2.2 2001/06/28 20:19:29 gunter Exp $
// GEANT4 tag $Name: $
// Author: A. Forti
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
// CERN Geneva Switzerland
//
// ------------ G4LowEnergyCompton low energy modifications --------
// by Alessandra Forti, October 1998
// **************************************************************
// History:
// --------
// Added Livermore data table construction methods A. Forti
// Modified BuildMeanFreePath to read new data tables A. Forti
// Modified PostStepDoIt to insert sampling with EPDL97 data A. Forti
// Added SelectRandomAtom A. Forti
// Added map of the elements A. Forti
// 24.04.01 V.Ivanchenko remove RogueWave
// --------------------------------------------------------------
// 24.04.2001 V.Ivanchenko - Remove RogueWave
// 06.08.2001 MGP - Revised according to a design iteration
//
// -------------------------------------------------------------------
// This Class Header
#include "G4LowEnergyCompton.hh"
// Collaborating Class Headers
#include "G4EnergyLossTables.hh"
#include "Randomize.hh"
#include "G4ParticleDefinition.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ForceCondition.hh"
#include "G4Gamma.hh"
#include "G4Electron.hh"
#include "G4DynamicParticle.hh"
#include "G4VParticleChange.hh"
#include "G4ThreeVector.hh"
#include "G4EnergyLossTables.hh"
#include "G4VCrossSectionHandler.hh"
#include "G4CrossSectionHandler.hh"
#include "G4VEMDataSet.hh"
#include "G4CompositeEMDataSet.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4LogLogInterpolation.hh"
#include "G4VRangeTest.hh"
#include "G4RangeTest.hh"
#include "G4CutsPerMaterialWarning.hh"
// constructor
G4LowEnergyCompton::G4LowEnergyCompton(const G4String& processName)
: G4VDiscreteProcess(processName),
theCrossSectionTable(0),
theScatteringFunctionTable(0),
theMeanFreePathTable(0),
ZNumVec(0),
lowestEnergyLimit (250*eV), // initialization
highestEnergyLimit(100*GeV),
numbBinTable(200)
lowEnergyLimit(250*eV),
highEnergyLimit(100*GeV),
intrinsicLowEnergyLimit(10*eV),
intrinsicHighEnergyLimit(100*GeV)
{
if (verboseLevel>0) {
G4cout << GetProcessName() << " is created "<< G4endl;
G4cout << "lowestEnergy: " << lowestEnergyLimit/keV << "keV ";
G4cout << "highestEnergy: " << highestEnergyLimit/TeV << "TeV " << G4endl;
}
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
highEnergyLimit > intrinsicHighEnergyLimit)
{
G4Exception("G4LowEnergyCompton::G4LowEnergyCompton - energy outside intrinsic process validity range");
}
crossSectionHandler = new G4CrossSectionHandler;
G4VDataSetAlgorithm* scatterInterpolation = new G4LogLogInterpolation;
G4String scatterFile = "comp/ce-sf-";
scatterFunctionData = new G4CompositeEMDataSet(scatterFile,scatterInterpolation,1.,1.);
meanFreePathTable = 0;
rangeTest = new G4RangeTest;
if (verboseLevel > 0)
{
G4cout << GetProcessName() << " is created " << G4endl
<< "Energy range: "
<< lowEnergyLimit / keV << " keV - "
<< highEnergyLimit / GeV << " GeV"
<< G4endl;
}
}
// destructor
G4LowEnergyCompton::~G4LowEnergyCompton()
{
if (theCrossSectionTable) {
delete theCrossSectionTable;
}
if (theScatteringFunctionTable) {
delete theScatteringFunctionTable;
}
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy();
delete theMeanFreePathTable;
}
if(ZNumVec){
ZNumVec->clear();
delete ZNumVec;
}
delete meanFreePathTable;
delete crossSectionHandler;
delete scatterFunctionData;
delete rangeTest;
}
// methods.............................................................................
void G4LowEnergyCompton::BuildPhysicsTable(const G4ParticleDefinition& GammaType){
BuildZVec();
// Build microscopic cross section table and mean free path table
BuildCrossSectionTable();
// Build mean free path table for the Compton Scattering process
BuildMeanFreePathTable();
// build the scattering function table
BuildScatteringFunctionTable();
}
// BUILD THE CS TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC
void G4LowEnergyCompton::BuildCrossSectionTable(){
if (theCrossSectionTable) {
delete theCrossSectionTable;
}
void G4LowEnergyCompton::BuildPhysicsTable(const G4ParticleDefinition& photon)
{
theCrossSectionTable = new G4SecondLevel();
G4int dataNum = 2;
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
G4FirstLevel* oneAtomCS = util.BuildFirstLevelTables(AtomInd, dataNum, "comp/ce-cs-");
// theCrossSectionTable->insert(oneAtomCS);
theCrossSectionTable->push_back(oneAtomCS);
}//end for on atoms
}
// BUILD THE SF TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC
void G4LowEnergyCompton::BuildScatteringFunctionTable(){
G4CutsPerMaterialWarning warning;
warning.PrintWarning(&photon);
if (theScatteringFunctionTable) {
delete theScatteringFunctionTable;
}
crossSectionHandler->Clear();
G4String crossSectionFile = "comp/ce-cs-";
crossSectionHandler->LoadData(crossSectionFile);
theScatteringFunctionTable = new G4SecondLevel();
G4int dataNum = 2;
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
G4FirstLevel* oneAtomSF = util.BuildFirstLevelTables(AtomInd, dataNum, "comp/ce-sf-");
// theScatteringFunctionTable->insert(oneAtomSF);
theScatteringFunctionTable->push_back(oneAtomSF);
}//end for on atoms
}
// vector mapping the elements in the material table
void G4LowEnergyCompton::BuildZVec(){
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
if(ZNumVec){
ZNumVec->clear();
delete ZNumVec;
}
ZNumVec = new G4DataVector();
for (G4int J=0 ; J < numOfMaterials; J++){
const G4Material* material= (*theMaterialTable)[J];
const G4ElementVector* theElementVector = material->GetElementVector();
const G4int NumberOfElements = material->GetNumberOfElements() ;
for (G4int iel=0; iel<NumberOfElements; iel++ ){
G4double Zel = (*theElementVector)(iel)->GetZ();
if(ZNumVec->contains(Zel) == FALSE){
ZNumVec->push_back(Zel);
} else{
continue;
}
}
}
delete meanFreePathTable;
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
}
G4VParticleChange* G4LowEnergyCompton::PostStepDoIt(const G4Track& aTrack,
const G4Step& aStep)
{
// The scattered gamma energy is sampled according to Klein - Nishina formula.
// then accepted or rejected depending on the Scattering Function multiplied
// by factor from Klein - Nishina formula.
// Expression of the angular distribution as Klein Nishina
// angular and energy distribution and Scattering fuctions is taken from
// D. E. Cullen "A simple model of photon transport" Nucl. Instr. Meth.
// Phys. Res. B 101 (1995). Method of sampling with form factors is different
// data are interpolated while in the article they are fitted.
// Reference to the article is from J. Stepanek New Photon, Positron
// and Electron Interaction Data for GEANT in Energy Range from 1 eV to 10
// TeV (draft).
// The random number techniques of Butcher & Messel are used
// (Nucl Phys 20(1960),15).
G4VParticleChange* G4LowEnergyCompton::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep){
//
// The scattered gamma energy is sampled according to Klein - Nishina formula.
// And then Accepted or rejected basing of the Scattering Function multiplied by factor
// from Klein - Nishina formula. Expression of the angular distribution as Klein Nishina
// angular and energy distribution and Scattering fuctions is taken from
// D. E. Cullen "A simple model of photon transport" Nucl. Instr. Meth.
// Phys. Res. B 101 (1995). Method of sampling with form factors is different
// data are interpolated while in the article they are fitted.
// Reference to the article is from J. Stepanek New Photon, Positron
// and Electron Interaction Data for GEANT in Energy Range from 1 eV to 10
// TeV (draft).
// The random number techniques of Butcher & Messel are used
// (Nuc Phys 20(1960),15).
// GEANT4 internal units
//
aParticleChange.Initialize(aTrack);
// Dynamic particle quantities
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
G4double GammaEnergy0 = aDynamicGamma->GetKineticEnergy();
if(GammaEnergy0 <= lowestEnergyLimit){
aParticleChange.SetStatusChange(fStopAndKill);
aParticleChange.SetEnergyChange(0.);
aParticleChange.SetLocalEnergyDeposit(GammaEnergy0);
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
G4double photonEnergy0 = incidentPhoton->GetKineticEnergy();
}
G4double E0_m = GammaEnergy0 / electron_mass_c2 ;
G4ParticleMomentum GammaDirection0 = aDynamicGamma->GetMomentumDirection();
// Select randomly one element
G4Material* aMaterial = aTrack.GetMaterial();
// const G4int numOfElem = aMaterial->GetNumberOfElements();
G4Element* theElement = SelectRandomAtom(aDynamicGamma, aMaterial);
G4int elementZ = (G4int) theElement->GetZ();
G4double epsilon, epsilonsq, onecost, sint2, greject ;
G4double epsilon0 = 1./(1. + 2*E0_m) , epsilon0sq = epsilon0*epsilon0;
G4double alpha1 = - log(epsilon0) , alpha2 = 0.5*(1.- epsilon0sq);
G4double ScatteringFunction, x;
G4double wlGamma = h_Planck*c_light/GammaEnergy0;
// sample the energy rate of the scattered gamma
do{
if ( alpha1/(alpha1+alpha2) > G4UniformRand()){
epsilon = exp(-alpha1*G4UniformRand()); // pow(epsilon0,G4UniformRand())
epsilonsq = epsilon*epsilon;
}
else{
epsilonsq = epsilon0sq + (1.- epsilon0sq)*G4UniformRand();
epsilon = sqrt(epsilonsq);
}
onecost = (1.- epsilon)/(epsilon*E0_m);
sint2 = onecost*(2.-onecost);
x = sqrt(onecost/2)/(wlGamma/cm);
const G4FirstLevel* oneAtomSF
= (*theScatteringFunctionTable)[ZNumVec->index(elementZ)];
ScatteringFunction = util.DataLogInterpolation(x, (*(*oneAtomSF)[0]),
(*(*oneAtomSF)[1]));
greject = (1. - epsilon*sint2/(1.+ epsilonsq))*ScatteringFunction;
} while(greject < G4UniformRand()*elementZ);
G4double cosTeta = 1. - onecost , sinTeta = sqrt (sint2);
G4double Phi = twopi * G4UniformRand() ;
G4double dirx = sinTeta*cos(Phi) , diry = sinTeta*sin(Phi) , dirz = cosTeta ;
//
// update G4VParticleChange for the scattered gamma
//
G4ThreeVector GammaDirection1 ( dirx,diry,dirz );
GammaDirection1.rotateUz(GammaDirection0);
aParticleChange.SetMomentumChange( GammaDirection1 ) ;
G4double GammaEnergy1 = epsilon*GammaEnergy0;
if (GammaEnergy1 > 0.)
if (photonEnergy0 <= lowEnergyLimit)
{
aParticleChange.SetEnergyChange( GammaEnergy1 ) ;
aParticleChange.SetStatusChange(fStopAndKill);
aParticleChange.SetEnergyChange(0.);
aParticleChange.SetLocalEnergyDeposit(photonEnergy0);
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
}
G4double e0m = photonEnergy0 / electron_mass_c2 ;
G4ParticleMomentum photonDirection0 = incidentPhoton->GetMomentumDirection();
// Select randomly one element in the current material
G4Material* material = aTrack.GetMaterial();
G4int Z = crossSectionHandler->SelectRandomAtom(material,photonEnergy0);
G4double epsilon0 = 1. / (1. + 2. * e0m);
G4double epsilon0Sq = epsilon0 * epsilon0;
G4double alpha1 = -log(epsilon0);
G4double alpha2 = 0.5 * (1. - epsilon0Sq);
G4double wlPhoton = h_Planck*c_light/photonEnergy0;
// Sample the energy of the scattered photon
G4double epsilon;
G4double epsilonSq;
G4double oneCosT;
G4double sinT2;
G4double gReject;
do
{
if ( alpha1/(alpha1+alpha2) > G4UniformRand())
{
epsilon = exp(-alpha1 * G4UniformRand()); // pow(epsilon0,G4UniformRand())
epsilonSq = epsilon * epsilon;
}
else
{
epsilonSq = epsilon0Sq + (1. - epsilon0Sq) * G4UniformRand();
epsilon = sqrt(epsilonSq);
}
oneCosT = (1. - epsilon) / ( epsilon * e0m);
sinT2 = oneCosT * (2. - oneCosT);
G4double x = sqrt(oneCosT/2.) / (wlPhoton/cm);
G4double scatteringFunction = scatterFunctionData->FindValue(x,Z-1);
gReject = (1. - epsilon * sinT2 / (1. + epsilonSq)) * scatteringFunction;
} while(gReject < G4UniformRand()*Z);
G4double cosTheta = 1. - oneCosT;
G4double sinTheta = sqrt (sinT2);
G4double phi = twopi * G4UniformRand() ;
G4double dirx = sinTheta * cos(phi);
G4double diry = sinTheta * sin(phi);
G4double dirz = cosTheta ;
// Update G4VParticleChange for the scattered photon
G4ThreeVector photonDirection1(dirx,diry,dirz);
photonDirection1.rotateUz(photonDirection0);
aParticleChange.SetMomentumChange(photonDirection1) ;
G4double photonEnergy1 = epsilon * photonEnergy0;
if (photonEnergy1 > 0.)
{
aParticleChange.SetEnergyChange(photonEnergy1) ;
}
else
{
aParticleChange.SetEnergyChange(0.) ;
aParticleChange.SetStatusChange(fStopAndKill);
}
//
// kinematic of the scattered electron
//
G4double ElecKineEnergy = GammaEnergy0 - GammaEnergy1 ;
if (G4EnergyLossTables::GetRange(G4Electron::Electron(), ElecKineEnergy, aMaterial)
>= G4std::min(G4Electron::GetCuts(), aStep.GetPostStepPoint()->GetSafety())){
// Kinematics of the scattered electron
G4double eKineticEnergy = photonEnergy0 - photonEnergy1;
G4double ElecMomentum = sqrt(ElecKineEnergy*(ElecKineEnergy+2.*electron_mass_c2));
G4ThreeVector ElecDirection((GammaEnergy0*GammaDirection0 -
GammaEnergy1*GammaDirection1)*(1./ElecMomentum));
// create G4DynamicParticle object for the electron.
G4DynamicParticle* aElectron= new G4DynamicParticle (G4Electron::Electron(),
ElecDirection, ElecKineEnergy) ;
aParticleChange.SetNumberOfSecondaries(1);
aParticleChange.AddSecondary( aElectron );
aParticleChange.SetLocalEnergyDeposit (0.);
}
else{
aParticleChange.SetNumberOfSecondaries(0);
aParticleChange.SetLocalEnergyDeposit (ElecKineEnergy);
}
#ifdef G4VERBOSE
if(verboseLevel > 0){
G4cout<<"LE Compton Effect PostStepDoIt"<<G4endl;
}
#endif
// Generate the electron only if with large enough range w.r.t. cuts and safety
G4double safety = aStep.GetPostStepPoint()->GetSafety();
if (rangeTest->Escape(G4Electron::Electron(),material,eKineticEnergy,safety))
{
G4double eMomentum = sqrt(eKineticEnergy*(eKineticEnergy+2.*electron_mass_c2));
G4ThreeVector eDirection((photonEnergy0 * photonDirection0 -
photonEnergy1 * photonDirection1) * (1./eMomentum));
G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),
eDirection,eKineticEnergy) ;
aParticleChange.SetNumberOfSecondaries(1);
aParticleChange.AddSecondary(electron);
aParticleChange.SetLocalEnergyDeposit(0.);
}
else
{
aParticleChange.SetNumberOfSecondaries(0);
aParticleChange.SetLocalEnergyDeposit(eKineticEnergy);
}
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep);
}
// used log-log interpolation instead of linear interpolation to build the MFP
// as reported in the stepanek paper
void G4LowEnergyCompton::BuildMeanFreePathTable(){
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy(); delete theMeanFreePathTable; }
// material
G4double NumbOfMaterials = G4Material::GetNumberOfMaterials();
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
G4Material* material;
// MeanFreePath
G4double LowEdgeEnergy, Value;
theMeanFreePathTable = new G4PhysicsTable(NumbOfMaterials);
G4PhysicsLogVector* ptrVector;
for ( G4int J = 0 ; J < NumbOfMaterials; J++ ) { // For each material
//create physics vector then fill it ....
ptrVector = new G4PhysicsLogVector(lowestEnergyLimit, highestEnergyLimit, numbBinTable);
material = (*theMaterialTable)(J);
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
for ( G4int i = 0 ; i < numbBinTable ; i++ ){
//For each energy
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy(i);
const G4double BigPath= DBL_MAX;
G4double SIGMA = 0 ;
for ( size_t k=0 ; k < material->GetNumberOfElements() ; k++ ){
G4int AtomIndex = (G4int) (*theElementVector)(k)->GetZ();
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
G4double interCrsSec = util.DataLogInterpolation(LowEdgeEnergy,
(*(*oneAtomCS)[0]),
(*(*oneAtomCS)[1]))*barn;
SIGMA += theAtomNumDensityVector[k]*interCrsSec;
}
Value = SIGMA<=0.0 ? BigPath : 1./SIGMA ;
ptrVector->PutValue( i , Value ) ;
}
theMeanFreePathTable->insertAt( J , ptrVector );
}
G4bool G4LowEnergyCompton::IsApplicable(const G4ParticleDefinition& particle)
{
return ( &particle == G4Gamma::Gamma() );
}
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE MODIFIED TO USE
// LIVERMORE DATA (using log-log interpolation as reported in stepanek paper)
G4Element* G4LowEnergyCompton::SelectRandomAtom(const G4DynamicParticle* aDynamicGamma,
G4Material* aMaterial){
// select randomly 1 element within the material
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
G4double G4LowEnergyCompton::GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition*)
{
const G4DynamicParticle* photon = track.GetDynamicParticle();
G4double energy = photon->GetKineticEnergy();
G4Material* material = track.GetMaterial();
size_t materialIndex = material->GetIndex();
if (NumberOfElements == 1) return (*theElementVector)(0);
const G4double* theAtomNumDensityVector = aMaterial->GetAtomicNumDensityVector();
G4double PartialSumSigma = 0.;
G4double rval = 0;
rval = G4UniformRand()/meanFreePath;
for ( G4int i=0 ; i < NumberOfElements ; i++ ){
G4double crossSection;
if (GammaEnergy < lowestEnergyLimit)
crossSection = 0. ;
else {
if (GammaEnergy > highestEnergyLimit) GammaEnergy = 0.99*highestEnergyLimit ;
G4int AtomIndex = (G4int) (*theElementVector)(i)->GetZ();
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
crossSection = util.DataLogInterpolation(GammaEnergy,
(*(*oneAtomCS)[0]),
(*(*oneAtomCS)[1]))*barn;
}
PartialSumSigma += theAtomNumDensityVector[i] * crossSection;
if(rval <= PartialSumSigma) return ((*theElementVector)(i));
}
return (*theElementVector)(0);
G4double meanFreePath;
if (energy > highEnergyLimit) meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
else meanFreePath = meanFreePathTable->FindValue(energy,materialIndex);
return meanFreePath;
}
@@ -20,149 +20,114 @@
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4LowEnergyGammaConversion.cc,v 1.19.2.2 2001/06/28 20:19:29 gunter Exp $
// GEANT4 tag $Name: $
// --------------------------------------------------------------------
///
// $Id: G4LowEnergyGammaConversion.cc,v 1.26 2001/11/07 21:31:16 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
// CERN Geneva Switzerland
//
// ------------ G4LowEnergyGammaConversion physics process --------
// by A.Forti 1999/03/02
// Author: A. Forti
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// --------
// 02/03/1999 A. Forti 1st implementation
// 14.03.2000 Veronique Lefebure;
// Change initialisation of lowestEnergyLimit from 1.22 to 1.022.
// Note that the hard coded value 1.022 should be used instead of
// 2*electron_mass_c2 in order to agree with the value of the data bank EPDL97
// 24.04.01 V.Ivanchenko remove RogueWave
// **************************************************************
// 27.07.01 F.Longo correct bug in energy distribution
//
// --------------------------------------------------------------
// This Class Header
#include "G4LowEnergyGammaConversion.hh"
// Collaborating Class Headers
#include "globals.hh"
#include "Randomize.hh"
#include "G4EnergyLossTables.hh"
#include "G4ParticleDefinition.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ForceCondition.hh"
#include "G4Gamma.hh"
#include "G4Electron.hh"
#include "G4DynamicParticle.hh"
#include "G4VParticleChange.hh"
#include "G4ThreeVector.hh"
#include "G4Positron.hh"
#include "G4IonisParamElm.hh"
#include "G4Material.hh"
#include "G4VCrossSectionHandler.hh"
#include "G4CrossSectionHandler.hh"
#include "G4VEMDataSet.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4LogLogInterpolation.hh"
#include "G4VRangeTest.hh"
#include "G4RangeTest.hh"
#include "G4CutsPerMaterialWarning.hh"
// constructor
G4LowEnergyGammaConversion::G4LowEnergyGammaConversion(const G4String& processName)
: G4VDiscreteProcess(processName),
theCrossSectionTable(0),
theMeanFreePathTable(0),
ZNumVec(0),
//Use lowest limit of EPDL97 which is larger than 2*electron_mass_c2 = 1.02199812 MeV
lowestEnergyLimit (1.022000*MeV),
highestEnergyLimit(100*GeV),
NumbBinTable(200)
lowEnergyLimit(1.022000*MeV),
highEnergyLimit(100*GeV),
intrinsicLowEnergyLimit(1.022000*MeV),
intrinsicHighEnergyLimit(100*GeV),
smallEnergy(2.*MeV)
{
if (verboseLevel>0) {
G4cout << GetProcessName() << " is created "<< G4endl;
G4cout << "lowestEnergy: " << lowestEnergyLimit/keV << "keV ";
G4cout << "highestEnergy: " << highestEnergyLimit/GeV << "GeV " << G4endl;
}
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
highEnergyLimit > intrinsicHighEnergyLimit)
{
G4Exception("G4LowEnergyGammaConversion::G4LowEnergyGammaConversion - energy limit outside intrinsic process validity range");
}
// The following pointer is owned by G4DataHandler
crossSectionHandler = new G4CrossSectionHandler();
crossSectionHandler->Initialise(0,1.0220*MeV,100.*GeV,400);
meanFreePathTable = 0;
rangeTest = new G4RangeTest;
if (verboseLevel > 0)
{
G4cout << GetProcessName() << " is created " << G4endl
<< "Energy range: "
<< lowEnergyLimit / MeV << " MeV - "
<< highEnergyLimit / GeV << " GeV"
<< G4endl;
}
}
// destructor
G4LowEnergyGammaConversion::~G4LowEnergyGammaConversion()
{
if (theCrossSectionTable) {
delete theCrossSectionTable;
}
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy();
delete theMeanFreePathTable;
}
if(ZNumVec){
ZNumVec->clear();
delete ZNumVec;
}
}
// methods.............................................................................
void G4LowEnergyGammaConversion::BuildPhysicsTable(const G4ParticleDefinition& GammaType){
BuildZVec();
// Build microscopic cross section tables for the Compton Scattering process
BuildCrossSectionTable();
// Build mean free path table for the Compton Scattering process
BuildMeanFreePathTable();
delete meanFreePathTable;
delete crossSectionHandler;
delete rangeTest;
}
void G4LowEnergyGammaConversion::BuildCrossSectionTable(){
if (theCrossSectionTable) {
delete theCrossSectionTable;
}
theCrossSectionTable = new G4SecondLevel();
G4int dataNum = 2;
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
G4FirstLevel* oneAtomCS = util.BuildFirstLevelTables(AtomInd, dataNum, "pair/pp-cs-");
// theCrossSectionTable->insert(oneAtomCS);
theCrossSectionTable->push_back(oneAtomCS);
}//end for on atoms
}
void G4LowEnergyGammaConversion::BuildZVec(){
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
if(ZNumVec){
ZNumVec->clear();
delete ZNumVec;
}
void G4LowEnergyGammaConversion::BuildPhysicsTable(const G4ParticleDefinition& photon)
{
ZNumVec = new G4DataVector();
for (G4int J=0 ; J < numOfMaterials; J++){
const G4Material* material= (*theMaterialTable)[J];
const G4ElementVector* theElementVector = material->GetElementVector();
const G4int NumberOfElements = material->GetNumberOfElements() ;
G4CutsPerMaterialWarning warning;
warning.PrintWarning(&photon);
for (G4int iel=0; iel<NumberOfElements; iel++ ){
G4double Zel = (*theElementVector)(iel)->GetZ();
if(ZNumVec->contains(Zel) == FALSE){
ZNumVec->push_back(Zel);
} else{
continue;
}
}
}
crossSectionHandler->Clear();
G4String crossSectionFile = "pair/pp-cs-";
crossSectionHandler->LoadData(crossSectionFile);
delete meanFreePathTable;
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
}
G4VParticleChange* G4LowEnergyGammaConversion::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep){
//
// The secondaries e+e- energies are sampled using the Bethe - Heitler
G4VParticleChange* G4LowEnergyGammaConversion::PostStepDoIt(const G4Track& aTrack,
const G4Step& aStep)
{
// The energies of the e+ e- secondaries are sampled using the Bethe - Heitler
// cross sections with Coulomb correction. A modified version of the random
// number techniques of Butcher & Messel is used (Nuc Phys 20(1960),15).
//
// GEANT4 internal units.
//
// Note 1 : Effects due to the breakdown of the Born approximation at low
// energy are ignored.
// Note 2 : The differential cross section implicitly takes account of
@@ -171,262 +136,216 @@ G4VParticleChange* G4LowEnergyGammaConversion::PostStepDoIt(const G4Track& aTrac
aParticleChange.Initialize(aTrack);
G4Material* aMaterial = aTrack.GetMaterial();
G4Material* material = aTrack.GetMaterial();
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
G4ParticleMomentum GammaDirection = aDynamicGamma->GetMomentumDirection();
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
G4double photonEnergy = incidentPhoton->GetKineticEnergy();
G4ParticleMomentum photonDirection = incidentPhoton->GetMomentumDirection();
G4double epsil ;
G4double epsil0 = electron_mass_c2 / GammaEnergy ;
G4double epsilon ;
G4double epsilon0 = electron_mass_c2 / photonEnergy ;
// do it fast if GammaEnergy < 2. MeV
const G4double Egsmall=2.*MeV;
if (GammaEnergy<Egsmall) { epsil = epsil0 + (0.5-epsil0)*G4UniformRand(); }
else{ // now comes the case with GammaEnergy >= 2. MeV
// Do it fast if photon energy < 2. MeV
if (photonEnergy < smallEnergy )
{
epsilon = epsilon0 + (0.5 - epsilon0) * G4UniformRand();
}
else
{
// Select randomly one element in the current material
const G4Element* element = crossSectionHandler->SelectRandomElement(material,photonEnergy);
if (element == 0)
{
G4cout << "G4LowEnergyGammaConversion::PostStepDoIt - element = 0" << G4endl;
}
G4IonisParamElm* ionisation = element->GetIonisation();
if (ionisation == 0)
{
G4cout << "G4LowEnergyGammaConversion::PostStepDoIt - ionisation = 0" << G4endl;
}
// Extract Coulomb factor for this Element
G4double fZ = 8. * (ionisation->GetlogZ3());
if (photonEnergy > 50. * MeV) fZ += 8. * (element->GetfCoulomb());
// select randomly one element constituing the material
G4Element* anElement = SelectRandomAtom(aDynamicGamma, aMaterial);
// Extract Coulomb factor for this Element
G4double FZ = 8.*(anElement->GetIonisation()->GetlogZ3());
if (GammaEnergy > 50.*MeV) FZ += 8.*(anElement->GetfCoulomb());
// limits of the screening variable
G4double screenfac = 136.*epsil0/(anElement->GetIonisation()->GetZ3()) ;
G4double screenmax = exp ((42.24 - FZ)/8.368) - 0.952 ;
G4double screenmin = G4std::min(4.*screenfac,screenmax) ;
// limits of the energy sampling
G4double epsil1 = 0.5 - 0.5*sqrt(1. - screenmin/screenmax) ;
G4double epsilmin = G4std::max(epsil0,epsil1) , epsilrange = 0.5 - epsilmin ;
//
// sample the energy rate of the created electron (or positron)
//
//G4double epsil, screenvar, greject ;
G4double screenvar, greject ;
G4double F10 = ScreenFunction1(screenmin) - FZ , F20 = ScreenFunction2(screenmin) - FZ;
G4double NormF1 = G4std::max(F10*epsilrange*epsilrange,0.) , NormF2 = G4std::max(1.5*F20,0.);
do {
if ( NormF1/(NormF1+NormF2) > G4UniformRand() ){
epsil = 0.5 - epsilrange*pow(G4UniformRand(), 1/3) ;
screenvar = screenfac/(epsil*(1-epsil));
greject = (ScreenFunction1(screenvar) - FZ)/F10 ;
}
else {
epsil = epsilmin + epsilrange*G4UniformRand();
screenvar = screenfac/(epsil*(1-epsil));
greject = (ScreenFunction2(screenvar) - FZ)/F20 ;
}
// Limits of the screening variable
G4double screenFactor = 136. * epsilon0 / (element->GetIonisation()->GetZ3()) ;
G4double screenMax = exp ((42.24 - fZ)/8.368) - 0.952 ;
G4double screenMin = G4std::min(4.*screenFactor,screenMax) ;
} while( greject < G4UniformRand() );
} // end of epsil sampling.........................
// Limits of the energy sampling
G4double epsilon1 = 0.5 - 0.5 * sqrt(1. - screenMin / screenMax) ;
G4double epsilonMin = G4std::max(epsilon0,epsilon1);
G4double epsilonRange = 0.5 - epsilonMin ;
// Sample the energy rate of the created electron (or positron)
G4double screen;
G4double gReject ;
G4double f10 = ScreenFunction1(screenMin) - fZ;
G4double f20 = ScreenFunction2(screenMin) - fZ;
G4double normF1 = G4std::max(f10 * epsilonRange * epsilonRange,0.);
G4double normF2 = G4std::max(1.5 * f20,0.);
do {
if (normF1 / (normF1 + normF2) > G4UniformRand() )
{
epsilon = 0.5 - epsilonRange * pow(G4UniformRand(), 0.3333) ;
screen = screenFactor / (epsilon * (1. - epsilon));
gReject = (ScreenFunction1(screen) - fZ) / f10 ;
}
else
{
epsilon = epsilonMin + epsilonRange * G4UniformRand();
screen = screenFactor / (epsilon * (1 - epsilon));
gReject = (ScreenFunction2(screen) - fZ) / f20 ;
}
} while ( gReject < G4UniformRand() );
} // End of epsilon sampling
//
// fixe charges randomly
//
// Fix charges randomly
G4double ElectTotEnergy, PositTotEnergy;
if (RandBit::shootBit()){
G4double electronTotEnergy;
G4double positronTotEnergy;
ElectTotEnergy = (1.-epsil)*GammaEnergy;
PositTotEnergy = epsil*GammaEnergy;
}
else{
PositTotEnergy = (1.-epsil)*GammaEnergy;
ElectTotEnergy = epsil*GammaEnergy;
}
if (RandBit::shootBit())
{
electronTotEnergy = (1. - epsilon) * photonEnergy;
positronTotEnergy = epsilon * photonEnergy;
}
else
{
positronTotEnergy = (1. - epsilon) * photonEnergy;
electronTotEnergy = epsilon * photonEnergy;
}
//
// scattered electron (positron) angles. ( Z - axis along the parent photon)
// universal distribution suggested by L. Urban (Geant3 manual (1993) Phys211),
// derived from Tsai distribution (Rev Mod Phys 49,421(1977))
// Scattered electron (positron) angles. ( Z - axis along the parent photon)
// Universal distribution suggested by L. Urban (Geant3 manual (1993) Phys211),
// derived from Tsai distribution (Rev. Mod. Phys. 49, 421 (1977)
G4double u;
const G4double a1 = 0.625 , a2 = 3.*a1 , d = 27. ;
const G4double a1 = 0.625;
G4double a2 = 3. * a1;
// G4double d = 27. ;
if (9./(9.+d) > G4UniformRand()){
u = - log(G4UniformRand()*G4UniformRand())/a1 ;
}
// if (9. / (9. + d) > G4UniformRand())
if (0.25 > G4UniformRand())
{
u = - log(G4UniformRand() * G4UniformRand()) / a1 ;
}
else
{
u = - log(G4UniformRand() * G4UniformRand()) / a2 ;
}
else{
u = - log(G4UniformRand()*G4UniformRand())/a2 ;
}
G4double theta = u * electron_mass_c2 / photonEnergy ;
G4double phi = twopi * G4UniformRand() ;
G4double dirX = sin(theta) * cos(phi);
G4double dirY = sin(theta) * sin(phi);
G4double dirZ = cos(theta);
G4double Teta = u*electron_mass_c2/GammaEnergy ;
G4double Phi = twopi * G4UniformRand() ;
G4double dirx = sin(Teta)*cos(Phi) , diry = sin(Teta)*sin(Phi) , dirz = cos(Teta);
//
// kinematic of the created pair
// Kinematics of the created pair:
// the electron and positron are assumed to have a symetric angular
// distribution with respect to the Z axis along the parent photon.
// distribution with respect to the Z axis along the parent photon
G4double LocalEnerDeposit = 0. ;
G4double localEnergyDeposit = 0. ;
aParticleChange.SetNumberOfSecondaries(2) ;
G4double ElectKineEnergy = G4std::max(0.,ElectTotEnergy - electron_mass_c2) ;
aParticleChange.SetNumberOfSecondaries(2.) ;
G4double electronKineEnergy = G4std::max(0.,electronTotEnergy - electron_mass_c2) ;
// if (G4EnergyLossTables::GetRange(G4Electron::Electron(), ElectKineEnergy, aMaterial)
// >= G4std::min(G4Electron::GetCuts(), aStep.GetPostStepPoint()->GetSafety()) ){
if((G4EnergyLossTables::GetRange(G4Electron::Electron(),
ElectKineEnergy,aMaterial)>aStep.GetPostStepPoint()->GetSafety())
||
(ElectKineEnergy >
(G4Electron::Electron()->GetCutsInEnergy())[aMaterial->GetIndex()]))
// Generate the electron only if with large enough range w.r.t. cuts and safety
{
G4double safety = aStep.GetPostStepPoint()->GetSafety();
G4ThreeVector ElectDirection ( dirx, diry, dirz );
ElectDirection.rotateUz(GammaDirection);
// create G4DynamicParticle object for the particle1
G4DynamicParticle* aParticle1= new G4DynamicParticle (G4Electron::Electron(),ElectDirection, ElectKineEnergy);
if (rangeTest->Escape(G4Electron::Electron(),material,electronKineEnergy,safety))
{
G4ThreeVector electronDirection ( dirX, dirY, dirZ );
electronDirection.rotateUz(photonDirection);
G4DynamicParticle* particle1 = new G4DynamicParticle (G4Electron::Electron(),
electronDirection,
electronKineEnergy);
aParticleChange.AddSecondary(particle1) ;
}
else
{
localEnergyDeposit += electronKineEnergy ;
}
aParticleChange.AddSecondary( aParticle1 ) ;
}
else{
LocalEnerDeposit += ElectKineEnergy ;
}
// The e+ is always created (even with kinetic energy = 0) for further annihilation
G4double positronKineEnergy = G4std::max(0.,positronTotEnergy - electron_mass_c2) ;
// the e+ is always created (even with Ekine=0) for further annihilation.
G4double PositKineEnergy = G4std::max(0.,PositTotEnergy - electron_mass_c2) ;
if (G4EnergyLossTables::GetRange(G4Positron::Positron(),PositKineEnergy,aMaterial)
< G4std::min(G4Positron::GetCuts(), aStep.GetPostStepPoint()->GetSafety()) ){
LocalEnerDeposit += PositKineEnergy ;
PositKineEnergy = 0. ;
}
G4ThreeVector PositDirection ( -dirx, -diry, dirz );
PositDirection.rotateUz(GammaDirection);
// Is the local energy deposit correct, if the positron is always created?
if (! (rangeTest->Escape(G4Positron::Positron(),material,positronKineEnergy,safety)))
{
localEnergyDeposit += positronKineEnergy ;
positronKineEnergy = 0. ;
}
G4ThreeVector positronDirection(-dirX,-dirY,dirZ);
positronDirection.rotateUz(photonDirection);
// create G4DynamicParticle object for the particle2
G4DynamicParticle* aParticle2= new G4DynamicParticle (G4Positron::Positron(),
PositDirection, PositKineEnergy);
// Create G4DynamicParticle object for the particle2
G4DynamicParticle* particle2 = new G4DynamicParticle(G4Positron::Positron(),
positronDirection, positronKineEnergy);
aParticleChange.AddSecondary(particle2) ;
aParticleChange.AddSecondary( aParticle2 ) ;
aParticleChange.SetLocalEnergyDeposit(localEnergyDeposit) ;
aParticleChange.SetLocalEnergyDeposit( LocalEnerDeposit ) ;
//
// Kill the incident photon
//
aParticleChange.SetMomentumChange( 0., 0., 0. ) ;
aParticleChange.SetEnergyChange( 0. ) ;
aParticleChange.SetStatusChange( fStopAndKill ) ;
#ifdef G4VERBOSE
if(verboseLevel > 15){
G4cout<<"LE Gamma Conversion PostStepDoIt"<<G4endl;
}
#endif
aParticleChange.SetMomentumChange(0.,0.,0.) ;
aParticleChange.SetEnergyChange(0.) ;
aParticleChange.SetStatusChange(fStopAndKill) ;
// Reset NbOfInteractionLengthLeft and return aParticleChange
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep );
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
}
void G4LowEnergyGammaConversion::BuildMeanFreePathTable(){
G4bool G4LowEnergyGammaConversion::IsApplicable(const G4ParticleDefinition& particle)
{
return ( &particle == G4Gamma::Gamma() );
}
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy(); delete theMeanFreePathTable; }
G4double G4LowEnergyGammaConversion::GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition*)
{
const G4DynamicParticle* photon = track.GetDynamicParticle();
G4double energy = photon->GetKineticEnergy();
G4Material* material = track.GetMaterial();
size_t materialIndex = material->GetIndex();
// material
G4double NumbOfMaterials = G4Material::GetNumberOfMaterials();
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
G4Material* material;
G4double meanFreePath;
if (energy > highEnergyLimit) meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
else meanFreePath = meanFreePathTable->FindValue(energy,materialIndex);
return meanFreePath;
}
// MeanFreePath
G4double LowEdgeEnergy, Value;
theMeanFreePathTable = new G4PhysicsTable(NumbOfMaterials);
G4PhysicsLogVector* ptrVector;
G4double G4LowEnergyGammaConversion::ScreenFunction1(G4double screenVariable)
{
// Compute the value of the screening function 3*phi1 - phi2
for ( G4int J = 0 ; J < NumbOfMaterials; J++ ) { // For each material
G4double value;
//create physics vector then fill it ....
ptrVector = new G4PhysicsLogVector(lowestEnergyLimit, highestEnergyLimit, NumbBinTable);
material = (*theMaterialTable)(J);
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
for ( G4int i = 0 ; i < NumbBinTable ; i++ ){
//For each energy
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy(i);
const G4double BigPath= DBL_MAX;
G4double SIGMA = 0 ;
for ( size_t k=0 ; k < material->GetNumberOfElements() ; k++ ){
// For each element
G4int AtomIndex = (G4int) (*theElementVector)(k)->GetZ();
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
G4double interCrsSec = util.DataLogInterpolation(LowEdgeEnergy,
(*(*oneAtomCS)[0]),
(*(*oneAtomCS)[1]))*barn;
SIGMA += theAtomNumDensityVector[k]*interCrsSec;
}
Value = SIGMA<=0.0 ? BigPath : 1./SIGMA ;
ptrVector->PutValue( i , Value ) ;
}
theMeanFreePathTable->insertAt( J , ptrVector ) ;
}
}
G4Element* G4LowEnergyGammaConversion::SelectRandomAtom(const G4DynamicParticle* aDynamicGamma, G4Material* aMaterial){
// select randomly 1 element within the material
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
if (NumberOfElements == 1) return (*theElementVector)(0);
const G4double* theAtomNumDensityVector = aMaterial->GetAtomicNumDensityVector();
G4double PartialSumSigma = 0.;
G4double rval = G4UniformRand()/MeanFreePath;
for ( G4int i=0 ; i < NumberOfElements ; i++ ){
G4double crossSection;
if (GammaEnergy < lowestEnergyLimit)
crossSection = 0. ;
else {
if (GammaEnergy > highestEnergyLimit) GammaEnergy = 0.99*highestEnergyLimit ;
G4int AtomIndex = (G4int) (*theElementVector)(i)->GetZ();
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
crossSection = util.DataLogInterpolation(GammaEnergy,
(*(*oneAtomCS)[0]),
(*(*oneAtomCS)[1]))*barn;
}
PartialSumSigma += theAtomNumDensityVector[i] * crossSection;
if(rval <= PartialSumSigma) return ((*theElementVector)(i));
}
// G4cout << " WARNING !!! - The Material '"<< aMaterial->GetName()
// << "' has no elements" << G4endl;
return (*theElementVector)(0);
}
if (screenVariable > 1.)
value = 42.24 - 8.368 * log(screenVariable + 0.952);
else
value = 42.392 - screenVariable * (7.796 - 1.961 * screenVariable);
return value;
}
G4double G4LowEnergyGammaConversion::ScreenFunction2(G4double screenVariable)
{
// Compute the value of the screening function 1.5*phi1 - 0.5*phi2
G4double value;
if (screenVariable > 1.)
value = 42.24 - 8.368 * log(screenVariable + 0.952);
else
value = 41.405 - screenVariable * (5.828 - 0.8945 * screenVariable);
return value;
}
File diff suppressed because it is too large Load Diff
@@ -21,17 +21,21 @@
// ********************************************************************
//
//
// $Id: G4LowEnergyPhotoElectric.cc,v 1.31.2.2 2001/06/28 20:19:30 gunter Exp $
// GEANT4 tag $Name: $
// $Id: G4LowEnergyPhotoElectric.cc,v 1.42 2001/11/07 21:31:16 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
// CERN Geneva Switzerland
// Author: A. Forti
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// ------------ G4LowEnergyPhotoelctric: low energy modifications --------
// by Alessandra Forti, October 1998
// **************************************************************
// History:
// --------
// October 1998 - low energy modifications by Alessandra Forti
// Added Livermore data table construction methods A. Forti
// Modified BuildMeanFreePath to read new data tables A. Forti
// Added EnergySampling method A. Forti
// Modified PostStepDoIt to insert sampling with EPDL97 data A. Forti
// Added SelectRandomAtom A. Forti
// Added map of the elements A. Forti
// 10.04.2000 VL
// - Correcting Fluorescence transition probabilities in order to take into account
// non-radiative transitions. No Auger electron simulated yet: energy is locally deposited.
@@ -41,707 +45,264 @@
// . no Fluorescence was simulated when the photo-electron energy
// was below production threshold.
//
// Added Livermore data table construction methods A. Forti
// Modified BuildMeanFreePath to read new data tables A. Forti
// Added EnergySampling method A. Forti
// Modified PostStepDoIt to insert sampling with EPDL97 data A. Forti
// Added SelectRandomAtom A. Forti
// Added map of the elements A. Forti
// 07-09-99, if no e- emitted: edep=photon energy, mma
// 24.04.01 V.Ivanchenko remove RogueWave
// 12.08.2001 MGP Revised according to a design iteration
// 16.09.2001 E. Guardincerri Added fluorescence generation
// 06.10.2001 MGP Added protection to avoid negative electron energies
// when binding energy of selected shell > photon energy
//
// --------------------------------------------------------------
// This Class Header
#include "G4LowEnergyPhotoElectric.hh"
// Collaborating Class Headers
#include "G4EnergyLossTables.hh"
#include "G4ParticleDefinition.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ForceCondition.hh"
#include "G4Gamma.hh"
#include "G4Electron.hh"
#include "G4DynamicParticle.hh"
#include "G4VParticleChange.hh"
#include "G4ThreeVector.hh"
#include "G4VCrossSectionHandler.hh"
#include "G4CrossSectionHandler.hh"
#include "G4VEMDataSet.hh"
#include "G4CompositeEMDataSet.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4LogLogInterpolation.hh"
#include "G4VRangeTest.hh"
#include "G4RangeTest.hh"
#include "G4AtomicTransitionManager.hh"
#include "G4AtomicShell.hh"
typedef G4std::vector<G4DynamicParticle*> G4ParticleVector;
#include "G4CutsPerMaterialWarning.hh"
// ..
// constructor
G4LowEnergyPhotoElectric::G4LowEnergyPhotoElectric(const G4String& processName)
: G4VDiscreteProcess(processName), // initialization
lowestEnergyLimit (250*eV),
highestEnergyLimit(100*GeV),
NumbBinTable(200),
CutForLowEnergySecondaryPhotons(0.),
theCrossSectionTable(0),
theMeanFreePathTable(0),
allAtomShellCrossSec(0),
theFluorTransitionTable(0),
theBindingEnergyTable(0),
ZNumVec(0),
ZNumVecFluor(0),
MeanFreePath(0.)
: G4VDiscreteProcess(processName), lowEnergyLimit(250*eV), highEnergyLimit(100*GeV),
intrinsicLowEnergyLimit(10*eV),
intrinsicHighEnergyLimit(100*GeV),
cutForLowEnergySecondaryPhotons(0.)
{
if (verboseLevel>0) {
G4cout << GetProcessName() << " is created "<< G4endl;
G4cout << "lowestEnergy: " << lowestEnergyLimit/keV << "keV ";
G4cout << "highestEnergy: " << highestEnergyLimit/MeV << "MeV " << G4endl;
}
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
highEnergyLimit > intrinsicHighEnergyLimit)
{
G4Exception("G4LowEnergyPhotoElectric::G4LowEnergyPhotoElectric - energy limit outside intrinsic process validity range");
}
crossSectionHandler = new G4CrossSectionHandler();
shellCrossSectionHandler = new G4CrossSectionHandler();
meanFreePathTable = 0;
rangeTest = new G4RangeTest;
if (verboseLevel > 0)
{
G4cout << GetProcessName() << " is created " << G4endl
<< "Energy range: "
<< lowEnergyLimit / keV << " keV - "
<< highEnergyLimit / GeV << " GeV"
<< G4endl;
}
}
// ..
// destructor
G4LowEnergyPhotoElectric::~G4LowEnergyPhotoElectric()
{
if (theCrossSectionTable) {
delete theCrossSectionTable;
}
if (theBindingEnergyTable) {
// theBindingEnergyTable->clearAndDestroy();
theBindingEnergyTable->clear();
delete theBindingEnergyTable;
}
if (theMeanFreePathTable) {
// theMeanFreePathTable->clearAndDestroy();
theMeanFreePathTable->clear();
delete theMeanFreePathTable;
}
// ClearAndDestroy of this tables is called in their destructors
if (theFluorTransitionTable) {
delete theFluorTransitionTable;
}
if (allAtomShellCrossSec) {
delete allAtomShellCrossSec;
}
if(ZNumVec){
ZNumVec->clear();
delete ZNumVec;
}
if(ZNumVecFluor){
ZNumVecFluor->erase(ZNumVecFluor->begin(),ZNumVecFluor->end());
delete ZNumVecFluor;
}
}
// ..
void G4LowEnergyPhotoElectric::SetCutForLowEnSecPhotons(G4double cut){
CutForLowEnergySecondaryPhotons = cut;
delete crossSectionHandler;
delete shellCrossSectionHandler;
delete meanFreePathTable;
delete rangeTest;
}
// ..
void G4LowEnergyPhotoElectric::BuildPhysicsTable(const G4ParticleDefinition& PhotonType)
// Build microscopic cross section table and mean free path table
void G4LowEnergyPhotoElectric::BuildPhysicsTable(const G4ParticleDefinition& photon)
{
BuildZVec();
BuildCrossSectionTable();
BuildShellCrossSectionTable();
BuildMeanFreePathTable();
BuildBindingEnergyTable();
G4CutsPerMaterialWarning warning;
warning.PrintWarning(&photon);
BuildFluorTransitionTable();
crossSectionHandler->Clear();
G4String crossSectionFile = "phot/pe-cs-";
crossSectionHandler->LoadData(crossSectionFile);
shellCrossSectionHandler->Clear();
G4String shellCrossSectionFile = "phot/pe-ss-cs-";
shellCrossSectionHandler->LoadShellData(shellCrossSectionFile);
delete meanFreePathTable;
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
}
// ..
// CONSTRUCT THE CROSS SECTION TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC USING EPDL DATA
void G4LowEnergyPhotoElectric::BuildCrossSectionTable(){
if (theCrossSectionTable) {
delete theCrossSectionTable;
}
theCrossSectionTable = new G4SecondLevel();
G4int dataNum = 2;
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
G4FirstLevel* oneAtomCS = util.BuildFirstLevelTables(AtomInd, dataNum, "phot/pe-cs-");
// theCrossSectionTable->insert(oneAtomCS);
theCrossSectionTable->push_back(oneAtomCS);
}//end for on atoms
}
// ..
// CONSTRUCT THE SUBSHELL CS TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC USING EPDL DATA
void G4LowEnergyPhotoElectric::BuildShellCrossSectionTable(){
if (allAtomShellCrossSec) {
delete allAtomShellCrossSec;
}
allAtomShellCrossSec = new allAtomTable();
G4int dataNum = 2;
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
oneAtomTable* oneAtomShellCS = util.BuildSecondLevelTables(AtomInd, dataNum, "phot/pe-ss-cs-");
// allAtomShellCrossSec->insert(oneAtomShellCS);
allAtomShellCrossSec->push_back(oneAtomShellCS);
}//end for on atoms
}
// ..
// CONSTRUCT THE BE TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC USING EADL DATA
void G4LowEnergyPhotoElectric::BuildBindingEnergyTable(){
if (theBindingEnergyTable) {
delete theBindingEnergyTable;
}
G4int dataNum = 2;
theBindingEnergyTable = util.BuildSecondLevelTables(0,dataNum,"fluor/binding");
}
// ..
// CONSTRUCT THE FTP TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC USING EADL DATA
void G4LowEnergyPhotoElectric::BuildFluorTransitionTable(){
if (theFluorTransitionTable) {
delete theFluorTransitionTable;
}
theFluorTransitionTable = new allAtomTable();
ZNumVecFluor = new G4DataVector(*ZNumVec);
G4int dataNum = 3;
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
if(AtomInd > 5){
oneAtomTable* oneAtomShellFL = util.BuildSecondLevelTables(AtomInd, dataNum, "fluor/fl-tr-pr-");
// theFluorTransitionTable->insert(oneAtomShellFL);
theFluorTransitionTable->push_back(oneAtomShellFL);
}
else{
ZNumVecFluor->remove(AtomInd);
}
}//end for on atoms
}
// ..
//
// vector mapping the elements of the material table
//
void G4LowEnergyPhotoElectric::BuildZVec(){
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
if(ZNumVec){
ZNumVec->clear();
delete ZNumVec;
}
ZNumVec = new G4DataVector();
for (G4int J=0 ; J < numOfMaterials; J++){
const G4Material* material= (*theMaterialTable)[J];
const G4ElementVector* theElementVector = material->GetElementVector();
const G4int NumberOfElements = material->GetNumberOfElements() ;
for (G4int iel=0; iel<NumberOfElements; iel++ ){
G4double Zel = (*theElementVector)(iel)->GetZ();
if(ZNumVec->contains(Zel) == FALSE){
ZNumVec->push_back(Zel);
} else{
continue;
}
}
}
}
// ..
// Compute total cross section from subshell integrated cross section: needed for
// selection of the first subshell ionized.
G4double G4LowEnergyPhotoElectric::ComputeCrossSection(const G4double AtomIndex,
const G4double IncEnergy){
// calculates the microscopic cross section from subshell cross sections
//(it is called for elements , AtomicNumber = Z )
G4double TotalCrossSection(0.);
const oneAtomTable* oneAtomCS
= (*allAtomShellCrossSec)[ZNumVec->index(AtomIndex)];
for(size_t ind = 0; ind < oneAtomCS->size(); ind++){
G4double crossSec = 0;
G4DataVector* EnergyVector = (*(*oneAtomCS)[ind])[0];
G4DataVector* CrossSecVector = (*(*oneAtomCS)[ind])[1];
if(IncEnergy < (*EnergyVector)[1]){ // First element is the shell number
crossSec = 0;
}
else{
crossSec = util.DataLogInterpolation(IncEnergy, (*EnergyVector), (*CrossSecVector))*barn;
}
TotalCrossSection += crossSec;
}
return TotalCrossSection ;
}
// ..
void G4LowEnergyPhotoElectric::BuildMeanFreePathTable(){
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy();
delete theMeanFreePathTable; }
// material
G4double NumbOfMaterials = G4Material::GetNumberOfMaterials();
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
G4Material* material;
// MeanFreePath
G4double LowEdgeEnergy, Value;
theMeanFreePathTable = new G4PhysicsTable(NumbOfMaterials);
G4PhysicsLogVector* ptrVector;
for ( G4int J = 0 ; J < NumbOfMaterials; J++ ) { // For each material
//create physics vector then fill it ....
// WARNING: Lower limit of total cross sections in the data is the binding energy
// of the relative subshell. MeanFreePath table require a common lowest limit.
// This lowestEnergyLimit is at the moment fixed at 250 ev.
ptrVector = new G4PhysicsLogVector(lowestEnergyLimit, highestEnergyLimit, NumbBinTable);
material = (*theMaterialTable)(J);
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
for ( G4int i = 0 ; i < NumbBinTable ; i++ ){
//For each energy
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy(i);
G4double SIGMA = 0;
for ( size_t k=0 ; k < material->GetNumberOfElements() ; k++ ){
// For each element
G4int AtomIndex = (G4int) (*theElementVector)(k)->GetZ();
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
G4double interCrsSec = util.DataLogInterpolation(LowEdgeEnergy, (*(*oneAtomCS)[0]), (*(*oneAtomCS)[1]))*barn;
SIGMA += theAtomNumDensityVector[k]*interCrsSec;
}
Value = SIGMA > DBL_MIN ? 1./SIGMA : DBL_MAX ;
ptrVector->PutValue( i , Value ) ;
}
theMeanFreePathTable->insertAt( J , ptrVector ) ;
}
}
// ..
G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep){
// Fluorescence (as reported by stepanek):
// J. Stepanek " A program to determine the radiation spectra due to a single atomic
G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
const G4Step& aStep)
{
// Fluorescence generated according to:
// J. Stepanek ,"A program to determine the radiation spectra due to a single atomic
// subshell ionisation by a particle or due to deexcitation or decay of radionuclides",
// Comp. Phys. Comm. 1206 pp 1-1-9 (1997)
//
// incoming particle initialization
aParticleChange.Initialize(aTrack);
G4Material* aMaterial = aTrack.GetMaterial();
const G4DynamicParticle* aDynamicPhoton = aTrack.GetDynamicParticle();
const G4double PhotonEnergy = aDynamicPhoton->GetKineticEnergy();
if(PhotonEnergy <= lowestEnergyLimit){
aParticleChange.SetStatusChange(fStopAndKill);
aParticleChange.SetEnergyChange(0.);
aParticleChange.SetLocalEnergyDeposit(PhotonEnergy);
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
}
const G4ParticleMomentum PhotonDirection = aDynamicPhoton->GetMomentumDirection();
// select randomly one element constituing the material.
G4Element* anElement = SelectRandomAtom(aDynamicPhoton, aMaterial);
// PAY ATTENTION TO THE MEANING OF THIS NUMBER!!! SelectRandomAtom requires to use AtomNum
// the BindingEnergyTable requires AtomNum-1
G4int AtomNum = (G4int) anElement->GetZ();
// First Ionised subshell is chosen basing on subshell integrated cross section EPDL97
// using the partial sum method.
// Select the subshell WARNING!!!!: it returns the subshell index in the table.
G4int subShellIndex = SelectRandomShell(AtomNum, PhotonEnergy);
G4FirstLevel* theBindEnVec = (*theBindingEnergyTable)[AtomNum-1];
G4int thePrimaryShell = (G4int) (*(*theBindEnVec)[0])[subShellIndex];
G4double BindingEn = ((*(*theBindEnVec)[1])[subShellIndex])*MeV;
if(thePrimShVec.size() != 0){
thePrimShVec.clear();
}
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
G4double photonEnergy = incidentPhoton->GetKineticEnergy();
if (photonEnergy <= lowEnergyLimit)
{
aParticleChange.SetStatusChange(fStopAndKill);
aParticleChange.SetEnergyChange(0.);
aParticleChange.SetLocalEnergyDeposit(photonEnergy);
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
}
G4ParticleMomentum photonDirection = incidentPhoton->GetMomentumDirection();
// Select randomly one element in the current material
G4Material* material = aTrack.GetMaterial();
G4int Z = crossSectionHandler->SelectRandomAtom(material,photonEnergy);
thePrimShVec.push_back(thePrimaryShell);
// Select the ionised shell in the current atom according to shell cross sections
size_t shellIndex = shellCrossSectionHandler->SelectRandomShell(Z,photonEnergy);
// Retrieve the corresponding identifier and binding energy of the selected shell
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
const G4AtomicShell* shell = transitionManager->Shell(Z,shellIndex);
G4double bindingEnergy = shell->BindingEnergy();
G4int shellId = shell->ShellId();
// Create lists of pointers to DynamicParticles (photons and electrons)
G4ParticleVector photvec;
// G4int photInd = 0;
G4ParticleVector elecvec;
// G4int elecInd = 0;
// (Is the electron vector necessary? To be checked)
G4std::vector<G4DynamicParticle*>* photonVector = 0;
G4std::vector<G4DynamicParticle*> electronVector;
// primary outcoming electron
G4double ElecKineEnergy = (PhotonEnergy - BindingEn);
G4double energyDeposit = bindingEnergy;
G4double theEnergyDeposit = BindingEn;
// Primary outcoming electron
G4double eKineticEnergy = photonEnergy - bindingEnergy;
if (G4EnergyLossTables::GetRange(G4Electron::Electron(),ElecKineEnergy,aMaterial)
>= G4std::min(G4Electron::GetCuts(), aStep.GetPostStepPoint()->GetSafety())){
// There may be cases where the binding energy of the selected shell is > photon energy
// In such cases do not generate secondaries
if (eKineticEnergy > 0.)
{
// Generate the electron only if with large enough range w.r.t. cuts and safety
G4double safety = aStep.GetPostStepPoint()->GetSafety();
// the electron is created in the direction of the incident photon ...
G4DynamicParticle* aElectron = new G4DynamicParticle (G4Electron::Electron(),
PhotonDirection, ElecKineEnergy) ;
elecvec.push_back(aElectron);
} // END OF CUTS
if (rangeTest->Escape(G4Electron::Electron(),material,eKineticEnergy,safety))
{
// The electron is created in the direction of the incident photon ...
G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),
photonDirection,
eKineticEnergy);
electronVector.push_back(electron);
}
else
{
energyDeposit += eKineticEnergy;
}
}
else
{
energyDeposit = photonEnergy;
}
G4int nElectrons = electronVector.size();
size_t nTotPhotons = 0;
G4int nPhotons=0;
// Generation of fluorescence
// Data in EADL are available only for Z > 5
// Protection to avoid generating photons in the unphysical case of
// shell binding energy > photon energy
if (Z > 5 && eKineticEnergy > 0.)
{
photonVector = deexcitationManager.GenerateParticles(Z,shellId);
nTotPhotons = photonVector->size();
for (size_t k=0; k<nTotPhotons; k++)
{
G4DynamicParticle* aPhoton = (*photonVector)[k];
if (aPhoton == 0)
{
delete aPhoton;
}
else
{
G4double itsKineticEnergy = aPhoton->GetKineticEnergy();
G4double eDepositTmp = energyDeposit - itsKineticEnergy;
if (itsKineticEnergy >= cutForLowEnergySecondaryPhotons &&
eDepositTmp > 0.)
{
nPhotons++;
// Local energy deposit is given as the sum of the
// energies of incident photons minus the energies
// of the outcoming fluorescence photons
energyDeposit -= itsKineticEnergy;
}
else
{ delete aPhoton; }
}
}
}
G4int nSecondaries = nElectrons + nPhotons;
else{
theEnergyDeposit += ElecKineEnergy;
}
// load the transition probability table for the element
// theTable[i][j][k]
// i = subshell, j = type of information (second shell, transition energy ,
// transition probability), k = previous vectors.
if(AtomNum > 5){
G4bool ThereAreShells = TRUE;
G4int AtomInd = ZNumVecFluor->index(AtomNum);
oneAtomTable* oneAtomFluorTrans = (*theFluorTransitionTable)[AtomInd];
while(ThereAreShells == TRUE){
// Select the second transition from another subshell
// fluorPar[0] = SubShell
// fluorPar[1] = Sec SubShell (if there is),
// fluorPar[2] = Transition Probability
// the same for augerPar
G4double fluorPar[3] = {0};
ThereAreShells = SelectRandomTransition(thePrimaryShell,
fluorPar,
oneAtomFluorTrans);
// Daugther dynamic particle
G4DynamicParticle* newPart;
// Direction of the outcoming particle isotropic selection
G4double newcosTh = 1-2*G4UniformRand();
G4double newsinTh = sqrt(1-newcosTh*newcosTh);
G4double newPhi = twopi*G4UniformRand();
G4double dirx, diry, dirz;
dirz = newcosTh;
diry = newsinTh*cos(newPhi);
dirx = newsinTh*sin(newPhi);
G4ThreeVector newPartDirection(dirx, diry, dirz);
/////newPartDirection.rotateUz(PhotonDirection);
if(ThereAreShells != FALSE){
thePrimaryShell = (G4int) fluorPar[0];
if(fluorPar[2]*MeV >= CutForLowEnergySecondaryPhotons){
theEnergyDeposit -= fluorPar[2]*MeV;
newPart = new G4DynamicParticle (G4Gamma::Gamma(),
newPartDirection,
fluorPar[2]*MeV);
// photvec.append(newPart);
photvec.push_back(newPart);
}
}
else{
/////Energy deposition vl
////=================NEW================vl
/*
G4int k = 0;
while(thePrimaryShell != (*(*theBindEnVec)[0])[k]) k++;
G4double lastTransEnergy = ((*(*theBindEnVec)[1])[k])*MeV;
thePrimaryShell = (G4int) fluorPar[0];
if(lastTransEnergy >= CutForLowEnergySecondaryPhotons){
theEnergyDeposit -= lastTransEnergy;
newPart = new G4DynamicParticle (G4Gamma::Gamma(),
newPartDirection,
lastTransEnergy) ;
photvec.push_back(newPart);
}
thePrimShVec.insert(thePrimaryShell);
*/
}
}
} //END OF THE CHECK ON ATOMIC NUMBER
G4int numOfElec = elecvec.size();
G4int numOfPhot = photvec.size();
G4int numOfDau = numOfElec + numOfPhot;
aParticleChange.SetNumberOfSecondaries(numOfDau);
G4int l = 0;
for( l = 0; l<numOfElec; l++ ){
aParticleChange.AddSecondary(elecvec[l]);
aParticleChange.SetNumberOfSecondaries(nSecondaries);
G4int l = 0;
for ( l = 0; l<nElectrons; l++ )
{
aParticleChange.AddSecondary(electronVector[l]);
}
for(l = 0; l < numOfPhot; l++) {
aParticleChange.AddSecondary(photvec[l]);
for (l = 0; l < nPhotons; l++)
{
aParticleChange.AddSecondary((*photonVector)[l]);
}
photvec.clear();
elecvec.clear();
if(theEnergyDeposit < 0){
theEnergyDeposit = 0;
delete photonVector;
if (energyDeposit < 0)
{
G4cout << "WARNING - "
<< "G4LowEnergyPhotoElectric::PostStepDoIt - Negative energy deposit"
<< G4endl;
energyDeposit = 0;
}
// Kill the incident photon
aParticleChange.SetMomentumChange( 0., 0., 0. );
aParticleChange.SetEnergyChange( 0. );
if (theEnergyDeposit < 0) theEnergyDeposit = 0;
aParticleChange.SetLocalEnergyDeposit(theEnergyDeposit);
aParticleChange.SetLocalEnergyDeposit(energyDeposit);
aParticleChange.SetStatusChange( fStopAndKill );
// Reset NbOfInteractionLengthLeft and return aParticleChange
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep );
}
// ..
G4int G4LowEnergyPhotoElectric::SelectRandomShell(const G4int AtomIndex,
const G4double IncEnergy)
{
G4double partialSum = 0;
G4double totalSum = ComputeCrossSection(AtomIndex,IncEnergy);
G4double rval = totalSum*G4UniformRand();
const oneAtomTable* oneAtomCS
= (*allAtomShellCrossSec)[ZNumVec->index(AtomIndex)];
for(size_t ind = 0; ind < oneAtomCS->size(); ind++){
G4double crossSec;
G4DataVector* EnergyVector = (*(*oneAtomCS)[ind])[0];
G4DataVector* CrossSecVector = (*(*oneAtomCS)[ind])[1];
if(IncEnergy < (*EnergyVector)[0]){ //First element is the shell number
crossSec = 0;
}
else{
crossSec = util.DataLogInterpolation(IncEnergy, (*EnergyVector), (*CrossSecVector))*barn;
}
partialSum += crossSec;
if(rval <= partialSum) return ind;
}
G4Exception("LEPhotoElectric: Cannot select a shell");
return 0;
}
// ..
G4Element*
G4LowEnergyPhotoElectric::SelectRandomAtom(const G4DynamicParticle* aDynamicPhoton,
G4Material* aMaterial)
G4bool G4LowEnergyPhotoElectric::IsApplicable(const G4ParticleDefinition& particle)
{
// select randomly 1 element within the material
G4double GammaEnergy = aDynamicPhoton->GetKineticEnergy();
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
if (NumberOfElements == 1) return (*theElementVector)(0);
const G4double* theAtomNumDensityVector = aMaterial->GetAtomicNumDensityVector();
G4double PartialSumSigma = 0. ;
G4double rval = G4UniformRand()/MeanFreePath;
for ( G4int i=0 ; i < NumberOfElements ; i++ ){
G4double crossSection;
if (GammaEnergy < lowestEnergyLimit)
crossSection = 0. ;
else {
if (GammaEnergy > highestEnergyLimit) GammaEnergy = 0.99*highestEnergyLimit ;
G4int AtomIndex = (G4int) (*theElementVector)(i)->GetZ();
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
crossSection = util.DataLogInterpolation(GammaEnergy, (*(*oneAtomCS)[0]), (*(*oneAtomCS)[1]))*barn;
}
PartialSumSigma += theAtomNumDensityVector[i] * crossSection;
if (rval <= PartialSumSigma) return ((*theElementVector)(i));
}
return (*theElementVector)(0);
}
// ..
//
// Select a random transition with the transition probabilities and the partial sum
// method using EADL data (A. Forti)
//
G4bool G4LowEnergyPhotoElectric::SelectRandomTransition(G4int thePrimShell,
G4double* TransParam,
const oneAtomTable* TransitionTable){
G4int SubShellCol = 0, ProbCol = 1, EnergyCol = 2;
// transitionTable contains all the transition probabilities of one atom:
// loop on subshell is inside the method.
// when the last subshell is reached CollIsFull becomes FALSE.
G4bool ColIsFull = FALSE;
G4int ShellNum = 0;
// G4double TotalSum = 0;
G4int maxNumOfShells = TransitionTable->size()-1;
if(thePrimShell <= 0) {
G4cerr<<"*** Unvalid Primary shell: "<<thePrimShell<<G4endl;
return FALSE;
}
if(thePrimShell <= (*(*(*TransitionTable)[maxNumOfShells])[0])[0]){
while(thePrimShell != (*(*(*TransitionTable)[ShellNum])[0])[0]){
if(ShellNum == maxNumOfShells){
break;
}
ShellNum++;
}
// TransProb is the index of the loop and of the table of transition. it starts from 1
// because the first element of the data table is the primary shell id number and not a
// transition probability: it must not be added to TotalSum.
G4int TransProb = 1;
// Include non-radiative transitions (vl):
//// for(TransProb = 1; TransProb < (*(*TransitionTable)[ShellNum])[ProbCol]->length(); TransProb++){
//// TotalSum += (*(*(*TransitionTable)[ShellNum])[ProbCol])[TransProb];
//// }
////G4double PartialProb = G4UniformRand()*TotalSum;
////
G4double PartialProb = G4UniformRand();
//vl.
G4double PartSum = 0;
TransProb = 1;
G4int trSize = (*(*TransitionTable)[ShellNum])[ProbCol]->size();
while(TransProb < trSize){
PartSum += (*(*(*TransitionTable)[ShellNum])[ProbCol])[TransProb];
if(PartialProb <= PartSum){
TransParam[0] = (*(*(*TransitionTable)[ShellNum])[SubShellCol])[TransProb];
TransParam[1] = (*(*(*TransitionTable)[ShellNum])[ProbCol])[TransProb];
TransParam[2] = (*(*(*TransitionTable)[ShellNum])[EnergyCol])[TransProb];
ColIsFull = TRUE;
break;
}
TransProb++;
}
}
else{
ColIsFull = FALSE;
}
return ColIsFull;
return ( &particle == G4Gamma::Gamma() );
}
// ..
G4double G4LowEnergyPhotoElectric::GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition*)
{
const G4DynamicParticle* photon = track.GetDynamicParticle();
G4double energy = photon->GetKineticEnergy();
G4Material* material = track.GetMaterial();
size_t materialIndex = material->GetIndex();
G4double meanFreePath;
if (energy > highEnergyLimit)
meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
else meanFreePath = meanFreePathTable->FindValue(energy,materialIndex);
return meanFreePath;
}
void G4LowEnergyPhotoElectric::SetCutForLowEnSecPhotons(G4double cut)
{
cutForLowEnergySecondaryPhotons = cut;
}
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4LowEnergyPolarizedCompton.cc,v 1.5.2.2 2001/06/28 20:19:30 gunter Exp $
// GEANT4 tag $Name: $
// $Id: G4LowEnergyPolarizedCompton.cc,v 1.11 2001/11/07 21:31:16 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// ------------------------------------------------------------
// GEANT 4 class implementation file
@@ -38,6 +38,8 @@
// Temporary protection to avoid crash in the case
// of polarisation || incident photon direction
//
// 17 October 2001 - F.Longo - Revised according to a design iteration
//
// ************************************************************
//
// Corrections by Rui Curado da Silva (2000)
@@ -49,257 +51,88 @@
// --------------------------------------------------------------
#include "G4LowEnergyPolarizedCompton.hh"
#include "G4Electron.hh"
#include "G4EnergyLossTables.hh"
#include "G4Gamma.hh"
#include "G4SecondLevel.hh"
#include "G4PhysicsTable.hh"
#include "G4DataVector.hh"
#include "Randomize.hh"
#include "G4ParticleDefinition.hh"
#include "G4ThreeVector.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ForceCondition.hh"
#include "G4Gamma.hh"
#include "G4Electron.hh"
#include "G4DynamicParticle.hh"
#include "G4VParticleChange.hh"
#include "G4ThreeVector.hh"
#include "G4VCrossSectionHandler.hh"
#include "G4CrossSectionHandler.hh"
#include "G4VEMDataSet.hh"
#include "G4CompositeEMDataSet.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4LogLogInterpolation.hh"
#include "G4VRangeTest.hh"
#include "G4RangeTest.hh"
#include "G4CutsPerMaterialWarning.hh"
// constructor
G4LowEnergyPolarizedCompton::G4LowEnergyPolarizedCompton(const G4String& processName)
: G4VDiscreteProcess(processName),
theCrossSectionTable(0),
theScatteringFunctionTable(0),
theMeanFreePathTable(0),
ZNumVec(0),
lowestEnergyLimit (250*eV), // initialization
highestEnergyLimit(100*GeV),
numbBinTable(200),
meanFreePath(0)
lowEnergyLimit (250*eV), // initialization
highEnergyLimit(100*GeV),
intrinsicLowEnergyLimit(10*eV),
intrinsicHighEnergyLimit(100*GeV)
{
if (verboseLevel>0) {
G4cout << GetProcessName() << " is created "<< G4endl;
G4cout << "LowestEnergy: " << lowestEnergyLimit/keV << "keV ";
G4cout << "HighestEnergy: " << highestEnergyLimit/TeV << "TeV " << G4endl;
}
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
highEnergyLimit > intrinsicHighEnergyLimit)
{
G4Exception("G4LowEnergyPolarizedCompton::G4LowEnergyPolarizedCompton - energy outside intrinsic process validity range");
}
crossSectionHandler = new G4CrossSectionHandler;
G4VDataSetAlgorithm* scatterInterpolation = new G4LogLogInterpolation;
G4String scatterFile = "comp/ce-sf-";
scatterFunctionData = new
G4CompositeEMDataSet(scatterFile,scatterInterpolation,1.,1.);
meanFreePathTable = 0;
rangeTest = new G4RangeTest;
if (verboseLevel > 0)
{
G4cout << GetProcessName() << " is created " << G4endl
<< "Energy range: "
<< lowEnergyLimit / keV << " keV - "
<< highEnergyLimit / GeV << " GeV"
<< G4endl;
}
}
// destructor
G4LowEnergyPolarizedCompton::~G4LowEnergyPolarizedCompton()
{
if (theCrossSectionTable) {
delete theCrossSectionTable;
}
if (theScatteringFunctionTable) {
delete theScatteringFunctionTable;
}
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy();
delete theMeanFreePathTable;
}
if(ZNumVec){
ZNumVec->clear();
delete ZNumVec;
}
delete meanFreePathTable;
delete crossSectionHandler;
delete scatterFunctionData;
delete rangeTest;
}
void G4LowEnergyPolarizedCompton::BuildPhysicsTable(const G4ParticleDefinition& GammaType){
BuildZVec();
// Build microscopic cross section table and mean free path table
BuildCrossSectionTable();
// Build mean free path table for the Compton Scattering process
BuildMeanFreePathTable();
// build the scattering function table
BuildScatteringFunctionTable();
}
void G4LowEnergyPolarizedCompton::BuildCrossSectionTable(){
// BUILD THE CS TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC
if (theCrossSectionTable) {
delete theCrossSectionTable;
}
void G4LowEnergyPolarizedCompton::BuildPhysicsTable(const G4ParticleDefinition& photon)
{
theCrossSectionTable = new G4SecondLevel();
G4int dataNum = 2;
for(size_t tableInd = 0; tableInd < ZNumVec->size(); tableInd++){
G4int atomInd = (G4int) (*ZNumVec)[tableInd];
G4FirstLevel* oneAtomCS = util.BuildFirstLevelTables(atomInd, dataNum, "comp/ce-cs-");
// theCrossSectionTable->insert(oneAtomCS);
theCrossSectionTable->push_back(oneAtomCS);
}//end for on atoms
G4CutsPerMaterialWarning warning;
warning.PrintWarning(&photon);
crossSectionHandler->Clear();
G4String crossSectionFile = "comp/ce-cs-";
crossSectionHandler->LoadData(crossSectionFile);
delete meanFreePathTable;
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
}
void G4LowEnergyPolarizedCompton::BuildScatteringFunctionTable(){
// BUILD THE SF TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC
if (theScatteringFunctionTable) {
delete theScatteringFunctionTable;
}
theScatteringFunctionTable = new G4SecondLevel();
G4int dataNum = 2;
for(size_t tableInd = 0; tableInd < ZNumVec->size(); tableInd++){
G4int atomInd = (G4int) (*ZNumVec)[tableInd];
G4FirstLevel* oneAtomSF = util.BuildFirstLevelTables(atomInd, dataNum, "comp/ce-sf-");
// theScatteringFunctionTable->insert(oneAtomSF);
theScatteringFunctionTable->push_back(oneAtomSF);
}//end for on atoms
}
void G4LowEnergyPolarizedCompton::BuildZVec(){
// vector mapping the elements in the material table
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
if(ZNumVec){
ZNumVec->clear();
delete ZNumVec;
}
ZNumVec = new G4DataVector();
for (G4int J=0 ; J < numOfMaterials; J++){
const G4Material* material= (*theMaterialTable)[J];
const G4ElementVector* theElementVector = material->GetElementVector();
const G4int numberOfElements = material->GetNumberOfElements() ;
for (G4int iel=0; iel<numberOfElements; iel++ ){
G4double Zel = (*theElementVector)(iel)->GetZ();
if(!(ZNumVec->contains(Zel))){
ZNumVec->push_back(Zel);
} else{
continue;
}
}
}
}
void G4LowEnergyPolarizedCompton::BuildMeanFreePathTable(){
// used log-log interpolation instead of linear interpolation to build the MFP
// as reported in the stepanek paper
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy(); delete theMeanFreePathTable; }
// material
G4double NumbOfMaterials = G4Material::GetNumberOfMaterials();
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
G4Material* material;
// MeanFreePath
G4double lowEdgeEnergy, value;
theMeanFreePathTable = new G4PhysicsTable(NumbOfMaterials);
G4PhysicsLogVector* ptrVector;
for ( G4int J = 0 ; J < NumbOfMaterials; J++ ) { // For each material
//create physics vector then fill it ....
ptrVector = new G4PhysicsLogVector(lowestEnergyLimit, highestEnergyLimit, numbBinTable);
material = (*theMaterialTable)(J);
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
for ( G4int i = 0 ; i < numbBinTable ; i++ ){
//For each energy
lowEdgeEnergy = ptrVector->GetLowEdgeEnergy(i);
const G4double bigPath = DBL_MAX;
G4double sigma = 0. ;
for ( size_t k=0 ; k < material->GetNumberOfElements() ; k++ ){
G4int atomIndex = (G4int) (*theElementVector)(k)->GetZ();
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(atomIndex)];
G4double interCrsSec = util.DataLogInterpolation(lowEdgeEnergy,
(*(*oneAtomCS)[0]),
(*(*oneAtomCS)[1]))*barn;
sigma += theAtomNumDensityVector[k]*interCrsSec;
}
value = sigma<=0.0 ? bigPath : 1./sigma ;
ptrVector->PutValue( i , value ) ;
}
theMeanFreePathTable->insertAt( J , ptrVector );
}
}
G4Element* G4LowEnergyPolarizedCompton::SelectRandomAtom(const G4DynamicParticle* aDynamicGamma,
G4Material* aMaterial){
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE MODIFIED TO USE
// LIVERMORE DATA (using log-log interpolation as reported in stepanek paper)
// select randomly 1 element within the material
G4double gammaEnergy = aDynamicGamma->GetKineticEnergy();
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
if (NumberOfElements == 1) return (*theElementVector)(0);
const G4double* theAtomNumDensityVector = aMaterial->GetAtomicNumDensityVector();
G4double partialSumSigma = 0.;
G4double rval = 0;
rval = G4UniformRand()/meanFreePath;
for ( G4int i=0 ; i < NumberOfElements ; i++ ){
G4double crossSection;
if (gammaEnergy < lowestEnergyLimit)
crossSection = 0. ;
else {
if (gammaEnergy > highestEnergyLimit) gammaEnergy = 0.99*highestEnergyLimit ;
G4int atomIndex = (G4int) (*theElementVector)(i)->GetZ();
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(atomIndex)];
crossSection = util.DataLogInterpolation(gammaEnergy,
(*(*oneAtomCS)[0]),
(*(*oneAtomCS)[1]))*barn;
}
partialSumSigma += theAtomNumDensityVector[i] * crossSection;
if(rval <= partialSumSigma) return ((*theElementVector)(i));
}
return (*theElementVector)(0);
}
G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTrack,
const G4Step& aStep)
{
@@ -312,261 +145,211 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
aParticleChange.Initialize(aTrack);
// Dynamic particle quantities
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
G4double gammaEnergy0 = aDynamicGamma->GetKineticEnergy();
G4ThreeVector gammaPolarization0 = aDynamicGamma->GetPolarization();
G4double polarisation = gammaPolarization0.mag();
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
G4double gammaEnergy0 = incidentPhoton->GetKineticEnergy();
G4ThreeVector gammaPolarization0 = incidentPhoton->GetPolarization();
// Check magnitude of polarisation vector
G4bool isPolarised = false;
if (polarisation > 0. && polarisation <= 1.)
{
isPolarised = true;
}
// gammaPolarization0 = gammaPolarization0.unit(); //
// Temporary protection: a polarisation parallel to the
// direction causes problems; in that case apply the regular LowEnergyCompton algorithm
G4ThreeVector gammaDirection = aDynamicGamma->GetMomentumDirection();
// Protection: a polarisation parallel to the
// direction causes problems;
// in that case find a random polarization
G4ThreeVector gammaDirection = incidentPhoton->GetMomentumDirection();
G4double scalarproduct = gammaPolarization0.dot(gammaDirection);
G4double angle = gammaPolarization0.angle(gammaDirection);
if (angle == 0.)
if (scalarproduct != 0. || angle == 0)
{
isPolarised = false;
// isPolarised = false;
gammaPolarization0 = SetRandomPolarization(gammaDirection);
}
// End of temporary protection
// End of Protection
// G4double polarisation = gammaPolarization0.mag();
// Within energy limit?
if(gammaEnergy0 <= lowestEnergyLimit)
{
aParticleChange.SetStatusChange(fStopAndKill);
aParticleChange.SetEnergyChange(0.);
aParticleChange.SetLocalEnergyDeposit(gammaEnergy0);
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
}
if(gammaEnergy0 <= lowEnergyLimit)
{
aParticleChange.SetStatusChange(fStopAndKill);
aParticleChange.SetEnergyChange(0.);
aParticleChange.SetLocalEnergyDeposit(gammaEnergy0);
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
}
// Select randomly one element
G4Material* aMaterial = aTrack.GetMaterial();
G4Element* theElement = SelectRandomAtom(aDynamicGamma, aMaterial);
G4int elementZ = (G4int) theElement->GetZ();
G4double E0_m = gammaEnergy0 / electron_mass_c2 ;
G4ThreeVector gammaDirection0 = incidentPhoton->GetMomentumDirection();
G4ThreeVector gammaDirection0 = aDynamicGamma->GetMomentumDirection();
// Select randomly one element in the current material
G4Material* material = aTrack.GetMaterial();
G4int Z = crossSectionHandler->SelectRandomAtom(material,gammaEnergy0);
// Sample the energy and the polarization of the scattered photon
G4double epsilon, epsilonSq, onecost, sinThetaSqr, greject ;
G4double epsilon0 = 1./(1. + 2*E0_m);
G4double epsilon0Sq = epsilon0*epsilon0;
G4double alpha1 = - log(epsilon0);
G4double alpha2 = 0.5*(1.- epsilon0Sq);
G4double ScatteringFunction;
G4double x;
G4double wlGamma = h_Planck*c_light/gammaEnergy0;
G4double gammaEnergy1;
G4ThreeVector gammaDirection1;
// if (isPolarised) // apply Polarized Condition
// {
if (isPolarised)
do {
if ( alpha1/(alpha1+alpha2) > G4UniformRand() )
{
epsilon = exp(-alpha1*G4UniformRand());
epsilonSq = epsilon*epsilon;
}
else
{
epsilonSq = epsilon0Sq + (1.- epsilon0Sq)*G4UniformRand();
epsilon = sqrt(epsilonSq);
}
onecost = (1.- epsilon)/(epsilon*E0_m);
sinThetaSqr = onecost*(2.-onecost);
// Protection
if (sinThetaSqr > 1.)
{
if (verboseLevel>0) G4cout
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
<< "sin(theta)**2 = "
<< sinThetaSqr
<< "; set to 1"
<< G4endl;
sinThetaSqr = 1.;
}
if (sinThetaSqr < 0.)
{
if (verboseLevel>0) G4cout
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
<< "sin(theta)**2 = "
<< sinThetaSqr
<< "; set to 0"
<< G4endl;
sinThetaSqr = 0.;
}
// End protection
G4double x = sqrt(onecost/2.) / (wlGamma/cm);;
G4double scatteringFunction = scatterFunctionData->FindValue(x,Z-1);
greject = (1. - epsilon*sinThetaSqr/(1.+ epsilonSq))*scatteringFunction;
//greject = 1. - epsilon*sinThetaSqr/(1.+ epsilonSq);
} while(greject < G4UniformRand()*Z);
//(greject < G4UniformRand());
// ****************************************************
// Phi determination
// ****************************************************
G4double phi = SetPhi(epsilon,sinThetaSqr);
//
// scattered gamma angles. ( Z - axis along the parent gamma)
//
G4double cosTheta = 1. - onecost;
// Protection
if (cosTheta > 1.)
{
do {
if ( alpha1/(alpha1+alpha2) > G4UniformRand() )
{
epsilon = exp(-alpha1*G4UniformRand());
epsilonSq = epsilon*epsilon;
}
else
{
epsilonSq = epsilon0Sq + (1.- epsilon0Sq)*G4UniformRand();
epsilon = sqrt(epsilonSq);
}
onecost = (1.- epsilon)/(epsilon*E0_m);
sinThetaSqr = onecost*(2.-onecost);
// Protection
if (sinThetaSqr > 1.)
{
if (verboseLevel>0) G4cout
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
<< "sin(theta)**2 = "
<< sinThetaSqr
<< "; set to 1"
<< G4endl;
sinThetaSqr = 1.;
}
if (sinThetaSqr < 0.)
{
if (verboseLevel>0) G4cout
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
<< "sin(theta)**2 = "
<< sinThetaSqr
<< "; set to 0"
<< G4endl;
sinThetaSqr = 0.;
}
// End protection
greject = 1. - epsilon*sinThetaSqr/(1.+ epsilonSq);
} while (greject < G4UniformRand());
if (verboseLevel>0) G4cout
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
<< "cosTheta = "
<< cosTheta
<< "; set to 1"
<< G4endl;
cosTheta = 1.;
}
if (cosTheta < -1.)
{
if (verboseLevel>0) G4cout
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
<< "cosTheta = "
<< cosTheta
<< "; set to -1"
<< G4endl;
cosTheta = -1.;
}
// End protection
G4double sinTheta = sqrt (sinThetaSqr);
// Protection
if (sinTheta > 1.)
{
if (verboseLevel>0) G4cout
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
<< "sinTheta = "
<< sinTheta
<< "; set to 1"
<< G4endl;
sinTheta = 1.;
}
if (sinTheta < -1.)
{
if (verboseLevel>0) G4cout
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
<< "sinTheta = "
<< sinTheta
<< "; set to -1"
<< G4endl;
sinTheta = -1.;
}
// End protection
// ****************************************************
// Phi determination
// ****************************************************
G4double dirx = sinTheta*cos(phi);
G4double diry = sinTheta*sin(phi);
G4double dirz = cosTheta ;
//
// update G4VParticleChange for the scattered photon
//
gammaEnergy1 = epsilon*gammaEnergy0;
G4double phi = SetPhi(epsilon,sinThetaSqr);
//
// scattered gamma angles. ( Z - axis along the parent gamma)
//
G4double cosTheta = 1. - onecost;
// Protection
if (cosTheta > 1.)
{
if (verboseLevel>0) G4cout
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
<< "cosTheta = "
<< cosTheta
<< "; set to 1"
<< G4endl;
cosTheta = 1.;
}
if (cosTheta < -1.)
{
if (verboseLevel>0) G4cout
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
<< "cosTheta = "
<< cosTheta
<< "; set to -1"
<< G4endl;
cosTheta = -1.;
}
// End protection
G4double sinTheta = sqrt (sinThetaSqr);
// Protection
if (sinTheta > 1.)
{
if (verboseLevel>0) G4cout
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
<< "sinTheta = "
<< sinTheta
<< "; set to 1"
<< G4endl;
sinTheta = 1.;
}
if (sinTheta < -1.)
{
if (verboseLevel>0) G4cout
<< " -- Warning -- G4LowEnergyPolarizedCompton::PostStepDoIt "
<< "sinTheta = "
<< sinTheta
<< "; set to -1"
<< G4endl;
sinTheta = -1.;
}
// End protection
G4double dirx = sinTheta*cos(phi);
G4double diry = sinTheta*sin(phi);
G4double dirz = cosTheta ;
//
// update G4VParticleChange for the scattered gamma
//
gammaEnergy1 = epsilon*gammaEnergy0;
// New polarization
G4ThreeVector gammaPolarization1 = SetNewPolarization(epsilon,
sinThetaSqr,
phi,
cosTheta);
// Set new direction
//G4ThreeVector tmpDirection1( dirx,diry,dirz );
G4ParticleMomentum tmpDirection1( dirx,diry,dirz );
gammaDirection1 = tmpDirection1;
// Change reference frame.
SystemOfRefChange(gammaDirection0,gammaDirection1,
gammaPolarization0,gammaPolarization1);
if (gammaEnergy1 > 0.)
{
aParticleChange.SetEnergyChange( gammaEnergy1 ) ;
}
else
{
aParticleChange.SetEnergyChange(0.) ;
aParticleChange.SetStatusChange(fStopAndKill);
}
// New polarization
G4ThreeVector gammaPolarization1 = SetNewPolarization(epsilon,
sinThetaSqr,
phi,
cosTheta);
// Set new direction
//G4ThreeVector tmpDirection1( dirx,diry,dirz );
G4ParticleMomentum tmpDirection1( dirx,diry,dirz );
gammaDirection1 = tmpDirection1;
// Change reference frame.
SystemOfRefChange(gammaDirection0,gammaDirection1,
gammaPolarization0,gammaPolarization1);
if (gammaEnergy1 > 0.)
{
aParticleChange.SetEnergyChange( gammaEnergy1 ) ;
}
else
{
// Temporary, same algorithm as G4LowEnergyCompton
do{
if ( alpha1/(alpha1+alpha2) > G4UniformRand()){
epsilon = exp(-alpha1*G4UniformRand()); // pow(epsilon0,G4UniformRand())
epsilonSq = epsilon*epsilon;
}
else{
epsilonSq = epsilon0Sq + (1.- epsilon0Sq)*G4UniformRand();
epsilon = sqrt(epsilonSq);
}
onecost = (1.- epsilon)/(epsilon*E0_m);
sinThetaSqr = onecost*(2.-onecost);
x = sqrt(onecost/2)/(wlGamma/cm);
const G4FirstLevel* oneAtomSF
= (*theScatteringFunctionTable)[ZNumVec->index(elementZ)];
ScatteringFunction = util.DataLogInterpolation(x, (*(*oneAtomSF)[0]),
(*(*oneAtomSF)[1]));
greject = (1. - epsilon*sinThetaSqr/(1.+ epsilonSq))*ScatteringFunction;
} while(greject < G4UniformRand()*elementZ);
G4double cosTheta = 1. - onecost ;
G4double sinTheta = sqrt (sinThetaSqr);
G4double phi = twopi * G4UniformRand() ;
G4double dirx = sinTheta*cos(phi) , diry = sinTheta*sin(phi) , dirz = cosTheta ;
//
// update G4VParticleChange for the scattered gamma
//
G4ThreeVector tmpGammaDirection( dirx,diry,dirz );
gammaDirection1 = tmpGammaDirection;
gammaDirection1.rotateUz(gammaDirection0);
aParticleChange.SetMomentumChange( gammaDirection1 ) ;
gammaEnergy1 = epsilon*gammaEnergy0;
if (gammaEnergy1 > 0.)
{
aParticleChange.SetEnergyChange( gammaEnergy1 ) ;
}
else
{
aParticleChange.SetEnergyChange(0.) ;
aParticleChange.SetStatusChange(fStopAndKill);
}
{
aParticleChange.SetEnergyChange(0.) ;
aParticleChange.SetStatusChange(fStopAndKill);
}
//
@@ -575,37 +358,27 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
G4double ElecKineEnergy = gammaEnergy0 - gammaEnergy1 ;
if((G4EnergyLossTables::GetRange(G4Electron::Electron(),
ElecKineEnergy,aMaterial)>aStep.GetPostStepPoint()->GetSafety())
||
(ElecKineEnergy >
(G4Electron::Electron()->GetCutsInEnergy())[aMaterial->GetIndex()]))
// Generate the electron only if with large enough range w.r.t. cuts and safety
G4double safety = aStep.GetPostStepPoint()->GetSafety();
if (rangeTest->Escape(G4Electron::Electron(),material,ElecKineEnergy,safety))
{
G4double ElecMomentum = sqrt(ElecKineEnergy*(ElecKineEnergy+2.*electron_mass_c2));
G4ThreeVector ElecDirection (
(gammaEnergy0*gammaDirection0 - gammaEnergy1*gammaDirection1)*(1./ElecMomentum) );
// create G4DynamicParticle object for the electron.
G4DynamicParticle* aElectron= new G4DynamicParticle (G4Electron::Electron(),
ElecDirection,
ElecKineEnergy) ;
aParticleChange.SetNumberOfSecondaries(1) ;
aParticleChange.AddSecondary( aElectron ) ;
aParticleChange.SetLocalEnergyDeposit (0.) ;
G4ThreeVector ElecDirection((gammaEnergy0 * gammaDirection0 -
gammaEnergy1 * gammaDirection1) * (1./ElecMomentum));
G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),ElecDirection,ElecKineEnergy) ;
aParticleChange.SetNumberOfSecondaries(1);
aParticleChange.AddSecondary(electron);
aParticleChange.SetLocalEnergyDeposit(0.);
}
else
{
aParticleChange.SetNumberOfSecondaries(0) ;
aParticleChange.SetLocalEnergyDeposit (ElecKineEnergy) ;
aParticleChange.SetNumberOfSecondaries(0);
aParticleChange.SetLocalEnergyDeposit(ElecKineEnergy);
}
// --- The end ---
// Reset NbOfInteractionLengthLeft and return aParticleChange
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep);
}
@@ -640,6 +413,44 @@ G4double G4LowEnergyPolarizedCompton::SetPhi(G4double energyRate,
}
G4ThreeVector G4LowEnergyPolarizedCompton::SetPerpendicularVector(G4ThreeVector& a)
{
G4double dx = a.x();
G4double dy = a.y();
G4double dz = a.z();
G4double x = dx < 0.0 ? -dx : dx;
G4double y = dy < 0.0 ? -dy : dy;
G4double z = dz < 0.0 ? -dz : dz;
if (x < y) {
return x < z ? G4ThreeVector(-dy,dx,0) : G4ThreeVector(0,-dz,dy);
}else{
return y < z ? G4ThreeVector(dz,0,-dx) : G4ThreeVector(-dy,dx,0);
}
}
G4ThreeVector G4LowEnergyPolarizedCompton::SetRandomPolarization(G4ThreeVector& direction0)
{
G4ThreeVector d0 = direction0.unit();
G4ThreeVector a1 = SetPerpendicularVector(d0); //different orthogonal
G4ThreeVector a0 = a1.unit(); // unit vector
G4double rand1 = G4UniformRand();
G4double angle = twopi*rand1; // random polar angle
G4ThreeVector b0 = d0.cross(a0); // cross product
G4ThreeVector c;
c.setX(cos(angle)*(a0.x())+sin(angle)*b0.x());
c.setY(cos(angle)*(a0.y())+sin(angle)*b0.y());
c.setZ(cos(angle)*(a0.z())+sin(angle)*b0.z());
G4ThreeVector c0 = c.unit();
return c0;
}
G4ThreeVector G4LowEnergyPolarizedCompton::SetNewPolarization(G4double epsilon,
G4double sinSqrTh,
G4double phi,
@@ -683,9 +494,9 @@ G4ThreeVector G4LowEnergyPolarizedCompton::SetNewPolarization(G4double epsilon,
G4double xParallel = normalisation*cosBeta;
G4double yParallel = -(sinSqrTh*cosPhi*sinPhi)*cosBeta/normalisation;
G4double zParallel = -(cosTheta*sinTheta*cosPhi)*cosBeta/normalisation;
G4double zParallel = -(costheta*sinTheta*cosPhi)*cosBeta/normalisation;
G4double xPerpendicular = 0.;
G4double yPerpendicular = (cosTheta)*sinBeta/normalisation;
G4double yPerpendicular = (costheta)*sinBeta/normalisation;
G4double zPerpendicular = -(sinTheta*sinPhi)*sinBeta/normalisation;
G4double xTotal = (xParallel + xPerpendicular);
@@ -737,7 +548,9 @@ void G4LowEnergyPolarizedCompton::SystemOfRefChange
}
// Added protection
G4double psi = 0;
if (sinPsi < 0.) psi = -pi/2.;
if (sinPsi > 0.) psi = pi/2.;
@@ -768,32 +581,19 @@ G4bool G4LowEnergyPolarizedCompton::IsApplicable(const G4ParticleDefinition& par
}
G4double G4LowEnergyPolarizedCompton::GetMeanFreePath(const G4Track& aTrack, G4double, G4ForceCondition*)
G4double G4LowEnergyPolarizedCompton::GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition*)
{
// returns the gamma mean free path in GEANT4 internal units
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
G4double gammaEnergy = aDynamicGamma->GetKineticEnergy();
G4Material* aMaterial = aTrack.GetMaterial();
// G4bool isOutRange ;
if (gammaEnergy > highestEnergyLimit)
{
meanFreePath = DBL_MAX;
}
else if(gammaEnergy < lowestEnergyLimit)
{
meanFreePath = DBL_MIN;
}
else
{
meanFreePath = util.DataLogInterpolation(gammaEnergy,
aMaterial->GetIndex(),
theMeanFreePathTable);
}
const G4DynamicParticle* photon = track.GetDynamicParticle();
G4double energy = photon->GetKineticEnergy();
G4Material* material = track.GetMaterial();
size_t materialIndex = material->GetIndex();
G4double meanFreePath;
if (energy > highEnergyLimit) meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
else meanFreePath = meanFreePathTable->FindValue(energy,materialIndex);
return meanFreePath;
}
@@ -810,4 +610,3 @@ G4double G4LowEnergyPolarizedCompton::GetMeanFreePath(const G4Track& aTrack, G4d
@@ -20,363 +20,191 @@
// * statement, and all its terms. *
// ********************************************************************
//
// --------------------------------------------------------------------
//
// $Id: G4LowEnergyRayleigh.cc,v 1.22.2.2 2001/06/28 20:19:30 gunter Exp $
// GEANT4 tag $Name: $
// $Id: G4LowEnergyRayleigh.cc,v 1.28 2001/11/07 21:31:16 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
// CERN Geneva Switzerland
// Author: A. Forti
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// ------------ G4LowEnergyRayleigh physics process --------
// by Alessandra Forti, November 1998
// **************************************************************
// History:
// --------
// Added Livermore data table construction methods A. Forti
// Added BuildMeanFreePath A. Forti
// Added PostStepDoIt A. Forti
// Added SelectRandomAtom A. Forti
// Added map of the elements A.Forti
// 24.04.01 V.Ivanchenko remove RogueWave
// --------------------------------------------------------------
// 11.08.2001 MGP - Major revision according to a design iteration
// 06.10.2001 MGP - Added strategy to test range for secondary generation
//
// --------------------------------------------------------------------
// This Class Header
#include "G4LowEnergyRayleigh.hh"
// Collaborating Class Headers
#include "G4EnergyLossTables.hh"
#include "Randomize.hh"
#include "G4ParticleDefinition.hh"
#include "G4Track.hh"
#include "G4Step.hh"
#include "G4ForceCondition.hh"
#include "G4Gamma.hh"
#include "G4Electron.hh"
#include "G4DynamicParticle.hh"
#include "G4VParticleChange.hh"
#include "G4ThreeVector.hh"
#include "G4VCrossSectionHandler.hh"
#include "G4CrossSectionHandler.hh"
#include "G4VEMDataSet.hh"
#include "G4CompositeEMDataSet.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4LogLogInterpolation.hh"
#include "G4CutsPerMaterialWarning.hh"
// constructor
G4LowEnergyRayleigh::G4LowEnergyRayleigh(const G4String& processName)
: G4VDiscreteProcess(processName),
theCrossSectionTable(0),
theFormFactorTable(0),
theMeanFreePathTable(0),
ZNumVec(0),
lowestEnergyLimit (250*eV), // initialization
highestEnergyLimit(100*GeV),
NumbBinTable(200),
MeanFreePath(0)
lowEnergyLimit(250*eV),
highEnergyLimit(100*GeV),
intrinsicLowEnergyLimit(10*eV),
intrinsicHighEnergyLimit(100*GeV)
{
if (verboseLevel>0) {
G4cout << GetProcessName() << " is created "<< G4endl;
G4cout << "lowestEnergy: " << lowestEnergyLimit/keV << "keV ";
G4cout << "highestEnergy: " << highestEnergyLimit/TeV << "TeV " << G4endl;
}
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
highEnergyLimit > intrinsicHighEnergyLimit)
{
G4Exception("G4LowEnergyRayleigh::G4LowEnergyRayleigh - energy limit outside intrinsic process validity range");
}
crossSectionHandler = new G4CrossSectionHandler();
G4VDataSetAlgorithm* ffInterpolation = new G4LogLogInterpolation;
G4String formFactorFile = "rayl/re-ff-";
formFactorData = new G4CompositeEMDataSet(formFactorFile,ffInterpolation,1.,1.);
meanFreePathTable = 0;
if (verboseLevel > 0)
{
G4cout << GetProcessName() << " is created " << G4endl
<< "Energy range: "
<< lowEnergyLimit / keV << " keV - "
<< highEnergyLimit / GeV << " GeV"
<< G4endl;
}
}
// destructor
G4LowEnergyRayleigh::~G4LowEnergyRayleigh()
{
if (theCrossSectionTable) {
delete theCrossSectionTable;
}
if(theFormFactorTable){
delete theFormFactorTable;
}
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy();
delete theMeanFreePathTable;
}
if(ZNumVec){
ZNumVec->clear();
delete ZNumVec;
}
delete meanFreePathTable;
delete crossSectionHandler;
delete formFactorData;
}
// methods.............................................................................
void G4LowEnergyRayleigh::BuildPhysicsTable(const G4ParticleDefinition& GammaType){
BuildZVec();
// Build microscopic cross section tables for the Rayleigh process
BuildCrossSectionTable();
void G4LowEnergyRayleigh::BuildPhysicsTable(const G4ParticleDefinition& photon)
{
// Build mean free path table for the Rayleigh Scattering process
BuildMeanFreePathTable();
// build the scattering function table
BuildFormFactorTable();
}
// CONSTRUCT THE CS TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC USING EPDL97 DATA
void G4LowEnergyRayleigh::BuildCrossSectionTable(){
if (theCrossSectionTable) {
delete theCrossSectionTable;
}
G4CutsPerMaterialWarning warning;
warning.PrintWarning(&photon);
theCrossSectionTable = new G4SecondLevel();
G4int dataNum = 2;
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
G4FirstLevel* oneAtomCS = util.BuildFirstLevelTables(AtomInd, dataNum, "rayl/re-cs-");
// theCrossSectionTable->insert(oneAtomCS);
theCrossSectionTable->push_back(oneAtomCS);
}//end for on atoms
}
// BUILD THE FF TABLE FOR THE ELEMENTS MAPPED IN ZNUMVEC USING EPDL97 DATA
void G4LowEnergyRayleigh::BuildFormFactorTable(){
if (theFormFactorTable) {
delete theFormFactorTable;
}
crossSectionHandler->Clear();
G4String crossSectionFile = "rayl/re-cs-";
crossSectionHandler->LoadData(crossSectionFile);
theFormFactorTable = new G4SecondLevel();
G4int dataNum = 2;
for(size_t TableInd = 0; TableInd < ZNumVec->size(); TableInd++){
G4int AtomInd = (G4int) (*ZNumVec)[TableInd];
G4FirstLevel* oneAtomFF = util.BuildFirstLevelTables(AtomInd, dataNum, "rayl/re-ff-");
// theFormFactorTable->insert(oneAtomFF);
theFormFactorTable->push_back(oneAtomFF);
}//end for on atoms
}
// vector mapping the elements in the material table
void G4LowEnergyRayleigh::BuildZVec(){
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
if(ZNumVec){
ZNumVec->clear();
delete ZNumVec;
}
ZNumVec = new G4DataVector();
for (G4int J=0 ; J < numOfMaterials; J++){
const G4Material* material= (*theMaterialTable)[J];
const G4ElementVector* theElementVector = material->GetElementVector();
const G4int NumberOfElements = material->GetNumberOfElements() ;
for (G4int iel=0; iel<NumberOfElements; iel++ ){
G4double Zel = (*theElementVector)(iel)->GetZ();
if(ZNumVec->contains(Zel) == FALSE){
ZNumVec->push_back(Zel);
} else{
continue;
}
}
}
delete meanFreePathTable;
meanFreePathTable = crossSectionHandler->BuildMeanFreePathForMaterials();
}
G4VParticleChange* G4LowEnergyRayleigh::PostStepDoIt(const G4Track& aTrack, const G4Step& aStep){
//
// The scattered gamma energy is sampled according to Form Factors
// multiplied by the Rayleigh distribution with a pure rejection technique.
// EGS4 W.R. Nelson et al. The EGS4 Code System. SLAC-Report-265 , December 1985
// Expression of the angular distribution as Rayleigh distribution and Form factors
// is taken from D. E. Cullen "A simple model of photon transport" Nucl. Instr. Meth.
// Phys. Res. B 101 (1995). Method of sampling with form factors is different.
// Reference to the article is from J. Stepanek New Photon, Positron
// and Electron Interaction Data for GEANT in Energy Range from 1 eV to 10
// TeV (draft).
G4VParticleChange* G4LowEnergyRayleigh::PostStepDoIt(const G4Track& aTrack,
const G4Step& aStep)
{
// The scattered gamma energy is sampled according to Form Factors
// multiplied by the Rayleigh distribution with a pure rejection technique.
// EGS4 W.R. Nelson et al. The EGS4 Code System. SLAC-Report-265 , December 1985
// Expression of the angular distribution as Rayleigh distribution and
// Form factors is taken from D. E. Cullen "A simple model of photon transport"
// NIM B Phys. 101 (1995). Method of sampling with form factors is different.
// Reference to the article is from J. Stepanek New Photon, Positron
// and Electron Interaction Data for GEANT in Energy Range from 1 eV to 10 TeV
// (draft).
aParticleChange.Initialize(aTrack);
// Dynamic particle quantities
const G4DynamicParticle* aDynamicGamma = aTrack.GetDynamicParticle();
G4double GammaEnergy0 = aDynamicGamma->GetKineticEnergy();
if(GammaEnergy0 <= lowestEnergyLimit){
aParticleChange.SetStatusChange(fStopAndKill);
aParticleChange.SetEnergyChange(0.);
aParticleChange.SetLocalEnergyDeposit(GammaEnergy0);
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
}
// G4double E0_m = GammaEnergy0 / electron_mass_c2 ;
G4ParticleMomentum GammaDirection0 = aDynamicGamma->GetMomentumDirection();
const G4DynamicParticle* incidentPhoton = aTrack.GetDynamicParticle();
G4double photonEnergy0 = incidentPhoton->GetKineticEnergy();
// Select randomly one element
G4Material* aMaterial = aTrack.GetMaterial();
// const G4int numOfElem = aMaterial->GetNumberOfElements();
G4Element* theElement = SelectRandomAtom(aDynamicGamma, aMaterial);
if (photonEnergy0 <= lowEnergyLimit)
{
aParticleChange.SetStatusChange(fStopAndKill);
aParticleChange.SetEnergyChange(0.);
aParticleChange.SetLocalEnergyDeposit(photonEnergy0);
return G4VDiscreteProcess::PostStepDoIt(aTrack,aStep);
}
// G4double e0m = photonEnergy0 / electron_mass_c2 ;
G4ParticleMomentum photonDirection0 = incidentPhoton->GetMomentumDirection();
// Select randomly one element in the current material
G4Material* material = aTrack.GetMaterial();
G4int Z = crossSectionHandler->SelectRandomAtom(material,photonEnergy0);
// sample the energy of the scattered gamma
// Sample the energy of the scattered photon
G4double wlGamma = h_Planck*c_light/GammaEnergy0;
G4int elementZ = (G4int) theElement->GetZ();
// G4double tableIndex = elementZ - 1;
G4double wlPhoton = h_Planck*c_light/photonEnergy0;
G4double Theta, DataFormFactor;
G4double cosTheta, greject;
G4double Theta_Half, x, SinThHalf, RandomFormFactor;
G4double gReject;
G4double randomFormFactor;
G4double cosTheta;
G4double sinTheta;
do{
Theta_Half = G4UniformRand()*pi/2;
SinThHalf = sin(Theta_Half);
x = SinThHalf/(wlGamma/cm);
const G4FirstLevel* oneAtomFF
= (*theFormFactorTable)[ZNumVec->index(elementZ)];
DataFormFactor = util.DataLogInterpolation(x, (*(*oneAtomFF)[0]),
(*(*oneAtomFF)[1]));
RandomFormFactor = G4UniformRand()*elementZ*elementZ;
Theta = Theta_Half*2;
cosTheta = cos(Theta);
sinTheta = sin(Theta);
G4double sqr_rayl = 1+cosTheta*cosTheta;
greject = sqr_rayl*DataFormFactor*DataFormFactor;
}while( greject < RandomFormFactor);
do
{
G4double thetaHalf = G4UniformRand() * pi / 2.;
G4double sinThetaHalf = sin(thetaHalf);
G4double x = sinThetaHalf / (wlPhoton/cm);
G4double dataFormFactor = formFactorData->FindValue(x,Z-1);
randomFormFactor = G4UniformRand() * Z * Z;
G4double theta = thetaHalf*2;
cosTheta = cos(theta);
sinTheta = sin(theta);
G4double sqrRayl = 1 + cosTheta * cosTheta;
gReject = sqrRayl * dataFormFactor * dataFormFactor;
} while( gReject < randomFormFactor);
// scattered gamma angles. ( Z - axis along the parent gamma)
G4double Phi = twopi * G4UniformRand() ;
G4double dirx = sinTheta*cos(Phi) , diry = sinTheta*sin(Phi) , dirz = cosTheta ;
// Scattered photon angles. ( Z - axis along the parent photon)
G4double phi = twopi * G4UniformRand() ;
G4double dirX = sinTheta*cos(phi);
G4double dirY = sinTheta*sin(phi);
G4double dirZ = cosTheta;
// update G4VParticleChange for the scattered gamma
G4ThreeVector GammaDirection1(dirx, diry, dirz);
// Update G4VParticleChange for the scattered photon
G4ThreeVector photonDirection1(dirX, dirY, dirZ);
GammaDirection1.rotateUz(GammaDirection0);
aParticleChange.SetEnergyChange(GammaEnergy0);
aParticleChange.SetMomentumChange(GammaDirection1);
photonDirection1.rotateUz(photonDirection0);
aParticleChange.SetEnergyChange(photonEnergy0);
aParticleChange.SetMomentumChange(photonDirection1);
aParticleChange.SetNumberOfSecondaries(0);
#ifdef G4VERBOSE
if(verboseLevel > 15){
G4cout<<"LE Rayleigh PostStepDoIt"<<G4endl;
}
#endif
return G4VDiscreteProcess::PostStepDoIt( aTrack, aStep);
}
// used log-log interpolation instead of linear interpolation to build the MFP
void G4LowEnergyRayleigh::BuildMeanFreePathTable(){
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy(); delete theMeanFreePathTable; }
// material
G4double NumbOfMaterials = G4Material::GetNumberOfMaterials();
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable() ;
G4Material* material;
// MeanFreePath
G4double LowEdgeEnergy, Value;
theMeanFreePathTable = new G4PhysicsTable(NumbOfMaterials);
G4PhysicsLogVector* ptrVector;
for ( G4int J = 0 ; J < NumbOfMaterials; J++ ) { // For each material
//create physics vector then fill it ....
ptrVector = new G4PhysicsLogVector(lowestEnergyLimit, highestEnergyLimit, NumbBinTable);
material = (*theMaterialTable)(J);
const G4ElementVector* theElementVector = material->GetElementVector();
const G4double* theAtomNumDensityVector = material->GetAtomicNumDensityVector();
for ( G4int i = 0 ; i < NumbBinTable ; i++ ){
//For each energy
LowEdgeEnergy = ptrVector->GetLowEdgeEnergy(i);
const G4double BigPath= DBL_MAX;
G4double SIGMA = 0 ;
for ( size_t k=0 ; k < material->GetNumberOfElements() ; k++ ){
// For each element
G4double AtomIndex = (*theElementVector)(k)->GetZ();
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
G4double interCrsSec = util.DataLogInterpolation(LowEdgeEnergy,
(*(*oneAtomCS)[0]),
(*(*oneAtomCS)[1]))*barn;
SIGMA += theAtomNumDensityVector[k]*interCrsSec;
}
Value = SIGMA<=0.0 ? BigPath : 1./SIGMA ;
ptrVector->PutValue( i , Value ) ;
}
theMeanFreePathTable->insertAt( J , ptrVector ) ;
}
return G4VDiscreteProcess::PostStepDoIt(aTrack, aStep);
}
// METHOD BELOW FROM STANDARD E_M PROCESSES CODE MODIFIED TO USE
// LIVERMORE DATA (using log-log interpolation as reported in stepanek paper)
G4Element* G4LowEnergyRayleigh::SelectRandomAtom(const G4DynamicParticle* aDynamicGamma,
G4Material* aMaterial) {
// select randomly 1 element within the material
G4double GammaEnergy = aDynamicGamma->GetKineticEnergy();
const G4int NumberOfElements = aMaterial->GetNumberOfElements();
const G4ElementVector* theElementVector = aMaterial->GetElementVector();
if (NumberOfElements == 1) return (*theElementVector)(0);
const G4double* theAtomNumDensityVector = aMaterial->GetAtomicNumDensityVector();
G4double PartialSumSigma = 0.;
G4double rval = G4UniformRand()/MeanFreePath;
for ( G4int i=0 ; i < NumberOfElements ; i++ ){
G4double crossSection;
if (GammaEnergy < lowestEnergyLimit)
crossSection = 0. ;
else {
if (GammaEnergy > highestEnergyLimit) GammaEnergy = 0.99*highestEnergyLimit ;
G4double AtomIndex = (*theElementVector)(i)->GetZ();
const G4FirstLevel* oneAtomCS
= (*theCrossSectionTable)[ZNumVec->index(AtomIndex)];
crossSection = util.DataLogInterpolation(GammaEnergy,
(*(*oneAtomCS)[0]),
(*(*oneAtomCS)[1]))*barn;
}
PartialSumSigma += theAtomNumDensityVector[i] * crossSection;
if(rval <= PartialSumSigma) return ((*theElementVector)(i));
}
return (*theElementVector)(0);
G4bool G4LowEnergyRayleigh::IsApplicable(const G4ParticleDefinition& particle)
{
return ( &particle == G4Gamma::Gamma() );
}
G4double G4LowEnergyRayleigh::GetMeanFreePath(const G4Track& track,
G4double previousStepSize,
G4ForceCondition*)
{
const G4DynamicParticle* photon = track.GetDynamicParticle();
G4double energy = photon->GetKineticEnergy();
G4Material* material = track.GetMaterial();
size_t materialIndex = material->GetIndex();
G4double meanFreePath;
if (energy > highEnergyLimit) meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
else meanFreePath = meanFreePathTable->FindValue(energy,materialIndex);
return meanFreePath;
}
@@ -1,244 +0,0 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4LowEnergyUtilities.cc,v 1.9.2.1 2001/06/28 19:11:51 gunter Exp $
// GEANT4 tag $Name: $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
//
// File name: G4LowEnergyUtilitie
//
// Author: A.Forti
//
// Creation date: 2 March 1999
//
// Modifications: 16.11.00 MG Pia Replaced HepString with G4String
// 24.04.01 V.Ivanchenko remove RogueWave
//
// --------------------------------------------------------------
// This Class Header
#include "G4LowEnergyUtilities.hh"
// Collaborating Class Headers
#include "G4Element.hh"
#include "G4DynamicParticle.hh"
#include "G4Material.hh"
#include "g4std/fstream"
#include "g4std/fstream"
#include "g4std/strstream"
G4LowEnergyUtilities::G4LowEnergyUtilities()
{}
G4LowEnergyUtilities::~G4LowEnergyUtilities()
{}
G4SecondLevel* G4LowEnergyUtilities::BuildSecondLevelTables(const G4int TableInd,
const G4int ParNum,
const char* prename){
G4String prenameStr(prename);
// HepString name, prenameStr(prename);
char nameChar[100] = {""};
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
if(TableInd != 0){
ost << prenameStr << TableInd << ".dat";
// HepString Znum(TableInd);
// name = prenameStr + Znum + ".dat";
}
else{
ost << prenameStr << ".dat";
// name = prenameStr+ ".dat";
}
G4String name(nameChar);
char* path = getenv("G4LEDATA");
if(!path){
G4String excep = "Error!!! G4LEDATA (Low Energy Electromagnetic processes data directory) environment variable not set";
G4Exception(excep);
}
G4String path_string(path);
G4String dir_file = path_string + "/" + name;
G4std::ifstream file(dir_file);
G4std::filebuf* lsdp = file.rdbuf();
if(!lsdp->is_open()){
G4String excep = "Error!!!! data file: " + dir_file + " NOT found";
G4Exception(excep);
}
oneAtomTable* oneAtomPar = new oneAtomTable();
oneShellTable* oneShellPar = new oneShellTable();
for(G4int j = 0; j < ParNum; j++){
// oneShellPar->insertAt(j,new G4DataVector());
oneShellPar->push_back(new G4DataVector());
}
G4double a = 0;
G4int k = 1, s = 0;
do{
file>>a;
if(a == -1){
if(s == 0){
// oneAtomPar->insert(oneShellPar);
oneAtomPar->push_back(oneShellPar);
oneShellPar = new oneShellTable();
for(G4int j = 0; j < ParNum; j++){
// oneShellPar->insertAt(j,new G4DataVector());
oneShellPar->push_back(new G4DataVector());
}
}
s++;
if(s == ParNum){
s = 0;
}
}
else if(a == -2){
delete oneShellPar;
}
else{
if(k%ParNum != 0){
(*oneShellPar)[k-1]->push_back(a);
k++;
}
else if(k%ParNum == 0){
(*oneShellPar)[k-1]->push_back(a);
k = 1;
}
}
}while(a != -2); //end for on file
file.close();
return oneAtomPar;
}
G4FirstLevel* G4LowEnergyUtilities::BuildFirstLevelTables(const G4int TableInd,
const G4int ParNum,
const char* prename){
G4String prenameStr(prename);
// HepString name, prenameStr(prename);
char nameChar[100] = {""};
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
if(TableInd != 0){
ost << prenameStr << TableInd << ".dat";
// HepString Znum(TableInd);
// name = prenameStr + Znum + ".dat";
}
else{
ost << prenameStr << ".dat";
// name = prenameStr+ ".dat";
}
G4String name(nameChar);
char* path = getenv("G4LEDATA");
if(!path){
G4String excep = "Error!!! G4LEDATA (Low Energy Electromagnetic processes data directory) environment variable not set";
G4Exception(excep);
}
G4String path_string(path);
G4String dir_file = path_string + "/" + name;
G4std::ifstream file(dir_file);
G4std::filebuf* lsdp = file.rdbuf();
if(!lsdp->is_open()){
G4String excep = "Error!!!! data file: " + dir_file + " NOT found";
G4Exception(excep);
}
G4FirstLevel* oneAtomPar = new G4FirstLevel();
for(G4int j = 0; j < ParNum; j++){
// oneAtomPar->insertAt(j,new G4DataVector());
oneAtomPar->push_back(new G4DataVector());
}
G4double a = 0;
G4int k = 1;
do{
file>>a;
if(a == -1 || a == -2){
}
else{
if(k%ParNum != 0){
(*oneAtomPar)[k-1]->push_back(a);
k++;
}
else if(k%ParNum == 0){
(*oneAtomPar)[k-1]->push_back(a);
k = 1;
}
}
}while(a != -2); //end for on file
file.close();
return oneAtomPar;
}
@@ -21,46 +21,31 @@
// ********************************************************************
//
//
// -------------------------------------------------------------------
// GEANT 4 class file
// $Id: G4RangeTest.cc,v 1.4 2001/11/07 20:47:30 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// CERN, Geneva, Switzerland
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// File name: G4ThirdLevel.hh
// History:
// -----------
// 05 Oct 2001 MGP Created
//
// Author: Alessandra Forti (Alessandra.Forti@cern.ch)
//
// Creation date: 1 Giugno 1999
//
// Modifications: 24.04.01 V.Ivanchenko remove RogueWave
//
// -------------------------------------------------------------------
#include "G4ThirdLevel.hh"
#include "G4RangeTest.hh"
#include "G4ParticleDefinition.hh"
#include "G4Material.hh"
#include "G4EnergyLossTables.hh"
G4bool G4RangeTest::Escape(const G4ParticleDefinition* particle,
const G4Material* material,
G4double energy,
G4double safety) const
{
G4double range = G4EnergyLossTables::GetRange(particle,energy,material);
G4double cut = particle->GetRangeThreshold(material);
G4double rMin = G4std::min(cut,safety);
G4bool value = (range > rMin);
G4ThirdLevel::~G4ThirdLevel(){
// this->clearAndDestroy();
this->clear();
return value;
}
G4bool G4ThirdLevel::operator == (const G4ThirdLevel& input) const{
// return( this->entries() == input.entries());
return( this->size() == input.size());
}
G4bool G4ThirdLevel::operator < (const G4ThirdLevel& input) const{
// return(this->entries() < input.entries());
return(this->size() < input.size());
}
@@ -0,0 +1,72 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4SemiLogInterpolation.cc,v 1.3 2001/09/10 18:07:35 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created
//
// -------------------------------------------------------------------
#include "G4SemiLogInterpolation.hh"
// Constructor
G4SemiLogInterpolation::G4SemiLogInterpolation()
{ }
// Destructor
G4SemiLogInterpolation::~G4SemiLogInterpolation()
{ }
G4double G4SemiLogInterpolation::Calculate(G4double x, G4int bin,
const G4DataVector& points,
const G4DataVector& data) const
{
G4int nBins = data.size() - 1;
G4double value = 0.;
if (x < points[0])
{
value = 0.;
}
else if (bin < nBins)
{
G4double e1 = points[bin];
G4double e2 = points[bin+1];
G4double d1 = data[bin];
G4double d2 = data[bin+1];
value = (d1*log10(e2/x) + d2*log10(x/e1)) / log10(e2/e1);
}
else
{
value = data[nBins];
}
return value;
}
@@ -0,0 +1,245 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4ShellData.cc,v 1.4 2001/09/26 21:19:23 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created
//
// -------------------------------------------------------------------
#include "G4ShellData.hh"
#include "G4DataVector.hh"
#include "g4std/fstream"
#include "g4std/strstream"
// Constructor
G4ShellData::G4ShellData(G4int minZ, G4int maxZ)
: zMin(minZ), zMax(maxZ)
{ }
// Destructor
G4ShellData::~G4ShellData()
{
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::iterator pos;
for (pos = idMap.begin(); pos != idMap.end(); pos++)
{
G4DataVector* dataSet = (*pos).second;
delete dataSet;
}
for (pos = bindingMap.begin(); pos != bindingMap.end(); pos++)
{
G4DataVector* dataSet = (*pos).second;
delete dataSet;
}
}
size_t G4ShellData::NumberOfShells(G4int Z) const
{
G4int z = Z - 1;
G4int n = 0;
if (Z>= zMin && Z <= zMax)
{
n = nShells[z];
}
return n;
}
const G4DataVector& G4ShellData::ShellIdVector(G4int Z) const
{
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator pos;
if (Z < zMin || Z > zMax)
G4Exception("G4ShellData::ShellIdVector - Z outside boundaries");
pos = idMap.find(Z);
G4DataVector* dataSet = (*pos).second;
return *dataSet;
}
G4int G4ShellData::ShellId(G4int Z, G4int shellIndex) const
{
G4int n = -1;
if (Z >= zMin && Z <= zMax)
{
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator pos;
pos = idMap.find(Z);
if (pos!= idMap.end())
{
G4DataVector dataSet = *((*pos).second);
G4int nData = dataSet.size();
if (shellIndex >= 0 && shellIndex < nData)
{
n = (G4int) dataSet[shellIndex];
}
}
}
return n;
}
G4double G4ShellData::BindingEnergy(G4int Z, G4int shellIndex) const
{
G4double value = 0.;
if (Z >= zMin && Z <= zMax)
{
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator pos;
pos = bindingMap.find(Z);
if (pos!= bindingMap.end())
{
G4DataVector dataSet = *((*pos).second);
G4int nData = dataSet.size();
if (shellIndex >= 0 && shellIndex < nData)
{
value = dataSet[shellIndex];
}
}
}
return value;
}
void G4ShellData::PrintData() const
{
for (G4int Z = zMin; Z <= zMax; Z++)
{
G4cout << "---- Shell data for Z = "
<< Z
<< " ---- "
<< G4endl;
G4int nSh = nShells[Z-1];
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator posId;
posId = idMap.find(Z);
G4DataVector* ids = (*posId).second;
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::const_iterator posE;
posE = bindingMap.find(Z);
G4DataVector* energies = (*posE).second;
for (G4int i=0; i<nSh; i++)
{
G4int id = (G4int) (*ids)[i];
G4double e = (*energies)[i] / MeV;
G4cout << i <<") Shell id: " << id
<< " - Binding energy = "
<< e << " MeV " << G4endl;
}
G4cout << "-------------------------------------------------"
<< G4endl;
}
}
void G4ShellData::LoadData(const G4String& fileName)
{
// Build the complete string identifying the file with the data set
char nameChar[100] = {""};
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
ost << fileName << ".dat";
G4String name(nameChar);
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = "G4EMDataSet - G4LEDATA environment variable not set";
G4Exception(excep);
}
G4String pathString(path);
G4String dirFile = pathString + name;
G4std::ifstream file(dirFile);
G4std::filebuf* lsdp = file.rdbuf();
if (! (lsdp->is_open()) )
{
G4String excep = "G4ShellData - data file: " + dirFile + " not found";
G4Exception(excep);
}
G4double a = 0;
G4int k = 1;
G4int s = 0;
G4int Z = 1;
G4DataVector* energies = new G4DataVector;
G4DataVector* ids = new G4DataVector;
do {
file >> a;
G4int nColumns = 2;
if (a == -1)
{
if (s == 0)
{
// End of a shell data set
idMap[Z] = ids;
bindingMap[Z] = energies;
G4int n = ids->size();
nShells.push_back(n);
// Start of new shell data set
ids = new G4DataVector;
energies = new G4DataVector;
Z++;
}
s++;
if (s == nColumns)
{
s = 0;
}
}
else if (a == -2)
{
// End of file; delete the empty vectors created when encountering the last -1 -1 row
delete energies;
delete ids;
//nComponents = components.size();
}
else
{
// 1st column is shell id
if(k%nColumns != 0)
{
ids->push_back(a);
k++;
}
else if (k%nColumns == 0)
{
// 2nd column is binding energy
G4double e = a * MeV;
energies->push_back(e);
k = 1;
}
}
} while (a != -2); // end of file
file.close();
}
@@ -0,0 +1,203 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4ShellEMDataSet.cc,v 1.7 2001/10/11 14:10:40 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 1 Aug 2001 MGP Created
// 09.10.01 V.Ivanchenko Add case z=0
//
// -------------------------------------------------------------------
#include "G4ShellEMDataSet.hh"
#include "G4EMDataSet.hh"
#include "G4VDataSetAlgorithm.hh"
#include "g4std/fstream"
#include "g4std/strstream"
G4ShellEMDataSet::G4ShellEMDataSet(G4int Z,
const G4VDataSetAlgorithm* interpolation,
G4double unitE, G4double unitData)
:z(Z), algorithm(interpolation)
{
nComponents = 0;
unit1 = unitE;
unit2 = unitData;
}
G4ShellEMDataSet::G4ShellEMDataSet(G4int Z, const G4String& dataFile,
const G4VDataSetAlgorithm* interpolation,
G4double unitE, G4double unitData)
:z(Z), algorithm(interpolation)
{
nComponents = 0;
unit1 = unitE;
unit2 = unitData;
LoadData(dataFile);
}
G4ShellEMDataSet::~G4ShellEMDataSet()
{
for (size_t i=0; i<nComponents; i++)
{
delete components[i];
}
delete algorithm;
}
G4double G4ShellEMDataSet::FindValue(G4double e, G4int id) const
{
// Returns the sum over the shells corresponding to e
G4double value = 0.;
for (size_t i=0; i<nComponents; i++)
{
G4VEMDataSet* component = components[i];
G4double shellValue = component->FindValue(e);
value = value + shellValue;
}
return value;
}
void G4ShellEMDataSet::PrintData() const
{
G4cout << "The data set has " << nComponents << " components" << G4endl;
for (size_t i=0; i<nComponents; i++)
{
G4cout << "--- Component " << i << " ---" << G4endl;
G4VEMDataSet* component = components[i];
component->PrintData();
}
}
void G4ShellEMDataSet::LoadData(const G4String& fileName)
{
// Build the complete string identifying the file with the data set
char nameChar[100] = {""};
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
if (z != 0) ost << fileName << z << ".dat";
else ost << fileName << ".dat";
G4String name(nameChar);
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = "G4ShellEMDataSet - G4LEDATA environment variable not set";
G4Exception(excep);
}
G4String pathString(path);
G4String dirFile = pathString + "/" + name;
G4std::ifstream file(dirFile);
G4std::filebuf* lsdp = file.rdbuf();
if (! (lsdp->is_open()) )
{
G4String excep = "G4ShellEMDataSet - data file: " + dirFile + " not found";
G4Exception(excep);
}
G4double a = 0;
G4int k = 1;
G4int s = 0;
G4int shellIndex = 0;
G4DataVector* energies = new G4DataVector;
G4DataVector* data = new G4DataVector;
do {
file >> a;
G4int nColumns = 2;
if (a == -1)
{
if (s == 0)
{
// End of a shell data set
G4VDataSetAlgorithm* algo = algorithm->Clone();
G4VEMDataSet* dataSet = new G4EMDataSet(shellIndex,energies,data,algo);
AddComponent(dataSet);
// Start of new shell data set
energies = new G4DataVector;
data = new G4DataVector;
shellIndex++;
}
s++;
if (s == nColumns)
{
s = 0;
}
}
else if (a == -2)
{
// End of file; delete the empty vectors created when encountering the last -1 -1 row
delete energies;
delete data;
}
else
{
// 1st column is energy
if(k%nColumns != 0)
{
G4double e = a * unit1;
energies->push_back(e);
k++;
}
else if (k%nColumns == 0)
{
// 2nd column is cross section
G4double value = a * unit2;
data->push_back(value);
k = 1;
}
}
} while (a != -2); // end of file
file.close();
}
void G4ShellEMDataSet::AddComponent(G4VEMDataSet* component)
{
components.push_back(component);
nComponents++;
}
const G4DataVector& G4ShellEMDataSet::GetEnergies(G4int i) const
{
const G4VEMDataSet* component = GetComponent(i);
return (component->GetEnergies(i));
}
const G4DataVector& G4ShellEMDataSet::GetData(G4int i) const
{
const G4VEMDataSet* component = GetComponent(i);
return (component->GetData(i));
}
@@ -0,0 +1,127 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4ShellVacancy.cc
// GEANT4 tag $Name:
//
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
//
// History:
// -----------
// 21 Sept 2001 Elena Guardincerri Created
//
// -------------------------------------------------------------------
#include "G4ShellVacancy.hh"
#include "G4Material.hh"
#include "G4Poisson.hh"
#include "G4VEMDataSet.hh"
G4ShellVacancy::G4ShellVacancy()
{ }
G4ShellVacancy::~G4ShellVacancy()
{
G4int size = xsis.size();
for (G4int k =0; k<size; k++)
{
delete xsis[k];
xsis[k] = 0;
}
}
void G4ShellVacancy::AddXsiTable(G4VEMDataSet* set)
{
xsis.push_back(set);
}
G4std::vector<G4int> G4ShellVacancy::GenerateNumberOfIonisations(const G4Material*
material,
G4double
incidentEnergy,
G4double eLoss) const
{
G4std::vector<G4int> numberOfIonisations;
size_t numberOfElements = material->GetNumberOfElements();
for (size_t i = 0; i<numberOfElements; i++)
{
const G4Element* element = material->GetElement(i);
G4int averageNumberOfIonisations = AverageNOfIonisations(material,
element,
incidentEnergy,
eLoss);
G4int ionisations = (G4int) G4Poisson(averageNumberOfIonisations);
numberOfIonisations.push_back(ionisations);
}
return numberOfIonisations;
}
G4int G4ShellVacancy::AverageNOfIonisations(const G4Material* material,
const G4Element* element,
G4double energy,
G4double eLoss) const
{
G4int indexOfElementInMaterial= -1;
G4double averageEnergy = energy - eLoss/2.;
G4String elementName = element->GetName();
size_t numberOfElements = material->GetNumberOfElements();
for (size_t i = 0; i<numberOfElements; i++)
{
const G4Element* anElement = material->GetElement(i);
G4String itsName = anElement->GetName();
if (itsName==elementName)
{
indexOfElementInMaterial=i;
break;
}
//else
//{break;}
}
size_t indexInMaterialTable = material->GetIndex();
G4VEMDataSet* aSetOfXsi = xsis[indexInMaterialTable];
G4double aXsi = aSetOfXsi->FindValue(averageEnergy,indexOfElementInMaterial);
G4int averageNumberOfIonisations = (G4int)(aXsi * eLoss);
return averageNumberOfIonisations;
}
@@ -0,0 +1,653 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4VCrossSectionHandler.cc,v 1.8 2001/10/10 16:46:06 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 1 Aug 2001 MGP Created
// 09.10.01 V.Ivanchenko Add FindValue with 3 parameters
// + NumberOfComponents
//
// -------------------------------------------------------------------
#include "G4VCrossSectionHandler.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4LogLogInterpolation.hh"
#include "G4VEMDataSet.hh"
#include "G4EMDataSet.hh"
#include "G4CompositeEMDataSet.hh"
#include "G4ShellEMDataSet.hh"
#include "G4MaterialTable.hh"
#include "G4Material.hh"
#include "G4Element.hh"
#include "Randomize.hh"
#include "g4std/map"
#include "g4std/vector"
#include "g4std/fstream"
#include "g4std/strstream"
G4VCrossSectionHandler::G4VCrossSectionHandler()
{
crossSections = 0;
interpolation = 0;
Initialise();
ActiveElements();
}
G4VCrossSectionHandler::G4VCrossSectionHandler(G4VDataSetAlgorithm* algorithm,
G4double minE,
G4double maxE,
G4int bins,
G4double unitE,
G4double unitData,
G4int minZ,
G4int maxZ)
: interpolation(algorithm), eMin(minE), eMax(maxE), nBins(bins),
unit1(unitE), unit2(unitData), zMin(minZ), zMax(maxZ)
{
crossSections = 0;
ActiveElements();
}
G4VCrossSectionHandler::~G4VCrossSectionHandler()
{
delete interpolation;
interpolation = 0;
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::iterator pos;
for (pos = dataMap.begin(); pos != dataMap.end(); ++pos)
{
// The following is a workaround for STL ObjectSpace implementation,
// which does not support the standard and does not accept
// the syntax pos->second
// G4VEMDataSet* dataSet = pos->second;
G4VEMDataSet* dataSet = (*pos).second;
delete dataSet;
}
if (crossSections != 0)
{
size_t n = crossSections->size();
for (size_t i=0; i<n; i++)
{
delete (*crossSections)[i];
}
delete crossSections;
crossSections = 0;
}
}
void G4VCrossSectionHandler::Initialise(G4VDataSetAlgorithm* algorithm,
G4double minE, G4double maxE,
G4int numberOfBins,
G4double unitE, G4double unitData,
G4int minZ, G4int maxZ)
{
if (algorithm != 0)
{
delete interpolation;
interpolation = algorithm;
}
else
{
interpolation = CreateInterpolation();
}
eMin = minE;
eMax = maxE;
nBins = numberOfBins;
unit1 = unitE;
unit2 = unitData;
zMin = minZ;
zMax = maxZ;
}
void G4VCrossSectionHandler::PrintData() const
{
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
for (pos = dataMap.begin(); pos != dataMap.end(); pos++)
{
// The following is a workaround for STL ObjectSpace implementation,
// which does not support the standard and does not accept
// the syntax pos->first or pos->second
// G4int z = pos->first;
// G4VEMDataSet* dataSet = pos->second;
G4int z = (*pos).first;
G4VEMDataSet* dataSet = (*pos).second;
G4cout << "---- Data set for Z = "
<< z
<< G4endl;
dataSet->PrintData();
G4cout << "--------------------------------------------------" << G4endl;
}
}
void G4VCrossSectionHandler::LoadData(const G4String& fileName)
{
size_t nZ = activeZ.size();
for (size_t i=0; i<nZ; i++)
{
G4int Z = (G4int) activeZ[i];
// Build the complete string identifying the file with the data set
char nameChar[100] = {""};
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
ost << fileName << Z << ".dat";
G4String name(nameChar);
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = "G4VCrossSectionHandler - G4LEDATA environment variable not set";
G4Exception(excep);
}
G4String pathString(path);
G4String dirFile = pathString + "/" + name;
G4std::ifstream file(dirFile);
G4std::filebuf* lsdp = file.rdbuf();
if (! (lsdp->is_open()) )
{
G4String excep = "G4VCrossSectionHandler - data file: " + dirFile + " not found";
G4Exception(excep);
}
G4double a = 0;
G4int k = 1;
G4DataVector* energies = new G4DataVector;
G4DataVector* data = new G4DataVector;
do
{
file >> a;
G4int nColumns = 2;
// The file is organized into two columns:
// 1st column is the energy
// 2nd column is the corresponding value
// The file terminates with the pattern: -1 -1
// -2 -2
if (a == -1 || a == -2)
{
}
else
{
if (k%nColumns != 0)
{
G4double e = a * unit1;
energies->push_back(e);
k++;
}
else if (k%nColumns == 0)
{
G4double value = a * unit2;
data->push_back(value);
k = 1;
}
}
} while (a != -2); // end of file
file.close();
G4VDataSetAlgorithm* algo = interpolation->Clone();
G4VEMDataSet* dataSet = new G4EMDataSet(Z,energies,data,algo);
dataMap[Z] = dataSet;
}
}
void G4VCrossSectionHandler::LoadShellData(const G4String& fileName)
{
size_t nZ = activeZ.size();
for (size_t i=0; i<nZ; i++)
{
G4int Z = (G4int) activeZ[i];
// Build the complete string identifying the file with the data set
char nameChar[100] = {""};
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
ost << fileName << Z << ".dat";
G4String name(nameChar);
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = "G4VCrossSectionHandler - G4LEDATA environment variable not set";
G4Exception(excep);
}
G4String pathString(path);
G4String dirFile = pathString + "/" + name;
G4std::ifstream file(dirFile);
G4std::filebuf* lsdp = file.rdbuf();
if (! (lsdp->is_open()) )
{
G4String excep = "G4VCrossSectionHandler - data file: " + dirFile + " not found";
G4Exception(excep);
}
G4double a = 0;
G4int k = 1;
G4DataVector* energies = new G4DataVector;
G4DataVector* data = new G4DataVector;
do
{
file >> a;
G4int nColumns = 2;
// The file is organized into two columns:
// 1st column is the energy
// 2nd column is the corresponding value
// The file terminates with the pattern: -1 -1
// -2 -2
if (a == -1 || a == -2)
{
}
else
{
if (k%nColumns != 0)
{
G4double e = a * unit1;
energies->push_back(e);
k++;
}
else if (k%nColumns == 0)
{
G4double value = a * unit2;
data->push_back(value);
k = 1;
}
}
} while (a != -2); // end of file
file.close();
G4VDataSetAlgorithm* algo = interpolation->Clone();
G4VEMDataSet* dataSet = new G4ShellEMDataSet(Z,fileName,algo);
dataMap[Z] = dataSet;
}
}
void G4VCrossSectionHandler::Clear()
{
// Reset the map of data sets: remove the data sets from the map
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::iterator pos;
if(! dataMap.empty())
{
for (pos = dataMap.begin(); pos != dataMap.end(); ++pos)
{
// The following is a workaround for STL ObjectSpace implementation,
// which does not support the standard and does not accept
// the syntax pos->first or pos->second
// G4VEMDataSet* dataSet = pos->second;
G4VEMDataSet* dataSet = (*pos).second;
delete dataSet;
dataSet = 0;
G4int i = (*pos).first;
dataMap[i] = 0;
}
dataMap.clear();
}
activeZ.clear();
ActiveElements();
}
G4double G4VCrossSectionHandler::FindValue(G4int Z, G4double energy) const
{
G4double value = 0.;
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
pos = dataMap.find(Z);
if (pos!= dataMap.end())
{
// The following is a workaround for STL ObjectSpace implementation,
// which does not support the standard and does not accept
// the syntax pos->first or pos->second
// G4VEMDataSet* dataSet = pos->second;
G4VEMDataSet* dataSet = (*pos).second;
value = dataSet->FindValue(energy);
}
else
{
G4cout << "WARNING: G4VCrossSectionHandler::FindValue did not find Z = "
<< Z << G4endl;
}
return value;
}
G4double G4VCrossSectionHandler::FindValue(G4int Z, G4double energy,
G4int shellIndex) const
{
G4double value = 0.;
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
pos = dataMap.find(Z);
if (pos!= dataMap.end())
{
// The following is a workaround for STL ObjectSpace implementation,
// which does not support the standard and does not accept
// the syntax pos->first or pos->second
// G4VEMDataSet* dataSet = pos->second;
G4VEMDataSet* dataSet = (*pos).second;
if (shellIndex >= 0)
{
G4int nComponents = dataSet->NumberOfComponents();
if(shellIndex < nComponents)
// - MGP - Why doesn't it use G4VEMDataSet::FindValue directly?
value = dataSet->GetComponent(shellIndex)->FindValue(energy);
else
{
G4cout << "WARNING: G4VCrossSectionHandler::FindValue did not find"
<< " shellIndex= " << shellIndex
<< " for Z= "
<< Z << G4endl;
}
} else {
value = dataSet->FindValue(energy);
}
}
else
{
G4cout << "WARNING: G4VCrossSectionHandler::FindValue did not find Z = "
<< Z << G4endl;
}
return value;
}
G4double G4VCrossSectionHandler::ValueForMaterial(const G4Material* material,
G4double energy) const
{
G4double value = 0.;
const G4ElementVector* elementVector = material->GetElementVector();
const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
G4int nElements = material->GetNumberOfElements();
for (G4int i=0 ; i<nElements ; i++)
{
G4int Z = (G4int) (*elementVector)[i]->GetZ();
G4double elementValue = FindValue(Z,energy);
G4double nAtomsVol = nAtomsPerVolume[i];
value += nAtomsVol * elementValue;
}
return value;
}
G4VEMDataSet* G4VCrossSectionHandler::BuildMeanFreePathForMaterials(
const G4DataVector* energyCuts)
{
// Builds a CompositeDataSet containing the mean free path for each material
// in the material table
G4DataVector energyVector;
G4double dBin = log10(eMax/eMin) / nBins;
for (G4int i=0; i<nBins+1; i++)
{
energyVector.push_back(pow(10., log10(eMin)+i*dBin));
}
// Factory method to build cross sections in derived classes,
// related to the type of physics process
if (crossSections != 0)
{ // Reset the list of cross sections
G4std::vector<G4VEMDataSet*>::iterator mat;
if (! crossSections->empty())
{
for (mat = crossSections->begin(); mat!= crossSections->end(); ++mat)
{
G4VEMDataSet* set = *mat;
delete set;
set = 0;
}
crossSections->clear();
delete crossSections;
crossSections = 0;
}
}
crossSections = BuildCrossSectionsForMaterials(energyVector,energyCuts);
if (crossSections == 0)
G4Exception("G4VCrossSectionHandler::BuildMeanFreePathForMaterials, crossSections = 0");
G4VDataSetAlgorithm* algo = CreateInterpolation();
G4VEMDataSet* materialSet = new G4CompositeEMDataSet(algo);
G4DataVector* energies;
G4DataVector* data;
size_t nMaterials = G4Material::GetNumberOfMaterials();
for (size_t m=0; m<nMaterials; m++)
{
energies = new G4DataVector;
data = new G4DataVector;
for (G4int bin=0; bin<nBins; bin++)
{
G4double energy = energyVector[bin];
energies->push_back(energy);
G4VEMDataSet* matCrossSet = (*crossSections)[m];
G4double materialCrossSection = matCrossSet->FindValue(energy);
if (materialCrossSection > 0.)
{
data->push_back(1./materialCrossSection);
}
else
{
data->push_back(DBL_MAX);
}
}
G4VDataSetAlgorithm* algo = CreateInterpolation();
G4VEMDataSet* dataSet = new G4EMDataSet(m,energies,data,algo,1.,1.);
materialSet->AddComponent(dataSet);
}
return materialSet;
}
G4int G4VCrossSectionHandler::SelectRandomAtom(const G4Material* material, G4double e) const
{
// Select randomly an element within the material, according to the weight
// determined by the cross sections in the data set
G4int nElements = material->GetNumberOfElements();
const G4ElementVector* elementVector = material->GetElementVector();
// Special case: the material consists of one element
if (nElements == 1)
{
G4int Z = (G4int) (*elementVector)[0]->GetZ();
return Z;
}
// Composite material
G4double materialCrossSection0 = ValueForMaterial(material,e);
// size_t materialIndex = material->GetIndex();
// G4VEMDataSet* materialSet = crossSections[materialIndex];
// G4double materialCrossSection = materialSet->FindValue(e);
G4double random = G4UniformRand() * materialCrossSection0;
const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
G4double partialSumSigma = 0.;
for ( G4int i=0 ; i < nElements ; i++ )
{
G4int Z = (G4int) (*elementVector)[i]->GetZ();
G4double crossSection = FindValue(Z,e);
partialSumSigma += nAtomsPerVolume[i] * crossSection;
if (random <= partialSumSigma) return Z;
}
// It should never get here
return 0;
}
const G4Element* G4VCrossSectionHandler::SelectRandomElement(const G4Material* material,
G4double e) const
{
// Select randomly an element within the material, according to the weight determined
// by the cross sections in the data set
G4Element* nullElement = 0;
G4int nElements = material->GetNumberOfElements();
const G4ElementVector* elementVector = material->GetElementVector();
// Special case: the material consists of one element
if (nElements == 1)
{
G4Element* element = (*elementVector)[0];
return element;
}
else
{
// Composite material
G4double materialCrossSection0 = ValueForMaterial(material,e);
// size_t materialIndex = material->GetIndex();
// G4VEMDataSet* materialSet = crossSections[materialIndex];
// G4double materialCrossSection = materialSet->FindValue(e);
G4double random = G4UniformRand() * materialCrossSection0;
const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
G4double partialSumSigma = 0.;
for ( G4int i=0 ; i < nElements ; i++ )
{
G4Element* element = (*elementVector)[i];
G4int Z = (G4int) element->GetZ();
G4double crossSection = FindValue(Z,e);
partialSumSigma += nAtomsPerVolume[i] * crossSection;
if (random <= partialSumSigma) return element;
}
}
// It should never end up here
G4cout << "G4VCrossSectionHandler::SelectRandomElement - no element found" << G4endl;
return nullElement;
}
G4int G4VCrossSectionHandler::SelectRandomShell(G4int Z, G4double e) const
{
// Select randomly a shell, according to the weight determined by the cross sections
// in the data set
// Note for later improvement: it would be useful to add a cache mechanism for already
// used shells to improve performance
G4int shell = 0;
G4double totCrossSection = FindValue(Z,e);
G4double random = G4UniformRand() * totCrossSection;
G4double partialSum = 0.;
G4VEMDataSet* dataSet = 0;
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
pos = dataMap.find(Z);
// The following is a workaround for STL ObjectSpace implementation,
// which does not support the standard and does not accept
// the syntax pos->first or pos->second
// if (pos != dataMap.end()) dataSet = pos->second;
if (pos != dataMap.end()) dataSet = (*pos).second;
size_t nShells = dataSet->NumberOfComponents();
for (size_t i=0; i<nShells; i++)
{
const G4VEMDataSet* shellDataSet = dataSet->GetComponent(i);
if (shellDataSet != 0)
{
G4double value = shellDataSet->FindValue(e);
partialSum += value;
if (random <= partialSum) return i;
}
}
// It should never get here
return shell;
}
void G4VCrossSectionHandler::ActiveElements()
{
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
if (materialTable == 0)
G4Exception("G4VCrossSectionHandler::ActiveElements - no MaterialTable found)");
G4int nMaterials = G4Material::GetNumberOfMaterials();
for (G4int m=0; m<nMaterials; m++)
{
const G4Material* material= (*materialTable)[m];
const G4ElementVector* elementVector = material->GetElementVector();
const G4int nElements = material->GetNumberOfElements();
for (G4int iEl=0; iEl<nElements; iEl++)
{
G4Element* element = (*elementVector)[iEl];
G4double Z = element->GetZ();
if (!(activeZ.contains(Z)) && Z >= zMin && Z <= zMax)
{
activeZ.push_back(Z);
}
}
}
}
G4VDataSetAlgorithm* G4VCrossSectionHandler::CreateInterpolation()
{
G4VDataSetAlgorithm* algorithm = new G4LogLogInterpolation;
return algorithm;
}
G4int G4VCrossSectionHandler::NumberOfComponents(G4int Z) const
{
G4int n = 0;
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
pos = dataMap.find(Z);
if (pos!= dataMap.end())
{
G4VEMDataSet* dataSet = (*pos).second;
n = dataSet->NumberOfComponents();
}
else
{
G4cout << "WARNING: G4VCrossSectionHandler::NumberOfComponents did not "
<< "find Z = "
<< Z << G4endl;
}
return n;
}
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4VeLowEnergyLoss.cc,v 1.12.2.2 2001/06/28 20:19:31 gunter Exp $
// GEANT4 tag $Name: $
// $Id: G4VeLowEnergyLoss.cc,v 1.17 2001/11/23 11:45:29 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
//
// --------------------------------------------------------------
@@ -37,6 +37,7 @@
// 22/11/00 minor fix in fluctuations V.Ivanchenko
// 10/05/01 V.Ivanchenko Clean up againist Linux compilation with -Wall
// 22/05/01 V.Ivanchenko Update range calculation
// 23/11/01 V.Ivanchenko Move static member-functions from header to source
//
// --------------------------------------------------------------
@@ -95,16 +96,33 @@ G4VeLowEnergyLoss::G4VeLowEnergyLoss(G4VeLowEnergyLoss& right)
{
}
//
void G4VeLowEnergyLoss::SetRndmStep(G4bool value)
{
rndmStepFlag = value;
}
void G4VeLowEnergyLoss::SetEnlossFluc(G4bool value)
{
EnlossFlucFlag = value;
}
void G4VeLowEnergyLoss::SetStepFunction (G4double c1, G4double c2)
{
dRoverRange = c1;
finalRange = c2;
c1lim=dRoverRange;
c2lim=2.*(1-dRoverRange)*finalRange;
c3lim=-(1.-dRoverRange)*finalRange*finalRange;
}
G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeTable(
G4PhysicsTable* theDEDXTable,G4PhysicsTable* theRangeTable,
G4double lowestKineticEnergy,G4double highestKineticEnergy,G4int TotBin)
G4double lowestKineticEnergy,G4double highestKineticEnergy,
G4int TotBin)
// Build range table from the energy loss table
{
const G4MaterialTable* theMaterialTable=
G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
if(theRangeTable)
{ theRangeTable->clearAndDestroy();
@@ -236,9 +254,8 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildLabTimeTable(G4PhysicsTable* theDEDXTabl
G4double highestKineticEnergy,G4int TotBin)
{
const G4MaterialTable* theMaterialTable=
G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
if(theLabTimeTable)
{ theLabTimeTable->clearAndDestroy();
@@ -270,9 +287,8 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildProperTimeTable(G4PhysicsTable* theDEDXT
G4double highestKineticEnergy,G4int TotBin)
{
const G4MaterialTable* theMaterialTable=
G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
if(theProperTimeTable)
{ theProperTimeTable->clearAndDestroy();
@@ -312,7 +328,6 @@ void G4VeLowEnergyLoss::BuildLabTimeVector(G4PhysicsTable* theDEDXTable,
LowEdgeEnergy,tau,Value ;
G4PhysicsVector* physicsVector= (*theDEDXTable)[materialIndex];
//const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
// low energy part first...
losslim = physicsVector->GetValue(tlim,isOut);
@@ -498,9 +513,8 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildInverseRangeTable(G4PhysicsTable* theRan
{
G4double SmallestRange,BiggestRange ;
G4bool isOut ;
const G4MaterialTable* theMaterialTable=
G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
if(theInverseRangeTable)
{ theInverseRangeTable->clearAndDestroy();
@@ -594,9 +608,8 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeCoeffATable(G4PhysicsTable* theRang
// Build tables of coefficients for the energy loss calculation
// create table for coefficients "A"
{
const G4MaterialTable* theMaterialTable=
G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
if(theRangeCoeffATable)
{ theRangeCoeffATable->clearAndDestroy();
@@ -657,9 +670,8 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeCoeffBTable(G4PhysicsTable* theRang
// Build tables of coefficients for the energy loss calculation
// create table for coefficients "B"
{
const G4MaterialTable* theMaterialTable=
G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
if(theRangeCoeffBTable)
{ theRangeCoeffBTable->clearAndDestroy();
@@ -719,9 +731,8 @@ G4PhysicsTable* G4VeLowEnergyLoss::BuildRangeCoeffCTable(G4PhysicsTable* theRang
// Build tables of coefficients for the energy loss calculation
// create table for coefficients "C"
{
const G4MaterialTable* theMaterialTable=
G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
if(theRangeCoeffCTable)
{ theRangeCoeffCTable->clearAndDestroy();
@@ -806,7 +817,7 @@ G4double G4VeLowEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
ipotLogFluct = aMaterial->GetIonisation()->GetLogMeanExcEnergy();
}
G4double threshold,w1,w2,C,
beta2,suma,e0,loss,lossc ,w;
beta2,suma,e0,loss,lossc,w;
G4double a1,a2,a3;
G4int p1,p2,p3;
G4int nb;
@@ -823,7 +834,7 @@ G4double G4VeLowEnergyLoss::GetLossWithFluct(const G4DynamicParticle* aParticle,
// G4cout << "MGP -- Fluc Tkin " << Tkin/keV << " keV " << " MeanLoss = " << MeanLoss/keV << G4endl;
threshold =((*G4Electron::Electron()).GetCutsInEnergy())[imat];
threshold = G4Electron::Electron()->GetEnergyThreshold(aMaterial);
G4double rmass = electron_mass_c2/ParticleMass;
G4double tau = Tkin/ParticleMass, tau1 = tau+1., tau2 = tau*(tau+2.);
G4double Tm = 2.*electron_mass_c2*tau2/(1.+2.*tau1*rmass+rmass*rmass);
@@ -0,0 +1,72 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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. *
// ********************************************************************
//
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4VhShellCrossSection
//
// Author: V.Ivanchenko (Vladimir.Ivanchenko@cern.ch)
//
// History:
// -----------
// 20 Oct 2001 V.Ivanchenko 1st implementation
// 24 Oct 2001 MGP Minor clean-up
// 29 Oct 2001 VI Add delta energy
//
// -------------------------------------------------------------------
#include "G4VhShellCrossSection.hh"
#include "Randomize.hh"
G4VhShellCrossSection::G4VhShellCrossSection()
{ }
G4VhShellCrossSection::~G4VhShellCrossSection()
{ }
G4int G4VhShellCrossSection::SelectRandomShell(G4int Z,
G4double incidentEnergy,
G4double mass,
G4double deltaEnergy) const
{
G4std::vector<G4double> p = Probabilities(Z,incidentEnergy,mass,deltaEnergy);
G4int shell = 0;
size_t nShells = p.size();
G4double q = G4UniformRand();
for (size_t i=0; i<nShells; i++) {
if (p[i] >= q) {
shell = i;
break;
}
q -= p[i];
}
return shell;
}
@@ -0,0 +1,346 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4eBremsstrahlungSpectrum.cc,v 1.5 2001/11/30 00:52:52 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4eBremsstrahlungSpectrum
//
// Author: V.Ivanchenko (Vladimir.Ivanchenko@cern.ch)
//
// Creation date: 29 September 2001
//
// Modifications:
// 10.10.01 MGP Revision to improve code quality and consistency with design
// 15.11.01 VI Update spectrum model Bethe-Haitler spectrum at high energy
//
// -------------------------------------------------------------------
#include "G4eBremsstrahlungSpectrum.hh"
#include "G4BremsstrahlungParameters.hh"
#include "Randomize.hh"
G4eBremsstrahlungSpectrum::G4eBremsstrahlungSpectrum():
G4VEnergySpectrum(),
lowestE(0.1*eV),
length(15)
{
theBRparam = new G4BremsstrahlungParameters();
xp.clear();
for(size_t i=0; i<length; i++) {
G4double x = 0.1*((G4double)i);
if(i == 0) x = 0.01;
if(i == 10) x = 0.95;
if(i == 11) x = 0.97;
if(i == 12) x = 0.99;
if(i == 13) x = 0.995;
if(i == 14) x = 1.0;
xp.push_back(x);
}
verbose = 0;
}
G4eBremsstrahlungSpectrum::~G4eBremsstrahlungSpectrum()
{
delete theBRparam;
}
G4double G4eBremsstrahlungSpectrum::Probability(G4int Z,
G4double tmin,
G4double tmax,
G4double e,
G4int,
const G4ParticleDefinition*) const
{
G4double tm = G4std::min(tmax, e);
G4double t0 = G4std::max(tmin, lowestE);
if(t0 >= tm) return 0.0;
t0 /= e;
tm /= e;
G4double z = lowestE/e;
G4double x, y;
// Below 10 MeV EEDL data base spectrum
if(e < 1000000.*MeV) {
G4int iMax = 16;
G4DataVector p;
// Access parameters
for (G4int i=0; i<iMax; i++) {
p.push_back(theBRparam->Parameter(i, Z, e));
}
x = IntSpectrum(t0, tm, p);
y = IntSpectrum(z, 1.0, p);
p.clear();
// Above Bethe-Heitler formula
} else {
x = log(tm/t0) - tm + t0 + 0.375*(tm*tm - t0*t0);
y = log(1./z) - 1.0 + z + 0.375*(1. - z*z);
}
if(1 < verbose) {
G4cout << "tcut(MeV)= " << tmin/MeV
<< "; tMax(MeV)= " << tmax/MeV
<< "; t0= " << t0
<< "; tm= " << tm
<< "; xp[0]= " << xp[0]
<< "; z= " << z
<< "; val= " << x
<< "; nor= " << y
<< G4endl;
}
if(y > 0.0) x /= y;
else x = 0.0;
if(x < 0.0) x = 0.0;
return x;
}
G4double G4eBremsstrahlungSpectrum::AverageEnergy(G4int Z,
G4double tmin,
G4double tmax,
G4double e,
G4int,
const G4ParticleDefinition*) const
{
G4double tm = G4std::min(tmax, e);
G4double t0 = G4std::max(tmin, lowestE);
if(t0 >= tm) return 0.0;
G4double c = sqrt(theBRparam->ParameterC(Z));
t0 /= e;
tm /= e;
G4double z = lowestE/e;
G4double x, y, f;
// Below 10 MeV EEDL data base spectrum
if(e < 1000000.*MeV) {
G4int iMax = 16;
G4DataVector p;
// Access parameters
for (G4int i=0; i<iMax; i++) {
p.push_back(theBRparam->Parameter(i, Z, e));
}
x = AverageValue(t0, tm, p);
y = IntSpectrum(z, 1.0, p);
f = Function(z, p);
p.clear();
// Above Bethe-Heitler formula
} else {
x = tm - t0 - 0.5*(tm*tm - t0*t0) + 0.25*(tm*tm*tm - t0*t0*t0);
y = log(1./z) - 1.0 + z + 0.375*(1. - z*z);
f = 1. - x + 0.75*x*x;
}
x += 0.5*f*z*(z - c*atan(z/c));
x *= e;
if(1 < verbose) {
G4cout << "tcut(MeV)= " << tmin/MeV
<< "; tMax(MeV)= " << tmax/MeV
<< "; e(MeV)= " << e/MeV
<< "; t0= " << t0
<< "; tm= " << tm
<< "; y= " << y
<< "; x= " << x
<< G4endl;
}
if(y > 0.0) x /= y;
else x = 0.0;
if(x < 0.0) x = 0.0;
return x;
}
G4double G4eBremsstrahlungSpectrum::SampleEnergy(G4int Z,
G4double tmin,
G4double tmax,
G4double e,
G4int,
const G4ParticleDefinition*) const
{
G4double tm = G4std::min(tmax, e);
G4double t0 = G4std::max(tmin, lowestE);
if(t0 >= tm) return 0.0;
t0 /= e;
tm /= e;
G4int iMax = 16;
G4DataVector p;
G4double amaj;
// Below 10 MeV EEDL data base spectrum
if(e < 10000000.*MeV) {
for (G4int i=0; i<iMax; i++) {
p.push_back(theBRparam->Parameter(i, Z, e));
}
amaj = G4std::max(p[15], 1. - (p[1] - p[0])/9.);
} else {
amaj = 1.0;
}
G4double amax = log(tm);
G4double amin = log(t0);
G4double tgam, q, fun;
do {
G4double x = amin + G4UniformRand()*(amax - amin);
tgam = exp(x);
if(e < 10.*MeV) {
fun = Function(tgam, p);
} else {
fun = 1. - tgam + 0.75*tgam*tgam;
}
if(fun > amaj) {
G4cout << "WARNING in G4eBremsstrahlungSpectrum::SampleEnergy:"
<< " Majoranta " << amaj
<< " < " << fun
<< G4endl;
}
q = amaj * G4UniformRand();
} while (q > fun);
tgam *= e;
p.clear();
return tgam;
}
G4double G4eBremsstrahlungSpectrum::IntSpectrum(G4double xMin,
G4double xMax,
const G4DataVector& p) const
{
G4double x1 = G4std::min(xMin, xp[0]);
G4double x2 = G4std::min(xMax, xp[0]);
G4double z1 = x1;
G4double z2 = x2;
G4double sum = 0.0;
if(x1 < x2) {
G4double k = (p[1] - p[0])/0.09;
sum += (1. - k*xp[0])*log(x2/x1) + k*(x2 - x1);
}
for (size_t i=0; i<length-1; i++) {
x1 = G4std::max(xMin, xp[i]);
x2 = G4std::min(xMax, xp[i+1]);
if(x1 < x2) {
z1 = p[i];
z2 = p[i+1];
sum += z2 - z1 + log(x2/x1)*(z1*x2 - z2*x1)/(x2 - x1);
}
}
if(sum < 0.0) sum = 0.0;
return sum;
}
G4double G4eBremsstrahlungSpectrum::AverageValue(G4double xMin,
G4double xMax,
const G4DataVector& p) const
{
G4double x1 = G4std::min(xMin, xp[0]);
G4double x2 = G4std::min(xMax, xp[0]);
G4double z1 = x1;
G4double z2 = x2;
G4double sum = 0.0;
if(x1 < x2) {
G4double k = (p[1] - p[0])/0.09;
sum += (z2 - z1)*(1. - k*xp[0]);
z1 *= x1;
z2 *= x2;
sum += 0.5*k*(z1 - z2);
}
for (size_t i=0; i<length-1; i++) {
x1 = G4std::max(xMin, xp[i]);
x2 = G4std::min(xMax, xp[i+1]);
if(x1 < x2) {
z1 = p[i];
z2 = p[i+1];
sum += 0.5*(z2 - z1)*(x2 + x1) + z1*x2 - z2*x1;
}
}
if(sum < 0.0) sum = 0.0;
return sum;
}
G4double G4eBremsstrahlungSpectrum::Function(G4double x,
const G4DataVector& p) const
{
G4double f = 0.0;
if(x <= xp[0]) {
f = 1. + (p[1] - p[0])*(x - xp[0])/0.09;
} else {
for (size_t i=0; i<length-1; i++) {
if(x <= xp[i+1] && x >= xp[i]) {
f = p[i] + (p[i+1] - p[i])*(x - xp[i])/(xp[i+1] - xp[i]);
break;
}
}
}
if(f < 0.0) f = 0.0;
return f;
}
void G4eBremsstrahlungSpectrum::PrintData() const
{ theBRparam->PrintData(); }
@@ -0,0 +1,140 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4eIonisationCrossSectionHandler.cc,v 1.6 2001/11/29 19:01:37 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4eIonisationCrossSectionHandler
//
// Author: V.Ivanchenko (Vladimir.Ivanchenko@cern.ch)
//
// Creation date: 25 Sept 2001
//
// Modifications:
// 10 Oct 2001 M.G. Pia Revision to improve code quality and consistency with design
//
// -------------------------------------------------------------------
#include "G4eIonisationCrossSectionHandler.hh"
#include "G4VEnergySpectrum.hh"
#include "G4DataVector.hh"
#include "G4CompositeEMDataSet.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4SemiLogInterpolation.hh"
#include "G4VEMDataSet.hh"
#include "G4EMDataSet.hh"
#include "G4Material.hh"
#include "G4MaterialTable.hh"
G4eIonisationCrossSectionHandler::G4eIonisationCrossSectionHandler(
const G4VEnergySpectrum* spec, G4VDataSetAlgorithm* alg,
G4double emin, G4double emax, G4int nbin)
: G4VCrossSectionHandler(),
theParam(spec)
{
G4VCrossSectionHandler::Initialise(alg, emin, emax, nbin);
interp = new G4SemiLogInterpolation();
}
G4eIonisationCrossSectionHandler::~G4eIonisationCrossSectionHandler()
{
delete interp;
}
G4std::vector<G4VEMDataSet*>* G4eIonisationCrossSectionHandler::BuildCrossSectionsForMaterials(
const G4DataVector& energyVector,
const G4DataVector* energyCuts)
{
G4std::vector<G4VEMDataSet*>* set = new G4std::vector<G4VEMDataSet*>;
G4DataVector* energies;
G4DataVector* cs;
G4int nOfBins = energyVector.size();
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
if (materialTable == 0)
G4Exception("G4VCrossSectionHandler::G4VCrossSectionHandler - no MaterialTable found)");
G4int nMaterials = G4Material::GetNumberOfMaterials();
for (G4int m=0; m<nMaterials; m++) {
const G4Material* material = (*materialTable)[m];
const G4ElementVector* elementVector = material->GetElementVector();
//const G4double* nAtomsPerVolume = material->GetVecNbOfAtomsPerVolume();
const G4double* nAtomsPerVolume = material->GetAtomicNumDensityVector();
G4int nElements = material->GetNumberOfElements();
G4double tcut = (*energyCuts)[m];
G4VDataSetAlgorithm* algo = interp->Clone();
G4VEMDataSet* setForMat = new G4CompositeEMDataSet(algo,1.,1.);
for (G4int i=0; i<nElements; i++) {
G4int Z = (G4int) (*elementVector)[i]->GetZ();
G4int nShells = NumberOfComponents(Z);
energies = new G4DataVector;
cs = new G4DataVector;
G4double density = nAtomsPerVolume[i];
for (G4int bin=0; bin<nOfBins; bin++) {
G4double e = energyVector[bin];
energies->push_back(e);
G4double value = 0.0;
if(e > tcut) {
for (G4int n=0; n<nShells; n++) {
G4double cross = FindValue(Z, e, n);
G4double p = theParam->Probability(Z, tcut, e, e, n);
value += cross * p * density;
/*
G4cout << "G4eIonisationCrossSectionHandler: e= " << e
<< " n= " << n
<< " cross= " << cross
<< " p= " << p
<< " value= " << value
<< G4endl;
*/
}
}
cs->push_back(value);
}
G4VDataSetAlgorithm* algo = interp->Clone();
G4VEMDataSet* elSet = new G4EMDataSet(i,energies,cs,algo,1.,1.);
setForMat->AddComponent(elSet);
}
set->push_back(setForMat);
}
return set;
}
@@ -0,0 +1,383 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4eIonisationParameters.cc,v 1.17 2001/11/30 00:52:52 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
// History:
// -----------
// 31 Jul 2001 MGP Created, with dummy implementation
// 12.09.01 V.Ivanchenko Add param and interpolation of parameters
// 04.10.01 V.Ivanchenko Add BindingEnergy method
// 25.10.01 MGP Many bug fixes, mostly related to the
// management of pointers
// 29.11.01 V.Ivanchenko New parametrisation + Excitation
//
// -------------------------------------------------------------------
#include "G4eIonisationParameters.hh"
#include "G4VEMDataSet.hh"
#include "G4ShellEMDataSet.hh"
#include "G4EMDataSet.hh"
#include "G4CompositeEMDataSet.hh"
#include "G4LogLogInterpolation.hh"
#include "G4Material.hh"
#include "G4DataVector.hh"
#include "g4std/fstream"
#include "g4std/strstream"
G4eIonisationParameters:: G4eIonisationParameters(G4int minZ, G4int maxZ)
: zMin(minZ), zMax(maxZ),
length(7)
{
LoadData();
}
G4eIonisationParameters::~G4eIonisationParameters()
{
// Reset the map of data sets: remove the data sets from the map
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::iterator pos;
for (pos = param.begin(); pos != param.end(); ++pos)
{
G4VEMDataSet* dataSet = (*pos).second;
delete dataSet;
}
for (pos = excit.begin(); pos != excit.end(); ++pos)
{
G4VEMDataSet* dataSet = (*pos).second;
delete dataSet;
}
activeZ.clear();
}
G4double G4eIonisationParameters::Parameter(G4int Z, G4int shellIndex,
G4int parameterIndex,
G4double e) const
{
G4double value = 0.;
G4int id = Z*20 + parameterIndex;
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
pos = param.find(id);
if (pos!= param.end()) {
G4VEMDataSet* dataSet = (*pos).second;
G4int nShells = dataSet->NumberOfComponents();
if(shellIndex < nShells) {
const G4VEMDataSet* component = dataSet->GetComponent(shellIndex);
const G4DataVector ener = component->GetEnergies(0);
G4double ee = G4std::max(ener.front(),G4std::min(ener.back(),e));
value = component->FindValue(ee);
} else {
G4cout << "WARNING: G4IonisationParameters::FindParameter "
<< "has no parameters for shell= " << shellIndex
<< "; Z= " << Z
<< G4endl;
}
} else {
G4cout << "WARNING: G4IonisationParameters::Parameter "
<< "did not find ID = "
<< shellIndex << G4endl;
}
return value;
}
G4double G4eIonisationParameters::Excitation(G4int Z, G4double e) const
{
G4double value = 0.;
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
pos = excit.find(Z);
if (pos!= excit.end()) {
G4VEMDataSet* dataSet = (*pos).second;
const G4DataVector ener = dataSet->GetEnergies(0);
G4double ee = G4std::max(ener.front(),G4std::min(ener.back(),e));
value = dataSet->FindValue(ee);
} else {
G4cout << "WARNING: G4IonisationParameters::Excitation "
<< "did not find ID = "
<< Z << G4endl;
}
return value;
}
void G4eIonisationParameters::LoadData()
{
// ---------------------------------------
// Please document what are the parameters
// ---------------------------------------
// define active elements
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
if (materialTable == 0)
G4Exception("G4eIonisationParameters: no MaterialTable found)");
G4int nMaterials = G4Material::GetNumberOfMaterials();
for (G4int m=0; m<nMaterials; m++) {
const G4Material* material= (*materialTable)[m];
const G4ElementVector* elementVector = material->GetElementVector();
const size_t nElements = material->GetNumberOfElements();
for (size_t iEl=0; iEl<nElements; iEl++) {
G4Element* element = (*elementVector)[iEl];
G4double Z = element->GetZ();
if (!(activeZ.contains(Z))) {
activeZ.push_back(Z);
}
}
}
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = "G4eIonisationParameters - G4LEDATA environment variable not set";
G4Exception(excep);
}
G4String pathString(path);
pathString += "/ioni/io-sp-";
G4double energy, sum;
size_t nZ = activeZ.size();
for (size_t i=0; i<nZ; i++) {
G4int Z = (G4int)activeZ[i];
char nameChar[100] = {""};
G4std::ostrstream ost(nameChar, 100, G4std::ios::out);
ost << pathString << Z << ".dat";
G4String name(nameChar);
G4std::ifstream file(name);
G4std::filebuf* lsdp = file.rdbuf();
if (! (lsdp->is_open()) ) {
G4String excep = "G4IonisationParameters - data file: "
+ name + " not found";
G4Exception(excep);
}
// - MGP - Please add some documentation about the parameters read
// The file is organized into...:
// 1st column is the energy
// The file terminates with the pattern: -1 -1
G4std::vector<G4VEMDataSet*> p;
for (size_t k=0; k<length; k++)
{
G4VDataSetAlgorithm* inter = new G4LogLogInterpolation();
G4VEMDataSet* composite = new G4CompositeEMDataSet(inter,1.,1.);
p.push_back(composite);
}
G4int shell = 0;
G4std::vector<G4DataVector*> a;
for (size_t j=0; j<length; j++)
{
G4DataVector* aa = new G4DataVector();
a.push_back(aa);
}
G4DataVector e;
e.clear();
do {
file >> energy >> sum;
if (energy == -2) break;
if (energy > -1) {
e.push_back(energy);
a[0]->push_back(sum);
for (size_t j=0; j<length-1; j++) {
G4double qRead;
file >> qRead;
a[j + 1]->push_back(qRead);
}
} else {
// End of set for a shell, fill the map
for (size_t k=0; k<length; k++) {
// G4int id = Z*20 + k;
G4VDataSetAlgorithm* interp = new G4LogLogInterpolation();
G4DataVector* eVector = new G4DataVector;
size_t eSize = e.size();
for (size_t s=0; s<eSize; s++) {
eVector->push_back(e[s]);
}
G4VEMDataSet* set = new G4EMDataSet(shell,eVector,a[k],interp,1.,1.);
p[k]->AddComponent(set);
}
// clear vectors
for (size_t j2=0; j2<length; j2++) {
a[j2] = new G4DataVector();
}
shell++;
e.clear();
}
} while (energy > -2);
file.close();
for (size_t kk=0; kk<length; kk++)
{
G4int id = Z*20 + kk;
param[id] = p[kk];
}
}
G4String pathString_a(path);
G4String name_a = pathString_a + "/ioni/io-ex-av.dat";
G4std::ifstream file_a(name_a);
G4std::filebuf* lsdp_a = file_a.rdbuf();
G4String pathString_b(path);
G4String name_b = pathString_b + "/ioni/io-ex-sig.dat";
G4std::ifstream file_b(name_b);
G4std::filebuf* lsdp_b = file_b.rdbuf();
if (! (lsdp_a->is_open()) ) {
G4String excep = G4String("G4eIonisationParameters: cannot open file ")
+ name_a;
G4Exception(excep);
}
if (! (lsdp_b->is_open()) ) {
G4String excep = G4String("G4eIonisationParameters: cannot open file ")
+ name_b;
G4Exception(excep);
}
// The file is organized into two columns:
// 1st column is the energy
// 2nd column is the corresponding value
// The file terminates with the pattern: -1 -1
// -2 -2
G4double ener, ener1, sig, sig1;
G4int z = 0;
G4DataVector e;
e.clear();
G4DataVector d;
d.clear();
do {
file_a >> ener >> sig;
file_b >> ener1 >> sig1;
if(ener != ener1) {
G4cout << "G4eIonisationParameters: problem in excitation data "
<< "ener= " << ener
<< " ener1= " << ener1
<< G4endl;
}
// End of file
if (ener == -2) {
break;
// End of next element
} else if (ener == -1) {
z++;
G4double Z = (G4double)z;
// fill map if Z is used
if (activeZ.contains(Z)) {
G4VDataSetAlgorithm* inter = new G4LogLogInterpolation();
G4DataVector* eVector = new G4DataVector;
G4DataVector* dVector = new G4DataVector;
size_t eSize = e.size();
for (size_t s=0; s<eSize; s++) {
eVector->push_back(e[s]);
dVector->push_back(d[s]);
}
G4VEMDataSet* set = new G4EMDataSet(z,eVector,dVector,inter,1.,1.);
excit[z] = set;
}
e.clear();
d.clear();
} else {
e.push_back(ener);
d.push_back(sig1*sig*barn*MeV);
}
} while (ener != -2);
file_a.close();
}
void G4eIonisationParameters::PrintData() const
{
G4cout << G4endl;
G4cout << "===== G4eIonisationParameters =====" << G4endl;
G4cout << G4endl;
size_t nZ = activeZ.size();
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
for (size_t i=0; i<nZ; i++) {
G4int Z = (G4int)activeZ[i];
for (size_t j=0; j<length; j++) {
G4int index = Z*20 + j;
pos = param.find(index);
if (pos!= param.end()) {
G4VEMDataSet* dataSet = (*pos).second;
size_t nShells = dataSet->NumberOfComponents();
for (size_t k=0; k<nShells; k++) {
G4cout << "===== Z= " << Z << " shell= " << k
<< " parameter[" << j << "] ====="
<< G4endl;
const G4VEMDataSet* comp = dataSet->GetComponent(k);
comp->PrintData();
}
}
}
}
G4cout << "====================================" << G4endl;
}
@@ -0,0 +1,387 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * 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. *
// * *
// * 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: G4eIonisationSpectrum.cc,v 1.12 2001/12/04 11:34:16 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// -------------------------------------------------------------------
//
// GEANT4 Class file
//
//
// File name: G4eIonisationSpectrum
//
// Author: V.Ivanchenko (Vladimir.Ivanchenko@cern.ch)
//
// Creation date: 29 September 2001
//
// Modifications:
// 10.10.2001 MGP Revision to improve code quality and
// consistency with design
// 02.11.2001 VI Optimize sampling of energy
// 29.11.2001 VI New parametrisation
//
// -------------------------------------------------------------------
//
#include "G4eIonisationSpectrum.hh"
#include "G4AtomicTransitionManager.hh"
#include "G4AtomicShell.hh"
#include "G4eIonisationParameters.hh"
#include "G4DataVector.hh"
#include "Randomize.hh"
G4eIonisationSpectrum::G4eIonisationSpectrum():G4VEnergySpectrum(),
lowestE(0.1*eV),
verbose(0)
{
theParam = new G4eIonisationParameters();
}
G4eIonisationSpectrum::~G4eIonisationSpectrum()
{
delete theParam;
}
G4double G4eIonisationSpectrum::Probability(G4int Z,
G4double tMin,
G4double tMax,
G4double e,
G4int shell,
const G4ParticleDefinition* part) const
{
// Please comment what Probability does and what are the three
// functions mentioned below
// Describe the algorithms used
G4double eMax = MaxEnergyOfSecondaries(e);
G4double t0 = G4std::max(tMin, lowestE);
G4double tm = G4std::min(tMax, eMax);
if(t0 >= tm) return 0.0;
G4double bindingEnergy = (G4AtomicTransitionManager::Instance())->
Shell(Z, shell)->BindingEnergy();
G4double x1 = G4std::min(0.5,(t0 + bindingEnergy)/(e + bindingEnergy));
G4double x2 = G4std::min(0.5,(tm + bindingEnergy)/(e + bindingEnergy));
if(verbose > 1) {
G4cout << "G4eIonisationSpectrum::Probability: Z= " << Z
<< "; shell= " << shell
<< "; E(keV)= " << e/keV
<< "; x1= " << x1
<< "; x2= " << x2
<< G4endl;
}
G4int iMax = 7;
G4DataVector p;
// Access parameters
for (G4int i=0; i<iMax; i++)
{
p.push_back(theParam->Parameter(Z, shell, i, e));
}
G4double g = (e + bindingEnergy)/electron_mass_c2 + 1.;
p.push_back((2.0*g - 1.0)/(g*g));
G4double val = IntSpectrum(x1, x2, p);
G4double x0 = (lowestE + bindingEnergy)/(e + bindingEnergy);
G4double nor = IntSpectrum(x0, 0.5, p);
if(verbose > 1) {
G4cout << "tcut= " << tMin
<< "; tMax= " << tMax
<< "; x0= " << x0
<< "; x1= " << x1
<< "; x2= " << x2
<< "; val= " << val
<< "; nor= " << nor
<< "; sum= " << p[0]
<< "; a= " << p[1]
<< "; b= " << p[2]
<< "; c= " << p[3]
<< G4endl;
}
p.clear();
if(nor > 0.0) val /= nor;
else val = 0.0;
if(val < 0.0) val = 0.0;
return val;
}
G4double G4eIonisationSpectrum::AverageEnergy(G4int Z,
G4double tMin,
G4double tMax,
G4double e,
G4int shell,
const G4ParticleDefinition* part) const
{
// Please comment what AverageEnergy does and what are the three
// functions mentioned below
// Describe the algorithms used
G4double eMax = MaxEnergyOfSecondaries(e);
G4double t0 = G4std::max(tMin, lowestE);
G4double tm = G4std::min(tMax, eMax);
if(t0 >= tm) return 0.0;
G4double bindingEnergy = (G4AtomicTransitionManager::Instance())->
Shell(Z, shell)->BindingEnergy();
G4double x1 = G4std::min(0.5,(t0 + bindingEnergy)/(e + bindingEnergy));
G4double x2 = G4std::min(0.5,(tm + bindingEnergy)/(e + bindingEnergy));
if(verbose > 1) {
G4cout << "G4eIonisationSpectrum::AverageEnergy: Z= " << Z
<< "; shell= " << shell
<< "; E(keV)= " << e/keV
<< "; bindingE(keV)= " << bindingEnergy/keV
<< "; x1= " << x1
<< "; x2= " << x2
<< G4endl;
}
G4int iMax = 7;
G4DataVector p;
// Access parameters
for (G4int i=0; i<iMax; i++)
{
p.push_back(theParam->Parameter(Z, shell, i, e));
}
G4double g = (e + bindingEnergy)/electron_mass_c2 + 1.;
p.push_back((2.0*g - 1.0)/(g*g));
G4double val = AverageValue(x1, x2, p);
G4double x0 = (lowestE + bindingEnergy)/(e + bindingEnergy);
G4double nor = IntSpectrum(x0, 0.5, p);
val *= (e + bindingEnergy);
if(verbose > 1) {
G4cout << "tcut(MeV)= " << tMin/MeV
<< "; tMax(MeV)= " << tMax/MeV
<< "; x0= " << x0
<< "; x1= " << x1
<< "; x2= " << x2
<< "; val= " << val
<< "; nor= " << nor
<< "; sum= " << p[0]
<< "; a= " << p[1]
<< "; b= " << p[2]
<< "; c= " << p[3]
<< G4endl;
}
p.clear();
if(nor > 0.0) val /= nor;
else val = 0.0;
if(val < 0.0) val = 0.0;
return val;
}
G4double G4eIonisationSpectrum::SampleEnergy(G4int Z,
G4double tMin,
G4double tMax,
G4double e,
G4int shell,
const G4ParticleDefinition* part) const
{
// Please comment what SampleEnergy does
G4double tDelta = 0.0;
G4double t0 = G4std::max(tMin, lowestE);
G4double tm = G4std::min(tMax, MaxEnergyOfSecondaries(e));
if(t0 > tm) return tDelta;
G4double bindingEnergy = (G4AtomicTransitionManager::Instance())->
Shell(Z, shell)->BindingEnergy();
G4double x1 = G4std::min(0.5,(t0 + bindingEnergy)/(e + bindingEnergy));
G4double x2 = G4std::min(0.5,(tm + bindingEnergy)/(e + bindingEnergy));
if(x1 >= x2) return tDelta;
if(verbose > 1) {
G4cout << "G4eIonisationSpectrum::SampleEnergy: Z= " << Z
<< "; shell= " << shell
<< "; E(keV)= " << e/keV
<< G4endl;
}
// Access parameters
G4int iMax = 7;
G4DataVector p;
// Access parameters
for (G4int i=0; i<iMax; i++)
{
p.push_back(theParam->Parameter(Z, shell, i, e));
}
G4double g = (e + bindingEnergy)/electron_mass_c2 + 1.;
p.push_back((2.0*g - 1.0)/(g*g));
G4double aria1 = 0.0;
G4double a1 = G4std::min(x1,p[6]);
G4double a2 = G4std::min(x2,p[6]);
if(a1 < a2) aria1 = IntSpectrum(a1, a2, p);
G4double aria2 = 0.0;
G4double a3 = G4std::max(x1,p[6]);
G4double a4 = G4std::max(x2,p[6]);
if(a3 < a4) aria2 = IntSpectrum(a3, a4, p);
G4double aria = (aria1 + aria2)*G4UniformRand();
G4double amaj, fun, q, x;
//======= First aria to sample =====
if(aria <= aria1) {
amaj = p[4];
a1 = 1./a1;
a2 = 1./a2;
//======= Second aria to sample =====
} else {
amaj = p[5];
a1 = 1./a3;
a2 = 1./a4;
}
amaj *= 1.25;
do {
x = 1./(a2 + G4UniformRand()*(a1 - a2));
fun = Function(x, p);
if(fun > amaj) {
G4cout << "WARNING in G4eIonisationSpectrum::SampleEnergy:"
<< " Majoranta " << amaj
<< " < " << fun
<< G4endl;
}
q = amaj*G4UniformRand();
} while (q >= fun);
p.clear();
tDelta = x*(e + bindingEnergy) - bindingEnergy;
if(verbose > 1) {
G4cout << "tcut(MeV)= " << tMin/MeV
<< "; tMax(MeV)= " << tMax/MeV
<< "; x1= " << x1
<< "; x2= " << x2
<< "; a1= " << a1
<< "; a2= " << a2
<< "; x= " << x
<< "; be= " << bindingEnergy
<< "; e= " << e
<< "; tDelta= " << tDelta
<< G4endl;
}
return tDelta;
}
G4double G4eIonisationSpectrum::IntSpectrum(G4double xMin,
G4double xMax,
const G4DataVector& p) const
{
// Please comment what IntSpectrum does
G4double x1 = 1./xMin;
G4double x2 = 1./xMax;
G4double x = x1 - x2 - p[7]*log(xMax/xMin) + (1. - p[7])*(xMax - xMin)
+ 1./(1. - xMax) - 1./(1. - xMin)
+ p[7]*log((1. - xMax)/(1. - xMin))
+ 0.5*p[1]*p[3]*(x1*x1 - x2*x2);
if(x < 0.0) x = 0.0;
return x;
}
G4double G4eIonisationSpectrum::AverageValue(G4double xMin,
G4double xMax,
const G4DataVector& p) const
{
// G4double x1 = 1.;
// G4double x2 = 1.;
G4double x = log(xMax/xMin)
+ 0.5*(1. - p[7])*(xMax*xMax - xMin*xMin)
+ 1./(1. - xMax) - 1./(1. - xMin)
+ (1. + p[7])*log((1. - xMax)/(1. - xMin))
+ p[1]*p[3]*(1./xMin - 1./xMax);
if(x < 0.0) x = 0.0;
return x;
}
G4double G4eIonisationSpectrum::Function(G4double x,
const G4DataVector& p) const
{
// Please comment what Function does
// G4double x1 = 1.0;
G4double f = 1.0 - p[7]*x + x*x*(1.0 - p[7]
+ (1.0/(1.0 - x) - p[7])/(1.0 - x) )
+ p[1]*p[3]/x;
if(f < 0.0) f = 0.0;
return f;
}
G4double G4eIonisationSpectrum::Excitation(G4int Z, G4double e) const
{
return theParam->Excitation(Z, e);
}
void G4eIonisationSpectrum::PrintData() const
{
theParam->PrintData();
}
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4eLowEnergyLoss.cc,v 1.9.2.2 2001/06/28 20:19:32 gunter Exp $
// GEANT4 tag $Name: $
// $Id: G4eLowEnergyLoss.cc,v 1.23 2001/11/23 11:45:29 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
//
// -----------------------------------------------------------
// GEANT 4 class implementation file
@@ -32,7 +32,6 @@
// ---------- G4eLowEnergyLoss physics process -----------
// by Laszlo Urban, 20 March 1997
// **************************************************************
// It is the first implementation of the NEW UNIFIED ENERGY LOSS PROCESS.
// It calculates the energy loss of e+/e-.
// --------------------------------------------------------------
//
@@ -48,7 +47,14 @@
// 10/02/00 modifications , new e.m. structure, L.Urban
// 11/04/00: Bug fix in dE/dx fluctuation simulation, Veronique Lefebure
// 19-09-00 change of fluctuation sampling V.Ivanchenko
// 20/09/00 update fluctuations V.Ivanchenko
// 20/09/00 update fluctuations V.Ivanchenko
// 18/10/01 add fluorescence AlongStepDoIt V.Ivanchenko
// 18/10/01 Revision to improve code quality and consistency with design, MGP
// 19/10/01 update according to new design, V.Ivanchenko
// 24/10/01 MGP - Protection against negative energy loss in AlongStepDoIt
// 26/10/01 VI Clean up access to deexcitation
// 23/11/01 VI Move static member-functions from header to source
//
// --------------------------------------------------------------
#include "G4eLowEnergyLoss.hh"
@@ -137,6 +143,55 @@ G4eLowEnergyLoss::~G4eLowEnergyLoss()
}
}
void G4eLowEnergyLoss::SetNbOfProcesses(G4int nb)
{
NbOfProcesses=nb;
}
void G4eLowEnergyLoss::PlusNbOfProcesses()
{
NbOfProcesses++;
}
void G4eLowEnergyLoss::MinusNbOfProcesses()
{
NbOfProcesses--;
}
G4int G4eLowEnergyLoss::GetNbOfProcesses()
{
return NbOfProcesses;
}
void G4eLowEnergyLoss::SetLowerBoundEloss(G4double val)
{
LowerBoundEloss=val;
}
void G4eLowEnergyLoss::SetUpperBoundEloss(G4double val)
{
UpperBoundEloss=val;
}
void G4eLowEnergyLoss::SetNbinEloss(G4int nb)
{
NbinEloss=nb;
}
G4double G4eLowEnergyLoss::GetLowerBoundEloss()
{
return LowerBoundEloss;
}
G4double G4eLowEnergyLoss::GetUpperBoundEloss()
{
return UpperBoundEloss;
}
G4int G4eLowEnergyLoss::GetNbinEloss()
{
return NbinEloss;
}
//
void G4eLowEnergyLoss::BuildDEDXTable(
@@ -154,8 +209,7 @@ void G4eLowEnergyLoss::BuildDEDXTable(
// different processes.
//
const G4MaterialTable* theMaterialTable=G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
// create table for the total energy loss
@@ -334,15 +388,13 @@ G4VParticleChange* G4eLowEnergyLoss::AlongStepDoIt( const G4Track& trackData,
// get particle and material pointers from trackData
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle();
G4double E = aParticle->GetKineticEnergy() ;
// G4cout << "MGP -- Along eInit " << E/keV << " keV " << G4endl;
G4Material* aMaterial = trackData.GetMaterial();
// G4int index = aMaterial->GetIndex();
G4double Step = stepData.GetStepLength();
fParticleChange.Initialize(trackData);
aParticleChange.Initialize(trackData);
//fParticleChange.Initialize(trackData);
G4double MeanLoss, finalT;
@@ -386,18 +438,64 @@ G4VParticleChange* G4eLowEnergyLoss::AlongStepDoIt( const G4Track& trackData,
if (finalT <= 0. )
{
finalT = 0.;
if (Charge < 0.) fParticleChange.SetStatusChange(fStopAndKill);
else fParticleChange.SetStatusChange(fStopButAlive);
if (Charge < 0.) aParticleChange.SetStatusChange(fStopAndKill);
else aParticleChange.SetStatusChange(fStopButAlive);
}
// MGP debug
// G4cout << "MGP AlongStepDoIt finalT = " << finalT/keV << " keV" << G4endl;
G4double edep = E - finalT;
aParticleChange.SetEnergyChange(finalT);
// Deexcitation of ionised atoms
G4std::vector<G4DynamicParticle*>* deexcitationProducts =
DeexciteAtom(aMaterial,E,edep);
fParticleChange.SetEnergyChange(finalT);
fParticleChange.SetLocalEnergyDeposit(E-finalT);
size_t nSecondaries = deexcitationProducts->size();
aParticleChange.SetNumberOfSecondaries(nSecondaries);
if (nSecondaries > 0) {
return &fParticleChange;
const G4StepPoint* preStep = stepData.GetPreStepPoint();
const G4StepPoint* postStep = stepData.GetPostStepPoint();
G4ThreeVector r = preStep->GetPosition();
G4ThreeVector deltaR = postStep->GetPosition();
deltaR -= r;
G4double t = preStep->GetGlobalTime();
G4double deltaT = postStep->GetGlobalTime();
deltaT -= t;
G4double time, q;
G4ThreeVector position;
for (size_t i=0; i<nSecondaries; i++) {
G4DynamicParticle* part = (*deexcitationProducts)[i];
if (part != 0) {
G4double eSecondary = part->GetKineticEnergy();
edep -= eSecondary;
if (edep > 0.)
{
q = G4UniformRand();
time = deltaT*q + t;
position = deltaR*q;
position += r;
G4Track* newTrack = new G4Track(part, time, position);
aParticleChange.AddSecondary(newTrack);
}
else
{
edep += eSecondary;
delete part;
part = 0;
}
}
}
}
delete deexcitationProducts;
aParticleChange.SetLocalEnergyDeposit(edep);
return &aParticleChange;
}
//
@@ -34,6 +34,7 @@
//
// Modifications:
// 20/07/2000 V.Ivanchenko First implementation
// 18/06/2001 V.Ivanchenko Continuation for eff.charge (small change of y)
//
// Class Description:
//
@@ -210,7 +211,7 @@ G4double G4hIonEffChargeSquare::IonEffChargeSquare(
} else {
for (G4int iel=0; iel<NumberOfElements; iel++)
{
const G4Element* element = (*theElementVector)(iel) ;
const G4Element* element = (*theElementVector)[iel] ;
G4double z2 = element->GetZ() ;
const G4double weight = theAtomicNumDensityVector[iel] ;
norm += weight ;
@@ -254,7 +255,7 @@ G4double G4hIonEffChargeSquare::IonEffChargeSquare(
// Slower than Fermi velocity
} else {
y = 0.75 * vF * (1.0 + 2.0*v1*v1/3.0 + v1*v1*v1*v1/15.0) / (z13*z13) ;
y = 0.6923 * vF * (1.0 + 2.0*v1*v1/3.0 + v1*v1*v1*v1/15.0) / (z13*z13) ;
}
G4double y3 = pow(y, 0.3) ;
@@ -65,6 +65,10 @@
// 10 May 2001 V.Ivanchenko Clean up againist Linux compilation with -Wall
// 23 May 2001 V.Ivanchenko Minor fix in PostStepDoIt
// 07 June 2001 V.Ivanchenko Clean up AntiProtonDEDX + add print out
// 18 June 2001 V.Ivanchenko Cleanup print out
// 18 Oct. 2001 V.Ivanchenko Add fluorescence
// 30 Oct. 2001 V.Ivanchenko Add minGammaEnergy and minElectronEnergy
// 07 Dec 2001 V.Ivanchenko Add SetFluorescence method
// -----------------------------------------------------------------------
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -80,6 +84,15 @@
#include "G4Material.hh"
#include "G4DynamicParticle.hh"
#include "G4ParticleDefinition.hh"
#include "G4AtomicDeexcitation.hh"
#include "G4ShellVacancy.hh"
#include "G4hShellCrossSection.hh"
#include "G4VEMDataSet.hh"
#include "G4EMDataSet.hh"
#include "G4CompositeEMDataSet.hh"
#include "G4Gamma.hh"
#include "G4LogLogInterpolation.hh"
#include "G4SemiLogInterpolation.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -98,7 +111,10 @@ G4hLowEnergyIonisation::G4hLowEnergyIonisation(const G4String& processName)
nStopping(true),
theBarkas(true),
theMeanFreePathTable(0),
paramStepLimit (0.005)
paramStepLimit (0.005),
shellVacancy(0),
shellCS(0),
theFluo(true)
{
InitializeMe();
}
@@ -110,11 +126,15 @@ void G4hLowEnergyIonisation::InitializeMe()
LowestKineticEnergy = 10.0*eV ;
HighestKineticEnergy = 100.0*TeV ;
MinKineticEnergy = 10.0*eV ;
TotBin = 200 ;
TotBin = 200 ;
protonLowEnergy = 1.*keV ;
protonHighEnergy = 2.*MeV ;
antiProtonLowEnergy = 1.*keV ;
antiProtonHighEnergy = 2.*MeV ;
minGammaEnergy = 25.*keV;
minElectronEnergy = 25.*keV;
verboseLevel = 0;
shellCS = new G4hShellCrossSection();
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -132,6 +152,16 @@ G4hLowEnergyIonisation::~G4hLowEnergyIonisation()
if(theIonEffChargeModel)delete theIonEffChargeModel;
if(theIonChuFluctuationModel)delete theIonChuFluctuationModel;
if(theIonYangFluctuationModel)delete theIonYangFluctuationModel;
if(shellVacancy) delete shellVacancy;
if(shellCS) delete shellCS;
cutForDelta.clear();
G4int length = zFluoDataVector.size();
if(length) {
for(G4int i=0; i<length; i++) {
delete &(zFluoDataVector[i]);
}
zFluoDataVector.clear();
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -156,10 +186,6 @@ void G4hLowEnergyIonisation::InitializeParametrisation()
G4Proton* theProton = G4Proton::Proton();
G4AntiProton* theAntiProton = G4AntiProton::AntiProton();
// cuts for electron
G4Electron* theElectron = G4Electron::Electron();
deltaCutInKineticEnergy = theElectron->GetCutsInEnergy() ;
// Define models for parametrisation of electronic energy losses
theBetheBlochModel = new G4hBetheBlochModel("Bethe-Bloch") ;
theProtonModel = new G4hParametrisedLossModel(theProtonTable) ;
@@ -197,15 +223,55 @@ void G4hLowEnergyIonisation::BuildPhysicsTable(
G4cout << "G4hLowEnergyIonisation::BuildPhysicsTable for "
<< aParticleType.GetParticleName() << G4endl;
}
InitializeParametrisation() ;
G4Proton* theProton = G4Proton::Proton();
G4AntiProton* theAntiProton = G4AntiProton::AntiProton();
G4Electron* theElectron = G4Electron::Electron();
charge = aParticleType.GetPDGCharge()/eplus ;
chargeSquare = charge*charge ;
G4double electronCutInRange = theElectron->GetCuts();
// ---- MGP ---- workaround for the deprecated "cuts per material"
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
const G4Material* material = (*theMaterialTable)[0];
G4double electronCutInRange = G4Electron::Electron()->GetEnergyThreshold(material);
// was = G4Electron::Electron()->GetCuts();
// ---- MGP ----
// Define cuts
// create table
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
cutForDelta.clear();
cutForGamma.clear();
for (G4int j=0; j<numOfMaterials; j++) {
// get material parameters needed for the energy loss calculation
const G4Material* material= (*theMaterialTable)[j];
// the cut cannot be below lowest limit
G4double tCut = G4Electron::Electron()->GetEnergyThreshold(material);
if(tCut > HighestKineticEnergy) tCut = HighestKineticEnergy;
G4double excEnergy = material->GetIonisation()->GetMeanExcitationEnergy();
tCut = G4std::max(tCut,excEnergy);
cutForDelta.push_back(tCut);
// the cut cannot be below lowest limit
tCut = G4Gamma::Gamma()->GetEnergyThreshold(material);
if(tCut > HighestKineticEnergy) tCut = HighestKineticEnergy;
tCut = G4std::max(tCut,minGammaEnergy);
cutForGamma.push_back(tCut);
}
if(verboseLevel > 0) {
G4cout << "Cuts are defined " << G4endl;
}
if(0.0 < charge)
{
@@ -235,6 +301,7 @@ void G4hLowEnergyIonisation::BuildPhysicsTable(
}
BuildLambdaTable(aParticleType) ;
BuildDataForFluorescence(aParticleType);
if(verboseLevel > 0) {
G4cout << "G4hLowEnergyIonisation::BuildPhysicsTable: "
@@ -276,7 +343,7 @@ void G4hLowEnergyIonisation::BuildLossTable(
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
// create table
G4int numOfMaterials = theMaterialTable->length();
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
if ( theLossTable) {
theLossTable->clearAndDestroy();
@@ -344,12 +411,140 @@ void G4hLowEnergyIonisation::BuildLossTable(
}
// now put the loss into the vector
if(verboseLevel > 1) {
G4cout << "E(MeV)= " << lowEdgeEnergy/MeV
<< " dE/dx(MeV/mm)= " << ionloss*mm/MeV
<< " in " << material->GetName() << G4endl;
}
aVector->PutValue(i,ionloss) ;
}
// Insert vector for this material into the table
theLossTable->insert(aVector) ;
}
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4hLowEnergyIonisation::BuildDataForFluorescence(
const G4ParticleDefinition& aParticleType)
{
if(verboseLevel > 1) {
G4cout << "G4hLowEnergyIonisation::BuildDataForFluorescence for "
<< aParticleType.GetParticleName() << " is started" << G4endl;
}
// fill data for fluorescence
G4double mass = aParticleType.GetPDGMass();
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
// create table
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
if (shellVacancy != 0) delete shellVacancy;
shellVacancy = new G4ShellVacancy();
G4DataVector* ksi = 0;
G4DataVector* ksi1 = 0;
G4DataVector* energy = 0;
G4DataVector* energy1 = 0;
size_t binForFluo = TotBin/10;
G4int length = zFluoDataVector.size();
if(length > 0) {
for(G4int i=0; i<length; i++) {
G4VEMDataSet* x = zFluoDataVector[i];
delete x;
}
zFluoDataVector.clear();
}
G4PhysicsLogVector* bVector = new G4PhysicsLogVector(LowestKineticEnergy,
HighestKineticEnergy,
binForFluo);
G4AtomicTransitionManager* transitionManager =
G4AtomicTransitionManager::Instance();
G4double bindingEnergy;
// G4double x;
// G4double y;
// loop for materials
for (G4int j=0; j<numOfMaterials; j++) {
// get material parameters needed for the energy loss calculation
const G4Material* material= (*theMaterialTable)[j];
const G4ElementVector* theElementVector = material->GetElementVector();
size_t NumberOfElements = material->GetNumberOfElements() ;
const G4double* theAtomicNumDensityVector =
material->GetAtomicNumDensityVector();
G4VDataSetAlgorithm* interp = new G4SemiLogInterpolation();
G4VEMDataSet* xsis = new G4CompositeEMDataSet(interp, 1., 1.);
G4VDataSetAlgorithm* interp1 = new G4SemiLogInterpolation();
G4VEMDataSet* xsis1 = new G4CompositeEMDataSet(interp1, 1., 1.);
G4double tCut = cutForDelta[j];
G4double elDensity = 1.;
for (size_t iel=0; iel<NumberOfElements; iel++ ) {
G4int Z = (G4int)((*theElementVector)[iel]->GetZ());
energy = new G4DataVector();
ksi = new G4DataVector();
energy1= new G4DataVector();
ksi1 = new G4DataVector();
//if(NumberOfElements > 1)
elDensity = theAtomicNumDensityVector[iel];
for (size_t j = 0; j<binForFluo; j++) {
G4double tkin = bVector->GetLowEdgeEnergy(j);
G4double gamma = tkin/mass + 1.;
G4double r = electron_mass_c2/mass;
G4double tmax = 2.*mass*r*(gamma*gamma - 1.)/(1. + 2.*gamma*r + r*r);
G4double cross = 0.;
G4double cross1 = 0.;
G4double eAverage= 0.;
G4int nShells = transitionManager->NumberOfShells(Z);
G4double tmin = G4std::min(tCut,tmax);
for (G4int n=0; n<nShells; n++) {
bindingEnergy = transitionManager->Shell(Z, n)->BindingEnergy();
eAverage += elDensity*log(tmin/bindingEnergy + 1.);
cross += elDensity*tmin/((bindingEnergy + tmin)*bindingEnergy);
cross1 += elDensity*(tmax - tmin)/
((tmax + bindingEnergy)*(tmin + bindingEnergy));
}
energy1->push_back(tkin);
ksi1->push_back(cross1);
if(eAverage > 0.) cross /= eAverage;
else cross = 0.;
energy->push_back(tkin);
ksi->push_back(cross);
}
G4VDataSetAlgorithm* algo = interp->Clone();
G4VEMDataSet* set = new G4EMDataSet(Z,energy,ksi,algo,1.,1.);
xsis->AddComponent(set);
G4VDataSetAlgorithm* algo1 = interp1->Clone();
G4VEMDataSet* set1 = new G4EMDataSet(Z,energy1,ksi1,algo1,1.,1.);
xsis1->AddComponent(set1);
}
if(verboseLevel > 1) {
G4cout << "### Shell inverse cross sections for "
<< material->GetName() << G4endl;
xsis->PrintData();
G4cout << "### Atom cross sections for "
<< material->GetName() << G4endl;
xsis1->PrintData();
}
shellVacancy->AddXsiTable(xsis);
zFluoDataVector.push_back(xsis1);
}
delete bVector;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -361,13 +556,19 @@ void G4hLowEnergyIonisation::BuildLambdaTable(
// Build mean free path tables for the delta ray production process
// tables are built for MATERIALS
if(verboseLevel > 1) {
G4cout << "G4hLowEnergyIonisation::BuildLambdaTable for "
<< aParticleType.GetParticleName() << " is started" << G4endl;
}
G4double lowEdgeEnergy, value;
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
charge = aParticleType.GetPDGCharge()/eplus ;
chargeSquare = charge*charge ;
//create table
G4int numOfMaterials = theMaterialTable->length();
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
if (theMeanFreePathTable) {
theMeanFreePathTable->clearAndDestroy();
@@ -375,11 +576,7 @@ void G4hLowEnergyIonisation::BuildLambdaTable(
}
theMeanFreePathTable = new G4PhysicsTable(numOfMaterials);
// get electron and particle cuts in kinetic energy
// deltaCutInKineticEnergy = theElectron->GetCutsInEnergy() ;
// loop for materials
for (G4int J=0 ; J < numOfMaterials; J++) {
@@ -397,15 +594,13 @@ void G4hLowEnergyIonisation::BuildLambdaTable(
const G4double* theAtomicNumDensityVector =
material->GetAtomicNumDensityVector();
const G4int NumberOfElements = material->GetNumberOfElements() ;
G4double excEnergy = material->GetIonisation()->GetMeanExcitationEnergy();
// get the electron kinetic energy cut for the actual material,
// it will be used in ComputeMicroscopicCrossSection
// ( it is the SAME for ALL the ELEMENTS in THIS MATERIAL )
// ------------------------------------------------------
// Cut in Delta energy is limited by exitation energy
G4double deltaCut = G4std::max(excEnergy,deltaCutInKineticEnergy[J]) ;
G4double deltaCut = cutForDelta[J];
for ( G4int i = 0 ; i < TotBin ; i++ ) {
lowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
@@ -419,7 +614,7 @@ void G4hLowEnergyIonisation::BuildLambdaTable(
ComputeMicroscopicCrossSection(
aParticleType,
lowEdgeEnergy,
(*theElementVector)(iel)->GetZ(),
(*theElementVector)[iel]->GetZ(),
deltaCut ) ;
}
@@ -429,9 +624,10 @@ void G4hLowEnergyIonisation::BuildLambdaTable(
aVector->PutValue(i, value) ;
}
theMeanFreePathTable->insert(aVector);
}
}
@@ -492,6 +688,33 @@ G4double G4hLowEnergyIonisation::ComputeMicroscopicCrossSection(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4hLowEnergyIonisation::GetMeanFreePath(const G4Track& trackData,
G4double previousStepSize,
enum G4ForceCondition* condition)
{
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle() ;
G4Material* aMaterial = trackData.GetMaterial() ;
G4double meanFreePath;
G4bool isOutRange ;
*condition = NotForced ;
G4double kineticEnergy = aParticle->GetKineticEnergy() ;
if(kineticEnergy < LowestKineticEnergy) meanFreePath = DBL_MAX;
else {
if(kineticEnergy > HighestKineticEnergy)
kineticEnergy = HighestKineticEnergy ;
meanFreePath = ((*theMeanFreePathTable)(aMaterial->GetIndex()))->
GetValue(kineticEnergy,isOutRange) ;
}
return meanFreePath ;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4hLowEnergyIonisation::GetConstraints(
const G4DynamicParticle* particle,
const G4Material* material)
@@ -569,8 +792,9 @@ G4double G4hLowEnergyIonisation::GetConstraints(
// Normal energy
} else {
fRangeNow = G4EnergyLossTables::GetRange(theAntiProton, tscaled, material) ;
dx = G4EnergyLossTables::GetRange(theAntiProton, highEnergy, material) ;
fRangeNow = G4EnergyLossTables::GetRange(theAntiProton, tscaled,
material);
dx = G4EnergyLossTables::GetRange(theAntiProton, highEnergy, material);
if(tscaled > highEnergy) {
fdEdx = G4EnergyLossTables::GetDEDX(theAntiProton, tscaled, material)
@@ -578,7 +802,7 @@ G4double G4hLowEnergyIonisation::GetConstraints(
// For Bragg's peak dE/dx is recalculated
} else {
fdEdx = AntiProtonParametrisedDEDX(material, tscaled) * chargeSquare ;
fdEdx = AntiProtonParametrisedDEDX(material, tscaled) * chargeSquare;
}
}
}
@@ -620,6 +844,7 @@ G4VParticleChange* G4hLowEnergyIonisation::AlongStepDoIt(
G4double finalT = 0.0 ;
aParticleChange.Initialize(trackData) ;
G4Material* material = trackData.GetMaterial() ;
// get the actual (true) Step length from stepData
@@ -652,9 +877,17 @@ G4VParticleChange* G4hLowEnergyIonisation::AlongStepDoIt(
G4double eFinal = kineticEnergy - step*fdEdx - nloss ;
if(0.0 < eFinal) {
eloss = (fdEdx +
ProtonParametrisedDEDX(material,eFinal*massRatio)*chargeSquare)
* step * 0.5 ;
G4double ts = eFinal*massRatio;
G4double fdEdx1 = ProtonParametrisedDEDX(material,ts)*chargeSquare;
// Correction for positive ions
//if(theBarkas && 1.0 < charge) {
// fdEdx1 += BarkasTerm(material,ts)*(charge -1.0) * chargeSquare ;
// fdEdx1 += BlochTerm(material,ts,chargeSquare) ;
// fdEdx1 -= BlochTerm(material,ts,1.0) ;
// }
eloss = (fdEdx + fdEdx1) * step * 0.5 ;
} else {
eloss = kineticEnergy - nloss ;
}
@@ -707,29 +940,84 @@ G4VParticleChange* G4hLowEnergyIonisation::AlongStepDoIt(
eloss = step*fdEdx ;
}
}
if(eloss < 0.0) eloss = 0.0;
finalT = kineticEnergy - eloss - nloss ;
finalT = kineticEnergy - eloss - nloss;
if( EnlossFlucFlag && 0.0 < eloss ) {
// now the electron loss with fluctuation
eloss = ElectronicLossFluctuation(particle, material, eloss, step) ;
finalT = kineticEnergy - eloss - nloss ;
if(eloss < 0.0) eloss = 0.0;
finalT = kineticEnergy - eloss - nloss;
}
// stop particle if the kinetic energy <= MinKineticEnergy
if (finalT <= MinKineticEnergy )
{
finalT = 0.0 ;
if( "proton" == (particle->GetDefinition()->GetParticleName()) )
if (finalT <= MinKineticEnergy ) {
finalT = 0.0;
if( "proton" == (particle->GetDefinition()->GetParticleName()) )
aParticleChange.SetStatusChange(fStopAndKill);
else
else
aParticleChange.SetStatusChange(fStopButAlive);
}
aParticleChange.SetEnergyChange( finalT ) ;
aParticleChange.SetLocalEnergyDeposit(kineticEnergy-finalT) ;
}
aParticleChange.SetEnergyChange( finalT );
G4double edep = kineticEnergy-finalT;
// Deexcitation only of ionised atoms
eloss = G4std::min(edep, eloss);
G4double hMass = particle->GetMass();
G4std::vector<G4DynamicParticle*>* newpart = 0;
G4DynamicParticle* part = 0;
if(theFluo) newpart = DeexciteAtom(material, kineticEnergy, hMass, eloss);
if(newpart != 0) {
size_t nSecondaries = newpart->size();
aParticleChange.SetNumberOfSecondaries(nSecondaries);
G4Track* newtrack = 0;
const G4StepPoint* preStep = stepData.GetPreStepPoint();
const G4StepPoint* postStep = stepData.GetPostStepPoint();
G4ThreeVector r = preStep->GetPosition();
G4ThreeVector deltaR = postStep->GetPosition();
deltaR -= r;
G4double t = preStep->GetGlobalTime();
G4double deltaT = postStep->GetGlobalTime();
deltaT -= t;
G4double time, q, e;
G4ThreeVector position;
for(size_t i=0; i<nSecondaries; i++) {
part = (*newpart)[i];
if(part) {
e = part->GetKineticEnergy();
if(e <= edep) {
edep -= e;
q = G4UniformRand();
time = deltaT*q + t;
position = deltaR*q;
position += r;
newtrack = new G4Track(part, time, position);
aParticleChange.AddSecondary(newtrack);
} else {
delete part;
}
}
}
delete newpart;
}
aParticleChange.SetLocalEnergyDeposit(edep);
return &aParticleChange ;
}
@@ -755,7 +1043,7 @@ G4double G4hLowEnergyIonisation::ProtonParametrisedDEDX(
// Delta rays energy
eloss -= DeltaRaysEnergy(material,kineticEnergy,proton_mass_c2) ;
if(verboseLevel > 1) {
if(verboseLevel > 2) {
G4cout << "p E(MeV)= " << kineticEnergy/MeV
<< " dE/dx(MeV/mm)= " << eloss*mm/MeV
<< " for " << material->GetName()
@@ -805,7 +1093,7 @@ G4double G4hLowEnergyIonisation::AntiProtonParametrisedDEDX(
// Delta rays energy
eloss -= DeltaRaysEnergy(material,kineticEnergy,proton_mass_c2) ;
if(verboseLevel > 0) {
if(verboseLevel > 2) {
G4cout << "pbar E(MeV)= " << kineticEnergy/MeV
<< " dE/dx(MeV/mm)= " << eloss*mm/MeV
<< " for " << material->GetName()
@@ -826,7 +1114,7 @@ G4double G4hLowEnergyIonisation::DeltaRaysEnergy(
{
G4double dloss = 0.0 ;
G4double deltaCutNow = deltaCutInKineticEnergy[(material->GetIndex())] ;
G4double deltaCutNow = cutForDelta[(material->GetIndex())] ;
G4double electronDensity = material->GetElectronDensity();
G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
@@ -861,58 +1149,43 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
{
// Units are expressed in GEANT4 internal units.
G4double KineticEnergy,TotalEnergy,TotalMomentum,
betasquare,MaxKineticEnergyTransfer,
G4double KineticEnergy,TotalEnergy,TotalMomentum,betasquare,
DeltaKineticEnergy,DeltaTotalMomentum,costheta,sintheta,phi,
dirx,diry,dirz,finalKineticEnergy,finalPx,finalPy,finalPz,
x,xc,grej,Psquare,Esquare,summass,rate,finalMomentum ;
x,xc,grej,Psquare,Esquare,rate,finalMomentum ;
aParticleChange.Initialize(trackData) ;
G4Material* aMaterial = trackData.GetMaterial() ;
G4double Eexc = aMaterial->GetIonisation()->GetMeanExcitationEnergy();
const G4DynamicParticle* aParticle = trackData.GetDynamicParticle() ;
// some kinematics
ParticleMass=aParticle->GetDefinition()->GetPDGMass();
KineticEnergy=aParticle->GetKineticEnergy();
TotalEnergy=KineticEnergy + ParticleMass ;
Psquare=KineticEnergy*(TotalEnergy+ParticleMass) ;
Esquare=TotalEnergy*TotalEnergy ;
summass = ParticleMass + electron_mass_c2 ;
G4ParticleMomentum ParticleDirection = aParticle->GetMomentumDirection() ;
Esquare=TotalEnergy*TotalEnergy;
betasquare=Psquare/Esquare;
G4ThreeVector ParticleDirection = aParticle->GetMomentumDirection() ;
// get kinetic energy cut for the electron....
G4double DeltaCutInKineticEnergyNow =
deltaCutInKineticEnergy[aMaterial->GetIndex()];
// some kinematics......................
G4double gamma= KineticEnergy/ParticleMass + 1.;
G4double r = electron_mass_c2/ParticleMass;
G4double tmax = 2.*ParticleMass*r*(gamma*gamma - 1.)/(1. + 2.*gamma*r + r*r);
betasquare=Psquare/Esquare ;
MaxKineticEnergyTransfer = 2.*electron_mass_c2*Psquare
/(summass*summass+2.*electron_mass_c2*KineticEnergy);
// Validity range for delta electron cross section
G4double DeltaCut = G4std::max(DeltaCutInKineticEnergyNow,Eexc);
G4double DeltaCut = cutForDelta[aMaterial->GetIndex()];
// This should not be a case
if(DeltaCut >= tmax)
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
// sampling kinetic energy of the delta ray
if( MaxKineticEnergyTransfer <= DeltaCut )
{
// pathological case (it should not happen ,
// there is no change at all).....
xc = DeltaCut / tmax;
rate = tmax / TotalEnergy;
rate = rate*rate ;
G4double spin = aParticle->GetDefinition()->GetPDGSpin() ;
return &aParticleChange;
//return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
}
else
{
// normal case ......................................
xc = DeltaCut / MaxKineticEnergyTransfer ;
rate = MaxKineticEnergyTransfer / TotalEnergy ;
rate = rate*rate ;
G4double spin = aParticle->GetDefinition()->GetPDGSpin() ;
// sampling follows ...
// sampling follows ...
do {
x=xc/(1.-(1.-xc)*G4UniformRand());
@@ -929,13 +1202,10 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
}
} while( G4UniformRand() > grej );
}
DeltaKineticEnergy = x * MaxKineticEnergyTransfer ;
if(DeltaKineticEnergy <= 0.)
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
DeltaKineticEnergy = x * tmax;
DeltaTotalMomentum = sqrt(DeltaKineticEnergy * (DeltaKineticEnergy +
2. * electron_mass_c2 )) ;
TotalMomentum = sqrt(Psquare) ;
@@ -950,7 +1220,7 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
// direction of the delta electron ........
phi = twopi * G4UniformRand() ;
sintheta = sqrt((1.+costheta)*(1.-costheta));
sintheta = sqrt(1. - costheta*costheta);
dirx = sintheta * cos(phi) ;
diry = sintheta * sin(phi) ;
dirz = costheta ;
@@ -968,8 +1238,69 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
// fill aParticleChange
finalKineticEnergy = KineticEnergy - DeltaKineticEnergy ;
G4double Edep = 0 ;
// Generation of Fluorescence and Auger
size_t nSecondaries = 0;
size_t totalNumber = 1;
G4std::vector<G4DynamicParticle*>* secondaryVector = 0;
G4DynamicParticle* aSecondary = 0;
G4ParticleDefinition* type = 0;
// Select atom and shell
G4int Z = SelectRandomAtom(aMaterial, KineticEnergy);
G4int shell = shellCS->SelectRandomShell(Z, KineticEnergy,
ParticleMass,DeltaKineticEnergy);
const G4AtomicShell* atomicShell =
(G4AtomicTransitionManager::Instance())->Shell(Z, shell);
G4double bindingEnergy = atomicShell->BindingEnergy();
if(verboseLevel > 1) {
G4cout << "PostStep Z= " << Z << " shell= " << shell
<< " bindingE(keV)= " << bindingEnergy/keV
<< " finalE(keV)= " << finalKineticEnergy/keV
<< G4endl;
}
// Fluorescence data start from element 6
if (theFluo && Z > 5 && finalKineticEnergy >= bindingEnergy
&& (bindingEnergy >= minGammaEnergy
|| bindingEnergy >= minElectronEnergy) ) {
G4int shellId = atomicShell->ShellId();
secondaryVector = deexcitationManager.GenerateParticles(Z, shellId);
if (secondaryVector != 0) {
nSecondaries = secondaryVector->size();
for (size_t i = 0; i<nSecondaries; i++) {
aSecondary = (*secondaryVector)[i];
if (aSecondary) {
G4double e = aSecondary->GetKineticEnergy();
type = aSecondary->GetDefinition();
if (e < finalKineticEnergy &&
((type == G4Gamma::Gamma() && e > minGammaEnergy ) ||
(type == G4Electron::Electron() && e > minElectronEnergy ))) {
finalKineticEnergy -= e;
totalNumber++;
} else {
delete aSecondary;
(*secondaryVector)[i] = 0;
}
}
}
}
}
// Save delta-electrons
G4double edep = 0.0;
if (finalKineticEnergy > MinKineticEnergy)
{
finalPx = TotalMomentum*ParticleDirection.x()
@@ -988,23 +1319,191 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
}
else
{
finalKineticEnergy = 0. ;
Edep = finalKineticEnergy ;
edep = finalKineticEnergy;
finalKineticEnergy = 0.;
aParticleChange.SetMomentumChange(ParticleDirection.x(),
ParticleDirection.y(),ParticleDirection.z());
if (aParticle->GetDefinition()->GetParticleName() == "proton")
aParticleChange.SetStatusChange(fStopAndKill);
else aParticleChange.SetStatusChange(fStopButAlive);
}
aParticleChange.SetEnergyChange( finalKineticEnergy );
aParticleChange.SetNumberOfSecondaries(1);
aParticleChange.AddSecondary( theDeltaRay );
aParticleChange.SetLocalEnergyDeposit (Edep);
aParticleChange.SetLocalEnergyDeposit (edep);
aParticleChange.SetNumberOfSecondaries(totalNumber);
aParticleChange.AddSecondary(theDeltaRay);
// Save Fluorescence and Auger
if (secondaryVector) {
for (size_t l = 0; l < nSecondaries; l++) {
aSecondary = (*secondaryVector)[l];
if(aSecondary) aParticleChange.AddSecondary(aSecondary);
}
delete secondaryVector;
}
return G4VContinuousDiscreteProcess::PostStepDoIt(trackData,stepData);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4std::vector<G4DynamicParticle*>*
G4hLowEnergyIonisation::DeexciteAtom(const G4Material* material,
G4double incidentEnergy,
G4double hMass,
G4double eLoss)
{
if (verboseLevel > 1) {
G4cout << "DeexciteAtom: cutForPhotons(keV)= " << minGammaEnergy/keV
<< " cutForElectrons(keV)= " << minElectronEnergy/keV
<< " eLoss(MeV)= " << eLoss
<< G4endl;
}
if(eLoss < minGammaEnergy && eLoss < minElectronEnergy) return 0;
G4int index = material->GetIndex();
G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
G4double x = cutForDelta[index]/eexc;
G4double deltaEnergy = eexc*(x + 1)*log(x + 1)/x;
G4AtomicTransitionManager* transitionManager =
G4AtomicTransitionManager::Instance();
size_t nElements = material->GetNumberOfElements();
const G4ElementVector* theElementVector = material->GetElementVector();
G4bool stop = true;
for (size_t j=0; j<nElements; j++) {
G4int Z = (G4int)((*theElementVector)[j]->GetZ());
G4double maxE = transitionManager->Shell(Z, 0)->BindingEnergy();
if (Z>5 && (maxE>minGammaEnergy || maxE>minElectronEnergy) ) {
stop = false;
break;
}
}
if(stop) return 0;
// create vector of tracks of secondary particles
G4std::vector<G4DynamicParticle*>* partVector =
new G4std::vector<G4DynamicParticle*>;
G4std::vector<G4DynamicParticle*>* secVector = 0;
G4DynamicParticle* aSecondary = 0;
G4ParticleDefinition* type = 0;
G4double e;
G4ThreeVector position;
G4int shell, shellId;
// sample secondaries
G4double etot = 0.0;
G4std::vector<G4int> n = shellVacancy->GenerateNumberOfIonisations(material,
incidentEnergy, eLoss);
for (size_t i=0; i<nElements; i++) {
size_t nVacancies = n[i];
G4int Z = (G4int)((*theElementVector)[i]->GetZ());
G4double maxE = transitionManager->Shell(Z, 0)->BindingEnergy();
if (nVacancies && Z>5 && (maxE>minGammaEnergy || maxE>minElectronEnergy)) {
for(size_t j=0; j<nVacancies; j++) {
shell = shellCS->SelectRandomShell(Z,incidentEnergy,hMass,deltaEnergy);
shellId = transitionManager->Shell(Z, shell)->ShellId();
G4double maxE = transitionManager->Shell(Z, shell)->BindingEnergy();
if (maxE>minGammaEnergy || maxE>minElectronEnergy ) {
secVector = deexcitationManager.GenerateParticles(Z, shellId);
} else {
secVector = 0;
}
if (secVector) {
for (size_t l = 0; l<secVector->size(); l++) {
aSecondary = (*secVector)[l];
if(aSecondary) {
e = aSecondary->GetKineticEnergy();
type = aSecondary->GetDefinition();
if ( etot + e <= eLoss &&
(type == G4Gamma::Gamma() && e > minGammaEnergy ) ||
(type == G4Electron::Electron() && e > minElectronEnergy)) {
etot += e;
partVector->push_back(aSecondary);
} else {
delete aSecondary;
}
}
}
delete secVector;
}
}
}
}
if(partVector->empty()) {
delete partVector;
return 0;
}
return partVector;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4int G4hLowEnergyIonisation::SelectRandomAtom(const G4Material* material,
G4double kineticEnergy) const
{
G4int nElements = material->GetNumberOfElements();
G4int Z = 0;
if(nElements == 1) {
Z = (G4int)(material->GetZ());
return Z;
}
const G4ElementVector* theElementVector = material->GetElementVector();
G4std::vector<G4double> p;
G4int index = material->GetIndex();
G4double norm = 0.0;
for (G4int j=0; j<nElements; j++) {
const G4VEMDataSet* set = (zFluoDataVector[index])->GetComponent(j);
G4double cross = set->FindValue(kineticEnergy);
p.push_back(cross);
norm += cross;
}
G4double q = norm*G4UniformRand();
for (G4int i=0; i<nElements; i++) {
if(p[i] > q) {
Z = (G4int)((*theElementVector)[i]->GetZ());
break;
}
q -= p[i];
}
return Z;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4double G4hLowEnergyIonisation::ComputeDEDX(
const G4ParticleDefinition* aParticle,
const G4Material* material,
@@ -1113,8 +1612,8 @@ G4double G4hLowEnergyIonisation::BarkasTerm(const G4Material* material,
for (G4int i = 0; i<numberOfElements; i++) {
AMaterial = (*theElementVector)(i)->GetA()*mole/g;
ZMaterial = (*theElementVector)(i)->GetZ();
AMaterial = (*theElementVector)[i]->GetA()*mole/g;
ZMaterial = (*theElementVector)[i]->GetZ();
G4double X = 137.0 * 137.0 * beta2 / ZMaterial;
@@ -1213,7 +1712,7 @@ G4double G4hLowEnergyIonisation::ElectronicLossFluctuation(
// get particle data
G4double tkin = particle->GetKineticEnergy();
G4double particleMass = particle->GetMass() ;
G4double deltaCutInKineticEnergyNow = deltaCutInKineticEnergy[imaterial];
G4double deltaCutInKineticEnergyNow = cutForDelta[imaterial];
// shortcut for very very small loss
if(meanLoss < minLoss) return meanLoss ;
@@ -1431,6 +1930,20 @@ G4double G4hLowEnergyIonisation::ElectronicLossFluctuation(
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4hLowEnergyIonisation::SetCutForSecondaryPhotons(G4double cut)
{
minGammaEnergy = cut;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4hLowEnergyIonisation::SetCutForAugerElectrons(G4double cut)
{
minElectronEnergy = cut;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4hLowEnergyIonisation::PrintInfoDefinition() const
{
G4String comments = " Knock-on electron cross sections . ";
@@ -1461,14 +1974,14 @@ void G4hLowEnergyIonisation::PrintInfoDefinition() const
G4bool printHead = true;
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
G4int numOfMaterials = theMaterialTable->length();
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
// loop for materials
for (G4int j=0 ; j < numOfMaterials; j++) {
const G4Material* material= (*theMaterialTable)[j];
G4double deltaCutNow = deltaCutInKineticEnergy[(material->GetIndex())] ;
G4double deltaCutNow = cutForDelta[(material->GetIndex())] ;
G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
if(eexc > deltaCutNow) {

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