Import Geant4 5.1.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-09 10:15:15 +02:00
parent 37fff30d2e
commit fbd4999cf7
4396 changed files with 56662 additions and 52446 deletions
@@ -22,7 +22,7 @@
//
//
// $Id: G4DalitzDecayChannel.cc,v 1.5 2001/07/11 10:01:59 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ------------------------------------------------------------
@@ -22,7 +22,7 @@
//
//
// $Id: G4DecayProducts.cc,v 1.9 2001/07/11 10:01:59 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ------------------------------------------------------------
@@ -22,7 +22,7 @@
//
//
// $Id: G4DecayTable.cc,v 1.7 2001/07/11 10:01:59 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ------------------------------------------------------------
@@ -22,7 +22,7 @@
//
//
// $Id: G4DecayTableMessenger.cc,v 1.4 2001/07/11 10:01:59 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
//---------------------------------------------------------------
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4DynamicParticle.cc,v 1.11 2001/07/11 10:01:59 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
// $Id: G4DynamicParticle.cc,v 1.12 2003/03/13 09:59:39 jwellisc Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
@@ -360,7 +360,7 @@ void G4DynamicParticle::Set4Momentum(const G4LorentzVector &momentum )
momentum.z()/pModule);
G4double totalenergy = momentum.t();
if (totalenergy > pModule) {
G4double mass = sqrt(totalenergy*totalenergy - pModule2);
G4double mass = sqrt(G4std::max(0., totalenergy*totalenergy - pModule2) );
theDynamicalMass = mass;
SetKineticEnergy(totalenergy-mass);
} else {
@@ -22,7 +22,7 @@
//
//
// $Id: G4ElectronOccupancy.cc,v 1.6 2001/07/11 10:01:59 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ----------------------------------------------------------------------
+4 -48
View File
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4IonTable.cc,v 1.30 2001/10/15 09:58:34 kurasige Exp $
// GEANT4 tag $Name: geant4-05-00 $
// $Id: G4IonTable.cc,v 1.33 2003/03/10 08:43:53 kurasige Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
@@ -40,7 +40,7 @@
// Modified GetIon methods 17 Aug. 99 H.Kurashige
// New design using G4VIsotopeTable 5 Oct. 99 H.Kurashige
// Modified Element Name for Z>103 06 Apr. 01 H.Kurashige
// Remove test of cuts in SetCuts 16 Jan 03 V.Ivanchenko
#include "G4IonTable.hh"
#include "G4ParticleTable.hh"
@@ -158,7 +158,7 @@ G4ParticleDefinition* G4IonTable::CreateIon(G4int Z, G4int A, G4double E, G4int
AddProcessManager(name);
// Set cut value same as "GenericIon"
SetCuts(ion);
// SetCuts(ion);
if (fProperty !=0) delete fProperty;
return ion;
@@ -474,50 +474,6 @@ void G4IonTable::AddProcessManager(const G4String& name)
}
#include "g4std/vector"
/////////////////
void G4IonTable::SetCuts(G4ParticleDefinition* ion)
{
// Set cut value same as "GenericIon"
G4ParticleDefinition* genericIon=G4ParticleTable::GetParticleTable()->FindParticle("GenericIon");
if (genericIon == 0) {
G4Exception("G4IonTable::SetCuts : GenericIon is not defined !!");
}
if (genericIon->GetEnergyCuts() != 0) {
G4std::vector<G4double> cuts;
for (size_t j=0; j<G4Material::GetNumberOfMaterials(); j +=1) {
cuts.push_back( (genericIon->GetLengthCuts())[j] );
}
ion->SetRangeCutVector(cuts);
G4String name = ion->GetParticleName();
// Build Physics Tables for the ion
// create command string for buildPhysicsTable
char cmdBld[60];
G4std::ostrstream osBld(cmdBld,60);
osBld << "/run/particle/buildPhysicsTable "<< name << '\0';
// set /control/verbose 0
G4int tempVerboseLevel = G4UImanager::GetUIpointer()->GetVerboseLevel();
G4UImanager::GetUIpointer()->SetVerboseLevel(0);
// issue /run/particle/buildPhysicsTable
G4UImanager::GetUIpointer()->ApplyCommand(cmdBld);
// retreive /control/verbose
G4UImanager::GetUIpointer()->SetVerboseLevel(tempVerboseLevel);
} else {
#ifdef G4VERBOSE
if (GetVerboseLevel()> 1) {
G4cout << "G4IonTable::GetIon() : ";
G4cout << " cut value of GenericIon has not be defined yet";
}
#endif
}
}
////////////////////
void G4IonTable::RegisterIsotopeTable(G4VIsotopeTable* table)
+4 -3
View File
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4Ions.cc,v 1.6 2001/07/11 10:02:00 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
// $Id: G4Ions.cc,v 1.8 2003/03/11 05:49:41 kurasige Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ----------------------------------------------------------------------
@@ -51,10 +51,11 @@ G4Ions::G4Ions(
G4int baryon, G4int encoding,
G4bool stable, G4double lifetime,
G4DecayTable *decaytable )
: G4ParticleWithCuts( aName,mass,width,charge,iSpin,iParity,
: G4ParticleDefinition( aName,mass,width,charge,iSpin,iParity,
iConjugation,iIsospin,iIsospin3,gParity,pType,
lepton,baryon,encoding,stable,lifetime,decaytable )
{
SetParticleSubType("generic");
// initialize excitation energy/level
theExcitationEnergy = 0.0;
}
@@ -22,7 +22,7 @@
//
//
// $Id: G4IsotopeProperty.cc,v 1.3 2001/07/11 10:02:00 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ----------------------------------------------------------------------
@@ -22,7 +22,7 @@
//
//
// $Id: G4KL3DecayChannel.cc,v 1.5 2001/07/11 10:02:00 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ------------------------------------------------------------
@@ -0,0 +1,80 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4MaterialCutsCouple.cc,v 1.4 2003/04/10 02:51:19 asaim Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file/ History:
// 18 Sep. 2002, H.Kuirashige : Structure created based on object model
// --------------------------------------------------------------
#include "G4MaterialCutsCouple.hh"
#include "g4std/iomanip"
#include "G4Material.hh"
#include "G4ProductionCuts.hh"
G4MaterialCutsCouple::G4MaterialCutsCouple() :
isMaterialModified(false),
fMaterial(0),
fCuts(0),
indexNumber(-1),
isUsedInGeometry(false)
{
}
G4MaterialCutsCouple::G4MaterialCutsCouple(const G4Material* material,
G4ProductionCuts* cut) :
isMaterialModified(true),
fMaterial(material),
fCuts(cut),
indexNumber(-1),
isUsedInGeometry(false)
{
}
G4MaterialCutsCouple::G4MaterialCutsCouple(const G4MaterialCutsCouple& right)
{
*this = right;
}
G4MaterialCutsCouple::~G4MaterialCutsCouple()
{
}
G4MaterialCutsCouple & G4MaterialCutsCouple::operator=(const G4MaterialCutsCouple &right)
{
if (&right==this) return *this;
fMaterial = right.fMaterial;
fCuts = right.fCuts;
isMaterialModified = right.isMaterialModified;
indexNumber = right.indexNumber;
isUsedInGeometry = right.isUsedInGeometry;
return *this;
}
@@ -22,7 +22,7 @@
//
//
// $Id: G4MuonDecayChannel.cc,v 1.9 2001/07/11 10:02:00 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ------------------------------------------------------------
@@ -22,7 +22,7 @@
//
//
// $Id: G4NeutronBetaDecayChannel.cc,v 1.4 2002/04/03 09:05:33 kurasige Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ------------------------------------------------------------
@@ -22,7 +22,7 @@
//
//
// $Id: G4NucleiProperties.cc,v 1.10 2002/05/30 02:13:10 kurasige Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ------------------------------------------------------------
@@ -22,7 +22,7 @@
//
//
// $Id: G4NucleiPropertiesTableA.cc,v 1.7 2001/10/15 09:58:34 kurasige Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
// -------------------------------------------------------------------
// GEANT 4 class file --- Copyright CERN 1997
@@ -22,7 +22,7 @@
//
//
// $Id: G4NucleiPropertiesTableB.cc,v 1.7 2001/10/15 09:58:35 kurasige Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
// -------------------------------------------------------------------
// GEANT 4 class implementation file
@@ -22,7 +22,7 @@
//
//
// $Id: G4NucleiPropertiesTheoreticalTableA.cc,v 1.4 2001/10/15 09:58:35 kurasige Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ------------------------------------------------------------
@@ -22,7 +22,7 @@
//
//
// $Id: G4PDGCodeChecker.cc,v 1.5 2001/07/11 10:02:03 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ----------------------------------------------------------------------
@@ -21,8 +21,8 @@
// ********************************************************************
//
//
// $Id: G4ParticleDefinition.cc,v 1.12 2001/07/11 10:02:03 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
// $Id: G4ParticleDefinition.cc,v 1.16 2003/04/11 11:48:40 asaim Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
@@ -96,8 +96,8 @@ G4ParticleDefinition::G4ParticleDefinition(
thePDGLifeTime(lifetime),
theDecayTable(decaytable),
theProcessManager(0),
fApplyCutsFlag(false),
verboseLevel(1)
verboseLevel(1),
fApplyCutsFlag(false)
{
// check name and register this particle into ParticleTable
theParticleTable = G4ParticleTable::GetParticleTable();
@@ -247,13 +247,132 @@ void G4ParticleDefinition::DumpTable() const
}
}
if ( fApplyCutsFlag ){
G4cout << " ApplyCuts : ON" << G4endl;
} else {
G4cout << " ApplyCuts : OFF" << G4endl;
}
void G4ParticleDefinition::SetApplyCutsFlag(G4bool flg)
{
if(theParticleName=="gamma"
|| theParticleName=="e-"
|| theParticleName=="e+")
{ fApplyCutsFlag = flg; }
else
{
G4cerr
<< "G4ParticleDefinition::SetApplyCutsFlag() for " << theParticleName
<< G4endl;
G4cerr
<< "becomes obsolete. Production threshold is applied only for "
<< "gamma, e- and e+." << G4endl;
}
}
// Following methods are moved from G4ParticleWithCuts class
// for keeping backward compatibility. These methods are obsolete
// and will be completely removed away in near future.
#include "G4MaterialCutsCouple.hh"
#include "G4ProductionCuts.hh"
#include "G4ProductionCutsTable.hh"
void G4ParticleDefinition::SetCuts(G4double aCut)
{
G4cerr << "Warning : you invoked G4ParticleDefinition::SetCuts." << G4endl;
G4cerr << " This method is obsolete and will be removed soon." << G4endl;
G4cerr << " Use G4ProductionCuts class." << G4endl;
G4ProductionCuts* defaultCuts
= G4ProductionCutsTable::GetProductionCutsTable()->GetDefaultProductionCuts();
defaultCuts->SetProductionCut(aCut,this);
}
void G4ParticleDefinition::SetRangeCut(G4double aCut, const G4Material*)
{
G4cerr << "Warning : you invoked G4ParticleDefinition::SetRangeCut." << G4endl;
G4cerr << " This method is obsolete and will be removed soon." << G4endl;
G4cerr << " Use G4ProductionCuts class." << G4endl;
G4ProductionCuts* defaultCuts
= G4ProductionCutsTable::GetProductionCutsTable()->GetDefaultProductionCuts();
defaultCuts->SetProductionCut(aCut,this);
}
void G4ParticleDefinition::SetRangeCutVector(G4std::vector<G4double>& vec)
{
G4cerr << "Warning : you invoked G4ParticleDefinition::SetRangeCutVector." << G4endl;
G4cerr << " This method is obsolete and will be removed soon." << G4endl;
G4cerr << " Use G4ProductionCuts class." << G4endl;
G4ProductionCuts* defaultCuts
= G4ProductionCutsTable::GetProductionCutsTable()->GetDefaultProductionCuts();
defaultCuts->SetProductionCut(vec[0],this);
}
G4double* G4ParticleDefinition::GetLengthCuts() const
{
G4cerr << "Warning : you invoked G4ParticleDefinition::GetLengthCuts." << G4endl;
G4cerr << " This method is obsolete and will be removed soon." << G4endl;
G4cerr << " Use G4ProductionCuts class." << G4endl;
G4int idx = G4ProductionCuts::GetIndex(this);
if(idx<0) return NULL;
return G4ProductionCutsTable::GetProductionCutsTable()->GetRangeCutsDoubleVector(idx);
}
G4double G4ParticleDefinition::GetRangeThreshold(const G4Material* aMat) const
{
G4cerr << "Warning : you invoked G4ParticleDefinition::GetLengthThreshold." << G4endl;
G4cerr << " This method is obsolete and will be removed soon." << G4endl;
G4cerr << " Use G4ProductionCuts class." << G4endl;
G4int idx = G4ProductionCuts::GetIndex(this);
if(idx<0) return -1.;
G4ProductionCuts* defaultCuts
= G4ProductionCutsTable::GetProductionCutsTable()->GetDefaultProductionCuts();
const G4MaterialCutsCouple* materialCutsCouple
= G4ProductionCutsTable::GetProductionCutsTable()->GetMaterialCutsCouple(aMat,defaultCuts);
if(materialCutsCouple==NULL) return -1.;
G4double* vec
= G4ProductionCutsTable::GetProductionCutsTable()->GetRangeCutsDoubleVector(idx);
return vec[materialCutsCouple->GetIndex()];
}
G4double* G4ParticleDefinition::GetEnergyCuts() const
{
G4cerr << "Warning : you invoked G4ParticleDefinition::GetEnergyCuts." << G4endl;
G4cerr << " This method is obsolete and will be removed soon." << G4endl;
G4cerr << " Use G4ProductionCuts class." << G4endl;
G4int idx = G4ProductionCuts::GetIndex(this);
if(idx<0) return NULL;
return G4ProductionCutsTable::GetProductionCutsTable()->GetEnergyCutsDoubleVector(idx);
}
G4double G4ParticleDefinition::GetEnergyThreshold(const G4Material* aMat) const
{
G4cerr << "Warning : you invoked G4ParticleDefinition::GetEnergyThreshold." << G4endl;
G4cerr << " This method is obsolete and will be removed soon." << G4endl;
G4cerr << " Use G4ProductionCuts class." << G4endl;
G4int idx = G4ProductionCuts::GetIndex(this);
if(idx<0) return -1.;
G4ProductionCuts* defaultCuts
= G4ProductionCutsTable::GetProductionCutsTable()->GetDefaultProductionCuts();
const G4MaterialCutsCouple* materialCutsCouple
= G4ProductionCutsTable::GetProductionCutsTable()->GetMaterialCutsCouple(aMat,defaultCuts);
if(materialCutsCouple==NULL) return -1.;
G4double* vec
= G4ProductionCutsTable::GetProductionCutsTable()->GetEnergyCutsDoubleVector(idx);
return vec[materialCutsCouple->GetIndex()];
}
#include "G4VRangeToEnergyConverter.hh"
void G4ParticleDefinition::SetEnergyRange(G4double lowedge, G4double highedge)
{
G4VRangeToEnergyConverter::SetEnergyRange(lowedge, highedge);
}
@@ -22,7 +22,7 @@
//
//
// $Id: G4ParticleMessenger.cc,v 1.6 2001/10/24 18:42:41 gcosmo Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
//---------------------------------------------------------------
@@ -22,7 +22,7 @@
//
//
// $Id: G4ParticlePropertyMessenger.cc,v 1.5 2002/12/04 18:36:45 asaim Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
//---------------------------------------------------------------
@@ -22,7 +22,7 @@
//
//
// $Id: G4ParticleTable.cc,v 1.18 2001/07/11 10:02:03 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
// class G4ParticleTable
//
@@ -1,776 +0,0 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4ParticleWithCuts.cc,v 1.17 2001/10/28 05:08:37 kurasige Exp $
// GEANT4 tag $Name: geant4-05-00 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
//
// History:
// first implementation, based on object model of Hisaya Kurashige,
// 21 Oct 1996
// calculation of Range Table is based on implementeation for Muon
// by L.Urban, 10 May 1996
// modify CalcEnergyCuts 09 Nov. 1998, L.Urban
// added RestoreCuts H.Kurashige 09 Mar. 2001
// modify for material-V03-02-02 (STL migration) H.Kurashige 19 Sep. 2001
// introduced material dependent range cuts 08 Oct. 2001
// ------------------------------------------------------------
#include "globals.hh"
#include "G4ParticleWithCuts.hh"
#include "G4ParticleTable.hh"
#include "G4Material.hh"
#include "G4PhysicsLogVector.hh"
#include "G4ios.hh"
#include "g4std/strstream"
// energy range
G4double G4ParticleWithCuts::LowestEnergy = 0.99e-3*MeV;
G4double G4ParticleWithCuts::HighestEnergy = 100.0e6*MeV;
// pointer to G4Proton
G4ParticleDefinition* G4ParticleWithCuts::theProton = 0;
G4ParticleWithCuts::G4ParticleWithCuts(
const G4String& aName,
G4double mass,
G4double width,
G4double charge,
G4int iSpin,
G4int iParity,
G4int iConjugation,
G4int iIsospin,
G4int iIsospinZ,
G4int gParity,
const G4String& pType,
G4int lepton,
G4int baryon,
G4int encoding,
G4bool stable,
G4double lifetime,
G4DecayTable *decaytable,
G4bool shortlived)
: G4ParticleDefinition(aName, mass, width, charge, iSpin, iParity,
iConjugation, iIsospin, iIsospinZ, gParity,
pType, lepton, baryon, encoding, stable,
lifetime, decaytable, shortlived),
//-- members initialisation for SetCuts ------------------------------
theCutInMaxInteractionLength(0),
theKineticEnergyCuts(0),
theLossTable(0),
NumberOfElements(0)
{
// -- set ApplyCutsFlag in default ----------
SetApplyCutsFlag(false);
//-- default values for SetCuts ------------------------------
// Lowest/Highest energy is defined in MeV
TotBin = 200;
}
G4ParticleWithCuts::~G4ParticleWithCuts()
{
if (theCutInMaxInteractionLength) delete [] theCutInMaxInteractionLength;
if (theKineticEnergyCuts) delete [] theKineticEnergyCuts;
if (theLossTable) delete theLossTable;
}
// **********************************************************************
// ************************ RangeLinSimpson *****************************
// **********************************************************************
G4double G4ParticleWithCuts::RangeLinSimpson(
const G4ElementVector* elementVector,
const G4double* atomicNumDensityVector,
const G4LossTable* aLossTable,
G4double aMass,
G4double taulow, G4double tauhigh,
G4int nbin, G4int NumEl)
{
// Simpson numerical integration, linear binning
G4double dtau = (tauhigh-taulow)/nbin;
G4double Value=0.;
for (G4int i=0; i<=nbin; i++)
{
G4double taui=taulow+dtau*i;
G4double ti=aMass*taui;
G4double lossi=0.;
for (G4int j=0; j<NumEl; j++)
{
G4bool isOut;
G4int IndEl = (*elementVector)[j]->GetIndex();
lossi += atomicNumDensityVector[j]*
(*aLossTable)[IndEl]->GetValue(ti,isOut);
}
if ( i==0 )
Value += 0.5/lossi;
else {
if ( i<nbin ) Value += 1./lossi;
else Value += 0.5/lossi;
}
}
Value *= aMass*dtau;
return Value;
}
// **********************************************************************
// ************************ RangeLogSimpson *****************************
// **********************************************************************
G4double G4ParticleWithCuts::RangeLogSimpson(
const G4ElementVector* elementVector,
const G4double* atomicNumDensityVector,
const G4LossTable* aLossTable,
G4double aMass,
G4double ltaulow, G4double ltauhigh,
G4int nbin, G4int NumEl)
{
// Simpson numerical integration, logarithmic binning
G4double ltt = ltauhigh-ltaulow;
G4double dltau = ltt/nbin;
G4double Value = 0.;
for (G4int i=0; i<=nbin; i++)
{
G4double ui = ltaulow+dltau*i;
G4double taui = exp(ui);
G4double ti = aMass*taui;
G4double lossi = 0.;
for (G4int j=0; j<NumEl; j++)
{
G4bool isOut;
G4int IndEl = (*elementVector)[j]->GetIndex();
lossi += atomicNumDensityVector[j]*
(*aLossTable)[IndEl]->GetValue(ti,isOut);
}
if ( i==0 )
Value += 0.5*taui/lossi;
else {
if ( i<nbin ) Value += taui/lossi;
else Value += 0.5*taui/lossi;
}
}
Value *= aMass*dltau;
return Value;
}
// **********************************************************************
// ************************ BuildLossTable ******************************
// **********************************************************************
// create Energy Loss Table for charged particles
// (cross section tabel for neutral )
void G4ParticleWithCuts::BuildLossTable()
{
// Build dE/dx tables for elements
if (NumberOfElements ==0)
{
NumberOfElements = G4Element::GetNumberOfElements();
theLossTable = new G4LossTable();
theLossTable->reserve(G4Element::GetNumberOfElements());
#ifdef G4VERBOSE
if (GetVerboseLevel()>2) {
G4cout << "G4ParticleWithCuts::BuildLossTable() ";
G4cout << "Create theLossTable[" << theLossTable << "]";
G4cout << " NumberOfElements=" << NumberOfElements <<G4endl;
}
#endif
} else {
if (NumberOfElements != G4int(G4Element::GetNumberOfElements())){
char errMsg[1024];
G4std::ostrstream errOs(errMsg,1024);
errOs << "Error in G4ParticlWithCuts::BuildLossTable()";
errOs << "[" << this->GetParticleName() << "] ";
errOs << " : inconsistent G4Element::GetNumberOfElements =" << G4Element::GetNumberOfElements();
errOs << " previous value" << NumberOfElements << '\0';
G4Exception(errMsg);
}
}
// fill the loss table
for (G4int J=0; J<NumberOfElements; J++)
{
G4double Value;
G4LossVector* aVector= new
G4LossVector(LowestEnergy, HighestEnergy, TotBin);
for (G4int i=0; i<TotBin; i++)
{
Value = ComputeLoss(
(*G4Element::GetElementTable())[J]->GetZ(),
aVector->GetLowEdgeEnergy(i)
);
aVector->PutValue(i,Value);
}
theLossTable->insert(aVector);
}
}
// **********************************************************************
// ****************** ConvertCutToKineticEnergy *************************
// **********************************************************************
G4double
G4ParticleWithCuts::ConvertCutToKineticEnergy(G4RangeVector* rangeVector,
size_t materialIndex
) const
{
const G4double epsilon=0.01;
const G4int NBIN=200;
// find max. range and the corresponding energy (rmax,Tmax)
G4double Tmax=HighestEnergy;
G4double rmax=-1.e10*mm;
G4double fac=log(HighestEnergy/LowestEnergy)/NBIN;
fac=exp(fac);
G4double T=LowestEnergy/fac;
G4bool isOut;
for (G4int ibin=0; ibin<NBIN; ibin++)
{
T=fac*T;
G4double r=rangeVector->GetValue(T,isOut);
if ( r>rmax )
{
Tmax=T;
rmax=r;
}
}
G4double T1 = LowestEnergy;
G4double r1 = rangeVector->GetValue(T1,isOut);
if ( theCutInMaxInteractionLength[materialIndex] <= r1 )
return T1;
if ( theCutInMaxInteractionLength[materialIndex] >= rmax )
{
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cout << "Error in G4ParticleWithCuts::ConvertCutToKineticEnergy" <<G4endl;
G4cout << "******** ConvertCutToKineticEnergy for " << GetParticleName();
G4cout << " ********************" << G4endl;
G4cout << "The cut energy is set " << DBL_MAX/GeV << "GeV " <<G4endl;
}
#endif
return DBL_MAX;
} else {
G4double T2 = Tmax ;
G4double T3 = sqrt(T1*T2);
G4double r3 = rangeVector->GetValue(T3,isOut);
while ( abs(1.-r3/theCutInMaxInteractionLength[materialIndex])>epsilon )
{
if ( theCutInMaxInteractionLength[materialIndex] <= r3 ) {
T2 = T3;
} else {
T1 = T3;
}
T3 = sqrt(T1*T2);
r3 = rangeVector->GetValue(T3,isOut);
}
return T3;
}
}
// **********************************************************************
// **************************** RestoreCuts *********************************
// **********************************************************************
void G4ParticleWithCuts::RestoreCuts(const G4double* cutInLength,
const G4double* cutInEnergy )
{
size_t numberOfMaterials = G4Material::GetNumberOfMaterials();
// Set cut in stopping range
if(theCutInMaxInteractionLength) delete [] theCutInMaxInteractionLength;
theCutInMaxInteractionLength = new G4double [numberOfMaterials];
// Restore the vector of cuts in energy corresponding to the range cut
if(theKineticEnergyCuts) delete [] theKineticEnergyCuts;
theKineticEnergyCuts = new G4double [numberOfMaterials];
for (size_t j=0; j<numberOfMaterials; j +=1) {
theCutInMaxInteractionLength[j] = cutInLength[j];
theKineticEnergyCuts[j] = cutInEnergy[j];
}
}
// **********************************************************************
// **************************** SetCuts *********************************
// **********************************************************************
G4bool G4ParticleWithCuts::UseProtonCut()
{
G4double Charge = this->GetPDGCharge() ;
G4bool useProtonCut =
((GetParticleName() != "gamma" ) &&
(GetParticleName() != "e-" ) &&
(GetParticleName() != "e+" ) &&
(GetParticleName() != "mu-" ) &&
(GetParticleName() != "mu+" ) &&
(GetParticleName() != "proton" ) &&
(GetParticleName() != "anti_proton" ) &&
(Charge != 0.) );
if (!useProtonCut) return false;
// check if the proton exists or not
if(theProton ==0) {
theProton = G4ParticleTable::GetParticleTable()->FindParticle("proton");
if (theProton ==0) {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cout << " G4ParticleWithCuts::UseProtonCut ";
G4cout << " proton is not defined !!" << G4endl;
}
#endif
return false;
}
}
// check if cuts for the proton are defined or not
if (theProton->GetEnergyCuts()==0) {
char errMsg[1024];
G4std::ostrstream errOs(errMsg,1024);
errOs << " G4ParticleWithCuts::CalcEnergyCuts ";
errOs << " proton energy cut is not defined !!" << '\0';
G4Exception(errMsg);
}
G4double* protonCuts = theProton->GetLengthCuts();
// check if the cut in range is same as one fro the proton
size_t numberOfMaterials = G4Material::GetNumberOfMaterials();
for (size_t J=0; J<numberOfMaterials; J +=1) {
useProtonCut = useProtonCut &&
( abs(theCutInMaxInteractionLength[J]-protonCuts[J])<1.*nanometer )
;
}
#ifdef G4VERBOSE
if (GetVerboseLevel()>2) {
G4cout << " G4ParticleWithCuts: [" << GetParticleName() <<"]";
if ( useProtonCut) {
G4cout << " uses Proton Cut " << G4endl;
} else {
G4cout << " calcurate by using its own loss table " << G4endl;
}
}
#endif
return useProtonCut;
}
G4bool G4ParticleWithCuts::CheckEnergyBinSetting() const
{
// check LowestEnergy/ HighestEnergy/TotBin
if (TotBin<1) {
char errMsg[1024];
G4std::ostrstream errOs(errMsg,1024);
errOs << "Error in G4ParticlWithCuts::G4ParticlWithCuts" ;
errOs << "[" << this->GetParticleName() << "]";
errOs << " : not defined or illegal TotBin [" << TotBin << "]" << '\0';
G4Exception(errMsg);
}
if ( (LowestEnergy<0.0)||(HighestEnergy<=LowestEnergy) ){
char errMsg[1024];
G4std::ostrstream errOs(errMsg,1024);
errOs << "Error in G4ParticlWithCuts::G4ParticlWithCuts";
errOs << "[" << this->GetParticleName() << "]";
errOs << " : illegal energy range" << "(" << LowestEnergy/GeV;
errOs << "," << HighestEnergy/GeV << ") [GeV]" << '\0';
G4Exception(errMsg);
}
return true;
}
void G4ParticleWithCuts::CalcEnergyCuts(const G4Material* theMaterial)
{
// check LowestEnergy/ HighestEnergy/TotBin
CheckEnergyBinSetting();
// number of materials
size_t numberOfMaterials = G4Material::GetNumberOfMaterials();
// Create the vector of cuts in energy
// corresponding to the stopping range cut
if( !theMaterial) {
if(theKineticEnergyCuts) delete [] theKineticEnergyCuts;
theKineticEnergyCuts = new G4double [numberOfMaterials];
} else {
if(!theKineticEnergyCuts) theKineticEnergyCuts = new G4double [numberOfMaterials];
}
G4double Charge = this->GetPDGCharge() ;
G4bool useProtonCut = UseProtonCut();
if (useProtonCut) {
// use energy cuts for Proton
G4double ChargeSquare = Charge*Charge/(eplus*eplus) ;
G4double massRatio = proton_mass_c2/(this->GetPDGMass()) ;
for (size_t J=0; J<numberOfMaterials; J +=1) {
if (theMaterial!=0) {
if ( theMaterial->GetIndex() != J ) continue;
}
G4double protonEnergyCut = (theProton->GetEnergyCuts())[J] ;
// cut energy is rescaled by using charge and mass ratio
theKineticEnergyCuts[J] = ChargeSquare*protonEnergyCut/massRatio ;
if(theKineticEnergyCuts[J] < LowestEnergy) {
theKineticEnergyCuts[J] = LowestEnergy ;
}
}
} else {
// Build the energy loss table
BuildLossTable();
// Build range vector for every material, convert cut into energy-cut,
// fill theKineticEnergyCuts and delete the range vector
G4double tune = 0.025*mm*g/cm3 ,lowen = 30.*keV ;
G4double density ;
const G4MaterialTable * materialTable = G4Material::GetMaterialTable();
for (size_t J=0; J<numberOfMaterials; J +=1){
if (theMaterial!=0) {
if ( theMaterial->GetIndex() != J ) continue;
}
G4RangeVector* rangeVector = new
G4RangeVector(LowestEnergy, HighestEnergy, TotBin);
G4Material* aMaterial = (*materialTable)[J];
density = aMaterial->GetDensity() ;
if(density == 0.) {
theKineticEnergyCuts[J] = 0. ;
} else {
this->BuildRangeVector(aMaterial, this->theLossTable,
this->HighestEnergy, this->GetPDGMass(),
rangeVector);
theKineticEnergyCuts[J] = ConvertCutToKineticEnergy(rangeVector, J);
if( ((GetParticleName()=="e-")||(GetParticleName()=="e+"))
&& (theKineticEnergyCuts[J] < lowen) ) {
theKineticEnergyCuts[J] /= (1.+tune/(theCutInMaxInteractionLength[J]*density));
}
if(theKineticEnergyCuts[J] < LowestEnergy) {
theKineticEnergyCuts[J] = LowestEnergy ;
}
}
delete rangeVector;
}
// Delete energy loss table
theLossTable->clearAndDestroy();
}
}
// **********************************************************************
// ************************** ComputeLoss *******************************
// **********************************************************************
G4double G4ParticleWithCuts::ComputeLoss(G4double AtomicNumber,
G4double KineticEnergy) const
{
// calculate dE/dx
static G4double Z;
static G4double ionpot, tau0, taum, taul, ca, cba, cc;
G4double z2Particle = GetPDGCharge()/eplus;
z2Particle *= z2Particle;
if (z2Particle < 0.1) return 0.0;
if( abs(AtomicNumber-Z)>0.1 )
{
// recalculate constants
Z = AtomicNumber;
G4double Z13 = exp(log(Z)/3.);
tau0 = 0.1*Z13*MeV/proton_mass_c2;
taum = 0.035*Z13*MeV/proton_mass_c2;
taul = 2.*MeV/proton_mass_c2;
ionpot = 1.6e-5*MeV*exp(0.9*log(Z));
cc = (taul+1.)*(taul+1.)*log(2.*electron_mass_c2*taul*(taul+2.)/ionpot)/(taul*(taul+2.))-1.;
cc = 2.*twopi_mc2_rcl2*Z*cc*sqrt(taul);
ca = cc/((1.-0.5*sqrt(tau0/taum))*tau0);
cba = -0.5/sqrt(taum);
}
G4double tau = KineticEnergy/GetPDGMass();
G4double dEdx;
if ( tau <= tau0 )
dEdx = ca*(sqrt(tau)+cba*tau);
else
{
if( tau <= taul )
dEdx = cc/sqrt(tau);
else
{
dEdx = (tau+1.)*(tau+1.)*
log(2.*electron_mass_c2*tau*(tau+2.)/ionpot)/(tau*(tau+2.))-1.;
dEdx = 2.*twopi_mc2_rcl2*Z*dEdx;
}
}
return dEdx*z2Particle ;
}
// **********************************************************************
// ************************ BuildRangeVector ****************************
// **********************************************************************
void G4ParticleWithCuts::BuildRangeVector(
const G4Material* aMaterial,
const G4LossTable* aLossTable,
G4double maxEnergy,
G4double aMass,
G4RangeVector* rangeVector)
{
// create range vector for a material
const G4double tlim=2.*MeV, t1=0.1*MeV, t2=0.025*MeV;
const G4int maxnbint=100;
const G4ElementVector* elementVector = aMaterial->GetElementVector();
const G4double* atomicNumDensityVector = aMaterial->GetAtomicNumDensityVector();
G4int NumEl = aMaterial->GetNumberOfElements();
if (rangeVector == 0) {
char errMsg[1024];
G4std::ostrstream errOs(errMsg,1024);
errOs << "Error in G4ParticleWithCuts::BuildRangeVector()";
errOs << "[" << this->GetParticleName() << "] ";
errOs << " : 0 pointer is found in absorptionLengthVector" << '\0';
G4Exception(errMsg);
}
// calculate parameters of the low energy part first
G4double loss1=0.;
G4double loss2=0.;
G4int i;
for (i=0; i<NumEl; i++)
{
G4bool isOut;
G4int IndEl = (*elementVector)[i]->GetIndex();
loss1 += atomicNumDensityVector[i]*
(*aLossTable)[IndEl]->GetValue(t1,isOut);
loss2 += atomicNumDensityVector[i]*
(*aLossTable)[IndEl]->GetValue(t2,isOut);
}
G4double tau1 = t1/proton_mass_c2;
G4double sqtau1 = sqrt(tau1);
G4double ca = (4.*loss2-loss1)/sqtau1;
G4double cb = (2.*loss1-4.*loss2)/tau1;
G4double cba = cb/ca;
G4double taulim = tlim/proton_mass_c2;
G4double taumax = maxEnergy/aMass;
G4double ltaumax = log(taumax);
// now we can fill the range vector....
G4double rmax = 0.0;
for (i=0; i<TotBin; i++)
{
G4double LowEdgeEnergy = rangeVector->GetLowEdgeEnergy(i);
G4double tau = LowEdgeEnergy/aMass;
G4double Value;
if ( tau <= tau1 ){
Value =2.*aMass*log(1.+cba*sqrt(tau))/cb;
} else {
Value = 2.*aMass*log(1.+cba*sqtau1)/cb;
if ( tau <= taulim )
{
G4int nbin = (G4int)(maxnbint*(tau-tau1)/(taulim-tau1));
if ( nbin<1 ) nbin = 1;
Value += RangeLinSimpson(elementVector,atomicNumDensityVector,
aLossTable, aMass,
tau1, tau,
nbin, NumEl);
} else {
Value += RangeLinSimpson(elementVector,atomicNumDensityVector,
aLossTable, aMass,
tau1, taulim,
maxnbint, NumEl);
G4double ltaulow = log(taulim);
G4double ltauhigh = log(tau);
G4int nbin = (G4int)(maxnbint*(ltauhigh-ltaulow)/(ltaumax-ltaulow));
if ( nbin<1 ) nbin = 1;
Value += RangeLogSimpson(elementVector,atomicNumDensityVector,
aLossTable, aMass,
ltaulow, ltauhigh,
nbin, NumEl);
}
}
rangeVector->PutValue(i,Value);
if (rmax < Value) rmax = Value;
}
if ( theCutInMaxInteractionLength[aMaterial->GetIndex()] >= rmax) {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cout << "Error in G4ParticleWithCuts::BuildRangeVector()" << G4endl;
G4cout << " SetCuts for " << GetParticleName() << G4endl;
G4cout << "The maximal meaningful cut is " << rmax/mm << " mm." << G4endl;
G4cout << "All the " << GetParticleName() << "will be killed !" << G4endl;
G4cout << "in the material " << aMaterial->GetName() << "." << G4endl;
}
#endif
}
}
void G4ParticleWithCuts::SetCuts(G4double aCut)
{
// set range cut values for all materials
SetCutInMaxInteractionLength(aCut);
// calculate energy cut values
CalcEnergyCuts();
}
void G4ParticleWithCuts::SetRangeCut(G4double aCut, const G4Material* aMaterial)
{
// set range cut values for all materials
SetCutInMaxInteractionLength(aCut, aMaterial);
// calculate energy cut values
CalcEnergyCuts(aMaterial);
}
void G4ParticleWithCuts::SetRangeCutVector(G4std::vector<G4double>& cuts)
{
// set material table pointer
size_t numberOfMaterials = G4Material::GetNumberOfMaterials();
// check vector
if (cuts.size() != numberOfMaterials) {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cout << " G4ParticleWithCuts::SetRangeCutVector: ";
G4cout << " given vector size is not consistent with material table size "
;
G4cout << G4endl;
G4cout << " Cut values remain unchanged !!" << G4endl;
}
#endif
return;
}
// Create the vector of cuts in range
if(theCutInMaxInteractionLength) delete [] theCutInMaxInteractionLength;
theCutInMaxInteractionLength = new G4double [numberOfMaterials];
// Set cut in stopping range for all materials
for (size_t J=0; J<numberOfMaterials; J +=1) {
theCutInMaxInteractionLength[J] = cuts[J];
}
CalcEnergyCuts();
}
void G4ParticleWithCuts::SetCutInMaxInteractionLength(G4double aCut)
{
// get number of materials
size_t numberOfMaterials = G4Material::GetNumberOfMaterials();
// Create the vector of cuts in range
if(theCutInMaxInteractionLength) delete [] theCutInMaxInteractionLength;
theCutInMaxInteractionLength = new G4double [numberOfMaterials];
// Set cut in stopping range for all materials
for (size_t J=0; J<numberOfMaterials; J +=1) {
theCutInMaxInteractionLength[J] = aCut;
}
}
void G4ParticleWithCuts::SetCutInMaxInteractionLength(G4double aCut ,
G4int materialIndex)
{
// get number of materials
size_t numberOfMaterials = G4Material::GetNumberOfMaterials();
// Create the vector of cuts in range
if(theCutInMaxInteractionLength==0){
theCutInMaxInteractionLength = new G4double [numberOfMaterials];
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cout << " G4ParticleWithCuts::SetCutInMaxInteractionLength: ";
G4cout << " Cut in range for all material is set to ";
G4cout << aCut/mm << " [mm]" << G4endl;
}
#endif
for (size_t J=0; J<numberOfMaterials; J +=1) {
theCutInMaxInteractionLength[J] = aCut;
}
}
theCutInMaxInteractionLength[materialIndex] = aCut;
}
void G4ParticleWithCuts::SetCutInMaxInteractionLength(G4double aCut ,
const G4Material* aMaterial)
{
// get number of materials
size_t numberOfMaterials = G4Material::GetNumberOfMaterials();
// Create the vector of cuts in range
if(theCutInMaxInteractionLength==0){
theCutInMaxInteractionLength = new G4double [numberOfMaterials];
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cout << " G4ParticleWithCuts::SetCutInMaxInteractionLength: ";
G4cout << " Cut in range for all material is set to ";
G4cout << aCut/mm << " [mm]" << G4endl;
}
#endif
for (size_t J=0; J<numberOfMaterials; J +=1) {
theCutInMaxInteractionLength[J] = aCut;
}
}
theCutInMaxInteractionLength[aMaterial->GetIndex()] = aCut;
}
void G4ParticleWithCuts::SetEnergyCutValues(G4double energyCut)
{
size_t numberOfMaterials = G4Material::GetNumberOfMaterials();
if(theKineticEnergyCuts) delete [] theKineticEnergyCuts;
theKineticEnergyCuts = new G4double [numberOfMaterials];
// fill theKineticEnergyCuts and delete the range vector
for (size_t J=0; J<numberOfMaterials; J++)
{
theKineticEnergyCuts[J] = energyCut;
}
}
void G4ParticleWithCuts::SetEnergyRange(G4double lowedge, G4double highedge)
{
LowestEnergy = lowedge;
HighestEnergy = highedge;
}
@@ -22,7 +22,7 @@
//
//
// $Id: G4PhaseSpaceDecayChannel.cc,v 1.7 2001/10/15 09:58:36 kurasige Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ------------------------------------------------------------
@@ -0,0 +1,82 @@
//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4ProductionCuts.cc,v 1.6 2003/04/10 02:51:19 asaim Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file/ History:
// 18 Sep. 2002, H.Kuirashige : Structure created based on object model
// --------------------------------------------------------------
#include "G4ProductionCuts.hh"
#include "g4std/iomanip"
const G4ParticleDefinition* G4ProductionCuts::gammaDef = 0;
const G4ParticleDefinition* G4ProductionCuts::electDef = 0;
const G4ParticleDefinition* G4ProductionCuts::positDef = 0;
G4ProductionCuts::G4ProductionCuts() :
isModified(true)
{
for (G4int i=0; i< NumberOfG4CutIndex; i++) {
fRangeCuts.push_back(0.0);
}
}
G4ProductionCuts::G4ProductionCuts(const G4ProductionCuts& right)
{
*this = right;
}
G4ProductionCuts::~G4ProductionCuts()
{
fRangeCuts.clear();
}
G4ProductionCuts & G4ProductionCuts::operator=(const G4ProductionCuts &right)
{
if (&right==this) return *this;
for (G4int i=0; i< NumberOfG4CutIndex; i++) {
fRangeCuts[i] = right.fRangeCuts[i];
}
isModified = right.isModified;
return *this;
}
G4int G4ProductionCuts::operator==(const G4ProductionCuts &right) const
{
return (this == &right);
}
G4int G4ProductionCuts::operator!=(const G4ProductionCuts &right) const
{
return (this != &right);
}
@@ -0,0 +1,998 @@
//
// ********************************************************************
// * 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: G4ProductionCutsTable.cc,v 1.14 2003/04/29 04:25:58 kurasige Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file/ History:
// 06/Oct. 2002, M.Asai : First implementation
// --------------------------------------------------------------
#include "G4ProductionCutsTable.hh"
#include "G4ProductionCuts.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTable.hh"
#include "G4RegionStore.hh"
#include "G4LogicalVolume.hh"
#include "G4RToEConvForElectron.hh"
#include "G4RToEConvForGamma.hh"
#include "G4RToEConvForPositron.hh"
#include "G4MaterialTable.hh"
#include "G4Material.hh"
#include "G4UnitsTable.hh"
#include "G4ios.hh"
#include "g4std/iomanip"
#include "g4std/fstream"
G4ProductionCutsTable* G4ProductionCutsTable::fG4ProductionCutsTable = 0;
G4ProductionCutsTable* G4ProductionCutsTable::GetProductionCutsTable()
{
if(!fG4ProductionCutsTable)
{ fG4ProductionCutsTable = new G4ProductionCutsTable(); }
return fG4ProductionCutsTable;
}
G4ProductionCutsTable::G4ProductionCutsTable()
: firstUse(true)
{
for(size_t i=0;i< NumberOfG4CutIndex;i++)
{
rangeCutTable.push_back(new G4CutVectorForAParticle);
energyCutTable.push_back(new G4CutVectorForAParticle);
rangeDoubleVector[i] = 0;
energyDoubleVector[i] = 0;
converters[i] = 0;
}
fG4RegionStore = G4RegionStore::GetInstance();
defaultProductionCuts = new G4ProductionCuts();
}
G4ProductionCutsTable::G4ProductionCutsTable(const G4ProductionCutsTable& right)
{;}
G4ProductionCutsTable::~G4ProductionCutsTable()
{
for(CoupleTableIterator itr=coupleTable.begin();itr!=coupleTable.end();itr++)
{ delete (*itr); }
coupleTable.clear();
for(size_t i=0;i< NumberOfG4CutIndex;i++)
{
delete rangeCutTable[i];
delete energyCutTable[i];
delete converters[i];
if(rangeDoubleVector[i]!=0) delete [] rangeDoubleVector[i];
if(energyDoubleVector[i]!=0) delete [] energyDoubleVector[i];
}
}
void G4ProductionCutsTable::UpdateCoupleTable()
{
if(firstUse)
{
if(G4ParticleTable::GetParticleTable()->FindParticle("gamma"))
{ converters[0] = new G4RToEConvForGamma(); }
if(G4ParticleTable::GetParticleTable()->FindParticle("e-"))
{ converters[1] = new G4RToEConvForElectron(); }
if(G4ParticleTable::GetParticleTable()->FindParticle("e+"))
{ converters[2] = new G4RToEConvForPositron(); }
firstUse = false;
}
// Reset "used" flags of all couples
for(CoupleTableIterator CoupleItr=coupleTable.begin();CoupleItr!=coupleTable.end();CoupleItr++)
{ (*CoupleItr)->SetUseFlag(false); }
// Update Material-Cut-Couple
typedef G4std::vector<G4Region*>::iterator regionIterator;
for(regionIterator rItr=fG4RegionStore->begin();rItr!=fG4RegionStore->end();rItr++)
{
///////////////////if(!((*rItr)->IsModified())) continue;
G4ProductionCuts* fProductionCut = (*rItr)->GetProductionCuts();
G4std::vector<G4Material*>::const_iterator mItr = (*rItr)->GetMaterialIterator();
size_t nMaterial = (*rItr)->GetNumberOfMaterials();
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The following part of the code should be removed once all EM processes
// become "Region-aware"
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//G4Region* theWorldRegion = *(fG4RegionStore->begin());
//if((*rItr)==theWorldRegion)
//{
// mItr = G4Material::GetMaterialTable()->begin();
// nMaterial = G4Material::GetMaterialTable()->size();
//}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The previous part of the code should be removed once all EM processes
// become "Region-aware"
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for(size_t iMate=0;iMate<nMaterial;iMate++)
{
//check if this material cut couple has already been made
G4bool coupleAlreadyDefined = false;
G4MaterialCutsCouple* aCouple;
for(CoupleTableIterator cItr=coupleTable.begin();cItr!=coupleTable.end();cItr++)
{
if((*cItr)->GetMaterial()==(*mItr) && (*cItr)->GetProductionCuts()==fProductionCut)
{
coupleAlreadyDefined = true;
aCouple = *cItr;
break;
}
}
//if this combination is new, cleate and register a couple
if(!coupleAlreadyDefined)
{
aCouple = new G4MaterialCutsCouple((*mItr),fProductionCut);
coupleTable.push_back(aCouple);
aCouple->SetIndex(coupleTable.size()-1);
}
//Set the couple to the proper logical volumes in that region
aCouple->SetUseFlag();
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The following part of the code should be removed once all EM processes
// become "Region-aware"
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// if((*rItr)==theWorldRegion)
// {
// aCouple->SetUseFlag(false);
// G4std::vector<G4Material*>::const_iterator mItr1 = (*rItr)->GetMaterialIterator();
// size_t nMaterial1 = (*rItr)->GetNumberOfMaterials();
// for(size_t iMate1=0;iMate1<nMaterial1;iMate1++)
// {
// if((*mItr1)==aCouple->GetMaterial()) aCouple->SetUseFlag();
// mItr1++;
// }
// }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The previous part of the code should be removed once all EM processes
// become "Region-aware"
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
G4std::vector<G4LogicalVolume*>::iterator rootLVItr
= (*rItr)->GetRootLogicalVolumeIterator();
size_t nRootLV = (*rItr)->GetNumberOfRootVolumes();
for(size_t iLV=0;iLV<nRootLV;iLV++)
{
//Set the couple to the proper logical volumes in that region
G4LogicalVolume* aLV = *rootLVItr;
G4Region* aR = *rItr;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The following part of the code should be removed once all EM processes
// become "Region-aware"
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// if(aR==theWorldRegion) aR = 0;
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// The previous part of the code should be removed once all EM processes
// become "Region-aware"
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ScanAndSetCouple(aLV,aCouple,aR);
//proceed to the next root logical volume in this region
rootLVItr++;
}
//proceed to next material in this region
mItr++;
}
}
// Check if sizes of Range/Energy cuts tables are equal to the size of
// the couple table
// If new couples are made during the previous procedure, nCouple becomes
// larger then nTable
size_t nCouple = coupleTable.size();
size_t nTable = energyCutTable[0]->size();
G4bool newCoupleAppears = nCouple>nTable;
if(newCoupleAppears)
{
for(size_t n=nCouple-nTable;n>0;n--)
{
for(size_t nn=0;nn< NumberOfG4CutIndex;nn++)
{
rangeCutTable[nn]->push_back(-1.);
energyCutTable[nn]->push_back(-1.);
}
}
}
// Update RangeEnergy cuts tables
size_t idx = 0;
for(CoupleTableIterator cItr=coupleTable.begin();cItr!=coupleTable.end();cItr++)
{
G4ProductionCuts* aCut = (*cItr)->GetProductionCuts();
const G4Material* aMat = (*cItr)->GetMaterial();
if((*cItr)->IsRecalcNeeded())
{
for(size_t ptcl=0;ptcl< NumberOfG4CutIndex;ptcl++)
{
G4double rCut = aCut->GetProductionCut(ptcl);
(*(rangeCutTable[ptcl]))[idx] = rCut;
// if(converters[ptcl] && (*cItr)->IsUsed())
if(converters[ptcl])
{ (*(energyCutTable[ptcl]))[idx] = converters[ptcl]->Convert(rCut,aMat); }
else
{ (*(energyCutTable[ptcl]))[idx] = -1.; }
}
}
idx++;
}
// resize Range/Energy cuts double vectors if new couple is made
if(newCoupleAppears)
{
for(size_t ix=0;ix<NumberOfG4CutIndex;ix++)
{
G4double* rangeVOld = rangeDoubleVector[ix];
G4double* energyVOld = energyDoubleVector[ix];
if(rangeVOld) delete [] rangeVOld;
if(energyVOld) delete [] energyVOld;
rangeDoubleVector[ix] = new G4double[(*(rangeCutTable[ix])).size()];
energyDoubleVector[ix] = new G4double[(*(energyCutTable[ix])).size()];
}
}
// Update Range/Energy cuts double vectors
for(size_t ix=0;ix<NumberOfG4CutIndex;ix++)
{
for(size_t ixx=0;ixx<(*(rangeCutTable[ix])).size();ixx++)
{
rangeDoubleVector[ix][ixx] = (*(rangeCutTable[ix]))[ixx];
energyDoubleVector[ix][ixx] = (*(energyCutTable[ix]))[ixx];
}
}
}
void G4ProductionCutsTable::SetEnergyRange(G4double lowedge, G4double highedge)
{
G4VRangeToEnergyConverter::SetEnergyRange(lowedge,highedge);
}
G4double G4ProductionCutsTable::GetLowEdgeEnergy() const
{
return G4VRangeToEnergyConverter::GetLowEdgeEnergy();
}
G4double G4ProductionCutsTable::GetHighEdgeEnergy() const
{
return G4VRangeToEnergyConverter::GetHighEdgeEnergy();
}
void G4ProductionCutsTable::ScanAndSetCouple(G4LogicalVolume* aLV,G4MaterialCutsCouple* aCouple,G4Region* aRegion)
{
//Check whether or not this logical volume belongs to the same region
if((aRegion!=0) && aLV->GetRegion()!=aRegion) return;
//Check if this particular volume has a material matched to the couple
if(aLV->GetMaterial()==aCouple->GetMaterial())
{
aLV->SetMaterialCutsCouple(aCouple);
}
size_t noDaughters = aLV->GetNoDaughters();
if(noDaughters==0) return;
//Loop over daughters with same region
for(size_t i=0;i<noDaughters;i++)
{
G4LogicalVolume* daughterLVol = aLV->GetDaughter(i)->GetLogicalVolume();
ScanAndSetCouple(daughterLVol,aCouple,aRegion);
}
}
void G4ProductionCutsTable::DumpCouples() const
{
G4cout << G4endl;
G4cout << "========= Table of registered couples ==============================" << G4endl;
for(CoupleTableIterator cItr=coupleTable.begin();cItr!=coupleTable.end();cItr++)
{
G4MaterialCutsCouple* aCouple = (*cItr);
G4ProductionCuts* aCut = aCouple->GetProductionCuts();
G4cout << G4endl;
G4cout << "Index : " << aCouple->GetIndex()
<< " used in the geometry : ";
if(aCouple->IsUsed()) G4cout << "Yes";
else G4cout << "No ";
G4cout << " recalculation needed : ";
if(aCouple->IsRecalcNeeded()) G4cout << "Yes";
else G4cout << "No ";
G4cout << G4endl;
G4cout << " Material : " << aCouple->GetMaterial()->GetName() << G4endl;
G4cout << " Range cuts : "
<< " gamma " << G4BestUnit(aCut->GetProductionCut("gamma"),"Length")
<< " e- " << G4BestUnit(aCut->GetProductionCut("e-"),"Length")
<< " e+ " << G4BestUnit(aCut->GetProductionCut("e+"),"Length")
<< G4endl;
G4cout << " Energy thresholds : " ;
// if(!(aCouple->IsUsed()) || aCouple->IsRecalcNeeded()) G4cout << " is not ready to print";
if(aCouple->IsRecalcNeeded()) G4cout << " is not ready to print";
else
G4cout << " gamma " << G4BestUnit((*(energyCutTable[0]))[aCouple->GetIndex()],"Energy")
<< " e- " << G4BestUnit((*(energyCutTable[1]))[aCouple->GetIndex()],"Energy")
<< " e+ " << G4BestUnit((*(energyCutTable[2]))[aCouple->GetIndex()],"Energy");
G4cout << G4endl;
if(aCouple->IsUsed())
{
G4cout << " Region(s) which use this couple : " << G4endl;
typedef G4std::vector<G4Region*>::iterator regionIterator;
for(regionIterator rItr=fG4RegionStore->begin();rItr!=fG4RegionStore->end();rItr++)
{
if (IsCoupleUsedInTheRegion(aCouple, *rItr) ){
G4cout << " " << (*rItr)->GetName() << G4endl;
}
}
}
}
G4cout << G4endl;
G4cout << "====================================================================" << G4endl;
G4cout << G4endl;
}
// Store cuts and material information in files under the specified directory.
G4bool G4ProductionCutsTable::StoreCutsTable(const G4String& dir,
G4bool ascii)
{
if (!StoreMaterialInfo(dir, ascii)) return false;
if (!StoreMaterialCutsCoupleInfo(dir, ascii)) return false;
if (!StoreCutsInfo(dir, ascii)) return false;
return true;
}
G4bool G4ProductionCutsTable::RetrieveCutsTable(const G4String& dir,
G4bool ascii)
{
if (!CheckForRetrieveCutsTable(dir, ascii)) return false;
if (!RetrieveCutsInfo(dir, ascii)) return false;
return true;
}
// check stored material and cut values are consistent with the current detector setup.
G4bool G4ProductionCutsTable::CheckForRetrieveCutsTable(const G4String& directory,
G4bool ascii)
{
if (!CheckMaterialInfo(directory, ascii)) return false;
if (!CheckMaterialCutsCoupleInfo(directory, ascii)) return false;
return true;
}
// Store material information in files under the specified directory.
G4bool G4ProductionCutsTable::StoreMaterialInfo(const G4String& directory,
G4bool ascii)
{
const G4String fileName = directory + "/" + "material.dat";
const G4String key = "MATERIAL-V2.0";
G4std::ofstream fOut;
// open output file //
#ifdef G4USE_STD_NAMESPACE
if (!ascii )
fOut.open(fileName,G4std::ios::out|G4std::ios::binary);
else
#endif
fOut.open(fileName,G4std::ios::out);
// check if the file has been opened successfully
if (!fOut) {
#ifdef G4VERBOSE
G4cerr << "G4ProductionCutsTable::StoreMaterialInfo ";
G4cerr << " Can not open file " << fileName << G4endl;
#endif
return false;
}
const G4MaterialTable* matTable = G4Material::GetMaterialTable();
// number of materials in the table
G4int numberOfMaterial = matTable->size();
if (ascii) {
/////////////// ASCII mode /////////////////
// key word
fOut << key << G4endl;
// number of materials in the table
fOut << numberOfMaterial << G4endl;
fOut.setf(G4std::ios::scientific);
// material name and density
for (size_t idx=0; G4int(idx)<numberOfMaterial; ++idx){
fOut << G4std::setw(FixedStringLengthForStore) << ((*matTable)[idx])->GetName();
fOut << G4std::setw(FixedStringLengthForStore) << ((*matTable)[idx])->GetDensity()/(g/cm3) << G4endl;
}
fOut.unsetf(G4std::ios::scientific);
} else {
/////////////// Binary mode /////////////////
char temp[FixedStringLengthForStore];
size_t i;
// key word
for (i=0; i<FixedStringLengthForStore; ++i) temp[i] = '\0';
for (i=0; i<key.length() && i<FixedStringLengthForStore-1; ++i) temp[i]=key[i];
fOut.write(temp, FixedStringLengthForStore);
// number of materials in the table
fOut.write( (char*)(&numberOfMaterial), sizeof (G4int));
// material name and density
for (size_t imat=0; G4int(imat)<numberOfMaterial; ++imat){
G4String name = ((*matTable)[imat])->GetName();
G4double density = ((*matTable)[imat])->GetDensity();
for (i=0; i<FixedStringLengthForStore; ++i) temp[i] = '\0';
for (i=0; i<name.length() && i<FixedStringLengthForStore-1; ++i) temp[i]=name[i];
fOut.write(temp, FixedStringLengthForStore);
fOut.write( (char*)(&density), sizeof (G4double));
}
}
fOut.close();
return true;
}
// check stored material is consistent with the current detector setup.
G4bool G4ProductionCutsTable::CheckMaterialInfo(const G4String& directory,
G4bool ascii)
{
const G4String fileName = directory + "/" + "material.dat";
const G4String key = "MATERIAL-V2.0";
G4std::ifstream fIn;
// open input file //
#ifdef G4USE_STD_NAMESPACE
if (!ascii )
fIn.open(fileName,G4std::ios::in|G4std::ios::binary);
else
#endif
fIn.open(fileName,G4std::ios::in);
// check if the file has been opened successfully
if (!fIn) {
#ifdef G4VERBOSE
G4cerr << "G4ProductionCutsTable::CheckMaterialInfo ";
G4cerr << " Can not open file " << fileName << G4endl;
#endif
return false;
}
char temp[FixedStringLengthForStore];
// key word
G4String keyword;
if (ascii) {
fIn >> keyword;
} else {
fIn.read(temp, FixedStringLengthForStore);
keyword = (const char*)(temp);
}
if (key!=keyword) {
#ifdef G4VERBOSE
G4cout << "G4ProductionCutsTable::CheckMaterialInfo ";
G4cout << " Wrong key word " << key ;
G4cout <<"( != "<< keyword << ")" <<G4endl;
#endif
return false;
}
const G4MaterialTable* matTable = G4Material::GetMaterialTable();
G4int numberOfMaterial = matTable->size();
// number of materials in the table
G4int nmat;
if (ascii) {
fIn >> nmat;
} else {
fIn.read( (char*)(&nmat), sizeof (G4int));
}
if (nmat!=numberOfMaterial) {
#ifdef G4VERBOSE
G4cout << "G4ProductionCutsTable::CheckMaterialInfo ";
G4cout << "Number of material is inconsistent "<< G4endl;
#endif
return false;
}
// list of material
for (G4int idx=0; idx<numberOfMaterial ; ++idx){
// check eof
if(fIn.eof()) {
#ifdef G4VERBOSE
G4cout << "G4ProductionCutsTable::CheckMaterialInfo ";
G4cout << " encountered End of File" << G4endl;
#endif
fIn.close();
return false;
}
// check material name and density
char name[FixedStringLengthForStore];
double density;
if (ascii) {
fIn >> name >> density;
density *= (g/cm3);
} else {
fIn.read(name, FixedStringLengthForStore);
fIn.read((char*)(&density), sizeof (G4double));
}
if (fIn.fail()) {
#ifdef G4VERBOSE
G4cout << "G4ProductionCutsTable::CheckMaterialInfo ";
G4cout << " Bad data format " << G4endl;
#endif
fIn.close();
return false;
}
G4double ratio = abs(density/((*matTable)[idx])->GetDensity() );
if ( (name != ((*matTable)[idx])->GetName()) || (0.999>ratio) || (ratio>1.001) ){
#ifdef G4VERBOSE
G4cout << "G4ProductionCutsTable::CheckMaterialInfo ";
G4cout << " Inconsistent material name or density" << G4endl;;
G4cout << G4std::setw(40) << name;
G4cout << G4std::setw(20) << G4std::setiosflags(G4std::ios::scientific) << density << G4endl;
G4cout << G4std::resetiosflags(G4std::ios::scientific);
#endif
fIn.close();
return false;
}
}
fIn.close();
return true;
}
// Store materialCutsCouple information in files under the specified directory.
G4bool G4ProductionCutsTable::StoreMaterialCutsCoupleInfo(const G4String& directory,
G4bool ascii)
{
const G4String fileName = directory + "/" + "couple.dat";
const G4String key = "COUPLE-V2.0";
G4std::ofstream fOut;
char temp[FixedStringLengthForStore];
// open output file //
#ifdef G4USE_STD_NAMESPACE
if (!ascii )
fOut.open(fileName,G4std::ios::out|G4std::ios::binary);
else
#endif
fOut.open(fileName,G4std::ios::out);
// check if the file has been opened successfully
if (!fOut) {
#ifdef G4VERBOSE
G4cerr << "G4ProductionCutsTable::StoreMaterialCutsCoupleInfo ";
G4cerr << " Can not open file " << fileName << G4endl;
#endif
return false;
}
G4int numberOfCouples = coupleTable.size();
if (ascii) {
/////////////// ASCII mode /////////////////
// key word
fOut << G4std::setw(FixedStringLengthForStore) << key << G4endl;
// number of couples in the table
fOut << numberOfCouples << G4endl;
} else {
/////////////// Binary mode /////////////////
// key word
size_t i;
for (i=0; i<FixedStringLengthForStore; ++i) temp[i] = '\0';
for (i=0; i<key.length() && i<FixedStringLengthForStore-1; ++i) temp[i]=key[i];
fOut.write(temp, FixedStringLengthForStore);
// number of couples in the table
fOut.write( (char*)(&numberOfCouples), sizeof (G4int));
}
// Loop over all couples
CoupleTableIterator cItr;
for (cItr=coupleTable.begin();cItr!=coupleTable.end();cItr++){
G4MaterialCutsCouple* aCouple = (*cItr);
G4int index = aCouple->GetIndex();
// cut value
G4ProductionCuts* aCut = aCouple->GetProductionCuts();
G4double cutValues[NumberOfG4CutIndex];
for (size_t idx=0; idx <NumberOfG4CutIndex; idx++) {
cutValues[idx] = aCut->GetProductionCut(idx);
}
// material/region info
G4String materialName = aCouple->GetMaterial()->GetName();
G4String regionName = "NONE";
if (aCouple->IsUsed()){
typedef G4std::vector<G4Region*>::iterator regionIterator;
for(regionIterator rItr=fG4RegionStore->begin();rItr!=fG4RegionStore->end();rItr++){
if (IsCoupleUsedInTheRegion(aCouple, *rItr) ){
regionName = (*rItr)->GetName();
break;
}
}
}
if (ascii) {
/////////////// ASCII mode /////////////////
// index number
fOut << index << G4endl;
// material name
fOut << G4std::setw(FixedStringLengthForStore) << materialName<< G4endl;
// region name
fOut << G4std::setw(FixedStringLengthForStore) << regionName<< G4endl;
fOut.setf(G4std::ios::scientific);
// cut values
for (size_t idx=0; idx< NumberOfG4CutIndex; idx++) {
fOut << G4std::setw(FixedStringLengthForStore) << cutValues[idx]/(mm) << G4endl;
}
fOut.unsetf(G4std::ios::scientific);
} else {
/////////////// Binary mode /////////////////
// index
fOut.write( (char*)(&index), sizeof (G4int));
// material name
size_t i;
for (i=0; i<FixedStringLengthForStore; ++i) temp[i] = '\0';
for (i=0; i<materialName.length() && i<FixedStringLengthForStore-1; ++i) {
temp[i]=materialName[i];
}
fOut.write(temp, FixedStringLengthForStore);
// region name
for (i=0; i<FixedStringLengthForStore; ++i) temp[i] = '\0';
for (i=0; i<regionName.length() && i<FixedStringLengthForStore-1; ++i) {
temp[i]=regionName[i];
}
fOut.write(temp, FixedStringLengthForStore);
// cut values
for (size_t idx=0; idx< NumberOfG4CutIndex; idx++) {
fOut.write( (char*)(&(cutValues[idx])), sizeof (G4double));
}
}
}
fOut.close();
return true;
}
// check stored materialCutsCouple is consistent with the current detector setup.
G4bool G4ProductionCutsTable::CheckMaterialCutsCoupleInfo(const G4String& directory,
G4bool ascii )
{
const G4String fileName = directory + "/" + "couple.dat";
const G4String key = "COUPLE-V2.0";
G4std::ifstream fIn;
// open input file //
#ifdef G4USE_STD_NAMESPACE
if (!ascii )
fIn.open(fileName,G4std::ios::in|G4std::ios::binary);
else
#endif
fIn.open(fileName,G4std::ios::in);
// check if the file has been opened successfully
if (!fIn) {
#ifdef G4VERBOSE
G4cerr << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo ";
G4cerr << " Can not open file " << fileName << G4endl;
#endif
return false;
}
char temp[FixedStringLengthForStore];
// key word
G4String keyword;
if (ascii) {
fIn >> keyword;
} else {
fIn.read(temp, FixedStringLengthForStore);
keyword = (const char*)(temp);
}
if (key!=keyword) {
#ifdef G4VERBOSE
G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo ";
G4cout << " Wrong key word " << key ;
G4cout <<"( != "<< keyword << ")" <<G4endl;
#endif
return false;
}
// numberOfCouples
G4int numberOfCouples;
if (ascii) {
fIn >> numberOfCouples;
} else {
fIn.read( (char*)(&numberOfCouples), sizeof (G4int));
}
if ( size_t(numberOfCouples) != coupleTable.size()) {
#ifdef G4VERBOSE
G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo ";
G4cout << "Number of couples is inconsistent "<< G4endl;
#endif
return false;
}
// Loop over all couples
CoupleTableIterator cItr;
for (cItr=coupleTable.begin();cItr!=coupleTable.end();cItr++){
char name[FixedStringLengthForStore];
G4MaterialCutsCouple* aCouple = (*cItr);
G4int index;
if (ascii) {
fIn >> index;
} else {
fIn.read( (char*)(&index), sizeof (G4int));
}
if ( index != aCouple->GetIndex() ) {
#ifdef G4VERBOSE
G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo ";
G4cout << "Index of couples is inconsistent "<< index << G4endl;
#endif
return false;
}
if (ascii) {
fIn >> name;
} else {
fIn.read(name, FixedStringLengthForStore);
}
if ( name != aCouple->GetMaterial()->GetName() ) {
#ifdef G4VERBOSE
G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo ";
G4cout << "MaterialName is inconsistent ";
G4cout << "[" << index << "] " << name << G4endl;
#endif
return false;
}
if (ascii) {
fIn >> name;
} else {
fIn.read(name, FixedStringLengthForStore);
}
if (!aCouple->IsUsed()){
if ( name != "NONE" ) {
#ifdef G4VERBOSE
G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo ";
G4cout << "Region Name is inconsistent ";
G4cout << "[" << index << "] " << name << G4endl;
#endif
return false;
}
} else {
G4Region* fRegion = fG4RegionStore->GetRegion(name);
if (!IsCoupleUsedInTheRegion(aCouple, fRegion) ){
#ifdef G4VERBOSE
G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo ";
G4cout << "Region Name is inconsistent ";
G4cout << "[" << index << "] " << name << G4endl;
#endif
return false;
}
}
// cut value
G4ProductionCuts* aCut = aCouple->GetProductionCuts();
G4double cutValues[NumberOfG4CutIndex];
for (size_t idx=0; idx< NumberOfG4CutIndex; idx++) {
if (ascii) {
fIn >> cutValues[idx];
cutValues[idx] *= (mm);
} else {
fIn.read( (char*)(&(cutValues[idx])), sizeof (G4double));
}
G4double ratio = cutValues[idx]/aCut->GetProductionCut(idx);
if ((0.999>ratio) || (ratio>1.001) ){
#ifdef G4VERBOSE
G4cout << "G4ProductionCutTable::CheckMaterialCutsCoupleInfo ";
G4cout << "CutValue for " << idx << " is inconsistent ";
G4cout << "[" << index << "] " << G4endl;
#endif
return false;
}
}
}
return true;
}
// Store cut values information in files under the specified directory.
G4bool G4ProductionCutsTable::StoreCutsInfo(const G4String& directory,
G4bool ascii)
{
const G4String fileName = directory + "/" + "cut.dat";
const G4String key = "CUT-V2.0";
G4std::ofstream fOut;
char temp[FixedStringLengthForStore];
// open output file //
#ifdef G4USE_STD_NAMESPACE
if (!ascii )
fOut.open(fileName,G4std::ios::out|G4std::ios::binary);
else
#endif
fOut.open(fileName,G4std::ios::out);
// check if the file has been opened successfully
if (!fOut) {
#ifdef G4VERBOSE
G4cerr << "G4ProductionCutsTable::StoreCutsInfo ";
G4cerr << " Can not open file " << fileName << G4endl;
#endif
return false;
}
G4int numberOfCouples = coupleTable.size();
if (ascii) {
/////////////// ASCII mode /////////////////
// key word
fOut << key << G4endl;
// number of couples in the table
fOut << numberOfCouples << G4endl;
} else {
/////////////// Binary mode /////////////////
// key word
size_t i;
for (i=0; i<FixedStringLengthForStore; ++i) temp[i] = '\0';
for (i=0; i<key.length() && i<FixedStringLengthForStore-1; ++i) temp[i]=key[i];
fOut.write(temp, FixedStringLengthForStore);
// number of couples in the table
fOut.write( (char*)(&numberOfCouples), sizeof (G4int));
}
for (size_t idx=0; idx <NumberOfG4CutIndex; idx++) {
const G4std::vector<G4double>* fRange = GetRangeCutsVector(idx);
const G4std::vector<G4double>* fEnergy = GetEnergyCutsVector(idx);
size_t i=0;
// Loop over all couples
CoupleTableIterator cItr;
for (cItr=coupleTable.begin();cItr!=coupleTable.end();cItr++, i++){
if (ascii) {
/////////////// ASCII mode /////////////////
fOut.setf(G4std::ios::scientific);
fOut << G4std::setw(20) << (*fRange)[i]/mm ;
fOut << G4std::setw(20) << (*fEnergy)[i]/keV << G4endl;
fOut.unsetf(G4std::ios::scientific);
} else {
/////////////// Binary mode /////////////////
G4double cut = (*fRange)[i];
fOut.write((char*)(&cut), sizeof (G4double));
cut = (*fEnergy)[i];
fOut.write((char*)(&cut), sizeof (G4double));
}
}
}
fOut.close();
return true;
}
// Retrieve cut values information in files under the specified directory.
G4bool G4ProductionCutsTable::RetrieveCutsInfo(const G4String& directory,
G4bool ascii)
{
const G4String fileName = directory + "/" + "cut.dat";
const G4String key = "CUT-V2.0";
G4std::ifstream fIn;
// open input file //
#ifdef G4USE_STD_NAMESPACE
if (!ascii )
fIn.open(fileName,G4std::ios::in|G4std::ios::binary);
else
#endif
fIn.open(fileName,G4std::ios::in);
// check if the file has been opened successfully
if (!fIn) {
#ifdef G4VERBOSE
G4cerr << "G4ProductionCutTable::RetreiveCutsInfo ";
G4cerr << " Can not open file " << fileName << G4endl;
#endif
return false;
}
char temp[FixedStringLengthForStore];
// key word
G4String keyword;
if (ascii) {
fIn >> keyword;
} else {
fIn.read(temp, FixedStringLengthForStore);
keyword = (const char*)(temp);
}
if (key!=keyword) {
#ifdef G4VERBOSE
G4cout << "G4ProductionCutTable::RetreiveCutsInfo ";
G4cout << " Wrong key word " << key ;
G4cout <<"( != "<< keyword << ")" <<G4endl;
#endif
return false;
}
// numberOfCouples
G4int numberOfCouples;
if (ascii) {
fIn >> numberOfCouples;
} else {
fIn.read( (char*)(&numberOfCouples), sizeof (G4int));
}
for (size_t idx=0; G4int(idx) <NumberOfG4CutIndex; idx++) {
G4CutVectorForAParticle* fRange = rangeCutTable[idx];
G4CutVectorForAParticle* fEnergy = energyCutTable[idx];
fRange->clear();
fEnergy->clear();
// Loop over all couples
for (size_t i=0; G4int(i)< numberOfCouples; i++){
G4double rcut, ecut;
if (ascii) {
fIn >> rcut >> ecut;
rcut *= mm;
ecut *= keV;
} else {
fIn.read((char*)(&rcut), sizeof (G4double));
fIn.read((char*)(&ecut), sizeof (G4double));
}
fRange->push_back(rcut);
fEnergy->push_back(ecut);
}
}
return true;
}
@@ -0,0 +1,58 @@
//
// ********************************************************************
// * 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: G4RToEConvForAntiNeutron.cc,v 1.2 2002/12/16 11:15:45 gcosmo Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file/ History:
// 5 Oct. 2002, H.Kuirashige : Structure created based on object model
// --------------------------------------------------------------
#include "G4RToEConvForAntiNeutron.hh"
#include "G4ParticleTable.hh"
#include "G4Material.hh"
#include "G4PhysicsLogVector.hh"
#include "G4ios.hh"
#include "g4std/iomanip"
#include "g4std/strstream"
G4RToEConvForAntiNeutron::G4RToEConvForAntiNeutron() : G4VRangeToEnergyConverter()
{
theParticle = G4ParticleTable::GetParticleTable()->FindParticle("anti_neutron");
if (theParticle ==0) {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cout << " G4RToEConvForAntiNeutron::G4RToEConvForAntiNeutron() ";
G4cout << " Antineutron is not defined !!" << G4endl;
}
#endif
}
}
G4RToEConvForAntiNeutron::~G4RToEConvForAntiNeutron()
{
}
@@ -0,0 +1,58 @@
//
// ********************************************************************
// * 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: G4RToEConvForAntiProton.cc,v 1.2 2002/12/16 11:15:45 gcosmo Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file/ History:
// 5 Oct. 2002, H.Kuirashige : Structure created based on object model
// --------------------------------------------------------------
#include "G4RToEConvForAntiProton.hh"
#include "G4ParticleTable.hh"
#include "G4Material.hh"
#include "G4PhysicsLogVector.hh"
#include "G4ios.hh"
#include "g4std/iomanip"
#include "g4std/strstream"
G4RToEConvForAntiProton::G4RToEConvForAntiProton() : G4VRangeToEnergyConverter()
{
theParticle = G4ParticleTable::GetParticleTable()->FindParticle("anti_proton");
if (theParticle ==0) {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cout << " G4RToEConvForAntiProton::G4RToEConvForAntiProton() ";
G4cout << " AntiProton is not defined !!" << G4endl;
}
#endif
}
}
G4RToEConvForAntiProton::~G4RToEConvForAntiProton()
{
}
@@ -0,0 +1,170 @@
//
// ********************************************************************
// * 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: G4RToEConvForElectron.cc,v 1.3 2003/01/07 23:52:24 asaim Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file/ History:
// 5 Oct. 2002, H.Kuirashige : Structure created based on object model
// --------------------------------------------------------------
#include "G4RToEConvForElectron.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTable.hh"
#include "G4Material.hh"
#include "G4PhysicsLogVector.hh"
#include "G4ios.hh"
#include "g4std/iomanip"
#include "g4std/strstream"
G4RToEConvForElectron::G4RToEConvForElectron() : G4VRangeToEnergyConverter()
{
theParticle = G4ParticleTable::GetParticleTable()->FindParticle("e-");
if (theParticle ==0) {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cout << " G4RToEConvForElectron::G4RToEConvForElectron() ";
G4cout << " Electron is not defined !!" << G4endl;
}
#endif
}
}
G4RToEConvForElectron::~G4RToEConvForElectron()
{
}
// **********************************************************************
// ************************* ComputeLoss ********************************
// **********************************************************************
G4double G4RToEConvForElectron::ComputeLoss(G4double AtomicNumber,
G4double KineticEnergy) const
{
static G4double Z;
static G4double taul, ionpot, ionpotlog;
const G4double cbr1=0.02, cbr2=-5.7e-5, cbr3=1., cbr4=0.072;
const G4double Tlow=10.*keV, Thigh=1.*GeV;
static G4double bremfactor= 0.1 ;
G4double Mass = theParticle->GetPDGMass();
// calculate dE/dx for electrons
if( abs(AtomicNumber-Z)>0.1 ) {
Z = AtomicNumber;
taul = Tlow/Mass;
ionpot = 1.6e-5*MeV*exp(0.9*log(Z))/Mass;
ionpotlog = log(ionpot);
}
G4double tau = KineticEnergy/Mass;
G4double dEdx;
if(tau<taul) {
G4double t1 = taul+1.;
G4double t2 = taul+2.;
G4double tsq = taul*taul;
G4double beta2 = taul*t2/(t1*t1);
G4double f = 1.-beta2+log(tsq/2.)
+(0.5+0.25*tsq+(1.+2.*taul)*log(0.5))/(t1*t1);
dEdx = (log(2.*taul+4.)-2.*ionpotlog+f)/beta2;
dEdx = twopi_mc2_rcl2*Z*dEdx;
G4double clow = dEdx*sqrt(taul);
dEdx = clow/sqrt(KineticEnergy/Mass);
} else {
G4double t1 = tau+1.;
G4double t2 = tau+2.;
G4double tsq = tau*tau;
G4double beta2 = tau*t2/(t1*t1);
G4double f = 1.-beta2+log(tsq/2.)
+(0.5+0.25*tsq+(1.+2.*tau)*log(0.5))/(t1*t1);
dEdx = (log(2.*tau+4.)-2.*ionpotlog+f)/beta2;
dEdx = twopi_mc2_rcl2*Z*dEdx;
// loss from bremsstrahlung follows
G4double cbrem = (cbr1+cbr2*Z)
*(cbr3+cbr4*log(KineticEnergy/Thigh));
cbrem = Z*(Z+1.)*cbrem*tau/beta2;
cbrem *= bremfactor ;
dEdx += twopi_mc2_rcl2*cbrem;
}
return dEdx;
}
void G4RToEConvForElectron::BuildRangeVector(const G4Material* aMaterial,
G4double maxEnergy,
G4double aMass,
G4PhysicsLogVector* rangeVector)
{
// create range vector for a material
const G4double tlim = 10.*keV;
const G4int maxnbint = 100;
const G4ElementVector* elementVector = aMaterial->GetElementVector();
const G4double* atomicNumDensityVector = aMaterial->GetAtomicNumDensityVector();
G4int NumEl = aMaterial->GetNumberOfElements();
// calculate parameters of the low energy part first
size_t i;
G4double loss=0.;
for (i=0; i<size_t(NumEl); i++) {
G4bool isOut;
G4int IndEl = (*elementVector)[i]->GetIndex();
loss += atomicNumDensityVector[i]*
(*theLossTable)[IndEl]->GetValue(tlim,isOut);
}
G4double taulim = tlim/aMass;
G4double clim = sqrt(taulim)*loss;
G4double taumax = maxEnergy/aMass;
// now the range vector can be filled
for ( i=0; i<size_t(TotBin); i++) {
G4double LowEdgeEnergy = rangeVector->GetLowEdgeEnergy(i);
G4double tau = LowEdgeEnergy/aMass;
if ( tau <= taulim ) {
G4double Value = 2.*aMass*tau*sqrt(tau)/(3.*clim);
rangeVector->PutValue(i,Value);
} else {
G4double rangelim = 2.*aMass*taulim*sqrt(taulim)/(3.*clim);
G4double ltaulow = log(taulim);
G4double ltauhigh = log(tau);
G4double ltaumax = log(taumax);
G4int nbin = G4int(maxnbint*(ltauhigh-ltaulow)/(ltaumax-ltaulow));
if( nbin < 1 ) nbin = 1;
G4double Value = RangeLogSimpson(elementVector, atomicNumDensityVector,
aMass,
ltaulow, ltauhigh, nbin)
+ rangelim;
rangeVector->PutValue(i,Value);
}
}
}
@@ -0,0 +1,159 @@
//
// ********************************************************************
// * 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: G4RToEConvForGamma.cc,v 1.4 2003/01/07 23:52:24 asaim Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file/ History:
// 5 Oct. 2002, H.Kuirashige : Structure created based on object model
// --------------------------------------------------------------
#include "G4RToEConvForGamma.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTable.hh"
#include "G4Material.hh"
#include "G4PhysicsLogVector.hh"
#include "G4ios.hh"
#include "g4std/iomanip"
#include "g4std/strstream"
G4RToEConvForGamma::G4RToEConvForGamma() : G4VRangeToEnergyConverter()
{
theParticle = G4ParticleTable::GetParticleTable()->FindParticle("gamma");
if (theParticle ==0) {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cout << " G4RToEConvForGamma::G4RToEConvForGamma() ";
G4cout << " Gamma is not defined !!" << G4endl;
}
#endif
}
TotBin = 100;
}
G4RToEConvForGamma::~G4RToEConvForGamma()
{
}
// ***********************************************************************
// ******************* BuildAbsorptionLengthVector ***********************
// ***********************************************************************
void G4RToEConvForGamma::BuildAbsorptionLengthVector(
const G4Material* aMaterial,
G4double ,
G4double ,
G4RangeVector* absorptionLengthVector )
{
// fill the absorption length vector for this material
// absorption length is defined here as
//
// absorption length = 5./ macroscopic absorption cross section
//
const G4CrossSectionTable* aCrossSectionTable = (G4CrossSectionTable*)(theLossTable);
const G4ElementVector* elementVector = aMaterial->GetElementVector();
const G4double* atomicNumDensityVector = aMaterial->GetAtomicNumDensityVector();
// fill absorption length vector
G4int NumEl = aMaterial->GetNumberOfElements();
G4double absorptionLengthMax = 0.0;
for (size_t ibin=0; ibin<size_t(TotBin); ibin++) {
G4double lowEdgeEnergy = absorptionLengthVector->GetLowEdgeEnergy(ibin);
G4double SIGMA = 0. ;
for (size_t iel=0; iel<size_t(NumEl); iel++) {
G4bool isOut;
G4int IndEl = (*elementVector)[iel]->GetIndex();
SIGMA += atomicNumDensityVector[iel]*
(*aCrossSectionTable)[IndEl]->GetValue(lowEdgeEnergy,isOut);
}
// absorption length=5./SIGMA
absorptionLengthVector->PutValue(ibin, 5./SIGMA);
if (absorptionLengthMax < 5./SIGMA ) absorptionLengthMax = 5./SIGMA;
}
}
// ***********************************************************************
// ********************** ComputeCrossSection ****************************
// ***********************************************************************
G4double G4RToEConvForGamma::ComputeCrossSection(G4double AtomicNumber,
G4double KineticEnergy) const
{
// Compute the "absorption" cross section of the photon "absorption"
// cross section means here the sum of the cross sections of the
// pair production, Compton scattering and photoelectric processes
static G4double Z;
const G4double t1keV = 1.*keV;
const G4double t200keV = 200.*keV;
const G4double t100MeV = 100.*MeV;
static G4double s200keV, s1keV;
static G4double tmin, tlow;
static G4double smin, slow;
static G4double cmin, clow, chigh;
// compute Z dependent quantities in the case of a new AtomicNumber
if(abs(AtomicNumber-Z)>0.1) {
Z = AtomicNumber;
G4double Zsquare = Z*Z;
G4double Zlog = log(Z);
G4double Zlogsquare = Zlog*Zlog;
s200keV = (0.2651-0.1501*Zlog+0.02283*Zlogsquare)*Zsquare;
tmin = (0.552+218.5/Z+557.17/Zsquare)*MeV;
smin = (0.01239+0.005585*Zlog-0.000923*Zlogsquare)*exp(1.5*Zlog);
cmin=log(s200keV/smin)/(log(tmin/t200keV)*log(tmin/t200keV));
tlow = 0.2*exp(-7.355/sqrt(Z))*MeV;
slow = s200keV*exp(0.042*Z*log(t200keV/tlow)*log(t200keV/tlow));
s1keV = 300.*Zsquare;
clow =log(s1keV/slow)/log(tlow/t1keV);
chigh=(7.55e-5-0.0542e-5*Z)*Zsquare*Z/log(t100MeV/tmin);
}
// calculate the cross section (using an approximate empirical formula)
G4double s;
if ( KineticEnergy<tlow ) {
if(KineticEnergy<t1keV) s = slow*exp(clow*log(tlow/t1keV));
else s = slow*exp(clow*log(tlow/KineticEnergy));
} else if ( KineticEnergy<t200keV ) {
s = s200keV
* exp(0.042*Z*log(t200keV/KineticEnergy)*log(t200keV/KineticEnergy));
} else if( KineticEnergy<tmin ){
s = smin
* exp(cmin*log(tmin/KineticEnergy)*log(tmin/KineticEnergy));
} else {
s = smin + chigh*log(KineticEnergy/tmin);
}
return s * barn;
}
@@ -0,0 +1,58 @@
//
// ********************************************************************
// * 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: G4RToEConvForNeutron.cc,v 1.2 2002/12/16 11:15:45 gcosmo Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file/ History:
// 5 Oct. 2002, H.Kuirashige : Structure created based on object model
// --------------------------------------------------------------
#include "G4RToEConvForNeutron.hh"
#include "G4ParticleTable.hh"
#include "G4Material.hh"
#include "G4PhysicsLogVector.hh"
#include "G4ios.hh"
#include "g4std/iomanip"
#include "g4std/strstream"
G4RToEConvForNeutron::G4RToEConvForNeutron() : G4VRangeToEnergyConverter()
{
theParticle = G4ParticleTable::GetParticleTable()->FindParticle("neutron");
if (theParticle ==0) {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cout << " G4RToEConvForNeutron::G4RToEConvForNeutron() ";
G4cout << " Neutron is not defined !!" << G4endl;
}
#endif
}
}
G4RToEConvForNeutron::~G4RToEConvForNeutron()
{
}
@@ -0,0 +1,172 @@
//
// ********************************************************************
// * 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: G4RToEConvForPositron.cc,v 1.3 2003/01/07 23:52:24 asaim Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file/ History:
// 5 Oct. 2002, H.Kuirashige : Structure created based on object model
// --------------------------------------------------------------
#include "G4RToEConvForPositron.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTable.hh"
#include "G4Material.hh"
#include "G4PhysicsLogVector.hh"
#include "G4ios.hh"
#include "g4std/iomanip"
#include "g4std/strstream"
G4RToEConvForPositron::G4RToEConvForPositron() : G4VRangeToEnergyConverter()
{
theParticle = G4ParticleTable::GetParticleTable()->FindParticle("e+");
if (theParticle ==0) {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cout << " G4RToEConvForPositron::G4RToEConvForPositron() ";
G4cout << " Positron is not defined !!" << G4endl;
}
#endif
}
}
G4RToEConvForPositron::~G4RToEConvForPositron()
{
}
// **********************************************************************
// ************************* ComputeLoss ********************************
// **********************************************************************
G4double G4RToEConvForPositron::ComputeLoss(G4double AtomicNumber,
G4double KineticEnergy) const
{
static G4double Z;
static G4double taul, ionpot, ionpotlog;
const G4double cbr1=0.02, cbr2=-5.7e-5, cbr3=1., cbr4=0.072;
const G4double Tlow=10.*keV, Thigh=1.*GeV;
static G4double bremfactor = 0.1 ;
G4double Mass = theParticle->GetPDGMass();
// calculate dE/dx for electrons
if( abs(AtomicNumber-Z)>0.1 ) {
Z = AtomicNumber;
taul = Tlow/Mass;
ionpot = 1.6e-5*MeV*exp(0.9*log(Z))/Mass;
ionpotlog = log(ionpot);
}
G4double tau = KineticEnergy/Mass;
G4double dEdx;
if(tau<taul)
{
G4double t1 = taul+1.;
G4double t2 = taul+2.;
G4double tsq = taul*taul;
G4double beta2 = taul*t2/(t1*t1);
G4double f = 2.*log(taul)
-(6.*taul+1.5*tsq-taul*(1.-tsq/3.)/t2-tsq*(0.5-tsq/12.)/
(t2*t2))/(t1*t1);
dEdx = (log(2.*taul+4.)-2.*ionpotlog+f)/beta2;
dEdx = twopi_mc2_rcl2*Z*dEdx;
G4double clow = dEdx*sqrt(taul);
dEdx = clow/sqrt(KineticEnergy/Mass);
} else {
G4double t1 = tau+1.;
G4double t2 = tau+2.;
G4double tsq = tau*tau;
G4double beta2 = tau*t2/(t1*t1);
G4double f = 2.*log(tau)
- (6.*tau+1.5*tsq-tau*(1.-tsq/3.)/t2-tsq*(0.5-tsq/12.)/
(t2*t2))/(t1*t1);
dEdx = (log(2.*tau+4.)-2.*ionpotlog+f)/beta2;
dEdx = twopi_mc2_rcl2*Z*dEdx;
// loss from bremsstrahlung follows
G4double cbrem = (cbr1+cbr2*Z)
*(cbr3+cbr4*log(KineticEnergy/Thigh));
cbrem = Z*(Z+1.)*cbrem*tau/beta2;
cbrem *= bremfactor ;
dEdx += twopi_mc2_rcl2*cbrem;
}
return dEdx;
}
void G4RToEConvForPositron::BuildRangeVector(const G4Material* aMaterial,
G4double maxEnergy,
G4double aMass,
G4PhysicsLogVector* rangeVector)
{
// create range vector for a material
const G4double tlim = 10.*keV;
const G4int maxnbint = 100;
const G4ElementVector* elementVector = aMaterial->GetElementVector();
const G4double* atomicNumDensityVector = aMaterial->GetAtomicNumDensityVector();
G4int NumEl = aMaterial->GetNumberOfElements();
// calculate parameters of the low energy part first
size_t i;
G4double loss=0.;
for (i=0; i<size_t(NumEl); i++) {
G4bool isOut;
G4int IndEl = (*elementVector)[i]->GetIndex();
loss += atomicNumDensityVector[i]*
(*theLossTable)[IndEl]->GetValue(tlim,isOut);
}
G4double taulim = tlim/aMass;
G4double clim = sqrt(taulim)*loss;
G4double taumax = maxEnergy/aMass;
// now the range vector can be filled
for ( i=0; i<size_t(TotBin); i++) {
G4double LowEdgeEnergy = rangeVector->GetLowEdgeEnergy(i);
G4double tau = LowEdgeEnergy/aMass;
if ( tau <= taulim ) {
G4double Value = 2.*aMass*tau*sqrt(tau)/(3.*clim);
rangeVector->PutValue(i,Value);
} else {
G4double rangelim = 2.*aMass*taulim*sqrt(taulim)/(3.*clim);
G4double ltaulow = log(taulim);
G4double ltauhigh = log(tau);
G4double ltaumax = log(taumax);
G4int nbin = G4int(maxnbint*(ltauhigh-ltaulow)/(ltaumax-ltaulow));
if( nbin < 1 ) nbin = 1;
G4double Value = RangeLogSimpson(elementVector, atomicNumDensityVector,
aMass,
ltaulow, ltauhigh, nbin)
+ rangelim;
rangeVector->PutValue(i,Value);
}
}
}
@@ -0,0 +1,58 @@
//
// ********************************************************************
// * 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: G4RToEConvForProton.cc,v 1.2 2002/12/16 11:15:45 gcosmo Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file/ History:
// 5 Oct. 2002, H.Kuirashige : Structure created based on object model
// --------------------------------------------------------------
#include "G4RToEConvForProton.hh"
#include "G4ParticleTable.hh"
#include "G4Material.hh"
#include "G4PhysicsLogVector.hh"
#include "G4ios.hh"
#include "g4std/iomanip"
#include "g4std/strstream"
G4RToEConvForProton::G4RToEConvForProton() : G4VRangeToEnergyConverter()
{
theParticle = G4ParticleTable::GetParticleTable()->FindParticle("proton");
if (theParticle ==0) {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cout << " G4RToEConvForProton::G4RToEConvForProton() ";
G4cout << " proton is not defined !!" << G4endl;
}
#endif
}
}
G4RToEConvForProton::~G4RToEConvForProton()
{
}
@@ -22,7 +22,7 @@
//
//
// $Id: G4ShortLivedTable.cc,v 1.10 2001/07/11 10:02:04 gunter Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
@@ -22,7 +22,7 @@
//
//
// $Id: G4TauLeptonicDecayChannel.cc,v 1.2 2002/03/28 10:56:09 kurasige Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ------------------------------------------------------------
@@ -22,7 +22,7 @@
//
//
// $Id: G4VDecayChannel.cc,v 1.15 2002/11/20 15:05:56 gcosmo Exp $
// GEANT4 tag $Name: geant4-05-00 $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// ------------------------------------------------------------
@@ -0,0 +1,464 @@
//
// ********************************************************************
// * 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: G4VRangeToEnergyConverter.cc,v 1.3 2003/01/07 23:52:24 asaim Exp $
// GEANT4 tag $Name: geant4-05-01 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file/ History:
// 5 Oct. 2002, H.Kuirashige : Structure created based on object model
// --------------------------------------------------------------
#include "G4VRangeToEnergyConverter.hh"
#include "G4ParticleTable.hh"
#include "G4Material.hh"
#include "G4PhysicsLogVector.hh"
#include "G4ios.hh"
#include "g4std/iomanip"
#include "g4std/strstream"
// energy range
G4double G4VRangeToEnergyConverter::LowestEnergy = 0.99e-3*MeV;
G4double G4VRangeToEnergyConverter::HighestEnergy = 100.0e6*MeV;
G4VRangeToEnergyConverter::G4VRangeToEnergyConverter():
theParticle(0), theLossTable(0), NumberOfElements(0), TotBin(200),
verboseLevel(1)
{
}
G4VRangeToEnergyConverter::G4VRangeToEnergyConverter(const G4VRangeToEnergyConverter& right)
{
*this = right;
}
G4VRangeToEnergyConverter & G4VRangeToEnergyConverter::operator=(const G4VRangeToEnergyConverter &right)
{
if (this == &right) return *this;
if (theLossTable) delete theLossTable;
NumberOfElements = right.NumberOfElements;
TotBin = right.TotBin;
theParticle = right.theParticle;
verboseLevel = right.verboseLevel;
// create the loss table
theLossTable = new G4LossTable();
theLossTable->reserve(G4Element::GetNumberOfElements());
// fill the loss table
for (size_t j=0; j<size_t(NumberOfElements); j++){
G4LossVector* aVector= new
G4LossVector(LowestEnergy, HighestEnergy, TotBin);
for (size_t i=0; i<size_t(TotBin); i++) {
G4double Value = (*((*right.theLossTable)[j]))[i];
aVector->PutValue(i,Value);
}
theLossTable->insert(aVector);
}
return *this;
}
G4VRangeToEnergyConverter::~G4VRangeToEnergyConverter()
{
if (theLossTable) delete theLossTable;
}
G4int G4VRangeToEnergyConverter::operator==(const G4VRangeToEnergyConverter &right) const
{
return this == &right;
}
G4int G4VRangeToEnergyConverter::operator!=(const G4VRangeToEnergyConverter &right) const
{
return this != &right;
}
// **********************************************************************
// ************************* Convert ***********************************
// **********************************************************************
G4double G4VRangeToEnergyConverter::Convert(G4double rangeCut,
const G4Material* material)
{
//???????????? G4double Charge = theParticle->GetPDGCharge();
G4double Mass = theParticle->GetPDGMass();
G4double theKineticEnergyCuts = 0.;
// Build the energy loss table
if (theLossTable ==0) BuildLossTable();
// Build range vector for every material, convert cut into energy-cut,
// fill theKineticEnergyCuts and delete the range vector
G4double tune = 0.025*mm*g/cm3 ,lowen = 30.*keV ;
G4int idx = material->GetIndex();
G4double density = material->GetDensity() ;
if(density > 0.) {
G4RangeVector* rangeVector = new G4RangeVector(LowestEnergy, HighestEnergy, TotBin);
BuildRangeVector(material, HighestEnergy, Mass, rangeVector);
theKineticEnergyCuts = ConvertCutToKineticEnergy(rangeVector, rangeCut, idx);
if( ((theParticle->GetParticleName()=="e-")||(theParticle->GetParticleName()=="e+"))
&& (theKineticEnergyCuts < lowen) )
{ theKineticEnergyCuts /= (1.+tune/(rangeCut*density)); }
if(theKineticEnergyCuts < LowestEnergy) {
theKineticEnergyCuts = LowestEnergy ;
}
delete rangeVector;
}
return theKineticEnergyCuts;
}
// **********************************************************************
// ************************ SetEnergyRange *****************************
// **********************************************************************
void G4VRangeToEnergyConverter::SetEnergyRange(G4double lowedge,
G4double highedge)
{
// check LowestEnergy/ HighestEnergy
if ( (lowedge<0.0)||(highedge<=lowedge) ){
G4cerr << "Error in G4VRangeToEnergyConverter::SetEnergyRange";
G4cerr << " : illegal energy range" << "(" << lowedge/GeV;
G4cerr << "," << highedge/GeV << ") [GeV]" << G4endl;
} else {
LowestEnergy = lowedge;
HighestEnergy = highedge;
}
}
G4double G4VRangeToEnergyConverter::GetLowEdgeEnergy()
{
return LowestEnergy;
}
G4double G4VRangeToEnergyConverter::GetHighEdgeEnergy()
{
return HighestEnergy;
}
// **********************************************************************
// ************************ RangeLinSimpson *****************************
// **********************************************************************
G4double G4VRangeToEnergyConverter::RangeLinSimpson(
const G4ElementVector* elementVector,
const G4double* atomicNumDensityVector,
G4double aMass,
G4double taulow, G4double tauhigh, G4int nbin)
{
// Simpson numerical integration, linear binning
G4double dtau = (tauhigh-taulow)/nbin;
G4double Value=0.;
for (size_t i=0; i<=size_t(nbin); i++){
G4double taui=taulow+dtau*i;
G4double ti=aMass*taui;
G4double lossi=0.;
size_t nEl = elementVector->size();
for (size_t j=0; j<nEl; j++) {
G4bool isOut;
G4int IndEl = (*elementVector)[j]->GetIndex();
lossi += atomicNumDensityVector[j]*
(*theLossTable)[IndEl]->GetValue(ti,isOut);
}
if ( i==0 ) {
Value += 0.5/lossi;
} else {
if ( i<size_t(nbin) ) Value += 1./lossi;
else Value += 0.5/lossi;
}
}
Value *= aMass*dtau;
return Value;
}
// **********************************************************************
// ************************ RangeLogSimpson *****************************
// **********************************************************************
G4double G4VRangeToEnergyConverter::RangeLogSimpson(
const G4ElementVector* elementVector,
const G4double* atomicNumDensityVector,
G4double aMass,
G4double ltaulow, G4double ltauhigh,
G4int nbin)
{
// Simpson numerical integration, logarithmic binning
if(nbin<0) nbin = TotBin;
G4double ltt = ltauhigh-ltaulow;
G4double dltau = ltt/nbin;
G4double Value = 0.;
for (size_t i=0; i<=size_t(nbin); i++){
G4double ui = ltaulow+dltau*i;
G4double taui = exp(ui);
G4double ti = aMass*taui;
G4double lossi = 0.;
size_t nEl = elementVector->size();
for (size_t j=0; j<nEl; j++) {
G4bool isOut;
G4int IndEl = (*elementVector)[j]->GetIndex();
lossi += atomicNumDensityVector[j]*
(*theLossTable)[IndEl]->GetValue(ti,isOut);
}
if ( i==0 ) {
Value += 0.5*taui/lossi;
} else {
if ( i<size_t(nbin) ) Value += taui/lossi;
else Value += 0.5*taui/lossi;
}
}
Value *= aMass*dltau;
return Value;
}
// **********************************************************************
// ************************ BuildLossTable ******************************
// **********************************************************************
// create Energy Loss Table for charged particles
// (cross section tabel for neutral )
void G4VRangeToEnergyConverter::BuildLossTable()
{
// Build dE/dx tables for elements
if (size_t(NumberOfElements) != G4Element::GetNumberOfElements()) {
if (theLossTable!=0) delete theLossTable;
theLossTable =0;
NumberOfElements = 0;
}
if (NumberOfElements ==0) {
NumberOfElements = G4Element::GetNumberOfElements();
theLossTable = new G4LossTable();
theLossTable->reserve(G4Element::GetNumberOfElements());
#ifdef G4VERBOSE
if (GetVerboseLevel()>2) {
G4cout << "G4VRangeToEnergyConverter::BuildLossTable() ";
G4cout << "Create theLossTable[" << theLossTable << "]";
G4cout << " NumberOfElements=" << NumberOfElements <<G4endl;
}
#endif
}
// fill the loss table
for (size_t j=0; j<size_t(NumberOfElements); j++){
G4double Value;
G4LossVector* aVector= new
G4LossVector(LowestEnergy, HighestEnergy, TotBin);
for (size_t i=0; i<size_t(TotBin); i++) {
Value = ComputeLoss( (*G4Element::GetElementTable())[j]->GetZ(),
aVector->GetLowEdgeEnergy(i)
);
aVector->PutValue(i,Value);
}
theLossTable->insert(aVector);
}
}
// **********************************************************************
// ************************** ComputeLoss *******************************
// **********************************************************************
G4double G4VRangeToEnergyConverter::ComputeLoss(G4double AtomicNumber,
G4double KineticEnergy) const
{
// calculate dE/dx
static G4double Z;
static G4double ionpot, tau0, taum, taul, ca, cba, cc;
G4double z2Particle = theParticle->GetPDGCharge()/eplus;
z2Particle *= z2Particle;
if (z2Particle < 0.1) return 0.0;
if( abs(AtomicNumber-Z)>0.1 ){
// recalculate constants
Z = AtomicNumber;
G4double Z13 = exp(log(Z)/3.);
tau0 = 0.1*Z13*MeV/proton_mass_c2;
taum = 0.035*Z13*MeV/proton_mass_c2;
taul = 2.*MeV/proton_mass_c2;
ionpot = 1.6e-5*MeV*exp(0.9*log(Z));
cc = (taul+1.)*(taul+1.)*log(2.*electron_mass_c2*taul*(taul+2.)/ionpot)/(taul*(taul+2.))-1.;
cc = 2.*twopi_mc2_rcl2*Z*cc*sqrt(taul);
ca = cc/((1.-0.5*sqrt(tau0/taum))*tau0);
cba = -0.5/sqrt(taum);
}
G4double tau = KineticEnergy/theParticle->GetPDGMass();
G4double dEdx;
if ( tau <= tau0 ) {
dEdx = ca*(sqrt(tau)+cba*tau);
} else {
if( tau <= taul ) {
dEdx = cc/sqrt(tau);
} else {
dEdx = (tau+1.)*(tau+1.)*
log(2.*electron_mass_c2*tau*(tau+2.)/ionpot)/(tau*(tau+2.))-1.;
dEdx = 2.*twopi_mc2_rcl2*Z*dEdx;
}
}
return dEdx*z2Particle ;
}
// **********************************************************************
// ************************ BuildRangeVector ****************************
// **********************************************************************
void G4VRangeToEnergyConverter::BuildRangeVector(
const G4Material* aMaterial,
G4double maxEnergy,
G4double aMass,
G4RangeVector* rangeVector)
{
// create range vector for a material
const G4double tlim=2.*MeV, t1=0.1*MeV, t2=0.025*MeV;
const G4int maxnbint=100;
const G4ElementVector* elementVector = aMaterial->GetElementVector();
const G4double* atomicNumDensityVector = aMaterial->GetAtomicNumDensityVector();
G4int NumEl = aMaterial->GetNumberOfElements();
// calculate parameters of the low energy part first
G4double loss1=0.;
G4double loss2=0.;
size_t i;
for (i=0; i<size_t(NumEl); i++) {
G4bool isOut;
G4int IndEl = (*elementVector)[i]->GetIndex();
loss1 += atomicNumDensityVector[i]*
(*theLossTable)[IndEl]->GetValue(t1,isOut);
loss2 += atomicNumDensityVector[i]*
(*theLossTable)[IndEl]->GetValue(t2,isOut);
}
G4double tau1 = t1/proton_mass_c2;
G4double sqtau1 = sqrt(tau1);
G4double ca = (4.*loss2-loss1)/sqtau1;
G4double cb = (2.*loss1-4.*loss2)/tau1;
G4double cba = cb/ca;
G4double taulim = tlim/proton_mass_c2;
G4double taumax = maxEnergy/aMass;
G4double ltaumax = log(taumax);
// now we can fill the range vector....
G4double rmax = 0.0;
for (i=0; i<size_t(TotBin); i++) {
G4double LowEdgeEnergy = rangeVector->GetLowEdgeEnergy(i);
G4double tau = LowEdgeEnergy/aMass;
G4double Value;
if ( tau <= tau1 ){
Value =2.*aMass*log(1.+cba*sqrt(tau))/cb;
} else {
Value = 2.*aMass*log(1.+cba*sqtau1)/cb;
if ( tau <= taulim ) {
G4int nbin = (G4int)(maxnbint*(tau-tau1)/(taulim-tau1));
if ( nbin<1 ) nbin = 1;
Value += RangeLinSimpson(elementVector,atomicNumDensityVector,
aMass,
tau1, tau, nbin);
} else {
Value += RangeLinSimpson(elementVector,atomicNumDensityVector,
aMass,
tau1, taulim, maxnbint);
G4double ltaulow = log(taulim);
G4double ltauhigh = log(tau);
G4int nbin = (G4int)(maxnbint*(ltauhigh-ltaulow)/(ltaumax-ltaulow));
if ( nbin<1 ) nbin = 1;
Value += RangeLogSimpson(elementVector,atomicNumDensityVector,
aMass,
ltaulow, ltauhigh, nbin);
}
}
rangeVector->PutValue(i,Value);
if (rmax < Value) rmax = Value;
}
}
// **********************************************************************
// ****************** ConvertCutToKineticEnergy *************************
// **********************************************************************
G4double G4VRangeToEnergyConverter::ConvertCutToKineticEnergy(
G4RangeVector* rangeVector,
G4double theCutInLength,
size_t materialIndex
) const
{
const G4double epsilon=0.01;
// find max. range and the corresponding energy (rmax,Tmax)
G4double rmax= -1.e10*mm;
G4double Tmax= HighestEnergy;
G4double fac = exp( log(HighestEnergy/LowestEnergy)/TotBin );
G4double T=LowestEnergy/fac;
G4bool isOut;
for (size_t ibin=0; ibin<size_t(TotBin); ibin++) {
T *= fac;
G4double r=rangeVector->GetValue(T,isOut);
if ( r>rmax ) {
Tmax=T;
rmax=r;
}
}
// check cut in length is smaller than range max
if ( theCutInLength >= rmax ) {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cout << "G4VRangeToEnergyConverter::ConvertCutToKineticEnergy ";
G4cout << " for " << theParticle->GetParticleName() << G4endl;
G4cout << "The cut in range [" << theCutInLength/mm << " (mm)] ";
G4cout << " is too big " << G4endl;
G4cout << "The cut in energy is set" << DBL_MAX/GeV << "GeV " <<G4endl;
}
#endif
return DBL_MAX;
}
// convert range to energy
G4double T1 = LowestEnergy;
G4double r1 = rangeVector->GetValue(T1,isOut);
if ( theCutInLength <= r1 )
{
return T1;
}
G4double T2 = Tmax ;
G4double T3 = sqrt(T1*T2);
G4double r3 = rangeVector->GetValue(T3,isOut);
while ( abs(1.-r3/theCutInLength)>epsilon ) {
if ( theCutInLength <= r3 ) {
T2 = T3;
} else {
T1 = T3;
}
T3 = sqrt(T1*T2);
r3 = rangeVector->GetValue(T3,isOut);
}
return T3;
}