Import Geant4 0.0.0 source tree

This commit is contained in:
Gabriele Cosmo
2016-06-01 15:25:35 +02:00
parent 54d6b71f95
commit b97f8d0df7
3237 changed files with 807095 additions and 0 deletions
@@ -0,0 +1,156 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4DalitzDecayChannel.cc,v 2.4 1998/11/18 09:46:32 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
//
// For information related to this code contact:
// CERN, CN Division, ASD group
// History: first implementation, based on object model of
// 30 May 1997 H.Kurashige
// ------------------------------------------------------------
#include "G4ParticleDefinition.hh"
#include "G4DecayProducts.hh"
#include "G4VDecayChannel.hh"
#include "G4DalitzDecayChannel.hh"
#include "G4PhaseSpaceDecayChannel.hh"
#include "Randomize.hh"
#include "G4LorentzVector.hh"
#include "G4LorentzRotation.hh"
G4DalitzDecayChannel::G4DalitzDecayChannel(
const G4String& theParentName,
G4double theBR,
const G4String& theLeptonName,
const G4String& theAntiLeptonName)
:G4VDecayChannel("Dalitz Decay",1)
{
//#ifdef G4VERBOSE
//if (GetVerboseLevel()>1) {
// G4cout << "G4DalitzDecayChannel:: constructor ";
// G4cout << "addr[" << this << "]" << endl;
//}
//#endif
// set names for daughter particles
SetParent(theParentName);
SetBR(theBR);
SetNumberOfDaughters(3);
SetDaughter(idGamma, "gamma");
SetDaughter(idLepton, theLeptonName);
SetDaughter(idAntiLepton, theAntiLeptonName);
//
//#ifdef G4VERBOSE
//if (GetVerboseLevel()>1) DumpInfo();
//#endif
}
G4DalitzDecayChannel::~G4DalitzDecayChannel()
{
}
G4DecayProducts *G4DalitzDecayChannel::DecayIt(G4double)
{
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) G4cout << "G4DalitzDecayChannel::DecayIt ";
#endif
if (parent == NULL) FillParent();
if (daughters == NULL) FillDaughters();
// parent mass
G4double parentmass = parent->GetPDGMass();
//create parent G4DynamicParticle at rest
G4ParticleMomentum dummy;
G4DynamicParticle * parentparticle = new G4DynamicParticle( parent, dummy, 0.0);
//daughters'mass
G4double leptonmass = daughters[idLepton]->GetPDGMass();
// Generate t ( = exp(x):mass Square of (l+ l-) system)
G4double xmin = 2.0*log(2.0*leptonmass);
G4double xmax = 2.0*log(parentmass);
G4double wmax = 1.5;
G4double x, w, ww, w1, w2, w3, t;
do {
x = G4UniformRand()*(xmax-xmin) + xmin;
w = G4UniformRand()*wmax;
t = exp(x);
w1 = (1.0-4.0*leptonmass*leptonmass/t);
if ( w1 > 0.0) {
w2 = ( 1.0 + 2.0*leptonmass*leptonmass/t );
w3 = ( 1.0 - t/parentmass/parentmass );
w3 = w3 * w3 * w3;
ww = w3 * w2 * sqrt(w1);
} else {
ww = 0.0;
}
} while (w > ww);
// calculate gamma momentum
G4double Pgamma =
G4PhaseSpaceDecayChannel::Pmx(parentmass, 0.0, sqrt(t));
G4double costheta = 2.*G4UniformRand()-1.0;
G4double sintheta = sqrt((1.0 - costheta)*(1.0 + costheta));
G4double phi = 2.0*M_PI*G4UniformRand()*rad;
G4ParticleMomentum gdirection(sintheta*cos(phi),sintheta*sin(phi),costheta);
//create G4DynamicParticle for gamma
G4DynamicParticle * gammaparticle
= new G4DynamicParticle(daughters[idGamma] , gdirection, Pgamma);
// calcurate beta of (l+ l-)system
G4double beta = Pgamma/(parentmass-Pgamma);
// calculate lepton momentum in the rest frame of (l+ l-)system
G4double Plepton =
G4PhaseSpaceDecayChannel::Pmx(sqrt(t),leptonmass, leptonmass);
G4double Elepton = sqrt(Plepton*Plepton + leptonmass*leptonmass );
costheta = 2.*G4UniformRand()-1.0;
sintheta = sqrt((1.0 - costheta)*(1.0 + costheta));
phi = 2.0*M_PI*G4UniformRand()*rad;
G4ParticleMomentum ldirection(sintheta*cos(phi),sintheta*sin(phi),costheta);
//create G4DynamicParticle for leptons in the rest frame of (l+ l-)system
G4DynamicParticle * leptonparticle
= new G4DynamicParticle(daughters[idLepton] ,
ldirection, Elepton-leptonmass );
G4DynamicParticle * antileptonparticle
= new G4DynamicParticle(daughters[idAntiLepton] ,
-1.0*ldirection, Elepton-leptonmass );
//boost leptons in the rest frame of the parent
G4LorentzVector p4 = leptonparticle->Get4Momentum();
p4.boost( -1.0*gdirection.x()*beta, -1.0*gdirection.y()*beta, -1.0*gdirection.z()*beta);
leptonparticle->Set4Momentum(p4);
p4 = antileptonparticle->Get4Momentum();
p4.boost( -1.0*gdirection.x()*beta, -1.0*gdirection.y()*beta, -1.0*gdirection.z()*beta);
antileptonparticle->Set4Momentum(p4);
//create G4Decayproducts
G4DecayProducts *products = new G4DecayProducts(*parentparticle);
delete parentparticle;
products->PushProducts(gammaparticle);
products->PushProducts(leptonparticle);
products->PushProducts(antileptonparticle);
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cout << "G4DalitzDecayChannel::DecayIt ";
G4cout << " create decay products in rest frame " <<endl;
products->DumpInfo();
}
#endif
return products;
}
@@ -0,0 +1,275 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4DecayProducts.cc,v 2.2 1998/11/13 17:04:39 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
//
// For information related to this code contact:
// CERN, CN Division, ASD group
// History: first implementation, based on object model of
// 10 July 1996 H.Kurashige
// 21 Oct 1996 H.Kurashige
// 12 Dec 1997 H.Kurashige
// ------------------------------------------------------------
#include "G4ios.hh"
#include "globals.hh"
#include "G4DecayProducts.hh"
#include "G4LorentzVector.hh"
#include "G4LorentzRotation.hh"
G4Allocator<G4DecayProducts> aDecayProductsAllocator;
G4DecayProducts::G4DecayProducts()
:numberOfProducts(0),theParentParticle(NULL)
{
}
G4DecayProducts::G4DecayProducts(const G4DynamicParticle &aParticle)
:numberOfProducts(0),theParentParticle(NULL)
{
theParentParticle = new G4DynamicParticle(aParticle);
}
G4DecayProducts::G4DecayProducts(const G4DecayProducts &right)
:numberOfProducts(0)
{
// copy parent (Deep Copy)
theParentParticle = new G4DynamicParticle(*right.theParentParticle);
//copy daughters (Deep Copy)
for (G4int index=0; index < right.numberOfProducts; index++)
{
PushProducts( new G4DynamicParticle(*right.theProductVector[index]) );
}
}
G4DecayProducts & G4DecayProducts::operator=(const G4DecayProducts &right)
{
G4int index;
if (this != &right)
{
// recreate parent
if (theParentParticle != NULL) delete theParentParticle;
theParentParticle = new G4DynamicParticle(*right.theParentParticle);
// delete G4DynamicParticle objects
for (index=0; index < numberOfProducts; index++)
{
delete theProductVector[index];
}
//copy daughters (Deep Copy)
for (index=0; index < right.numberOfProducts; index++) {
PushProducts( new G4DynamicParticle(*right.theProductVector[index]) );
}
numberOfProducts = right.numberOfProducts;
}
return *this;
}
G4DecayProducts::~G4DecayProducts()
{
//delete parent
if (theParentParticle != NULL) delete theParentParticle;
// delete G4DynamicParticle object
for (G4int index=0; index < numberOfProducts; index++)
{
delete theProductVector[index];
}
numberOfProducts = 0;
}
G4DynamicParticle* G4DecayProducts::PopProducts()
{
if ( numberOfProducts >0 ) {
numberOfProducts -= 1;
return theProductVector[numberOfProducts];
} else {
return NULL;
}
}
G4int G4DecayProducts::PushProducts(G4DynamicParticle *aParticle)
{
if ( numberOfProducts < MaxNumberOfProducts) {
theProductVector[numberOfProducts]= aParticle;
numberOfProducts += 1;
} else {
#ifdef G4VERBOSE
G4cerr << "G4DecayProducts::PushProducts ";
G4cerr << " exceeds MaxNumberOfProducts(=" <<MaxNumberOfProducts << ")";
G4cerr << endl;
#endif
}
return numberOfProducts;
}
G4DynamicParticle* G4DecayProducts::operator[](G4int anIndex) const
{
if ((numberOfProducts > anIndex) && (anIndex >=0) ) {
return theProductVector[anIndex];
} else {
return NULL;
}
}
void G4DecayProducts::SetParentParticle(const G4DynamicParticle &aParticle)
{
if (theParentParticle != NULL) delete theParentParticle;
theParentParticle = new G4DynamicParticle(aParticle);
}
void G4DecayProducts::Boost(G4double totalEnergy, const G4ParticleMomentum &momentumDirection)
{
// calcurate new beta
G4double mass = theParentParticle->GetMass();
G4double totalMomentum = sqrt( (totalEnergy - mass)*(totalEnergy + mass) );
G4double betax = momentumDirection.x()*totalMomentum/totalEnergy;
G4double betay = momentumDirection.y()*totalMomentum/totalEnergy;
G4double betaz = momentumDirection.z()*totalMomentum/totalEnergy;
this->Boost(betax, betay, betaz);
}
void G4DecayProducts::Boost(G4double newbetax, G4double newbetay, G4double newbetaz)
{
G4double mass = theParentParticle->GetMass();
G4double energy = theParentParticle->GetTotalEnergy();
G4double momentum = 0.0;
G4ParticleMomentum direction(0.0,0.0,1.0);
G4LorentzVector p4;
if (energy - mass > DBL_MIN) {
// calcurate beta of initial state
momentum = theParentParticle->GetTotalMomentum();
direction = theParentParticle->GetMomentumDirection();
G4double betax = -1.0*direction.x()*momentum/energy;
G4double betay = -1.0*direction.y()*momentum/energy;
G4double betaz = -1.0*direction.z()*momentum/energy;
for (G4int index=0; index < numberOfProducts; index++) {
// make G4LorentzVector for secondaries
p4 = theProductVector[index]->Get4Momentum();
// boost secondaries to theParentParticle's rest frame
p4.boost(betax, betay, betaz);
// boost secondaries to new frame
p4.boost(newbetax, newbetay, newbetaz);
// change energy/momentum
theProductVector[index]->Set4Momentum(p4);
}
} else {
for (G4int index=0; index < numberOfProducts; index++) {
// make G4LorentzVector for secondaries
p4 = theProductVector[index]->Get4Momentum();
// boost secondaries to new frame
p4.boost(newbetax, newbetay, newbetaz);
// change energy/momentum
theProductVector[index]->Set4Momentum(p4);
}
}
// make G4LorentzVector for parent in its rest frame
mass = theParentParticle->GetMass();
G4LorentzVector parent4( 0.0, 0.0, 0.0, mass);
// boost parent to new frame
parent4.boost(newbetax, newbetay, newbetaz);
// change energy/momentum
theParentParticle->Set4Momentum(parent4);
}
G4bool G4DecayProducts::IsChecked()
{
G4bool returnValue = true;
// check parent
// energy/momentum
G4double parent_mass = theParentParticle->GetMass();
G4double parent_energy = theParentParticle->GetTotalEnergy();
G4ParticleMomentum direction = theParentParticle->GetMomentumDirection();
G4ThreeVector parent_momentum = direction*(theParentParticle->GetTotalMomentum());
// check momentum dirction is a unit vector
if ( (parent_momentum.mag() >0.0) && (abs(direction.mag()-1.0) >1.0e-6 ) ) {
#ifdef G4VERBOSE
G4cout << " Momentum Direction Vector of Parent is not normalized ";
G4cout << " (=" << direction.mag() << ")" << endl;
#endif
returnValue = false;
parent_momentum = parent_momentum * (1./direction.mag());
}
//daughters
G4double mass, energy;
G4ThreeVector momentum;
G4double total_energy = parent_energy;
G4ThreeVector total_momentum = parent_momentum;
for (G4int index=0; index < numberOfProducts; index++)
{
mass = theProductVector[index]->GetMass();
energy = theProductVector[index]->GetTotalEnergy();
direction = theProductVector[index]->GetMomentumDirection();
momentum = direction*(theProductVector[index]->GetTotalMomentum());
// check momentum dirction is a unit vector
if ( (momentum.mag()>0.0) && (abs(direction.mag()-1.0) > 1.0e-6)) {
#ifdef G4VERBOSE
G4cout << " Momentum Direction Vector of Daughter [" << index;
G4cout << "] is not normalized (=" << direction.mag() << ")" << endl;
#endif
returnValue = false;
momentum = momentum * (1./direction.mag());
}
// whether daughter stops or not
if (energy - mass < DBL_MIN ) {
#ifdef G4VERBOSE
G4cout << "Daughter [" << index << "] has no kinetic energy "<< endl;
#endif
returnValue = false;
}
total_energy -= energy;
total_momentum -= momentum;
}
// check energy/momentum conservation
if ( (abs(total_energy) >1.0e-6) || (total_momentum.mag() >1.0e-6 ) ){
#ifdef G4VERBOSE
G4cout << " Energy/Momentum is not conserved ";
G4cout << total_energy << " " << total_momentum << endl;
#endif
returnValue = false;
}
return returnValue;
}
void G4DecayProducts::DumpInfo()
{
G4cout << " ----- List of DecayProducts -----" << endl;
G4cout << " ------ Parent Particle ----------" << endl;
if (theParentParticle != NULL) theParentParticle->DumpInfo();
G4cout << " ------ Daughter Particles ------" << endl;
for (G4int index=0; index < numberOfProducts; index++)
{
G4cout << " ----------" << index+1 << " -------------" << endl;
theProductVector[index]-> DumpInfo();
}
G4cout << " ----- End List of DecayProducts -----" << endl;
G4cout << endl;
}
@@ -0,0 +1,95 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4DecayTable.cc,v 2.2 1998/10/13 11:25:40 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 class implementation file
//
// For information related to this code contact:
// CERN, CN Division, ASD group
// History: first implementation, based on object model of
// 2nd December 1995, G.Cosmo
// 27 July 1996 H.Kurashige
// ------------------------------------------------------------
#include "G4DecayTable.hh"
#include "Randomize.hh"
G4DecayTable::G4DecayTable():parent(NULL)
{
channels = new G4VDecayChannelVector;
}
G4DecayTable::~G4DecayTable()
{
channels->clearAndDestroy();
delete channels;
}
void G4DecayTable::Insert( G4VDecayChannel * aChannel){
if (parent == NULL) { parent = aChannel->GetParent(); }
if (parent != aChannel->GetParent()) {
#ifdef G4VERBOSE
G4cerr << " G4DecayTable::Insert :: bad G4VDecayChannel (mismatch parent) ";
G4cerr << " " << parent->GetParticleName();
G4cerr << " input:" << aChannel->GetParent()->GetParticleName() << endl;
#endif
} else {
channels->insert(aChannel);
}
}
G4VDecayChannel *G4DecayTable::SelectADecayChannel()
{
// make cumlative table for branching ratio
G4double sumBR = 0.0;
G4int index;
G4int numberofchannels = channels->entries();
G4double *cumBR = new G4double[numberofchannels];
for (index=numberofchannels-1; index >=0 ; index--) {
sumBR += ((*channels)(index))->GetBR();
cumBR[index] = sumBR;
}
// select decay channel
G4double r = sumBR* G4UniformRand();
G4VDecayChannel *channel;
for (index= numberofchannels-1; index >=0 ; index--) {
if (r < cumBR[index]) {
channel = (*channels)(index);
break;
}
}
delete [] cumBR;
return channel;
}
void G4DecayTable::DumpInfo() const
{
G4cout << "G4DecayTable: " << parent->GetParticleName() << endl;
G4int numberofchannels = channels->entries();
for (G4int index= numberofchannels -1; index >=0 ; index -=1)
{
G4cout << index << ": ";
((*channels)(index))->DumpInfo();
}
G4cout << endl;
}
@@ -0,0 +1,185 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4DecayTableMessenger.cc,v 2.3 1998/07/13 17:18:38 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
//---------------------------------------------------------------
//
// G4DecayTableMessenger.cc
//
// Description:
// This is a messenger class to interface to exchange information
// between ParticleDefinition and UI.
//
// History:
// 13 June 1997, H. Kurashige : The 1st version created.
// 10 Nov. 1997 H. Kurashige : fixed bugs
// 08 jan. 1998 H. Kurashige : new UIcommnds
//
//---------------------------------------------------------------
#include "G4DecayTableMessenger.hh"
#include "G4UImanager.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithADouble.hh"
#include "G4VDecayChannel.hh"
#include "G4DecayTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticleTable.hh"
#include "G4ios.hh" // Include from 'system'
#include <iomanip.h> // Include from 'system'
G4DecayTableMessenger::G4DecayTableMessenger(G4ParticleTable* pTable)
:theParticleTable(pTable)
{
if ( theParticleTable == NULL) theParticleTable = G4ParticleTable::GetParticleTable();
currentParticle = NULL;
//Commnad /particle/property/decay/
thisDirectory = new G4UIdirectory("/particle/property/decay/");
thisDirectory->SetGuidance("Decay Table control commands.");
//Commnad /particle/property/decay/select
selectCmd = new G4UIcmdWithAnInteger("/particle/property/decay/select",this);
selectCmd->SetGuidance("Enter index of decay mode.");
selectCmd->SetParameterName("mode", true);
selectCmd->SetDefaultValue(0);
selectCmd->SetRange("mode >=0");
currentChannel = NULL;
//Commnad /particle/property/decay/dump
dumpCmd = new G4UIcmdWithoutParameter("/particle/property/decay/dump",this);
dumpCmd->SetGuidance("Dump decay mode information.");
//Command /particle/property/decay/br
brCmd = new G4UIcmdWithADouble("/particle/property/decay/br",this);
brCmd->SetGuidance("Set branching ratio. [0< BR <1.0]");
brCmd->SetParameterName("br",false);
brCmd->SetRange("(br >=0.0) && (br <=1.0)");
}
G4DecayTableMessenger::~G4DecayTableMessenger()
{
delete dumpCmd;
delete selectCmd;
delete brCmd;
delete thisDirectory;
}
void G4DecayTableMessenger::SetNewValue(G4UIcommand * command,G4String newValue)
{
if (SetCurrentParticle()==NULL) {
G4cout << "Particle is not selected yet !! Command ignored." << endl;
return;
}
if (currentDecayTable==NULL) {
G4cout << "The particle has no decay table !! Command ignored." << endl;
return;
}
if( command == dumpCmd ){
//Commnad /particle/property/decay/dump
currentDecayTable->DumpInfo();
} else if ( command == selectCmd ){
//Commnad /particle/property/decay/select
G4int index = selectCmd->GetNewIntValue(newValue) ;
currentChannel = currentDecayTable->GetDecayChannel(index);
if ( currentChannel == NULL ) {
G4cout << "Invalid index. Command ignored." << endl;
} else {
idxCurrentChannel = index;
}
} else {
if ( currentChannel == NULL ) {
G4cout << "Select a decay channel. Command ignored." << endl;
return;
}
if (command == brCmd) {
//Commnad /particle/property/decay/br
G4double br = brCmd->GetNewDoubleValue(newValue);
if( (br<0.0) || (br>1.0) ) {
G4cout << "Invalid brancing ratio. Command ignored." << endl;
} else {
currentChannel->SetBR(br);
}
}
}
}
G4ParticleDefinition* G4DecayTableMessenger::SetCurrentParticle()
{
// set currentParticle pointer
// get particle name by asking G4ParticleMessenger via UImanager
G4String particleName = G4UImanager::GetUIpointer()->GetCurrentStringValue("/particle/select");
if (currentParticle != NULL ){
// check whether selection is changed
if (currentParticle->GetParticleName() != particleName) {
currentParticle = theParticleTable->FindParticle(particleName);
idxCurrentChannel = -1;
currentDecayTable = NULL;
} else {
// no change
return currentParticle;
}
} else {
currentParticle = theParticleTable->FindParticle(particleName);
idxCurrentChannel = -1;
currentDecayTable = NULL;
}
if (currentParticle != NULL ){
currentDecayTable = currentParticle->GetDecayTable();
if ((currentDecayTable != NULL ) && (idxCurrentChannel >0) ) {
currentChannel = currentDecayTable->GetDecayChannel(idxCurrentChannel);
} else {
idxCurrentChannel = -1;
currentChannel = NULL;
}
}
return currentParticle;
}
G4String G4DecayTableMessenger::GetCurrentValue(G4UIcommand * command)
{
G4String returnValue('\0');
if (SetCurrentParticle()==NULL) {
// no particle is selected. return null
return returnValue;
}
if( command == selectCmd ){
//Commnad /particle/property/decay/select
returnValue = selectCmd->ConvertToString(idxCurrentChannel);
} else if( command == brCmd ){
if ( currentChannel != NULL) {
returnValue = brCmd->ConvertToString(currentChannel->GetBR());
}
}
return returnValue;
}
@@ -0,0 +1,274 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4DynamicParticle.cc,v 2.4 1998/11/25 13:59:04 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
//
// For information related to this code contact:
// CERN, CN Division, ASD Group
// History: first implementation, based on object model of
// 2nd December 1995, G.Cosmo
// ---------------- G4DynamicParticle ----------------
// first implementation by Makoto Asai, 29 January 1996
// revised by G.Cosmo, 29 February 1996
// revised by H.Kurashige 06 May 1996
// revised by Hisaya Kurashige, 27 July 1996
// modify thePreAssignedDecayProducts
// add void SetMomentum(G4ThreeVector &momentum)
// add void Set4Momentum(G4LorentzVector &momentum)
// add G4DynamicParticle(G4ParticleDefinition * aParticleDefinition,
// G4LorentzVector &p4vector)
// revised by Hisaya Kurashige, 19 Oct 1996
// add theKillProcess
// add ProperTime
// revised by Hisaya Kurashige, 26 Mar 1997
// modify destructor
// revised by Hisaya Kurashige, 05 June 1997
// modify DumpInfo()
// revised by Hisaya Kurashige, 5 June 1998
// remove theKillProcess
//--------------------------------------------------------------
#include "G4DynamicParticle.hh"
#include "G4DecayProducts.hh"
#include "G4LorentzVector.hh"
#include "G4ParticleDefinition.hh"
G4Allocator<G4DynamicParticle> aDynamicParticleAllocator;
static const G4double EnergyMomentumRelationAllowance = keV;
G4DynamicParticle::G4DynamicParticle():
theParticleDefinition(NULL),
theMomentumDirection(),
theKineticEnergy(0.0),
theProperTime(0.0),
thePreAssignedDecayProducts(NULL),
verboseLevel(1)
{
theDynamicalMass = 0.0;
}
// -- constructors ----
G4DynamicParticle::G4DynamicParticle(G4ParticleDefinition * aParticleDefinition,
const G4ParticleMomentum& aMomentumDirection,
G4double aKineticEnergy):
theParticleDefinition(aParticleDefinition),
theMomentumDirection(aMomentumDirection),
theKineticEnergy(aKineticEnergy),
theProperTime(0.0),
thePreAssignedDecayProducts(NULL),
verboseLevel(1)
{
theDynamicalMass = aParticleDefinition->GetPDGMass();
}
G4DynamicParticle::G4DynamicParticle(G4ParticleDefinition * aParticleDefinition,
const G4ThreeVector& aParticleMomentum):
theParticleDefinition(aParticleDefinition),
theProperTime(0.0),
thePreAssignedDecayProducts(NULL),
verboseLevel(1)
{
theDynamicalMass = aParticleDefinition->GetPDGMass();
G4double pModule2 = aParticleMomentum.mag2();
if (pModule2>0.0) {
G4double mass = theDynamicalMass;
SetKineticEnergy(sqrt(pModule2+mass*mass)-mass);
G4double pModule = sqrt(pModule2);
SetMomentumDirection(aParticleMomentum.x()/pModule,
aParticleMomentum.y()/pModule,
aParticleMomentum.z()/pModule);
} else {
SetMomentumDirection(1.0,0.0,0.0);
SetKineticEnergy(0.0);
}
}
G4DynamicParticle::G4DynamicParticle(G4ParticleDefinition * aParticleDefinition,
const G4LorentzVector &aParticleMomentum):
theParticleDefinition(aParticleDefinition),
theProperTime(0.0),
thePreAssignedDecayProducts(NULL),
verboseLevel(1)
{
theDynamicalMass = aParticleDefinition->GetPDGMass();
G4double pModule2 = aParticleMomentum.x()*aParticleMomentum.x()
+ aParticleMomentum.y()*aParticleMomentum.y()
+ aParticleMomentum.z()*aParticleMomentum.z();
if (pModule2>0.0) {
G4double pModule = sqrt(pModule2);
SetMomentumDirection(aParticleMomentum.x()/pModule,
aParticleMomentum.y()/pModule,
aParticleMomentum.z()/pModule);
G4double totalenergy = aParticleMomentum.t();
if (totalenergy > pModule) {
G4double mass = sqrt(totalenergy*totalenergy - pModule2);
theDynamicalMass = mass;
SetKineticEnergy(totalenergy-mass);
} else {
theDynamicalMass = 0.;
SetKineticEnergy(totalenergy);
}
} else {
SetMomentumDirection(1.0,0.0,0.0);
SetKineticEnergy(0.0);
}
}
G4DynamicParticle::G4DynamicParticle(G4ParticleDefinition * aParticleDefinition,
G4double totalEnergy,
const G4ThreeVector &aParticleMomentum):
theParticleDefinition(aParticleDefinition),
thePreAssignedDecayProducts(NULL),
theProperTime(0.0),
verboseLevel(1)
{
theDynamicalMass = aParticleDefinition->GetPDGMass();
G4double pModule2 = aParticleMomentum.mag2();
if (pModule2>0.0) {
G4double pModule = sqrt(pModule2);
SetMomentumDirection(aParticleMomentum.x()/pModule,
aParticleMomentum.y()/pModule,
aParticleMomentum.z()/pModule);
if (totalEnergy > pModule2) {
G4double mass = sqrt(totalEnergy*totalEnergy - pModule2);
theDynamicalMass = mass;
SetKineticEnergy(totalEnergy-mass);
} else {
theDynamicalMass = 0.;
SetKineticEnergy(totalEnergy);
}
} else {
SetMomentumDirection(1.0,0.0,0.0);
SetKineticEnergy(0.0);
}
}
G4DynamicParticle::G4DynamicParticle(const G4DynamicParticle &right)
{
SetMass(right.theDynamicalMass);
SetDefinition(right.GetDefinition());
theMomentumDirection = right.GetMomentumDirection();
theKineticEnergy = right.GetKineticEnergy();
thePolarization = right.GetPolarization();
verboseLevel = right.GetVerboseLevel();
// proper time is set to zero
theProperTime = 0.0;
// thePreAssignedDecayProducts must not be copied.
thePreAssignedDecayProducts = NULL;
}
// -- destructor ----
G4DynamicParticle::~G4DynamicParticle() {
// delete thePreAssignedDecayProducts
if (thePreAssignedDecayProducts != NULL) delete thePreAssignedDecayProducts;
thePreAssignedDecayProducts = NULL;
}
G4DynamicParticle & G4DynamicParticle::operator=(const G4DynamicParticle &right)
{
if (this != &right) {
SetDefinition(right.GetDefinition());
SetMass(right.theDynamicalMass);
theMomentumDirection = right.GetMomentumDirection();
theKineticEnergy = right.GetKineticEnergy();
thePolarization = right.GetPolarization();
theProperTime = right.GetProperTime();
verboseLevel = right.GetVerboseLevel();
// thePreAssignedDecayProducts must not be copied.
thePreAssignedDecayProducts = NULL;
}
return *this;
}
G4int G4DynamicParticle::operator==(const G4DynamicParticle &right) const
{
return (this == (G4DynamicParticle *) &right);
}
G4int G4DynamicParticle::operator!=(const G4DynamicParticle &right) const
{
return (this != (G4DynamicParticle *) &right);
}
void G4DynamicParticle::SetMomentum(const G4ThreeVector &momentum)
{
G4double pModule2 = momentum.mag2();
if (pModule2>0.0) {
G4double mass = theDynamicalMass;
G4double pModule = sqrt(pModule2);
SetMomentumDirection(momentum.x()/pModule,
momentum.y()/pModule,
momentum.z()/pModule);
SetKineticEnergy(sqrt(pModule2 + mass*mass)-mass);
} else {
SetMomentumDirection(1.0,0.0,0.0);
SetKineticEnergy(0.0);
}
}
void G4DynamicParticle::Set4Momentum(const G4LorentzVector &momentum )
{
G4double pModule2 = momentum.x()*momentum.x()
+ momentum.y()*momentum.y()
+ momentum.z()*momentum.z();
if (pModule2>0.0) {
G4double pModule = sqrt(pModule2);
SetMomentumDirection(momentum.x()/pModule,
momentum.y()/pModule,
momentum.z()/pModule);
G4double totalenergy = momentum.t();
if (totalenergy > pModule) {
G4double mass = sqrt(totalenergy*totalenergy - pModule2);
theDynamicalMass = mass;
SetKineticEnergy(totalenergy-mass);
} else {
theDynamicalMass = 0.;
SetKineticEnergy(totalenergy);
}
} else {
SetMomentumDirection(1.0,0.0,0.0);
SetKineticEnergy(0.0);
}
}
void G4DynamicParticle::DumpInfo() const
{
if (theParticleDefinition == NULL) {
G4cout << " G4DynamicParticle::DumpInfo():: !!!Particle type not defined !!!! " << endl;
} else {
G4cout << " Particle type - " << theParticleDefinition->GetParticleName() << endl
<< " mass: " << GetMass()/GeV << "[GeV]" <<endl
<< " Direction x: " << GetMomentumDirection().x() << ", y: "
<< GetMomentumDirection().y() << ", z: "
<< GetMomentumDirection().z() << endl
<< " Total Momentum = " << GetTotalMomentum() /GeV << "[GeV]" << endl
<< " Momentum: " << GetMomentum().x() /GeV << "[GeV]" << ", y: "
<< GetMomentum().y() /GeV << "[GeV]" << ", z: "
<< GetMomentum().z() /GeV << "[GeV]" << endl
<< " Total Energy = " << GetTotalEnergy()/GeV << "[GeV]" << endl
<< " Kinetic Energy = " << GetKineticEnergy() /GeV << "[GeV]" << endl
<< " ProperTime = " << GetProperTime() /ns << "[ns]" << endl;
}
}
@@ -0,0 +1,301 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4IonTable.cc,v 2.17 1998/12/11 17:56:37 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
//
// For information related to this code contact:
// CERN, IT Division, ASD Group
// History: first implementation, based on object model of
// 27 June 1998 H.Kurashige
// ---------------------------------------------------------------
// modified GetIon 02 Aug., 98 H.Kurashige
// added Remove() 06 Nov.,98 H.Kurashige
// use G4NucleiPropoerties to get nuceli Mass 17 Nov.,98 H.Kurashige
// use G4GenericIon for process List
// modify fomula of Ion mass 09 Dec., 98 H.Kurashige
#include "G4IonTable.hh"
#include "G4ParticleTable.hh"
#include "G4Ions.hh"
#include "G4UImanager.hh"
#include "G4NucleiProperties.hh"
#include "G4ios.hh"
#ifdef WIN32
# include <Strstrea.h>
#else
# include <strstream.h>
#endif
G4IonTable::G4IonTable()
{
fIonList = new G4IonList();
protonMass=0.0;
neutronMass=0.0;
electronMass=0.0;
}
G4IonTable::~G4IonTable()
{
G4int idx;
G4String name;
for (idx=(fIonList->entries()-1); idx >=0 ; idx--) {
G4ParticleDefinition* particle = (*fIonList)(idx);
name = particle->GetParticleName();
if (name == "alpha") {
} else if (name == "deuteron") {
} else if (name == "triton") {
} else if (name == "He3") {
} else {
// delete if not static objects
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cerr << "G4IonTable:~IonTable() : delete ion of " << name << endl;
}
#endif
delete particle;
}
}
// remove all scontents in the Ion List
fIonList->clear();
delete fIonList;
}
G4int G4IonTable::GetVerboseLevel() const
{
return G4ParticleTable::GetParticleTable()->GetVerboseLevel();
}
G4ParticleDefinition* G4IonTable::GetIon(G4int Z, G4int A, G4int J, G4int Q)
{
// Search ions with A, Z
G4ParticleDefinition* ion;
G4bool isFound = false;
// check if proton/neutron/electron exits and get their masses
if (protonMass<=0.0) {
G4ParticleDefinition* proton = G4ParticleTable::GetParticleTable()->FindParticle("proton");
G4ParticleDefinition* neutron = G4ParticleTable::GetParticleTable()->FindParticle("neutron");
if ((proton == NULL)||(neutron == NULL)) {
G4Exception("G4IonTable: G4Proton or G4Neutron is not defined !!");
}
protonMass = proton->GetPDGMass();
neutronMass = neutron->GetPDGMass();
G4ParticleDefinition* electron = G4ParticleTable::GetParticleTable()->FindParticle("e-");
if (electron == NULL) {
G4Exception("G4IonTable: G4Electron is not defined !!");
}
electronMass = electron->GetPDGMass();
}
// -- loop over all particles in Ion table
for (G4int idx= 0; idx < fIonList->entries() ; idx++) {
ion = (*fIonList)(idx);
// charge = charge /eplus
G4int aCharge = int(ion->GetPDGCharge()/eplus);
// A = baryon number
G4int anAtomicMass = ion->GetBaryonNumber();
// spin
G4int anAngularMomentum = ion->GetPDGiSpin();
if ( (A == anAtomicMass) && (Q == aCharge) && ( J == anAngularMomentum )){
isFound = true;
break;
}
}
if (!isFound) {
// create ion
G4String name = GetIonName(Z, A, J, Q);
if ( name(0) == '?') {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cerr << "G4IonTable::GetIon() : can not create ions " << endl;
G4cerr << " Z =" << Z << " A = " << A << endl;
}
#endif
return NULL;
}
G4double mass = GetIonMass(Z, A) + electronMass*G4double(Q);
G4double charge = G4double(Q)*eplus;
// create an ion
// spin, parity, isospin values are fixed
//
ion = new G4Ions( name, mass, 0.0*MeV, charge,
J, +1, 0,
0, 0, 0,
"nucleus", 0, A, 0,
true, -1.0, NULL);
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cerr << "G4IonTable::GetIon() : create ion of " << name << endl;
}
#endif
char cmd[60];
ostrstream os(cmd,60);
os << "/run/particle/addProcManager "<< name << '\0';
G4UImanager::GetUIpointer()->ApplyCommand(cmd);
G4ParticleDefinition* alpha=G4ParticleTable::GetParticleTable()->FindParticle("GenericIon");
if (alpha->GetEnergyCuts() != NULL) {
ion->SetCuts( alpha->GetLengthCuts());
}
}
return ion;
}
G4String G4IonTable::GetIonName(G4int Z, G4int A, G4int J, G4int Q) const
{
G4String name;
if ( (0< Z) && (Z <=numberOfElements) ) {
name = elementName[Z-1];
} else {
return "?";
}
char val[50];
ostrstream os(val,50);
os << A << '-' << J << "/2" << '[' << Q << ']' << '\0';
name += val;
return name;
}
G4double G4IonTable::GetIonMass(G4int Z, G4int A) const
{
G4ParticleDefinition* ion=NULL;
G4double mass;
if ( (Z<=2) ) {
if ( (Z==1)&&(A==1) ) {
ion = G4ParticleTable::GetParticleTable()->FindParticle("proton"); // proton
} else if ( (Z==0)&&(A==1) ) {
ion = G4ParticleTable::GetParticleTable()->FindParticle("neutron"); // neutron
} else if ( (Z==1)&&(A==2) ) {
ion = G4ParticleTable::GetParticleTable()->FindParticle("deuteron"); // deuteron
} else if ( (Z==1)&&(A==3) ) {
ion = G4ParticleTable::GetParticleTable()->FindParticle("triton"); // tritoon
} else if ( (Z==2)&&(A==4) ) {
ion = G4ParticleTable::GetParticleTable()->FindParticle("alpha"); // alpha
} else if ( (Z==2)&&(A==3) ) {
ion = G4ParticleTable::GetParticleTable()->FindParticle("He3"); // He3
}
}
if (ion!=NULL) {
mass = ion->GetPDGMass();
}else {
// This routine returns mass of nuclei (w/o including electron mass)
mass = G4NucleiProperties::GetAtomicMass(G4double(A),G4double(Z));
mass - electronMass*G4double(Z);
}
return mass;
}
G4bool G4IonTable::IsIon(G4ParticleDefinition* particle) const
{
return (particle->GetParticleType() == "nucleus");
}
void G4IonTable::Insert(G4ParticleDefinition* particle)
{
if (IsIon(particle)) {
fIonList->insert(particle);
} else {
//#ifdef G4VERBOSE
//if (GetVerboseLevel()>0) {
// G4cerr << "G4IonTable::Insert :" << particle->GetParticleName() ;
// G4cerr << " is not ions" << endl;
//}
//#endif
}
}
void G4IonTable::Remove(G4ParticleDefinition* particle)
{
if (IsIon(particle)) {
fIonList->remove(particle);
} else {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cerr << "G4IonTable::Remove :" << particle->GetParticleName() ;
G4cerr << " is not ions" << endl;
}
#endif
}
}
void G4IonTable::DumpTable(const G4String &particle_name) const
{
for (G4int idx= 0; idx < fIonList->entries() ; idx++) {
if (( particle_name == "ALL" ) || (particle_name == "all")){
((*fIonList)(idx))->DumpTable();
} else if ( particle_name == ((*fIonList)(idx))->GetParticleName() ) {
((*fIonList)(idx))->DumpTable();
}
}
}
const G4String G4IonTable::elementName[] = {
"H", "He",
"Li", "Be", "B", "C", "N", "O", "F", "Ne",
"Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar",
"K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As", "Se", "Br", "Kr",
"Rb", "Sr", "Y", "Zr", "Nb", "Mo","Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I", "Xe",
"Cs", "Ba",
"La", "Ce", "Pr", "Nd", "Pr", "Sm", "Eu", "Gd", "Tb", "Dy", "Ho", "Er", "Tm", "Yb", "Lu",
"Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn",
"Fr", "Ra",
"Ac", "Th", "Pa", "U", "Np", "Pu", "Am", "Cm", "Bk", "Cf", "Es", "Fm", "Md", "No", "Lr",
"Db", "Jl", "Rf", "Bh", "Hn", "Mt", "Xa"
};
+47
View File
@@ -0,0 +1,47 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4Ions.cc,v 2.2 1998/11/18 17:38:19 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// ----------------------------------------------------------------------
// GEANT 4 class implementation file
//
// For information related to this code contact:
// CERN, CN Division, ASD Group
// History: first implementation, based on object model of
// 4th April 1996, G.Cosmo
// **********************************************************************
#include <fstream.h>
#include <iomanip.h>
#include "G4Ions.hh"
// ######################################################################
// ### Ions ###
// ######################################################################
G4Ions::G4Ions(
const G4String& aName, G4double mass,
G4double width, G4double charge,
G4int iSpin, G4int iParity,
G4int iConjugation, G4int iIsospin,
G4int iIsospin3, G4int gParity,
const G4String& pType, G4int lepton,
G4int baryon, G4int encoding,
G4bool stable, G4double lifetime,
G4DecayTable *decaytable )
: G4ParticleWithCuts( aName,mass,width,charge,iSpin,iParity,
iConjugation,iIsospin,iIsospin3,gParity,pType,
lepton,baryon,encoding,stable,lifetime,decaytable )
{
// Initialise cuts at construction to enable production cuts since
// ions are not in the particle table at initialisation.
// SetCuts(1.e-30);
}
@@ -0,0 +1,306 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4KL3DecayChannel.cc,v 2.4 1998/11/18 09:46:34 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
//
// For information related to this code contact:
// CERN, CN Division, ASD group
// History: first implementation, based on object model of
// 30 May 1997 H.Kurashige
// ------------------------------------------------------------
#include "G4ParticleDefinition.hh"
#include "G4DecayProducts.hh"
#include "G4VDecayChannel.hh"
#include "G4KL3DecayChannel.hh"
#include "Randomize.hh"
#include "G4LorentzVector.hh"
#include "G4LorentzRotation.hh"
G4KL3DecayChannel::G4KL3DecayChannel(
const G4String& theParentName,
G4double theBR,
const G4String& thePionName,
const G4String& theLeptonName,
const G4String& theNutrinoName)
:G4VDecayChannel("KL3 Decay",theParentName,
theBR, 3,
thePionName,theLeptonName,theNutrinoName)
{
//#ifdef G4VERBOSE
//if (GetVerboseLevel()>1) {
// G4cout << "G4KL3DecayChannel:: constructor ";
// G4cout << "addr[" << this << "]" << endl;
//}
//#endif
// check modes
if ( ((theParentName == "kaon+")&&(theLeptonName == "e+")) ||
((theParentName == "kaon-")&&(theLeptonName == "e-")) ) {
// K+- (Ke3)
pLambda = 0.0286;
pXi0 = -0.35;
} else if ( ((theParentName == "kaon+")&&(theLeptonName == "mu+")) ||
((theParentName == "kaon-")&&(theLeptonName == "mu-")) ) {
// K+- (Kmu3)
pLambda = 0.033;
pXi0 = -0.35;
} else if ( (theParentName == "kaon0L") &&
((theLeptonName == "e+") ||(theLeptonName == "e-")) ){
// K0L (Ke3)
pLambda = 0.0300;
pXi0 = -0.11;
} else if ( (theParentName == "kaon0L") &&
((theLeptonName == "mu+") ||(theLeptonName == "mu-")) ){
// K0L (Kmu3)
pLambda = 0.034;
pXi0 = -0.11;
} else {
//#ifdef G4VERBOSE
//if (GetVerboseLevel()>0) {
// G4cout << "G4KL3DecayChannel:: constructor :";
// G4cout << "illegal arguments " << endl;;
// DumpInfo();
// }
//#endif
// set values for K0L (Ke3) temporarily
pLambda = 0.0300;
pXi0 = -0.11;
}
}
G4KL3DecayChannel::~G4KL3DecayChannel()
{
}
G4DecayProducts* G4KL3DecayChannel::DecayIt(G4double)
{
// this version neglects muon polarization
// assumes the pure V-A coupling
// gives incorrect energy spectrum for Nutrinos
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) G4cout << "G4KL3DecayChannel::DecayIt " << endl;
#endif
// fill parent particle and its mass
if (parent == NULL) {
FillParent();
}
massK = parent->GetPDGMass();
// fill daughter particles and their mass
if (daughters == NULL) {
FillDaughters();
}
daughterM[idPi] = daughters[idPi]->GetPDGMass();
daughterM[idLepton] = daughters[idLepton]->GetPDGMass();
daughterM[idNutrino] = daughters[idNutrino]->GetPDGMass();
// determine momentum/energy of daughters
// according to DalitzDensity
G4double daughterP[3], daughterE[3];
G4double w;
G4double r;
do {
r = G4UniformRand();
PhaseSpace(massK, &daughterM[0], &daughterE[0], &daughterP[0]);
w = DalitzDensity(daughterE[idPi],daughterE[idLepton],daughterE[idNutrino]);
} while ( r > w);
// output message
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cout << *daughters_name[0] << ":" << daughterP[0]/GeV << "[GeV/c]" <<endl;
G4cout << *daughters_name[1] << ":" << daughterP[1]/GeV << "[GeV/c]" <<endl;
G4cout << *daughters_name[2] << ":" << daughterP[2]/GeV << "[GeV/c]" <<endl;
}
#endif
//create parent G4DynamicParticle at rest
G4ParticleMomentum* direction = new G4ParticleMomentum(1.0,0.0,0.0);
G4DynamicParticle * parentparticle = new G4DynamicParticle( parent, *direction, 0.0);
delete direction;
//create G4Decayproducts
G4DecayProducts *products = new G4DecayProducts(*parentparticle);
delete parentparticle;
//create daughter G4DynamicParticle
G4double costheta, sintheta, phi, sinphi, cosphi;
G4double costhetan, sinthetan, phin, sinphin, cosphin;
// pion
costheta = 2.*G4UniformRand()-1.0;
sintheta = sqrt((1.0-costheta)*(1.0+costheta));
phi = 2.0*M_PI*G4UniformRand()*rad;
sinphi = sin(phi);
cosphi = cos(phi);
direction = new G4ParticleMomentum(sintheta*cosphi,sintheta*sinphi,costheta);
G4ThreeVector momentum0 = (*direction)*daughterP[0];
G4DynamicParticle * daughterparticle
= new G4DynamicParticle( daughters[0], momentum0);
products->PushProducts(daughterparticle);
// neutrino
costhetan = (daughterP[1]*daughterP[1]-daughterP[2]*daughterP[2]-daughterP[0]*daughterP[0])/(2.0*daughterP[2]*daughterP[0]);
sinthetan = sqrt((1.0-costhetan)*(1.0+costhetan));
phin = 2.0*M_PI*G4UniformRand()*rad;
sinphin = sin(phin);
cosphin = cos(phin);
direction->setX( sinthetan*cosphin*costheta*cosphi - sinthetan*sinphin*sinphi + costhetan*sintheta*cosphi);
direction->setY( sinthetan*cosphin*costheta*sinphi + sinthetan*sinphin*cosphi + costhetan*sintheta*sinphi);
direction->setZ( -sinthetan*cosphin*sintheta + costhetan*costheta);
G4ThreeVector momentum2 = (*direction)*daughterP[2];
daughterparticle = new G4DynamicParticle( daughters[2], momentum2);
products->PushProducts(daughterparticle);
//lepton
G4ThreeVector momentum1 = (momentum0 + momentum2) * (-1.0);
daughterparticle =
new G4DynamicParticle( daughters[1], momentum1);
products->PushProducts(daughterparticle);
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cout << "G4KL3DecayChannel::DecayIt ";
G4cout << " create decay products in rest frame " <<endl;
G4cout << " decay products address=" << products << endl;
products->DumpInfo();
}
#endif
delete direction;
return products;
}
void G4KL3DecayChannel::PhaseSpace(G4double parentM,
const G4double* M,
G4double* E,
G4double* P )
// algorism of this code is originally written in GDECA3 of GEANT3
{
//sum of daughters'mass
G4double sumofdaughtermass = 0.0;
G4int index;
for (index=0; index<3; index++){
sumofdaughtermass += M[index];
}
//calculate daughter momentum
// Generate two
G4double rd1, rd2, rd;
G4double momentummax=0.0, momentumsum = 0.0;
G4double energy;
do {
rd1 = G4UniformRand();
rd2 = G4UniformRand();
if (rd2 > rd1) {
rd = rd1;
rd1 = rd2;
rd2 = rd;
}
momentummax = 0.0;
momentumsum = 0.0;
// daughter 0
energy = rd2*(parentM - sumofdaughtermass);
P[0] = sqrt(energy*energy + 2.0*energy*M[0]);
E[0] = energy;
if ( P[0] >momentummax )momentummax = P[0];
momentumsum += P[0];
// daughter 1
energy = (1.-rd1)*(parentM - sumofdaughtermass);
P[1] = sqrt(energy*energy + 2.0*energy*M[1]);
E[1] = energy;
if ( P[1] >momentummax )momentummax = P[1];
momentumsum += P[1];
// daughter 2
energy = (rd1-rd2)*(parentM - sumofdaughtermass);
P[2] = sqrt(energy*energy + 2.0*energy*M[2]);
E[2] = energy;
if ( P[2] >momentummax )momentummax = P[2];
momentumsum += P[2];
} while (momentummax > momentumsum - momentummax );
#ifdef G4VERBOSE
if (GetVerboseLevel()>2) {
G4cout << "G4KL3DecayChannel::PhaseSpace ";
G4cout << "Kon mass:" << parentM/GeV << "GeV/c/c" << endl;
for (index=0; index<3; index++){
G4cout << index << " : " << M[index]/GeV << "GeV/c/c ";
G4cout << " : " << E[index]/GeV << "GeV ";
G4cout << " : " << P[index]/GeV << "GeV/c " << endl;
}
}
#endif
}
G4double G4KL3DecayChannel::DalitzDensity(G4double Epi, G4double El, G4double Enu)
{
// KL3 decay Dalitz Plot Density
// see Chounet et al Phys. Rep. 4, 201
// arguments
// Epi: kinetic enregy of pion
// El: kinetic enregy of lepton (e or mu)
// Enu: kinetic energy of nutrino
// constants
// pLambda : linear energy dependence of f+
// pXi0 : = f+(0)/f-
// pNorm : normalization factor
// variables
// Epi: total energy of pion
// El: total energy of lepton (e or mu)
// Enu: total energy of nutrino
// mass of daughters
G4double massPi = daughterM[idPi];
G4double massL = daughterM[idLepton];
G4double massNu = daughterM[idNutrino];
// calcurate total energy
Epi = Epi + massPi;
El = El + massL;
Enu = Enu + massNu;
G4double Epi_max = (massK*massK+massPi*massPi-massL*massL)/2.0/massK;
G4double E = Epi_max - Epi;
G4double q2 = massK*massK + massPi*massPi - 2.0*massK*Epi;
G4double F = 1.0 + pLambda*q2/massPi/massPi;
G4double Fmax = 1.0;
if (pLambda >0.0) Fmax = (1.0 + pLambda*(massK*massK/massPi/massPi+1.0));
G4double Xi = pXi0*(1.0 + pLambda*q2/massPi/massPi);
G4double coeffA = massK*(2.0*El*Enu-massK*E)+massL*massL*(E/4.0-Enu);
G4double coeffB = massL*massL*(Enu-E/2.0);
G4double coeffC = massL*massL*E/4.0;
G4double RhoMax = (Fmax*Fmax)*(massK*massK*massK/8.0);
G4double Rho = (F*F)*(coeffA + coeffB*Xi + coeffC*Xi*Xi);
#ifdef G4VERBOSE
if (GetVerboseLevel()>2) {
G4cout << "G4KL3DecayChannel::DalitzDensity " <<endl;
G4cout << " Pi[" << massPi/GeV <<"GeV/c/c] :" << Epi/GeV << "GeV" <<endl;
G4cout << " L[" << massL/GeV <<"GeV/c/c] :" << El/GeV << "GeV" <<endl;
G4cout << " Nu[" << massNu/GeV <<"GeV/c/c] :" << Enu/GeV << "GeV" <<endl;
G4cout << " F :" << F << " Fmax :" << Fmax << " Xi :" << Xi << endl;
G4cout << " A :" << coeffA << " B :" << coeffB << " C :"<< coeffC <<endl;
G4cout << " Rho :" << Rho << " RhoMax :" << RhoMax << endl;
}
#endif
return (Rho/RhoMax);
}
@@ -0,0 +1,193 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4MuonDecayChannel.cc,v 2.3 1998/11/18 09:46:36 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
//
// For information related to this code contact:
// CERN, CN Division, ASD group
// History: first implementation, based on object model of
// 30 May 1997 H.Kurashige
// 10 June 1997 H.Kurashige
// ------------------------------------------------------------
#include "G4ParticleDefinition.hh"
#include "G4DecayProducts.hh"
#include "G4VDecayChannel.hh"
#include "G4MuonDecayChannel.hh"
#include "Randomize.hh"
#include "G4LorentzVector.hh"
#include "G4LorentzRotation.hh"
G4MuonDecayChannel::G4MuonDecayChannel(const G4String& theParentName,
G4double theBR)
:G4VDecayChannel("Muon Decay",1)
{
//#ifdef G4VERBOSE
//if (GetVerboseLevel()>1) {
// G4cout << "G4MuonDecayChannel:: constructor ";
// G4cout << "addr[" << this << "]" << endl;
//}
//#endif
// set names for daughter particles
if (theParentName == "mu+") {
SetBR(theBR);
SetParent("mu+");
SetNumberOfDaughters(3);
SetDaughter(0, "e+");
SetDaughter(1, "nu_e");
SetDaughter(2, "anti_nu_mu");
} else if (theParentName == "mu-") {
SetBR(theBR);
SetParent("mu-");
SetNumberOfDaughters(3);
SetDaughter(0, "e-");
SetDaughter(1, "anti_nu_e");
SetDaughter(2, "nu_mu");
} else {
//#ifdef G4VERBOSE
// if (GetVerboseLevel()>0) {
// G4cout << "G4MuonDecayChannel:: constructor :";
// G4cout << " parent particle is not muon but ";
// G4cout << theParentName << endl;
// }
//#endif
}
}
G4MuonDecayChannel::~G4MuonDecayChannel()
{
}
G4DecayProducts *G4MuonDecayChannel::DecayIt(G4double)
{
// this version neglects muon polarization
// assumes the pure V-A coupling
// gives incorrect energy spectrum for neutrinos
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) G4cout << "G4MuonDecayChannel::DecayIt ";
#endif
if (parent == NULL) FillParent();
if (daughters == NULL) FillDaughters();
// parent mass
G4double parentmass = parent->GetPDGMass();
//daughters'mass
G4double daughtermass[3];
G4double sumofdaughtermass = 0.0;
for (G4int index=0; index<3; index++){
daughtermass[index] = daughters[index]->GetPDGMass();
sumofdaughtermass += daughtermass[index];
}
//create parent G4DynamicParticle at rest
G4ParticleMomentum dummy;
G4DynamicParticle * parentparticle = new G4DynamicParticle( parent, dummy, 0.0);
//create G4Decayproducts
G4DecayProducts *products = new G4DecayProducts(*parentparticle);
delete parentparticle;
// calculate daughter momentum
G4double daughtermomentum[3];
G4double momentumsum = 0.0;
G4double energy;
// calcurate electron energy
G4double xmax = (1.0+daughtermass[0]*daughtermass[0]/parentmass/parentmass);
G4double x;
G4double r;
do {
do {
r = G4UniformRand();
x = xmax*G4UniformRand();
} while (r < (3.0 - 2.0*x)*x*x);
energy = x*parentmass/2.0 - daughtermass[0];
} while (energy <0.0);
//create daughter G4DynamicParticle
// daughter 0 (electron)
daughtermomentum[0] = sqrt(energy*energy + 2.0*energy* daughtermass[0]);
G4double costheta, sintheta, phi, sinphi, cosphi;
costheta = 2.*G4UniformRand()-1.0;
sintheta = sqrt((1.0-costheta)*(1.0+costheta));
phi = 2.0*M_PI*G4UniformRand()*rad;
sinphi = sin(phi);
cosphi = cos(phi);
G4ParticleMomentum direction0(sintheta*cosphi,sintheta*sinphi,costheta);
G4DynamicParticle * daughterparticle
= new G4DynamicParticle( daughters[0], direction0*daughtermomentum[0]);
products->PushProducts(daughterparticle);
// daughter 1 ,2 (nutrinos)
// create neutrinos in the C.M frame of two neutrinos
G4double energy2 = parentmass*(1.0 - x/2.0);
G4double vmass = sqrt((energy2-daughtermomentum[0])*(energy2+daughtermomentum[0]));
G4double beta = -1.0*daughtermomentum[0]/energy2;
G4double costhetan = 2.*G4UniformRand()-1.0;
G4double sinthetan = sqrt((1.0-costhetan)*(1.0+costhetan));
G4double phin = 2.0*M_PI*G4UniformRand()*rad;
G4double sinphin = sin(phin);
G4double cosphin = cos(phin);
G4ParticleMomentum direction1(sinthetan*cosphin,sinthetan*sinphin,costhetan);
G4DynamicParticle * daughterparticle1
= new G4DynamicParticle( daughters[1], direction1*(vmass/2.));
G4DynamicParticle * daughterparticle2
= new G4DynamicParticle( daughters[2], direction1*(-1.0*vmass/2.));
// boost to the muon rest frame
G4LorentzVector p4;
p4 = daughterparticle1->Get4Momentum();
p4.boost( direction0.x()*beta, direction0.y()*beta, direction0.z()*beta);
daughterparticle1->Set4Momentum(p4);
p4 = daughterparticle2->Get4Momentum();
p4.boost( direction0.x()*beta, direction0.y()*beta, direction0.z()*beta);
daughterparticle2->Set4Momentum(p4);
products->PushProducts(daughterparticle1);
products->PushProducts(daughterparticle2);
daughtermomentum[1] = daughterparticle1->GetTotalMomentum();
daughtermomentum[2] = daughterparticle2->GetTotalMomentum();
// output message
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cout << " daughter 0:" << daughtermomentum[0]/GeV << "[GeV/c]" <<endl;
G4cout << " daughter 1:" << daughtermomentum[1]/GeV << "[GeV/c]" <<endl;
G4cout << " daughter 2:" << daughtermomentum[2]/GeV << "[GeV/c]" <<endl;
}
#endif
// if (!products->IsChecked()) {
// G4cout << " daughter 0:" << daughtermomentum[0]/GeV << "[GeV/c]" <<endl;
// G4cout << " daughter 1:" << daughtermomentum[1]/GeV << "[GeV/c]" <<endl;
// G4cout << " daughter 2:" << daughtermomentum[2]/GeV << "[GeV/c]" <<endl;
// G4cout << " costheta = " << costheta << " sinphi = " << sinphi <<endl;
// G4cout << " costhetan = " << costhetan << " sinphin = " << sinphin <<endl;
// products->DumpInfo();
// G4Exception(" ");
// }
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cout << "G4MuonDecayChannel::DecayIt ";
G4cout << " create decay products in rest frame " <<endl;
products->DumpInfo();
}
#endif
return products;
}
@@ -0,0 +1,159 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4NucleiProperties.cc,v 2.6 1998/12/10 18:08:06 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
//
// For information related to this code contact:
// CERN, IT Division, ASD group
// ------------------------------------------------------------
//
// Hadronic Process: Nuclear De-excitations
// by V. Lara (Oct 1998)
// Migrate into particles category by H.Kurashige (17 Nov. 98)
#include "G4NucleiProperties.hh"
G4double G4NucleiProperties::CameronMassExcess(const G4int A, const G4int Z)
{
const G4double A03 = pow(A,1.0/3.0);
const G4double A06 = A03*A03;
const G4double A13 = A06*A06;
const G4double Z13 = pow(Z,1.0+1.0/3.0);
const G4double D = (A - 2.0*Z)/A;
const G4double DR = 1.0 - 0.32052/A06;
// Surface term
G4double SurfaceEnergy = (25.8357-44.2355*D*D)*DR*DR*A06;
// Coulomb term
G4double CoulombEnergy = 0.779*(Z*(Z-1)/A03)*(1.0-1.5849/A06+1.2273/A+1.5772/A13);
// Exchange term
G4double ExchangeEnergy = -0.4323*(Z13/A03)*(1.0-0.57811/A03-0.14518/A06+0.49597/A);
// Volume term
G4double VolumeEnergy = A*(-17.0354+31.4506*D*D);
// Compute Mass Excess
// Neutron mass 8.07169 MeV Proton mass 7.2892 MeV
return (8.07169*A - 0.7892*Z + SurfaceEnergy + CoulombEnergy + ExchangeEnergy + VolumeEnergy)*MeV;
}
G4double G4NucleiProperties::AtomicMass(G4double Z, G4double A)
{
// derived from original FORTRAN code ATOMAS by H. Fesefeldt (2-Dec-1986)
//
// Computes atomic mass in MeV
// units for A example: A = material->GetA()/(g/mole);
//
// Note: can't just use aEff and zEff since the Nuclear Reaction
// function needs to calculate atomic mass for various values of A and Z
G4ParticleDefinition* proton = G4ParticleTable::GetParticleTable()->FindParticle("proton");
G4ParticleDefinition* neutron = G4ParticleTable::GetParticleTable()->FindParticle("neutron");
G4ParticleDefinition* electron = G4ParticleTable::GetParticleTable()->FindParticle("e-");
if ((proton == NULL)||(neutron == NULL)||(electron == NULL)) {
G4Exception("G4NucleiProperties: G4Proton or G4Neutron is not defined !!");
}
const G4double proton_mass = proton->GetPDGMass();
const G4double neutron_mass = neutron->GetPDGMass();
const G4double electron_mass = electron->GetPDGMass();
//
// Weitzsaecker's Mass formula
//
G4int nNeutron = A-Z;
G4int ipp = G4int(nNeutron)%2; // pairing
G4int izz = G4int(Z)%2;
G4double mass =
nNeutron*neutron_mass + Z*proton_mass
- 15.67*double(A) // nuclear volume
+ 17.23*pow(double(A),2./3.) // surface energy
+ 93.15*(double(A/2.-Z)*double(A/2.-Z))/double(A) // asymmetry
+ 0.6984523*double(Z*Z)*pow(double(A),-1./3.) // coulomb
+ Z*electron_mass; // electrons mass
if( ipp == izz ) mass += (ipp+izz-1) * 12.0 / sqrt(double(A)); // pairing
return mass*MeV;
}
// S(Z)+P(Z) from Tab. 1 from A.G.W. Cameron, Canad. J. Phys., 35(1957)1021
// or Delta M(Z) from Tab. 97 of book [1]
const G4double G4NucleiProperties::daTZ[G4NucleiProperties::NTZ] = {
20.80, 15.80, 21.00, 16.80, 19.80, 16.50, 18.80, 16.50, 18.50, 17.20, // 1
18.26, 15.05, 16.01, 12.04, 13.27, 11.09, 12.17, 10.26, 11.04, 8.41, // 2
9.79, 7.36, 8.15, 5.63, 5.88, 3.17, 3.32, .82, 1.83, .97, // 3
2.33, 1.27, 2.92, 1.61, 2.91, 1.35, 2.40, .89, 1.74, .36, // 4
0.95, -0.65, -0.04, -1.73, -0.96, -2.87, -2.05, -4.05, -3.40, -5.72, // 5
-3.75, -4.13, -2.42, -2.85, -1.01, -1.33, 0.54, -0.02, 1.74, 0.75, // 6
2.24, 1.00, 1.98, 0.79, 1.54, 0.39, 1.08, 0.00, 0.78, -0.35, // 7
0.58, -0.55, 0.59, -0.61, 0.59, -0.35, 0.32, -0.96, -0.52, -2.08, // 8
-2.46, -3.64, -1.55, -0.96, 0.97, 0.88, 2.37, 1.75, 2.72, 1.90, // 9
2.55, 1.46, 1.93, 0.86, 1.17, 0.08, 0.39, -0.76, -0.39, -1.51, // 0
-1.17, -2.36, -1.95, -3.06, -2.62, -3.55, -2.95, -3.75, -3.07, -3.79, // 1
-3.06, -3.77, -3.05, -3.78, -3.12, -3.90, -3.35, -4.24, -3.86, -4.92, // 2
-5.06, -6.77, -7.41, -9.18,-10.16,-11.12, -9.76, -9.23, -7.96, -7.65 // 3
};
// S(N)+P(N) from Tab. 1 from A.G.W. Cameron, Canad. J. Phys., 35(1957)1021
// or Delta M(N) from Tab. 97 of book [1]
const G4double G4NucleiProperties::daTAZ[G4NucleiProperties::NTAZ] = {
-8.40,-12.90, -8.00, 11.90, -9.20,-12.50,-10.80,-13.60,-11.20,-12.20, // 1
-12.81,-15.40,-13.07,-15.80,-13.81,-14.98,-12.63,-13.76,-11.37,-12.38, // 2
-9.23, -9.65, -7.64, -9.17, -8.05, -9.72, -8.87,-10.76, -8.64, -8.89, // 3
-6.60, -7.13, -4.77, -5.33, -3.06, -3.79, -1.72, -2.79, -0.93, -2.19, // 4
-0.52, -1.90, -0.45, -2.20, -1.22, -3.07, -2.42, -4.37, -3.94, -6.08, // 5
-4.49, -4.50, -3.14, -2.93, -1.04, -1.36, 0.69, 0.21, 2.11, 1.33, // 6
3.29, 2.46, 4.30, 3.32, 4.79, 3.62, 4.97, 3.64, 4.63, 3.07, // 7
4.06, 2.49, 3.30, 1.46, 2.06, 0.51, 0.74, -1.18, -1.26, -3.54, // 8
-3.97, -5.26, -4.18, -3.71, -2.10, -1.70, -0.08, -0.18, 0.94, 0.27, // 9
1.13, 0.08, 0.91, -0.31, 0.49, -0.78, 0.08, -1.15, -0.23, -1.41, // 0
-0.42, -1.55, -0.55, -1.66, -0.66, -1.73, -0.75, -1.74, -0.78, -1.69, // 1
-0.78, -1.60, -0.75, -1.46, -0.67, -1.26, -0.51, -1.04, -0.53, -1.84, // 2
-2.42, -4.52, -4.76, -6.33, -6.76, -7.81, -5.80, -5.37, -3.63, -3.35, // 3
-1.75, -1.88, -0.61, -0.90, 0.09, -0.32, 0.55, -0.13, 0.70, -0.06, // 4
0.49, -0.20, 0.40, -0.22, 0.36, -0.09, 0.58, 0.12, 0.75, 0.15, // 5
0.70, 0.17, 1.11, 0.89, 1.85, 1.62, 2.54, 2.29, 3.20, 2.91, // 6
3.84, 3.53, 4.48, 4.15, 5.12, 4.78, 5.75, 5.39, 6.31, 5.91, // 7
6.87, 6.33, 7.13, 6.61, 7.30, 6.31, 6.27, 4.83, 4.49, 2.85, // 8
2.32, 0.58, -0.11, -0.98, 0.81, 1.77, 3.37, 4.13, 5.60, 6.15, // 9
7.29, 7.35, 7.95, 7.67, 8.16, 7.83, 8.31, 8.01, 8.53, 8.27 // 0
};
G4double G4NucleiProperties::PSCorrectedCameronMassExcess( const G4int A, const G4int Z )
{
if( Z >= G4NucleiProperties::NTZ || A - Z >= G4NucleiProperties::NTAZ )
G4Exception( "G4NucleiProperties::CameronMassExcess: Value parameters error!" );
const G4double A03 = pow(A,1.0/3.0);
const G4double A06 = A03*A03;
const G4double A13 = A06*A06;
const G4double Z13 = pow(Z,1.0+1.0/3.0);
const G4double D = (A - 2.0*Z)/A;
const G4double DR = 1.0 - 0.32052/A06;
// Surface term
G4double SurfaceEnergy = (25.8357 - 44.2355 * D * D) * DR*DR * A06;
// Coulomb term
G4double CoulombEnergy = 0.779* (Z*(Z-1)/A03)* (1.0 - 1.5849/A06 + 1.2273/A + 1.5772/A13);
// Exchange term
G4double ExchangeEnergy = -0.4323 * (Z13/A03) * (1.0 - 0.57811/A03 - 0.14518/A06 + 0.49597/A);
// Volume term
G4double VolumeEnergy = A* 8.367 + (31.4506/A) * (A - 2*Z)*(A - 2*Z) - 0.783* Z - 17.0354 * A;
// Compute Mass Excess
return (SurfaceEnergy + CoulombEnergy + ExchangeEnergy + VolumeEnergy + daTZ[Z] + daTAZ[A - Z])*MeV;
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,523 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4ParticleDefinition.cc,v 2.9 1998/11/26 10:13:39 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
//
// For information related to this code contact:
// CERN, IT Division, ASD Group
// History: first implementation, based on object model of
// 2nd December 1995, G.Cosmo
// ---------------- G4ParticleDefinition -----------------
// first implementation by Makoto Asai, 29 January 1996
// revised by G.Cosmo, 29 February 1996
// revised by H.Kurashige, 19 April 1996
// Code uses operators (+=, *=, ++, -> etc.) correctly, P. Urban, 26/6/96
// revised by H.Kurashige, 4 July 1996
// revised by H.Kurashige, 16 Feb 1997
// revised by H.Kurashige, 10 Nov 1997
// remove new/delete G4ProcessManager by H.Kurashige 06 June 1998
// added Resonance flag and ApplyCuts flag H.Kurashige 27 June 1998
// modify FillQuarkContents() for quarks/diquarks H.Kurashige 30 June 1998
// modify encoding rule H.Kurashige 23 Oct. 98
// commented out G4cout/G4cerr in the constructor 10 Nov.,98 H.Kurashige
// modify FillQuarkContents() for deltas 25 Nov.,98 H.Kurashige
// --------------------------------------------------------------
#include "G4ParticleDefinition.hh"
#include "G4ParticleTable.hh"
#include "G4DecayTable.hh"
G4ParticleDefinition::G4ParticleDefinition(
const G4String& aName,
G4double mass,
G4double width,
G4double charge,
G4int iSpin,
G4int iParity,
G4int iConjugation,
G4int iIsospin,
G4int iIsospin3,
G4int gParity,
const G4String& pType,
G4int lepton,
G4int baryon,
G4int encoding,
G4bool stable,
G4double lifetime,
G4DecayTable *decaytable,
G4bool shortlived)
: theParticleName(aName),
thePDGMass(mass),
thePDGWidth(width),
thePDGCharge(charge),
thePDGiSpin(iSpin),
thePDGSpin(iSpin*0.5),
thePDGiParity(iParity),
thePDGiConjugation(iConjugation),
thePDGiGParity(gParity),
thePDGiIsospin(iIsospin),
thePDGiIsospin3(iIsospin3),
thePDGIsospin(iIsospin*0.5),
thePDGIsospin3(iIsospin3*0.5),
theParticleType(pType),
theLeptonNumber(lepton),
theBaryonNumber(baryon),
thePDGEncoding(encoding),
theAntiPDGEncoding(-1*encoding),
thePDGStable(stable),
thePDGLifeTime(lifetime),
theDecayTable(decaytable),
theProcessManager(NULL),
fShortLivedFlag(shortlived),
fApplyCutsFlag(false),
verboseLevel(1)
{
// check name and register this particle into ParticleTable
theParticleTable = G4ParticleTable::GetParticleTable();
G4ParticleDefinition *ptr = theParticleTable->Insert(this);
//#ifdef G4VERBOSE
//if (ptr != this) {
// // Fail to register to ParticleTable
// if (ptr != NULL) {
// // particle with same name already exists in ParticleTable
// if (verboseLevel>0) {
// G4cerr << "Particle name of " << aName << " has already defined " <<endl;
// G4cerr << "This particle is not registered in ParticleTable " << endl;
// } else {
// if (verboseLevel>0) {
// G4cerr << "Particle name of " << aName;
// G4cerr << " is not registered in ParticleTable" <<endl;
// if (verboseLevel>1) this->DumpTable();
// }
// }
// }
//}
//#endif
// check quark contents
#ifdef G4VERBOSE
if (this->FillQuarkContents() != thePDGEncoding) {
if (verboseLevel>0) {
// G4cerr << "Particle " << aName << " has a strange PDGEncoding " <<endl;
cerr << "Particle " << aName << " has a strange PDGEncoding " <<endl;
// if (verboseLevel>1) this->DumpTable();
}
}
#endif
}
G4ParticleDefinition::G4ParticleDefinition(const G4ParticleDefinition &right)
{
G4Exception("You call Copy Constructor of G4ParticleDefinition ");
//G4cerr << "You call Copy Constructor of G4ParticleDefinition " << endl;
//#ifdef G4VERBOSE
// if (verboseLevel>0) right.DumpTable();
//#endif
}
G4ParticleDefinition::G4ParticleDefinition()
{
G4Exception("You call Default Constructor of G4ParticleDefinition ");
//G4cerr << "You call Default Constructor of G4ParticleDefinition " << endl;
}
G4ParticleDefinition::~G4ParticleDefinition()
{
if (theDecayTable!= NULL) delete theDecayTable;
}
const G4ParticleDefinition & G4ParticleDefinition::operator=(const G4ParticleDefinition &right)
{
if (this != &right) {
} return right;
}
G4int G4ParticleDefinition::operator==(const G4ParticleDefinition &right) const
{
return (this->theParticleName == right.theParticleName);
}
G4int G4ParticleDefinition::operator!=(const G4ParticleDefinition &right) const
{
return (this->theParticleName != right.theParticleName);
}
G4int G4ParticleDefinition::FillQuarkContents()
// calculate quark and anti-quark contents
// return value is PDG encoding for this particle.
// It means error if the return value is differnt from
// this->thePDGEncoding.
{
G4int tempPDGcode = thePDGEncoding;
for (G4int flavor=0; flavor<NumberOfQuarkFlavor; flavor++){
theQuarkContent[flavor] =0;
theAntiQuarkContent[flavor] =0;
}
G4int temp = abs(tempPDGcode);
G4int higherSpin = temp/10000000;
temp -= G4int(higherSpin*10000000);
G4int exotic = temp/1000000;
temp -= G4int(exotic*1000000);
G4int radial = temp/100000;
temp -= G4int(radial*100000);
G4int multiplet = temp/10000;
temp -= G4int(multiplet*10000);
G4int quark1 = temp/1000;
temp -= G4int(quark1*1000);
G4int quark2 = temp/100;
temp -= G4int(quark2*100);
G4int quark3 = temp/10;
temp -= G4int(quark3*10);
G4int spin= temp;
if ((spin ==0) && ( higherSpin !=0 )) {
spin = higherSpin-1;
} else {
spin -= 1;
}
if (theParticleType =="quarks") {
if ((quark1 !=0) || (quark2 !=0) || (quark3 !=0)) {
//#ifdef G4VERBOSE
//if (verboseLevel>0) {
// G4cerr << " ??? unknown quark ";
// G4cerr << " PDG code=" << thePDGEncoding <<endl;
//}
//#endif
// --- thePDGEncoding is wrong
tempPDGcode = 0;
} else {
quark1 = abs(tempPDGcode);
if (quark1>NumberOfQuarkFlavor){
//#ifdef G4VERBOSE
//if (verboseLevel>0) {
// G4cerr << " ??? unknown quark ";
// G4cerr << " PDG code=" << thePDGEncoding <<endl;
//}
//#endif
// --- thePDGEncoding is wrong
tempPDGcode = 0;
} else {
if (tempPDGcode>0){
theQuarkContent[quark1-1] =1;
} else {
theAntiQuarkContent[quark1-1] =1;
}
}
}
} else if (theParticleType =="diquarks") {
if ((quark1 ==0) || (quark2 ==0) || (quark3 !=0)) {
// quark3 should be 0
// --- thePDGEncoding is wrong
tempPDGcode = 0;
} else if (quark1 < quark2) {
// --- thePDGEncoding is wrong
tempPDGcode = 0;
} else if (quark2>NumberOfQuarkFlavor){
//#ifdef G4VERBOSE
//if (verboseLevel>0) {
// G4cerr << " ??? unknown quark ";
// G4cerr << " PDG code=" << thePDGEncoding <<endl;
//}
//#endif
tempPDGcode = 0;
} else {
if (tempPDGcode>0){
theQuarkContent[quark1-1] +=1;
theQuarkContent[quark2-1] +=1;
} else {
theAntiQuarkContent[quark1-1] +=1;
theAntiQuarkContent[quark2-1] +=1;
}
}
} else if (theParticleType =="gluons") {
// gluons
// do not care about
} else if (theParticleType == "meson") {
// check meson or not
// -- exceptions --
if (tempPDGcode == 310) spin = 0; //K0s
if (tempPDGcode == 130) { //K0l
spin = 0;
quark2 = 3;
quark3 = 1;
}
if (quark1 !=0) {
//#ifdef G4VERBOSE
//if (verboseLevel>0) {
// G4cerr << " meson has only quark and anti-quark pair";
// G4cerr << " PDG code=" << thePDGEncoding <<endl;
//}
//#endif
tempPDGcode = 0;
}
if ((quark2==0)||(quark3==0)){
//#ifdef G4VERBOSE
//if (verboseLevel>0) {
// G4cerr << " meson has quark and anti-quark pair";
// G4cerr << " PDG code=" << thePDGEncoding <<endl;
//}
//#endif
tempPDGcode = 0;
}
// check spin
if ( spin != thePDGiSpin) {
//#ifdef G4VERBOSE
//if (verboseLevel>0) {
// G4cerr << " illegal SPIN (" << thePDGiSpin << "/2)";
// G4cerr << " PDG code=" << thePDGEncoding <<endl;
//}
//#endif
tempPDGcode = 0;
}
if (quark2<quark3) {
//#ifdef G4VERBOSE
//if (verboseLevel>0) {
// G4cerr << " illegal code for meson ";
// G4cerr << " PDG code=" << thePDGEncoding <<endl;
//}
//#endif
tempPDGcode = 0;
}
// check quark flavor
if (quark2> NumberOfQuarkFlavor){
//#ifdef G4VERBOSE
//if (verboseLevel>0) {
// G4cerr << " ??? unknown quark ";
// G4cerr << " PDG code=" << thePDGEncoding <<endl;
//}
//#endif
tempPDGcode = 0;
}
// check heavier quark type
if (quark2 & 1) {
// down type qurak
if (tempPDGcode >0) {
theQuarkContent[quark3-1] =1;
theAntiQuarkContent[quark2-1] =1;
} else {
theQuarkContent[quark2-1] =1;
theAntiQuarkContent[quark3-1] =1;
}
} else {
// up type quark
if (tempPDGcode >0) {
theQuarkContent[quark2-1] =1;
theAntiQuarkContent[quark3-1] =1;
} else {
theQuarkContent[quark3-1] =1;
theAntiQuarkContent[quark2-1] =1;
}
}
// check charge
G4double totalCharge = 0.0;
for (G4int flavor= 0; flavor<NumberOfQuarkFlavor-1; flavor+=2){
totalCharge += (-1./3.)*eplus*theQuarkContent[flavor];
totalCharge += 1./3.*eplus*theAntiQuarkContent[flavor];
totalCharge += 2./3.*eplus*theQuarkContent[flavor+1];
totalCharge += (-2./3.)*eplus*theAntiQuarkContent[flavor+1];
}
if (abs(totalCharge-thePDGCharge)>0.1*eplus) {
//#ifdef G4VERBOSE
//if (verboseLevel>0) {
// G4cerr << " illegal charge for meson " << thePDGCharge/eplus;
// G4cerr << " PDG code=" << thePDGEncoding <<endl;
//}
//#endif
tempPDGcode = 0;
}
} else if (theParticleType == "baryon"){
// check meson or not
if ((quark1==0)||(quark2==0)||(quark3==0)){
//#ifdef G4VERBOSE
//if (verboseLevel>0) {
// G4cerr << " meson has three quark ";
// G4cerr << " PDG code=" << thePDGEncoding <<endl;
//}
//#endif
tempPDGcode = 0;
}
//exceptions
if (abs(tempPDGcode)%10000 == 3122) {
// Lambda
quark2=2; quark3 = 1; spin = 1;
} else if (abs(tempPDGcode)%10000 == 4122) {
// Lambda_c
quark2=2; quark3 = 1; spin = 1;
} else if (abs(tempPDGcode)%10000 == 4132) {
// Xi_c0
quark2=3; quark3 = 1; spin = 1;
} else if (abs(tempPDGcode)%10000 == 4232) {
// Xi_c+
quark2=3; quark3 = 2; spin = 1;
} else if (abs(tempPDGcode)%10000 == 2122) {
// Delta+ (spin 1/2)
quark2=2; quark3 = 1; spin = 1;
} else if (abs(tempPDGcode)%10000 == 1212) {
// Delta0 (spin 1/2)
quark1=2; quark2 = 1; spin = 1;
} else if (abs(tempPDGcode)%10000 == 2126) {
// Delta+ (spin 5/2)
quark2=2; quark3 = 1; spin = 5;
} else if (abs(tempPDGcode)%10000 == 1216) {
// Delta0 (spin 5/2)
quark1=2; quark2 = 1; spin = 5;
} else if (abs(tempPDGcode)%10000 == 2128) {
// Delta+ (spin 7/2)
quark2=2; quark3 = 1; spin = 7;
} else if (abs(tempPDGcode)%10000 == 1218) {
// Delta0 (spin 7/2)
quark1=2; quark2 = 1; spin = 7;
} else if (abs(tempPDGcode)%10000 == 2124) {
// N*+ (spin 3/2)
quark2=2; quark3 = 1; spin = 3;
} else if (abs(tempPDGcode)%10000 == 1214) {
// N*0 (spin 3/2)
quark1=2; quark2 = 1; spin = 3;
}
// check spin
if (spin != thePDGiSpin) {
//#ifdef G4VERBOSE
//if (verboseLevel>0) {
// G4cerr << " illegal SPIN (" << thePDGiSpin << "/2";
// G4cerr << " PDG code=" << thePDGEncoding <<endl;
//}
//#endif
tempPDGcode = 0;
}
// check quark flavor
if ((quark1<quark2)||(quark2<quark3)||(quark1<quark3)) {
//#ifdef G4VERBOSE
//if (verboseLevel>0) {
// G4cerr << " illegal code for baryon ";
// G4cerr << " PDG code=" << thePDGEncoding <<endl;
//}
//#endif
tempPDGcode = 0;
}
if (quark1> NumberOfQuarkFlavor) {
//#ifdef G4VERBOSE
//if (verboseLevel>0) {
// G4cerr << " ??? unknown quark ";
// G4cerr << " PDG code=" << thePDGEncoding <<endl;
//}
//#endif
tempPDGcode = 0;
}
if (tempPDGcode >0) {
theQuarkContent[quark1-1] ++;
theQuarkContent[quark2-1] ++;
theQuarkContent[quark3-1] ++;
} else {
theAntiQuarkContent[quark1-1] ++;
theAntiQuarkContent[quark2-1] ++;
theAntiQuarkContent[quark3-1] ++;
}
// check charge
G4double totalCharge = 0.0;
for (G4int flavor= 0; flavor<NumberOfQuarkFlavor-1; flavor+=2){
totalCharge += (-1./3.)*eplus*theQuarkContent[flavor];
totalCharge += 1./3.*eplus*theAntiQuarkContent[flavor];
totalCharge += 2./3.*eplus*theQuarkContent[flavor+1];
totalCharge += (-2./3.)*eplus*theAntiQuarkContent[flavor+1];
}
if (abs(totalCharge-thePDGCharge)>0.1*eplus) {
//#ifdef G4VERBOSE
//if (verboseLevel>0) {
// G4cerr << " illegal charge for baryon " << thePDGCharge/eplus;
// G4cerr << " PDG code=" << thePDGEncoding <<endl;
//}
//#endif
tempPDGcode = 0;
}
} else {
}
return tempPDGcode;
}
void G4ParticleDefinition::DumpTable() const
{
G4cout << endl;
G4cout << "--- G4ParticleDefinition ---" << endl;
G4cout << " Particle Name : " << theParticleName << endl;
G4cout << " PDG particle code : " << thePDGEncoding;
G4cout << " [PDG anti-particle code: " << this->GetAntiPDGEncoding() << "]"<< endl;
G4cout << " Mass [GeV/c2] : " << thePDGMass/GeV ;
G4cout << " Width : " << thePDGWidth/GeV << endl;
G4cout << " Lifetime [nsec] : " << thePDGLifeTime/ns << endl;
G4cout << " Charge [e]: " << thePDGCharge/eplus << endl;
G4cout << " Spin : " << thePDGiSpin << "/2" << endl;
G4cout << " Parity : " << thePDGiParity << endl;
G4cout << " Charge conjugation : " << thePDGiConjugation << endl;
G4cout << " Isospin : (I,Iz): (" << thePDGiIsospin <<"/2";
G4cout << " , " << thePDGiIsospin3 << "/2 ) " << endl;
G4cout << " GParity : " << thePDGiGParity << endl;
G4cout << " Quark contents (d,u,s,c,b,t) : " << theQuarkContent[0];
G4cout << ", " << theQuarkContent[1];
G4cout << ", " << theQuarkContent[2];
G4cout << ", " << theQuarkContent[3];
G4cout << ", " << theQuarkContent[4];
G4cout << ", " << theQuarkContent[5] << endl;
G4cout << " AntiQuark contents : " << theAntiQuarkContent[0];
G4cout << ", " << theAntiQuarkContent[1];
G4cout << ", " << theAntiQuarkContent[2];
G4cout << ", " << theAntiQuarkContent[3];
G4cout << ", " << theAntiQuarkContent[4];
G4cout << ", " << theAntiQuarkContent[5] << endl;
G4cout << " Lepton number : " << theLeptonNumber;
G4cout << " Baryon number : " << theBaryonNumber << endl;
G4cout << " Particle type : " << theParticleType << endl;
if ( fShortLivedFlag ){
G4cout << " ShortLived : ON" << endl;
}
if ( thePDGStable ){
G4cout << " Stable : stable" << endl;
} else {
if( theDecayTable != NULL ){
theDecayTable->DumpInfo();
} else {
G4cout << "Decay Table is not defined !!" <<endl;
}
}
if ( fApplyCutsFlag ){
G4cout << " ApplyCuts : ON" << endl;
} else {
G4cout << " ApplyCuts : OFF" << endl;
}
}
@@ -0,0 +1,159 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4ParticleMessenger.cc,v 2.5 1998/11/25 13:59:07 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
//---------------------------------------------------------------
//
// G4ParticleMessenger.cc
//
// Description:
// This is a messenger class to interface to exchange information
// between Particle related classes and UI.
//
// History:
// 13 June 1997, H. Kurashige : The 1st version created.
// 10 Nov. 1997 H. Kurashige : fixed bugs
// 08 Jan. 1998 H. Kurashige : new UIcommnds
// 08 June 1998, H. Kurashige : remove fProcessManagerMessenger
// 25 Nov. 1998, H. Kurashige : add /particle/find
//---------------------------------------------------------------
#include "G4ios.hh" // Include from 'system'
#include <iomanip.h> // Include from 'system'
#include "G4ParticleMessenger.hh"
#include "G4UImanager.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithAString.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4ParticleTable.hh"
#include "G4ParticleDefinition.hh"
#include "G4ParticlePropertyMessenger.hh"
G4ParticleMessenger::G4ParticleMessenger(G4ParticleTable* pTable)
{
// get the pointer to ParticleTable
if ( pTable == NULL) {
theParticleTable = G4ParticleTable::GetParticleTable();
} else {
theParticleTable = pTable;
}
//Directory /particle/
thisDirectory = new G4UIdirectory("/particle/");
thisDirectory->SetGuidance("Paricle control commands.");
//Commnad /particle/select
selectCmd = new G4UIcmdWithAString("/particle/select",this);
selectCmd->SetGuidance("Select particle ");
selectCmd->SetDefaultValue("none");
selectCmd->SetParameterName("particle name", false);
//Commnad /particle/list
listCmd = new G4UIcmdWithAString("/particle/list",this);
listCmd->SetGuidance("List name of particles.");
listCmd->SetGuidance(" all(default)/lepton/baryon/meson");
listCmd->SetParameterName("particle type", true);
listCmd->SetDefaultValue("all");
listCmd->SetCandidates("all lepton baryon meson");
//Commnad /particle/find
findCmd = new G4UIcmdWithAnInteger("/particle/find",this);
findCmd->SetGuidance("Find particle by encoding");
findCmd->SetDefaultValue(0);
findCmd->SetParameterName("encoding", false);
currentParticle = NULL;
//UI messenger for Particle Properties
fParticlePropertyMessenger = new G4ParticlePropertyMessenger(theParticleTable);
}
G4ParticleMessenger::~G4ParticleMessenger()
{
delete fParticlePropertyMessenger;
delete listCmd;
delete selectCmd;
delete thisDirectory;
delete findCmd;
}
void G4ParticleMessenger::SetNewValue(G4UIcommand * command,G4String newValues)
{
if( command==listCmd ){
//Commnad /particle/List
G4int counter = 0;
G4ParticleTable::G4PTblDicIterator *piter = theParticleTable->GetIterator();
piter -> reset();
while( (*piter)() ){
G4ParticleDefinition *particle = piter->value();
newValues.toLower();
if ((newValues=="all") || (newValues==particle->GetParticleType())) {
G4cout << setw(19) << particle->GetParticleName();
if ((counter++)%4 == 3) {
G4cout << endl;
} else {
G4cout << ",";
}
}
}
G4cout << endl;
if (counter == 0) G4cout << newValues << " is not found " << endl;
} else if( command==selectCmd ){
//Commnad /particle/select
currentParticle = theParticleTable->FindParticle(newValues);
if(currentParticle == NULL) {
G4cout << "Unknown particle [" << newValues << "]. Command ignored." << endl;
}
} else if( command==findCmd ){
//Commnad /particle/find
G4ParticleDefinition* tmp = theParticleTable->FindParticle( findCmd->GetNewIntValue(newValues));
if(tmp == NULL) {
G4cout << "Unknown particle [" << newValues << "]. Command ignored." << endl;
} else {
G4cout << tmp->GetParticleName() << endl;
tmp->DumpTable();
}
}
}
G4String G4ParticleMessenger::GetCurrentValue(G4UIcommand * command)
{
if( command==selectCmd ){
//Command /particle/select
// set candidate List
G4String candidates("none");
G4ParticleTable::G4PTblDicIterator *piter = theParticleTable->GetIterator();
piter -> reset();
while( (*piter)() ){
G4ParticleDefinition *particle = piter->value();
candidates += " " + particle->GetParticleName();
}
selectCmd->SetCandidates(candidates);
// current value
if(currentParticle == NULL) {
// no particle is selected. return null
return "none";
} else {
return currentParticle->GetParticleName();
}
}
return "";
}
@@ -0,0 +1,184 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4ParticlePropertyMessenger.cc,v 2.4 1998/07/13 17:18:47 urbi Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
//---------------------------------------------------------------
//
// G4ParticlePropertyMessenger.cc
//
// Description:
// This is a messenger class to interface to exchange information
// between ParticleDefinition and UI.
//
// History:
// 13 June 1997, H. Kurashige : The 1st version created.
// 10 Nov. 1997 H. Kurashige : fixed bugs
// 08 jan. 1998 H. Kurashige : new UIcommnds
// 19 June 1998 H. Kurashige : adds UnitCategory
//---------------------------------------------------------------
#include "G4ParticlePropertyMessenger.hh"
#include "G4UImanager.hh"
#include "G4UIdirectory.hh"
#include "G4UIcmdWithoutParameter.hh"
#include "G4UIcmdWithAnInteger.hh"
#include "G4UIcmdWithADoubleAndUnit.hh"
#include "G4UIcmdWithABool.hh"
#include "G4ParticleDefinition.hh"
#include "G4DecayTableMessenger.hh"
#include "G4ParticlePropertyMessenger.hh"
#include "G4ParticleTable.hh"
#include "G4ios.hh" // Include from 'system'
#include <iomanip.h> // Include from 'system'
G4ParticlePropertyMessenger::G4ParticlePropertyMessenger(G4ParticleTable* pTable)
:theParticleTable(pTable),
currentParticle(NULL),
fDecayTableMessenger(NULL)
{
if ( theParticleTable == NULL) theParticleTable = G4ParticleTable::GetParticleTable();
//Commnad /particle/property/
thisDirectory = new G4UIdirectory("/particle/property/");
thisDirectory->SetGuidance("Paricle Table control commands.");
//Commnad /particle/property/dump
dumpCmd = new G4UIcmdWithoutParameter("/particle/property/dump",this);
dumpCmd->SetGuidance("dump particle properties.");
//Command /particle/property/stable
stableCmd = new G4UIcmdWithABool("/particle/property/stable",this);
stableCmd->SetGuidance("Set stable flag.");
stableCmd->SetGuidance(" false: Unstable true: Stable");
stableCmd->SetParameterName("stable",false);
stableCmd->AvailableForStates(PreInit,Idle,GeomClosed);
//particle/property/lifetime
lifetimeCmd = new G4UIcmdWithADoubleAndUnit("/particle/property/lifetime",this);
lifetimeCmd->SetGuidance("Set life time.");
lifetimeCmd->SetGuidance("Unit of the time can be :");
lifetimeCmd->SetGuidance(" s, ms, ns (default)");
lifetimeCmd->SetParameterName("life",false);
lifetimeCmd->SetDefaultValue(0.0);
lifetimeCmd->SetRange("life >0.0");
//lifetimeCmd->SetUnitCategory("Time");
//lifetimeCmd->SetUnitCandidates("s ms ns");
lifetimeCmd->SetDefaultUnit("ns");
lifetimeCmd->AvailableForStates(PreInit,Idle,GeomClosed);
// -- particle/property/Verbose ---
verboseCmd = new G4UIcmdWithAnInteger("/particle/property/verbose",this);
verboseCmd->SetGuidance("Set Verbose level of particle property.");
verboseCmd->SetGuidance(" 0 : Silent (default)");
verboseCmd->SetGuidance(" 1 : Display warning messages");
verboseCmd->SetGuidance(" 2 : Display more");
verboseCmd->SetParameterName("verbose_level",true);
verboseCmd->SetDefaultValue(0);
verboseCmd->SetRange("verbose_level >=0");
//UI messenger for Decay Table
fDecayTableMessenger = new G4DecayTableMessenger(theParticleTable);
}
G4ParticlePropertyMessenger::~G4ParticlePropertyMessenger()
{
if (fDecayTableMessenger !=NULL) delete fDecayTableMessenger;
fDecayTableMessenger = NULL;
delete stableCmd;
delete verboseCmd;
delete lifetimeCmd;
delete dumpCmd;
delete thisDirectory;
}
void G4ParticlePropertyMessenger::SetNewValue(G4UIcommand * command,G4String newValue)
{
if (SetCurrentParticle()==NULL) {
G4cout << "Particle is not selected yet !! Command ignored." << endl;
return;
}
if( command == dumpCmd ){
//Commnad /particle/property/dump
currentParticle->DumpTable();
} else if (command == lifetimeCmd ) {
//Commnad /particle/property/lifetime
currentParticle->SetPDGLifeTime(lifetimeCmd->GetNewDoubleValue(newValue));
} else if (command == stableCmd ) {
//Commnad /particle/property/stable
if (currentParticle->GetPDGLifeTime()<0.0) {
G4cout << "Life time is negative! Command ignored." << endl;
} else if (currentParticle->GetPDGMass()<=0.0) {
G4cout << "Zero Mass! Command ignored." << endl;
} else {
currentParticle->SetPDGStable(stableCmd->GetNewBoolValue(newValue));
}
} else if( command==verboseCmd ) {
//Commnad /particle/property/Verbose
currentParticle->SetVerboseLevel(verboseCmd->GetNewIntValue(newValue));
}
}
G4ParticleDefinition* G4ParticlePropertyMessenger::SetCurrentParticle()
{
// set currentParticle pointer
// get particle name by asking G4ParticleMessenger via UImanager
G4String particleName = G4UImanager::GetUIpointer()->GetCurrentStringValue("/particle/select");
if (currentParticle != NULL ){
// check whether selection is changed
if (currentParticle->GetParticleName() != particleName) {
currentParticle = theParticleTable->FindParticle(particleName);
}
} else {
currentParticle = theParticleTable->FindParticle(particleName);
}
return currentParticle;
}
G4String G4ParticlePropertyMessenger::GetCurrentValue(G4UIcommand * command)
{
G4String returnValue('\0');
if (SetCurrentParticle()==NULL) {
// no particle is selected. return null
return returnValue;
}
if( command == stableCmd ){
//Commnad /particle/property/stable
returnValue = stableCmd->ConvertToString( currentParticle->GetPDGStable());
} else if( command == lifetimeCmd ){
//Commnad /particle/property/lifetime
returnValue = lifetimeCmd->ConvertToString( currentParticle->GetPDGLifeTime() , "ns" );
} else if( command==verboseCmd ){
//Commnad /particle/property/Verbose
returnValue= verboseCmd->ConvertToString(currentParticle ->GetVerboseLevel());
}
return returnValue;
}
@@ -0,0 +1,326 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4ParticleTable.cc,v 2.10 1998/11/13 17:37:33 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
// class G4ParticleTable
//
// Implementation
//
// History:
// modified Apr., 97 H.Kurashige
// added fParticleMessenger 14 Nov., 97 H.Kurashige
// added GetParticle() 13 Dec., 97 H.Kurashige
// added IonTable and ShortLivedTable 27 June, 98 H.Kurashige
// modified FindIon 02 Aug., 98 H.Kurashige
// added dictionary for encoding 24 Sep., 98 H.Kurashige
// fixed bugs in destruction of IonTable 08 Nov.,98 H.Kurashige
// commented out G4cout/G4cerr in the constructor 10 Nov.,98 H.Kurashige
#include "G4ios.hh"
#include "globals.hh"
#include "G4ParticleTable.hh"
#include "G4UImessenger.hh"
#include "G4ParticleMessenger.hh"
#include "G4IonTable.hh"
#include "G4ShortLivedTable.hh"
const G4int G4ParticleTableDefaultBucket = 32;
const G4int G4ParticleTableMaxInABucket = 64;
G4ParticleTable::G4ParticleTable():verboseLevel(0),fParticleMessenger(NULL)
{
DictionaryBucketSize = G4ParticleTableDefaultBucket;
fDictionary = new G4PTblDictionary(G4ParticleTable::HashFun,DictionaryBucketSize);
fIterator = new G4PTblDicIterator( *fDictionary );
fEncodingDictionary = new G4PTblEncodingDictionary(G4ParticleTable::EncodingHashFun,DictionaryBucketSize);
// Ion Table
fIonTable = new G4IonTable();
// short lived table
fShortLivedTable = new G4ShortLivedTable();
}
G4ParticleTable::~G4ParticleTable()
{
// delete G4String objects for key
G4String* pS;
if (fDictionary->entries()>0){
fIterator -> reset();
while( (*fIterator)() ){
if (pS = fIterator -> key()) delete pS;
}
fDictionary -> clear();
}
delete fIterator;
delete fDictionary;
if (fParticleMessenger!=NULL) delete fParticleMessenger;
// delete dictionary for encoding
if (fEncodingDictionary!=NULL){
fEncodingDictionary -> clear();
delete fEncodingDictionary;
}
//delete Ion Table and contents
if (fIonTable!=NULL) delete fIonTable;
// delete Short Lived table and contents
if (fShortLivedTable!=NULL) delete fShortLivedTable;
}
G4ParticleTable::G4ParticleTable(const G4ParticleTable &right)
{
G4Exception("you call copy constructor of G4ParticleTable");
fDictionary = new G4PTblDictionary(*(right.fDictionary));
fIterator = new G4PTblDicIterator(*fDictionary);
}
// Static class variable: ptr to single instance of class
G4ParticleTable* G4ParticleTable::fgParticleTable =0;
G4ParticleTable* G4ParticleTable::GetParticleTable()
{
static G4ParticleTable theParticleTable;
if (!fgParticleTable){
fgParticleTable = &theParticleTable;
}
return fgParticleTable;
}
G4UImessenger* G4ParticleTable::CreateMessenger()
{
if (fParticleMessenger== NULL) {
//UI messenger
fParticleMessenger = new G4ParticleMessenger(this);
}
return fParticleMessenger;
}
void G4ParticleTable::DeleteMessenger()
{
if (fParticleMessenger!= NULL) {
//UI messenger
delete fParticleMessenger;
fParticleMessenger= NULL;
// remove all items from G4ParticleTable
RemoveAllParticles();
}
}
void G4ParticleTable::RemoveAllParticles()
{
#ifdef G4VERBOSE
if (verboseLevel>1){
G4cerr << "G4ParticleTable::RemoveAllParticles() " << endl;
}
#endif
//delete Ion Table and contents
if (fIonTable!=NULL) {
delete fIonTable;
fIonTable = NULL;
}
// delete Short Lived table and contents
if (fShortLivedTable!=NULL) {
delete fShortLivedTable;
fShortLivedTable = NULL;
}
// delete dictionary for encoding
if (fEncodingDictionary!=NULL){
G4int* pCode;
G4PTblEncodingDicIterator* fEncodeIterator;
fEncodeIterator = new G4PTblEncodingDicIterator(*fEncodingDictionary);
fEncodeIterator-> reset();
while( (*fEncodeIterator)() ){
if (pCode = fEncodeIterator-> key()) delete pCode;
}
fEncodingDictionary -> clear();
delete fEncodeIterator;
delete fEncodingDictionary;
fEncodingDictionary = NULL;
}
// delete G4String objects for key
G4String* pS;
fIterator -> reset();
while( (*fIterator)() ){
if (pS = fIterator -> key()) delete pS;
}
fDictionary -> clear();
}
G4ParticleDefinition* G4ParticleTable::Insert(G4ParticleDefinition *particle)
{
// check particle name
if ((particle == NULL) || (GetKey(particle).isNull())) {
//#ifdef G4VERBOSE
//if (verboseLevel>0){
// G4cerr << "The particle[Addr:" << particle << "] has no name "<< endl;
//}
//#endif
return NULL;
}else {
if (contains(particle)) {
//#ifdef G4VERBOSE
//if (verboseLevel>1){
// G4cerr << "The particle[Addr:" << particle;
// G4cerr << "] has same name as "<< endl;
// FindParticle(particle) -> DumpTable();
//}
//#endif
return FindParticle(particle);
} else {
G4PTblDictionary *pdic = GetDictionary();
pdic -> insertKeyAndValue(new G4String(GetKey(particle)), particle);
// if HashDictionary get too big, rehash all of the key
if (pdic -> entries() > G4ParticleTableMaxInABucket*DictionaryBucketSize) {
DictionaryBucketSize *= 2;
pdic -> resize(DictionaryBucketSize);
G4PTblDicIterator *piter = GetIterator();
piter -> reset();
}
// insert into EncodingDictionary
G4int code = particle->GetPDGEncoding();
if (code !=0 ) {
G4PTblEncodingDictionary *pedic = GetEncodingDictionary();
pedic -> insertKeyAndValue(new G4int(code), particle);
}
// insert it in IonTable if "nucleus"
if (fIonTable->IsIon(particle) ){
fIonTable->Insert(particle);
}
// insert it in SHortLivedTable if "shortlived"
if (particle->IsShortLived() ){
fShortLivedTable->Insert(particle);
}
return particle;
}
}
}
G4ParticleDefinition* G4ParticleTable::Remove(G4ParticleDefinition* particle)
{
if (! contains(particle) ) return NULL;
G4String particle_name = GetKey(particle);
fDictionary->remove(&particle_name );
// remove from EncodingDictionary
G4int code = particle->GetPDGEncoding();
if (code !=0 ) {
G4PTblEncodingDictionary *pedic = GetEncodingDictionary();
pedic -> remove(&code);
}
// remove it from IonTable if "nucleus"
if (fIonTable->IsIon(particle) ){
fIonTable->Remove(particle);
}
// Remove it from ShortLivedTable if "shortlived"
if (particle->IsShortLived() ){
fShortLivedTable->Remove(particle);
}
return particle;
}
G4ParticleDefinition* G4ParticleTable::FindIon(G4int Z, G4int A, G4int J, G4int Q)
{
if (Z<=0) return NULL;
if (A<Z) return NULL;
if (J<0) return NULL;
if (Q<0) Q=Z;
return fIonTable->GetIon(Z, A, J, Q);
}
G4ParticleDefinition* G4ParticleTable::GetParticle(G4int index)
{
if ( (index >=0) && (index < entries()) ) {
G4PTblDicIterator *piter = GetIterator();
piter -> reset();
G4int counter = 0;
while( (*piter)() ){
if ( counter == index ) return piter->value();
counter++;
}
}
#ifdef G4VERBOSE
if (verboseLevel>0){
G4cerr << " G4ParticleTable::GetParticle";
G4cerr << " invalid index (=" << index << ")" << endl;
}
#endif
return NULL;
}
G4ParticleDefinition* G4ParticleTable::FindParticle(G4int aPDGEncoding ) const
{
// check aPDGEncoding is valid
if (aPDGEncoding == 0){
#ifdef G4VERBOSE
if (verboseLevel>0){
G4cerr << "PDGEncoding [" << aPDGEncoding << "] is not valid " << endl;
}
#endif
return NULL;
}
G4PTblEncodingDictionary *pedic = GetEncodingDictionary();
G4ParticleDefinition* particle = pedic -> findValue( &aPDGEncoding );
#ifdef G4VERBOSE
if ((particle == NULL) && (verboseLevel>0) ){
G4cerr << "CODE:" << aPDGEncoding << " does not exist in ParticleTable " << endl;
}
#endif
return particle;
}
void G4ParticleTable::DumpTable(const G4String &particle_name) const
{
if (( particle_name == "ALL" ) || (particle_name == "all")){
// dump all particles
G4PTblDicIterator *piter = GetIterator();
piter -> reset();
while( (*piter)() ){
(piter->value())->DumpTable();
}
} else {
// dump only particle with name of particle_name
G4ParticleDefinition *ptr;
if ( (ptr = FindParticle(particle_name)) != NULL) {
ptr->DumpTable();
} else {
#ifdef G4VERBOSE
if (verboseLevel>0){
G4cout << particle_name << " does not exist in ParticleTable " <<endl;
}
#endif
}
}
}
@@ -0,0 +1,590 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4ParticleWithCuts.cc,v 2.12 1998/11/28 08:24:17 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
//
// For information related to this code contact:
// CERN, IT Division, ASD Group
// Hisaya Kurashige, 21 Oct 1996
// Hisaya Kurashige, 04 Jan 1997
// --------------------------------------------------------------
// New Physics scheme 8 Jan. 1997 H.Kurahige
// The cut in kinetic energy is set to zero for vacuum,
// bug in ConvertCutToKineticEnergy is corrected . L.Urban 04/04/97
// remove sprintf 10 Nov. 1997 H.Kurashige
// remove BuildPhysicTabel() 06 June 1998 H.Kurashige
// bug in CalcEnergyCuts is corrected , 22 June 1998 L.Urban
// modify CalcEnergyCuts 09 Nov. 1998, L.Urban
// ------------------------------------------------------------
#include "globals.hh"
#include "G4ParticleWithCuts.hh"
#include "G4ParticleTable.hh"
#include "G4Material.hh"
#include "G4PhysicsLogVector.hh"
G4double G4ParticleWithCuts::LowestEnergy = 0.99e-3*MeV;
G4double G4ParticleWithCuts::HighestEnergy = 100.0e6*MeV;
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),
NumberOfElements(0),
theLossTable(NULL),
//-- members initialisation for SetCuts ------------------------------
theCutInMaxInteractionLength(-1.0),
theKineticEnergyCuts(NULL)
{
// -- set ApplyCutsFlag in default ----------
SetApplyCutsFlag(false);
//-- default values for SetCuts ------------------------------
// Lowest/Highest energy is defined in MeV
TotBin = 200;
}
G4ParticleWithCuts::~G4ParticleWithCuts()
{
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(G4Element::GetNumberOfElements());
#ifdef G4VERBOSE
if (GetVerboseLevel()>2) {
G4cerr << "G4ParticleWithCuts::BuildLossTable() ";
G4cerr << "Create theLossTable[" << theLossTable << "]";
G4cerr << " NumberOfElements=" << NumberOfElements <<endl;
}
#endif
} else {
if (NumberOfElements != G4Element::GetNumberOfElements())
{
G4String aErrorMessage("Error in G4ParticlWithCuts::BuildLossTable()");
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cerr << aErrorMessage;
G4cerr << "[" << this->GetParticleName() << "] " <<endl;
G4cerr <<"inconsistent G4Element::GetNumberOfElements";
G4cerr << G4Element::GetNumberOfElements();
G4cerr << " previous value" << NumberOfElements << endl;
}
#endif
G4Exception((const char*)aErrorMessage);
}
}
// 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) 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 <= r1 )
return T1;
if ( theCutInMaxInteractionLength >= rmax )
{
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cerr << "Error in G4ParticleWithCuts::ConvertCutToKineticEnergy" <<endl;
G4cerr << "******** ConvertCutToKineticEnergy for " << GetParticleName();
G4cerr << " ********************" << endl;
G4cerr << "The cut energy is set " << DBL_MAX/GeV << "GeV " <<endl;
}
#endif
return DBL_MAX;
} else {
G4double T2 = Tmax ;
G4double T3 = sqrt(T1*T2);
G4double r3 = rangeVector->GetValue(T3,isOut);
while ( abs(1.-r3/theCutInMaxInteractionLength)>epsilon )
{
if ( theCutInMaxInteractionLength <= r3 ) {
T2 = T3;
} else {
T1 = T3;
}
T3 = sqrt(T1*T2);
r3 = rangeVector->GetValue(T3,isOut);
}
return T3;
}
}
// **********************************************************************
// **************************** SetCuts *********************************
// **********************************************************************
void G4ParticleWithCuts::CalcEnergyCuts(G4double aCut)
{
// check LowestEnergy/ HighestEnergy/TotBin
if (TotBin<1) {
G4String aErrorMessage("Error in G4ParticlWithCuts::G4ParticlWithCuts");
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cerr << aErrorMessage;
G4cerr << "[" << this->GetParticleName() << "]" << endl;
G4cerr << "not defined or illegal TotBin [" << TotBin << "]" <<endl;
}
#endif
G4Exception((const char*)aErrorMessage);
}
if ( (LowestEnergy<0.0)||(HighestEnergy<=LowestEnergy) ){
G4String aErrorMessage("Error in G4ParticlWithCuts::G4ParticlWithCuts");
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cerr << aErrorMessage;
G4cerr << "[" << this->GetParticleName() << "]" << endl;
G4cerr << " illegal energy range" << "(" << LowestEnergy/GeV;
G4cerr << "," << HighestEnergy/GeV << ") [GeV]" <<endl;
}
#endif
G4Exception((const char*)aErrorMessage);
}
// Set cut in stopping range
theCutInMaxInteractionLength = aCut;
const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
// Create the vector of cuts in energy
// corresponding to the stopping range cut
if(theKineticEnergyCuts) delete [] theKineticEnergyCuts;
theKineticEnergyCuts = new G4double [materialTable->length()];
G4double Charge = this->GetPDGCharge() ;
G4ParticleDefinition* theProton = G4ParticleTable::GetParticleTable()->FindParticle("proton");
G4bool useProtonCut =
((GetParticleName() != "gamma" ) &&
(GetParticleName() != "e-" ) &&
(GetParticleName() != "e+" ) &&
(GetParticleName() != "mu-" ) &&
(GetParticleName() != "mu+" ) &&
(GetParticleName() != "proton" ) &&
(GetParticleName() != "anti_proton" ) &&
(Charge != 0.) );
if (useProtonCut) {
if (theProton ==NULL) {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cerr << " G4ParticleWithCuts::CalcEnergyCuts ";
G4cerr << " proton is not defined !!" << endl;
}
#endif
useProtonCut = false;
}
if (theProton->GetEnergyCuts()==NULL) {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cerr << " G4ParticleWithCuts::CalcEnergyCuts ";
G4cerr << " proton energy cut is not defined !!" << endl;
}
#endif
G4Exception("G4ParticleWithCuts::CalcEnergyCuts");
}
}
if ( useProtonCut &&
( abs(aCut-theProton->GetLengthCuts())<1.*nanometer) ){
// use energy cuts for Proton
#ifdef G4VERBOSE
if (GetVerboseLevel()>2) {
G4cerr << " G4ParticleWithCuts: [" << GetParticleName() <<"]";
G4cerr << " user Proton Cut " << endl;
}
#endif
G4double ChargeSquare = Charge*Charge ;
G4double massRatio = proton_mass_c2/(this->GetPDGMass()) ;
for (G4int J=0; J<materialTable->length(); J +=1) {
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 {
#ifdef G4VERBOSE
if (GetVerboseLevel()>2) {
G4cerr << " G4ParticleWithCuts: [" << GetParticleName() <<"]";
G4cerr << " calcurate by using its own loss table " << endl;
}
#endif
// 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 ;
for (G4int J=0; J<materialTable->length(); J +=1){
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);
if( ((GetParticleName()=="e-")||(GetParticleName()=="e+"))
&& (theKineticEnergyCuts[J] < lowen) ) {
theKineticEnergyCuts[J] /= (1.+tune/(aCut*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 == NULL) {
G4String aErrorMessage("Error in G4ParticleWithCuts::BuildRangeVector()");
#ifdef G4VERBOSE
if (GetVerboseLevel() >0) {
G4cerr << aErrorMessage << "[" << this->GetParticleName() << "] " << endl;
G4cerr << "NULL pointer is found in absorptionLengthVector" << endl;
}
#endif
G4Exception((const char*)aErrorMessage);
}
// 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 ltaulim = log(taulim);
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 >= rmax) {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cerr << "Error in G4ParticleWithCuts::BuildRangeVector()" << endl;
G4cerr << " SetCuts for " << GetParticleName() << endl;
G4cerr << "The maximal meaningful cut is " << rmax/mm << " mm." << endl;
G4cerr << "All the " << GetParticleName() << "will be killed !" << endl;
G4cerr << "in the material " << aMaterial->GetName() << "." << endl;
}
#endif
}
}
@@ -0,0 +1,485 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4PhaseSpaceDecayChannel.cc,v 2.5 1998/11/18 09:46:39 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
//
// For information related to this code contact:
// CERN, CN Division, ASD group
// History: first implementation, based on object model of
// 27 July 1996 H.Kurashige
// 20 Oct 1996 H.Kurashige
// 30 May 1997 H.Kurashige
// ------------------------------------------------------------
#include "G4ParticleDefinition.hh"
#include "G4DecayProducts.hh"
#include "G4VDecayChannel.hh"
#include "G4PhaseSpaceDecayChannel.hh"
#include "Randomize.hh"
#include "G4LorentzVector.hh"
#include "G4LorentzRotation.hh"
G4PhaseSpaceDecayChannel::G4PhaseSpaceDecayChannel(G4int Verbose)
:G4VDecayChannel("Phase Space", Verbose)
{
}
G4PhaseSpaceDecayChannel::G4PhaseSpaceDecayChannel(
const G4String& theParentName,
G4double theBR,
G4int theNumberOfDaughters,
const G4String& theDaughterName1,
const G4String& theDaughterName2,
const G4String& theDaughterName3,
const G4String& theDaughterName4 )
:G4VDecayChannel("Phase Space",
theParentName,theBR,
theNumberOfDaughters,
theDaughterName1,
theDaughterName2,
theDaughterName3,
theDaughterName4)
{
}
G4PhaseSpaceDecayChannel::~G4PhaseSpaceDecayChannel()
{
}
G4DecayProducts *G4PhaseSpaceDecayChannel::DecayIt(G4double parentMass)
{
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) G4cout << "G4PhaseSpaceDecayChannel::DecayIt ";
#endif
G4DecayProducts * products = NULL;
if (parent == NULL) FillParent();
if (daughters == NULL) FillDaughters();
if (parentMass >0.0) parent_mass = parentMass;
switch (numberOfDaughters){
case 0:
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cout << "G4PhaseSpaceDecayChannel::DecayIt ";
G4cout << " daughters not defined " <<endl;
}
#endif
break;
case 1:
products = OneBodyDecayIt();
break;
case 2:
products = TwoBodyDecayIt();
break;
case 3:
products = ThreeBodyDecayIt();
break;
default:
products = ManyBodyDecayIt();
break;
}
#ifdef G4VERBOSE
if ((products == NULL) && (GetVerboseLevel()>0)) {
G4cout << "G4PhaseSpaceDecayChannel::DecayIt ";
G4cout << *parent_name << " can not decay " << endl;
DumpInfo();
}
#endif
return products;
}
G4DecayProducts *G4PhaseSpaceDecayChannel::OneBodyDecayIt()
{
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) G4cout << "G4PhaseSpaceDecayChannel::OneBodyDecayIt()"<<endl;
#endif
G4double parentmass = parent_mass;
G4double daughtermass = daughters_mass[0];
//create parent G4DynamicParticle at rest
G4ParticleMomentum dummy;
G4DynamicParticle * parentparticle = new G4DynamicParticle( parent, dummy, 0.0);
//create G4Decayproducts
G4DecayProducts *products = new G4DecayProducts(*parentparticle);
delete parentparticle;
//create daughter G4DynamicParticle at rest
G4DynamicParticle * daughterparticle = new G4DynamicParticle( daughters[0], dummy, 0.0);
products->PushProducts(daughterparticle);
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cout << "G4PhaseSpaceDecayChannel::OneBodyDecayIt ";
G4cout << " create decay products in rest frame " <<endl;
products->DumpInfo();
}
#endif
return products;
}
G4DecayProducts *G4PhaseSpaceDecayChannel::TwoBodyDecayIt()
{
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) G4cout << "G4PhaseSpaceDecayChannel::TwoBodyDecayIt()"<<endl;
#endif
// parent mass
G4double parentmass = parent_mass;
//daughters'mass
G4double daughtermass[2];
G4double daughtermomentum;
daughtermass[0] = daughters_mass[0];
daughtermass[1] = daughters_mass[1];
G4double sumofdaughtermass = daughtermass[0] + daughtermass[1];
//create parent G4DynamicParticle at rest
G4ParticleMomentum dummy;
G4DynamicParticle * parentparticle = new G4DynamicParticle( parent, dummy, 0.0);
//create G4Decayproducts
G4DecayProducts *products = new G4DecayProducts(*parentparticle);
delete parentparticle;
//calculate daughter momentum
daughtermomentum = Pmx(parentmass,daughtermass[0],daughtermass[1]);
G4double costheta = 2.*G4UniformRand()-1.0;
G4double sintheta = sqrt((1.0 - costheta)*(1.0 + costheta));
G4double phi = 2.0*M_PI*G4UniformRand()*rad;
G4ParticleMomentum direction(sintheta*cos(phi),sintheta*sin(phi),costheta);
//create daughter G4DynamicParticle
G4DynamicParticle * daughterparticle = new G4DynamicParticle( daughters[0], direction*daughtermomentum);
products->PushProducts(daughterparticle);
daughterparticle = new G4DynamicParticle( daughters[1], direction*(-1.0*daughtermomentum));
products->PushProducts(daughterparticle);
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cout << "G4PhaseSpaceDecayChannel::TwoBodyDecayIt ";
G4cout << " create decay products in rest frame " <<endl;
products->DumpInfo();
}
#endif
return products;
}
G4DecayProducts *G4PhaseSpaceDecayChannel::ThreeBodyDecayIt()
// algorism of this code is originally written in GDECA3 of GEANT3
{
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) G4cout << "G4PhaseSpaceDecayChannel::ThreeBodyDecayIt()"<<endl;
#endif
// parent mass
G4double parentmass = parent_mass;
//daughters'mass
G4double daughtermass[3];
G4double sumofdaughtermass = 0.0;
for (G4int index=0; index<3; index++){
daughtermass[index] = daughters_mass[index];
sumofdaughtermass += daughtermass[index];
}
//create parent G4DynamicParticle at rest
G4ParticleMomentum dummy;
G4DynamicParticle * parentparticle = new G4DynamicParticle( parent, dummy, 0.0);
//create G4Decayproducts
G4DecayProducts *products = new G4DecayProducts(*parentparticle);
delete parentparticle;
//calculate daughter momentum
// Generate two
G4double rd1, rd2, rd;
G4double daughtermomentum[3];
G4double momentummax=0.0, momentumsum = 0.0;
G4double energy;
do {
rd1 = G4UniformRand();
rd2 = G4UniformRand();
if (rd2 > rd1) {
rd = rd1;
rd1 = rd2;
rd2 = rd;
}
momentummax = 0.0;
momentumsum = 0.0;
// daughter 0
energy = rd2*(parentmass - sumofdaughtermass);
daughtermomentum[0] = sqrt(energy*energy + 2.0*energy* daughtermass[0]);
if ( daughtermomentum[0] >momentummax )momentummax = daughtermomentum[0];
momentumsum += daughtermomentum[0];
// daughter 1
energy = (1.-rd1)*(parentmass - sumofdaughtermass);
daughtermomentum[1] = sqrt(energy*energy + 2.0*energy* daughtermass[1]);
if ( daughtermomentum[1] >momentummax )momentummax = daughtermomentum[1];
momentumsum += daughtermomentum[1];
// daughter 2
energy = (rd1-rd2)*(parentmass - sumofdaughtermass);
daughtermomentum[2] = sqrt(energy*energy + 2.0*energy* daughtermass[2]);
if ( daughtermomentum[2] >momentummax )momentummax = daughtermomentum[2];
momentumsum += daughtermomentum[2];
} while (momentummax > momentumsum - momentummax );
// output message
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cout << " daughter 0:" << daughtermomentum[0]/GeV << "[GeV/c]" <<endl;
G4cout << " daughter 1:" << daughtermomentum[1]/GeV << "[GeV/c]" <<endl;
G4cout << " daughter 2:" << daughtermomentum[2]/GeV << "[GeV/c]" <<endl;
G4cout << " momentum sum:" << momentumsum/GeV << "[GeV/c]" <<endl;
}
#endif
//create daughter G4DynamicParticle
G4double costheta, sintheta, phi, sinphi, cosphi;
G4double costhetan, sinthetan, phin, sinphin, cosphin;
costheta = 2.*G4UniformRand()-1.0;
sintheta = sqrt((1.0-costheta)*(1.0+costheta));
phi = 2.0*M_PI*G4UniformRand()*rad;
sinphi = sin(phi);
cosphi = cos(phi);
G4ParticleMomentum direction0(sintheta*cosphi,sintheta*sinphi,costheta);
G4DynamicParticle * daughterparticle
= new G4DynamicParticle( daughters[0], direction0*daughtermomentum[0]);
products->PushProducts(daughterparticle);
costhetan = (daughtermomentum[1]*daughtermomentum[1]-daughtermomentum[2]*daughtermomentum[2]-daughtermomentum[0]*daughtermomentum[0])/(2.0*daughtermomentum[2]*daughtermomentum[0]);
sinthetan = sqrt((1.0-costhetan)*(1.0+costhetan));
phin = 2.0*M_PI*G4UniformRand()*rad;
sinphin = sin(phin);
cosphin = cos(phin);
G4ParticleMomentum direction2;
direction2.setX( sinthetan*cosphin*costheta*cosphi - sinthetan*sinphin*sinphi + costhetan*sintheta*cosphi);
direction2.setY( sinthetan*cosphin*costheta*sinphi + sinthetan*sinphin*cosphi + costhetan*sintheta*sinphi);
direction2.setZ( -sinthetan*cosphin*sintheta + costhetan*costheta);
daughterparticle = new G4DynamicParticle( daughters[2], direction2*(daughtermomentum[2]/direction2.mag()));
products->PushProducts(daughterparticle);
daughterparticle =
new G4DynamicParticle(
daughters[1],
(direction0*daughtermomentum[0] + direction2*(daughtermomentum[2]/direction2.mag()))*(-1.0)
);
products->PushProducts(daughterparticle);
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cout << "G4PhaseSpaceDecayChannel::ThreeBodyDecayIt ";
G4cout << " create decay products in rest frame " <<endl;
products->DumpInfo();
}
#endif
return products;
}
G4DecayProducts *G4PhaseSpaceDecayChannel::ManyBodyDecayIt()
// algorithm of this code is originally written in FORTRAN by M.Asai
//******************************************************************
// NBODY
// N-body phase space Monte-Carlo generator
// Makoto Asai
// Hiroshima Institute of Technology
// (asai@kekvax.kek.jp)
// Revised release : 19/Apr/1995
//
{
G4int index, index2;
//return value
G4DecayProducts *products;
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) G4cout << "G4PhaseSpaceDecayChannel::ManyBodyDecayIt()"<<endl;
#endif
// parent mass
G4double parentmass = parent_mass;
//daughters'mass
G4double *daughtermass = new G4double[numberOfDaughters];
G4double sumofdaughtermass = 0.0;
for (index=0; index<numberOfDaughters; index++){
daughtermass[index] = daughters_mass[index];
sumofdaughtermass += daughtermass[index];
}
//Calculate daughter momentum
G4double *daughtermomentum = new G4double[numberOfDaughters];
G4ParticleMomentum direction;
G4DynamicParticle **daughterparticle;
G4double *sm = new G4double[numberOfDaughters];
G4double tmas;
G4double weight = 1.0;
G4int numberOfTry = 0;
do {
//Generate rundom number in descending order
G4double temp;
G4double *rd = new G4double[numberOfDaughters];
rd[0] = 1.0;
for(index =1; index < numberOfDaughters -1; index++) rd[index] = G4UniformRand();
rd[ numberOfDaughters -1] = 0.0;
for(index =1; index < numberOfDaughters -1; index++) {
for(index2 = index+1; index2 < numberOfDaughters; index2++) {
if (rd[index] < rd[index2]){
temp = rd[index];
rd[index] = rd[index2];
rd[index2] = temp;
}
}
}
//calcurate virtual mass
tmas = parentmass - sumofdaughtermass;
temp = sumofdaughtermass;
for(index =0; index < numberOfDaughters; index++) {
sm[index] = rd[index]*tmas + temp;
temp -= daughtermass[index];
if (GetVerboseLevel()>1) {
G4cout << index << " rundom number:" << rd[index];
G4cout << " virtual mass:" << sm[index]/GeV << "[GeV/c/c]" <<endl;
}
}
delete [] rd;
//Calculate daughter momentum
weight = 1.0;
index =numberOfDaughters-1;
daughtermomentum[index]= Pmx( sm[index-1],daughtermass[index-1], sm[index]);
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cout << " daughter " << index << ":" << *daughters_name[index];
G4cout << " momentum:" << daughtermomentum[index]/GeV << "[GeV/c]" <<endl;
}
#endif
for(index =numberOfDaughters-2; index>=0; index--) {
// calculate
daughtermomentum[index]= Pmx( sm[index],daughtermass[index], sm[index +1]);
if(daughtermomentum[index] < 0.0) {
// !!! illegal momentum !!!
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cout << "G4PhaseSpaceDecayChannel::ManyBodyDecayIt ";
G4cout << " can not calculate daughter momentum " <<endl;
G4cout << " parent:" << *parent_name;
G4cout << " mass:" << parentmass/GeV << "[GeV/c/c]" <<endl;
G4cout << " daughter " << index << ":" << *daughters_name[index];
G4cout << " mass:" << daughtermass[index]/GeV << "[GeV/c/c]" ;
G4cout << " mass:" << daughtermomentum[index]/GeV << "[GeV/c]" <<endl;
}
#endif
delete [] sm;
delete [] daughtermass;
delete [] daughtermomentum;
return NULL; // Error detection
} else {
// calculate weight of this events
weight *= daughtermomentum[index]/sm[index];
if (GetVerboseLevel()>1) {
G4cout << " daughter " << index << ":" << *daughters_name[index];
G4cout << " momentum:" << daughtermomentum[index]/GeV << "[GeV/c]" <<endl;
}
}
}
if (GetVerboseLevel()>1) {
G4cout << " weight: " << weight <<endl;
}
// exit if number of Try exceeds 100
if (numberOfTry++ >100) {
if (GetVerboseLevel()>0) {
G4cout << "G4PhaseSpaceDecayChannel::ManyBodyDecayIt: ";
G4cout << " can not determine Decay Kinematics " << endl;
}
delete [] sm;
delete [] daughtermass;
delete [] daughtermomentum;
return NULL; // Error detection
}
} while ( weight > G4UniformRand());
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cout << "Start calulation of daughters momentum vector "<<endl;
}
#endif
G4double costheta, sintheta, phi;
G4double beta;
daughterparticle = new G4DynamicParticle*[numberOfDaughters];
index = numberOfDaughters -2;
costheta = 2.*G4UniformRand()-1.0;
sintheta = sqrt((1.0-costheta)*(1.0+costheta));
phi = 2.0*M_PI*G4UniformRand()*rad;
direction.setZ(costheta);
direction.setY(sintheta*sin(phi));
direction.setX(sintheta*cos(phi));
daughterparticle[index] = new G4DynamicParticle( daughters[index], direction*daughtermomentum[index] );
daughterparticle[index+1] = new G4DynamicParticle( daughters[index+1], direction*(-1.0*daughtermomentum[index]) );
for (index = numberOfDaughters -3; index >= 0; index--) {
//calculate momentum direction
costheta = 2.*G4UniformRand()-1.0;
sintheta = sqrt((1.0-costheta)*(1.0+costheta));
phi = 2.0*M_PI*G4UniformRand()*rad;
direction.setZ(costheta);
direction.setY(sintheta*sin(phi));
direction.setX(sintheta*cos(phi));
// boost already created particles
beta = daughtermomentum[index];
beta /= sqrt( daughtermomentum[index]*daughtermomentum[index] + sm[index+1]*sm[index+1] );
for (G4int index2 = index+1; index2<numberOfDaughters; index2++) {
G4LorentzVector p4;
// make G4LorentzVector for secondaries
p4 = daughterparticle[index2]->Get4Momentum();
// boost secondaries to new frame
p4.boost( direction.x()*beta, direction.y()*beta, direction.z()*beta);
// change energy/momentum
daughterparticle[index2]->Set4Momentum(p4);
}
//create daughter G4DynamicParticle
daughterparticle[index]= new G4DynamicParticle( daughters[index], direction*(-1.0*daughtermomentum[index]));
}
//create G4Decayproducts
G4DynamicParticle *parentparticle;
direction.setX(1.0); direction.setY(0.0); direction.setZ(0.0);
parentparticle = new G4DynamicParticle( parent, direction, 0.0);
products = new G4DecayProducts(*parentparticle);
delete parentparticle;
for (index = 0; index<numberOfDaughters; index++) {
products->PushProducts(daughterparticle[index]);
}
#ifdef G4VERBOSE
if (GetVerboseLevel()>1) {
G4cout << "G4PhaseSpaceDecayChannel::ManyBodyDecayIt ";
G4cout << " create decay products in rest frame " << endl;
products->DumpInfo();
}
#endif
delete [] daughterparticle;
delete [] daughtermomentum;
delete [] daughtermass;
delete [] sm;
return products;
}
@@ -0,0 +1,96 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4ShortLivedTable.cc,v 2.4 1998/11/13 17:04:52 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// --------------------------------------------------------------
// GEANT 4 class implementation file
//
// For information related to this code contact:
// CERN, IT Division, ASD Group
// History: first implementation, based on object model of
// 27 June 1998 H.Kurashige
// ------------------------------------------------------------
// added Remove() 06 Nov.,98 H.Kurashige
#include "G4ShortLivedTable.hh"
#include "G4ParticleTable.hh"
#include "G4ios.hh"
#ifdef WIN32
# include <Strstrea.h>
#else
# include <strstream.h>
#endif
G4ShortLivedTable::G4ShortLivedTable()
{
fShortLivedList = new G4ShortLivedList();
}
G4ShortLivedTable::~G4ShortLivedTable()
{
// remove all contents in the short lived List and delete all particles
fShortLivedList->clearAndDestroy();
delete fShortLivedList;
}
G4int G4ShortLivedTable::GetVerboseLevel() const
{
return G4ParticleTable::GetParticleTable()->GetVerboseLevel();
}
G4bool G4ShortLivedTable::IsShortLived(G4ParticleDefinition* particle) const
{
return particle->IsShortLived();
}
void G4ShortLivedTable::Insert(G4ParticleDefinition* particle)
{
if (IsShortLived(particle)) {
fShortLivedList->insert(particle);
} else {
//#ifdef G4VERBOSE
//if (GetVerboseLevel()>0) {
// G4cerr << "G4ShortLivedTable::Insert :" << particle->GetParticleName() ;
// G4cerr << " is not short lived" << endl;
//}
//#endif
}
}
void G4ShortLivedTable::Remove(G4ParticleDefinition* particle)
{
if (IsShortLived(particle)) {
fShortLivedList->remove(particle);
} else {
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cerr << "G4ShortLivedTable::Remove :" << particle->GetParticleName() ;
G4cerr << " is not short lived" << endl;
}
#endif
}
}
void G4ShortLivedTable::DumpTable(const G4String &particle_name) const
{
for (G4int idx= 0; idx < fShortLivedList->entries() ; idx++) {
if (( particle_name == "ALL" ) || (particle_name == "all")){
((*fShortLivedList)(idx))->DumpTable();
} else if ( particle_name == ((*fShortLivedList)(idx))->GetParticleName() ) {
((*fShortLivedList)(idx))->DumpTable();
}
}
}
@@ -0,0 +1,379 @@
// This code implementation is the intellectual property of
// the RD44 GEANT4 collaboration.
//
// By copying, distributing or modifying the Program (or any work
// based on the Program) you indicate your acceptance of this statement,
// and all its terms.
//
// $Id: G4VDecayChannel.cc,v 2.5 1998/11/18 09:46:41 kurasige Exp $
// GEANT4 tag $Name: geant4-00 $
//
//
// ------------------------------------------------------------
// GEANT 4 class header file
//
// For information related to this code contact:
// CERN, CN Division, ASD group
// History: first implementation, based on object model of
// 27 July 1996 H.Kurashige
// 30 May 1997 H.Kurashige
// ------------------------------------------------------------
#include "G4ParticleDefinition.hh"
#include "G4ParticleTable.hh"
#include "G4DecayTable.hh"
#include "G4DecayProducts.hh"
#include "G4VDecayChannel.hh"
G4VDecayChannel::G4VDecayChannel(const G4String &aName, G4int Verbose)
:kinematics_name(aName),
verboseLevel(Verbose),rbranch(0.0),
numberOfDaughters(0),
parent_name(NULL),parent(NULL),parent_mass(0.0),
daughters_name(NULL),daughters(NULL),daughters_mass(NULL),
particletable(NULL)
{
// set pointer to G4ParticleTable (static and singleton object)
particletable = G4ParticleTable::GetParticleTable();
}
G4VDecayChannel::G4VDecayChannel(const G4String &aName,
const G4String& theParentName,
G4double theBR,
G4int theNumberOfDaughters,
const G4String& theDaughterName1,
const G4String& theDaughterName2,
const G4String& theDaughterName3,
const G4String& theDaughterName4 )
:kinematics_name(aName),
verboseLevel(1),rbranch(theBR),
numberOfDaughters(theNumberOfDaughters),
parent_name(NULL),parent(NULL),parent_mass(0.0),
daughters_name(NULL),daughters(NULL),daughters_mass(NULL),
particletable(NULL)
{
// set pointer to G4ParticleTable (static and singleton object)
particletable = G4ParticleTable::GetParticleTable();
// parent name
parent_name = new G4String(theParentName);
// cleate array
daughters_name = new G4String*[numberOfDaughters];
for (G4int index=0;index<numberOfDaughters;index++) daughters_name[index]=NULL;
// daughters' name
if (numberOfDaughters>0) daughters_name[0] = new G4String(theDaughterName1);
if (numberOfDaughters>1) daughters_name[1] = new G4String(theDaughterName2);
if (numberOfDaughters>2) daughters_name[2] = new G4String(theDaughterName3);
if (numberOfDaughters>3) daughters_name[3] = new G4String(theDaughterName4);
}
G4VDecayChannel::G4VDecayChannel(const G4VDecayChannel &right)
{
kinematics_name = right.kinematics_name;
verboseLevel = right.verboseLevel;
rbranch = right.rbranch;
// copy parent name
parent_name = new G4String(*right.parent_name);
parent = NULL;
parent_mass = 0.0;
//create array
numberOfDaughters = right.numberOfDaughters;
if ( numberOfDaughters >0 ) {
daughters_name = new G4String*[numberOfDaughters];
//copy daughters name
for (G4int index=0; index < numberOfDaughters; index++)
{
daughters_name[index] = new G4String(*right.daughters_name[index]);
}
}
//
daughters_mass = NULL;
daughters = NULL;
// particle table
particletable = G4ParticleTable::GetParticleTable();
}
G4VDecayChannel & G4VDecayChannel::operator=(const G4VDecayChannel &right)
{
if (this != &right) {
kinematics_name = right.kinematics_name;
verboseLevel = right.verboseLevel;
rbranch = right.rbranch;
// copy parent name
parent_name = new G4String(*right.parent_name);
// clear daughters_name array
ClearDaughtersName();
// recreate array
numberOfDaughters = right.numberOfDaughters;
if ( numberOfDaughters >0 ) {
daughters_name = new G4String*[numberOfDaughters];
//copy daughters name
for (G4int index=0; index < numberOfDaughters; index++) {
daughters_name[index] = new G4String(*right.daughters_name[index]);
}
}
}
//
parent = NULL;
daughters = NULL;
parent_mass = 0.0;
daughters_mass = NULL;
// particle table
particletable = G4ParticleTable::GetParticleTable();
return *this;
}
G4VDecayChannel::~G4VDecayChannel()
{
if (parent_name != NULL) delete parent_name;
ClearDaughtersName();
if (daughters_mass != NULL) delete [] daughters_mass;
}
void G4VDecayChannel::ClearDaughtersName()
{
if ( daughters_name != NULL) {
if (numberOfDaughters>0) {
#ifdef G4VERBOSE
if (verboseLevel>1) {
G4cerr << "G4VDecayChannel::ClearDaughtersName ";
G4cerr << "clear all daughters " << endl;
}
#endif
for (G4int index=0; index < numberOfDaughters; index++) {
if (daughters_name[index] != NULL) delete daughters_name[index];
}
}
delete [] daughters_name;
daughters_name = NULL;
}
//
if (daughters != NULL) delete [] daughters;
if (daughters_mass != NULL) delete [] daughters_mass;
daughters = NULL;
daughters_mass = NULL;
numberOfDaughters = 0;
}
void G4VDecayChannel::SetNumberOfDaughters(G4int size)
{
if (size >0) {
// remove old contents
ClearDaughtersName();
// cleate array
daughters_name = new G4String*[size];
for (G4int index=0;index<size;index++) daughters_name[index]=NULL;
numberOfDaughters = size;
}
}
void G4VDecayChannel::SetDaughter(G4int anIndex,
const G4String &particle_name)
{
// check numberOfDaughters is positive
if (numberOfDaughters<=0) {
#ifdef G4VERBOSE
if (verboseLevel>0) {
G4cerr << "G4VDecayChannel::SetDaughter: ";
G4cerr << "Number of daughters is not defined" << endl;
}
#endif
return;
}
// check existence of daughters_name array
if (daughters_name == NULL) {
// cleate array
daughters_name = new G4String*[numberOfDaughters];
for (G4int index=0;index<numberOfDaughters;index++) {
daughters_name[index]=NULL;
}
}
// check an index
if ( (anIndex<0) || (anIndex>=numberOfDaughters) ) {
#ifdef G4VERBOSE
if (verboseLevel>0) {
G4cerr << "G4VDecayChannel::SetDaughter";
G4cerr << "index out of range " << anIndex << endl;
}
#endif
} else {
// delete the old name if it exists
if (daughters_name[anIndex]!=NULL) delete daughters_name[anIndex];
// fill the name
daughters_name[anIndex] = new G4String(particle_name);
// refill the array of daughters[] if it exists
if (daughters != NULL) FillDaughters();
#ifdef G4VERBOSE
if (verboseLevel>1) {
G4cerr << "G4VDecayChannel::SetDaughter[" << anIndex <<"] :";
G4cerr << daughters_name[anIndex] << ":" << *daughters_name[anIndex]<<endl;
}
#endif
}
}
void G4VDecayChannel::SetDaughter(G4int anIndex, const G4ParticleDefinition * parent_type)
{
if (parent_type != NULL) SetDaughter(anIndex, parent_type->GetParticleName());
}
void G4VDecayChannel::FillDaughters()
{
G4int index;
#ifdef G4VERBOSE
if (verboseLevel>1) G4cerr << "G4VDecayChannel::FillDaughters()" <<endl;
#endif
if (daughters != NULL) delete [] daughters;
// parent mass
if (parent == NULL) FillParent();
G4double parentmass = parent->GetPDGMass();
//
G4double sumofdaughtermass = 0.0;
if ((numberOfDaughters <=0) || (daughters_name == NULL) ){
#ifdef G4VERBOSE
if (verboseLevel>0) {
G4cerr << "G4VDecayChannel::FillDaughters ";
G4cerr << "numberOfDaughters is not defined yet";
}
#endif
daughters = NULL;
G4Exception("G4VDecayChannel::FillDaughters");
}
//create and set the array of pointers to daughter particles
daughters = new G4ParticleDefinition*[numberOfDaughters];
if (daughters_mass != NULL) delete [] daughters_mass;
daughters_mass = new G4double[numberOfDaughters];
// loop over all daughters
for (index=0; index < numberOfDaughters; index++) {
if (daughters_name[index] == NULL) {
// daughter name is not defined
#ifdef G4VERBOSE
if (verboseLevel>0) {
G4cerr << "G4VDecayChannel::FillDaughters ";
G4cerr << index << "-th daughter is not defined yet" << endl;
}
#endif
daughters[index] = NULL;
G4Exception("G4VDecayChannel::FillDaughters");
}
//search daughter particles in the particle table
daughters[index] = particletable->FindParticle(*daughters_name[index]);
if (daughters[index] == NULL) {
// can not find the daughter particle
#ifdef G4VERBOSE
if (verboseLevel>0) {
G4cerr << "G4VDecayChannel::FillDaughters ";
G4cerr << index << ":" << *daughters_name[index];
G4cerr << " is not defined !!" << endl;
G4cerr << " The BR of this decay mode is set to zero " << endl;
}
#endif
SetBR(0.0);
// G4Exception("G4VDecayChannel::FillDaughters");
}
#ifdef G4VERBOSE
if (verboseLevel>1) {
G4cerr << index << ":" << *daughters_name[index];
G4cerr << ":" << daughters[index] << endl;
}
#endif
daughters_mass[index] = daughters[index]->GetPDGMass();
sumofdaughtermass += daughters[index]->GetPDGMass();
} // end loop over all daughters
// check sum of daghter mass
if (sumofdaughtermass > parentmass) {
// !!! illegal mass !!!
#ifdef G4VERBOSE
if (GetVerboseLevel()>0) {
G4cerr << "G4VDecayChannel::FillDaughters ";
G4cerr << " Energy/Momentum conserevation breaks " <<endl;
G4cerr << " parent:" << *parent_name;
G4cerr << " mass:" << parentmass/GeV << "[GeV/c/c]" <<endl;
for (index=0; index < 3; index++){
G4cerr << " daughter " << index << ":" << *daughters_name[index];
G4cerr << " mass:" << daughters[index]->GetPDGMass()/GeV << "[GeV/c/c]" <<endl;
}
}
#endif
G4Exception("G4VDecayChannel::FillDaughters");
}
}
void G4VDecayChannel::FillParent()
{
if (parent_name == NULL) {
// parent name is not defined
#ifdef G4VERBOSE
if (verboseLevel>0) {
G4cerr << "G4VDecayChannel::FillParent ";
G4cerr << ": parent name is not defined !!" << endl;
}
#endif
parent = NULL;
G4Exception("G4VDecayChannel::FillParent");
}
// search parent particle in the particle table
parent = particletable->FindParticle(*parent_name);
if (parent == NULL) {
// parent particle does not exist
#ifdef G4VERBOSE
if (verboseLevel>0) {
G4cerr << "G4VDecayChannel::FillParent ";
G4cerr << *parent_name << " does not exist !!" << endl;
}
#endif
G4Exception("G4VDecayChannel::FillParent");
}
parent_mass = parent->GetPDGMass();
}
void G4VDecayChannel::SetParent(const G4ParticleDefinition * parent_type)
{
if (parent_type != NULL) SetParent(parent_type->GetParticleName());
}
void G4VDecayChannel::DumpInfo()
{
G4cout << " BR: " << rbranch << " [" << kinematics_name << "]";
G4cout << " : " ;
for (G4int index=0; index < numberOfDaughters; index++)
{
if(daughters_name[index] != NULL) {
G4cout << " " << *(daughters_name[index]);
} else {
G4cout << " not defined ";
}
}
G4cout << endl;
}