Import Geant4 4.1.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-08 16:39:52 +02:00
parent 921d3b1cda
commit 330b82b769
4524 changed files with 178689 additions and 43575 deletions
@@ -22,7 +22,7 @@
//
//
// $Id: G4AtomicTransitionManager.hh,v 1.2 ????
// GEANT4 tag $Name: geant4-04-00 $
// GEANT4 tag $Name: geant4-04-01 $
//
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
@@ -37,13 +37,18 @@
#include "G4AtomicDeexcitation.hh"
#include "Randomize.hh"
#include "G4Gamma.hh"
#include "G4Electron.hh"
#include "G4AtomicTransitionManager.hh"
#include "G4FluoTransition.hh"
G4AtomicDeexcitation::G4AtomicDeexcitation()
{ }
G4AtomicDeexcitation::G4AtomicDeexcitation():
minGammaEnergy(250.*eV),
minElectronEnergy(250.*eV),
fAuger(false)
{}
G4AtomicDeexcitation::~G4AtomicDeexcitation()
{ }
{}
G4std::vector<G4DynamicParticle*>* G4AtomicDeexcitation::GenerateParticles(G4int Z,G4int shellId)
{
@@ -54,7 +59,7 @@ G4std::vector<G4DynamicParticle*>* G4AtomicDeexcitation::GenerateParticles(G4int
// The aim of this loop is to generate more than one fluorecence photon
// from the same ionizing event
while (provShellId >= 0)
do
{
if (counter == 0)
// First call to GenerateParticles(...):
@@ -62,11 +67,11 @@ G4std::vector<G4DynamicParticle*>* G4AtomicDeexcitation::GenerateParticles(G4int
{
provShellId = SelectTypeOfTransition(Z, shellId);
if ( provShellId >0)
if ( provShellId >0)
{
aParticle = GenerateFluorescence(Z,shellId,provShellId);
}
else if ( provShellId ==-1)
else if ( provShellId == -1)
{
aParticle = GenerateAuger(Z, shellId);
}
@@ -80,22 +85,24 @@ G4std::vector<G4DynamicParticle*>* G4AtomicDeexcitation::GenerateParticles(G4int
// newShellId is given by GenerateFluorescence(...)
{
provShellId = SelectTypeOfTransition(Z,newShellId);
if ( provShellId >0)
if (provShellId >0)
{
aParticle = GenerateFluorescence(Z,newShellId,provShellId);
}
else if ( provShellId ==-1)
else if ( provShellId == -1)
{
aParticle = GenerateAuger(Z, newShellId);
}
}
else
{
G4Exception("G4AtomicDeexcitation: starting shell uncorrect: check it");
}
}
counter++;
vectorOfParticles->push_back(aParticle);
}
if (aParticle != 0) {vectorOfParticles->push_back(aParticle);}
else {provShellId = -2;}
}
while (provShellId >= 0);
return vectorOfParticles;
}
@@ -105,12 +112,13 @@ const G4int G4AtomicDeexcitation::SelectTypeOfTransition(G4int Z, G4int shellId)
if (shellId <=0 )
{G4Exception("G4AtomicDeexcitation: zero or negative shellId");}
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
const G4AtomicTransitionManager* transitionManager =
G4AtomicTransitionManager::Instance();
G4int provShellId = -1;
G4int shellNum = 0;
G4int maxNumOfShells = transitionManager->NumberOfReachableShells(Z);
const G4AtomicTransition* refShell = transitionManager->ReachableShell(Z,maxNumOfShells-1);
const G4FluoTransition* 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
@@ -129,7 +137,7 @@ const G4int G4AtomicDeexcitation::SelectTypeOfTransition(G4int Z, G4int shellId)
G4double partialProb = G4UniformRand();
G4double partSum = 0;
const G4AtomicTransition* aShell = transitionManager->ReachableShell(Z,shellNum);
const G4FluoTransition* aShell = transitionManager->ReachableShell(Z,shellNum);
G4int trSize = (aShell->TransitionProbabilities()).size();
// Loop over the shells wich can provide an electron for a
@@ -164,7 +172,9 @@ G4DynamicParticle* G4AtomicDeexcitation::GenerateFluorescence(G4int Z,
G4int shellId,
G4int provShellId )
{
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
const G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
// G4int provenienceShell = provShellId;
//isotropic angular distribution for the outcoming photon
@@ -226,7 +236,203 @@ G4DynamicParticle* G4AtomicDeexcitation::GenerateFluorescence(G4int Z,
G4DynamicParticle* G4AtomicDeexcitation::GenerateAuger(G4int Z, G4int shellId)
{
return 0;
if(!fAuger) return 0;
const G4AtomicTransitionManager* transitionManager =
G4AtomicTransitionManager::Instance();
if (shellId <=0 )
{G4Exception("G4AtomicDeexcitation: zero or negative shellId");}
// G4int provShellId = -1;
G4int maxNumOfShells = transitionManager->NumberOfReachableAugerShells(Z);
const G4AugerTransition* refAugerTransition =
transitionManager->ReachableAugerShell(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 NON-radiative transition
// ---- MGP ---- Next line commented out to remove compilation warning
// G4int p = refAugerTransition->FinalShellId();
G4int shellNum = 0;
if ( shellId <= refAugerTransition->FinalShellId() )
{
do
{
if(shellNum == maxNumOfShells-1)
{
break;
}
shellNum++;
}
while (shellId != transitionManager->ReachableAugerShell(Z,shellNum)->FinalShellId());
// Now we have that shellnum is the shellIndex of the shell named ShellId
// But we have now to select two shells: one for the transition,
// and another for the auger emission.
G4int transitionLoopShellIndex = 0;
G4double partSum = 0;
const G4AugerTransition* anAugerTransition =
transitionManager->ReachableAugerShell(Z,shellNum);
G4int transitionSize =
(anAugerTransition->TransitionOriginatingShellIds())->size();
while (transitionLoopShellIndex < transitionSize) {
G4std::vector<G4int>::const_iterator pos =
anAugerTransition->TransitionOriginatingShellIds()->begin();
G4int transitionLoopShellId = *(pos+transitionLoopShellIndex);
G4int numberOfPossibleAuger =
(anAugerTransition->AugerTransitionProbabilities(transitionLoopShellId))->size();
G4int augerIndex = 0;
// G4int partSum2 = 0;
while (augerIndex < numberOfPossibleAuger) {
partSum += anAugerTransition->AugerTransitionProbability(augerIndex,
transitionLoopShellId);
augerIndex++;
}
transitionLoopShellIndex++;
}
// Now we have the entire probability of an auger transition for the vacancy
// located in shellNum (index of shellId)
G4double totalVacancyAugerProbability = partSum;
//And now we start to select the right auger transition and emission
G4int transitionRandomShellIndex = 0;
G4int transitionRandomShellId = 0;
G4int augerIndex = 0;
partSum = 0;
G4double partialProb = G4UniformRand();
// G4int augerOriginatingShellId = 0;
while (transitionRandomShellIndex < transitionSize) {
G4std::vector<G4int>::const_iterator pos =
anAugerTransition->TransitionOriginatingShellIds()->begin();
transitionRandomShellId = *(pos+transitionRandomShellIndex);
// G4int transitionRandomShellId = *(anAugerTransition->TransitionOriginatingShellIds())[transitionRandomShellIndex];
G4int numberOfPossibleAuger =
(anAugerTransition->AugerTransitionProbabilities(transitionRandomShellId))->size();
augerIndex = 0;
while (augerIndex < numberOfPossibleAuger) {
partSum += anAugerTransition->AugerTransitionProbability(augerIndex,
transitionRandomShellId);
if (partSum >= (partialProb/totalVacancyAugerProbability) ) {break;}
augerIndex++;
}
if (partSum >= (partialProb/totalVacancyAugerProbability) ) {break;}
transitionRandomShellIndex++;
}
// Now we have the index of the shell from wich comes the auger electron (augerIndex),
// and the id of the shell, from which the transition e- come (transitionRandomShellid)
// Isotropic angular distribution for the outcoming e-
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 newElectronDirection(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 auger electron emitted
G4double transitionEnergy =
anAugerTransition->AugerTransitionEnergy(augerIndex, transitionRandomShellId);
// This is the shell where the new vacancy is: it is the same
// shell where the electron came from
newShellId = transitionRandomShellId;
G4DynamicParticle* newPart = new G4DynamicParticle(G4Electron::Electron(),
newElectronDirection,
transitionEnergy);
return newPart;
}
else
{
//G4Exception("G4AtomicDeexcitation: no auger transition found");
return 0;
}
}
void G4AtomicDeexcitation::SetCutForSecondaryPhotons(G4double cut)
{
minGammaEnergy = cut;
}
void G4AtomicDeexcitation::SetCutForAugerElectrons(G4double cut)
{
minElectronEnergy = cut;
}
void G4AtomicDeexcitation::ActivateAugerElectronProduction(G4bool val)
{
fAuger = val;
}
@@ -22,7 +22,7 @@
//
//
// $Id: G4AtomicShell.cc,v 1.2 ????
// GEANT4 tag $Name: geant4-04-00 $
// GEANT4 tag $Name: geant4-04-01 $
//
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
@@ -22,7 +22,7 @@
//
//
// $Id: G4AtomicTransition.cc,v 1.2 ????
// GEANT4 tag $Name: geant4-04-00 $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
//
@@ -39,12 +39,11 @@ G4AtomicTransition::G4AtomicTransition(G4int finalShell,
const G4std::vector<G4int>& ids,
const G4DataVector& energies,
const G4DataVector& prob)
{
finalShellId = finalShell;
originatingShellIds = ids;
transitionEnergies = energies;
transitionProbabilities = prob;
}
:finalShellId(finalShell),
originatingShellIds(ids),
transitionEnergies(energies),
transitionProbabilities(prob)
{ }
G4AtomicTransition::~G4AtomicTransition()
{ }
@@ -22,7 +22,7 @@
//
//
// $Id: G4AtomicTransitionManager.cc,v 1.2 ????
// GEANT4 tag $Name: geant4-04-00 $
// GEANT4 tag $Name: geant4-04-01 $
//
// Authors: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
// Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
@@ -35,12 +35,20 @@
#include "G4AtomicTransitionManager.hh"
G4AtomicTransitionManager::G4AtomicTransitionManager(G4int minZ, G4int maxZ, G4int limitInfTable,G4int limitSupTable)
:zMin(minZ), zMax(maxZ),infTableLimit(limitInfTable),supTableLimit(limitSupTable)
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;
// initialization of the data for auger effect
augerData = new G4AugerData;
shellManager->LoadData("/fluor/binding");
// Fills shellTable with the data from EADL, identities and binding
@@ -68,7 +76,7 @@ G4AtomicTransitionManager::G4AtomicTransitionManager(G4int minZ, G4int maxZ, G4i
// energies and transition probabilities
for (G4int Znum= infTableLimit; Znum<=supTableLimit; Znum++)
{ G4FluoData* fluoManager = new G4FluoData;
G4std::vector<G4AtomicTransition*> vectorOfTransitions;
G4std::vector<G4FluoTransition*> vectorOfTransitions;
fluoManager->LoadData(Znum);
size_t numberOfVacancies = fluoManager-> NumberOfVacancies();
@@ -82,7 +90,8 @@ G4AtomicTransitionManager::G4AtomicTransitionManager(G4int minZ, G4int maxZ, G4i
G4int finalShell = fluoManager->VacancyId(vacancyIndex);
size_t numberOfTransitions = fluoManager->NumberOfTransitions(vacancyIndex);
for (size_t origShellIndex = 0; origShellIndex <= numberOfTransitions;origShellIndex++)
for (size_t origShellIndex = 0; origShellIndex <= numberOfTransitions;
origShellIndex++)
{
@@ -95,7 +104,7 @@ G4AtomicTransitionManager::G4AtomicTransitionManager(G4int minZ, G4int maxZ, G4i
G4double transitionProbability = fluoManager->StartShellProb(origShellIndex,vacancyIndex);
vectorOfProbabilities.push_back(transitionProbability);
}
G4AtomicTransition * transition = new G4AtomicTransition (finalShell,vectorOfIds,
G4FluoTransition * transition = new G4FluoTransition (finalShell,vectorOfIds,
vectorOfEnergies,vectorOfProbabilities);
vectorOfTransitions.push_back(transition);
}
@@ -109,7 +118,11 @@ G4AtomicTransitionManager::G4AtomicTransitionManager(G4int minZ, G4int maxZ, G4i
G4AtomicTransitionManager::~G4AtomicTransitionManager()
{ G4std::map<G4int,G4std::vector<G4AtomicShell*>,G4std::less<G4int> >::iterator pos;
{
delete augerData;
G4std::map<G4int,G4std::vector<G4AtomicShell*>,G4std::less<G4int> >::iterator pos;
for (pos = shellTable.begin(); pos != shellTable.end(); pos++){
@@ -118,23 +131,23 @@ G4AtomicTransitionManager::~G4AtomicTransitionManager()
G4int vecSize=vec.size();
for (G4int i=0; i< vecSize; i++){
delete vec[i];
G4AtomicShell* shell = vec[i];
delete shell;
}
}
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator ppos;
G4std::map<G4int,G4std::vector<G4FluoTransition*>,G4std::less<G4int> >::iterator ppos;
for (ppos = transitionTable.begin(); ppos != transitionTable.end(); ppos++){
G4std::vector< G4AtomicTransition*>vec = (*ppos).second;
G4std::vector<G4FluoTransition*>vec = (*ppos).second;
G4int vecSize=vec.size();
for (G4int i=0; i< vecSize; i++){
delete vec[i];
G4FluoTransition* transition = vec[i];
delete transition;
}
}
@@ -145,7 +158,7 @@ G4AtomicTransitionManager* G4AtomicTransitionManager::instance = 0;
G4AtomicTransitionManager* G4AtomicTransitionManager::Instance()
{
if (instance==0)
if (instance == 0)
{
instance = new G4AtomicTransitionManager;
@@ -154,9 +167,9 @@ G4AtomicTransitionManager* G4AtomicTransitionManager::Instance()
}
const G4AtomicShell* G4AtomicTransitionManager::Shell(G4int Z, size_t shellIndex)
G4AtomicShell* G4AtomicTransitionManager::Shell(G4int Z, size_t shellIndex) const
{
G4std::map<G4int,G4std::vector<G4AtomicShell*>,G4std::less<G4int> >::iterator pos;
G4std::map<G4int,G4std::vector<G4AtomicShell*>,G4std::less<G4int> >::const_iterator pos;
pos = shellTable.find(Z);
@@ -180,13 +193,16 @@ const G4AtomicShell* G4AtomicTransitionManager::Shell(G4int Z, size_t shellIndex
}
}
const G4AtomicTransition* G4AtomicTransitionManager:: ReachableShell(G4int Z,size_t shellIndex)
// This function gives, upon Z and the Index of the initial shell where te vacancy is,
// the radiative transition that can happen (originating shell, energy, probability)
const G4FluoTransition* G4AtomicTransitionManager::ReachableShell(G4int Z,size_t shellIndex) const
{
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator pos;
G4std::map<G4int,G4std::vector<G4FluoTransition*>,G4std::less<G4int> >::const_iterator pos;
pos = transitionTable.find(Z);
if (pos!= transitionTable.end())
{
G4std::vector<G4AtomicTransition*> v = (*pos).second;
G4std::vector<G4FluoTransition*> v = (*pos).second;
if (shellIndex < v.size()) return(v[shellIndex]);
else {
G4Exception("G4AtomicTransitionManager:reachable shell not found");
@@ -199,10 +215,19 @@ const G4AtomicTransition* G4AtomicTransitionManager:: ReachableShell(G4int Z,siz
}
}
G4int G4AtomicTransitionManager::NumberOfShells (G4int Z)
const G4AugerTransition* G4AtomicTransitionManager::ReachableAugerShell(G4int Z, G4int vacancyShellIndex) const
{
G4AugerTransition* augerTransition = augerData->GetAugerTransition(Z,vacancyShellIndex);
return augerTransition;
}
G4int G4AtomicTransitionManager::NumberOfShells (G4int Z) const
{
G4std::map<G4int,G4std::vector<G4AtomicShell*>,G4std::less<G4int> >::iterator pos;
G4std::map<G4int,G4std::vector<G4AtomicShell*>,G4std::less<G4int> >::const_iterator pos;
pos = shellTable.find(Z);
@@ -219,15 +244,18 @@ G4std::map<G4int,G4std::vector<G4AtomicShell*>,G4std::less<G4int> >::iterator po
}
}
G4int G4AtomicTransitionManager::NumberOfReachableShells(G4int Z)
// This function returns the number of possible radiative transitions for the atom with atomic number Z
// i.e. the number of shell in wich a vacancy can be filled with a radiative transition
G4int G4AtomicTransitionManager::NumberOfReachableShells(G4int Z) const
{
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator pos;
G4std::map<G4int,G4std::vector<G4FluoTransition*>,G4std::less<G4int> >::const_iterator pos;
pos = transitionTable.find(Z);
if (pos!= transitionTable.end())
{
G4std::vector<G4AtomicTransition*> v = (*pos).second;
G4std::vector<G4FluoTransition*> v = (*pos).second;
return v.size();
}
else
@@ -237,21 +265,32 @@ G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterat
}
}
// This function returns the number of possible NON-radiative transitions for the atom with atomic number Z
// i.e. the number of shell in wich a vacancy can be filled with a NON-radiative transition
G4int G4AtomicTransitionManager::NumberOfReachableAugerShells(G4int Z)const
{
G4int n = augerData->NumberOfVacancies(Z);
return n;
}
G4double G4AtomicTransitionManager::TotalRadiativeTransitionProbability(G4int Z,
size_t shellIndex)
{
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator pos;
G4std::map<G4int,G4std::vector<G4FluoTransition*>,G4std::less<G4int> >::iterator pos;
pos = transitionTable.find(Z);
if (pos!= transitionTable.end())
{
G4std::vector<G4AtomicTransition*> v = (*pos).second;
G4std::vector<G4FluoTransition*> v = (*pos).second;
if (shellIndex < v.size())
{
G4AtomicTransition* transition = v[shellIndex];
G4FluoTransition* transition = v[shellIndex];
G4DataVector transProb = transition->TransitionProbabilities();
G4double totalRadTransProb = 0;
@@ -278,18 +317,18 @@ G4double G4AtomicTransitionManager::TotalNonRadiativeTransitionProbability(G4int
{
G4std::map<G4int,G4std::vector<G4AtomicTransition*>,G4std::less<G4int> >::iterator pos;
G4std::map<G4int,G4std::vector<G4FluoTransition*>,G4std::less<G4int> >::iterator pos;
pos = transitionTable.find(Z);
if (pos!= transitionTable.end()){
G4std::vector<G4AtomicTransition*> v = (*pos).second;
G4std::vector<G4FluoTransition*> v = (*pos).second;
if (shellIndex<v.size()){
G4AtomicTransition* transition=v[shellIndex];
G4FluoTransition* transition=v[shellIndex];
G4DataVector transProb = transition->TransitionProbabilities();
G4double totalRadTransProb = 0;
@@ -0,0 +1,527 @@
//
// ********************************************************************
// * 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: G4AugerData.cc v1.0
//
//
// Author: Alfonso Mmantero (Alfonso.Mantero@ge.infn.it)
//
// History:
// -----------
// Based on G4FluoData by Elena Guardincerri
//
// -------------------------------------------------------------------
#include "G4AugerData.hh"
#include "G4DataVector.hh"
#include "g4std/fstream"
#include "g4std/strstream"
G4AugerData::G4AugerData()
{
G4int n = 0;
G4int pos = 0;
for (pos = 0 ; pos < 100; pos++)
{
numberOfVacancies.push_back(n);
}
BuildAugerTransitionTable();
}
G4AugerData::~G4AugerData()
{
/*
G4std::map<G4int,G4std::vector<G4AugerTransition>,G4std::less<G4int> >::iterator pos;
for (pos = augerTransitionTable.begin(); pos != augerTransitionTable.end(); pos++)
{
G4std::vector<G4AugerTransition> dataSet = (*pos).second;
delete dataSet;
}
for (pos = energyMap.begin(); pos != energyMap.end(); pos++)
{
G4std::map<G4Int,G4DataVector*,G4std::less<G4int>>* dataMap = (*pos).second;
for (pos2 = newIdProbabilityMap.begin(); pos2 != idMap.end(); pos2++)
{
G4DataVector* dataSet = (*pos2).second;
delete dataSet;
}
}
for (pos = probabilityMap.begin(); pos != probabilityMap.end(); pos++)
{
G4std::map<G4Int,G4DataVector*,G4std::less<G4int>>* dataMap = (*pos).second;
for (pos2 = newIdProbabilityMap.begin(); pos2 != idMap.end(); pos2++)
{
G4DataVector* dataSet = (*pos2).second;
delete dataSet;
}
}
for (pos2 = newIdMap.begin(); pos2 != idMap.end(); pos2++)
{
G4DataVector* dataSet = (*pos2).second;
delete dataSet;
}
for (pos2 = newIdEnergyMap.begin(); pos2 != idMap.end(); pos2++)
{
G4DataVector* dataSet = (*pos2).second;
delete dataSet;
}
for (pos2 = newIdProbabilityMap.begin(); pos2 != idMap.end(); pos2++)
{
G4DataVector* dataSet = (*pos2).second;
delete dataSet;
}
*/
}
size_t G4AugerData::NumberOfVacancies(G4int Z) const
{
return numberOfVacancies[Z];
}
G4int G4AugerData::VacancyId(G4int Z, G4int vacancyIndex) const
{
G4int n = 0;
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies[Z])
{G4Exception("G4AugerData::vacancyIndex outside boundaries");}
else {
trans_Table::const_iterator element = augerTransitionTable.find(Z);
if (element == augerTransitionTable.end()) {G4Exception("G4AugerData::augerTransitionTable: Data not Loaded");}
G4std::vector<G4AugerTransition> dataSet = (*element).second;
n = (G4int) dataSet[vacancyIndex].FinalShellId();
}
return n;
}
// Attenzione: questa funzione vuole l'indice della vacanza, non l'Id
size_t G4AugerData::NumberOfTransitions(G4int Z, G4int vacancyIndex) const
{
G4int n = 0;
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies[Z])
{G4Exception("G4AugerData::vacancyIndex outside boundaries");}
else {
trans_Table::const_iterator element = augerTransitionTable.find(Z);
if (element == augerTransitionTable.end()) {G4Exception("G4AugerData::augerTransitionTable: Data not Loaded");}
G4std::vector<G4AugerTransition> dataSet = (*element).second;
n = (G4int)dataSet[vacancyIndex].TransitionOriginatingShellIds()->size();
}
return n;
}
size_t G4AugerData::NumberOfAuger(G4int Z, G4int initIndex, G4int vacancyId) const
{
size_t n = 0;
if (initIndex<0 || initIndex>=numberOfVacancies[Z])
{G4Exception("G4AugerData::vacancyIndex outside boundaries");}
else {
trans_Table::const_iterator element = augerTransitionTable.find(Z);
if (element == augerTransitionTable.end()) {G4Exception("G4AugerData::augerTransitionTable: Data not Loaded");}
G4std::vector<G4AugerTransition> dataSet = (*element).second;
const G4std::vector<G4int>* temp = dataSet[initIndex].AugerOriginatingShellIds(vacancyId);
n = temp->size();
}
return n;
}
size_t G4AugerData::AugerShellId(G4int Z, G4int vacancyIndex, G4int transId, G4int augerIndex) const
{
size_t n = 0;
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies[Z])
{G4Exception("G4AugerData::vacancyIndex outside boundaries");}
else {
trans_Table::const_iterator element = augerTransitionTable.find(Z);
if (element == augerTransitionTable.end()) {G4Exception("G4AugerData::augerTransitionTable: Data not Loaded");}
G4std::vector<G4AugerTransition> dataSet = (*element).second;
n = dataSet[vacancyIndex].AugerOriginatingShellId(augerIndex,transId);
}
return n;
}
G4int G4AugerData::StartShellId(G4int Z, G4int vacancyIndex, G4int transitionShellIndex) const
{
G4int n = 0;
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies[Z])
{G4Exception("G4AugerData::vacancyIndex outside boundaries");}
else {
trans_Table::const_iterator element = augerTransitionTable.find(Z);
if (element == augerTransitionTable.end()) {G4Exception("G4AugerData::augerTransitionTable: Data not Loaded");}
G4std::vector<G4AugerTransition> dataSet = (*element).second;
n = dataSet[vacancyIndex].TransitionOriginatingShellId(transitionShellIndex);
}
return n;
}
G4double G4AugerData::StartShellEnergy(G4int Z, G4int vacancyIndex, G4int transitionId, G4int augerIndex) const
{
G4double n = 0;
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies[Z])
{G4Exception("G4AugerData::vacancyIndex outside boundaries");}
else {
trans_Table::const_iterator element = augerTransitionTable.find(Z);
if (element == augerTransitionTable.end()) {G4Exception("G4AugerData::augerTransitionTable: Data not Loaded");}
G4std::vector<G4AugerTransition> dataSet = (*element).second;
n = dataSet[vacancyIndex].AugerTransitionEnergy(augerIndex,transitionId);
}
return n;
}
G4double G4AugerData::StartShellProb(G4int Z, G4int vacancyIndex,G4int transitionId,G4int augerIndex) const
{
G4double n = 0;
if (vacancyIndex<0 || vacancyIndex>=numberOfVacancies[Z])
{G4Exception("G4AugerData::vacancyIndex outside boundaries");}
else {
trans_Table::const_iterator element = augerTransitionTable.find(Z);
if (element == augerTransitionTable.end()) {G4Exception("G4AugerData::augerTransitionTable: Data not Loaded");}
G4std::vector<G4AugerTransition> dataSet = (*element).second;
n = dataSet[vacancyIndex].AugerTransitionProbability(augerIndex, transitionId);
}
return n;
}
G4std::vector<G4AugerTransition> G4AugerData::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 << "au-tr-pr-"<< Z << ".dat";
}
else{
ost << "au-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 + "/auger/" + name;
G4std::ifstream file(dirFile);
G4std::filebuf* lsdp = file.rdbuf();
if (! (lsdp->is_open()) )
{
G4String excep = "G4AugerData - data file: " + dirFile + " not found";
G4Exception(excep);
}
G4double a = 0;
G4int k = 1;
G4int s = 0;
G4int vacId = 0;
G4std::vector<G4int>* initIds = new G4std::vector<G4int>;
G4std::vector<G4int>* newIds = new G4std::vector<G4int>;
G4DataVector* transEnergies = new G4DataVector;
G4DataVector* transProbabilities = new G4DataVector;
G4std::vector<G4AugerTransition> augerTransitionVector;
G4std::map<G4int,G4std::vector<G4int>,G4std::less<G4int> >* newIdMap =
new G4std::map<G4int,G4std::vector<G4int>,G4std::less<G4int> >;
G4std::map<G4int,G4DataVector,G4std::less<G4int> >* newEnergyMap =
new G4std::map<G4int,G4DataVector,G4std::less<G4int> >;
G4std::map<G4int,G4DataVector,G4std::less<G4int> >* newProbabilityMap =
new G4std::map<G4int,G4DataVector,G4std::less<G4int> >;
do {
file >> a;
G4int nColumns = 4;
if (a == -1)
{
if (s == 0)
{
// End of a shell data set
G4std::vector<G4int>::iterator vectorIndex = initIds->begin();
vacId = *vectorIndex;
//initIds->erase(vectorIndex);
G4std::vector<G4int> identifiers;
for (vectorIndex = initIds->begin()+1 ; vectorIndex != initIds->end(); ++vectorIndex){
identifiers.push_back(*vectorIndex);
}
vectorIndex = (initIds->end())-1;
G4int augerShellId = *(vectorIndex);
(*newIdMap)[augerShellId] = *newIds;
(*newEnergyMap)[augerShellId] = *transEnergies;
(*newProbabilityMap)[augerShellId] = *transProbabilities;
augerTransitionVector.push_back(G4AugerTransition(vacId, identifiers, newIdMap, newEnergyMap, newProbabilityMap));
// Now deleting all the variables I used, and creating new ones for the next shell
delete newIdMap;
delete newEnergyMap;
delete newProbabilityMap;
G4int n = initIds->size();
nInitShells.push_back(n);
numberOfVacancies[Z]++;
delete initIds;
delete newIds;
delete transEnergies;
delete transProbabilities;
initIds = new G4std::vector<G4int>;
newIds = new G4std::vector<G4int>;
transEnergies = new G4DataVector;
transProbabilities = new G4DataVector;
newIdMap = new G4std::map<G4int,G4std::vector<G4int>,G4std::less<G4int> >;
newEnergyMap = new G4std::map<G4int,G4DataVector,G4std::less<G4int> >;
newProbabilityMap = new G4std::map<G4int,G4DataVector,G4std::less<G4int> >;
}
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 newIds;
delete transEnergies;
delete transProbabilities;
delete newIdMap ;
delete newEnergyMap;
delete newProbabilityMap;
}
else
{
if (k%nColumns == 3){
// 3rd column is the transition probabilities
transProbabilities->push_back(a);
k++;}
else if(k%nColumns == 2){
// 2nd column is new auger vacancy
// 2nd column is new auger vacancy
G4int l = (G4int)a;
newIds->push_back(l);
k++;
}
else if (k%nColumns == 1)
{
// 1st column is shell id
if(initIds->size() == 0) {
// if this is the first data of the shell, alla the colums are equal
// to the shell Id; so we skip the next colums ang go to the next row
initIds->push_back(a);
file >> a;
file >> a;
file >> a;
k = k+3;
}
else {
G4std::vector<G4int>::iterator vectorIndex = (initIds->end())-1;
if((G4int)a != *vectorIndex){
if((initIds->size()) == 1) {
initIds->push_back(a);
}
else {
initIds->push_back(a);
G4int augerShellId = *vectorIndex;
(*newIdMap)[augerShellId] = *newIds;
(*newEnergyMap)[augerShellId] = *transEnergies;
(*newProbabilityMap)[augerShellId] = *transProbabilities;
delete newIds;
delete transEnergies;
delete transProbabilities;
newIds = new G4std::vector<G4int>;
transEnergies = new G4DataVector;
transProbabilities = new G4DataVector;
}
}
}
k++;
}
else if (k%nColumns == 0)
{//fourth column is transition energies
G4double e = a * MeV;
transEnergies->push_back(e);
k=1;
}
}
}
while (a != -2); // end of file
file.close();
return augerTransitionVector;
}
void G4AugerData::BuildAugerTransitionTable()
{
// trans_Table::iterator pos = augerTransitionTable.begin();
for (G4int element = 6; element < 99; element++)
{
augerTransitionTable.insert(trans_Table::value_type(element,LoadData(element)));
//G4cout << "G4AugerData for Element no. " << element << " are loaded" << G4endl;
}
G4cout << "AugerTransitionTable complete"<< G4endl;
}
void G4AugerData::PrintData(G4int Z)
{
for (G4int i = 0; i < numberOfVacancies[Z]; i++)
{
G4cout << "---- TransitionData for the vacancy nb "
<<i
<<" of the atomic number elemnt "
<< Z
<<"----- "
<<G4endl;
for (size_t k = 0; k<=NumberOfTransitions(Z,i); k++)
{
G4int id = StartShellId(Z,i,k);
for (size_t a = 0; a <= NumberOfAuger(Z,i,id); a++) {
G4double e = StartShellEnergy(Z,i,id,a) /MeV;
G4double p = StartShellProb(Z,i,id,a);
G4int augerId = AugerShellId(Z, i, id, a);
G4cout << k <<") Shell id: " << id <<G4endl;
G4cout << " Auger Originatig Shell Id :"<< augerId <<G4endl;
G4cout << " - Transition energy = " << e << " MeV "<<G4endl;
G4cout << " - Transition probability = " << p <<G4endl;
}
}
G4cout << "-------------------------------------------------"
<< G4endl;
}
}
G4AugerTransition* G4AugerData::GetAugerTransition(G4int Z,G4int vacancyShellIndex)
{
G4std::vector<G4AugerTransition>* dataSet = &augerTransitionTable[Z];
G4std::vector<G4AugerTransition>::iterator vectorIndex = dataSet->begin() + vacancyShellIndex;
G4AugerTransition* augerTransition = &(*vectorIndex);
return augerTransition;
}
G4std::vector<G4AugerTransition>* G4AugerData::GetAugerTransitions(G4int Z)
{
G4std::vector<G4AugerTransition>* dataSet = &augerTransitionTable[Z];
return dataSet;
}
@@ -0,0 +1,178 @@
//
// ********************************************************************
// * 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: G4AugerTransition.cc,v 1.2 ????
//
// Based on G4AtomicTransition.cc by
// Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
//
// Author: Alfonso Mantero (Alfonso.Mantero@ge.infn.it)
//
// History:
// -----------
// 4 Mar 2002: first implementation
//
// -------------------------------------------------------------------
#include "G4AugerTransition.hh"
// the final shell in wich the electron goes is needed, to know the data for the auger electron emitted
// (i.e. originating shell id, electron energy and transition probability)
G4AugerTransition::G4AugerTransition(G4int finalShell, G4std::vector<G4int> transIds,
const G4std::map<G4int,G4std::vector<G4int>,G4std::less<G4int> >* idMap,
const G4std::map<G4int,G4DataVector,G4std::less<G4int> >* energyMap,
const G4std::map<G4int,G4DataVector,G4std::less<G4int> >* probabilityMap)
{
finalShellId = finalShell;
augerOriginatingShellIdsMap = *idMap;
augerTransitionEnergiesMap = *energyMap;
augerTransitionProbabilitiesMap = *probabilityMap;
transitionOriginatingShellIds = transIds;
}
G4AugerTransition::~G4AugerTransition()
{
}
// Returns the ids of the shells from wich an auger electron culd came from, given th shell
// from wich the transition electron cames from.
const G4std::vector<G4int>* G4AugerTransition::AugerOriginatingShellIds(G4int startShellId) const
{
G4std::map<G4int,G4std::vector<G4int>,G4std::less<G4int> >::const_iterator shellId = augerOriginatingShellIdsMap.find(startShellId);
const G4std::vector<G4int> dataSet = (*shellId).second;
const G4std::vector<G4int>* dataOut = 0;
if (dataSet.size() == 0) {G4cout << "Error: no auger Id found"<< G4endl;}
else {
dataOut = &dataSet;
}
return dataOut;
}
// Returns the ids of the shells from wich an electron cuuld fill the vacancy in finalShellId
const G4std::vector<G4int>* G4AugerTransition::TransitionOriginatingShellIds() const
{
const G4std::vector<G4int>* dataSet = &transitionOriginatingShellIds;
return dataSet;
}
// Returns the energiess of the possible auger electrons, given th shell
// from wich the transition electron cames from.
const G4DataVector* G4AugerTransition::AugerTransitionEnergies(G4int startShellId) const
{
G4std::map<G4int,G4DataVector,G4std::less<G4int> >::const_iterator shellId = augerTransitionEnergiesMap.find(startShellId);
const G4DataVector* dataSet = &(*shellId).second;
return dataSet;
}
// Returns the emission probabilities of the auger electrons, given th shell
// from wich the transition electron cames from.
const G4DataVector* G4AugerTransition::AugerTransitionProbabilities(G4int startShellId) const
{
G4std::map<G4int,G4DataVector,G4std::less<G4int> >::const_iterator shellId = augerTransitionProbabilitiesMap.find(startShellId);
const G4DataVector* dataSet = &(*shellId).second;
return dataSet;
}
const G4int G4AugerTransition::FinalShellId() const
{
return finalShellId;
}
// Returns the id of the shell from wich come the auger electron , given the shell
// from wich the transition electron cames from and the index number.
G4int G4AugerTransition::AugerOriginatingShellId(G4int index, G4int startShellId) const
{
const G4std::vector<G4int>* ids = AugerOriginatingShellIds(startShellId);
// G4int i =
G4std::vector<G4int>::const_iterator pos = ids->begin();
G4int n = *(pos+index);
return n;
}
// Returns the energy of the auger electron, given the shell
// from wich the transition electron cames from and the index number.
G4double G4AugerTransition::AugerTransitionEnergy(G4int index, G4int startShellId) const
{
const G4DataVector* energies = AugerTransitionEnergies(startShellId);
G4DataVector::const_iterator pos = energies->begin();
G4double energy = *(pos+index);
return energy;
}
// Returns the probability of the auger emission, given the shell
// from wich the transition electron cames from and the index number.
G4double G4AugerTransition::AugerTransitionProbability(G4int index, G4int startShellId) const
{
const G4DataVector *probabilities = AugerTransitionProbabilities(startShellId);
G4DataVector::const_iterator pos = probabilities->begin();
G4double* probability = new G4double;
*probability = *(pos+index);
return *probability;
delete probability;
}
G4int G4AugerTransition::TransitionOriginatingShellId(G4int index) const
{
return transitionOriginatingShellIds[index];
}
@@ -21,7 +21,7 @@
// ********************************************************************
//
// $Id: G4BremsstrahlungCrossSectionHandler.cc,v 1.5 2001/10/25 14:31:20 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
// GEANT4 tag $Name: geant4-04-01 $
//
// -------------------------------------------------------------------
//
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4BremsstrahlungParameters.cc,v 1.11 2001/11/29 22:59:56 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4BremsstrahlungParameters.cc,v 1.13 2002/05/30 17:53:07 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
// V.Ivanchenko (Vladimir.Ivantchenko@cern.ch)
@@ -59,7 +59,7 @@ 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++)
for (pos = param.begin(); pos != param.end(); ++pos)
{
G4VEMDataSet* dataSet = (*pos).second;
delete dataSet;
@@ -133,22 +133,23 @@ void G4BremsstrahlungParameters::LoadData()
// Read parameters
char* path = getenv("G4LEDATA");
if (!path)
if (path == 0)
{
G4String excep = G4String("G4BremsstrahlungParameters - G4LEDATA")
+ G4String("environment variable not set");
G4String excep("G4BremsstrahlungParameters - G4LEDATA environment variable not set");
G4Exception(excep);
}
G4String pathString_a(path);
G4String name_a = pathString_a + "/brem/br-sp.dat";
G4String stringConversion1("/brem/br-sp.dat");
G4String name_a = pathString_a + stringConversion1;
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);
if (! (lsdp_a->is_open()) )
{
G4String stringConversion2("G4BremsstrahlungParameters: cannot open file ");
G4String excep = stringConversion2 + name_a;
G4Exception(excep);
}
// The file is organized into two columns:
@@ -226,18 +227,6 @@ void G4BremsstrahlungParameters::LoadData()
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);
}
@@ -252,10 +241,13 @@ void G4BremsstrahlungParameters::LoadData()
G4double G4BremsstrahlungParameters::ParameterC(G4int id) const
{
G4int n = paramC.size();
if (id < 0 || id >= n) {
G4String ex = "G4BremsstrahlungParameters::ParameterC - wrong id=" + id;
G4Exception(ex);
}
if (id < 0 || id >= n)
{
G4String stringConversion1("G4BremsstrahlungParameters::ParameterC - wrong id = ");
G4String stringConversion2(id);
G4String ex = stringConversion1 + stringConversion2;
G4Exception(ex);
}
return paramC[id];
}
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4CompositeEMDataSet.cc,v 1.5 2001/10/25 02:32:16 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4CompositeEMDataSet.cc,v 1.6 2002/05/28 09:20:18 pia Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
@@ -61,7 +61,8 @@ G4CompositeEMDataSet::~G4CompositeEMDataSet()
{
for (size_t i=0; i<nComponents; i++)
{
delete components[i];
G4VEMDataSet* dataSet = components[i];
delete dataSet;
}
delete algorithm;
}
@@ -114,18 +115,21 @@ void G4CompositeEMDataSet::LoadData(const G4String& fileName)
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = "G4CompositeEMDataSet - G4LEDATA environment variable not set";
G4String excep("G4CompositeEMDataSet - G4LEDATA environment variable not set");
G4Exception(excep);
}
G4String pathString(path);
G4String dirFile = pathString + "/" + name;
G4String separator = G4String("/");
G4String dirFile = pathString + separator + name;
G4std::ifstream file(dirFile);
G4std::filebuf* lsdp = file.rdbuf();
if (! (lsdp->is_open()) )
{
G4String excep = "G4CompositeEMDataSet - data file: " + dirFile + " not found";
G4String s1("G4CompositeEMDataSet - data file: ");
G4String s2(" not found");
G4String excep = s1 + dirFile + s2;
G4Exception(excep);
}
G4double a = 0;
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4CrossSectionHandler.cc,v 1.12 2001/10/08 07:48:57 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4CrossSectionHandler.cc,v 1.13 2002/05/28 09:20:18 pia Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
@@ -74,7 +74,7 @@ G4CrossSectionHandler::BuildCrossSectionsForMaterials(const G4DataVector& energy
const G4Material* material= (*materialTable)[m];
energies = new G4DataVector;
data = new G4DataVector;
G4VDataSetAlgorithm* interpolationAlgo = CreateInterpolation();
const G4VDataSetAlgorithm* interpolationAlgo = CreateInterpolation();
for (size_t bin=0; bin<nOfBins; bin++)
{
G4double e = energyVector[bin];
@@ -22,7 +22,7 @@
//
//
// $Id: G4CutsPerMaterialWarning.cc,v 1.1 2001/11/07 22:39:02 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4EMDataSet.cc,v 1.5 2001/10/08 07:48:57 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4EMDataSet.cc,v 1.6 2002/05/28 09:20:19 pia Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
@@ -42,7 +42,7 @@
G4EMDataSet::G4EMDataSet(G4int Z,
G4DataVector* points,
G4DataVector* values,
G4VDataSetAlgorithm* interpolation,
const G4VDataSetAlgorithm* interpolation,
G4double unitE, G4double unitData)
:z(Z), energies(points), data(values), algorithm(interpolation)
{
@@ -55,7 +55,7 @@ G4EMDataSet::G4EMDataSet(G4int Z,
G4EMDataSet:: G4EMDataSet(G4int Z,
const G4String& dataFile,
G4VDataSetAlgorithm* interpolation,
const G4VDataSetAlgorithm* interpolation,
G4double unitE, G4double unitData)
:z(Z), algorithm(interpolation)
{
@@ -152,18 +152,22 @@ void G4EMDataSet::LoadData(const G4String& fileName)
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = "G4EMDataSet - G4LEDATA environment variable not set";
G4String excep("G4EMDataSet - G4LEDATA environment variable not set");
G4Exception(excep);
}
G4String pathString(path);
G4String dirFile = pathString + "/" + name;
G4String separator("/");
G4String dirFile = pathString + separator + name;
G4std::ifstream file(dirFile);
G4std::filebuf* lsdp = file.rdbuf();
if (! (lsdp->is_open()) )
{
G4String excep = "G4EMDataSet - data file: " + dirFile + " not found";
G4String s1("G4EMDataSet - data file: ");
G4String s2(" not found");
G4String excep = s1 + dirFile + s2;
G4Exception(excep);
}
G4double a = 0;
@@ -216,3 +220,13 @@ void G4EMDataSet::PrintData() const
<< G4endl;
}
}
const G4VEMDataSet* G4EMDataSet::GetComponent(G4int i) const
{ return 0; }
void G4EMDataSet::AddComponent(G4VEMDataSet* dataSet)
{ }
size_t G4EMDataSet::NumberOfComponents() const
{ return 0; }
@@ -21,8 +21,6 @@
// ********************************************************************
//
//
// $Id: G4FluoDataData.cc,v 1.2
// GEANT4 tag $Name: geant4-04-00 $
//
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
//
@@ -34,6 +32,7 @@
#include "G4FluoData.hh"
#include "G4DataVector.hh"
#include "G4FluoTransition.hh"
#include "g4std/fstream"
#include "g4std/strstream"
@@ -46,17 +45,17 @@ G4FluoData::~G4FluoData()
{
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::iterator pos;
for (pos = idMap.begin(); pos != idMap.end(); pos++)
for (pos = idMap.begin(); pos != idMap.end(); ++pos)
{
G4DataVector* dataSet = (*pos).second;
delete dataSet;
}
for (pos = energyMap.begin(); pos != energyMap.end(); pos++)
for (pos = energyMap.begin(); pos != energyMap.end(); ++pos)
{
G4DataVector* dataSet = (*pos).second;
delete dataSet;
}
for (pos = probabilityMap.begin(); pos != probabilityMap.end(); pos++)
for (pos = probabilityMap.begin(); pos != probabilityMap.end(); ++pos)
{
G4DataVector* dataSet = (*pos).second;
delete dataSet;
@@ -100,7 +99,7 @@ size_t G4FluoData::NumberOfTransitions(G4int vacancyIndex) const
}
return n;
}
G4int G4FluoData::StartShellId(G4int initIndex,G4int vacancyIndex)
G4int G4FluoData::StartShellId(G4int initIndex, G4int vacancyIndex) const
{
G4int n = -1;
@@ -124,7 +123,7 @@ G4int G4FluoData::StartShellId(G4int initIndex,G4int vacancyIndex)
return n;
}
G4double G4FluoData::StartShellEnergy(G4int initIndex,G4int vacancyIndex)
G4double G4FluoData::StartShellEnergy(G4int initIndex, G4int vacancyIndex) const
{
G4double n = -1;
@@ -148,7 +147,7 @@ G4double G4FluoData::StartShellEnergy(G4int initIndex,G4int vacancyIndex)
return n;
}
G4double G4FluoData::StartShellProb(G4int initIndex,G4int vacancyIndex)
G4double G4FluoData::StartShellProb(G4int initIndex, G4int vacancyIndex) const
{
G4double n = -1;
@@ -189,12 +188,13 @@ void G4FluoData::LoadData(G4int Z)
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = "G4EMDataSet - G4LEDATA environment variable not set";
G4String excep("G4EMDataSet - G4LEDATA environment variable not set");
G4Exception(excep);
}
G4String pathString(path);
G4String dirFile = pathString + "/fluor/" + name;
G4String fluor("/fluor/");
G4String dirFile = pathString + fluor + name;
G4std::ifstream file(dirFile);
G4std::filebuf* lsdp = file.rdbuf();
@@ -255,7 +255,7 @@ void G4FluoData::LoadData(G4int Z)
if(k%nColumns == 2)
{
// 2nd column is transition probabilities
transProbabilities->push_back(a);
k++;
@@ -271,10 +271,10 @@ void G4FluoData::LoadData(G4int Z)
else if (k%nColumns == 0)
{//third column is transition energies
G4double e = a * MeV;
transEnergies->push_back(e);
k=1;
}
}
@@ -317,3 +317,32 @@ void G4FluoData::PrintData()
@@ -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. *
// ********************************************************************
//
//
// $Id: G4FluoTransition.cc,v 1.2 ????
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Elena Guardincerri (Elena.Guardincerri@ge.infn.it)
//
// History:
// -----------
// 16 Sept 2001 EG Modified according to a design iteration in the
// LowEnergy category
//
// -------------------------------------------------------------------
#include "G4FluoTransition.hh"
G4FluoTransition::G4FluoTransition(G4int finalShell,
const G4std::vector<G4int>& ids,
const G4DataVector& energies,
const G4DataVector& prob)
:finalShellId(finalShell),
originatingShellIds(ids),
transitionEnergies(energies),
transitionProbabilities(prob)
{ }
G4FluoTransition::~G4FluoTransition()
{ }
const G4std::vector<G4int>& G4FluoTransition::OriginatingShellIds() const
{
return originatingShellIds;
}
const G4DataVector& G4FluoTransition::TransitionEnergies() const
{
return transitionEnergies;
}
const G4DataVector& G4FluoTransition::TransitionProbabilities() const
{
return transitionProbabilities;
}
const G4int G4FluoTransition::FinalShellId() const
{
return finalShellId;
}
G4int G4FluoTransition::OriginatingShellId(G4int index) const
{
return originatingShellIds[index];
}
G4double G4FluoTransition::TransitionEnergy(G4int index) const
{
return transitionEnergies[index];
}
G4double G4FluoTransition::TransitionProbability(G4int index) const
{
return transitionProbabilities[index];
}
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4LinInterpolation.cc,v 1.1 2001/11/29 19:01:36 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4LinInterpolation.cc,v 1.2 2002/05/28 09:20:19 pia Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
@@ -39,16 +39,18 @@
G4LinInterpolation::G4LinInterpolation()
{ }
// Destructor
G4LinInterpolation::~G4LinInterpolation()
{ }
G4VDataSetAlgorithm* G4LinInterpolation::Clone() const
{ return new G4LinInterpolation; }
G4double G4LinInterpolation::Calculate(G4double x, G4int bin,
const G4DataVector& points,
const G4DataVector& data) const
const G4DataVector& points,
const G4DataVector& data) const
{
G4int nBins = data.size() - 1;
G4double value = 0.;
@@ -0,0 +1,70 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
//
// Author: Vladimir Ivanchenko (Vladimir.Ivantchenko@cern.ch)
//
// History:
// -----------
// 27 May 2002 VI Created
//
// -------------------------------------------------------------------
#include "G4LinLogInterpolation.hh"
// Constructor
G4LinLogInterpolation::G4LinLogInterpolation()
{ }
// Destructor
G4LinLogInterpolation::~G4LinLogInterpolation()
{ }
G4double G4LinLogInterpolation::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 = log(data[bin]);
G4double d2 = log(data[bin+1]);
value = exp(d1 + (d2 - d1)*(x - e1)/ (e2 - e1));
}
else
{
value = data[nBins];
}
return value;
}
@@ -0,0 +1,77 @@
//
// ********************************************************************
// * 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. *
// ********************************************************************
//
//
// Author: Vladimir Ivanchenko (Vladimir.Ivantchenko@cern.ch)
//
// History:
// -----------
// 29 May 2002 VI Created
//
// -------------------------------------------------------------------
#include "G4LinLogLogInterpolation.hh"
// Constructor
G4LinLogLogInterpolation::G4LinLogLogInterpolation()
{ }
// Destructor
G4LinLogLogInterpolation::~G4LinLogLogInterpolation()
{ }
G4VDataSetAlgorithm* G4LinLogLogInterpolation::Clone() const
{ return new G4LinLogLogInterpolation; }
G4double G4LinLogLogInterpolation::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];
if(d1 > 0.0 && d2 > 0.0) {
value = (log10(d1)*log10(e2/x) + log10(d2)*log10(x/e1)) / log10(e2/e1);
value = pow(10,value);
} else {
value = (d1*log10(e2/x) + d2*log10(x/e1)) / log10(e2/e1);
}
}
else
{
value = data[nBins];
}
return value;
}
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4LogLogInterpolation.cc,v 1.3 2001/09/10 18:07:35 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4LogLogInterpolation.cc,v 1.4 2002/05/28 09:20:19 pia Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
@@ -39,12 +39,14 @@
G4LogLogInterpolation::G4LogLogInterpolation()
{ }
// Destructor
G4LogLogInterpolation::~G4LogLogInterpolation()
{ }
G4VDataSetAlgorithm* G4LogLogInterpolation::Clone() const
{ return new G4LogLogInterpolation; }
G4double G4LogLogInterpolation::Calculate(G4double x, G4int bin,
const G4DataVector& points,
@@ -21,7 +21,7 @@
// ********************************************************************
//
// $Id: G4LowEnergyBremsstrahlung.cc,v 1.54 2001/11/29 19:01:36 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
// GEANT4 tag $Name: geant4-04-01 $
//
// --------------------------------------------------------------
//
@@ -21,7 +21,7 @@
// ********************************************************************
//
// $Id: G4LowEnergyCompton.cc,v 1.33 2001/11/07 20:47:29 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: A. Forti
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
@@ -22,8 +22,8 @@
//
// --------------------------------------------------------------------
///
// $Id: G4LowEnergyGammaConversion.cc,v 1.26 2001/11/07 21:31:16 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4LowEnergyGammaConversion.cc,v 1.27 2002/05/31 18:48:43 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
//
// --------------------------------------------------------------
@@ -252,7 +252,7 @@ G4VParticleChange* G4LowEnergyGammaConversion::PostStepDoIt(const G4Track& aTrac
G4double localEnergyDeposit = 0. ;
aParticleChange.SetNumberOfSecondaries(2.) ;
aParticleChange.SetNumberOfSecondaries(2) ;
G4double electronKineEnergy = G4std::max(0.,electronTotEnergy - electron_mass_c2) ;
// Generate the electron only if with large enough range w.r.t. cuts and safety
@@ -20,8 +20,8 @@
// * statement, and all its terms. *
// ********************************************************************
//
// $Id: G4LowEnergyIonisation.cc,v 1.76 2001/11/29 19:01:36 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4LowEnergyIonisation.cc,v 1.85 2002/06/03 00:07:17 pia Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// --------------------------------------------------------------
//
@@ -83,6 +83,12 @@
// 26.10.01 V.Ivanchenko clean up deexcitation
// 28.10.01 V.Ivanchenko update printout
// 29.11.01 V.Ivanchenko New parametrisation introduced
// 25.03.02 V.Ivanchneko Fix in fluorescence
// 28.03.02 V.Ivanchenko Add flag of fluorescence
// 28.05.02 V.Ivanchenko Remove flag fStopAndKill
// 31.05.02 V.Ivanchenko Add path of Fluo + Auger cuts to
// AtomicDeexcitation
// 03.06.02 MGP Restore fStopAndKill
//
// --------------------------------------------------------------
@@ -244,8 +250,7 @@ void G4LowEnergyIonisation::BuildLossTable(
G4PhysicsLogVector* bVector = new G4PhysicsLogVector(lowKineticEnergy,
highKineticEnergy,
binForFluo);
G4AtomicTransitionManager* transitionManager =
G4AtomicTransitionManager::Instance();
const G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
// Clean up the vector of cuts
@@ -300,8 +305,6 @@ void G4LowEnergyIonisation::BuildLossTable(
lowEdgeEnergy, n);
G4double cs= crossSectionHandler->FindValue(Z, lowEdgeEnergy, n);
ionloss += e * cs * pro * theAtomicNumDensityVector[iel];
G4double esp = energySpectrum->Excitation(Z, lowEdgeEnergy);
//ionloss += esp * theAtomicNumDensityVector[iel];
if(verboseLevel > 1) {
G4cout << "Z= " << Z
<< " shell= " << n
@@ -309,11 +312,12 @@ void G4LowEnergyIonisation::BuildLossTable(
<< " Eav(keV)= " << e/keV
<< " pro= " << pro
<< " cs= " << cs
<< " esp= " << esp
<< " loss= " << ionloss
<< G4endl;
}
}
G4double esp = energySpectrum->Excitation(Z, lowEdgeEnergy);
ionloss += esp * theAtomicNumDensityVector[iel];
}
aVector->PutValue(i,ionloss);
}
@@ -385,7 +389,7 @@ void G4LowEnergyIonisation::BuildLossTable(
G4VParticleChange* G4LowEnergyIonisation::PostStepDoIt(const G4Track& track,
const G4Step& step)
const G4Step& step)
{
// Delta electron production mechanism on base of the model
// J. Stepanek " A program to determine the radiation spectra due
@@ -481,6 +485,7 @@ G4VParticleChange* G4LowEnergyIonisation::PostStepDoIt(const G4Track& track,
if(finalKinEnergy < 0.0) {
theEnergyDeposit += finalKinEnergy;
finalKinEnergy = 0.0;
aParticleChange.SetStatusChange(fStopAndKill);
} else {
@@ -491,7 +496,6 @@ G4VParticleChange* G4LowEnergyIonisation::PostStepDoIt(const G4Track& track,
aParticleChange.SetMomentumChange(finalPx, finalPy, finalPz);
}
aParticleChange.SetEnergyChange(finalKinEnergy);
// Generation of Fluorescence and Auger
@@ -503,7 +507,7 @@ G4VParticleChange* G4LowEnergyIonisation::PostStepDoIt(const G4Track& track,
// Fluorescence data start from element 6
if (Z > 5 && (bindingEnergy >= cutForPhotons
if (Fluorescence() && Z > 5 && (bindingEnergy >= cutForPhotons
|| bindingEnergy >= cutForElectrons)) {
secondaryVector = deexcitationManager.GenerateParticles(Z, shellId);
@@ -586,8 +590,8 @@ G4bool G4LowEnergyIonisation::IsApplicable(const G4ParticleDefinition& particle)
G4std::vector<G4DynamicParticle*>*
G4LowEnergyIonisation::DeexciteAtom(const G4Material* material,
G4double incidentEnergy,
G4double eLoss)
G4double incidentEnergy,
G4double eLoss)
{
// create vector of secondary particles
@@ -596,7 +600,7 @@ G4LowEnergyIonisation::DeexciteAtom(const G4Material* material,
if(eLoss > cutForPhotons && eLoss > cutForElectrons) {
G4AtomicTransitionManager* transitionManager =
const G4AtomicTransitionManager* transitionManager =
G4AtomicTransitionManager::Instance();
size_t nElements = material->GetNumberOfElements();
@@ -622,8 +626,7 @@ G4LowEnergyIonisation::DeexciteAtom(const G4Material* material,
G4double maxE = transitionManager->Shell(Z, 0)->BindingEnergy();
if (Z>5 && (maxE>cutForPhotons || maxE>cutForElectrons)
&& nVacancies > 0 ) {
if (nVacancies && Z > 5 && (maxE>cutForPhotons || maxE>cutForElectrons)) {
for (size_t j=0; j<nVacancies; j++) {
@@ -683,10 +686,19 @@ G4double G4LowEnergyIonisation::GetMeanFreePath(const G4Track& track,
void G4LowEnergyIonisation::SetCutForLowEnSecPhotons(G4double cut)
{
cutForPhotons = cut;
deexcitationManager.SetCutForSecondaryPhotons(cut);
ActivateFluorescence(true);
}
void G4LowEnergyIonisation::SetCutForLowEnSecElectrons(G4double cut)
{
cutForElectrons = cut;
deexcitationManager.SetCutForAugerElectrons(cut);
ActivateFluorescence(true);
}
void G4LowEnergyIonisation::ActivateAuger(G4bool val)
{
deexcitationManager.ActivateAugerElectronProduction(val);
}
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4LowEnergyPhotoElectric.cc,v 1.42 2001/11/07 21:31:16 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4LowEnergyPhotoElectric.cc,v 1.48 2002/06/14 17:39:09 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: A. Forti
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
@@ -45,12 +45,16 @@
// . no Fluorescence was simulated when the photo-electron energy
// was below production threshold.
//
// 07-09-99, if no e- emitted: edep=photon energy, mma
// 24.04.01 V.Ivanchenko remove RogueWave
// 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
// 18.04.2001 V.Ivanchenko Fix problem with low energy gammas from fluorescence
// MeanFreePath is calculated by crosSectionHandler directly
// 31.05.2002 V.Ivanchenko Add path of Fluo + Auger cuts to AtomicDeexcitation
// 14.06.2002 V.Ivanchenko By default do not cheak range of e-
//
// --------------------------------------------------------------
@@ -72,7 +76,7 @@
#include "G4VDataSetAlgorithm.hh"
#include "G4LogLogInterpolation.hh"
#include "G4VRangeTest.hh"
#include "G4RangeTest.hh"
#include "G4RangeNoTest.hh"
#include "G4AtomicTransitionManager.hh"
#include "G4AtomicShell.hh"
@@ -82,7 +86,8 @@ G4LowEnergyPhotoElectric::G4LowEnergyPhotoElectric(const G4String& processName)
: G4VDiscreteProcess(processName), lowEnergyLimit(250*eV), highEnergyLimit(100*GeV),
intrinsicLowEnergyLimit(10*eV),
intrinsicHighEnergyLimit(100*GeV),
cutForLowEnergySecondaryPhotons(0.)
cutForLowEnergySecondaryPhotons(250.*eV),
cutForLowEnergySecondaryElectrons(250.*eV)
{
if (lowEnergyLimit < intrinsicLowEnergyLimit ||
highEnergyLimit > intrinsicHighEnergyLimit)
@@ -93,7 +98,7 @@ G4LowEnergyPhotoElectric::G4LowEnergyPhotoElectric(const G4String& processName)
crossSectionHandler = new G4CrossSectionHandler();
shellCrossSectionHandler = new G4CrossSectionHandler();
meanFreePathTable = 0;
rangeTest = new G4RangeTest;
rangeTest = new G4RangeNoTest;
if (verboseLevel > 0)
{
@@ -161,7 +166,7 @@ G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
size_t shellIndex = shellCrossSectionHandler->SelectRandomShell(Z,photonEnergy);
// Retrieve the corresponding identifier and binding energy of the selected shell
G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
const G4AtomicTransitionManager* transitionManager = G4AtomicTransitionManager::Instance();
const G4AtomicShell* shell = transitionManager->Shell(Z,shellIndex);
G4double bindingEnergy = shell->BindingEnergy();
G4int shellId = shell->ShellId();
@@ -171,7 +176,7 @@ G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
G4std::vector<G4DynamicParticle*>* photonVector = 0;
G4std::vector<G4DynamicParticle*> electronVector;
G4double energyDeposit = bindingEnergy;
G4double energyDeposit = 0.0;
// Primary outcoming electron
G4double eKineticEnergy = photonEnergy - bindingEnergy;
@@ -198,60 +203,71 @@ G4VParticleChange* G4LowEnergyPhotoElectric::PostStepDoIt(const G4Track& aTrack,
}
else
{
energyDeposit = photonEnergy;
bindingEnergy = photonEnergy;
}
G4int nElectrons = electronVector.size();
size_t nTotPhotons = 0;
G4int nPhotons=0;
G4double cutg = G4std::min(cutForLowEnergySecondaryPhotons,
G4Gamma::Gamma()->GetEnergyThreshold(material));
G4double cute = G4std::min(cutForLowEnergySecondaryElectrons,
G4Electron::Electron()->GetEnergyThreshold(material));
G4DynamicParticle* aPhoton;
// 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.)
if (Z > 5 && (bindingEnergy > cutg || bindingEnergy > cute))
{
photonVector = deexcitationManager.GenerateParticles(Z,shellId);
nTotPhotons = photonVector->size();
for (size_t k=0; k<nTotPhotons; k++)
{
G4DynamicParticle* aPhoton = (*photonVector)[k];
if (aPhoton == 0)
aPhoton = (*photonVector)[k];
if (aPhoton)
{
delete aPhoton;
}
else
{
G4double itsKineticEnergy = aPhoton->GetKineticEnergy();
G4double eDepositTmp = energyDeposit - itsKineticEnergy;
if (itsKineticEnergy >= cutForLowEnergySecondaryPhotons &&
eDepositTmp > 0.)
G4double itsCut = cutg;
if(aPhoton->GetDefinition() == G4Electron::Electron()) itsCut = cute;
G4double itsEnergy = aPhoton->GetKineticEnergy();
if (itsEnergy > itsCut && itsEnergy <= bindingEnergy)
{
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;
bindingEnergy -= itsEnergy;
}
else
{ delete aPhoton; }
{
delete aPhoton;
(*photonVector)[k] = 0;
}
}
}
}
energyDeposit += bindingEnergy;
G4int nSecondaries = nElectrons + nPhotons;
aParticleChange.SetNumberOfSecondaries(nSecondaries);
G4int l = 0;
for ( l = 0; l<nElectrons; l++ )
for (G4int l = 0; l<nElectrons; l++ )
{
aParticleChange.AddSecondary(electronVector[l]);
aPhoton = electronVector[l];
if(aPhoton) {
aParticleChange.AddSecondary(aPhoton);
}
}
for (l = 0; l < nPhotons; l++)
for ( size_t ll = 0; ll < nTotPhotons; ll++)
{
aParticleChange.AddSecondary((*photonVector)[l]);
aPhoton = (*photonVector)[ll];
if(aPhoton) {
aParticleChange.AddSecondary(aPhoton);
}
}
delete photonVector;
@@ -287,19 +303,36 @@ G4double G4LowEnergyPhotoElectric::GetMeanFreePath(const G4Track& track,
const G4DynamicParticle* photon = track.GetDynamicParticle();
G4double energy = photon->GetKineticEnergy();
G4Material* material = track.GetMaterial();
size_t materialIndex = material->GetIndex();
// size_t materialIndex = material->GetIndex();
G4double meanFreePath = DBL_MAX;
// if (energy > highEnergyLimit)
// meanFreePath = meanFreePathTable->FindValue(highEnergyLimit,materialIndex);
// else if (energy < lowEnergyLimit) meanFreePath = DBL_MAX;
// else meanFreePath = meanFreePathTable->FindValue(energy,materialIndex);
G4double cross = shellCrossSectionHandler->ValueForMaterial(material,energy);
if(cross > 0.0) meanFreePath = 1.0/cross;
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;
deexcitationManager.SetCutForSecondaryPhotons(cut);
}
void G4LowEnergyPhotoElectric::SetCutForLowEnSecElectrons(G4double cut)
{
cutForLowEnergySecondaryElectrons = cut;
deexcitationManager.SetCutForAugerElectrons(cut);
}
void G4LowEnergyPhotoElectric::ActivateAuger(G4bool val)
{
deexcitationManager.ActivateAugerElectronProduction(val);
}
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4LowEnergyPolarizedCompton.cc,v 1.11 2001/11/07 21:31:16 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4LowEnergyPolarizedCompton.cc,v 1.13 2002/06/02 21:27:52 pia Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// ------------------------------------------------------------
// GEANT 4 class implementation file
@@ -32,6 +32,7 @@
// --------- G4LowEnergyPolarizedCompton class -----
//
// by G.Depaola & F.Longo (21 may 2001)
//
// 21 May 2001 - MGP Modified to inherit from G4VDiscreteProcess
// Applies same algorithm as LowEnergyCompton
// if the incoming photon is not polarised
@@ -40,6 +41,11 @@
//
// 17 October 2001 - F.Longo - Revised according to a design iteration
//
// 21 February 2002 - F.Longo Revisions with A.Zoglauer and G.Depaola
// - better description of parallelism
// - system of ref change method improved
//
//
// ************************************************************
//
// Corrections by Rui Curado da Silva (2000)
@@ -155,21 +161,28 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
// direction causes problems;
// in that case find a random polarization
G4ThreeVector gammaDirection = incidentPhoton->GetMomentumDirection();
G4ThreeVector gammaDirection0 = incidentPhoton->GetMomentumDirection();
// ---- MGP ---- Next two lines commented out to remove compilation warnings
// G4double scalarproduct = gammaPolarization0.dot(gammaDirection0);
// G4double angle = gammaPolarization0.angle(gammaDirection0);
// Make sure that the polarization vector is perpendicular to the
// gamma direction. If not
G4double scalarproduct = gammaPolarization0.dot(gammaDirection);
G4double angle = gammaPolarization0.angle(gammaDirection);
if (scalarproduct != 0. || angle == 0)
{
// isPolarised = false;
gammaPolarization0 = SetRandomPolarization(gammaDirection);
if(!(gammaPolarization0.isOrthogonal(gammaDirection0, 1e-6))||(gammaPolarization0.mag()==0))
{ // only for testing now
gammaPolarization0 = GetRandomPolarization(gammaDirection0);
}
else
{
if ( gammaPolarization0.howOrthogonal(gammaDirection0) != 0)
{
gammaPolarization0 = GetPerpendicularPolarization(gammaDirection0, gammaPolarization0);
}
}
// End of Protection
// G4double polarisation = gammaPolarization0.mag();
// Within energy limit?
if(gammaEnergy0 <= lowEnergyLimit)
@@ -181,7 +194,6 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
}
G4double E0_m = gammaEnergy0 / electron_mass_c2 ;
G4ThreeVector gammaDirection0 = incidentPhoton->GetMomentumDirection();
// Select randomly one element in the current material
@@ -201,9 +213,6 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
G4double gammaEnergy1;
G4ThreeVector gammaDirection1;
// if (isPolarised) // apply Polarized Condition
// {
do {
if ( alpha1/(alpha1+alpha2) > G4UniformRand() )
{
@@ -245,11 +254,9 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
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
@@ -332,9 +339,7 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
cosTheta);
// Set new direction
//G4ThreeVector tmpDirection1( dirx,diry,dirz );
G4ParticleMomentum tmpDirection1( dirx,diry,dirz );
G4ThreeVector tmpDirection1( dirx,diry,dirz );
gammaDirection1 = tmpDirection1;
// Change reference frame.
@@ -345,6 +350,8 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
if (gammaEnergy1 > 0.)
{
aParticleChange.SetEnergyChange( gammaEnergy1 ) ;
aParticleChange.SetMomentumChange( gammaDirection1 );
aParticleChange.SetPolarizationChange( gammaPolarization1 );
}
else
{
@@ -358,7 +365,6 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
G4double ElecKineEnergy = gammaEnergy0 - gammaEnergy1 ;
// Generate the electron only if with large enough range w.r.t. cuts and safety
G4double safety = aStep.GetPostStepPoint()->GetSafety();
@@ -368,7 +374,7 @@ G4VParticleChange* G4LowEnergyPolarizedCompton::PostStepDoIt(const G4Track& aTra
G4double ElecMomentum = sqrt(ElecKineEnergy*(ElecKineEnergy+2.*electron_mass_c2));
G4ThreeVector ElecDirection((gammaEnergy0 * gammaDirection0 -
gammaEnergy1 * gammaDirection1) * (1./ElecMomentum));
G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),ElecDirection,ElecKineEnergy) ;
G4DynamicParticle* electron = new G4DynamicParticle (G4Electron::Electron(),ElecDirection.unit(),ElecKineEnergy) ;
aParticleChange.SetNumberOfSecondaries(1);
aParticleChange.AddSecondary(electron);
aParticleChange.SetLocalEnergyDeposit(0.);
@@ -428,7 +434,7 @@ G4ThreeVector G4LowEnergyPolarizedCompton::SetPerpendicularVector(G4ThreeVector&
}
}
G4ThreeVector G4LowEnergyPolarizedCompton::SetRandomPolarization(G4ThreeVector& direction0)
G4ThreeVector G4LowEnergyPolarizedCompton::GetRandomPolarization(G4ThreeVector& direction0)
{
G4ThreeVector d0 = direction0.unit();
G4ThreeVector a1 = SetPerpendicularVector(d0); //different orthogonal
@@ -451,6 +457,25 @@ G4ThreeVector G4LowEnergyPolarizedCompton::SetRandomPolarization(G4ThreeVector&
}
G4ThreeVector G4LowEnergyPolarizedCompton::GetPerpendicularPolarization
(const G4ThreeVector& gammaDirection, const G4ThreeVector& gammaPolarization) const
{
//
// The polarization of a photon is always perpendicular to its momentum direction.
// Therefore this function removes those vector component of gammaPolarization, which
// points in direction of gammaDirection
//
// Mathematically we search the projection of the vector a on the plane E, where n is the
// plains normal vector.
// The basic equation can be found in each geometry book (e.g. Bronstein):
// p = a + (a o n)/(n o n)*n
return gammaPolarization + gammaPolarization.dot(gammaDirection)/gammaDirection.dot(gammaDirection) * gammaDirection;
}
G4ThreeVector G4LowEnergyPolarizedCompton::SetNewPolarization(G4double epsilon,
G4double sinSqrTh,
G4double phi,
@@ -480,16 +505,16 @@ G4ThreeVector G4LowEnergyPolarizedCompton::SetNewPolarization(G4double epsilon,
rand2 = G4UniformRand();
thetaProbability=0.;
theta = twopi*rand1;
a = 4;
a = 4*normalisation*normalisation;
b = (epsilon + 1/epsilon) - 2;
thetaProbability = (b + a*cos(theta)*cos(theta))/(a+b);
cosTheta = cos(theta);
}
while ( rand2 > thetaProbability || abs(cosTheta) > abs(normalisation) );
while ( rand2 > thetaProbability );
G4double cosBeta = cosTheta/normalisation;
G4double cosBeta = cosTheta;
G4double sinBeta = sqrt(1-cosBeta*cosBeta);
G4ThreeVector gammaPolarization1;
G4double xParallel = normalisation*cosBeta;
@@ -517,60 +542,24 @@ void G4LowEnergyPolarizedCompton::SystemOfRefChange
G4ThreeVector& polarization0,G4ThreeVector& polarization1)
{
// Angles for go back to the original RS
// direction0 is the original photon direction ---> z
// polarization0 is the original photon polarization ---> x
// need to specify y axis in the real reference frame ---> y
G4ThreeVector Axis_Z0 = direction0.unit();
G4ThreeVector Axis_X0 = polarization0.unit();
G4ThreeVector Axis_Y0 = (Axis_Z0.cross(Axis_X0)).unit(); // to be confirmed;
G4double direction_x = direction1.getX();
G4double direction_y = direction1.getY();
G4double direction_z = direction1.getZ();
G4double cosTheta0 = direction0.cosTheta();
G4double sinTheta0 = sin(direction0.theta());
G4double cosPhi0 = cos(direction0.phi());
G4double sinPhi0 = sin(direction0.phi());
G4double cosPsi, sinPsi;
direction1 = (direction_x*Axis_X0 + direction_y*Axis_Y0 + direction_z*Axis_Z0).unit();
// if (sinTheta0 >= 1.e-14 ) {
if (sinTheta0 != 0. )
{
cosPsi = -polarization0.z()/sinTheta0;
// if (cosPhi0 >=1.e-14 ) {
if (cosPhi0 != 0. )
{
sinPsi = (polarization0.y() - cosTheta0*sinPhi0*cosPsi)/cosPhi0;
}
else
{
sinPsi = -polarization0.x()/sinPhi0;
}
}
else
{
cosPsi = polarization0.x()/cosTheta0;
sinPsi = polarization0.y();
}
G4double polarization_x = polarization1.getX();
G4double polarization_y = polarization1.getY();
G4double polarization_z = polarization1.getZ();
// Added protection
G4double psi = 0;
if (sinPsi < 0.) psi = -pi/2.;
if (sinPsi > 0.) psi = pi/2.;
if (cosPsi != 0.)
{
psi = atan(sinPsi/cosPsi);
}
// Rotation along Z axis
direction1.rotateZ(psi);
//
direction1.rotateUz(direction0);
aParticleChange.SetMomentumChange( direction1 ) ;
// 3 Euler angles rotation for scattered photon polarization
polarization1.rotateZ(psi);
polarization1.rotateUz(direction0);
aParticleChange.SetPolarizationChange( polarization1 );
polarization1 =(polarization_x*Axis_X0+polarization_y*Axis_Y0+polarization_z*Axis_Z0).unit();
}
@@ -589,7 +578,6 @@ G4double G4LowEnergyPolarizedCompton::GetMeanFreePath(const G4Track& track,
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;
@@ -22,8 +22,8 @@
//
// --------------------------------------------------------------------
//
// $Id: G4LowEnergyRayleigh.cc,v 1.28 2001/11/07 21:31:16 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4LowEnergyRayleigh.cc,v 1.29 2002/06/07 10:25:02 flongo Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: A. Forti
// Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
@@ -38,6 +38,7 @@
// 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
// 05.06.2002 F.Longo and G.Depaola - bug fixed in angular distribution
//
// --------------------------------------------------------------------
@@ -165,9 +166,9 @@ G4VParticleChange* G4LowEnergyRayleigh::PostStepDoIt(const G4Track& aTrack,
G4double theta = thetaHalf*2;
cosTheta = cos(theta);
sinTheta = sin(theta);
G4double sqrRayl = 1 + cosTheta * cosTheta;
G4double sqrRayl = sqrt(27./32.)*(1 + cosTheta * cosTheta)*sinTheta;
gReject = sqrRayl * dataFormFactor * dataFormFactor;
} while( gReject < randomFormFactor);
// Scattered photon angles. ( Z - axis along the parent photon)
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4RangeTest.cc,v 1.4 2001/11/07 20:47:30 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4RangeTest.cc,v 1.5 2002/05/28 09:20:21 pia Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
@@ -37,6 +37,9 @@
#include "G4Material.hh"
#include "G4EnergyLossTables.hh"
G4RangeTest::~G4RangeTest()
{ }
G4bool G4RangeTest::Escape(const G4ParticleDefinition* particle,
const G4Material* material,
G4double energy,
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4SemiLogInterpolation.cc,v 1.3 2001/09/10 18:07:35 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4SemiLogInterpolation.cc,v 1.4 2002/05/28 09:20:21 pia Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
@@ -45,6 +45,9 @@ G4SemiLogInterpolation::G4SemiLogInterpolation()
G4SemiLogInterpolation::~G4SemiLogInterpolation()
{ }
G4VDataSetAlgorithm* G4SemiLogInterpolation::Clone() const
{ return new G4SemiLogInterpolation; }
G4double G4SemiLogInterpolation::Calculate(G4double x, G4int bin,
const G4DataVector& points,
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4ShellData.cc,v 1.4 2001/09/26 21:19:23 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4ShellData.cc,v 1.5 2002/05/28 09:20:21 pia Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
@@ -48,12 +48,12 @@ G4ShellData::~G4ShellData()
{
G4std::map<G4int,G4DataVector*,G4std::less<G4int> >::iterator pos;
for (pos = idMap.begin(); pos != idMap.end(); pos++)
for (pos = idMap.begin(); pos != idMap.end(); ++pos)
{
G4DataVector* dataSet = (*pos).second;
delete dataSet;
}
for (pos = bindingMap.begin(); pos != bindingMap.end(); pos++)
for (pos = bindingMap.begin(); pos != bindingMap.end(); ++pos)
{
G4DataVector* dataSet = (*pos).second;
delete dataSet;
@@ -170,7 +170,7 @@ void G4ShellData::LoadData(const G4String& fileName)
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = "G4EMDataSet - G4LEDATA environment variable not set";
G4String excep("G4EMDataSet - G4LEDATA environment variable not set");
G4Exception(excep);
}
@@ -181,7 +181,9 @@ void G4ShellData::LoadData(const G4String& fileName)
if (! (lsdp->is_open()) )
{
G4String excep = "G4ShellData - data file: " + dirFile + " not found";
G4String s1("G4ShellData - data file: ");
G4String s2(" not found");
G4String excep = s1 + dirFile + s2;
G4Exception(excep);
}
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4ShellEMDataSet.cc,v 1.7 2001/10/11 14:10:40 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4ShellEMDataSet.cc,v 1.8 2002/05/28 09:20:21 pia Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
@@ -65,7 +65,8 @@ G4ShellEMDataSet::~G4ShellEMDataSet()
{
for (size_t i=0; i<nComponents; i++)
{
delete components[i];
G4VEMDataSet* dataSet = components[i];
delete dataSet;
}
delete algorithm;
}
@@ -112,18 +113,21 @@ void G4ShellEMDataSet::LoadData(const G4String& fileName)
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = "G4ShellEMDataSet - G4LEDATA environment variable not set";
G4String excep("G4ShellEMDataSet - G4LEDATA environment variable not set");
G4Exception(excep);
}
G4String pathString(path);
G4String dirFile = pathString + "/" + name;
G4String separator("/" );
G4String dirFile = pathString + separator + name;
G4std::ifstream file(dirFile);
G4std::filebuf* lsdp = file.rdbuf();
if (! (lsdp->is_open()) )
{
G4String excep = "G4ShellEMDataSet - data file: " + dirFile + " not found";
G4String s1("G4ShellEMDataSet - data file: ");
G4String s2(" not found");
G4String excep = s1 + dirFile + s2;
G4Exception(excep);
}
@@ -29,6 +29,7 @@
// History:
// -----------
// 21 Sept 2001 Elena Guardincerri Created
// 25 Mar 2002 V.Ivanchenko Change AverageNOfIonisations int->double
//
// -------------------------------------------------------------------
@@ -67,17 +68,18 @@ G4std::vector<G4int> G4ShellVacancy::GenerateNumberOfIonisations(const G4Materia
{
G4std::vector<G4int> numberOfIonisations;
size_t numberOfElements = material->GetNumberOfElements();
G4int numberOfElements = material->GetNumberOfElements();
for (size_t i = 0; i<numberOfElements; i++)
for (G4int i = 0; i<numberOfElements; i++)
{
const G4Element* element = material->GetElement(i);
G4int averageNumberOfIonisations = AverageNOfIonisations(material,
element,
incidentEnergy,
eLoss);
G4int ionisations = (G4int) G4Poisson(averageNumberOfIonisations);
G4double averageNumberOfIonisations = AverageNOfIonisations(material,
i,
incidentEnergy,
eLoss);
G4int ionisations = 0;
if(averageNumberOfIonisations > 0.0) {
ionisations = (G4int) G4Poisson(averageNumberOfIonisations);
}
numberOfIonisations.push_back(ionisations);
@@ -86,42 +88,21 @@ G4std::vector<G4int> G4ShellVacancy::GenerateNumberOfIonisations(const G4Materia
}
G4int G4ShellVacancy::AverageNOfIonisations(const G4Material* material,
const G4Element* element,
G4double energy,
G4double eLoss) const
G4double G4ShellVacancy::AverageNOfIonisations(const G4Material* material,
G4int index,
G4double energy,
G4double eLoss) const
{
G4int indexOfElementInMaterial= -1;
// 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];
G4VEMDataSet* aSetOfXsi = xsis[indexInMaterialTable];
G4double aXsi = aSetOfXsi->FindValue(averageEnergy,indexOfElementInMaterial);
G4int averageNumberOfIonisations = (G4int)(aXsi * eLoss);
return averageNumberOfIonisations;
G4double aXsi = aSetOfXsi->FindValue(averageEnergy,index);
return aXsi * eLoss;
}
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4VCrossSectionHandler.cc,v 1.8 2001/10/10 16:46:06 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4VCrossSectionHandler.cc,v 1.9 2002/05/28 09:20:21 pia Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
@@ -405,8 +405,7 @@ G4double G4VCrossSectionHandler::ValueForMaterial(const G4Material* material,
}
G4VEMDataSet* G4VCrossSectionHandler::BuildMeanFreePathForMaterials(
const G4DataVector* energyCuts)
G4VEMDataSet* G4VCrossSectionHandler::BuildMeanFreePathForMaterials(const G4DataVector* energyCuts)
{
// Builds a CompositeDataSet containing the mean free path for each material
// in the material table
@@ -22,7 +22,7 @@
//
//
// $Id: G4VeLowEnergyLoss.cc,v 1.17 2001/11/23 11:45:29 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
// GEANT4 tag $Name: geant4-04-01 $
//
//
// --------------------------------------------------------------
@@ -20,8 +20,8 @@
// * 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 $
// $Id: G4eBremsstrahlungSpectrum.cc,v 1.7 2002/05/30 17:53:09 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// -------------------------------------------------------------------
//
@@ -37,6 +37,8 @@
// 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
// 30.05.02 VI Update interpolation between 2 last energy points in the
// parametrisation
//
// -------------------------------------------------------------------
@@ -73,10 +75,10 @@ G4eBremsstrahlungSpectrum::~G4eBremsstrahlungSpectrum()
G4double G4eBremsstrahlungSpectrum::Probability(G4int Z,
G4double tmin,
G4double tmax,
G4double e,
G4int,
G4double tmin,
G4double tmax,
G4double e,
G4int,
const G4ParticleDefinition*) const
{
G4double tm = G4std::min(tmax, e);
@@ -87,31 +89,16 @@ G4double G4eBremsstrahlungSpectrum::Probability(G4int Z,
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);
G4DataVector p;
// Access parameters
for (size_t i=0; i<=length; i++) {
p.push_back(theBRparam->Parameter(i, Z, e));
}
G4double x = IntSpectrum(t0, tm, p);
G4double y = IntSpectrum(z, 1.0, p);
if(1 < verbose) {
G4cout << "tcut(MeV)= " << tmin/MeV
@@ -124,60 +111,47 @@ G4double G4eBremsstrahlungSpectrum::Probability(G4int Z,
<< "; nor= " << y
<< G4endl;
}
p.clear();
if(y > 0.0) x /= y;
else x = 0.0;
if(x < 0.0) x = 0.0;
// if(x < 0.0) x = 0.0;
return x;
}
G4double G4eBremsstrahlungSpectrum::AverageEnergy(G4int Z,
G4double tmin,
G4double tmax,
G4double e,
G4int,
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;
G4double z0 = lowestE/e;
// Below 10 MeV EEDL data base spectrum
if(e < 1000000.*MeV) {
G4DataVector p;
G4int iMax = 16;
G4DataVector p;
// Access parameters
for (G4int i=0; i<iMax; i++) {
// Access parameters
for (size_t i=0; i<=length; 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));
G4double x = AverageValue(t0, tm, p);
G4double y = IntSpectrum(z0, 1.0, p);
// Add integrant over lowest energies
G4double c = sqrt(theBRparam->ParameterC(Z));
G4double f = Function(z0, p);
x += 0.5*f*z0*(z0 - c*atan(z0/c));
x *= e;
@@ -191,21 +165,21 @@ G4double G4eBremsstrahlungSpectrum::AverageEnergy(G4int Z,
<< "; x= " << x
<< G4endl;
}
p.clear();
if(y > 0.0) x /= y;
else x = 0.0;
if(x < 0.0) x = 0.0;
// if(x < 0.0) x = 0.0;
return x;
}
G4double G4eBremsstrahlungSpectrum::SampleEnergy(G4int Z,
G4double tmin,
G4double tmax,
G4double e,
G4int,
G4double tmin,
G4double tmax,
G4double e,
G4int,
const G4ParticleDefinition*) const
{
G4double tm = G4std::min(tmax, e);
@@ -215,34 +189,22 @@ G4double G4eBremsstrahlungSpectrum::SampleEnergy(G4int Z,
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;
for (size_t i=0; i<=length; i++) {
p.push_back(theBRparam->Parameter(i, Z, e));
}
G4double amaj = G4std::max(p[15], 1. - (p[1] - p[0])/9.);
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;
}
fun = Function(tgam, p);
if(fun > amaj) {
G4cout << "WARNING in G4eBremsstrahlungSpectrum::SampleEnergy:"
<< " Majoranta " << amaj
@@ -261,13 +223,11 @@ G4double G4eBremsstrahlungSpectrum::SampleEnergy(G4int Z,
}
G4double G4eBremsstrahlungSpectrum::IntSpectrum(G4double xMin,
G4double xMax,
const G4DataVector& p) const
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) {
@@ -279,8 +239,8 @@ G4double G4eBremsstrahlungSpectrum::IntSpectrum(G4double xMin,
x1 = G4std::max(xMin, xp[i]);
x2 = G4std::min(xMax, xp[i+1]);
if(x1 < x2) {
z1 = p[i];
z2 = p[i+1];
G4double z1 = p[i];
G4double z2 = p[i+1];
sum += z2 - z1 + log(x2/x1)*(z1*x2 - z2*x1)/(x2 - x1);
}
}
@@ -289,8 +249,8 @@ G4double G4eBremsstrahlungSpectrum::IntSpectrum(G4double xMin,
}
G4double G4eBremsstrahlungSpectrum::AverageValue(G4double xMin,
G4double xMax,
const G4DataVector& p) const
G4double xMax,
const G4DataVector& p) const
{
G4double x1 = G4std::min(xMin, xp[0]);
G4double x2 = G4std::min(xMax, xp[0]);
@@ -303,7 +263,7 @@ G4double G4eBremsstrahlungSpectrum::AverageValue(G4double xMin,
sum += (z2 - z1)*(1. - k*xp[0]);
z1 *= x1;
z2 *= x2;
sum += 0.5*k*(z1 - z2);
sum += 0.5*k*(z2 - z1);
}
for (size_t i=0; i<length-1; i++) {
@@ -320,7 +280,7 @@ G4double G4eBremsstrahlungSpectrum::AverageValue(G4double xMin,
}
G4double G4eBremsstrahlungSpectrum::Function(G4double x,
const G4DataVector& p) const
const G4DataVector& p) const
{
G4double f = 0.0;
@@ -331,16 +291,26 @@ G4double G4eBremsstrahlungSpectrum::Function(G4double x,
for (size_t i=0; i<length-1; i++) {
if(x <= xp[i+1] && x >= xp[i]) {
if(x <= xp[i+1]) {
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(); }
G4double G4eBremsstrahlungSpectrum::Excitation(G4int Z, G4double kineticEnergy) const
{
return 0.0;
}
G4double G4eBremsstrahlungSpectrum::MaxEnergyOfSecondaries(G4double kineticEnergy,
G4int Z,
const G4ParticleDefinition*) const
{
return kineticEnergy;
}
@@ -20,8 +20,8 @@
// * 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 $
// $Id: G4eIonisationCrossSectionHandler.cc,v 1.7 2002/05/30 17:53:09 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// -------------------------------------------------------------------
//
@@ -44,6 +44,7 @@
#include "G4DataVector.hh"
#include "G4CompositeEMDataSet.hh"
#include "G4VDataSetAlgorithm.hh"
#include "G4LinLogLogInterpolation.hh"
#include "G4SemiLogInterpolation.hh"
#include "G4VEMDataSet.hh"
#include "G4EMDataSet.hh"
@@ -58,7 +59,7 @@ G4eIonisationCrossSectionHandler::G4eIonisationCrossSectionHandler(
theParam(spec)
{
G4VCrossSectionHandler::Initialise(alg, emin, emax, nbin);
interp = new G4SemiLogInterpolation();
interp = new G4LinLogLogInterpolation();
}
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4eIonisationParameters.cc,v 1.17 2001/11/30 00:52:52 pia Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4eIonisationParameters.cc,v 1.19 2002/05/30 17:53:09 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// Author: Maria Grazia Pia (Maria.Grazia.Pia@cern.ch)
//
@@ -34,6 +34,8 @@
// 25.10.01 MGP Many bug fixes, mostly related to the
// management of pointers
// 29.11.01 V.Ivanchenko New parametrisation + Excitation
// 30.05.02 V.Ivanchenko Format and names of the data files were
// chenged to "ion-..."
//
// -------------------------------------------------------------------
@@ -42,7 +44,10 @@
#include "G4ShellEMDataSet.hh"
#include "G4EMDataSet.hh"
#include "G4CompositeEMDataSet.hh"
#include "G4LinInterpolation.hh"
#include "G4LogLogInterpolation.hh"
#include "G4LinLogLogInterpolation.hh"
#include "G4SemiLogInterpolation.hh"
#include "G4Material.hh"
#include "G4DataVector.hh"
#include "g4std/fstream"
@@ -51,7 +56,7 @@
G4eIonisationParameters:: G4eIonisationParameters(G4int minZ, G4int maxZ)
: zMin(minZ), zMax(maxZ),
length(7)
length(24)
{
LoadData();
}
@@ -83,7 +88,7 @@ G4double G4eIonisationParameters::Parameter(G4int Z, G4int shellIndex,
G4double e) const
{
G4double value = 0.;
G4int id = Z*20 + parameterIndex;
G4int id = Z*100 + parameterIndex;
G4std::map<G4int,G4VEMDataSet*,G4std::less<G4int> >::const_iterator pos;
pos = param.find(id);
@@ -165,12 +170,13 @@ void G4eIonisationParameters::LoadData()
char* path = getenv("G4LEDATA");
if (!path)
{
G4String excep = "G4eIonisationParameters - G4LEDATA environment variable not set";
G4String excep("G4eIonisationParameters - G4LEDATA environment variable not set");
G4Exception(excep);
}
G4String pathString(path);
pathString += "/ioni/io-sp-";
G4String path2("/ioni/ion-sp-");
pathString += path2;
G4double energy, sum;
@@ -188,20 +194,26 @@ void G4eIonisationParameters::LoadData()
G4std::filebuf* lsdp = file.rdbuf();
if (! (lsdp->is_open()) ) {
G4String excep = "G4IonisationParameters - data file: "
+ name + " not found";
G4String excep = G4String("G4IonisationParameters - data file: ")
+ name + G4String(" not found. The version 1.# of G4LEDATA should be used");
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
// The file is organized into:
// For each shell there are two lines:
// 1st line:
// 1st column is the energy of incident e-,
// 2d column is the parameter of screan term;
// 2d line:
// 3 energy (MeV) subdividing different approximation area of the spectrum
// 20 point on the spectrum
// The shell terminates with the pattern: -1 -1
// The file terminates with the pattern: -2 -2
G4std::vector<G4VEMDataSet*> p;
for (size_t k=0; k<length; k++)
{
G4VDataSetAlgorithm* inter = new G4LogLogInterpolation();
G4VDataSetAlgorithm* inter = new G4LinLogLogInterpolation();
G4VEMDataSet* composite = new G4CompositeEMDataSet(inter,1.,1.);
p.push_back(composite);
}
@@ -233,8 +245,10 @@ void G4eIonisationParameters::LoadData()
// 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();
G4VDataSetAlgorithm* interp;
if(0 == k) interp = new G4LinLogLogInterpolation();
else interp = new G4LogLogInterpolation();
G4DataVector* eVector = new G4DataVector;
size_t eSize = e.size();
for (size_t s=0; s<eSize; s++) {
@@ -258,17 +272,17 @@ void G4eIonisationParameters::LoadData()
for (size_t kk=0; kk<length; kk++)
{
G4int id = Z*20 + kk;
G4int id = Z*100 + kk;
param[id] = p[kk];
}
}
G4String pathString_a(path);
G4String name_a = pathString_a + "/ioni/io-ex-av.dat";
G4String name_a = pathString_a + G4String("/ioni/ion-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";
G4String name_b = pathString_b + G4String("/ioni/ion-ex-sig.dat");
G4std::ifstream file_b(name_b);
G4std::filebuf* lsdp_b = file_b.rdbuf();
@@ -300,12 +314,14 @@ void G4eIonisationParameters::LoadData()
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;
@@ -319,7 +335,7 @@ void G4eIonisationParameters::LoadData()
// fill map if Z is used
if (activeZ.contains(Z)) {
G4VDataSetAlgorithm* inter = new G4LogLogInterpolation();
G4VDataSetAlgorithm* inter = new G4LinInterpolation();
G4DataVector* eVector = new G4DataVector;
G4DataVector* dVector = new G4DataVector;
size_t eSize = e.size();
@@ -335,7 +351,7 @@ void G4eIonisationParameters::LoadData()
} else {
e.push_back(ener);
e.push_back(ener*MeV);
d.push_back(sig1*sig*barn*MeV);
}
} while (ener != -2);
@@ -359,7 +375,7 @@ void G4eIonisationParameters::PrintData() const
for (size_t j=0; j<length; j++) {
G4int index = Z*20 + j;
G4int index = Z*100 + j;
pos = param.find(index);
if (pos!= param.end()) {
@@ -20,8 +20,8 @@
// * 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 $
// $Id: G4eIonisationSpectrum.cc,v 1.19 2002/06/03 17:52:12 pia Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// -------------------------------------------------------------------
//
@@ -39,6 +39,8 @@
// consistency with design
// 02.11.2001 VI Optimize sampling of energy
// 29.11.2001 VI New parametrisation
// 19.04.2002 VI Add protection in case of energy below binding
// 30.05.2002 VI Update to 24-parameters data
//
// -------------------------------------------------------------------
//
@@ -46,13 +48,14 @@
#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),
factor(1.3),
iMax(24),
verbose(0)
{
theParam = new G4eIonisationParameters();
@@ -84,8 +87,12 @@ G4double G4eIonisationSpectrum::Probability(G4int Z,
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(e <= bindingEnergy) return 0.0;
G4double energy = e + bindingEnergy;
G4double x1 = G4std::min(0.5,(t0 + bindingEnergy)/energy);
G4double x2 = G4std::min(0.5,(tm + bindingEnergy)/energy);
if(verbose > 1) {
G4cout << "G4eIonisationSpectrum::Probability: Z= " << Z
@@ -96,20 +103,25 @@ G4double G4eIonisationSpectrum::Probability(G4int Z,
<< 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 x = theParam->Parameter(Z, shell, i, e);
if(i<4) x /= energy;
p.push_back(x);
}
G4double g = (e + bindingEnergy)/electron_mass_c2 + 1.;
if(p[3] > 0.5) p[3] = 0.5;
G4double g = energy/electron_mass_c2 + 1.;
p.push_back((2.0*g - 1.0)/(g*g));
p[iMax-1] = Function(p[3], p);
G4double val = IntSpectrum(x1, x2, p);
G4double x0 = (lowestE + bindingEnergy)/(e + bindingEnergy);
G4double x0 = (lowestE + bindingEnergy)/energy;
G4double nor = IntSpectrum(x0, 0.5, p);
if(verbose > 1) {
@@ -131,7 +143,7 @@ G4double G4eIonisationSpectrum::Probability(G4int Z,
if(nor > 0.0) val /= nor;
else val = 0.0;
if(val < 0.0) val = 0.0;
// if(val < 0.0) val = 0.0;
return val;
}
@@ -156,8 +168,12 @@ G4double G4eIonisationSpectrum::AverageEnergy(G4int Z,
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(e <= bindingEnergy) return 0.0;
G4double energy = e + bindingEnergy;
G4double x1 = G4std::min(0.5,(t0 + bindingEnergy)/energy);
G4double x2 = G4std::min(0.5,(tm + bindingEnergy)/energy);
if(verbose > 1) {
G4cout << "G4eIonisationSpectrum::AverageEnergy: Z= " << Z
@@ -169,22 +185,27 @@ G4double G4eIonisationSpectrum::AverageEnergy(G4int Z,
<< 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 x = theParam->Parameter(Z, shell, i, e);
if(i<4) x /= energy;
p.push_back(x);
}
G4double g = (e + bindingEnergy)/electron_mass_c2 + 1.;
if(p[3] > 0.5) p[3] = 0.5;
G4double g = energy/electron_mass_c2 + 1.;
p.push_back((2.0*g - 1.0)/(g*g));
p[iMax-1] = Function(p[3], p);
G4double val = AverageValue(x1, x2, p);
G4double x0 = (lowestE + bindingEnergy)/(e + bindingEnergy);
G4double x0 = (lowestE + bindingEnergy)/energy;
G4double nor = IntSpectrum(x0, 0.5, p);
val *= (e + bindingEnergy);
val *= energy;
if(verbose > 1) {
G4cout << "tcut(MeV)= " << tMin/MeV
@@ -205,7 +226,7 @@ G4double G4eIonisationSpectrum::AverageEnergy(G4int Z,
if(nor > 0.0) val /= nor;
else val = 0.0;
if(val < 0.0) val = 0.0;
// if(val < 0.0) val = 0.0;
return val;
}
@@ -227,8 +248,12 @@ G4double G4eIonisationSpectrum::SampleEnergy(G4int Z,
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(e <= bindingEnergy) return 0.0;
G4double energy = e + bindingEnergy;
G4double x1 = G4std::min(0.5,(t0 + bindingEnergy)/energy);
G4double x2 = G4std::min(0.5,(tm + bindingEnergy)/energy);
if(x1 >= x2) return tDelta;
if(verbose > 1) {
@@ -239,68 +264,112 @@ G4double G4eIonisationSpectrum::SampleEnergy(G4int Z,
}
// 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 x = theParam->Parameter(Z, shell, i, e);
if(i<4) x /= energy;
p.push_back(x);
}
G4double g = (e + bindingEnergy)/electron_mass_c2 + 1.;
if(p[3] > 0.5) p[3] = 0.5;
G4double g = energy/electron_mass_c2 + 1.;
p.push_back((2.0*g - 1.0)/(g*g));
p[iMax-1] = Function(p[3], p);
G4double aria1 = 0.0;
G4double a1 = G4std::min(x1,p[6]);
G4double a2 = G4std::min(x2,p[6]);
G4double a1 = G4std::max(x1,p[1]);
G4double a2 = G4std::min(x2,p[3]);
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]);
G4double a3 = G4std::max(x1,p[3]);
G4double a4 = x2;
if(a3 < a4) aria2 = IntSpectrum(a3, a4, p);
G4double aria = (aria1 + aria2)*G4UniformRand();
G4double amaj, fun, q, x;
G4double amaj, fun, q, x, z1, z2, dx, dx1;
//======= First aria to sample =====
if(aria <= aria1) {
amaj = p[4];
for (size_t j=5; j<24; j++) {
if(p[j] > amaj) amaj = p[j];
}
a1 = 1./a1;
a2 = 1./a2;
size_t i;
do {
x = 1./(a2 + G4UniformRand()*(a1 - a2));
z1 = p[1];
z2 = p[3];
dx = (p[2] - p[1]) / 3.0;
dx1= exp(log(p[3]/p[2]) / 16.0);
for (i=5; i<23; i++) {
if (i <= 8) {
z2 = z1 + dx;
} else if(22 == i) {
z2 = p[3];
break;
} else {
z2 = z1*dx1;
}
if(x <= z2) break;
z1 = z2;
}
fun = p[i] + (x - z1) * (p[i+1] - p[i])/(z2 - z1);
if(fun > amaj) {
G4cout << "WARNING in G4eIonisationSpectrum::SampleEnergy:"
<< " Majoranta " << amaj
<< " < " << fun
<< " in the first aria at x= " << x
<< G4endl;
}
q = amaj*G4UniformRand();
} while (q >= fun);
//======= Second aria to sample =====
} else {
amaj = p[5];
amaj = G4std::max(p[iMax-1], Function(0.5, p)) * factor;
a1 = 1./a3;
a2 = 1./a4;
}
amaj *= 1.25;
do {
do {
x = 1./(a2 + G4UniformRand()*(a1 - a2));
fun = Function(x, p);
x = 1./(a2 + G4UniformRand()*(a1 - a2));
fun = Function(x, p);
if(fun > amaj) {
if(fun > amaj) {
G4cout << "WARNING in G4eIonisationSpectrum::SampleEnergy:"
<< " Majoranta " << amaj
<< " < " << fun
<< " in the second aria at x= " << x
<< G4endl;
}
}
q = amaj*G4UniformRand();
q = amaj*G4UniformRand();
} while (q >= fun);
} while (q >= fun);
}
p.clear();
tDelta = x*(e + bindingEnergy) - bindingEnergy;
tDelta = x*energy - bindingEnergy;
if(verbose > 1) {
G4cout << "tcut(MeV)= " << tMin/MeV
@@ -326,15 +395,75 @@ G4double G4eIonisationSpectrum::IntSpectrum(G4double xMin,
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);
G4double sum = 0.0;
if(xMin >= xMax) return sum;
if(x < 0.0) x = 0.0;
return x;
G4double x1, x2, xs1, xs2, y1, y2, ys1, ys2;
// Integral over interpolation aria
if(xMin < p[3]) {
x1 = p[1];
y1 = p[4];
G4double dx = (p[2] - p[1]) / 3.0;
G4double dx1= exp(log(p[3]/p[2]) / 16.0);
for (size_t i=0; i<19; i++) {
if (i <= 3) {
x2 = x1 + dx;
} else {
x2 = x1*dx1;
}
y2 = p[5 + i];
if (xMin >= x2 || xMax <= x1) {
continue;
} else {
xs1 = x1;
xs2 = x2;
ys1 = y1;
ys2 = y2;
if (xMin > x1) {
xs1 = xMin;
ys1 += (xs1 - x1)*(y2 - y1)/(x2 - x1);
}
if (xMax < x2) {
xs2 = xMax;
ys2 += (xs2 - x2)*(y1 - y2)/(x1 - x2);
}
if (xs2 > xs1) {
sum += (ys1*xs2 - ys2*xs1)/(xs1*xs2)
+ log(xs2/xs1)*(ys2 - ys1)/(xs2 - xs1);
}
}
x1 = x2;
y1 = y2;
}
}
// Integral over aria with parametrised formula
x1 = G4std::max(xMin, p[3]);
if(x1 >= xMax) return sum;
x2 = xMax;
xs1 = 1./x1;
xs2 = 1./x2;
sum += (xs1 - xs2)*(1.0 - p[0])
- p[iMax]*log(x2/x1)
+ (1. - p[iMax])*(x2 - x1)
+ 1./(1. - x2) - 1./(1. - x1)
+ p[iMax]*log((1. - x2)/(1. - x1))
+ 0.25*p[0]*(xs1*xs1 - xs2*xs2);
// if(sum < 0.0) sum = 0.0;
return sum;
}
@@ -342,40 +471,78 @@ G4double G4eIonisationSpectrum::AverageValue(G4double xMin,
G4double xMax,
const G4DataVector& p) const
{
G4double sum = 0.0;
if(xMin >= xMax) return sum;
// 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);
G4double x1, x2, xs1, xs2, y1, y2, ys1, ys2;
if(x < 0.0) x = 0.0;
return x;
// Integral over interpolation aria
if(xMin < p[3]) {
x1 = p[1];
y1 = p[4];
G4double dx = (p[2] - p[1]) / 3.0;
G4double dx1= exp(log(p[3]/p[2]) / 16.0);
for (size_t i=0; i<19; i++) {
if (i <= 3) {
x2 = x1 + dx;
} else {
x2 = x1*dx1;
}
y2 = p[5 + i];
if (xMin >= x2 || xMax <= x1) {
continue;
} else {
xs1 = x1;
xs2 = x2;
ys1 = y1;
ys2 = y2;
if (xMin > x1) {
xs1 = xMin;
ys1 += (xs1 - x1)*(y2 - y1)/(x2 - x1);
}
if (xMax < x2) {
xs2 = xMax;
ys2 += (xs2 - x2)*(y1 - y2)/(x1 - x2);
}
if (xs2 > xs1) {
sum += log(xs2/xs1)*(ys1*xs2 - ys2*xs1)/(xs2 - xs1)
+ ys2 - ys1;
}
}
x1 = x2;
y1 = y2;
}
}
// Integral over aria with parametrised formula
x1 = G4std::max(xMin, p[3]);
if(x1 >= xMax) return sum;
x2 = xMax;
xs1 = 1./x1;
xs2 = 1./x2;
sum += log(x2/x1)*(1.0 - p[0])
+ 0.5*(1. - p[iMax])*(x2*x2 - x1*x1)
+ 1./(1. - x2) - 1./(1. - x1)
+ (1. + p[iMax])*log((1. - x2)/(1. - x1))
+ 0.5*p[0]*(xs1 - xs2);
// if(sum < 0.0) sum = 0.0;
return sum;
}
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.23 2001/11/23 11:45:29 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4eLowEnergyLoss.cc,v 1.28 2002/06/03 00:07:18 pia Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// -----------------------------------------------------------
// GEANT 4 class implementation file
@@ -54,6 +54,8 @@
// 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
// 28/05/02 VI Remove flag fStopAndKill
// 03/06/02 MGP - Restore fStopAndKill
//
// --------------------------------------------------------------
@@ -125,7 +127,8 @@ G4eLowEnergyLoss::G4eLowEnergyLoss(const G4String& processName)
RecorderOfProcess(0),
fdEdx(0),
fRangeNow(0),
linLossLimit(0.05)
linLossLimit(0.05),
theFluo(false)
{
//create (only once) EnergyLoss messenger
@@ -438,8 +441,7 @@ G4VParticleChange* G4eLowEnergyLoss::AlongStepDoIt( const G4Track& trackData,
if (finalT <= 0. )
{
finalT = 0.;
if (Charge < 0.) aParticleChange.SetStatusChange(fStopAndKill);
else aParticleChange.SetStatusChange(fStopButAlive);
aParticleChange.SetStatusChange(fStopAndKill);
}
G4double edep = E - finalT;
@@ -447,11 +449,11 @@ G4VParticleChange* G4eLowEnergyLoss::AlongStepDoIt( const G4Track& trackData,
aParticleChange.SetEnergyChange(finalT);
// Deexcitation of ionised atoms
G4std::vector<G4DynamicParticle*>* deexcitationProducts =
DeexciteAtom(aMaterial,E,edep);
G4std::vector<G4DynamicParticle*>* deexcitationProducts = 0;
if (theFluo) deexcitationProducts = DeexciteAtom(aMaterial,E,edep);
size_t nSecondaries = deexcitationProducts->size();
size_t nSecondaries = 0;
if (deexcitationProducts != 0) nSecondaries = deexcitationProducts->size();
aParticleChange.SetNumberOfSecondaries(nSecondaries);
if (nSecondaries > 0) {
@@ -69,6 +69,18 @@
// 18 Oct. 2001 V.Ivanchenko Add fluorescence
// 30 Oct. 2001 V.Ivanchenko Add minGammaEnergy and minElectronEnergy
// 07 Dec 2001 V.Ivanchenko Add SetFluorescence method
// 15 Feb 2002 V.Ivanchenko Fix problem of Generic Ions
// 25 Mar 2002 V.Ivanchenko Fix problem of fluorescence below threshold
// 28 Mar 2002 V.Ivanchenko Set fluorescence off by default
// 09 Apr 2002 V.Ivanchenko Fix table problem of GenericIons
// 28 May 2002 V.Ivanchenko Remove flag fStopAndKill
// 31 May 2002 V.Ivanchenko Add path of Fluo + Auger cuts to
// AtomicDeexcitation
// 03 Jun 2002 MGP Restore fStopAndKill
// 10 Jun 2002 V.Ivanchenko Restore fStopButAlive
// 12 Jun 2002 V.Ivanchenko Fix in fluctuations - if tmax<2*Ipot Gaussian
// fluctuations enables
// -----------------------------------------------------------------------
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -85,6 +97,7 @@
#include "G4DynamicParticle.hh"
#include "G4ParticleDefinition.hh"
#include "G4AtomicDeexcitation.hh"
#include "G4AtomicTransitionManager.hh"
#include "G4ShellVacancy.hh"
#include "G4hShellCrossSection.hh"
#include "G4VEMDataSet.hh"
@@ -93,6 +106,7 @@
#include "G4Gamma.hh"
#include "G4LogLogInterpolation.hh"
#include "G4SemiLogInterpolation.hh"
#include "G4ProcessManager.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -114,7 +128,7 @@ G4hLowEnergyIonisation::G4hLowEnergyIonisation(const G4String& processName)
paramStepLimit (0.005),
shellVacancy(0),
shellCS(0),
theFluo(true)
theFluo(false)
{
InitializeMe();
}
@@ -221,21 +235,54 @@ void G4hLowEnergyIonisation::BuildPhysicsTable(
{
if(verboseLevel > 0) {
G4cout << "G4hLowEnergyIonisation::BuildPhysicsTable for "
<< aParticleType.GetParticleName() << G4endl;
<< aParticleType.GetParticleName()
<< " mass(MeV)= " << aParticleType.GetPDGMass()/MeV
<< " charge= " << aParticleType.GetPDGCharge()/eplus
<< " type= " << aParticleType.GetParticleType()
<< G4endl;
if(verboseLevel > 1) {
G4ProcessVector* pv = aParticleType.GetProcessManager()->GetProcessList();
G4cout << " 0: " << (*pv)[0]->GetProcessName() << " " << (*pv)[0]
<< " 1: " << (*pv)[1]->GetProcessName() << " " << (*pv)[1]
// << " 2: " << (*pv)[2]->GetProcessName() << " " << (*pv)[2]
<< G4endl;
G4cout << "ionModel= " << theIonEffChargeModel
<< " MFPtable= " << theMeanFreePathTable
<< " iniMass= " << initialMass
<< G4endl;
}
}
if(aParticleType.GetParticleType() == "nucleus" &&
aParticleType.GetParticleName() != "GenericIon" &&
theMeanFreePathTable) {
G4EnergyLossTables::Register(&aParticleType,
theDEDXpTable,
theRangepTable,
theInverseRangepTable,
theLabTimepTable,
theProperTimepTable,
LowestKineticEnergy, HighestKineticEnergy,
proton_mass_c2/aParticleType.GetPDGMass(),
TotBin);
return;
}
InitializeParametrisation() ;
G4Proton* theProton = G4Proton::Proton();
G4AntiProton* theAntiProton = G4AntiProton::AntiProton();
charge = aParticleType.GetPDGCharge()/eplus ;
charge = aParticleType.GetPDGCharge()/eplus;
chargeSquare = charge*charge ;
// ---- MGP ---- workaround for the deprecated "cuts per material"
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
const G4Material* material = (*theMaterialTable)[0];
G4double electronCutInRange = G4Electron::Electron()->GetEnergyThreshold(material);
G4double electronCutInRange = G4Electron::Electron()->GetRangeThreshold(material);
// was = G4Electron::Electron()->GetCuts();
// ---- MGP ----
@@ -324,7 +371,7 @@ void G4hLowEnergyIonisation::BuildLossTable(
const G4ParticleDefinition& aParticleType)
{
// Inicialisation
// Initialisation
G4double lowEdgeEnergy , ionloss, ionlossBB, paramB ;
G4double lowEnergy, highEnergy;
G4Proton* theProton = G4Proton::Proton();
@@ -376,10 +423,13 @@ void G4hLowEnergyIonisation::BuildLossTable(
ionlossBB = theBetheBlochModel->TheValue(&aParticleType,material,highE) ;
ionlossBB -= DeltaRaysEnergy(material,highE,proton_mass_c2) ;
/*
if(theBarkas) {
ionlossBB += BarkasTerm(material,highE)*charge ;
ionlossBB += BlochTerm(material,highE,1.0) ;
}
*/
paramB = ionloss/ionlossBB - 1.0 ;
// now comes the loop for the kinetic energy values
@@ -403,10 +453,12 @@ void G4hLowEnergyIonisation::BuildLossTable(
ionloss -= DeltaRaysEnergy(material,lowEdgeEnergy,proton_mass_c2) ;
/*
if(theBarkas) {
ionloss += BarkasTerm(material,lowEdgeEnergy)*charge ;
ionloss += BlochTerm(material,lowEdgeEnergy,1.0) ;
}
*/
ionloss *= (1.0 + paramB*highEnergy/lowEdgeEnergy) ;
}
@@ -461,7 +513,7 @@ void G4hLowEnergyIonisation::BuildDataForFluorescence(
G4PhysicsLogVector* bVector = new G4PhysicsLogVector(LowestKineticEnergy,
HighestKineticEnergy,
binForFluo);
G4AtomicTransitionManager* transitionManager =
const G4AtomicTransitionManager* transitionManager =
G4AtomicTransitionManager::Instance();
G4double bindingEnergy;
@@ -489,34 +541,41 @@ void G4hLowEnergyIonisation::BuildDataForFluorescence(
for (size_t iel=0; iel<NumberOfElements; iel++ ) {
G4int Z = (G4int)((*theElementVector)[iel]->GetZ());
G4int nShells = transitionManager->NumberOfShells(Z);
energy = new G4DataVector();
ksi = new G4DataVector();
energy1= new G4DataVector();
ksi1 = new G4DataVector();
//if(NumberOfElements > 1)
elDensity = theAtomicNumDensityVector[iel];
elDensity = theAtomicNumDensityVector[iel]/((G4double)nShells);
for (size_t j = 0; j<binForFluo; j++) {
G4double tkin = bVector->GetLowEdgeEnergy(j);
G4double gamma = tkin/mass + 1.;
G4double beta2 = 1.0 - 1.0/(gamma*gamma);
G4double r = electron_mass_c2/mass;
G4double tmax = 2.*mass*r*(gamma*gamma - 1.)/(1. + 2.*gamma*r + r*r);
G4double tmax = 2.*electron_mass_c2*(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);
G4double rel;
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));
if (tmin > bindingEnergy) {
rel = log(tmin/bindingEnergy);
eAverage += rel - beta2*(tmin - bindingEnergy)/tmax;
cross += 1.0/bindingEnergy - 1.0/tmin - beta2*rel/tmax;
}
if (tmax > tmin) {
cross1 += 1.0/tmin - 1.0/tmax - beta2*log(tmax/tmin)/tmax;
}
}
cross1 *= elDensity;
energy1->push_back(tkin);
ksi1->push_back(cross1);
@@ -566,6 +625,7 @@ void G4hLowEnergyIonisation::BuildLambdaTable(
const G4MaterialTable* theMaterialTable = G4Material::GetMaterialTable();
charge = aParticleType.GetPDGCharge()/eplus ;
chargeSquare = charge*charge ;
initialMass = aParticleType.GetPDGMass();
//create table
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
@@ -604,13 +664,9 @@ void G4hLowEnergyIonisation::BuildLambdaTable(
for ( G4int i = 0 ; i < TotBin ; i++ ) {
lowEdgeEnergy = aVector->GetLowEdgeEnergy(i) ;
chargeSquare = theIonEffChargeModel->
TheValue(&aParticleType,material,lowEdgeEnergy) ;
G4double sigma = 0.0 ;
for (G4int iel=0; iel<NumberOfElements; iel++ ) {
sigma += theAtomicNumDensityVector[iel]*
chargeSquare*
ComputeMicroscopicCrossSection(
aParticleType,
lowEdgeEnergy,
@@ -646,10 +702,10 @@ G4double G4hLowEnergyIonisation::ComputeMicroscopicCrossSection(
// calculates the microscopic cross section in GEANT4 internal units
// ( it is called for elements , AtomicNumber = z )
G4double energy, beta2, tmax, var ;
G4double energy, gamma, beta2, tmax, var;
G4double totalCrossSection = 0.0 ;
G4double particleMass = aParticleType.GetPDGMass() ;
G4double particleMass = initialMass;
// get particle data ...................................
@@ -657,10 +713,10 @@ G4double G4hLowEnergyIonisation::ComputeMicroscopicCrossSection(
// some kinematics......................
beta2 = kineticEnergy*(energy+particleMass) / (energy*energy);
var = particleMass+electron_mass_c2;
tmax = 2.0*electron_mass_c2*kineticEnergy * (energy+particleMass)
/ (var*var + 2.0*electron_mass_c2*kineticEnergy) ;
gamma = energy/particleMass;
beta2 = 1.0 - 1.0/(gamma*gamma);
var = electron_mass_c2/particleMass;
tmax = 2.*electron_mass_c2*(gamma*gamma - 1.)/(1. + 2.*gamma*var + var*var);
// now you can calculate the total cross section
@@ -699,15 +755,17 @@ G4double G4hLowEnergyIonisation::GetMeanFreePath(const G4Track& trackData,
*condition = NotForced ;
G4double kineticEnergy = aParticle->GetKineticEnergy() ;
G4double kineticEnergy = (aParticle->GetKineticEnergy())*initialMass/(aParticle->GetMass());
charge = aParticle->GetCharge();
chargeSquare = theIonEffChargeModel->TheValue(aParticle, aMaterial);
if(kineticEnergy < LowestKineticEnergy) meanFreePath = DBL_MAX;
else {
if(kineticEnergy > HighestKineticEnergy)
kineticEnergy = HighestKineticEnergy ;
meanFreePath = ((*theMeanFreePathTable)(aMaterial->GetIndex()))->
GetValue(kineticEnergy,isOutRange) ;
kineticEnergy = HighestKineticEnergy;
meanFreePath = (((*theMeanFreePathTable)(aMaterial->GetIndex()))->
GetValue(kineticEnergy,isOutRange))/chargeSquare;
}
return meanFreePath ;
@@ -731,48 +789,25 @@ G4double G4hLowEnergyIonisation::GetConstraints(
G4double massRatio = proton_mass_c2/(particle->GetMass()) ;
G4double kineticEnergy = particle->GetKineticEnergy() ;
charge = (particle->GetCharge())/eplus ;
// Scale the kinetic energy
G4double tscaled = kineticEnergy*massRatio ;
chargeSquare = theIonEffChargeModel->TheValue(particle,material) ;
if(charge > 0.0) {
highEnergy = protonHighEnergy ;
//Very low energy dE/dx assumed to be according to Free Electron Gas Model
if(tscaled < MinKineticEnergy) {
fdEdx = 0.5 * ProtonParametrisedDEDX(material, MinKineticEnergy)
* sqrt(tscaled/MinKineticEnergy) ;
fRangeNow = tscaled/fdEdx ;
fdEdx *= chargeSquare ;
dx = fRangeNow/paramStepLimit ;
fRangeNow = G4EnergyLossTables::GetRange(theProton, tscaled, material);
dx = G4EnergyLossTables::GetRange(theProton, highEnergy, material);
fdEdx = G4EnergyLossTables::GetDEDX(theProton, tscaled, material)
* chargeSquare ;
// Normal energy
} else {
fRangeNow = G4EnergyLossTables::GetRange(theProton, tscaled, material) ;
dx = G4EnergyLossTables::GetRange(theProton, highEnergy, material) ;
if(tscaled > highEnergy) {
fdEdx = G4EnergyLossTables::GetDEDX(theProton, tscaled, material)
* chargeSquare ;
if(tscaled > highEnergy) {
// Correction for positive ions
if(theBarkas && 1.0 < charge) {
G4double loss = BarkasTerm(material,tscaled)*(charge -1.0)
* chargeSquare ;
loss += BlochTerm(material,tscaled,chargeSquare) ;
loss -= BlochTerm(material,tscaled,1.0) ;
fdEdx += loss ;
}
// Parametrisation - recalculate dE/dx
} else {
fdEdx = ProtonParametrisedDEDX(material, tscaled) * chargeSquare ;
if(theBarkas) {
fdEdx += BarkasTerm(material,tscaled)*sqrt(chargeSquare)*chargeSquare;
fdEdx += BlochTerm(material,tscaled,chargeSquare);
}
}
@@ -780,29 +815,17 @@ G4double G4hLowEnergyIonisation::GetConstraints(
} else {
highEnergy = antiProtonHighEnergy ;
fRangeNow = G4EnergyLossTables::GetRange(theAntiProton, tscaled, material);
dx = G4EnergyLossTables::GetRange(theAntiProton, highEnergy, material);
fdEdx = G4EnergyLossTables::GetDEDX(theAntiProton, tscaled, material)
* chargeSquare ;
//Very low energy dE/dx assumed to be constant
if(tscaled < MinKineticEnergy) {
fdEdx = AntiProtonParametrisedDEDX(material, MinKineticEnergy)
* sqrt(tscaled/MinKineticEnergy) ;
fRangeNow = tscaled/fdEdx ;
fdEdx *= chargeSquare ;
dx = fRangeNow/paramStepLimit ;
if(tscaled > highEnergy) {
// Normal energy
} else {
fRangeNow = G4EnergyLossTables::GetRange(theAntiProton, tscaled,
material);
dx = G4EnergyLossTables::GetRange(theAntiProton, highEnergy, material);
if(tscaled > highEnergy) {
fdEdx = G4EnergyLossTables::GetDEDX(theAntiProton, tscaled, material)
* chargeSquare ;
// For Bragg's peak dE/dx is recalculated
} else {
fdEdx = AntiProtonParametrisedDEDX(material, tscaled) * chargeSquare;
// Correction for positive ions
if(theBarkas) {
fdEdx -= BarkasTerm(material,tscaled)*sqrt(chargeSquare)*chargeSquare;
fdEdx += BlochTerm(material,tscaled,chargeSquare);
}
}
}
@@ -868,46 +891,6 @@ G4VParticleChange* G4hLowEnergyIonisation::AlongStepDoIt(
} else if( kineticEnergy > HighestKineticEnergy) {
eloss = step*fdEdx ;
// proton parametrisation model
} else if(tscaled < protonHighEnergy && charge > 0.0) {
if(nStopping) nloss =
(theNuclearStoppingModel->TheValue(particle, material))*step ;
G4double eFinal = kineticEnergy - step*fdEdx - nloss ;
if(0.0 < eFinal) {
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 ;
}
// antiproton parametrisation model
} else if(tscaled < antiProtonHighEnergy && charge < 0.0) {
if(nStopping) nloss =
(theNuclearStoppingModel->TheValue(particle, material))*step ;
G4double eFinal = kineticEnergy - step*fdEdx - nloss ;
if(0.0 < eFinal) {
eloss = (fdEdx +
AntiProtonParametrisedDEDX(material,eFinal*massRatio)*chargeSquare)
* step * 0.5 ;
} else {
eloss = kineticEnergy - nloss ;
}
// big step
} else if(step >= fRangeNow ) {
eloss = kineticEnergy ;
@@ -939,13 +922,23 @@ G4VParticleChange* G4hLowEnergyIonisation::AlongStepDoIt(
} else {
eloss = step*fdEdx ;
}
// Correction for positive ions
if(theBarkas && 1.0 < charge) {
G4double ts = tscaled - eloss*0.5*massRatio;
if(ts < protonHighEnergy) ts = protonHighEnergy;
eloss += BarkasTerm(material,ts)*charge*chargeSquare*step;
eloss += BlochTerm(material,ts,chargeSquare)*step;
}
if(nStopping && tscaled < protonHighEnergy) {
nloss = (theNuclearStoppingModel->TheValue(particle, material))*step;
}
}
if(eloss < 0.0) eloss = 0.0;
finalT = kineticEnergy - eloss - nloss;
if( EnlossFlucFlag && 0.0 < eloss ) {
if( EnlossFlucFlag && 0.0 < eloss && finalT > MinKineticEnergy) {
// now the electron loss with fluctuation
eloss = ElectronicLossFluctuation(particle, material, eloss, step) ;
@@ -957,10 +950,11 @@ G4VParticleChange* G4hLowEnergyIonisation::AlongStepDoIt(
if (finalT <= MinKineticEnergy ) {
finalT = 0.0;
if( "proton" == (particle->GetDefinition()->GetParticleName()) )
aParticleChange.SetStatusChange(fStopAndKill);
else
aParticleChange.SetStatusChange(fStopButAlive);
if(!particle->GetDefinition()->GetProcessManager()->
GetAtRestProcessVector()->size())
aParticleChange.SetStatusChange(fStopAndKill);
else
aParticleChange.SetStatusChange(fStopButAlive);
}
aParticleChange.SetEnergyChange( finalT );
@@ -1171,7 +1165,7 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
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);
G4double tmax = 2.*electron_mass_c2*(gamma*gamma - 1.)/(1. + 2.*gamma*r + r*r);
// Validity range for delta electron cross section
G4double DeltaCut = cutForDelta[aMaterial->GetIndex()];
@@ -1248,49 +1242,52 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
// Select atom and shell
G4int Z = SelectRandomAtom(aMaterial, KineticEnergy);
G4int shell = shellCS->SelectRandomShell(Z, KineticEnergy,
ParticleMass,DeltaKineticEnergy);
const G4AtomicShell* atomicShell =
if(theFluo && Z > 5) {
G4int shell = shellCS->SelectRandomShell(Z, KineticEnergy,
ParticleMass,DeltaKineticEnergy);
const G4AtomicShell* atomicShell =
(G4AtomicTransitionManager::Instance())->Shell(Z, shell);
G4double bindingEnergy = atomicShell->BindingEnergy();
G4double bindingEnergy = atomicShell->BindingEnergy();
if(verboseLevel > 1) {
G4cout << "PostStep Z= " << Z << " shell= " << shell
<< " bindingE(keV)= " << bindingEnergy/keV
<< " finalE(keV)= " << finalKineticEnergy/keV
<< G4endl;
}
if(verboseLevel > 1) {
G4cout << "PostStep Z= " << Z << " shell= " << shell
<< " bindingE(keV)= " << bindingEnergy/keV
<< " finalE(keV)= " << finalKineticEnergy/keV
<< G4endl;
}
// Fluorescence data start from element 6
// Fluorescence data start from element 6
if (theFluo && Z > 5 && finalKineticEnergy >= bindingEnergy
&& (bindingEnergy >= minGammaEnergy
|| bindingEnergy >= minElectronEnergy) ) {
if (finalKineticEnergy >= bindingEnergy
&& (bindingEnergy >= minGammaEnergy
|| bindingEnergy >= minElectronEnergy) ) {
G4int shellId = atomicShell->ShellId();
secondaryVector = deexcitationManager.GenerateParticles(Z, shellId);
G4int shellId = atomicShell->ShellId();
secondaryVector = deexcitationManager.GenerateParticles(Z, shellId);
if (secondaryVector != 0) {
if (secondaryVector != 0) {
nSecondaries = secondaryVector->size();
for (size_t i = 0; i<nSecondaries; i++) {
nSecondaries = secondaryVector->size();
for (size_t i = 0; i<nSecondaries; i++) {
aSecondary = (*secondaryVector)[i];
if (aSecondary) {
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 ))) {
G4double e = aSecondary->GetKineticEnergy();
type = aSecondary->GetDefinition();
if (e < finalKineticEnergy &&
((type == G4Gamma::Gamma() && e > minGammaEnergy ) ||
(type == G4Electron::Electron() && e > minElectronEnergy ))) {
finalKineticEnergy -= e;
totalNumber++;
finalKineticEnergy -= e;
totalNumber++;
} else {
} else {
delete aSecondary;
(*secondaryVector)[i] = 0;
delete aSecondary;
(*secondaryVector)[i] = 0;
}
}
}
}
@@ -1323,9 +1320,11 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
finalKineticEnergy = 0.;
aParticleChange.SetMomentumChange(ParticleDirection.x(),
ParticleDirection.y(),ParticleDirection.z());
if (aParticle->GetDefinition()->GetParticleName() == "proton")
aParticleChange.SetStatusChange(fStopAndKill);
else aParticleChange.SetStatusChange(fStopButAlive);
if(!aParticle->GetDefinition()->GetProcessManager()->
GetAtRestProcessVector()->size())
aParticleChange.SetStatusChange(fStopAndKill);
else
aParticleChange.SetStatusChange(fStopButAlive);
}
aParticleChange.SetEnergyChange( finalKineticEnergy );
@@ -1340,7 +1339,9 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
for (size_t l = 0; l < nSecondaries; l++) {
aSecondary = (*secondaryVector)[l];
if(aSecondary) aParticleChange.AddSecondary(aSecondary);
if(aSecondary) {
aParticleChange.AddSecondary(aSecondary);
}
}
delete secondaryVector;
}
@@ -1352,9 +1353,9 @@ G4VParticleChange* G4hLowEnergyIonisation::PostStepDoIt(
G4std::vector<G4DynamicParticle*>*
G4hLowEnergyIonisation::DeexciteAtom(const G4Material* material,
G4double incidentEnergy,
G4double hMass,
G4double eLoss)
G4double incidentEnergy,
G4double hMass,
G4double eLoss)
{
if (verboseLevel > 1) {
@@ -1366,11 +1367,14 @@ G4hLowEnergyIonisation::DeexciteAtom(const G4Material* material,
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 =
G4int index = material->GetIndex();
// G4double eexc = material->GetIonisation()->GetMeanExcitationEnergy();
G4double gamma = incidentEnergy/hMass + 1;
G4double beta2 = 1.0 - 1.0/(gamma*gamma);
G4double r = electron_mass_c2/hMass;
G4double tmax = 2.*electron_mass_c2*(gamma*gamma - 1.)/(1. + 2.*gamma*r + r*r);
G4double tcut = G4std::min(tmax,cutForDelta[index]);
const G4AtomicTransitionManager* transitionManager =
G4AtomicTransitionManager::Instance();
size_t nElements = material->GetNumberOfElements();
@@ -1382,7 +1386,7 @@ G4hLowEnergyIonisation::DeexciteAtom(const G4Material* material,
G4int Z = (G4int)((*theElementVector)[j]->GetZ());
G4double maxE = transitionManager->Shell(Z, 0)->BindingEnergy();
if (Z>5 && (maxE>minGammaEnergy || maxE>minElectronEnergy) ) {
if (Z > 5 && maxE < tcut && (maxE > minGammaEnergy || maxE > minElectronEnergy) ) {
stop = false;
break;
}
@@ -1397,7 +1401,7 @@ G4hLowEnergyIonisation::DeexciteAtom(const G4Material* material,
G4std::vector<G4DynamicParticle*>* secVector = 0;
G4DynamicParticle* aSecondary = 0;
G4ParticleDefinition* type = 0;
G4double e;
G4double e, tkin, grej;
G4ThreeVector position;
G4int shell, shellId;
@@ -1413,10 +1417,18 @@ G4hLowEnergyIonisation::DeexciteAtom(const G4Material* material,
G4int Z = (G4int)((*theElementVector)[i]->GetZ());
G4double maxE = transitionManager->Shell(Z, 0)->BindingEnergy();
if (nVacancies && Z>5 && (maxE>minGammaEnergy || maxE>minElectronEnergy)) {
if (nVacancies && Z > 5 && maxE < tcut && (maxE > minGammaEnergy || maxE > minElectronEnergy)) {
for(size_t j=0; j<nVacancies; j++) {
shell = shellCS->SelectRandomShell(Z,incidentEnergy,hMass,deltaEnergy);
// sampling follows
do {
tkin = tcut/(1.0 + (tcut/maxE - 1.0)*G4UniformRand());
grej = 1.0 - beta2 * tkin/tmax;
} while( G4UniformRand() > grej );
shell = shellCS->SelectRandomShell(Z,incidentEnergy,hMass,tkin);
shellId = transitionManager->Shell(Z, shell)->ShellId();
G4double maxE = transitionManager->Shell(Z, shell)->BindingEnergy();
@@ -1464,7 +1476,7 @@ G4hLowEnergyIonisation::DeexciteAtom(const G4Material* material,
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4int G4hLowEnergyIonisation::SelectRandomAtom(const G4Material* material,
G4double kineticEnergy) const
G4double kineticEnergy) const
{
G4int nElements = material->GetNumberOfElements();
G4int Z = 0;
@@ -1488,6 +1500,8 @@ G4int G4hLowEnergyIonisation::SelectRandomAtom(const G4Material* material,
norm += cross;
}
if(norm == 0.0) return 0;
G4double q = norm*G4UniformRand();
for (G4int i=0; i<nElements; i++) {
@@ -1727,13 +1741,12 @@ G4double G4hLowEnergyIonisation::ElectronicLossFluctuation(
G4double tau2 = tau*(tau+2.);
G4double tmax = 2.*electron_mass_c2*tau2/(1.+2.*tau1*rmass+rmass*rmass);
if (tmax <= ipotFluct) tmax = ipotFluct ;
if(tmax > threshold) tmax = threshold;
G4double beta2 = tau2/(tau1*tau1);
// Gaussian fluctuation
if(meanLoss > kappa*tmax)
if(meanLoss > kappa*tmax || tmax < kappa*ipotFluct )
{
siga = tmax * (1.0-0.5*beta2) * step * twopi_mc2_rcl2
* electronDensity / beta2 ;
@@ -1749,14 +1762,14 @@ G4double G4hLowEnergyIonisation::ElectronicLossFluctuation(
G4double yang = theIonYangFluctuationModel->TheValue(particle, material);
siga = sqrt( siga * (chargeSquare * chu + yang)) ;
}
loss = G4RandGauss::shoot(meanLoss,siga) ;
if(loss < 0.) loss = 0. ;
return loss ;
do {
loss = G4RandGauss::shoot(meanLoss,siga);
} while (loss < 0. || loss > 2.0*meanLoss);
return loss;
}
// Non Gaussian fluctuation
G4double mLoss = meanLoss/chargeSquare;
static const G4double probLim = 0.01 ;
static const G4double sumaLim = -log(probLim) ;
static const G4double alim = 10.;
@@ -1780,22 +1793,19 @@ G4double G4hLowEnergyIonisation::ElectronicLossFluctuation(
w1 = tmax/ipotFluct;
w2 = log(2.*electron_mass_c2*tau2);
C = mLoss*(1.-rateFluct)/(w2-ipotLogFluct-beta2);
C = meanLoss*(1.-rateFluct)/(w2-ipotLogFluct-beta2);
a1 = C*f1Fluct*(w2-e1LogFluct-beta2)/e1Fluct;
a2 = C*f2Fluct*(w2-e2LogFluct-beta2)/e2Fluct;
if(tmax > ipotFluct)
a3 = rateFluct*mLoss*(tmax-ipotFluct)/(ipotFluct*tmax*log(w1));
else
{
a1 /= 1.-rateFluct ;
a2 /= 1.-rateFluct ;
a3 = 0. ;
}
a3 = rateFluct*meanLoss*(tmax-ipotFluct)/(ipotFluct*tmax*log(w1));
if(a1 < 0.0) a1 = 0.0;
if(a2 < 0.0) a2 = 0.0;
if(a3 < 0.0) a3 = 0.0;
suma = a1+a2+a3;
loss = 0. ;
loss = 0.;
if(suma < sumaLim) // very small Step
{
@@ -1803,12 +1813,12 @@ G4double G4hLowEnergyIonisation::ElectronicLossFluctuation(
if(tmax == ipotFluct)
{
a3 = mLoss/e0;
a3 = meanLoss/e0;
if(a3>alim)
{
siga=sqrt(a3) ;
p3 = G4std::max(0,int(G4RandGauss::shoot(a3,siga)+0.5));
p3 = G4std::max(0,G4int(G4RandGauss::shoot(a3,siga)+0.5));
}
else
p3 = G4Poisson(a3);
@@ -1822,7 +1832,7 @@ G4double G4hLowEnergyIonisation::ElectronicLossFluctuation(
else
{
tmax = tmax-ipotFluct+e0 ;
a3 = mLoss*(tmax-e0)/(tmax*e0*log(tmax/e0));
a3 = meanLoss*(tmax-e0)/(tmax*e0*log(tmax/e0));
if(a3>alim)
{
@@ -1856,7 +1866,7 @@ G4double G4hLowEnergyIonisation::ElectronicLossFluctuation(
if(a1>alim)
{
siga=sqrt(a1) ;
p1 = G4std::max(0,int(G4RandGauss::shoot(a1,siga)+0.5));
p1 = G4std::max(0,G4int(G4RandGauss::shoot(a1,siga)+0.5));
}
else
p1 = G4Poisson(a1);
@@ -1865,7 +1875,7 @@ G4double G4hLowEnergyIonisation::ElectronicLossFluctuation(
if(a2>alim)
{
siga=sqrt(a2) ;
p2 = G4std::max(0,int(G4RandGauss::shoot(a2,siga)+0.5));
p2 = G4std::max(0,G4int(G4RandGauss::shoot(a2,siga)+0.5));
}
else
p2 = G4Poisson(a2);
@@ -1884,7 +1894,7 @@ G4double G4hLowEnergyIonisation::ElectronicLossFluctuation(
if(a3>alim)
{
siga=sqrt(a3) ;
p3 = G4std::max(0,int(G4RandGauss::shoot(a3,siga)+0.5));
p3 = G4std::max(0,G4int(G4RandGauss::shoot(a3,siga)+0.5));
}
else
p3 = G4Poisson(a3);
@@ -1923,7 +1933,6 @@ G4double G4hLowEnergyIonisation::ElectronicLossFluctuation(
loss += lossc;
}
}
loss *= chargeSquare;
return loss ;
}
@@ -1933,6 +1942,8 @@ G4double G4hLowEnergyIonisation::ElectronicLossFluctuation(
void G4hLowEnergyIonisation::SetCutForSecondaryPhotons(G4double cut)
{
minGammaEnergy = cut;
deexcitationManager.SetCutForSecondaryPhotons(cut);
theFluo = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -1940,6 +1951,15 @@ void G4hLowEnergyIonisation::SetCutForSecondaryPhotons(G4double cut)
void G4hLowEnergyIonisation::SetCutForAugerElectrons(G4double cut)
{
minElectronEnergy = cut;
deexcitationManager.SetCutForAugerElectrons(cut);
theFluo = true;
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
void G4hLowEnergyIonisation::ActivateAugerElectronProduction(G4bool val)
{
deexcitationManager.ActivateAugerElectronProduction(val);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4hLowEnergyLoss.cc,v 1.14 2001/11/23 11:45:29 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-00 $
// $Id: G4hLowEnergyLoss.cc,v 1.15 2002/02/27 14:38:53 vnivanch Exp $
// GEANT4 tag $Name: geant4-04-01 $
//
// -----------------------------------------------------------
// GEANT 4 class implementation file
@@ -370,7 +370,8 @@ void G4hLowEnergyLoss::BuildDEDXTable(
(Charge>0)?
theProperTimepTable: theProperTimepbarTable,
LowestKineticEnergy, HighestKineticEnergy,
proton_mass_c2/aParticleType.GetPDGMass(),TotBin);
proton_mass_c2/aParticleType.GetPDGMass(),
TotBin);
}
@@ -380,7 +381,7 @@ void G4hLowEnergyLoss::BuildRangeTable(
const G4ParticleDefinition& aParticleType)
// Build range table from the energy loss table
{
Mass = proton_mass_c2;
Mass = aParticleType.GetPDGMass();
G4int numOfMaterials = G4Material::GetNumberOfMaterials();
@@ -61,10 +61,9 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4hNuclearStoppingModel::G4hNuclearStoppingModel(const G4String& name):
G4VLowEnergyModel(name)
G4hNuclearStoppingModel::G4hNuclearStoppingModel(const G4String& name)
:G4VLowEnergyModel(name), modelName(name)
{
modelName = name ;
InitializeMe() ;
}
@@ -102,6 +101,7 @@ void G4hNuclearStoppingModel::InitializeMe()
}
// Default is nuclear stopping fluctuations On
// nStopingPowerTable->SetNuclearStoppingFluctuationsOn();
nStopingPowerTable->SetNuclearStoppingFluctuationsOff();
}
@@ -64,10 +64,9 @@
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
G4hParametrisedLossModel::G4hParametrisedLossModel(const G4String& name):
G4VLowEnergyModel(name)
G4hParametrisedLossModel::G4hParametrisedLossModel(const G4String& name)
:G4VLowEnergyModel(name), modelName(name)
{
modelName = name ;
InitializeMe();
}
@@ -64,7 +64,7 @@ G4std::vector<G4double> G4hShellCrossSection::Probabilities(
// V.Ivanchenko add only implementation of the formula (53)
// last factor neglected because it is 1 with a good accuracy
G4AtomicTransitionManager* transitionManager =
const G4AtomicTransitionManager* transitionManager =
G4AtomicTransitionManager::Instance();
size_t nShells = transitionManager->NumberOfShells(Z);