Import Geant4 0.0.0 source tree
This commit is contained in:
@@ -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"
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user