Import Geant4 10.7.0.beta source tree
This commit is contained in:
@@ -23,14 +23,12 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4AdjointPosOnPhysVolGenerator class implementation
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Class Name: G4AdjointCrossSurfChecker
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Author: L. Desorgher, SpaceIT GmbH - 01.06.2006
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4AdjointPosOnPhysVolGenerator.hh"
|
||||
#include "G4VSolid.hh"
|
||||
@@ -41,20 +39,21 @@
|
||||
#include "G4PhysicalVolumeStore.hh"
|
||||
#include "G4LogicalVolumeStore.hh"
|
||||
|
||||
G4ThreadLocal G4AdjointPosOnPhysVolGenerator* G4AdjointPosOnPhysVolGenerator::theInstance = 0;
|
||||
G4ThreadLocal G4AdjointPosOnPhysVolGenerator*
|
||||
G4AdjointPosOnPhysVolGenerator::theInstance = nullptr;
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4AdjointPosOnPhysVolGenerator* G4AdjointPosOnPhysVolGenerator::GetInstance()
|
||||
{
|
||||
if(!theInstance)
|
||||
if(theInstance == nullptr)
|
||||
{
|
||||
theInstance = new G4AdjointPosOnPhysVolGenerator;
|
||||
theInstance = new G4AdjointPosOnPhysVolGenerator;
|
||||
}
|
||||
return theInstance;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4AdjointPosOnPhysVolGenerator::~G4AdjointPosOnPhysVolGenerator()
|
||||
{
|
||||
@@ -63,168 +62,222 @@ G4AdjointPosOnPhysVolGenerator::~G4AdjointPosOnPhysVolGenerator()
|
||||
////////////////////////////////////////////////////
|
||||
//
|
||||
G4AdjointPosOnPhysVolGenerator::G4AdjointPosOnPhysVolGenerator()
|
||||
: theSolid(0), thePhysicalVolume(0),
|
||||
UseSphere(true), ModelOfSurfaceSource("OnSolid"),
|
||||
: UseSphere(true), ModelOfSurfaceSource("OnSolid"),
|
||||
AreaOfExtSurfaceOfThePhysicalVolume(0.), CosThDirComparedToNormal(0.)
|
||||
{
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4VPhysicalVolume* G4AdjointPosOnPhysVolGenerator::DefinePhysicalVolume(const G4String& aName)
|
||||
G4VPhysicalVolume*
|
||||
G4AdjointPosOnPhysVolGenerator::DefinePhysicalVolume(const G4String& aName)
|
||||
{
|
||||
thePhysicalVolume = 0;
|
||||
theSolid =0;
|
||||
G4PhysicalVolumeStore* thePhysVolStore =G4PhysicalVolumeStore::GetInstance();
|
||||
for ( unsigned int i=0; i< thePhysVolStore->size();i++){
|
||||
G4String vol_name =(*thePhysVolStore)[i]->GetName();
|
||||
if (vol_name == ""){
|
||||
vol_name = (*thePhysVolStore)[i]->GetLogicalVolume()->GetName();
|
||||
}
|
||||
if (vol_name == aName){
|
||||
thePhysicalVolume = (*thePhysVolStore)[i];
|
||||
}
|
||||
thePhysicalVolume = nullptr;
|
||||
theSolid = nullptr;
|
||||
G4PhysicalVolumeStore* thePhysVolStore = G4PhysicalVolumeStore::GetInstance();
|
||||
for ( unsigned int i=0; i< thePhysVolStore->size(); ++i )
|
||||
{
|
||||
G4String vol_name =(*thePhysVolStore)[i]->GetName();
|
||||
if (vol_name == "")
|
||||
{
|
||||
vol_name = (*thePhysVolStore)[i]->GetLogicalVolume()->GetName();
|
||||
}
|
||||
if (vol_name == aName)
|
||||
{
|
||||
thePhysicalVolume = (*thePhysVolStore)[i];
|
||||
}
|
||||
}
|
||||
if (thePhysicalVolume){
|
||||
theSolid = thePhysicalVolume->GetLogicalVolume()->GetSolid();
|
||||
ComputeTransformationFromPhysVolToWorld();
|
||||
/*AreaOfExtSurfaceOfThePhysicalVolume=ComputeAreaOfExtSurface(1.e-3);
|
||||
G4cout<<"Monte Carlo Estimate of the area of the external surface :"<<AreaOfExtSurfaceOfThePhysicalVolume/m/m<<" m2"<<std::endl;*/
|
||||
if (thePhysicalVolume != nullptr)
|
||||
{
|
||||
theSolid = thePhysicalVolume->GetLogicalVolume()->GetSolid();
|
||||
ComputeTransformationFromPhysVolToWorld();
|
||||
}
|
||||
else {
|
||||
G4cout<<"The physical volume with name "<<aName<<" does not exist!!"<<std::endl;
|
||||
G4cout<<"Before generating a source on an external surface of a volume you should select another physical volume"<<std::endl;
|
||||
else
|
||||
{
|
||||
G4cout << "The physical volume with name " << aName
|
||||
<< " does not exist!!" << G4endl;
|
||||
G4cout << "Before generating a source on an external surface " << G4endl
|
||||
<< "of a volume you should select another physical volume."
|
||||
<< G4endl;
|
||||
}
|
||||
return thePhysicalVolume;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
void G4AdjointPosOnPhysVolGenerator::DefinePhysicalVolume1(const G4String& aName)
|
||||
void
|
||||
G4AdjointPosOnPhysVolGenerator::DefinePhysicalVolume1(const G4String& aName)
|
||||
{
|
||||
thePhysicalVolume = DefinePhysicalVolume(aName);
|
||||
thePhysicalVolume = DefinePhysicalVolume(aName);
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface()
|
||||
{
|
||||
return ComputeAreaOfExtSurface(theSolid);
|
||||
return ComputeAreaOfExtSurface(theSolid);
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface(G4int NStats)
|
||||
{
|
||||
return ComputeAreaOfExtSurface(theSolid,NStats);
|
||||
return ComputeAreaOfExtSurface(theSolid,NStats);
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface(G4double eps)
|
||||
{
|
||||
return ComputeAreaOfExtSurface(theSolid,eps);
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface(G4VSolid* aSolid)
|
||||
G4double
|
||||
G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface(G4VSolid* aSolid)
|
||||
{
|
||||
return ComputeAreaOfExtSurface(aSolid,1.e-3);
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface(G4VSolid* aSolid,G4int NStats)
|
||||
G4double
|
||||
G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface(G4VSolid* aSolid,
|
||||
G4int NStats)
|
||||
{
|
||||
if (ModelOfSurfaceSource == "OnSolid" ){
|
||||
if (UseSphere){
|
||||
return ComputeAreaOfExtSurfaceStartingFromSphere(aSolid,NStats);
|
||||
}
|
||||
else {
|
||||
return ComputeAreaOfExtSurfaceStartingFromBox(aSolid,NStats);
|
||||
}
|
||||
if (ModelOfSurfaceSource == "OnSolid")
|
||||
{
|
||||
if (UseSphere)
|
||||
{
|
||||
return ComputeAreaOfExtSurfaceStartingFromSphere(aSolid,NStats);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ComputeAreaOfExtSurfaceStartingFromBox(aSolid,NStats);
|
||||
}
|
||||
}
|
||||
else {
|
||||
G4ThreeVector p,dir;
|
||||
if (ModelOfSurfaceSource == "ExternalSphere" ) return GenerateAPositionOnASphereBoundary(aSolid, p,dir);
|
||||
return GenerateAPositionOnABoxBoundary(aSolid, p,dir);
|
||||
else
|
||||
{
|
||||
G4ThreeVector p, dir;
|
||||
if (ModelOfSurfaceSource == "ExternalSphere")
|
||||
{
|
||||
return GenerateAPositionOnASphereBoundary(aSolid, p,dir);
|
||||
}
|
||||
return GenerateAPositionOnABoxBoundary(aSolid, p,dir);
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface(G4VSolid* aSolid,G4double eps)
|
||||
G4double
|
||||
G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurface(G4VSolid* aSolid,
|
||||
G4double eps)
|
||||
{
|
||||
G4int Nstats = G4int(1./(eps*eps));
|
||||
return ComputeAreaOfExtSurface(aSolid,Nstats);
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
void G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnTheExtSurfaceOfASolid(G4VSolid* aSolid,G4ThreeVector& p, G4ThreeVector& direction)
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
void G4AdjointPosOnPhysVolGenerator::
|
||||
GenerateAPositionOnTheExtSurfaceOfASolid(G4VSolid* aSolid, G4ThreeVector& p,
|
||||
G4ThreeVector& direction)
|
||||
{
|
||||
if (ModelOfSurfaceSource == "OnSolid" ){
|
||||
GenerateAPositionOnASolidBoundary(aSolid, p,direction);
|
||||
return;
|
||||
if (ModelOfSurfaceSource == "OnSolid")
|
||||
{
|
||||
GenerateAPositionOnASolidBoundary(aSolid, p,direction);
|
||||
return;
|
||||
}
|
||||
if (ModelOfSurfaceSource == "ExternalSphere" ) {
|
||||
GenerateAPositionOnASphereBoundary(aSolid, p, direction);
|
||||
return;
|
||||
}
|
||||
GenerateAPositionOnABoxBoundary(aSolid, p, direction);
|
||||
return;
|
||||
if (ModelOfSurfaceSource == "ExternalSphere")
|
||||
{
|
||||
GenerateAPositionOnASphereBoundary(aSolid, p, direction);
|
||||
return;
|
||||
}
|
||||
GenerateAPositionOnABoxBoundary(aSolid, p, direction);
|
||||
return;
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
void G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnTheExtSurfaceOfTheSolid(G4ThreeVector& p, G4ThreeVector& direction)
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
void G4AdjointPosOnPhysVolGenerator::
|
||||
GenerateAPositionOnTheExtSurfaceOfTheSolid(G4ThreeVector& p,
|
||||
G4ThreeVector& direction)
|
||||
{
|
||||
GenerateAPositionOnTheExtSurfaceOfASolid(theSolid,p,direction);
|
||||
}
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurfaceStartingFromBox(G4VSolid* aSolid,G4int Nstat)
|
||||
G4double G4AdjointPosOnPhysVolGenerator::
|
||||
ComputeAreaOfExtSurfaceStartingFromBox(G4VSolid* aSolid, G4int Nstat)
|
||||
{
|
||||
if ( Nstat <= 0 ) return 0.;
|
||||
if ( Nstat <= 0 ) { return 0.; }
|
||||
G4double area=1.;
|
||||
G4int i=0;
|
||||
G4int j=0;
|
||||
while (i<Nstat){
|
||||
G4ThreeVector p, direction;
|
||||
area = GenerateAPositionOnABoxBoundary( aSolid,p, direction);
|
||||
G4double dist_to_in = aSolid->DistanceToIn(p,direction);
|
||||
if (dist_to_in<kInfinity/2.) i++;
|
||||
j++;
|
||||
}
|
||||
area=area*double(i)/double(j);
|
||||
return area;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::ComputeAreaOfExtSurfaceStartingFromSphere(G4VSolid* aSolid,G4int Nstat)
|
||||
{
|
||||
if ( Nstat <= 0 ) return 0.;
|
||||
G4double area=1.;
|
||||
G4int i=0;
|
||||
G4int j=0;
|
||||
while (i<Nstat){
|
||||
G4ThreeVector p, direction;
|
||||
area = GenerateAPositionOnASphereBoundary( aSolid,p, direction);
|
||||
G4double dist_to_in = aSolid->DistanceToIn(p,direction);
|
||||
if (dist_to_in<kInfinity/2.) i++;
|
||||
j++;
|
||||
}
|
||||
area=area*double(i)/double(j);
|
||||
return area;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnASolidBoundary(G4VSolid* aSolid,G4ThreeVector& p, G4ThreeVector& direction)
|
||||
{
|
||||
G4bool find_pos =false;
|
||||
while (!find_pos){
|
||||
if (UseSphere) GenerateAPositionOnASphereBoundary( aSolid,p, direction);
|
||||
else GenerateAPositionOnABoxBoundary( aSolid,p, direction);
|
||||
G4int i=0, j=0;
|
||||
while (i<Nstat)
|
||||
{
|
||||
G4ThreeVector p, direction;
|
||||
area = GenerateAPositionOnABoxBoundary( aSolid,p, direction);
|
||||
G4double dist_to_in = aSolid->DistanceToIn(p,direction);
|
||||
if (dist_to_in<kInfinity/2.) {
|
||||
find_pos =true;
|
||||
p+= 0.999999*direction*dist_to_in;
|
||||
if (dist_to_in<kInfinity/2.) { ++i; }
|
||||
++j;
|
||||
}
|
||||
area=area*G4double(i)/G4double(j);
|
||||
return area;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::
|
||||
ComputeAreaOfExtSurfaceStartingFromSphere(G4VSolid* aSolid, G4int Nstat)
|
||||
{
|
||||
if ( Nstat <= 0 ) { return 0.; }
|
||||
G4double area=1.;
|
||||
G4int i=0, j=0;
|
||||
while (i<Nstat)
|
||||
{
|
||||
G4ThreeVector p, direction;
|
||||
area = GenerateAPositionOnASphereBoundary( aSolid,p, direction);
|
||||
G4double dist_to_in = aSolid->DistanceToIn(p,direction);
|
||||
if (dist_to_in<kInfinity/2.) { ++i; }
|
||||
++j;
|
||||
}
|
||||
area=area*G4double(i)/G4double(j);
|
||||
return area;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
void G4AdjointPosOnPhysVolGenerator::
|
||||
GenerateAPositionOnASolidBoundary(G4VSolid* aSolid, G4ThreeVector& p,
|
||||
G4ThreeVector& direction)
|
||||
{
|
||||
G4bool find_pos = false;
|
||||
while (!find_pos)
|
||||
{
|
||||
if (UseSphere)
|
||||
{
|
||||
GenerateAPositionOnASphereBoundary( aSolid,p, direction );
|
||||
}
|
||||
else
|
||||
{
|
||||
GenerateAPositionOnABoxBoundary( aSolid,p, direction);
|
||||
}
|
||||
G4double dist_to_in = aSolid->DistanceToIn(p,direction);
|
||||
if (dist_to_in<kInfinity/2.)
|
||||
{
|
||||
find_pos = true;
|
||||
p += 0.999999*direction*dist_to_in;
|
||||
}
|
||||
}
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnASphereBoundary(G4VSolid* aSolid,G4ThreeVector& p, G4ThreeVector& direction)
|
||||
G4double G4AdjointPosOnPhysVolGenerator::
|
||||
GenerateAPositionOnASphereBoundary(G4VSolid* aSolid, G4ThreeVector& p,
|
||||
G4ThreeVector& direction)
|
||||
{
|
||||
G4double minX,maxX,minY,maxY,minZ,maxZ;
|
||||
|
||||
@@ -239,8 +292,9 @@ G4double G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnASphereBoundary(G4VS
|
||||
aSolid->CalculateExtent(kYAxis,limit,origin,minY,maxY);
|
||||
aSolid->CalculateExtent(kZAxis,limit,origin,minZ,maxZ);
|
||||
|
||||
G4ThreeVector center = G4ThreeVector((minX+maxX)/2.,(minY+maxY)/2.,(minZ+maxZ)/2.);
|
||||
|
||||
G4ThreeVector center = G4ThreeVector((minX+maxX)/2.,
|
||||
(minY+maxY)/2.,
|
||||
(minZ+maxZ)/2.);
|
||||
G4double dX=(maxX-minX)/2.;
|
||||
G4double dY=(maxY-minY)/2.;
|
||||
G4double dZ=(maxZ-minZ)/2.;
|
||||
@@ -249,22 +303,25 @@ G4double G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnASphereBoundary(G4VS
|
||||
|
||||
G4double cos_th2 = G4UniformRand();
|
||||
G4double theta = std::acos(std::sqrt(cos_th2));
|
||||
G4double phi=G4UniformRand()*3.1415926*2;
|
||||
G4double phi=G4UniformRand()*CLHEP::twopi;
|
||||
direction.setRThetaPhi(1.,theta,phi);
|
||||
direction=-direction;
|
||||
G4double cos_th = (1.-2.*G4UniformRand());
|
||||
theta = std::acos(cos_th);
|
||||
if (G4UniformRand() <0.5) theta=3.1415926-theta;
|
||||
phi=G4UniformRand()*3.1415926*2;
|
||||
if (G4UniformRand() < 0.5) { theta=CLHEP::pi-theta; }
|
||||
phi=G4UniformRand()*CLHEP::twopi;
|
||||
p.setRThetaPhi(r,theta,phi);
|
||||
p+=center;
|
||||
direction.rotateY(theta);
|
||||
direction.rotateZ(phi);
|
||||
return 4.*3.1415926*r*r;;
|
||||
return 4.*CLHEP::pi*r*r;;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4double G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnABoxBoundary(G4VSolid* aSolid,G4ThreeVector& p, G4ThreeVector& direction)
|
||||
G4double G4AdjointPosOnPhysVolGenerator::
|
||||
GenerateAPositionOnABoxBoundary(G4VSolid* aSolid, G4ThreeVector& p,
|
||||
G4ThreeVector& direction)
|
||||
{
|
||||
|
||||
G4double ran_var,px,py,pz,minX,maxX,minY,maxY,minZ,maxZ;
|
||||
@@ -304,104 +361,124 @@ G4double G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnABoxBoundary(G4VSoli
|
||||
G4double cos_th2 = G4UniformRand();
|
||||
G4double sth = std::sqrt(1.-cos_th2);
|
||||
G4double cth = std::sqrt(cos_th2);
|
||||
G4double phi=G4UniformRand()*3.1415926*2;
|
||||
G4double phi = G4UniformRand()*CLHEP::twopi;
|
||||
G4double dirX = sth*std::cos(phi);
|
||||
G4double dirY = sth*std::sin(phi);
|
||||
G4double dirZ = cth;
|
||||
if (ran_var <=XY_prob){ //on the XY faces
|
||||
G4double ran_var1=ran_var/XY_prob;
|
||||
G4double ranX=ran_var1;
|
||||
if (ran_var1<=0.5){
|
||||
pz=minZ;
|
||||
direction=G4ThreeVector(dirX,dirY,dirZ);
|
||||
ranX=ran_var1*2.;
|
||||
}
|
||||
else{
|
||||
pz=maxZ;
|
||||
direction=-G4ThreeVector(dirX,dirY,dirZ);
|
||||
ranX=(ran_var1-0.5)*2.;
|
||||
}
|
||||
G4double ranY=G4UniformRand();
|
||||
px=minX+(maxX-minX)*ranX;
|
||||
py=minY+(maxY-minY)*ranY;
|
||||
if (ran_var <=XY_prob) // on the XY faces
|
||||
{
|
||||
G4double ran_var1=ran_var/XY_prob;
|
||||
G4double ranX=ran_var1;
|
||||
if (ran_var1<=0.5)
|
||||
{
|
||||
pz=minZ;
|
||||
direction=G4ThreeVector(dirX,dirY,dirZ);
|
||||
ranX=ran_var1*2.;
|
||||
}
|
||||
else
|
||||
{
|
||||
pz=maxZ;
|
||||
direction=-G4ThreeVector(dirX,dirY,dirZ);
|
||||
ranX=(ran_var1-0.5)*2.;
|
||||
}
|
||||
G4double ranY=G4UniformRand();
|
||||
px=minX+(maxX-minX)*ranX;
|
||||
py=minY+(maxY-minY)*ranY;
|
||||
}
|
||||
else if (ran_var <=(XY_prob+YZ_prob)){ //on the YZ faces
|
||||
G4double ran_var1=(ran_var-XY_prob)/YZ_prob;
|
||||
G4double ranY=ran_var1;
|
||||
if (ran_var1<=0.5){
|
||||
px=minX;
|
||||
direction=G4ThreeVector(dirZ,dirX,dirY);
|
||||
ranY=ran_var1*2.;
|
||||
}
|
||||
else{
|
||||
px=maxX;
|
||||
direction=-G4ThreeVector(dirZ,dirX,dirY);
|
||||
ranY=(ran_var1-0.5)*2.;
|
||||
}
|
||||
G4double ranZ=G4UniformRand();
|
||||
py=minY+(maxY-minY)*ranY;
|
||||
pz=minZ+(maxZ-minZ)*ranZ;
|
||||
|
||||
else if (ran_var <=(XY_prob+YZ_prob)) // on the YZ faces
|
||||
{
|
||||
G4double ran_var1=(ran_var-XY_prob)/YZ_prob;
|
||||
G4double ranY=ran_var1;
|
||||
if (ran_var1<=0.5)
|
||||
{
|
||||
px=minX;
|
||||
direction=G4ThreeVector(dirZ,dirX,dirY);
|
||||
ranY=ran_var1*2.;
|
||||
}
|
||||
else
|
||||
{
|
||||
px=maxX;
|
||||
direction=-G4ThreeVector(dirZ,dirX,dirY);
|
||||
ranY=(ran_var1-0.5)*2.;
|
||||
}
|
||||
G4double ranZ=G4UniformRand();
|
||||
py=minY+(maxY-minY)*ranY;
|
||||
pz=minZ+(maxZ-minZ)*ranZ;
|
||||
}
|
||||
else{ //on the ZX faces
|
||||
G4double ran_var1=(ran_var-XY_prob-YZ_prob)/ZX_prob;
|
||||
G4double ranZ=ran_var1;
|
||||
if (ran_var1<=0.5){
|
||||
py=minY;
|
||||
direction=G4ThreeVector(dirY,dirZ,dirX);
|
||||
ranZ=ran_var1*2.;
|
||||
}
|
||||
else{
|
||||
py=maxY;
|
||||
direction=-G4ThreeVector(dirY,dirZ,dirX);
|
||||
ranZ=(ran_var1-0.5)*2.;
|
||||
}
|
||||
G4double ranX=G4UniformRand();
|
||||
px=minX+(maxX-minX)*ranX;
|
||||
pz=minZ+(maxZ-minZ)*ranZ;
|
||||
else // on the ZX faces
|
||||
{
|
||||
G4double ran_var1=(ran_var-XY_prob-YZ_prob)/ZX_prob;
|
||||
G4double ranZ=ran_var1;
|
||||
if (ran_var1<=0.5)
|
||||
{
|
||||
py=minY;
|
||||
direction=G4ThreeVector(dirY,dirZ,dirX);
|
||||
ranZ=ran_var1*2.;
|
||||
}
|
||||
else
|
||||
{
|
||||
py=maxY;
|
||||
direction=-G4ThreeVector(dirY,dirZ,dirX);
|
||||
ranZ=(ran_var1-0.5)*2.;
|
||||
}
|
||||
G4double ranX=G4UniformRand();
|
||||
px=minX+(maxX-minX)*ranX;
|
||||
pz=minZ+(maxZ-minZ)*ranZ;
|
||||
}
|
||||
|
||||
p=G4ThreeVector(px,py,pz);
|
||||
return area;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
void G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnTheExtSurfaceOfThePhysicalVolume(G4ThreeVector& p, G4ThreeVector& direction)
|
||||
void G4AdjointPosOnPhysVolGenerator::
|
||||
GenerateAPositionOnTheExtSurfaceOfThePhysicalVolume(G4ThreeVector& p,
|
||||
G4ThreeVector& direction)
|
||||
{
|
||||
if (!thePhysicalVolume) {
|
||||
G4cout<<"Before generating a source on an external surface of volume you should select a physical volume"<<std::endl;
|
||||
return;
|
||||
};
|
||||
if (thePhysicalVolume == nullptr)
|
||||
{
|
||||
G4cout << "Before generating a source on an external surface" << G4endl
|
||||
<< "of volume you should select a physical volume" << G4endl;
|
||||
return;
|
||||
}
|
||||
GenerateAPositionOnTheExtSurfaceOfTheSolid(p,direction);
|
||||
p = theTransformationFromPhysVolToWorld.TransformPoint(p);
|
||||
direction = theTransformationFromPhysVolToWorld.TransformAxis(direction);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
void G4AdjointPosOnPhysVolGenerator::GenerateAPositionOnTheExtSurfaceOfThePhysicalVolume(G4ThreeVector& p, G4ThreeVector& direction,
|
||||
G4double& costh_to_normal)
|
||||
void G4AdjointPosOnPhysVolGenerator::
|
||||
GenerateAPositionOnTheExtSurfaceOfThePhysicalVolume(G4ThreeVector& p,
|
||||
G4ThreeVector& direction,
|
||||
G4double& costh_to_normal)
|
||||
{
|
||||
GenerateAPositionOnTheExtSurfaceOfThePhysicalVolume(p, direction);
|
||||
costh_to_normal = CosThDirComparedToNormal;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
void G4AdjointPosOnPhysVolGenerator::ComputeTransformationFromPhysVolToWorld()
|
||||
{
|
||||
G4VPhysicalVolume* daughter =thePhysicalVolume;
|
||||
G4VPhysicalVolume* daughter = thePhysicalVolume;
|
||||
G4LogicalVolume* mother = thePhysicalVolume->GetMotherLogical();
|
||||
theTransformationFromPhysVolToWorld = G4AffineTransform();
|
||||
G4PhysicalVolumeStore* thePhysVolStore =G4PhysicalVolumeStore::GetInstance();
|
||||
while (mother){
|
||||
theTransformationFromPhysVolToWorld *=
|
||||
G4AffineTransform(daughter->GetFrameRotation(),daughter->GetObjectTranslation());
|
||||
for ( unsigned int i=0; i< thePhysVolStore->size();i++){
|
||||
if ((*thePhysVolStore)[i]->GetLogicalVolume() == mother){
|
||||
daughter = (*thePhysVolStore)[i];
|
||||
mother =daughter->GetMotherLogical();
|
||||
break;
|
||||
};
|
||||
}
|
||||
G4PhysicalVolumeStore* thePhysVolStore = G4PhysicalVolumeStore::GetInstance();
|
||||
while (mother != nullptr)
|
||||
{
|
||||
theTransformationFromPhysVolToWorld *=
|
||||
G4AffineTransform(daughter->GetFrameRotation(),
|
||||
daughter->GetObjectTranslation());
|
||||
for ( unsigned int i=0; i<thePhysVolStore->size(); ++i )
|
||||
{
|
||||
if ((*thePhysVolStore)[i]->GetLogicalVolume() == mother)
|
||||
{
|
||||
daughter = (*thePhysVolStore)[i];
|
||||
mother = daughter->GetMotherLogical();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,14 +23,12 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4AdjointPrimaryGenerator class implementation
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Class Name: G4AdjointCrossSurfChecker
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Author: L. Desorgher, SpaceIT GmbH - November 2009
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4AdjointPrimaryGenerator.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
@@ -43,14 +41,10 @@
|
||||
#include "G4VPhysicalVolume.hh"
|
||||
#include "G4Material.hh"
|
||||
#include "Randomize.hh"
|
||||
/*
|
||||
#include "G4AdjointCSManager.hh"
|
||||
#include "G4MaterialCutsCouple.hh"
|
||||
*/
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4AdjointPrimaryGenerator::G4AdjointPrimaryGenerator()
|
||||
: radius_spherical_source(0.),fLinearNavigator(0),theAccumulatedDepthVector(0)
|
||||
{
|
||||
center_spherical_source = G4ThreeVector(0.,0.,0.);
|
||||
type_of_adjoint_source="Spherical";
|
||||
@@ -62,74 +56,86 @@ G4AdjointPrimaryGenerator::G4AdjointPrimaryGenerator()
|
||||
theSingleParticleSource->GetAngDist()->SetAngDistType("planar");
|
||||
|
||||
theG4AdjointPosOnPhysVolGenerator = G4AdjointPosOnPhysVolGenerator::GetInstance();
|
||||
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4AdjointPrimaryGenerator::~G4AdjointPrimaryGenerator()
|
||||
{
|
||||
delete theSingleParticleSource;
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
void G4AdjointPrimaryGenerator::GenerateAdjointPrimaryVertex(G4Event* anEvent,G4ParticleDefinition* adj_part,G4double E1,G4double E2)
|
||||
void G4AdjointPrimaryGenerator::
|
||||
GenerateAdjointPrimaryVertex(G4Event* anEvent, G4ParticleDefinition* adj_part,
|
||||
G4double E1, G4double E2)
|
||||
{
|
||||
if (type_of_adjoint_source == "ExternalSurfaceOfAVolume") {
|
||||
|
||||
//Generate position and direction relative to the external surface of sensitive volume
|
||||
//-------------------------------------------------------------
|
||||
if (type_of_adjoint_source == "ExternalSurfaceOfAVolume")
|
||||
{
|
||||
// Generate position and direction relative to the external surface
|
||||
// of sensitive volume
|
||||
|
||||
G4double costh_to_normal=1.;
|
||||
G4ThreeVector pos =G4ThreeVector(0.,0.,0.);
|
||||
G4ThreeVector direction = G4ThreeVector(0.,0.,1.);
|
||||
theG4AdjointPosOnPhysVolGenerator->GenerateAPositionOnTheExtSurfaceOfThePhysicalVolume(pos, direction,costh_to_normal);
|
||||
if (costh_to_normal <1.e-4) costh_to_normal =1.e-4;
|
||||
//compute now the position along the ray backward direction
|
||||
|
||||
theSingleParticleSource->GetAngDist()->SetParticleMomentumDirection(-direction);
|
||||
theSingleParticleSource->GetPosDist()->SetCentreCoords(pos);
|
||||
}
|
||||
|
||||
theSingleParticleSource->GetEneDist()->SetEmin(E1);
|
||||
theSingleParticleSource->GetEneDist()->SetEmax(E2);
|
||||
|
||||
theSingleParticleSource->SetParticleDefinition(adj_part);
|
||||
theSingleParticleSource->GeneratePrimaryVertex(anEvent);
|
||||
G4double costh_to_normal=1.;
|
||||
G4ThreeVector pos =G4ThreeVector(0.,0.,0.);
|
||||
G4ThreeVector direction = G4ThreeVector(0.,0.,1.);
|
||||
theG4AdjointPosOnPhysVolGenerator
|
||||
->GenerateAPositionOnTheExtSurfaceOfThePhysicalVolume(pos, direction,
|
||||
costh_to_normal);
|
||||
if (costh_to_normal <1.e-4) { costh_to_normal = 1.e-4; }
|
||||
|
||||
// compute now the position along the ray backward direction
|
||||
//
|
||||
theSingleParticleSource->GetAngDist()
|
||||
->SetParticleMomentumDirection(-direction);
|
||||
theSingleParticleSource->GetPosDist()->SetCentreCoords(pos);
|
||||
}
|
||||
|
||||
theSingleParticleSource->GetEneDist()->SetEmin(E1);
|
||||
theSingleParticleSource->GetEneDist()->SetEmax(E2);
|
||||
|
||||
theSingleParticleSource->SetParticleDefinition(adj_part);
|
||||
theSingleParticleSource->GeneratePrimaryVertex(anEvent);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
void G4AdjointPrimaryGenerator::GenerateFwdPrimaryVertex(G4Event* anEvent,G4ParticleDefinition* fwd_part,G4double E1,G4double E2)
|
||||
void G4AdjointPrimaryGenerator::
|
||||
GenerateFwdPrimaryVertex(G4Event* anEvent,G4ParticleDefinition* fwd_part,
|
||||
G4double E1, G4double E2)
|
||||
{
|
||||
if (type_of_adjoint_source == "ExternalSurfaceOfAVolume") {
|
||||
if (type_of_adjoint_source == "ExternalSurfaceOfAVolume")
|
||||
{
|
||||
// Generate position and direction relative to the external surface
|
||||
// of sensitive volume
|
||||
|
||||
//Generate position and direction relative to the external surface of sensitive volume
|
||||
//-------------------------------------------------------------
|
||||
G4double costh_to_normal=1.;
|
||||
G4ThreeVector pos =G4ThreeVector(0.,0.,0.);
|
||||
G4ThreeVector direction = G4ThreeVector(0.,0.,1.);
|
||||
theG4AdjointPosOnPhysVolGenerator
|
||||
->GenerateAPositionOnTheExtSurfaceOfThePhysicalVolume(pos, direction,
|
||||
costh_to_normal);
|
||||
if (costh_to_normal <1.e-4) { costh_to_normal =1.e-4; }
|
||||
theSingleParticleSource->GetAngDist()
|
||||
->SetParticleMomentumDirection(direction);
|
||||
theSingleParticleSource->GetPosDist()->SetCentreCoords(pos);
|
||||
}
|
||||
|
||||
G4double costh_to_normal=1.;
|
||||
G4ThreeVector pos =G4ThreeVector(0.,0.,0.);
|
||||
G4ThreeVector direction = G4ThreeVector(0.,0.,1.);
|
||||
theG4AdjointPosOnPhysVolGenerator->GenerateAPositionOnTheExtSurfaceOfThePhysicalVolume(pos, direction,costh_to_normal);
|
||||
if (costh_to_normal <1.e-4) costh_to_normal =1.e-4;
|
||||
theSingleParticleSource->GetAngDist()->SetParticleMomentumDirection(direction);
|
||||
theSingleParticleSource->GetPosDist()->SetCentreCoords(pos);
|
||||
}
|
||||
theSingleParticleSource->GetEneDist()->SetEmin(E1);
|
||||
theSingleParticleSource->GetEneDist()->SetEmax(E2);
|
||||
|
||||
theSingleParticleSource->GetEneDist()->SetEmin(E1);
|
||||
theSingleParticleSource->GetEneDist()->SetEmax(E2);
|
||||
|
||||
theSingleParticleSource->SetParticleDefinition(fwd_part);
|
||||
theSingleParticleSource->GeneratePrimaryVertex(anEvent);
|
||||
theSingleParticleSource->SetParticleDefinition(fwd_part);
|
||||
theSingleParticleSource->GeneratePrimaryVertex(anEvent);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
void G4AdjointPrimaryGenerator::SetSphericalAdjointPrimarySource(G4double radius, G4ThreeVector center_pos)
|
||||
void G4AdjointPrimaryGenerator::
|
||||
SetSphericalAdjointPrimarySource(G4double radius, G4ThreeVector center_pos)
|
||||
{
|
||||
radius_spherical_source = radius;
|
||||
center_spherical_source = center_pos;
|
||||
type_of_adjoint_source ="Spherical";
|
||||
type_of_adjoint_source = "Spherical";
|
||||
theSingleParticleSource->GetPosDist()->SetPosDisType("Surface");
|
||||
theSingleParticleSource->GetPosDist()->SetPosDisShape("Sphere");
|
||||
theSingleParticleSource->GetPosDist()->SetCentreCoords(center_pos);
|
||||
@@ -138,9 +144,11 @@ void G4AdjointPrimaryGenerator::SetSphericalAdjointPrimarySource(G4double radius
|
||||
theSingleParticleSource->GetAngDist()->SetMaxTheta(pi);
|
||||
theSingleParticleSource->GetAngDist()->SetMinTheta(halfpi);
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
void G4AdjointPrimaryGenerator::SetAdjointPrimarySourceOnAnExtSurfaceOfAVolume(const G4String& volume_name)
|
||||
void G4AdjointPrimaryGenerator::
|
||||
SetAdjointPrimarySourceOnAnExtSurfaceOfAVolume(const G4String& volume_name)
|
||||
{
|
||||
theG4AdjointPosOnPhysVolGenerator->DefinePhysicalVolume1(volume_name);
|
||||
type_of_adjoint_source ="ExternalSurfaceOfAVolume";
|
||||
@@ -148,68 +156,51 @@ void G4AdjointPrimaryGenerator::SetAdjointPrimarySourceOnAnExtSurfaceOfAVolume(c
|
||||
theSingleParticleSource->GetAngDist()->SetAngDistType("planar");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
void G4AdjointPrimaryGenerator::ComputeAccumulatedDepthVectorAlongBackRay(
|
||||
G4ThreeVector glob_pos,
|
||||
G4ThreeVector direction,
|
||||
G4double,
|
||||
G4ParticleDefinition*)
|
||||
{ if (!fLinearNavigator) fLinearNavigator =
|
||||
G4TransportationManager::GetTransportationManager()
|
||||
->GetNavigatorForTracking();
|
||||
G4ThreeVector position = glob_pos;
|
||||
G4double safety=1.;
|
||||
G4VPhysicalVolume* thePhysVolume =
|
||||
fLinearNavigator->LocateGlobalPointAndSetup(position);
|
||||
G4double newStep =fLinearNavigator->ComputeStep(position,direction,1.e50,
|
||||
safety);
|
||||
if (theAccumulatedDepthVector) delete theAccumulatedDepthVector;
|
||||
theAccumulatedDepthVector = new G4PhysicsOrderedFreeVector();
|
||||
//if (theAccumulatedCSDepthVector) delete theAccumulatedCSDepthVector;
|
||||
//theAccumulatedCSDepthVector = new G4PhysicsOrderedFreeVector();
|
||||
void G4AdjointPrimaryGenerator::
|
||||
ComputeAccumulatedDepthVectorAlongBackRay(G4ThreeVector glob_pos,
|
||||
G4ThreeVector direction,
|
||||
G4double, G4ParticleDefinition*)
|
||||
{
|
||||
if (fLinearNavigator == nullptr)
|
||||
{
|
||||
fLinearNavigator = G4TransportationManager::GetTransportationManager()
|
||||
->GetNavigatorForTracking();
|
||||
}
|
||||
G4ThreeVector position = glob_pos;
|
||||
G4double safety=1.;
|
||||
G4VPhysicalVolume* thePhysVolume =
|
||||
fLinearNavigator->LocateGlobalPointAndSetup(position);
|
||||
G4double newStep = fLinearNavigator->ComputeStep(position,direction,1.e50,
|
||||
safety);
|
||||
if (theAccumulatedDepthVector != nullptr) {delete theAccumulatedDepthVector;}
|
||||
theAccumulatedDepthVector = new G4PhysicsOrderedFreeVector();
|
||||
|
||||
G4double acc_depth=0.;
|
||||
G4double acc_length=0.;
|
||||
//G4double acc_cs_depth=0.;
|
||||
//theAccumulatedCSDepthVector->InsertValues(acc_cs_depth, acc_length);
|
||||
theAccumulatedDepthVector->InsertValues(acc_length,acc_depth);
|
||||
G4double acc_depth=0.;
|
||||
G4double acc_length=0.;
|
||||
theAccumulatedDepthVector->InsertValues(acc_length,acc_depth);
|
||||
|
||||
while (newStep > 0. && thePhysVolume) {
|
||||
acc_length+=newStep;
|
||||
/*
|
||||
const G4MaterialCutsCouple* theMatCutsCouple=
|
||||
thePhysVolume->GetLogicalVolume()->GetMaterialCutsCouple();
|
||||
|
||||
|
||||
acc_cs_depth+=newStep*G4AdjointCSManager::GetAdjointCSManager()->GetTotalAdjointCS(aPartDef,
|
||||
ekin,
|
||||
theMatCutsCouple);
|
||||
theAccumulatedCSDepthVector->InsertValues(acc_cs_depth, acc_length);*/
|
||||
|
||||
acc_depth+=newStep*thePhysVolume->GetLogicalVolume()->GetMaterial()->GetDensity();
|
||||
theAccumulatedDepthVector->InsertValues(acc_length,acc_depth);
|
||||
position=position+newStep*direction;
|
||||
thePhysVolume =
|
||||
fLinearNavigator->LocateGlobalPointAndSetup(position,0,false);
|
||||
newStep =fLinearNavigator->ComputeStep(position,direction,1.e50,
|
||||
safety);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
G4double G4AdjointPrimaryGenerator::SampleDistanceAlongBackRayAndComputeWeightCorrection(G4double& weight_corr)
|
||||
{G4double rand = G4UniformRand();
|
||||
G4double distance = theAccumulatedDepthVector->FindLinearEnergy(rand);
|
||||
/*
|
||||
G4double acc_cs_depth=theAccumulatedCSDepthVector->GetEnergy(distance);
|
||||
weight_corr=std::exp(-acc_cs_depth);*/
|
||||
weight_corr=1.;
|
||||
return distance;
|
||||
while (newStep > 0. && thePhysVolume != nullptr)
|
||||
{
|
||||
acc_length+=newStep;
|
||||
acc_depth+=newStep*thePhysVolume->GetLogicalVolume()
|
||||
->GetMaterial()->GetDensity();
|
||||
theAccumulatedDepthVector->InsertValues(acc_length,acc_depth);
|
||||
position=position+newStep*direction;
|
||||
thePhysVolume = fLinearNavigator
|
||||
->LocateGlobalPointAndSetup(position,nullptr,false);
|
||||
newStep = fLinearNavigator->ComputeStep(position,direction,1.e50,safety);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4double G4AdjointPrimaryGenerator::
|
||||
SampleDistanceAlongBackRayAndComputeWeightCorrection(G4double& weight_corr)
|
||||
{
|
||||
G4double rand = G4UniformRand();
|
||||
G4double distance = theAccumulatedDepthVector->FindLinearEnergy(rand);
|
||||
weight_corr=1.;
|
||||
return distance;
|
||||
}
|
||||
|
||||
@@ -23,14 +23,12 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4AdjointStackingAction class implementation
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Class Name: G4AdjointCrossSurfChecker
|
||||
// Author: L. Desorgher
|
||||
// Organisation: SpaceIT GmbH
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Author: L. Desorgher, SpaceIT GmbH - April 2008
|
||||
// Contract: ESA contract 21435/08/NL/AT
|
||||
// Customer: ESA/ESTEC
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4AdjointStackingAction.hh"
|
||||
#include "G4AdjointTrackingAction.hh"
|
||||
@@ -39,53 +37,80 @@
|
||||
#include "G4ios.hh"
|
||||
#include "G4StackManager.hh"
|
||||
|
||||
|
||||
G4AdjointStackingAction::G4AdjointStackingAction(G4AdjointTrackingAction* anAction)
|
||||
: reclassification_stage (false)
|
||||
G4AdjointStackingAction::
|
||||
G4AdjointStackingAction(G4AdjointTrackingAction* anAction)
|
||||
{
|
||||
theFwdStackingAction =0;
|
||||
theUserAdjointStackingAction =0;
|
||||
theAdjointTrackingAction = anAction;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4AdjointStackingAction::~G4AdjointStackingAction()
|
||||
{;}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
G4ClassificationOfNewTrack G4AdjointStackingAction::ClassifyNewTrack(const G4Track * aTrack)
|
||||
G4ClassificationOfNewTrack
|
||||
G4AdjointStackingAction::ClassifyNewTrack(const G4Track * aTrack)
|
||||
{
|
||||
G4ClassificationOfNewTrack classification = fUrgent;
|
||||
G4String partType = aTrack->GetParticleDefinition()->GetParticleType();
|
||||
adjoint_mode = partType.contains(G4String("adjoint"));
|
||||
if (!adjoint_mode ){
|
||||
if (!reclassification_stage) classification = fWaiting;
|
||||
else { //need to check if forwrad tracking can be continued use of
|
||||
if (theAdjointTrackingAction->GetNbOfAdointTracksReachingTheExternalSurface()>0) {
|
||||
if (theFwdStackingAction) classification = theFwdStackingAction->ClassifyNewTrack(aTrack);
|
||||
}
|
||||
else classification = fKill;
|
||||
}
|
||||
}
|
||||
else if (theUserAdjointStackingAction) classification = theUserAdjointStackingAction->ClassifyNewTrack(aTrack);
|
||||
return classification;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointStackingAction::NewStage()
|
||||
{ reclassification_stage =true;
|
||||
if (first_reclassification_stage){
|
||||
if (theUserAdjointStackingAction) theUserAdjointStackingAction->NewStage();
|
||||
stackManager->ReClassify();
|
||||
G4ClassificationOfNewTrack classification = fUrgent;
|
||||
G4String partType = aTrack->GetParticleDefinition()->GetParticleType();
|
||||
adjoint_mode = partType.contains(G4String("adjoint"));
|
||||
if (!adjoint_mode )
|
||||
{
|
||||
if (!reclassification_stage)
|
||||
{
|
||||
classification = fWaiting;
|
||||
}
|
||||
else // need to check if forwrad tracking can be continued use of
|
||||
{
|
||||
if (theAdjointTrackingAction->GetNbOfAdointTracksReachingTheExternalSurface()>0)
|
||||
{
|
||||
if (theFwdStackingAction)
|
||||
{
|
||||
classification = theFwdStackingAction->ClassifyNewTrack(aTrack);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
classification = fKill;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (theFwdStackingAction) theFwdStackingAction->NewStage();
|
||||
first_reclassification_stage =false;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
void G4AdjointStackingAction::PrepareNewEvent()
|
||||
{ reclassification_stage =false;
|
||||
first_reclassification_stage =true;
|
||||
if (theUserAdjointStackingAction) theUserAdjointStackingAction->PrepareNewEvent();
|
||||
else if (theUserAdjointStackingAction)
|
||||
{
|
||||
classification = theUserAdjointStackingAction->ClassifyNewTrack(aTrack);
|
||||
}
|
||||
return classification;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
void G4AdjointStackingAction::NewStage()
|
||||
{
|
||||
reclassification_stage = true;
|
||||
if (first_reclassification_stage)
|
||||
{
|
||||
if (theUserAdjointStackingAction)
|
||||
{
|
||||
theUserAdjointStackingAction->NewStage();
|
||||
}
|
||||
stackManager->ReClassify();
|
||||
}
|
||||
else if (theFwdStackingAction) theFwdStackingAction->NewStage();
|
||||
{
|
||||
first_reclassification_stage = false;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
void G4AdjointStackingAction::PrepareNewEvent()
|
||||
{
|
||||
reclassification_stage = false;
|
||||
first_reclassification_stage = true;
|
||||
if (theUserAdjointStackingAction)
|
||||
{
|
||||
theUserAdjointStackingAction->PrepareNewEvent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4EvManMessenger class implementation
|
||||
//
|
||||
//
|
||||
// Author: M.Asai, SLAC
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4EvManMessenger.hh"
|
||||
@@ -34,7 +35,7 @@
|
||||
#include "G4UIcmdWithAnInteger.hh"
|
||||
|
||||
G4EvManMessenger::G4EvManMessenger(G4EventManager * fEvMan)
|
||||
:fEvManager(fEvMan)
|
||||
: fEvManager(fEvMan)
|
||||
{
|
||||
eventDirectory = new G4UIdirectory("/event/");
|
||||
eventDirectory->SetGuidance("EventManager control commands.");
|
||||
@@ -84,4 +85,3 @@ G4String G4EvManMessenger::GetCurrentValue(G4UIcommand * command)
|
||||
{ cv = verboseCmd->ConvertToString(fEvManager->GetVerboseLevel()); }
|
||||
return cv;
|
||||
}
|
||||
|
||||
|
||||
+19
-34
@@ -23,51 +23,36 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4Event class implementation
|
||||
//
|
||||
//
|
||||
|
||||
// G4Event
|
||||
// Author: M.Asai, SLAC
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4Event.hh"
|
||||
#include "G4VVisManager.hh"
|
||||
//#include "G4HCofThisEvent.hh"
|
||||
//#include "G4DCofThisEvent.hh"
|
||||
#include "G4VHitsCollection.hh"
|
||||
#include "G4VDigiCollection.hh"
|
||||
#include "G4ios.hh"
|
||||
|
||||
G4Allocator<G4Event>*& anEventAllocator()
|
||||
{
|
||||
G4ThreadLocalStatic G4Allocator<G4Event>* _instance = nullptr;
|
||||
return _instance;
|
||||
G4ThreadLocalStatic G4Allocator<G4Event>* _instance = nullptr;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
G4Event::G4Event()
|
||||
:eventID(0),
|
||||
thePrimaryVertex(nullptr),numberOfPrimaryVertex(0),
|
||||
HC(nullptr),DC(nullptr),trajectoryContainer(nullptr),
|
||||
eventAborted(false),userInfo(nullptr),
|
||||
randomNumberStatus(nullptr),validRandomNumberStatus(false),
|
||||
randomNumberStatusForProcessing(nullptr),validRandomNumberStatusForProcessing(false),
|
||||
keepTheEvent(false),grips(0)
|
||||
{
|
||||
}
|
||||
|
||||
G4Event::G4Event(G4int evID)
|
||||
:eventID(evID),
|
||||
thePrimaryVertex(nullptr),numberOfPrimaryVertex(0),
|
||||
HC(nullptr),DC(nullptr),trajectoryContainer(nullptr),
|
||||
eventAborted(false),userInfo(nullptr),
|
||||
randomNumberStatus(nullptr),validRandomNumberStatus(false),
|
||||
randomNumberStatusForProcessing(nullptr),validRandomNumberStatusForProcessing(false),
|
||||
keepTheEvent(false),grips(0)
|
||||
: eventID(evID)
|
||||
{
|
||||
}
|
||||
|
||||
G4Event::~G4Event()
|
||||
{
|
||||
G4PrimaryVertex* nextVertex = thePrimaryVertex;
|
||||
while(nextVertex)
|
||||
while(nextVertex != nullptr)
|
||||
{
|
||||
G4PrimaryVertex* thisVertex = nextVertex;
|
||||
nextVertex = thisVertex->GetNext();
|
||||
@@ -77,7 +62,7 @@ G4Event::~G4Event()
|
||||
thePrimaryVertex = nullptr;
|
||||
delete HC;
|
||||
delete DC;
|
||||
if(trajectoryContainer)
|
||||
if(trajectoryContainer != nullptr)
|
||||
{
|
||||
trajectoryContainer->clearAndDestroy();
|
||||
delete trajectoryContainer;
|
||||
@@ -87,12 +72,12 @@ G4Event::~G4Event()
|
||||
delete randomNumberStatusForProcessing;
|
||||
}
|
||||
|
||||
G4bool G4Event::operator==(const G4Event &right) const
|
||||
G4bool G4Event::operator==(const G4Event& right) const
|
||||
{
|
||||
return ( eventID == right.eventID );
|
||||
}
|
||||
|
||||
G4bool G4Event::operator!=(const G4Event &right) const
|
||||
G4bool G4Event::operator!=(const G4Event& right) const
|
||||
{
|
||||
return ( eventID != right.eventID );
|
||||
}
|
||||
@@ -105,31 +90,31 @@ void G4Event::Print() const
|
||||
void G4Event::Draw() const
|
||||
{
|
||||
G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
|
||||
if(!pVVisManager) return;
|
||||
if(pVVisManager == nullptr) return;
|
||||
|
||||
if(trajectoryContainer)
|
||||
{
|
||||
G4int n_traj = trajectoryContainer->entries();
|
||||
for(G4int i=0;i<n_traj;i++)
|
||||
for(G4int i=0; i<n_traj; ++i)
|
||||
{ (*trajectoryContainer)[i]->DrawTrajectory(); }
|
||||
}
|
||||
|
||||
if(HC)
|
||||
if(HC != nullptr)
|
||||
{
|
||||
G4int n_HC = HC->GetCapacity();
|
||||
for(G4int j=0;j<n_HC;j++)
|
||||
for(G4int j=0; j<n_HC; ++j)
|
||||
{
|
||||
G4VHitsCollection * VHC = HC->GetHC(j);
|
||||
if(VHC) VHC->DrawAllHits();
|
||||
G4VHitsCollection* VHC = HC->GetHC(j);
|
||||
if(VHC != nullptr) VHC->DrawAllHits();
|
||||
}
|
||||
}
|
||||
|
||||
if(DC)
|
||||
if(DC != nullptr)
|
||||
{
|
||||
G4int n_DC = DC->GetCapacity();
|
||||
for(G4int j=0;j<n_DC;j++)
|
||||
for(G4int j=0; j<n_DC; ++j)
|
||||
{
|
||||
G4VDigiCollection * VDC = DC->GetDC(j);
|
||||
G4VDigiCollection* VDC = DC->GetDC(j);
|
||||
if(VDC) VDC->DrawAllDigi();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4EventManager class implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// Author: M.Asai, SLAC
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4EventManager.hh"
|
||||
#include "G4ios.hh"
|
||||
@@ -42,73 +42,54 @@
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4ThreadLocal G4EventManager* G4EventManager::fpEventManager = nullptr;
|
||||
G4EventManager* G4EventManager::GetEventManager()
|
||||
{ return fpEventManager; }
|
||||
|
||||
G4EventManager::G4EventManager()
|
||||
:currentEvent(nullptr),trajectoryContainer(nullptr),
|
||||
trackIDCounter(0),
|
||||
verboseLevel(0),tracking(false),abortRequested(false),
|
||||
storetRandomNumberStatusToG4Event(false)
|
||||
G4EventManager* G4EventManager::GetEventManager()
|
||||
{
|
||||
if(fpEventManager)
|
||||
{
|
||||
G4Exception("G4EventManager::G4EventManager","Event0001",FatalException,
|
||||
"G4EventManager::G4EventManager() has already been made.");
|
||||
}
|
||||
else
|
||||
{
|
||||
trackManager = new G4TrackingManager;
|
||||
transformer = new G4PrimaryTransformer;
|
||||
trackContainer = new G4StackManager;
|
||||
theMessenger = new G4EvManMessenger(this);
|
||||
sdManager = G4SDManager::GetSDMpointerIfExist();
|
||||
stateManager = G4StateManager::GetStateManager();
|
||||
fpEventManager = this;
|
||||
userEventAction = nullptr;
|
||||
userStackingAction = nullptr;
|
||||
userTrackingAction = nullptr;
|
||||
userSteppingAction = nullptr;
|
||||
}
|
||||
return fpEventManager;
|
||||
}
|
||||
|
||||
/* private -> never called
|
||||
G4EventManager::G4EventManager(const G4EventManager&) {;}
|
||||
G4EventManager& G4EventManager::operator=(const G4EventManager&)
|
||||
{ return *this; }
|
||||
*/
|
||||
G4EventManager::G4EventManager()
|
||||
{
|
||||
if(fpEventManager != nullptr)
|
||||
{
|
||||
G4Exception("G4EventManager::G4EventManager", "Event0001", FatalException,
|
||||
"G4EventManager::G4EventManager() has already been made.");
|
||||
}
|
||||
else
|
||||
{
|
||||
trackManager = new G4TrackingManager;
|
||||
transformer = new G4PrimaryTransformer;
|
||||
trackContainer = new G4StackManager;
|
||||
theMessenger = new G4EvManMessenger(this);
|
||||
sdManager = G4SDManager::GetSDMpointerIfExist();
|
||||
stateManager = G4StateManager::GetStateManager();
|
||||
fpEventManager = this;
|
||||
}
|
||||
}
|
||||
|
||||
G4EventManager::~G4EventManager()
|
||||
{
|
||||
delete trackContainer;
|
||||
delete transformer;
|
||||
delete trackManager;
|
||||
delete theMessenger;
|
||||
delete userEventAction;
|
||||
fpEventManager = 0;
|
||||
delete trackContainer;
|
||||
delete transformer;
|
||||
delete trackManager;
|
||||
delete theMessenger;
|
||||
delete userEventAction;
|
||||
fpEventManager = nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
const G4EventManager & G4EventManager::operator=(const G4EventManager &right)
|
||||
{ }
|
||||
G4bool G4EventManager::operator==(const G4EventManager &right) const { }
|
||||
G4bool G4EventManager::operator!=(const G4EventManager &right) const { }
|
||||
*/
|
||||
|
||||
void G4EventManager::DoProcessing(G4Event* anEvent)
|
||||
{
|
||||
abortRequested = false;
|
||||
G4ApplicationState currentState = stateManager->GetCurrentState();
|
||||
if(currentState!=G4State_GeomClosed)
|
||||
if(currentState != G4State_GeomClosed)
|
||||
{
|
||||
G4Exception("G4EventManager::ProcessOneEvent",
|
||||
"Event0002", JustWarning,
|
||||
"IllegalApplicationState -- Geometry is not closed : cannot process an event.");
|
||||
G4Exception("G4EventManager::ProcessOneEvent", "Event0002", JustWarning,
|
||||
"IllegalState -- Geometry not closed: cannot process an event.");
|
||||
return;
|
||||
}
|
||||
currentEvent = anEvent;
|
||||
stateManager->SetNewState(G4State_EventProc);
|
||||
if(storetRandomNumberStatusToG4Event>1)
|
||||
if(storetRandomNumberStatusToG4Event > 1)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
CLHEP::HepRandom::saveFullState(oss);
|
||||
@@ -116,14 +97,14 @@ void G4EventManager::DoProcessing(G4Event* anEvent)
|
||||
currentEvent->SetRandomNumberStatusForProcessing(randomNumberStatusToG4Event);
|
||||
}
|
||||
|
||||
// Resetting Navigator has been moved to G4EventManager, so that resetting
|
||||
// is now done for every event.
|
||||
// Resetting Navigator has been moved to G4EventManager,
|
||||
// so that resetting is now done for every event.
|
||||
G4ThreeVector center(0,0,0);
|
||||
G4Navigator* navigator =
|
||||
G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking();
|
||||
G4Navigator* navigator = G4TransportationManager::GetTransportationManager()
|
||||
->GetNavigatorForTracking();
|
||||
navigator->LocateGlobalPointAndSetup(center,0,false);
|
||||
|
||||
G4Track * track = nullptr;
|
||||
G4Track* track = nullptr;
|
||||
G4TrackStatus istop = fAlive;
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
@@ -142,7 +123,7 @@ void G4EventManager::DoProcessing(G4Event* anEvent)
|
||||
#endif
|
||||
|
||||
sdManager = G4SDManager::GetSDMpointerIfExist();
|
||||
if(sdManager)
|
||||
if(sdManager != nullptr)
|
||||
{ currentEvent->SetHCofThisEvent(sdManager->PrepareNewEvent()); }
|
||||
|
||||
if(userEventAction) userEventAction->BeginOfEventAction(currentEvent);
|
||||
@@ -156,27 +137,29 @@ void G4EventManager::DoProcessing(G4Event* anEvent)
|
||||
#endif
|
||||
|
||||
if(!abortRequested)
|
||||
{ StackTracks( transformer->GimmePrimaries( currentEvent, trackIDCounter ),true ); }
|
||||
{
|
||||
StackTracks(transformer->GimmePrimaries(currentEvent,trackIDCounter), true);
|
||||
}
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if ( verboseLevel > 0 )
|
||||
{
|
||||
G4cout << trackContainer->GetNTotalTrack() << " primaries "
|
||||
<< "are passed from G4EventTransformer." << G4endl;
|
||||
<< "are passed from G4EventTransformer." << G4endl;
|
||||
G4cout << "!!!!!!! Now start processing an event !!!!!!!" << G4endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
G4VTrajectory* previousTrajectory;
|
||||
while( ( track = trackContainer->PopNextTrack(&previousTrajectory) ) != 0 ) // Loop checking 12.28.2015 M.Asai
|
||||
{
|
||||
while( (track=trackContainer->PopNextTrack(&previousTrajectory)) != nullptr )
|
||||
{ // Loop checking 12.28.2015 M.Asai
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if ( verboseLevel > 1 )
|
||||
{
|
||||
G4cout << "Track " << track << " (trackID " << track->GetTrackID()
|
||||
<< ", parentID " << track->GetParentID()
|
||||
<< ") is passed to G4TrackingManager." << G4endl;
|
||||
<< ", parentID " << track->GetParentID()
|
||||
<< ") is passed to G4TrackingManager." << G4endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -189,16 +172,16 @@ void G4EventManager::DoProcessing(G4Event* anEvent)
|
||||
if ( verboseLevel > 0 )
|
||||
{
|
||||
G4cout << "Track (trackID " << track->GetTrackID()
|
||||
<< ", parentID " << track->GetParentID()
|
||||
<< ", parentID " << track->GetParentID()
|
||||
<< ") is processed with stopping code " << istop << G4endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
G4VTrajectory * aTrajectory = nullptr;
|
||||
G4VTrajectory* aTrajectory = nullptr;
|
||||
#ifdef G4_STORE_TRAJECTORY
|
||||
aTrajectory = trackManager->GimmeTrajectory();
|
||||
|
||||
if(previousTrajectory)
|
||||
if(previousTrajectory != nullptr)
|
||||
{
|
||||
previousTrajectory->MergeTrajectory(aTrajectory);
|
||||
delete aTrajectory;
|
||||
@@ -206,14 +189,16 @@ void G4EventManager::DoProcessing(G4Event* anEvent)
|
||||
}
|
||||
if(aTrajectory&&(istop!=fStopButAlive)&&(istop!=fSuspend))
|
||||
{
|
||||
if(!trajectoryContainer)
|
||||
{ trajectoryContainer = new G4TrajectoryContainer;
|
||||
currentEvent->SetTrajectoryContainer(trajectoryContainer); }
|
||||
if(trajectoryContainer == nullptr)
|
||||
{
|
||||
trajectoryContainer = new G4TrajectoryContainer;
|
||||
currentEvent->SetTrajectoryContainer(trajectoryContainer);
|
||||
}
|
||||
trajectoryContainer->insert(aTrajectory);
|
||||
}
|
||||
#endif
|
||||
|
||||
G4TrackVector * secondaries = trackManager->GimmeSecondaries();
|
||||
G4TrackVector* secondaries = trackManager->GimmeSecondaries();
|
||||
switch (istop)
|
||||
{
|
||||
case fStopButAlive:
|
||||
@@ -233,15 +218,14 @@ void G4EventManager::DoProcessing(G4Event* anEvent)
|
||||
break;
|
||||
|
||||
case fAlive:
|
||||
G4Exception("G4EventManager::DoProcessing","Event004",JustWarning,
|
||||
"Illegal trackstatus returned from G4TrackingManager. Continue with"\
|
||||
"simulation.");
|
||||
G4Exception("G4EventManager::DoProcessing", "Event004", JustWarning,
|
||||
"Illegal trackstatus returned from G4TrackingManager."\
|
||||
" Continue with simulation.");
|
||||
break;
|
||||
case fKillTrackAndSecondaries:
|
||||
//if( secondaries ) secondaries->clearAndDestroy();
|
||||
if( secondaries )
|
||||
{
|
||||
for(size_t i=0;i<secondaries->size();i++)
|
||||
for(std::size_t i=0; i<secondaries->size(); ++i)
|
||||
{ delete (*secondaries)[i]; }
|
||||
secondaries->clear();
|
||||
}
|
||||
@@ -258,29 +242,30 @@ void G4EventManager::DoProcessing(G4Event* anEvent)
|
||||
}
|
||||
#endif
|
||||
|
||||
if(sdManager)
|
||||
{ sdManager->TerminateCurrentEvent(currentEvent->GetHCofThisEvent()); }
|
||||
if(sdManager != nullptr)
|
||||
{
|
||||
sdManager->TerminateCurrentEvent(currentEvent->GetHCofThisEvent());
|
||||
}
|
||||
|
||||
if(userEventAction) userEventAction->EndOfEventAction(currentEvent);
|
||||
if(userEventAction)
|
||||
{
|
||||
userEventAction->EndOfEventAction(currentEvent);
|
||||
}
|
||||
|
||||
stateManager->SetNewState(G4State_GeomClosed);
|
||||
currentEvent = nullptr;
|
||||
abortRequested = false;
|
||||
}
|
||||
|
||||
void G4EventManager::StackTracks(G4TrackVector *trackVector,G4bool IDhasAlreadySet)
|
||||
void G4EventManager::StackTracks(G4TrackVector* trackVector,
|
||||
G4bool IDhasAlreadySet)
|
||||
{
|
||||
if( trackVector )
|
||||
if( trackVector != nullptr )
|
||||
{
|
||||
//size_t n_passedTrack = trackVector->size();
|
||||
//if( n_passedTrack == 0 ) return;
|
||||
//for( size_t i = 0; i < n_passedTrack; i++ )
|
||||
//{
|
||||
// newTrack = (*trackVector)[ i ];
|
||||
if( trackVector->size() == 0 ) return;
|
||||
for( auto newTrack : *trackVector )
|
||||
{
|
||||
trackIDCounter++;
|
||||
++trackIDCounter;
|
||||
if(!IDhasAlreadySet)
|
||||
{
|
||||
newTrack->SetTrackID( trackIDCounter );
|
||||
@@ -297,9 +282,9 @@ void G4EventManager::StackTracks(G4TrackVector *trackVector,G4bool IDhasAlreadyS
|
||||
if ( verboseLevel > 1 )
|
||||
{
|
||||
G4cout << "A new track " << newTrack
|
||||
<< " (trackID " << newTrack->GetTrackID()
|
||||
<< ", parentID " << newTrack->GetParentID()
|
||||
<< ") is passed to G4StackManager." << G4endl;
|
||||
<< " (trackID " << newTrack->GetTrackID()
|
||||
<< ", parentID " << newTrack->GetParentID()
|
||||
<< ") is passed to G4StackManager." << G4endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -310,7 +295,10 @@ void G4EventManager::StackTracks(G4TrackVector *trackVector,G4bool IDhasAlreadyS
|
||||
void G4EventManager::SetUserAction(G4UserEventAction* userAction)
|
||||
{
|
||||
userEventAction = userAction;
|
||||
if(userEventAction) userEventAction->SetEventManager(this);
|
||||
if(userEventAction != nullptr)
|
||||
{
|
||||
userEventAction->SetEventManager(this);
|
||||
}
|
||||
}
|
||||
|
||||
void G4EventManager::SetUserAction(G4UserStackingAction* userAction)
|
||||
@@ -337,18 +325,20 @@ void G4EventManager::ProcessOneEvent(G4Event* anEvent)
|
||||
DoProcessing(anEvent);
|
||||
}
|
||||
|
||||
void G4EventManager::ProcessOneEvent(G4TrackVector* trackVector,G4Event* anEvent)
|
||||
void G4EventManager::ProcessOneEvent(G4TrackVector* trackVector,
|
||||
G4Event* anEvent)
|
||||
{
|
||||
static G4ThreadLocal G4String *randStat = 0;
|
||||
if (!randStat) randStat = new G4String;
|
||||
static G4ThreadLocal G4String* randStat = nullptr;
|
||||
if (randStat == nullptr) randStat = new G4String;
|
||||
trackIDCounter = 0;
|
||||
G4bool tempEvent = false;
|
||||
if(!anEvent)
|
||||
if(anEvent == nullptr)
|
||||
{
|
||||
anEvent = new G4Event();
|
||||
tempEvent = true;
|
||||
}
|
||||
if(storetRandomNumberStatusToG4Event==1 || storetRandomNumberStatusToG4Event==3)
|
||||
if (storetRandomNumberStatusToG4Event==1
|
||||
|| storetRandomNumberStatusToG4Event==3)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
CLHEP::HepRandom::saveFullState(oss);
|
||||
@@ -356,18 +346,18 @@ void G4EventManager::ProcessOneEvent(G4TrackVector* trackVector,G4Event* anEvent
|
||||
}
|
||||
StackTracks(trackVector,false);
|
||||
DoProcessing(anEvent);
|
||||
if(tempEvent)
|
||||
{ delete anEvent; }
|
||||
if(tempEvent) { delete anEvent; }
|
||||
}
|
||||
|
||||
void G4EventManager::SetUserInformation(G4VUserEventInformation* anInfo)
|
||||
{
|
||||
G4ApplicationState currentState = stateManager->GetCurrentState();
|
||||
if(currentState!=G4State_EventProc || currentEvent==0)
|
||||
if(currentState != G4State_EventProc || currentEvent == 0)
|
||||
{
|
||||
G4Exception("G4EventManager::SetUserInformation",
|
||||
"Event0003", JustWarning,
|
||||
"G4VUserEventInformation cannot be set because of ansense of G4Event.");
|
||||
"G4VUserEventInformation cannot be set because of absence "\
|
||||
"of G4Event.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -377,14 +367,18 @@ void G4EventManager::SetUserInformation(G4VUserEventInformation* anInfo)
|
||||
G4VUserEventInformation* G4EventManager::GetUserInformation()
|
||||
{
|
||||
G4ApplicationState currentState = stateManager->GetCurrentState();
|
||||
if(currentState!=G4State_EventProc || currentEvent==0)
|
||||
{ return 0; }
|
||||
if(currentState != G4State_EventProc || currentEvent == 0)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return currentEvent->GetUserInformation();
|
||||
}
|
||||
|
||||
void G4EventManager::KeepTheCurrentEvent()
|
||||
{ if(currentEvent) currentEvent->KeepTheEvent(); }
|
||||
{
|
||||
if(currentEvent != nullptr) { currentEvent->KeepTheEvent(); }
|
||||
}
|
||||
|
||||
void G4EventManager::AbortCurrentEvent()
|
||||
{
|
||||
@@ -392,4 +386,3 @@ void G4EventManager::AbortCurrentEvent()
|
||||
trackContainer->clear();
|
||||
if(tracking) trackManager->EventAborted();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,43 +23,13 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MODULE: G4GeneralParticleSource.cc
|
||||
//
|
||||
// Version: 2.0
|
||||
// Date: 5/02/04
|
||||
// Author: Fan Lei
|
||||
// Organisation: QinetiQ ltd.
|
||||
// Customer: ESA/ESTEC
|
||||
//
|
||||
// Documentation avaialable at http://reat.space.qinetiq.com/gps
|
||||
// These include:
|
||||
// User Requirement Document (URD)
|
||||
// Software Specification Documents (SSD)
|
||||
// Software User Manual (SUM): on-line version available
|
||||
// Technical Note (TN) on the physics and algorithms
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
//
|
||||
// Version 2.0, 05/02/2004, Fan Lei, Created.
|
||||
// After changes to version 1.1 as in Geant4 v6.0
|
||||
// - Mutilple particle source definition
|
||||
// - Re-structured commands
|
||||
// - Split the task into smaller classes
|
||||
//
|
||||
// - old commonds have been retained for backward compatibility, will be
|
||||
// removed in the future.
|
||||
//
|
||||
// 25/03/2014, Andrew Green
|
||||
// Various changes to use the new G4GeneralParticleSourceData class, mostly
|
||||
// just transparent wrappers around the thread safe object.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// G4GeneralParticleSource class implementation
|
||||
//
|
||||
// Author: Fan Lei, QinetiQ ltd - 05/02/2004
|
||||
// Customer: ESA/ESTEC
|
||||
// Version: 2.0
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4Event.hh"
|
||||
#include "Randomize.hh"
|
||||
#include "G4GeneralParticleSource.hh"
|
||||
@@ -71,161 +41,186 @@
|
||||
#include "G4Threading.hh"
|
||||
#include "G4AutoLock.hh"
|
||||
|
||||
namespace {
|
||||
G4Mutex messangerInit = G4MUTEX_INITIALIZER;
|
||||
namespace
|
||||
{
|
||||
G4Mutex messangerInit = G4MUTEX_INITIALIZER;
|
||||
}
|
||||
|
||||
G4GeneralParticleSource::G4GeneralParticleSource() : normalised(false),
|
||||
theMessenger(0)
|
||||
G4GeneralParticleSource::G4GeneralParticleSource()
|
||||
{
|
||||
GPSData = G4GeneralParticleSourceData::Instance();
|
||||
//currentSource = GPSData->GetCurrentSource();
|
||||
//currentSourceIdx = G4int(GPSData->GetSourceVectorSize() - 1);
|
||||
GPSData = G4GeneralParticleSourceData::Instance();
|
||||
// currentSource = GPSData->GetCurrentSource();
|
||||
// currentSourceIdx = G4int(GPSData->GetSourceVectorSize() - 1);
|
||||
|
||||
//Messenger is special, only a worker should instantiate it. Singleton pattern
|
||||
theMessenger = G4GeneralParticleSourceMessenger::GetInstance(this);
|
||||
//Some initialization should be done only once
|
||||
G4AutoLock l(&messangerInit);
|
||||
static G4bool onlyOnce = false;
|
||||
if ( !onlyOnce ) {
|
||||
theMessenger->SetParticleGun(GPSData->GetCurrentSource());
|
||||
IntensityNormalization();
|
||||
onlyOnce = true;
|
||||
}
|
||||
// Messenger is special, only a worker should instantiate it.
|
||||
// Singleton pattern
|
||||
//
|
||||
theMessenger = G4GeneralParticleSourceMessenger::GetInstance(this);
|
||||
|
||||
// Some initialization should be done only once
|
||||
//
|
||||
G4AutoLock l(&messangerInit);
|
||||
static G4bool onlyOnce = false;
|
||||
if ( !onlyOnce )
|
||||
{
|
||||
theMessenger->SetParticleGun(GPSData->GetCurrentSource());
|
||||
IntensityNormalization();
|
||||
onlyOnce = true;
|
||||
}
|
||||
}
|
||||
|
||||
G4GeneralParticleSource::~G4GeneralParticleSource()
|
||||
{
|
||||
theMessenger->Destroy();
|
||||
theMessenger->Destroy();
|
||||
}
|
||||
|
||||
void G4GeneralParticleSource::AddaSource(G4double aV)
|
||||
{
|
||||
GPSData->Lock();
|
||||
GPSData->AddASource(aV);
|
||||
theMessenger->SetParticleGun(GPSData->GetCurrentSource());
|
||||
//TODO: But do we really normalize here after each source?
|
||||
IntensityNormalization();
|
||||
GPSData->Unlock();
|
||||
GPSData->Lock();
|
||||
|
||||
GPSData->AddASource(aV);
|
||||
theMessenger->SetParticleGun(GPSData->GetCurrentSource());
|
||||
|
||||
// TODO: But do we really normalize here after each source?
|
||||
IntensityNormalization();
|
||||
|
||||
GPSData->Unlock();
|
||||
}
|
||||
|
||||
void G4GeneralParticleSource::IntensityNormalization()
|
||||
{
|
||||
GPSData->IntensityNormalise();
|
||||
normalised=GPSData->Normalised();
|
||||
GPSData->IntensityNormalise();
|
||||
normalised=GPSData->Normalised();
|
||||
}
|
||||
|
||||
void G4GeneralParticleSource::ListSource()
|
||||
{
|
||||
G4cout << "The number of particle sources is: " << GPSData->GetIntensityVectorSize() << G4endl;
|
||||
G4cout <<" Multiple Vertex sources: "<<GPSData->GetMultipleVertex();
|
||||
G4cout <<" Flat Sampling flag: "<<GPSData->GetFlatSampling()<<G4endl;
|
||||
const G4int currentIdx = GPSData->GetCurrentSourceIdx();
|
||||
for(G4int i=0; i<GPSData->GetIntensityVectorSize(); i++)
|
||||
{
|
||||
G4cout << "\tsource " << i << " with intensity: " << GPSData->GetIntensity(i) << G4endl;
|
||||
const G4SingleParticleSource* thisSrc = GPSData->GetCurrentSource(i);
|
||||
G4cout <<" \t\tNum Particles: "<<thisSrc->GetNumberOfParticles()<<"; Particle type: "<<thisSrc->GetParticleDefinition()->GetParticleName()<<G4endl;
|
||||
G4cout <<" \t\tEnergy: "<<G4BestUnit(thisSrc->GetParticleEnergy(),"Energy")<<G4endl;
|
||||
G4cout <<" \t\tDirection: "<<thisSrc->GetAngDist()->GetDirection()<<"; Position: ";
|
||||
G4cout <<G4BestUnit(thisSrc->GetPosDist()->GetCentreCoords(),"Length")<<G4endl;
|
||||
G4cout <<" \t\tAngular Distribution: "<<thisSrc->GetAngDist()->GetDistType()<<G4endl;
|
||||
G4cout <<" \t\tEnergy Distribution: "<<thisSrc->GetEneDist()->GetEnergyDisType()<<G4endl;
|
||||
G4cout <<" \t\tPosition Distribution Type: "<<thisSrc->GetPosDist()->GetPosDisType();
|
||||
G4cout <<"; Position Shape: "<<thisSrc->GetPosDist()->GetPosDisShape()<<G4endl;
|
||||
}
|
||||
//Set back previous source
|
||||
GPSData->GetCurrentSource(currentIdx);
|
||||
G4cout << "The number of particle sources is: "
|
||||
<< GPSData->GetIntensityVectorSize() << G4endl;
|
||||
G4cout << " Multiple Vertex sources: " << GPSData->GetMultipleVertex();
|
||||
G4cout << " Flat Sampling flag: " << GPSData->GetFlatSampling() << G4endl;
|
||||
const G4int currentIdx = GPSData->GetCurrentSourceIdx();
|
||||
for(G4int i=0; i<GPSData->GetIntensityVectorSize(); ++i)
|
||||
{
|
||||
G4cout << "\tsource " << i << " with intensity: "
|
||||
<< GPSData->GetIntensity(i) << G4endl;
|
||||
const G4SingleParticleSource* thisSrc = GPSData->GetCurrentSource(i);
|
||||
G4cout << " \t\tNum Particles: "<<thisSrc->GetNumberOfParticles()
|
||||
<< "; Particle type: "
|
||||
<< thisSrc->GetParticleDefinition()->GetParticleName() << G4endl;
|
||||
G4cout << " \t\tEnergy: "
|
||||
<< G4BestUnit(thisSrc->GetParticleEnergy(),"Energy") << G4endl;
|
||||
G4cout << " \t\tDirection: "
|
||||
<< thisSrc->GetAngDist()->GetDirection() << "; Position: ";
|
||||
G4cout << G4BestUnit(thisSrc->GetPosDist()->GetCentreCoords(),"Length")
|
||||
<< G4endl;
|
||||
G4cout << " \t\tAngular Distribution: "
|
||||
<< thisSrc->GetAngDist()->GetDistType() << G4endl;
|
||||
G4cout << " \t\tEnergy Distribution: "
|
||||
<< thisSrc->GetEneDist()->GetEnergyDisType() << G4endl;
|
||||
G4cout << " \t\tPosition Distribution Type: "
|
||||
<< thisSrc->GetPosDist()->GetPosDisType();
|
||||
G4cout << "; Position Shape: "
|
||||
<< thisSrc->GetPosDist()->GetPosDisShape() << G4endl;
|
||||
}
|
||||
|
||||
// Set back previous source
|
||||
GPSData->GetCurrentSource(currentIdx);
|
||||
}
|
||||
|
||||
void G4GeneralParticleSource::SetCurrentSourceto(G4int aV)
|
||||
{
|
||||
G4int id = aV;
|
||||
if ( id < GPSData->GetIntensityVectorSize() )
|
||||
{
|
||||
//currentSourceIdx = aV;
|
||||
//currentSource = GPSData->GetCurrentSource(id);
|
||||
theMessenger->SetParticleGun(GPSData->GetCurrentSource(id));
|
||||
}
|
||||
else
|
||||
{
|
||||
G4ExceptionDescription msg;
|
||||
msg<<"Trying to set source to index "<<aV<<" but only "<<GPSData->GetIntensityVectorSize()<<" sources are defined.";
|
||||
G4Exception("G4GeneralParticleSoruce::SetCurrentSourceto","G4GPS004",FatalException,msg);
|
||||
}
|
||||
G4int id = aV;
|
||||
if ( id < GPSData->GetIntensityVectorSize() )
|
||||
{
|
||||
// currentSourceIdx = aV;
|
||||
// currentSource = GPSData->GetCurrentSource(id);
|
||||
theMessenger->SetParticleGun(GPSData->GetCurrentSource(id));
|
||||
}
|
||||
else
|
||||
{
|
||||
G4ExceptionDescription msg;
|
||||
msg << "Trying to set source to index " << aV << " but only "
|
||||
<< GPSData->GetIntensityVectorSize() << " sources are defined.";
|
||||
G4Exception("G4GeneralParticleSoruce::SetCurrentSourceto", "G4GPS004",
|
||||
FatalException, msg);
|
||||
}
|
||||
}
|
||||
|
||||
void G4GeneralParticleSource::SetCurrentSourceIntensity(G4double aV)
|
||||
{
|
||||
GPSData->Lock();
|
||||
GPSData->SetCurrentSourceIntensity(aV);
|
||||
GPSData->Unlock();
|
||||
normalised = GPSData->Normalised();
|
||||
GPSData->Lock();
|
||||
GPSData->SetCurrentSourceIntensity(aV);
|
||||
GPSData->Unlock();
|
||||
normalised = GPSData->Normalised();
|
||||
}
|
||||
|
||||
void G4GeneralParticleSource::ClearAll()
|
||||
{
|
||||
GPSData->ClearSources();
|
||||
normalised=GPSData->Normalised();
|
||||
GPSData->ClearSources();
|
||||
normalised=GPSData->Normalised();
|
||||
}
|
||||
|
||||
void G4GeneralParticleSource::DeleteaSource(G4int aV)
|
||||
{
|
||||
G4int id = aV;
|
||||
if ( id <= GPSData->GetIntensityVectorSize() )
|
||||
{
|
||||
GPSData->DeleteASource(aV);
|
||||
normalised=GPSData->Normalised();
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << " source index is invalid " << G4endl;
|
||||
G4cout << " it shall be <= " << GPSData->GetIntensityVectorSize() << G4endl;
|
||||
}
|
||||
G4int id = aV;
|
||||
if ( id <= GPSData->GetIntensityVectorSize() )
|
||||
{
|
||||
GPSData->DeleteASource(aV);
|
||||
normalised=GPSData->Normalised();
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << " source index is invalid " << G4endl;
|
||||
G4cout << " it shall be <= "
|
||||
<< GPSData->GetIntensityVectorSize() << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
void G4GeneralParticleSource::GeneratePrimaryVertex(G4Event* evt)
|
||||
{
|
||||
if (!GPSData->GetMultipleVertex())
|
||||
if (!GPSData->GetMultipleVertex())
|
||||
{
|
||||
G4SingleParticleSource* currentSource = GPSData->GetCurrentSource();
|
||||
if (GPSData->GetIntensityVectorSize() > 1)
|
||||
{
|
||||
G4SingleParticleSource* currentSource = GPSData->GetCurrentSource();
|
||||
if (GPSData->GetIntensityVectorSize() > 1)
|
||||
// Try to minimize locks
|
||||
if (! normalised )
|
||||
{
|
||||
// According to local variable, normalization is needed
|
||||
// Check with underlying shared resource, another
|
||||
// thread could have already normalized this
|
||||
GPSData->Lock();
|
||||
G4bool norm = GPSData->Normalised();
|
||||
if (!norm)
|
||||
{
|
||||
//Try to minimize locks
|
||||
if (! normalised ) {
|
||||
//According to local variable, normalization is needed
|
||||
//Check with underlying shared resource, another
|
||||
//thread could have already normalized this
|
||||
GPSData->Lock();
|
||||
G4bool norm = GPSData->Normalised();
|
||||
if (!norm) {
|
||||
IntensityNormalization();
|
||||
}
|
||||
//This takes care of the case in which the local variable
|
||||
//is False and the underlying resource is true.
|
||||
normalised = GPSData->Normalised();
|
||||
GPSData->Unlock();
|
||||
}
|
||||
G4double rndm = G4UniformRand();
|
||||
size_t i = 0 ;
|
||||
if (! GPSData->GetFlatSampling() )
|
||||
{
|
||||
while ( rndm > GPSData->GetSourceProbability(i) ) i++;
|
||||
currentSource = GPSData->GetCurrentSource(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = size_t (GPSData->GetIntensityVectorSize()*rndm);
|
||||
currentSource = GPSData->GetCurrentSource(i);
|
||||
}
|
||||
}
|
||||
currentSource->GeneratePrimaryVertex(evt);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (G4int i = 0; i < GPSData->GetIntensityVectorSize(); i++)
|
||||
{
|
||||
GPSData->GetCurrentSource(i)->GeneratePrimaryVertex(evt);
|
||||
IntensityNormalization();
|
||||
}
|
||||
// This takes care of the case in which the local variable
|
||||
// is False and the underlying resource is true.
|
||||
normalised = GPSData->Normalised();
|
||||
GPSData->Unlock();
|
||||
}
|
||||
G4double rndm = G4UniformRand();
|
||||
std::size_t i = 0 ;
|
||||
if (! GPSData->GetFlatSampling() )
|
||||
{
|
||||
while ( rndm > GPSData->GetSourceProbability(i) ) ++i;
|
||||
currentSource = GPSData->GetCurrentSource(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = std::size_t (GPSData->GetIntensityVectorSize()*rndm);
|
||||
currentSource = GPSData->GetCurrentSource(i);
|
||||
}
|
||||
}
|
||||
currentSource->GeneratePrimaryVertex(evt);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (G4int i = 0; i < GPSData->GetIntensityVectorSize(); ++i)
|
||||
{
|
||||
GPSData->GetCurrentSource(i)->GeneratePrimaryVertex(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,187 +23,159 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4GeneralParticleSourceData class implementation
|
||||
//
|
||||
// -------------------------------------------------------------------
|
||||
//
|
||||
// GEANT4 Class file
|
||||
//
|
||||
//
|
||||
// File name: G4GeneralParticleSourceData.cc
|
||||
//
|
||||
// Author: Andrew Green
|
||||
//
|
||||
// Creation date: 20 Mar 2014
|
||||
//
|
||||
// Modifications:
|
||||
// 24/03/2014
|
||||
// Fixed a bug whereby there was a data race for ownership of the "currentSource"
|
||||
// member data. This has been resolved by returning a pointer to the G4SPS from
|
||||
// the source vector. Tested up to 4 threads, and works fine; may need some further
|
||||
// locking in the G4SPS code.
|
||||
//
|
||||
//
|
||||
// Class Description:
|
||||
// This class uses the singleton pattern to create a single copy of the data
|
||||
// needed for the G4GPS class. As yet, only the largest parts have been split
|
||||
// off.
|
||||
//
|
||||
//
|
||||
// Author: Andrew Green, 20.03.2014
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4GeneralParticleSourceData.hh"
|
||||
#include "G4Threading.hh"
|
||||
#include "G4AutoLock.hh"
|
||||
|
||||
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
G4Mutex singMutex = G4MUTEX_INITIALIZER; //Protects singleton access
|
||||
G4Mutex singMutex = G4MUTEX_INITIALIZER; // Protects singleton access
|
||||
}
|
||||
|
||||
//G4GeneralParticleSourceData* G4GeneralParticleSourceData::theInstance = 0;
|
||||
|
||||
G4GeneralParticleSourceData::G4GeneralParticleSourceData() :
|
||||
multiple_vertex(false) ,flat_sampling(false),
|
||||
normalised(false),currentSourceIdx(0)
|
||||
G4GeneralParticleSourceData::G4GeneralParticleSourceData()
|
||||
{
|
||||
G4MUTEXINIT(mutex);
|
||||
G4MUTEXINIT(mutex);
|
||||
|
||||
sourceVector.clear();
|
||||
sourceIntensity.clear();
|
||||
sourceProbability.clear();
|
||||
sourceVector.clear();
|
||||
sourceIntensity.clear();
|
||||
sourceProbability.clear();
|
||||
|
||||
currentSource = new G4SingleParticleSource();
|
||||
sourceVector.push_back(currentSource);
|
||||
sourceIntensity.push_back(1.);
|
||||
|
||||
currentSource = new G4SingleParticleSource();
|
||||
sourceVector.push_back(currentSource);
|
||||
sourceIntensity.push_back(1.);
|
||||
}
|
||||
|
||||
G4GeneralParticleSourceData::~G4GeneralParticleSourceData()
|
||||
{
|
||||
G4MUTEXDESTROY(mutex);
|
||||
for ( std::vector<G4SingleParticleSource*>::const_iterator it = sourceVector.begin() ;
|
||||
it != sourceVector.end() ; ++it ) { delete *it; }
|
||||
for ( auto it = sourceVector.cbegin(); it != sourceVector.cend(); ++it )
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
sourceVector.clear();
|
||||
}
|
||||
|
||||
|
||||
G4GeneralParticleSourceData* G4GeneralParticleSourceData::Instance()
|
||||
{
|
||||
G4AutoLock lock(&singMutex);
|
||||
static G4GeneralParticleSourceData instance;
|
||||
return &instance;
|
||||
G4AutoLock lock(&singMutex);
|
||||
static G4GeneralParticleSourceData instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
void G4GeneralParticleSourceData::IntensityNormalise()
|
||||
{
|
||||
G4double total = 0.;
|
||||
size_t i = 0 ;
|
||||
for (i = 0; i < sourceIntensity.size(); i++)
|
||||
{
|
||||
total += sourceIntensity[i] ;
|
||||
}
|
||||
sourceProbability.clear();
|
||||
std::vector <G4double> sourceNormalizedIntensity;
|
||||
sourceNormalizedIntensity.clear();
|
||||
G4double total = 0.;
|
||||
std::size_t i = 0 ;
|
||||
for (i = 0; i < sourceIntensity.size(); ++i)
|
||||
{
|
||||
total += sourceIntensity[i] ;
|
||||
}
|
||||
sourceProbability.clear();
|
||||
std::vector <G4double> sourceNormalizedIntensity;
|
||||
sourceNormalizedIntensity.clear();
|
||||
|
||||
sourceNormalizedIntensity.push_back(sourceIntensity[0]/total);
|
||||
sourceProbability.push_back(sourceNormalizedIntensity[0]);
|
||||
sourceNormalizedIntensity.push_back(sourceIntensity[0]/total);
|
||||
sourceProbability.push_back(sourceNormalizedIntensity[0]);
|
||||
|
||||
for ( i = 1 ; i < sourceIntensity.size(); i++)
|
||||
for (i = 1 ; i < sourceIntensity.size(); ++i)
|
||||
{
|
||||
sourceNormalizedIntensity.push_back(sourceIntensity[i]/total);
|
||||
sourceProbability.push_back(sourceNormalizedIntensity[i]+sourceProbability[i-1]);
|
||||
}
|
||||
|
||||
// set source weights here based on sampling scheme (analog/flat)
|
||||
// and intensities
|
||||
//
|
||||
for (i = 0 ; i < sourceIntensity.size(); ++i)
|
||||
{
|
||||
if (!flat_sampling)
|
||||
{
|
||||
sourceNormalizedIntensity.push_back(sourceIntensity[i]/total);
|
||||
sourceProbability.push_back(sourceNormalizedIntensity[i] + sourceProbability[i-1]);
|
||||
GetCurrentSource(i)->GetBiasRndm()->SetIntensityWeight(1.);
|
||||
}
|
||||
|
||||
// set source weights here based on sampling scheme (analog/flat) and intensities
|
||||
for ( i = 0 ; i < sourceIntensity.size(); i++)
|
||||
else
|
||||
{
|
||||
if (!flat_sampling)
|
||||
{
|
||||
this->GetCurrentSource(i)->GetBiasRndm()->SetIntensityWeight(1.);
|
||||
}
|
||||
else
|
||||
{
|
||||
this->GetCurrentSource(i)->GetBiasRndm()->SetIntensityWeight(sourceNormalizedIntensity[i]*sourceIntensity.size());
|
||||
}
|
||||
GetCurrentSource(i)->GetBiasRndm()
|
||||
->SetIntensityWeight(sourceNormalizedIntensity[i]*sourceIntensity.size());
|
||||
}
|
||||
|
||||
normalised = true;
|
||||
}
|
||||
normalised = true;
|
||||
}
|
||||
|
||||
void G4GeneralParticleSourceData::SetCurrentSourceIntensity(G4double intensity)
|
||||
{
|
||||
sourceIntensity.at(currentSourceIdx) = intensity;
|
||||
normalised = false;
|
||||
sourceIntensity.at(currentSourceIdx) = intensity;
|
||||
normalised = false;
|
||||
}
|
||||
|
||||
void G4GeneralParticleSourceData::AddASource(G4double intensity)
|
||||
{
|
||||
currentSource = new G4SingleParticleSource();
|
||||
sourceVector.push_back(currentSource);
|
||||
sourceIntensity.push_back(intensity);
|
||||
currentSourceIdx = sourceVector.size() - 1;
|
||||
normalised = false;
|
||||
currentSource = new G4SingleParticleSource();
|
||||
sourceVector.push_back(currentSource);
|
||||
sourceIntensity.push_back(intensity);
|
||||
currentSourceIdx = sourceVector.size() - 1;
|
||||
normalised = false;
|
||||
}
|
||||
|
||||
void G4GeneralParticleSourceData::DeleteASource(G4int idx)
|
||||
{
|
||||
delete sourceVector[idx];
|
||||
sourceVector.erase(sourceVector.begin() + idx);
|
||||
sourceIntensity.erase(sourceIntensity.begin()+idx);
|
||||
normalised = false ;
|
||||
if (currentSourceIdx == idx )
|
||||
delete sourceVector[idx];
|
||||
sourceVector.erase(sourceVector.begin() + idx);
|
||||
sourceIntensity.erase(sourceIntensity.begin()+idx);
|
||||
normalised = false ;
|
||||
if (currentSourceIdx == idx )
|
||||
{
|
||||
if ( GetIntensityVectorSize() > 0 )
|
||||
{
|
||||
if ( this->GetIntensityVectorSize() > 0 )
|
||||
{
|
||||
currentSource = this->GetCurrentSource(0);
|
||||
currentSourceIdx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentSource = NULL;
|
||||
currentSourceIdx = -1;
|
||||
}
|
||||
currentSource = GetCurrentSource(0);
|
||||
currentSourceIdx = 0;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
currentSource = nullptr;
|
||||
currentSourceIdx = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G4GeneralParticleSourceData::ClearSources()
|
||||
{
|
||||
currentSourceIdx = -1;
|
||||
currentSource = NULL;
|
||||
for ( std::vector<G4SingleParticleSource*>::iterator it = sourceVector.begin();
|
||||
it != sourceVector.end() ; ++it ) { delete *it; }
|
||||
sourceVector.clear();
|
||||
sourceIntensity.clear();
|
||||
normalised = false;
|
||||
currentSourceIdx = -1;
|
||||
currentSource = nullptr;
|
||||
for ( auto it = sourceVector.cbegin(); it != sourceVector.cend(); ++it )
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
sourceVector.clear();
|
||||
sourceIntensity.clear();
|
||||
normalised = false;
|
||||
}
|
||||
|
||||
void G4GeneralParticleSourceData::SetVerbosityAllSources(G4int vl )
|
||||
void G4GeneralParticleSourceData::SetVerbosityAllSources(G4int vl)
|
||||
{
|
||||
for ( std::vector<G4SingleParticleSource*>::iterator it = sourceVector.begin();
|
||||
it != sourceVector.end() ; ++it ) {
|
||||
(*it)->SetVerbosity(vl);
|
||||
|
||||
}
|
||||
|
||||
for ( auto it = sourceVector.cbegin(); it != sourceVector.cend(); ++it )
|
||||
{
|
||||
(*it)->SetVerbosity(vl);
|
||||
}
|
||||
}
|
||||
|
||||
G4SingleParticleSource* G4GeneralParticleSourceData::GetCurrentSource(G4int idx)
|
||||
{
|
||||
currentSource = sourceVector[idx];
|
||||
currentSourceIdx = idx;
|
||||
return sourceVector[idx];
|
||||
currentSource = sourceVector[idx];
|
||||
currentSourceIdx = idx;
|
||||
return sourceVector[idx];
|
||||
}
|
||||
|
||||
void G4GeneralParticleSourceData::Lock()
|
||||
{
|
||||
G4MUTEXLOCK(&mutex);
|
||||
G4MUTEXLOCK(&mutex);
|
||||
}
|
||||
|
||||
void G4GeneralParticleSourceData::Unlock()
|
||||
{
|
||||
G4MUTEXUNLOCK(&mutex);
|
||||
G4MUTEXUNLOCK(&mutex);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -23,9 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4HEPEvtInterface class implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
// Author: Makoto Asai, 1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4HEPEvtInterface.hh"
|
||||
@@ -40,49 +40,55 @@
|
||||
#include "G4Event.hh"
|
||||
|
||||
G4HEPEvtInterface::G4HEPEvtInterface(const char* evfile, G4int vl)
|
||||
:vLevel(vl)
|
||||
: vLevel(vl)
|
||||
{
|
||||
inputFile.open((char*)evfile);
|
||||
if (inputFile.is_open()) {
|
||||
if (inputFile.is_open())
|
||||
{
|
||||
fileName = evfile;
|
||||
if(vl>0) G4cout << "G4HEPEvtInterface - " << fileName << " is open." << G4endl;
|
||||
if(vl>0)
|
||||
G4cout << "G4HEPEvtInterface - " << fileName << " is open." << G4endl;
|
||||
}
|
||||
else {
|
||||
G4Exception("G4HEPEvtInterface::G4HEPEvtInterface","Event0201",FatalException,
|
||||
"G4HEPEvtInterface:: cannot open file.");
|
||||
else
|
||||
{
|
||||
G4Exception("G4HEPEvtInterface::G4HEPEvtInterface","Event0201",
|
||||
FatalException, "G4HEPEvtInterface:: cannot open file.");
|
||||
}
|
||||
G4ThreeVector zero;
|
||||
particle_position = zero;
|
||||
particle_time = 0.0;
|
||||
|
||||
}
|
||||
|
||||
G4HEPEvtInterface::~G4HEPEvtInterface()
|
||||
{;}
|
||||
{
|
||||
}
|
||||
|
||||
void G4HEPEvtInterface::GeneratePrimaryVertex(G4Event* evt)
|
||||
{
|
||||
G4int NHEP = 0; // number of entries
|
||||
if (inputFile.is_open()) {
|
||||
if (inputFile.is_open())
|
||||
{
|
||||
inputFile >> NHEP;
|
||||
}
|
||||
else {
|
||||
G4Exception("G4HEPEvtInterface::G4HEPEvtInterface","Event0201",FatalException,
|
||||
"G4HEPEvtInterface:: cannot open file.");
|
||||
else
|
||||
{
|
||||
G4Exception("G4HEPEvtInterface::G4HEPEvtInterface","Event0201",
|
||||
FatalException, "G4HEPEvtInterface:: cannot open file.");
|
||||
}
|
||||
if( inputFile.eof() )
|
||||
{
|
||||
G4Exception("G4HEPEvtInterface::GeneratePrimaryVertex","Event0202",
|
||||
RunMustBeAborted,"End-Of-File : HEPEvt input file -- no more event to read!");
|
||||
G4Exception("G4HEPEvtInterface::GeneratePrimaryVertex", "Event0202",
|
||||
RunMustBeAborted,
|
||||
"End-Of-File: HEPEvt input file -- no more event to read!");
|
||||
return;
|
||||
}
|
||||
|
||||
if(vLevel > 0)
|
||||
{
|
||||
G4cout << "G4HEPEvtInterface - reading " << NHEP << " HEPEvt particles from "
|
||||
<< fileName << "." << G4endl;
|
||||
G4cout << "G4HEPEvtInterface - reading " << NHEP
|
||||
<< " HEPEvt particles from " << fileName << "." << G4endl;
|
||||
}
|
||||
for( G4int IHEP=0; IHEP<NHEP; IHEP++ )
|
||||
for( G4int IHEP=0; IHEP<NHEP; ++IHEP )
|
||||
{
|
||||
G4int ISTHEP; // status code
|
||||
G4int IDHEP; // PDG code
|
||||
@@ -94,46 +100,50 @@ void G4HEPEvtInterface::GeneratePrimaryVertex(G4Event* evt)
|
||||
G4double PHEP5; // mass in GeV
|
||||
|
||||
inputFile >> ISTHEP >> IDHEP >> JDAHEP1 >> JDAHEP2
|
||||
>> PHEP1 >> PHEP2 >> PHEP3 >> PHEP5;
|
||||
>> PHEP1 >> PHEP2 >> PHEP3 >> PHEP5;
|
||||
if( inputFile.eof() )
|
||||
{
|
||||
G4Exception("G4HEPEvtInterface::GeneratePrimaryVertex","Event0203",
|
||||
FatalException,"Unexpected End-Of-File in the middle of an event");
|
||||
G4Exception("G4HEPEvtInterface::GeneratePrimaryVertex", "Event0203",
|
||||
FatalException,
|
||||
"Unexpected End-Of-File in the middle of an event");
|
||||
}
|
||||
if(vLevel > 1)
|
||||
{
|
||||
G4cout << " " << ISTHEP << " " << IDHEP << " " << JDAHEP1 << " " << JDAHEP2
|
||||
<< " " << PHEP1 << " " << PHEP2 << " " << PHEP3 << " " << PHEP5
|
||||
<< G4endl;
|
||||
G4cout << " " << ISTHEP << " " << IDHEP << " " << JDAHEP1
|
||||
<< " " << JDAHEP2 << " " << PHEP1 << " " << PHEP2
|
||||
<< " " << PHEP3 << " " << PHEP5 << G4endl;
|
||||
}
|
||||
|
||||
// create G4PrimaryParticle object
|
||||
G4PrimaryParticle* particle
|
||||
= new G4PrimaryParticle( IDHEP );
|
||||
// Create G4PrimaryParticle object
|
||||
//
|
||||
G4PrimaryParticle* particle = new G4PrimaryParticle( IDHEP );
|
||||
particle->SetMass( PHEP5*GeV );
|
||||
particle->SetMomentum(PHEP1*GeV, PHEP2*GeV, PHEP3*GeV );
|
||||
|
||||
// create G4HEPEvtParticle object
|
||||
// Create G4HEPEvtParticle object
|
||||
//
|
||||
G4HEPEvtParticle* hepParticle
|
||||
= new G4HEPEvtParticle( particle, ISTHEP, JDAHEP1, JDAHEP2 );
|
||||
|
||||
// Store
|
||||
//
|
||||
HPlist.push_back( hepParticle );
|
||||
}
|
||||
|
||||
// check if there is at least one particle
|
||||
// Check if there is at least one particle
|
||||
//
|
||||
if( HPlist.size() == 0 ) return;
|
||||
|
||||
// make connection between daughter particles decayed from
|
||||
// the same mother
|
||||
for( size_t i=0; i<HPlist.size(); i++ )
|
||||
// Make connection between daughter particles decayed from the same mother
|
||||
//
|
||||
for( std::size_t i=0; i<HPlist.size(); ++i )
|
||||
{
|
||||
if( HPlist[i]->GetJDAHEP1() > 0 ) // it has daughters
|
||||
{
|
||||
G4int jda1 = HPlist[i]->GetJDAHEP1()-1; // FORTRAN index starts from 1
|
||||
G4int jda2 = HPlist[i]->GetJDAHEP2()-1; // but C++ starts from 0.
|
||||
G4PrimaryParticle* mother = HPlist[i]->GetTheParticle();
|
||||
for( G4int j=jda1; j<=jda2; j++ )
|
||||
for( G4int j=jda1; j<=jda2; ++j )
|
||||
{
|
||||
G4PrimaryParticle* daughter = HPlist[j]->GetTheParticle();
|
||||
if(HPlist[j]->GetISTHEP()>0)
|
||||
@@ -145,27 +155,31 @@ void G4HEPEvtInterface::GeneratePrimaryVertex(G4Event* evt)
|
||||
}
|
||||
}
|
||||
|
||||
// create G4PrimaryVertex object
|
||||
// Create G4PrimaryVertex object
|
||||
//
|
||||
G4PrimaryVertex* vertex = new G4PrimaryVertex(particle_position,particle_time);
|
||||
|
||||
// put initial particles to the vertex
|
||||
for( size_t ii=0; ii<HPlist.size(); ii++ )
|
||||
// Put initial particles to the vertex
|
||||
//
|
||||
for( std::size_t ii=0; ii<HPlist.size(); ++ii )
|
||||
{
|
||||
if( HPlist[ii]->GetISTHEP() > 0 ) // ISTHEP of daughters had been
|
||||
// set to negative
|
||||
// set to negative
|
||||
{
|
||||
G4PrimaryParticle* initialParticle = HPlist[ii]->GetTheParticle();
|
||||
vertex->SetPrimary( initialParticle );
|
||||
}
|
||||
}
|
||||
|
||||
// clear G4HEPEvtParticles
|
||||
//HPlist.clearAndDestroy();
|
||||
for(size_t iii=0;iii<HPlist.size();iii++)
|
||||
{ delete HPlist[iii]; }
|
||||
// Clear G4HEPEvtParticles
|
||||
//
|
||||
for(std::size_t iii=0; iii<HPlist.size(); ++iii)
|
||||
{
|
||||
delete HPlist[iii];
|
||||
}
|
||||
HPlist.clear();
|
||||
|
||||
// Put the vertex to G4Event object
|
||||
//
|
||||
evt->AddPrimaryVertex( vertex );
|
||||
}
|
||||
|
||||
|
||||
@@ -23,25 +23,26 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4HEPEvtParticle class implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
// Author: Makoto Asai, 1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4HEPEvtParticle.hh"
|
||||
|
||||
G4Allocator<G4HEPEvtParticle>*& aHEPEvtParticleAllocator()
|
||||
{
|
||||
G4ThreadLocalStatic G4Allocator<G4HEPEvtParticle>* _instance = nullptr;
|
||||
return _instance;
|
||||
G4ThreadLocalStatic G4Allocator<G4HEPEvtParticle>* _instance = nullptr;
|
||||
return _instance;
|
||||
}
|
||||
|
||||
G4HEPEvtParticle::G4HEPEvtParticle()
|
||||
: theParticle(0), ISTHEP(1), JDAHEP1(1), JDAHEP2(1)
|
||||
{
|
||||
}
|
||||
|
||||
G4HEPEvtParticle::G4HEPEvtParticle(G4PrimaryParticle* pp,
|
||||
G4int isthep, G4int jdahep1, G4int jdahep2)
|
||||
G4HEPEvtParticle::
|
||||
G4HEPEvtParticle(G4PrimaryParticle* pp,
|
||||
G4int isthep, G4int jdahep1, G4int jdahep2)
|
||||
: theParticle(pp),ISTHEP(isthep),JDAHEP1(jdahep1),JDAHEP2(jdahep2)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -23,17 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4MultiEventAction class implementation
|
||||
//
|
||||
//
|
||||
//---------------------------------------------------------------
|
||||
//
|
||||
// G4MultiEventAction.cc
|
||||
//
|
||||
// Created on: Jan 17, 2016
|
||||
// Author: adotti
|
||||
//
|
||||
// ---------------------------------------------------------------
|
||||
//
|
||||
// Author: Andrea Dotti, SLAC - 17.01.2016
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4MultiEventAction.hh"
|
||||
#include <algorithm>
|
||||
@@ -58,4 +51,3 @@ void G4MultiEventAction::EndOfEventAction(const G4Event* evt)
|
||||
[evt](G4UserEventActionUPtr& e) { e->EndOfEventAction(evt); }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,11 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ParticleGun class implementation
|
||||
//
|
||||
//
|
||||
// Author: Makoto Asai, 1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// G4ParticleGun
|
||||
#include "G4ParticleGun.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
#include "G4PrimaryParticle.hh"
|
||||
@@ -45,8 +46,8 @@ G4ParticleGun::G4ParticleGun(G4int numberofparticles)
|
||||
NumberOfParticlesToBeGenerated = numberofparticles;
|
||||
}
|
||||
|
||||
G4ParticleGun::G4ParticleGun
|
||||
(G4ParticleDefinition * particleDef, G4int numberofparticles)
|
||||
G4ParticleGun::G4ParticleGun(G4ParticleDefinition* particleDef,
|
||||
G4int numberofparticles)
|
||||
{
|
||||
SetInitialValues();
|
||||
NumberOfParticlesToBeGenerated = numberofparticles;
|
||||
@@ -73,48 +74,25 @@ G4ParticleGun::~G4ParticleGun()
|
||||
delete theMessenger;
|
||||
}
|
||||
|
||||
//G4ParticleGun::G4ParticleGun(const G4ParticleGun& /*right*/)
|
||||
//:G4VPrimaryGenerator()
|
||||
//{ G4Exception(
|
||||
// "G4ParticleGun::G4ParticleGun","Event0191",FatalException,
|
||||
// "G4ParticleGun : Copy constructor should not be used."); }
|
||||
//
|
||||
//const G4ParticleGun& G4ParticleGun::operator=(const G4ParticleGun& right)
|
||||
//{ G4Exception(
|
||||
// "G4ParticleGun::operator=","Event0192",FatalException,
|
||||
// "G4ParticleGun : Equal operator should not be used.");
|
||||
// return right; }
|
||||
//
|
||||
//G4bool G4ParticleGun::operator==(const G4ParticleGun& /*right*/) const
|
||||
//{ G4Exception(
|
||||
// "G4ParticleGun::operator==","Event0193",FatalException,
|
||||
// "G4ParticleGun : == operator should not be used.");
|
||||
// return true; }
|
||||
//
|
||||
//G4bool G4ParticleGun::operator!=(const G4ParticleGun& /*right*/) const
|
||||
//{ G4Exception(
|
||||
// "G4ParticleGun::operator!=","Event0193",FatalException,
|
||||
// "G4ParticleGun : != operator should not be used.");
|
||||
// return false; }
|
||||
|
||||
void G4ParticleGun::SetParticleDefinition
|
||||
(G4ParticleDefinition * aParticleDefinition)
|
||||
void G4ParticleGun::
|
||||
SetParticleDefinition(G4ParticleDefinition* aParticleDefinition)
|
||||
{
|
||||
if(!aParticleDefinition)
|
||||
if(aParticleDefinition == nullptr)
|
||||
{
|
||||
G4Exception("G4ParticleGun::SetParticleDefinition()","Event0101",
|
||||
FatalException,"Null pointer is given.");
|
||||
G4Exception("G4ParticleGun::SetParticleDefinition()", "Event0101",
|
||||
FatalException, "Null pointer is given.");
|
||||
}
|
||||
if(aParticleDefinition->IsShortLived())
|
||||
{
|
||||
if(!(aParticleDefinition->GetDecayTable()))
|
||||
if(aParticleDefinition->GetDecayTable() == nullptr)
|
||||
{
|
||||
G4ExceptionDescription ED;
|
||||
ED << "G4ParticleGun does not support shooting a short-lived particle without a valid decay table." << G4endl;
|
||||
ED << "G4ParticleGun does not support shooting a short-lived "
|
||||
<< "particle without a valid decay table." << G4endl;
|
||||
ED << "G4ParticleGun::SetParticleDefinition for "
|
||||
<< aParticleDefinition->GetParticleName() << " is ignored." << G4endl;
|
||||
G4Exception("G4ParticleGun::SetParticleDefinition()","Event0102",
|
||||
JustWarning,ED);
|
||||
G4Exception("G4ParticleGun::SetParticleDefinition()", "Event0102",
|
||||
JustWarning, ED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -122,20 +100,24 @@ void G4ParticleGun::SetParticleDefinition
|
||||
particle_charge = particle_definition->GetPDGCharge();
|
||||
if(particle_momentum>0.0)
|
||||
{
|
||||
G4double mass = particle_definition->GetPDGMass();
|
||||
G4double mass = particle_definition->GetPDGMass();
|
||||
particle_energy =
|
||||
std::sqrt(particle_momentum*particle_momentum+mass*mass)-mass;
|
||||
std::sqrt(particle_momentum*particle_momentum+mass*mass)-mass;
|
||||
}
|
||||
}
|
||||
|
||||
void G4ParticleGun::SetParticleEnergy(G4double aKineticEnergy)
|
||||
{
|
||||
particle_energy = aKineticEnergy;
|
||||
if(particle_momentum>0.0){
|
||||
if(particle_definition){
|
||||
if(particle_momentum>0.0)
|
||||
{
|
||||
if(particle_definition != nullptr)
|
||||
{
|
||||
G4cout << "G4ParticleGun::" << particle_definition->GetParticleName()
|
||||
<< G4endl;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "G4ParticleGun::" << " " << G4endl;
|
||||
}
|
||||
G4cout << " was defined in terms of Momentum: "
|
||||
@@ -148,11 +130,15 @@ void G4ParticleGun::SetParticleEnergy(G4double aKineticEnergy)
|
||||
|
||||
void G4ParticleGun::SetParticleMomentum(G4double aMomentum)
|
||||
{
|
||||
if(particle_energy>0.0){
|
||||
if(particle_definition){
|
||||
if(particle_energy>0.0)
|
||||
{
|
||||
if(particle_definition != nullptr)
|
||||
{
|
||||
G4cout << "G4ParticleGun::" << particle_definition->GetParticleName()
|
||||
<< G4endl;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "G4ParticleGun::" << " " << G4endl;
|
||||
}
|
||||
G4cout << " was defined in terms of KineticEnergy: "
|
||||
@@ -160,29 +146,34 @@ void G4ParticleGun::SetParticleMomentum(G4double aMomentum)
|
||||
G4cout << " is now defined in terms Momentum: "
|
||||
<< aMomentum/GeV << "GeV/c" << G4endl;
|
||||
}
|
||||
if(!particle_definition)
|
||||
if(particle_definition == nullptr)
|
||||
{
|
||||
G4cout <<"Particle Definition not defined yet for G4ParticleGun"<< G4endl;
|
||||
G4cout <<"Zero Mass is assumed"<<G4endl;
|
||||
G4cout << "Particle Definition not defined yet for G4ParticleGun"
|
||||
<< G4endl;
|
||||
G4cout << "Zero Mass is assumed" << G4endl;
|
||||
particle_momentum = aMomentum;
|
||||
particle_energy = aMomentum;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4double mass = particle_definition->GetPDGMass();
|
||||
G4double mass = particle_definition->GetPDGMass();
|
||||
particle_momentum = aMomentum;
|
||||
particle_energy =
|
||||
std::sqrt(particle_momentum*particle_momentum+mass*mass)-mass;
|
||||
std::sqrt(particle_momentum*particle_momentum+mass*mass)-mass;
|
||||
}
|
||||
}
|
||||
|
||||
void G4ParticleGun::SetParticleMomentum(G4ParticleMomentum aMomentum)
|
||||
{
|
||||
if(particle_energy>0.0){
|
||||
if(particle_definition){
|
||||
if(particle_energy>0.0)
|
||||
{
|
||||
if(particle_definition != nullptr)
|
||||
{
|
||||
G4cout << "G4ParticleGun::" << particle_definition->GetParticleName()
|
||||
<< G4endl;
|
||||
}else{
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "G4ParticleGun::" << " " << G4endl;
|
||||
}
|
||||
G4cout << " was defined in terms of KineticEnergy: "
|
||||
@@ -190,11 +181,12 @@ void G4ParticleGun::SetParticleMomentum(G4ParticleMomentum aMomentum)
|
||||
G4cout << " is now defined in terms Momentum: "
|
||||
<< aMomentum.mag()/GeV << "GeV/c" << G4endl;
|
||||
}
|
||||
if(!particle_definition)
|
||||
if(particle_definition == nullptr)
|
||||
{
|
||||
G4cout <<"Particle Definition not defined yet for G4ParticleGun"<< G4endl;
|
||||
G4cout <<"Zero Mass is assumed"<<G4endl;
|
||||
particle_momentum_direction = aMomentum.unit();
|
||||
G4cout << "Particle Definition not defined yet for G4ParticleGun"
|
||||
<< G4endl;
|
||||
G4cout << "Zero Mass is assumed" << G4endl;
|
||||
particle_momentum_direction = aMomentum.unit();
|
||||
particle_momentum = aMomentum.mag();
|
||||
particle_energy = aMomentum.mag();
|
||||
}
|
||||
@@ -202,31 +194,35 @@ void G4ParticleGun::SetParticleMomentum(G4ParticleMomentum aMomentum)
|
||||
{
|
||||
G4double mass = particle_definition->GetPDGMass();
|
||||
particle_momentum = aMomentum.mag();
|
||||
particle_momentum_direction = aMomentum.unit();
|
||||
particle_momentum_direction = aMomentum.unit();
|
||||
particle_energy =
|
||||
std::sqrt(particle_momentum*particle_momentum+mass*mass)-mass;
|
||||
std::sqrt(particle_momentum*particle_momentum+mass*mass)-mass;
|
||||
}
|
||||
}
|
||||
|
||||
void G4ParticleGun::GeneratePrimaryVertex(G4Event* evt)
|
||||
{
|
||||
if(!particle_definition)
|
||||
if(particle_definition == nullptr)
|
||||
{
|
||||
G4ExceptionDescription ED;
|
||||
ED << "Particle definition is not defined." << G4endl;
|
||||
ED << "G4ParticleGun::SetParticleDefinition() has to be invoked beforehand." << G4endl;
|
||||
G4Exception("G4ParticleGun::GeneratePrimaryVertex()","Event0109",
|
||||
FatalException, ED);
|
||||
ED << "G4ParticleGun::SetParticleDefinition() has to be invoked beforehand."
|
||||
<< G4endl;
|
||||
G4Exception("G4ParticleGun::GeneratePrimaryVertex()", "Event0109",
|
||||
FatalException, ED);
|
||||
return;
|
||||
}
|
||||
|
||||
// create a new vertex
|
||||
// Create a new vertex
|
||||
//
|
||||
G4PrimaryVertex* vertex =
|
||||
new G4PrimaryVertex(particle_position,particle_time);
|
||||
|
||||
// create new primaries and set them to the vertex
|
||||
// Create new primaries and set them to the vertex
|
||||
//
|
||||
G4double mass = particle_definition->GetPDGMass();
|
||||
for( G4int i=0; i<NumberOfParticlesToBeGenerated; i++ ){
|
||||
for( G4int i=0; i<NumberOfParticlesToBeGenerated; ++i )
|
||||
{
|
||||
G4PrimaryParticle* particle =
|
||||
new G4PrimaryParticle(particle_definition);
|
||||
particle->SetKineticEnergy( particle_energy );
|
||||
@@ -234,12 +230,9 @@ void G4ParticleGun::GeneratePrimaryVertex(G4Event* evt)
|
||||
particle->SetMomentumDirection( particle_momentum_direction );
|
||||
particle->SetCharge( particle_charge );
|
||||
particle->SetPolarization(particle_polarization.x(),
|
||||
particle_polarization.y(),
|
||||
particle_polarization.z());
|
||||
particle_polarization.y(),
|
||||
particle_polarization.z());
|
||||
vertex->SetPrimary( particle );
|
||||
}
|
||||
|
||||
evt->AddPrimaryVertex( vertex );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4ParticleGunMessenger class implementation
|
||||
//
|
||||
//
|
||||
// Author: Makoto Asai, 1997
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4ParticleGunMessenger.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
@@ -42,11 +44,10 @@
|
||||
#include "G4UIcmdWithAnInteger.hh"
|
||||
#include "G4ios.hh"
|
||||
#include "G4Tokenizer.hh"
|
||||
#include "G4IonTable.hh"
|
||||
|
||||
G4ParticleGunMessenger::G4ParticleGunMessenger(G4ParticleGun * fPtclGun)
|
||||
:fParticleGun(fPtclGun),fShootIon(false),
|
||||
fAtomicNumber(0),fAtomicMass(0),fIonCharge(0),fIonExciteEnergy(0.0),
|
||||
fIonFloatingLevelBase('\0'),fIonEnergyLevel(0)
|
||||
G4ParticleGunMessenger::G4ParticleGunMessenger(G4ParticleGun* fPtclGun)
|
||||
: fParticleGun(fPtclGun)
|
||||
{
|
||||
particleTable = G4ParticleTable::GetParticleTable();
|
||||
|
||||
@@ -69,7 +70,7 @@ G4ParticleGunMessenger::G4ParticleGunMessenger(G4ParticleGun * fPtclGun)
|
||||
while( (*itr)() )
|
||||
{
|
||||
G4ParticleDefinition* pd = itr->value();
|
||||
if( !(pd->IsShortLived()) || pd->GetDecayTable() )
|
||||
if( !(pd->IsShortLived()) || pd->GetDecayTable() != nullptr )
|
||||
{
|
||||
candidateList += pd->GetParticleName();
|
||||
candidateList += " ";
|
||||
@@ -80,7 +81,7 @@ G4ParticleGunMessenger::G4ParticleGunMessenger(G4ParticleGun * fPtclGun)
|
||||
|
||||
directionCmd = new G4UIcmdWith3Vector("/gun/direction",this);
|
||||
directionCmd->SetGuidance("Set momentum direction.");
|
||||
directionCmd->SetGuidance("Direction needs not to be a unit vector.");
|
||||
directionCmd->SetGuidance(" Direction needs not to be a unit vector.");
|
||||
directionCmd->SetParameterName("ex","ey","ez",true,true);
|
||||
directionCmd->SetRange("ex != 0 || ey != 0 || ez != 0");
|
||||
|
||||
@@ -92,15 +93,16 @@ G4ParticleGunMessenger::G4ParticleGunMessenger(G4ParticleGun * fPtclGun)
|
||||
//energyCmd->SetUnitCandidates("eV keV MeV GeV TeV");
|
||||
|
||||
momCmd = new G4UIcmdWith3VectorAndUnit("/gun/momentum",this);
|
||||
momCmd->SetGuidance("Set momentum. This command is equivalent to two commands /gun/direction and /gun/momentumAmp");
|
||||
momCmd->SetGuidance("Set momentum. This command is equivalent to two commands");
|
||||
momCmd->SetGuidance(" /gun/direction and /gun/momentumAmp");
|
||||
momCmd->SetParameterName("px","py","pz",true,true);
|
||||
momCmd->SetRange("px != 0 || py != 0 || pz != 0");
|
||||
momCmd->SetDefaultUnit("GeV");
|
||||
|
||||
momAmpCmd = new G4UIcmdWithADoubleAndUnit("/gun/momentumAmp",this);
|
||||
momAmpCmd->SetGuidance("Set absolute value of momentum.");
|
||||
momAmpCmd->SetGuidance("Direction should be set by /gun/direction command.");
|
||||
momAmpCmd->SetGuidance("This command should be used alternatively with /gun/energy.");
|
||||
momAmpCmd->SetGuidance(" Direction should be set by /gun/direction command.");
|
||||
momAmpCmd->SetGuidance(" This command should be used alternatively with /gun/energy.");
|
||||
momAmpCmd->SetParameterName("Momentum",true,true);
|
||||
momAmpCmd->SetDefaultUnit("GeV");
|
||||
|
||||
@@ -108,15 +110,15 @@ G4ParticleGunMessenger::G4ParticleGunMessenger(G4ParticleGun * fPtclGun)
|
||||
positionCmd->SetGuidance("Set starting position of the particle.");
|
||||
positionCmd->SetParameterName("X","Y","Z",true,true);
|
||||
positionCmd->SetDefaultUnit("cm");
|
||||
//positionCmd->SetUnitCategory("Length");
|
||||
//positionCmd->SetUnitCandidates("microm mm cm m km");
|
||||
// positionCmd->SetUnitCategory("Length");
|
||||
// positionCmd->SetUnitCandidates("microm mm cm m km");
|
||||
|
||||
timeCmd = new G4UIcmdWithADoubleAndUnit("/gun/time",this);
|
||||
timeCmd->SetGuidance("Set initial time of the particle.");
|
||||
timeCmd->SetParameterName("t0",true,true);
|
||||
timeCmd->SetDefaultUnit("ns");
|
||||
//timeCmd->SetUnitCategory("Time");
|
||||
//timeCmd->SetUnitCandidates("ns ms s");
|
||||
// timeCmd->SetUnitCategory("Time");
|
||||
// timeCmd->SetUnitCandidates("ns ms s");
|
||||
|
||||
polCmd = new G4UIcmdWith3Vector("/gun/polarization",this);
|
||||
polCmd->SetGuidance("Set polarization.");
|
||||
@@ -154,10 +156,10 @@ G4ParticleGunMessenger::G4ParticleGunMessenger(G4ParticleGun * fPtclGun)
|
||||
ionCmd->SetParameter(param);
|
||||
|
||||
ionLvlCmd = new G4UIcommand("/gun/ionL",this);
|
||||
ionLvlCmd->SetGuidance("THIS COMMAND IS DEPRECATED and will be removed in release 10.5.");
|
||||
ionLvlCmd->SetGuidance("Use /gun/ion instead.");
|
||||
ionLvlCmd->SetGuidance("Set properties of ion to be generated.");
|
||||
ionLvlCmd->SetGuidance("[usage] /gun/ionL Z A [Q I]");
|
||||
ionLvlCmd->SetGuidance("THIS COMMAND IS DEPRECATED and will be removed in future releases.");
|
||||
ionLvlCmd->SetGuidance(" Use /gun/ion instead.");
|
||||
ionLvlCmd->SetGuidance(" Set properties of ion to be generated.");
|
||||
ionLvlCmd->SetGuidance(" [usage] /gun/ionL Z A [Q I]");
|
||||
ionLvlCmd->SetGuidance(" Z:(int) AtomicNumber");
|
||||
ionLvlCmd->SetGuidance(" A:(int) AtomicMass");
|
||||
ionLvlCmd->SetGuidance(" Q:(int) Charge of Ion (in unit of e)");
|
||||
@@ -175,7 +177,8 @@ G4ParticleGunMessenger::G4ParticleGunMessenger(G4ParticleGun * fPtclGun)
|
||||
paraml->SetDefaultValue("0");
|
||||
ionLvlCmd->SetParameter(paraml);
|
||||
|
||||
// set initial value to G4ParticleGun
|
||||
// Set initial value to G4ParticleGun
|
||||
//
|
||||
fParticleGun->SetParticleDefinition( G4Geantino::Geantino() );
|
||||
fParticleGun->SetParticleMomentumDirection( G4ThreeVector(1.0,0.0,0.0) );
|
||||
fParticleGun->SetParticleEnergy( 1.0*GeV );
|
||||
@@ -200,20 +203,30 @@ G4ParticleGunMessenger::~G4ParticleGunMessenger()
|
||||
delete gunDirectory;
|
||||
}
|
||||
|
||||
void G4ParticleGunMessenger::SetNewValue(G4UIcommand * command,G4String newValues)
|
||||
void G4ParticleGunMessenger::
|
||||
SetNewValue(G4UIcommand* command, G4String newValues)
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
if (command==listCmd) {
|
||||
if (command==listCmd)
|
||||
{
|
||||
particleTable->DumpTable();
|
||||
} else if (command==particleCmd) {
|
||||
if (newValues =="ion") {
|
||||
}
|
||||
else if (command==particleCmd)
|
||||
{
|
||||
if (newValues =="ion")
|
||||
{
|
||||
fShootIon = true;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fShootIon = false;
|
||||
G4ParticleDefinition* pd = particleTable->FindParticle(newValues);
|
||||
if(pd != 0) {
|
||||
if(pd != nullptr)
|
||||
{
|
||||
fParticleGun->SetParticleDefinition( pd );
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ed << "Particle [" << newValues << "] is not found.";
|
||||
command->CommandFailed(ed);
|
||||
}
|
||||
@@ -237,9 +250,12 @@ void G4ParticleGunMessenger::SetNewValue(G4UIcommand * command,G4String newValue
|
||||
{ fParticleGun->SetNumberOfParticles(numberCmd->GetNewIntValue(newValues)); }
|
||||
else if( command==ionCmd )
|
||||
{
|
||||
if (fShootIon) {
|
||||
if (fShootIon)
|
||||
{
|
||||
IonCommand(newValues);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ed << "Set /gun/particle to ion before using /gun/ion command";
|
||||
command->CommandFailed(ed);
|
||||
}
|
||||
@@ -247,20 +263,24 @@ void G4ParticleGunMessenger::SetNewValue(G4UIcommand * command,G4String newValue
|
||||
else if( command==ionLvlCmd )
|
||||
{
|
||||
G4ExceptionDescription depWarn;
|
||||
depWarn << "\nCommand /gun/ionL is deprecated and will be removed in release 10.5.\n"
|
||||
depWarn << "\nCommand /gun/ionL is deprecated and will be removed in future releases.\n"
|
||||
<< "Use /gun/ion instead.\n";
|
||||
G4Exception("G4ParticleGunMessenger::SetNewValue","IonLWarn",JustWarning,depWarn);
|
||||
G4Exception("G4ParticleGunMessenger::SetNewValue", "IonLWarn",
|
||||
JustWarning, depWarn);
|
||||
|
||||
if (fShootIon) {
|
||||
if (fShootIon)
|
||||
{
|
||||
IonLevelCommand(newValues);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
ed << "Set /gun/particle to ion before using /gun/ion command";
|
||||
command->CommandFailed(ed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
G4String G4ParticleGunMessenger::GetCurrentValue(G4UIcommand * command)
|
||||
G4String G4ParticleGunMessenger::GetCurrentValue(G4UIcommand* command)
|
||||
{
|
||||
G4String cv;
|
||||
|
||||
@@ -280,7 +300,10 @@ G4String G4ParticleGunMessenger::GetCurrentValue(G4UIcommand * command)
|
||||
{
|
||||
G4double mom = fParticleGun->GetParticleMomentum();
|
||||
if(mom == 0.)
|
||||
{ G4cerr << " G4ParticleGun: was defined in terms of kinetic energy." << G4endl; }
|
||||
{
|
||||
G4cerr << " G4ParticleGun: was defined in terms of kinetic energy."
|
||||
<< G4endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( command==momCmd )
|
||||
@@ -299,53 +322,67 @@ G4String G4ParticleGunMessenger::GetCurrentValue(G4UIcommand * command)
|
||||
{ cv = numberCmd->ConvertToString(fParticleGun->GetNumberOfParticles()); }
|
||||
else if( command==ionCmd )
|
||||
{
|
||||
if (fShootIon) {
|
||||
if (fShootIon)
|
||||
{
|
||||
cv = ItoS(fAtomicNumber) + " " + ItoS(fAtomicMass) + " ";
|
||||
cv += ItoS(fIonCharge);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
cv = "";
|
||||
}
|
||||
}
|
||||
return cv;
|
||||
}
|
||||
|
||||
#include "G4IonTable.hh"
|
||||
|
||||
void G4ParticleGunMessenger::IonLevelCommand(G4String newValues)
|
||||
void G4ParticleGunMessenger::IonLevelCommand(const G4String& newValues)
|
||||
{
|
||||
G4Tokenizer next( newValues );
|
||||
// check argument
|
||||
|
||||
// Check argument
|
||||
//
|
||||
fAtomicNumber = StoI(next());
|
||||
fAtomicMass = StoI(next());
|
||||
G4String sQ = next();
|
||||
if (sQ.isNull() || StoI(sQ)<0) {
|
||||
if (sQ.isNull() || StoI(sQ)<0)
|
||||
{
|
||||
fIonCharge = fAtomicNumber;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fIonCharge = StoI(sQ);
|
||||
}
|
||||
sQ = next();
|
||||
if (sQ.isNull()) {
|
||||
if (sQ.isNull())
|
||||
{
|
||||
fIonEnergyLevel = 0;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fIonEnergyLevel = StoI(sQ);
|
||||
}
|
||||
G4ParticleDefinition* ion = 0;
|
||||
ion = G4IonTable::GetIonTable()->GetIon(fAtomicNumber,fAtomicMass,fIonEnergyLevel);
|
||||
if (ion == 0) {
|
||||
G4ParticleDefinition* ion = G4IonTable::GetIonTable()
|
||||
->GetIon(fAtomicNumber,fAtomicMass,fIonEnergyLevel);
|
||||
if (ion == nullptr)
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Ion with Z = " << fAtomicNumber << ", A = " << fAtomicMass
|
||||
<< ", I = " << fIonEnergyLevel << " is not defined ";
|
||||
ionLvlCmd->CommandFailed(ed);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fParticleGun->SetParticleDefinition(ion);
|
||||
fParticleGun->SetParticleCharge(fIonCharge*eplus);
|
||||
}
|
||||
}
|
||||
|
||||
void G4ParticleGunMessenger::IonCommand(G4String newValues)
|
||||
void G4ParticleGunMessenger::IonCommand(const G4String& newValues)
|
||||
{
|
||||
G4Tokenizer next( newValues );
|
||||
// check argument
|
||||
|
||||
// Check argument
|
||||
//
|
||||
fAtomicNumber = StoI(next());
|
||||
fAtomicMass = StoI(next());
|
||||
fIonCharge = fAtomicNumber;
|
||||
@@ -366,20 +403,21 @@ void G4ParticleGunMessenger::IonCommand(G4String newValues)
|
||||
if (sQ.isNull()||sQ=="noFloat")
|
||||
{ fIonFloatingLevelBase = '\0'; }
|
||||
else
|
||||
{ fIonFloatingLevelBase = sQ[(size_t)0]; }
|
||||
{ fIonFloatingLevelBase = sQ[(std::size_t)0]; }
|
||||
}
|
||||
}
|
||||
G4ParticleDefinition* ion = 0;
|
||||
ion = G4IonTable::GetIonTable()->GetIon( fAtomicNumber, fAtomicMass,
|
||||
fIonExciteEnergy, fIonFloatingLevelBase);
|
||||
if (ion==0) {
|
||||
G4ParticleDefinition* ion = G4IonTable::GetIonTable()
|
||||
->GetIon(fAtomicNumber,fAtomicMass,fIonExciteEnergy,fIonFloatingLevelBase);
|
||||
if (ion==nullptr)
|
||||
{
|
||||
G4ExceptionDescription ed;
|
||||
ed << "Ion with Z=" << fAtomicNumber;
|
||||
ed << " A=" << fAtomicMass << "is not defined";
|
||||
ionCmd->CommandFailed(ed);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
fParticleGun->SetParticleDefinition(ion);
|
||||
fParticleGun->SetParticleCharge(fIonCharge*eplus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4PrimaryTransformer class implementation
|
||||
//
|
||||
//
|
||||
// Author: Makoto Asai, 1999
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4PrimaryTransformer.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
@@ -40,43 +42,41 @@
|
||||
#include "Randomize.hh"
|
||||
|
||||
G4PrimaryTransformer::G4PrimaryTransformer()
|
||||
:verboseLevel(0),trackID(0),
|
||||
unknown(nullptr),unknownParticleDefined(false),
|
||||
opticalphoton(nullptr),opticalphotonDefined(false),
|
||||
nWarn(0)
|
||||
{
|
||||
particleTable = G4ParticleTable::GetParticleTable();
|
||||
CheckUnknown();
|
||||
}
|
||||
|
||||
G4PrimaryTransformer::~G4PrimaryTransformer()
|
||||
{;}
|
||||
{
|
||||
}
|
||||
|
||||
void G4PrimaryTransformer::CheckUnknown()
|
||||
{
|
||||
unknown = particleTable->FindParticle("unknown");
|
||||
if(unknown)
|
||||
if(unknown != nullptr)
|
||||
{ unknownParticleDefined = true; }
|
||||
else
|
||||
{ unknownParticleDefined = false; }
|
||||
opticalphoton = particleTable->FindParticle("opticalphoton");
|
||||
if(opticalphoton)
|
||||
if(opticalphoton != nullptr)
|
||||
{ opticalphotonDefined = true; }
|
||||
else
|
||||
{ opticalphotonDefined = false; }
|
||||
}
|
||||
|
||||
G4TrackVector* G4PrimaryTransformer::GimmePrimaries(G4Event* anEvent,G4int trackIDCounter)
|
||||
G4TrackVector*
|
||||
G4PrimaryTransformer::GimmePrimaries(G4Event* anEvent, G4int trackIDCounter)
|
||||
{
|
||||
trackID = trackIDCounter;
|
||||
|
||||
//TV.clearAndDestroy();
|
||||
for(auto tr : TV) delete tr;
|
||||
TV.clear();
|
||||
|
||||
//Loop over vertices
|
||||
// Loop over vertices
|
||||
//
|
||||
G4PrimaryVertex* nextVertex = anEvent->GetPrimaryVertex();
|
||||
while(nextVertex) // Loop checking 12.28.2015 M.Asai
|
||||
while(nextVertex != nullptr) // Loop checking 12.28.2015 M.Asai
|
||||
{
|
||||
GenerateTracks(nextVertex);
|
||||
nextVertex = nextVertex->GetNext();
|
||||
@@ -93,9 +93,12 @@ void G4PrimaryTransformer::GenerateTracks(G4PrimaryVertex* primaryVertex)
|
||||
G4double WV = primaryVertex->GetWeight();
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if(verboseLevel>2) {
|
||||
if(verboseLevel>2)
|
||||
{
|
||||
primaryVertex->Print();
|
||||
} else if (verboseLevel==1) {
|
||||
}
|
||||
else if (verboseLevel==1)
|
||||
{
|
||||
G4cout << "G4PrimaryTransformer::PrimaryVertex ("
|
||||
<< X0 / mm << "(mm),"
|
||||
<< Y0 / mm << "(mm),"
|
||||
@@ -105,21 +108,21 @@ void G4PrimaryTransformer::GenerateTracks(G4PrimaryVertex* primaryVertex)
|
||||
#endif
|
||||
|
||||
G4PrimaryParticle* primaryParticle = primaryVertex->GetPrimary();
|
||||
while( primaryParticle != 0 ) // Loop checking 12.28.2015 M.Asai
|
||||
while( primaryParticle != nullptr ) // Loop checking 12.28.2015 M.Asai
|
||||
{
|
||||
GenerateSingleTrack( primaryParticle, X0, Y0, Z0, T0, WV );
|
||||
primaryParticle = primaryParticle->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
void G4PrimaryTransformer::GenerateSingleTrack
|
||||
(G4PrimaryParticle* primaryParticle,
|
||||
G4double x0,G4double y0,G4double z0,G4double t0,G4double wv)
|
||||
void G4PrimaryTransformer::
|
||||
GenerateSingleTrack( G4PrimaryParticle* primaryParticle,
|
||||
G4double x0, G4double y0, G4double z0,
|
||||
G4double t0, G4double wv)
|
||||
{
|
||||
G4ParticleDefinition* partDef = GetDefinition(primaryParticle);
|
||||
if(!IsGoodForTrack(partDef))
|
||||
// The particle cannot be converted to G4Track, check daughters
|
||||
{
|
||||
{ // The particle cannot be converted to G4Track, check daughters
|
||||
#ifdef G4VERBOSE
|
||||
if(verboseLevel>2)
|
||||
{
|
||||
@@ -128,37 +131,39 @@ void G4PrimaryTransformer::GenerateSingleTrack
|
||||
}
|
||||
#endif
|
||||
G4PrimaryParticle* daughter = primaryParticle->GetDaughter();
|
||||
while(daughter) // Loop checking 12.28.2015 M.Asai
|
||||
while(daughter != nullptr) // Loop checking 12.28.2015 M.Asai
|
||||
{
|
||||
GenerateSingleTrack(daughter,x0,y0,z0,t0,wv);
|
||||
daughter = daughter->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
// The particle is defined in GEANT4
|
||||
else
|
||||
else // The particle is defined in GEANT4
|
||||
{
|
||||
// Create G4DynamicParticle object
|
||||
#ifdef G4VERBOSE
|
||||
if(verboseLevel>1)
|
||||
{
|
||||
G4cout << "Primary particle (" << partDef->GetParticleName()
|
||||
<< ") --- Transfered with momentum " << primaryParticle->GetMomentum()
|
||||
<< ") --- Transfered with momentum "
|
||||
<< primaryParticle->GetMomentum()
|
||||
<< G4endl;
|
||||
}
|
||||
#endif
|
||||
G4DynamicParticle* DP =
|
||||
new G4DynamicParticle(partDef,
|
||||
primaryParticle->GetMomentumDirection(),
|
||||
primaryParticle->GetKineticEnergy());
|
||||
if(opticalphotonDefined && partDef==opticalphoton && primaryParticle->GetPolarization().mag2()==0.)
|
||||
primaryParticle->GetMomentumDirection(),
|
||||
primaryParticle->GetKineticEnergy());
|
||||
if(opticalphotonDefined && partDef==opticalphoton
|
||||
&& primaryParticle->GetPolarization().mag2()==0.)
|
||||
{
|
||||
if(nWarn<10)
|
||||
{
|
||||
G4Exception("G4PrimaryTransformer::GenerateSingleTrack","ZeroPolarization",JustWarning,
|
||||
"Polarization of the optical photon is null. Random polarization is assumed.");
|
||||
G4Exception("G4PrimaryTransformer::GenerateSingleTrack",
|
||||
"ZeroPolarization", JustWarning,
|
||||
"Polarization of the optical photon is null.\
|
||||
Random polarization is assumed.");
|
||||
G4cerr << "This warning message is issued up to 10 times." << G4endl;
|
||||
nWarn++;
|
||||
++nWarn;
|
||||
}
|
||||
|
||||
G4double angle = G4UniformRand() * 360.0*deg;
|
||||
@@ -171,7 +176,8 @@ void G4PrimaryTransformer::GenerateSingleTrack
|
||||
if (modul2 > 0.) e_perpend = (1./std::sqrt(modul2))*product;
|
||||
G4ThreeVector e_paralle = e_perpend.cross(kphoton);
|
||||
|
||||
G4ThreeVector polar = std::cos(angle)*e_paralle + std::sin(angle)*e_perpend;
|
||||
G4ThreeVector polar = std::cos(angle)*e_paralle
|
||||
+ std::sin(angle)*e_perpend;
|
||||
DP->SetPolarization(polar.x(),polar.y(),polar.z());
|
||||
}
|
||||
else
|
||||
@@ -181,68 +187,91 @@ void G4PrimaryTransformer::GenerateSingleTrack
|
||||
primaryParticle->GetPolZ());
|
||||
}
|
||||
if(primaryParticle->GetProperTime()>=0.0)
|
||||
{ DP->SetPreAssignedDecayProperTime(primaryParticle->GetProperTime()); }
|
||||
{
|
||||
DP->SetPreAssignedDecayProperTime(primaryParticle->GetProperTime());
|
||||
}
|
||||
|
||||
// Set Mass if it is specified
|
||||
//
|
||||
G4double pmas = primaryParticle->GetMass();
|
||||
if(pmas>=0.)
|
||||
{ DP->SetMass(pmas); }
|
||||
if(pmas>=0.) { DP->SetMass(pmas); }
|
||||
|
||||
// Set Charge if it is specified
|
||||
if (primaryParticle->GetCharge()<DBL_MAX) {
|
||||
if (partDef->GetAtomicNumber() <0) {
|
||||
DP->SetCharge(primaryParticle->GetCharge());
|
||||
} else {
|
||||
// ions
|
||||
G4int iz = partDef->GetAtomicNumber();
|
||||
G4int iq = static_cast<int>(primaryParticle->GetCharge()/eplus);
|
||||
G4int n_e = iz - iq;
|
||||
if (n_e>0) DP->AddElectron(0,n_e);
|
||||
}
|
||||
//
|
||||
if (primaryParticle->GetCharge()<DBL_MAX)
|
||||
{
|
||||
if (partDef->GetAtomicNumber() <0)
|
||||
{
|
||||
DP->SetCharge(primaryParticle->GetCharge());
|
||||
}
|
||||
else // ions
|
||||
{
|
||||
G4int iz = partDef->GetAtomicNumber();
|
||||
G4int iq = static_cast<G4int>(primaryParticle->GetCharge()/eplus);
|
||||
G4int n_e = iz - iq;
|
||||
if (n_e>0) DP->AddElectron(0,n_e);
|
||||
}
|
||||
}
|
||||
// Set decay products to the DynamicParticle
|
||||
//
|
||||
SetDecayProducts( primaryParticle, DP );
|
||||
|
||||
// Set primary particle
|
||||
//
|
||||
DP->SetPrimaryParticle(primaryParticle);
|
||||
|
||||
// Set PDG code if it is different from G4ParticleDefinition
|
||||
//
|
||||
if(partDef->GetPDGEncoding()==0 && primaryParticle->GetPDGcode()!=0)
|
||||
{
|
||||
DP->SetPDGcode(primaryParticle->GetPDGcode());
|
||||
}
|
||||
|
||||
// Check the particle is properly constructed
|
||||
//
|
||||
if(!CheckDynamicParticle(DP))
|
||||
{
|
||||
delete DP;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create G4Track object
|
||||
//
|
||||
G4Track* track = new G4Track(DP,t0,G4ThreeVector(x0,y0,z0));
|
||||
|
||||
// Set trackID and let primary particle know it
|
||||
trackID++;
|
||||
//
|
||||
++trackID;
|
||||
track->SetTrackID(trackID);
|
||||
primaryParticle->SetTrackID(trackID);
|
||||
// Set parentID to 0 as a primary particle
|
||||
track->SetParentID(0);
|
||||
// Set weight ( vertex weight * particle weight )
|
||||
track->SetWeight(wv*(primaryParticle->GetWeight()));
|
||||
// Store it to G4TrackVector
|
||||
TV.push_back( track );
|
||||
|
||||
// Set parentID to 0 as a primary particle
|
||||
//
|
||||
track->SetParentID(0);
|
||||
|
||||
// Set weight ( vertex weight * particle weight )
|
||||
//
|
||||
track->SetWeight(wv*(primaryParticle->GetWeight()));
|
||||
|
||||
// Store it to G4TrackVector
|
||||
//
|
||||
TV.push_back( track );
|
||||
}
|
||||
}
|
||||
|
||||
void G4PrimaryTransformer::SetDecayProducts
|
||||
(G4PrimaryParticle* mother, G4DynamicParticle* motherDP)
|
||||
void G4PrimaryTransformer::
|
||||
SetDecayProducts(G4PrimaryParticle* mother, G4DynamicParticle* motherDP)
|
||||
{
|
||||
G4PrimaryParticle* daughter = mother->GetDaughter();
|
||||
if(!daughter) return;
|
||||
G4DecayProducts* decayProducts = (G4DecayProducts*)(motherDP->GetPreAssignedDecayProducts() );
|
||||
if(!decayProducts)
|
||||
if(daughter == nullptr) return;
|
||||
G4DecayProducts* decayProducts
|
||||
= (G4DecayProducts*)(motherDP->GetPreAssignedDecayProducts() );
|
||||
if(decayProducts == nullptr)
|
||||
{
|
||||
decayProducts = new G4DecayProducts(*motherDP);
|
||||
motherDP->SetPreAssignedDecayProducts(decayProducts);
|
||||
}
|
||||
while(daughter)
|
||||
while(daughter != nullptr)
|
||||
{
|
||||
G4ParticleDefinition* partDef = GetDefinition(daughter);
|
||||
if(!IsGoodForTrack(partDef))
|
||||
@@ -266,23 +295,39 @@ void G4PrimaryTransformer::SetDecayProducts
|
||||
<< G4endl;
|
||||
}
|
||||
#endif
|
||||
G4DynamicParticle*DP
|
||||
G4DynamicParticle* DP
|
||||
= new G4DynamicParticle(partDef,daughter->GetMomentum());
|
||||
DP->SetPrimaryParticle(daughter);
|
||||
|
||||
// Decay proper time for daughter
|
||||
//
|
||||
if(daughter->GetProperTime()>=0.0)
|
||||
{ DP->SetPreAssignedDecayProperTime(daughter->GetProperTime()); }
|
||||
// Set Charge is specified
|
||||
if (daughter->GetCharge()<DBL_MAX) {
|
||||
{
|
||||
DP->SetPreAssignedDecayProperTime(daughter->GetProperTime());
|
||||
}
|
||||
|
||||
// Set Charge and Mass is specified
|
||||
//
|
||||
if (daughter->GetCharge()<DBL_MAX)
|
||||
{
|
||||
DP->SetCharge(daughter->GetCharge());
|
||||
}
|
||||
G4double pmas = daughter->GetMass();
|
||||
if(pmas>=0.)
|
||||
{ DP->SetMass(pmas); }
|
||||
DP->SetPolarization(daughter->GetPolX(),daughter->GetPolY(),daughter->GetPolZ());
|
||||
{
|
||||
DP->SetMass(pmas);
|
||||
}
|
||||
|
||||
// Set Polarization
|
||||
//
|
||||
DP->SetPolarization(daughter->GetPolX(),
|
||||
daughter->GetPolY(),
|
||||
daughter->GetPolZ());
|
||||
decayProducts->PushProducts(DP);
|
||||
SetDecayProducts(daughter,DP);
|
||||
|
||||
// Check the particle is properly constructed
|
||||
//
|
||||
if(!CheckDynamicParticle(DP))
|
||||
{
|
||||
delete DP;
|
||||
@@ -297,43 +342,58 @@ void G4PrimaryTransformer::SetUnknnownParticleDefined(G4bool vl)
|
||||
{
|
||||
unknownParticleDefined = vl;
|
||||
if(unknownParticleDefined && !unknown)
|
||||
{ G4cerr << "unknownParticleDefined cannot be set true because G4UnknownParticle is not defined in the physics list."
|
||||
<< G4endl << "Command ignored." << G4endl;
|
||||
{
|
||||
G4cerr << "unknownParticleDefined cannot be set true because" << G4endl
|
||||
<< "G4UnknownParticle is not defined in the physics list." << G4endl
|
||||
<< "Command ignored." << G4endl;
|
||||
unknownParticleDefined = false;
|
||||
}
|
||||
}
|
||||
|
||||
G4bool G4PrimaryTransformer::CheckDynamicParticle(G4DynamicParticle*DP)
|
||||
G4bool G4PrimaryTransformer::CheckDynamicParticle(G4DynamicParticle* DP)
|
||||
{
|
||||
if(IsGoodForTrack(DP->GetDefinition())) return true;
|
||||
G4DecayProducts* decayProducts = (G4DecayProducts*)(DP->GetPreAssignedDecayProducts());
|
||||
if(decayProducts && decayProducts->entries()>0) return true;
|
||||
G4DecayProducts* decayProducts
|
||||
= (G4DecayProducts*)(DP->GetPreAssignedDecayProducts());
|
||||
if(decayProducts != nullptr && decayProducts->entries()>0) return true;
|
||||
G4cerr << G4endl
|
||||
<< "G4PrimaryTransformer: a shortlived primary particle is found" << G4endl
|
||||
<< " without any valid decay table nor pre-assigned decay mode." << G4endl;
|
||||
G4Exception("G4PrimaryTransformer","InvalidPrimary",JustWarning,
|
||||
<< "G4PrimaryTransformer: a shortlived primary particle is found"
|
||||
<< G4endl
|
||||
<< " without any valid decay table nor pre-assigned decay mode."
|
||||
<< G4endl;
|
||||
G4Exception("G4PrimaryTransformer", "InvalidPrimary", JustWarning,
|
||||
"This primary particle will be ignored.");
|
||||
return false;
|
||||
}
|
||||
|
||||
G4ParticleDefinition* G4PrimaryTransformer::GetDefinition(G4PrimaryParticle*pp)
|
||||
G4ParticleDefinition*
|
||||
G4PrimaryTransformer::GetDefinition(G4PrimaryParticle* pp)
|
||||
{
|
||||
G4ParticleDefinition* partDef = pp->GetG4code();
|
||||
if(!partDef) partDef = particleTable->FindParticle(pp->GetPDGcode());
|
||||
if(unknownParticleDefined && ((!partDef)||partDef->IsShortLived())) partDef = unknown;
|
||||
if(partDef == nullptr)
|
||||
{
|
||||
partDef = particleTable->FindParticle(pp->GetPDGcode());
|
||||
}
|
||||
if(unknownParticleDefined && ((!partDef)||partDef->IsShortLived()))
|
||||
{
|
||||
partDef = unknown;
|
||||
}
|
||||
return partDef;
|
||||
}
|
||||
|
||||
G4bool G4PrimaryTransformer::IsGoodForTrack(G4ParticleDefinition* pd)
|
||||
{
|
||||
if(!pd)
|
||||
if(pd == nullptr)
|
||||
{ return false; }
|
||||
else if(!(pd->IsShortLived()))
|
||||
{ return true; }
|
||||
// Following two lines should be removed if the user does not want to make shortlived
|
||||
// primary particle with proper decay table to be converted into a track.
|
||||
else if(pd->GetDecayTable())
|
||||
//
|
||||
// Following two lines should be removed if the user does not want to make
|
||||
// shortlived primary particle with proper decay table to be converted into
|
||||
// a track.
|
||||
//
|
||||
else if(pd->GetDecayTable() != nullptr)
|
||||
{ return true; }
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4RayShooter class implementation
|
||||
//
|
||||
//
|
||||
// Author: Makoto Asai, 2000
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4RayShooter.hh"
|
||||
#include "G4SystemOfUnits.hh"
|
||||
@@ -34,7 +36,6 @@
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
|
||||
G4RayShooter::G4RayShooter()
|
||||
{
|
||||
SetInitialValues();
|
||||
@@ -42,12 +43,10 @@ G4RayShooter::G4RayShooter()
|
||||
|
||||
void G4RayShooter::SetInitialValues()
|
||||
{
|
||||
particle_definition = 0;
|
||||
G4ThreeVector zero;
|
||||
particle_momentum_direction = (G4ParticleMomentum)zero;
|
||||
particle_energy = 1.0*GeV;
|
||||
particle_position = zero;
|
||||
particle_time = 0.0;
|
||||
particle_polarization = zero;
|
||||
}
|
||||
|
||||
@@ -55,38 +54,37 @@ G4RayShooter::~G4RayShooter()
|
||||
{
|
||||
}
|
||||
|
||||
void G4RayShooter::Shoot(G4Event* evt,G4ThreeVector vtx,G4ThreeVector direc)
|
||||
void G4RayShooter::Shoot(G4Event* evt,G4ThreeVector vtx, G4ThreeVector direc)
|
||||
{
|
||||
if(!particle_definition)
|
||||
if(particle_definition == nullptr)
|
||||
{
|
||||
G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
|
||||
G4String particleName;
|
||||
particle_definition = particleTable->FindParticle(particleName="geantino");
|
||||
if(!particle_definition)
|
||||
if(particle_definition == nullptr)
|
||||
{
|
||||
G4String msg;
|
||||
msg = " G4RayTracer uses geantino to trace the ray, but your physics list does not\n";
|
||||
msg = "G4RayTracer uses geantino to trace the ray, but your physics list does not\n";
|
||||
msg += "define G4Geantino. Please add G4Geantino in your physics list.";
|
||||
G4Exception("G4RayShooter::Shoot","RayTracer001",FatalException,msg);
|
||||
G4Exception("G4RayShooter::Shoot()", "RayTracer001", FatalException, msg);
|
||||
}
|
||||
}
|
||||
|
||||
// create a new vertex
|
||||
// Create a new vertex
|
||||
//
|
||||
G4PrimaryVertex* vertex = new G4PrimaryVertex(vtx,particle_time);
|
||||
|
||||
// create new primaries and set them to the vertex
|
||||
// Create new primaries and set them to the vertex
|
||||
//
|
||||
G4double mass = particle_definition->GetPDGMass();
|
||||
G4PrimaryParticle* particle =
|
||||
new G4PrimaryParticle(particle_definition);
|
||||
G4PrimaryParticle* particle = new G4PrimaryParticle(particle_definition);
|
||||
particle->SetKineticEnergy( particle_energy );
|
||||
particle->SetMass( mass );
|
||||
particle->SetMomentumDirection( direc );
|
||||
particle->SetPolarization(particle_polarization.x(),
|
||||
particle_polarization.y(),
|
||||
particle_polarization.z());
|
||||
particle_polarization.y(),
|
||||
particle_polarization.z());
|
||||
vertex->SetPrimary( particle );
|
||||
|
||||
evt->AddPrimaryVertex( vertex );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -23,37 +23,20 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MODULE: G4SPSAngDistribution.cc
|
||||
//
|
||||
// Version: 1.0
|
||||
// Date: 5/02/04
|
||||
// Author: Fan Lei
|
||||
// Organisation: QinetiQ ltd.
|
||||
// Customer: ESA/ESTEC
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
//
|
||||
//
|
||||
// Version 1.0, 05/02/2004, Fan Lei, Created.
|
||||
// Based on the G4GeneralParticleSource class in Geant4 v6.0
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// G4SPSAngDistribution class implementation
|
||||
//
|
||||
// Author: Fan Lei, QinetiQ ltd. - 05/02/2004
|
||||
// Customer: ESA/ESTEC
|
||||
// Revisions: Andrea Dotti, SLAC
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4SPSAngDistribution.hh"
|
||||
|
||||
#include "Randomize.hh"
|
||||
#include "G4PhysicalConstants.hh"
|
||||
|
||||
|
||||
G4SPSAngDistribution::G4SPSAngDistribution()
|
||||
: Theta(0.), Phi(0.), posDist(0),angRndm(0)
|
||||
: Theta(0.), Phi(0.)
|
||||
{
|
||||
// Angular distribution Variables
|
||||
G4ThreeVector zero;
|
||||
@@ -76,8 +59,8 @@ G4SPSAngDistribution::G4SPSAngDistribution()
|
||||
UserAngRef = false;
|
||||
IPDFThetaExist = false;
|
||||
IPDFPhiExist = false;
|
||||
verbosityLevel = 0 ;
|
||||
|
||||
verbosityLevel = 0;
|
||||
|
||||
G4MUTEXINIT(mutex);
|
||||
}
|
||||
|
||||
@@ -86,30 +69,36 @@ G4SPSAngDistribution::~G4SPSAngDistribution()
|
||||
G4MUTEXDESTROY(mutex);
|
||||
}
|
||||
|
||||
//
|
||||
void G4SPSAngDistribution::SetAngDistType(G4String atype)
|
||||
void G4SPSAngDistribution::SetAngDistType(const G4String& atype)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
G4AutoLock l(&mutex);
|
||||
if(atype != "iso" && atype != "cos" && atype != "user" && atype != "planar"
|
||||
&& atype != "beam1d" && atype != "beam2d" && atype != "focused")
|
||||
G4cout << "Error, distribution must be iso, cos, planar, beam1d, beam2d, focused or user" << G4endl;
|
||||
{
|
||||
G4cout << "Error, distribution must be iso, cos, planar, beam1d, beam2d, focused or user"
|
||||
<< G4endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
AngDistType = atype;
|
||||
if (AngDistType == "cos") MaxTheta = pi/2. ;
|
||||
if (AngDistType == "user") {
|
||||
UDefThetaH = IPDFThetaH = ZeroPhysVector ;
|
||||
IPDFThetaExist = false ;
|
||||
UDefPhiH = IPDFPhiH = ZeroPhysVector ;
|
||||
IPDFPhiExist = false ;
|
||||
}
|
||||
if (AngDistType == "cos") { MaxTheta = pi/2.; }
|
||||
if (AngDistType == "user")
|
||||
{
|
||||
UDefThetaH = IPDFThetaH = ZeroPhysVector;
|
||||
IPDFThetaExist = false;
|
||||
UDefPhiH = IPDFPhiH = ZeroPhysVector;
|
||||
IPDFPhiExist = false;
|
||||
}
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::DefineAngRefAxes(G4String refname, G4ThreeVector ref)
|
||||
void G4SPSAngDistribution::DefineAngRefAxes(const G4String& refname,
|
||||
const G4ThreeVector& ref)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
if(refname == "angref1")
|
||||
G4AutoLock l(&mutex);
|
||||
if (refname == "angref1")
|
||||
AngRef1 = ref.unit(); // x'
|
||||
else if(refname == "angref2")
|
||||
else if (refname == "angref2")
|
||||
AngRef2 = ref.unit(); // vector in x'y' plane
|
||||
|
||||
// User defines x' (AngRef1) and a vector in the x'y'
|
||||
@@ -121,134 +110,164 @@ void G4SPSAngDistribution::DefineAngRefAxes(G4String refname, G4ThreeVector ref)
|
||||
AngRef2 = AngRef3.cross(AngRef1); // y'
|
||||
UserAngRef = true ;
|
||||
if(verbosityLevel == 2)
|
||||
{
|
||||
G4cout << "Angular distribution rotation axes " << AngRef1 << " " << AngRef2 << " " << AngRef3 << G4endl;
|
||||
}
|
||||
{
|
||||
G4cout << "Angular distribution rotation axes " << AngRef1
|
||||
<< " " << AngRef2 << " " << AngRef3 << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::SetMinTheta(G4double mint)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
G4AutoLock l(&mutex);
|
||||
MinTheta = mint;
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::SetMinPhi(G4double minp)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
G4AutoLock l(&mutex);
|
||||
MinPhi = minp;
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::SetMaxTheta(G4double maxt)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
G4AutoLock l(&mutex);
|
||||
MaxTheta = maxt;
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::SetMaxPhi(G4double maxp)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
G4AutoLock l(&mutex);
|
||||
MaxPhi = maxp;
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::SetBeamSigmaInAngR(G4double r)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
G4AutoLock l(&mutex);
|
||||
DR = r;
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::SetBeamSigmaInAngX(G4double r)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
G4AutoLock l(&mutex);
|
||||
DX = r;
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::SetBeamSigmaInAngY(G4double r)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
G4AutoLock l(&mutex);
|
||||
DY = r;
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::SetParticleMomentumDirection(G4ParticleMomentum aMomentumDirection)
|
||||
void G4SPSAngDistribution::
|
||||
SetParticleMomentumDirection(const G4ParticleMomentum& aMomentumDirection)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
particle_momentum_direction = aMomentumDirection.unit();
|
||||
|
||||
G4AutoLock l(&mutex);
|
||||
particle_momentum_direction = aMomentumDirection.unit();
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::SetPosDistribution(G4SPSPosDistribution* a)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
posDist = a;
|
||||
G4AutoLock l(&mutex);
|
||||
posDist = a;
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::SetBiasRndm(G4SPSRandomGenerator* a)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
angRndm = a;
|
||||
G4AutoLock l(&mutex);
|
||||
angRndm = a;
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::SetVerbosity(G4int a)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
verbosityLevel = a;
|
||||
G4AutoLock l(&mutex);
|
||||
verbosityLevel = a;
|
||||
}
|
||||
|
||||
|
||||
void G4SPSAngDistribution::UserDefAngTheta(G4ThreeVector input)
|
||||
void G4SPSAngDistribution::UserDefAngTheta(const G4ThreeVector& input)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
G4AutoLock l(&mutex);
|
||||
if(UserDistType == "NULL") UserDistType = "theta";
|
||||
if(UserDistType == "phi") UserDistType = "both";
|
||||
G4double thi, val;
|
||||
thi = input.x();
|
||||
val = input.y();
|
||||
if(verbosityLevel >= 1)
|
||||
G4cout << "In UserDefAngTheta" << G4endl;
|
||||
if(verbosityLevel >= 1) G4cout << "In UserDefAngTheta" << G4endl;
|
||||
UDefThetaH.InsertValues(thi, val);
|
||||
}
|
||||
|
||||
G4String G4SPSAngDistribution::GetDistType() { G4AutoLock l(&mutex); return AngDistType;}
|
||||
G4double G4SPSAngDistribution::GetMinTheta() { G4AutoLock l(&mutex); return MinTheta; }
|
||||
G4double G4SPSAngDistribution::GetMaxTheta() { G4AutoLock l(&mutex); return MaxTheta; }
|
||||
G4double G4SPSAngDistribution::GetMinPhi() { G4AutoLock l(&mutex); return MinPhi; }
|
||||
G4double G4SPSAngDistribution::GetMaxPhi() { G4AutoLock l(&mutex); return MaxPhi; }
|
||||
G4ThreeVector G4SPSAngDistribution::GetDirection() { G4AutoLock l(&mutex); return particle_momentum_direction; }
|
||||
|
||||
void G4SPSAngDistribution::UserDefAngPhi(G4ThreeVector input)
|
||||
G4String G4SPSAngDistribution::GetDistType()
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
G4AutoLock l(&mutex);
|
||||
return AngDistType;
|
||||
}
|
||||
|
||||
G4double G4SPSAngDistribution::GetMinTheta()
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
return MinTheta;
|
||||
}
|
||||
|
||||
G4double G4SPSAngDistribution::GetMaxTheta()
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
return MaxTheta;
|
||||
}
|
||||
|
||||
G4double G4SPSAngDistribution::GetMinPhi()
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
return MinPhi;
|
||||
}
|
||||
|
||||
G4double G4SPSAngDistribution::GetMaxPhi()
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
return MaxPhi;
|
||||
}
|
||||
|
||||
G4ThreeVector G4SPSAngDistribution::GetDirection()
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
return particle_momentum_direction;
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::UserDefAngPhi(const G4ThreeVector& input)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
if(UserDistType == "NULL") UserDistType = "phi";
|
||||
if(UserDistType == "theta") UserDistType = "both";
|
||||
G4double phhi, val;
|
||||
phhi = input.x();
|
||||
val = input.y();
|
||||
if(verbosityLevel >= 1)
|
||||
G4cout << "In UserDefAngPhi" << G4endl;
|
||||
if(verbosityLevel >= 1) G4cout << "In UserDefAngPhi" << G4endl;
|
||||
UDefPhiH.InsertValues(phhi, val);
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::SetFocusPoint(G4ThreeVector input)
|
||||
void G4SPSAngDistribution::SetFocusPoint(const G4ThreeVector& input)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
G4AutoLock l(&mutex);
|
||||
FocusPoint = input;
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::SetUserWRTSurface(G4bool wrtSurf)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
// This is only applied in user mode?
|
||||
G4AutoLock l(&mutex);
|
||||
|
||||
// if UserWRTSurface = true then the user wants momenta with respect
|
||||
// to the surface normals.
|
||||
// When doing this theta has to be 0-90 only otherwise there will be
|
||||
// errors, which currently are flagged anywhere.
|
||||
//
|
||||
UserWRTSurface = wrtSurf;
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::SetUseUserAngAxis(G4bool userang)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
G4AutoLock l(&mutex);
|
||||
|
||||
// if UserAngRef = true the angular distribution is defined wrt
|
||||
// the user defined co-ordinates
|
||||
// the user defined coordinates
|
||||
//
|
||||
UserAngRef = userang;
|
||||
}
|
||||
|
||||
@@ -257,28 +276,32 @@ void G4SPSAngDistribution::GenerateBeamFlux(G4ParticleMomentum& mom)
|
||||
G4double theta, phi;
|
||||
G4double px, py, pz;
|
||||
if (AngDistType == "beam1d")
|
||||
{
|
||||
theta = G4RandGauss::shoot(0.0,DR);
|
||||
phi = twopi * G4UniformRand();
|
||||
}
|
||||
{
|
||||
theta = G4RandGauss::shoot(0.0,DR);
|
||||
phi = twopi * G4UniformRand();
|
||||
}
|
||||
else
|
||||
{
|
||||
px = G4RandGauss::shoot(0.0,DX);
|
||||
py = G4RandGauss::shoot(0.0,DY);
|
||||
theta = std::sqrt (px*px + py*py);
|
||||
if (theta != 0.) {
|
||||
phi = std::acos(px/theta);
|
||||
if ( py < 0.) phi = -phi;
|
||||
} else {
|
||||
phi = 0.0;
|
||||
}
|
||||
{
|
||||
px = G4RandGauss::shoot(0.0,DX);
|
||||
py = G4RandGauss::shoot(0.0,DY);
|
||||
theta = std::sqrt (px*px + py*py);
|
||||
if (theta != 0.)
|
||||
{
|
||||
phi = std::acos(px/theta);
|
||||
if ( py < 0.) phi = -phi;
|
||||
}
|
||||
else
|
||||
{
|
||||
phi = 0.0;
|
||||
}
|
||||
}
|
||||
px = -std::sin(theta) * std::cos(phi);
|
||||
py = -std::sin(theta) * std::sin(phi);
|
||||
pz = -std::cos(theta);
|
||||
G4double finx, finy, finz ;
|
||||
finx = px, finy =py, finz =pz;
|
||||
if (UserAngRef){
|
||||
G4double finx, finy, finz;
|
||||
finx=px, finy=py, finz=pz;
|
||||
if (UserAngRef)
|
||||
{
|
||||
// Apply Angular Rotation Matrix
|
||||
// x * AngRef1, y * AngRef2 and z * AngRef3
|
||||
finx = (px * AngRef1.x()) + (py * AngRef2.x()) + (pz * AngRef3.x());
|
||||
@@ -293,31 +316,38 @@ void G4SPSAngDistribution::GenerateBeamFlux(G4ParticleMomentum& mom)
|
||||
mom.setY(finy);
|
||||
mom.setZ(finz);
|
||||
|
||||
// particle_momentum_direction now holds unit momentum vector.
|
||||
// particle_momentum_direction now holds unit momentum vector
|
||||
|
||||
if(verbosityLevel >= 1)
|
||||
{
|
||||
G4cout << "Generating beam vector: " << mom << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::GenerateFocusedFlux(G4ParticleMomentum& mom)
|
||||
{
|
||||
mom = (FocusPoint - posDist->GetParticlePos()).unit();
|
||||
//
|
||||
|
||||
// particle_momentum_direction now holds unit momentum vector.
|
||||
|
||||
if(verbosityLevel >= 1)
|
||||
{
|
||||
G4cout << "Generating focused vector: " << mom << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::GenerateIsotropicFlux(G4ParticleMomentum& mom)
|
||||
{
|
||||
// generates isotropic flux.
|
||||
// No vectors are needed.
|
||||
|
||||
G4double rndm, rndm2;
|
||||
G4double px, py, pz;
|
||||
|
||||
//
|
||||
G4double sintheta, sinphi,costheta,cosphi;
|
||||
rndm = angRndm->GenRandTheta();
|
||||
costheta = std::cos(MinTheta) - rndm * (std::cos(MinTheta) - std::cos(MaxTheta));
|
||||
costheta = std::cos(MinTheta) - rndm * (std::cos(MinTheta)
|
||||
- std::cos(MaxTheta));
|
||||
sintheta = std::sqrt(1. - costheta*costheta);
|
||||
|
||||
rndm2 = angRndm->GenRandPhi();
|
||||
@@ -329,33 +359,50 @@ void G4SPSAngDistribution::GenerateIsotropicFlux(G4ParticleMomentum& mom)
|
||||
py = -sintheta * sinphi;
|
||||
pz = -costheta;
|
||||
|
||||
// for volume and ponit source use mother or user defined co-ordinates
|
||||
// for plane and surface source user surface-normal or userdefined co-ordinates
|
||||
// For volume and point source use mother or user defined coordinates
|
||||
// for plane and surface source user surface-normal or user-defined
|
||||
// coordinates
|
||||
//
|
||||
G4double finx, finy, finz;
|
||||
if (posDist->GetSourcePosType() == "Point" || posDist->GetSourcePosType() == "Volume") {
|
||||
if (UserAngRef){
|
||||
if (posDist->GetSourcePosType() == "Point"
|
||||
|| posDist->GetSourcePosType() == "Volume")
|
||||
{
|
||||
if (UserAngRef)
|
||||
{
|
||||
// Apply Rotation Matrix
|
||||
// x * AngRef1, y * AngRef2 and z * AngRef3
|
||||
finx = (px * AngRef1.x()) + (py * AngRef2.x()) + (pz * AngRef3.x());
|
||||
finy = (px * AngRef1.y()) + (py * AngRef2.y()) + (pz * AngRef3.y());
|
||||
finz = (px * AngRef1.z()) + (py * AngRef2.z()) + (pz * AngRef3.z());
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
finx = px;
|
||||
finy = py;
|
||||
finz = pz;
|
||||
}
|
||||
} else { // for plane and surface source
|
||||
if (UserAngRef){
|
||||
}
|
||||
else
|
||||
{ // for plane and surface source
|
||||
if (UserAngRef)
|
||||
{
|
||||
// Apply Rotation Matrix
|
||||
// x * AngRef1, y * AngRef2 and z * AngRef3
|
||||
finx = (px * AngRef1.x()) + (py * AngRef2.x()) + (pz * AngRef3.x());
|
||||
finy = (px * AngRef1.y()) + (py * AngRef2.y()) + (pz * AngRef3.y());
|
||||
finz = (px * AngRef1.z()) + (py * AngRef2.z()) + (pz * AngRef3.z());
|
||||
} else {
|
||||
finx = (px*posDist->GetSideRefVec1().x()) + (py*posDist->GetSideRefVec2().x()) + (pz*posDist->GetSideRefVec3().x());
|
||||
finy = (px*posDist->GetSideRefVec1().y()) + (py*posDist->GetSideRefVec2().y()) + (pz*posDist->GetSideRefVec3().y());
|
||||
finz = (px*posDist->GetSideRefVec1().z()) + (py*posDist->GetSideRefVec2().z()) + (pz*posDist->GetSideRefVec3().z());
|
||||
}
|
||||
else
|
||||
{
|
||||
finx = (px*posDist->GetSideRefVec1().x())
|
||||
+ (py*posDist->GetSideRefVec2().x())
|
||||
+ (pz*posDist->GetSideRefVec3().x());
|
||||
finy = (px*posDist->GetSideRefVec1().y())
|
||||
+ (py*posDist->GetSideRefVec2().y())
|
||||
+ (pz*posDist->GetSideRefVec3().y());
|
||||
finz = (px*posDist->GetSideRefVec1().z())
|
||||
+ (py*posDist->GetSideRefVec2().z())
|
||||
+ (pz*posDist->GetSideRefVec3().z());
|
||||
}
|
||||
}
|
||||
G4double ResMag = std::sqrt((finx*finx) + (finy*finy) + (finz*finz));
|
||||
@@ -368,20 +415,25 @@ void G4SPSAngDistribution::GenerateIsotropicFlux(G4ParticleMomentum& mom)
|
||||
mom.setZ(finz);
|
||||
|
||||
// particle_momentum_direction now holds unit momentum vector.
|
||||
|
||||
if(verbosityLevel >= 1)
|
||||
{
|
||||
G4cout << "Generating isotropic vector: " << mom << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::GenerateCosineLawFlux(G4ParticleMomentum& mom)
|
||||
{
|
||||
// Method to generate flux distributed with a cosine law
|
||||
|
||||
G4double px, py, pz;
|
||||
G4double rndm, rndm2;
|
||||
//
|
||||
|
||||
G4double sintheta, sinphi,costheta,cosphi;
|
||||
rndm = angRndm->GenRandTheta();
|
||||
sintheta = std::sqrt( rndm * (std::sin(MaxTheta)*std::sin(MaxTheta) - std::sin(MinTheta)*std::sin(MinTheta) )
|
||||
+std::sin(MinTheta)*std::sin(MinTheta) );
|
||||
sintheta = std::sqrt( rndm * (std::sin(MaxTheta)*std::sin(MaxTheta)
|
||||
- std::sin(MinTheta)*std::sin(MinTheta) )
|
||||
+ std::sin(MinTheta)*std::sin(MinTheta) );
|
||||
costheta = std::sqrt(1. -sintheta*sintheta);
|
||||
|
||||
rndm2 = angRndm->GenRandPhi();
|
||||
@@ -393,31 +445,48 @@ void G4SPSAngDistribution::GenerateCosineLawFlux(G4ParticleMomentum& mom)
|
||||
py = -sintheta * sinphi;
|
||||
pz = -costheta;
|
||||
|
||||
// for volume and ponit source use mother or user defined co-ordinates
|
||||
// for plane and surface source user surface-normal or userdefined co-ordinates
|
||||
// for volume and point source use mother or user defined coordinates
|
||||
// for plane and surface source user surface-normal or userdefined
|
||||
// coordinates
|
||||
//
|
||||
G4double finx, finy, finz;
|
||||
if (posDist->GetSourcePosType() == "Point" || posDist->GetSourcePosType() == "Volume") {
|
||||
if (UserAngRef){
|
||||
if (posDist->GetSourcePosType() == "Point"
|
||||
|| posDist->GetSourcePosType() == "Volume")
|
||||
{
|
||||
if (UserAngRef)
|
||||
{
|
||||
// Apply Rotation Matrix
|
||||
finx = (px * AngRef1.x()) + (py * AngRef2.x()) + (pz * AngRef3.x());
|
||||
finy = (px * AngRef1.y()) + (py * AngRef2.y()) + (pz * AngRef3.y());
|
||||
finz = (px * AngRef1.z()) + (py * AngRef2.z()) + (pz * AngRef3.z());
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
finx = px;
|
||||
finy = py;
|
||||
finz = pz;
|
||||
}
|
||||
} else { // for plane and surface source
|
||||
if (UserAngRef){
|
||||
}
|
||||
else
|
||||
{ // for plane and surface source
|
||||
if (UserAngRef)
|
||||
{
|
||||
// Apply Rotation Matrix
|
||||
finx = (px * AngRef1.x()) + (py * AngRef2.x()) + (pz * AngRef3.x());
|
||||
finy = (px * AngRef1.y()) + (py * AngRef2.y()) + (pz * AngRef3.y());
|
||||
finz = (px * AngRef1.z()) + (py * AngRef2.z()) + (pz * AngRef3.z());
|
||||
} else {
|
||||
finx = (px*posDist->GetSideRefVec1().x()) + (py*posDist->GetSideRefVec2().x()) + (pz*posDist->GetSideRefVec3().x());
|
||||
finy = (px*posDist->GetSideRefVec1().y()) + (py*posDist->GetSideRefVec2().y()) + (pz*posDist->GetSideRefVec3().y());
|
||||
finz = (px*posDist->GetSideRefVec1().z()) + (py*posDist->GetSideRefVec2().z()) + (pz*posDist->GetSideRefVec3().z());
|
||||
}
|
||||
else
|
||||
{
|
||||
finx = (px*posDist->GetSideRefVec1().x())
|
||||
+ (py*posDist->GetSideRefVec2().x())
|
||||
+ (pz*posDist->GetSideRefVec3().x());
|
||||
finy = (px*posDist->GetSideRefVec1().y())
|
||||
+ (py*posDist->GetSideRefVec2().y())
|
||||
+ (pz*posDist->GetSideRefVec3().y());
|
||||
finz = (px*posDist->GetSideRefVec1().z())
|
||||
+ (py*posDist->GetSideRefVec2().z())
|
||||
+ (pz*posDist->GetSideRefVec3().z());
|
||||
}
|
||||
}
|
||||
G4double ResMag = std::sqrt((finx*finx) + (finy*finy) + (finz*finz));
|
||||
@@ -430,10 +499,11 @@ void G4SPSAngDistribution::GenerateCosineLawFlux(G4ParticleMomentum& mom)
|
||||
mom.setZ(finz);
|
||||
|
||||
// particle_momentum_direction now contains unit momentum vector.
|
||||
|
||||
if(verbosityLevel >= 1)
|
||||
{
|
||||
G4cout << "Resultant cosine-law unit momentum vector " << mom << G4endl;
|
||||
}
|
||||
{
|
||||
G4cout << "Resultant cosine-law unit momentum vector " << mom << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::GeneratePlanarFlux(G4ParticleMomentum& mom)
|
||||
@@ -441,10 +511,11 @@ void G4SPSAngDistribution::GeneratePlanarFlux(G4ParticleMomentum& mom)
|
||||
// particle_momentum_direction now contains unit momentum vector.
|
||||
// nothing need be done here as the m-directions have been set directly
|
||||
// under this option
|
||||
|
||||
if(verbosityLevel >= 1)
|
||||
{
|
||||
G4cout << "Resultant Planar wave momentum vector " << mom << G4endl;
|
||||
}
|
||||
{
|
||||
G4cout << "Resultant Planar wave momentum vector " << mom << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::GenerateUserDefFlux(G4ParticleMomentum& mom)
|
||||
@@ -452,52 +523,69 @@ void G4SPSAngDistribution::GenerateUserDefFlux(G4ParticleMomentum& mom)
|
||||
G4double rndm, px, py, pz, pmag;
|
||||
|
||||
if(UserDistType == "NULL")
|
||||
{
|
||||
G4cout << "Error: UserDistType undefined" << G4endl;
|
||||
else if(UserDistType == "theta") {
|
||||
}
|
||||
else if(UserDistType == "theta")
|
||||
{
|
||||
Theta = 10.;
|
||||
while(Theta > MaxTheta || Theta < MinTheta)
|
||||
{
|
||||
Theta = GenerateUserDefTheta();
|
||||
}
|
||||
Phi = 10.;
|
||||
while(Phi > MaxPhi || Phi < MinPhi) {
|
||||
while(Phi > MaxPhi || Phi < MinPhi)
|
||||
{
|
||||
rndm = angRndm->GenRandPhi();
|
||||
Phi = twopi * rndm;
|
||||
}
|
||||
}
|
||||
else if(UserDistType == "phi") {
|
||||
else if(UserDistType == "phi")
|
||||
{
|
||||
Theta = 10.;
|
||||
while(Theta > MaxTheta || Theta < MinTheta)
|
||||
{
|
||||
rndm = angRndm->GenRandTheta();
|
||||
Theta = std::acos(1. - (2. * rndm));
|
||||
}
|
||||
{
|
||||
rndm = angRndm->GenRandTheta();
|
||||
Theta = std::acos(1. - (2. * rndm));
|
||||
}
|
||||
Phi = 10.;
|
||||
while(Phi > MaxPhi || Phi < MinPhi)
|
||||
{
|
||||
Phi = GenerateUserDefPhi();
|
||||
}
|
||||
}
|
||||
else if(UserDistType == "both")
|
||||
{
|
||||
Theta = 10.;
|
||||
while(Theta > MaxTheta || Theta < MinTheta)
|
||||
{
|
||||
Theta = 10.;
|
||||
while(Theta > MaxTheta || Theta < MinTheta)
|
||||
Theta = GenerateUserDefTheta();
|
||||
Phi = 10.;
|
||||
while(Phi > MaxPhi || Phi < MinPhi)
|
||||
Phi = GenerateUserDefPhi();
|
||||
Theta = GenerateUserDefTheta();
|
||||
}
|
||||
Phi = 10.;
|
||||
while(Phi > MaxPhi || Phi < MinPhi)
|
||||
{
|
||||
Phi = GenerateUserDefPhi();
|
||||
}
|
||||
}
|
||||
px = -std::sin(Theta) * std::cos(Phi);
|
||||
py = -std::sin(Theta) * std::sin(Phi);
|
||||
pz = -std::cos(Theta);
|
||||
|
||||
pmag = std::sqrt((px*px) + (py*py) + (pz*pz));
|
||||
|
||||
if(!UserWRTSurface) {
|
||||
if(!UserWRTSurface)
|
||||
{
|
||||
G4double finx, finy, finz;
|
||||
if (UserAngRef) {
|
||||
if (UserAngRef)
|
||||
{
|
||||
// Apply Rotation Matrix
|
||||
// x * AngRef1, y * AngRef2 and z * AngRef3
|
||||
finx = (px * AngRef1.x()) + (py * AngRef2.x()) + (pz * AngRef3.x());
|
||||
finy = (px * AngRef1.y()) + (py * AngRef2.y()) + (pz * AngRef3.y());
|
||||
finz = (px * AngRef1.z()) + (py * AngRef2.z()) + (pz * AngRef3.z());
|
||||
} else { // use mother co-ordinates
|
||||
}
|
||||
else // use mother coordinates
|
||||
{
|
||||
finx = px;
|
||||
finy = py;
|
||||
finz = pz;
|
||||
@@ -511,24 +599,34 @@ void G4SPSAngDistribution::GenerateUserDefFlux(G4ParticleMomentum& mom)
|
||||
mom.setY(finy);
|
||||
mom.setZ(finz);
|
||||
}
|
||||
else { // UserWRTSurface = true
|
||||
else // UserWRTSurface = true
|
||||
{
|
||||
G4double pxh = px/pmag;
|
||||
G4double pyh = py/pmag;
|
||||
G4double pzh = pz/pmag;
|
||||
if(verbosityLevel > 1) {
|
||||
G4cout <<"SideRefVecs " <<posDist->GetSideRefVec1()<<posDist->GetSideRefVec2()<<posDist->GetSideRefVec3()<<G4endl;
|
||||
G4cout <<"Raw Unit vector "<<pxh<<","<<pyh<<","<<pzh<<G4endl;
|
||||
if(verbosityLevel > 1)
|
||||
{
|
||||
G4cout << "SideRefVecs " << posDist->GetSideRefVec1()
|
||||
<< posDist->GetSideRefVec2() << posDist->GetSideRefVec3()
|
||||
<< G4endl;
|
||||
G4cout << "Raw Unit vector " << pxh
|
||||
<< "," << pyh << "," << pzh << G4endl;
|
||||
}
|
||||
G4double resultx = (pxh*posDist->GetSideRefVec1().x()) + (pyh*posDist->GetSideRefVec2().x()) +
|
||||
(pzh*posDist->GetSideRefVec3().x());
|
||||
G4double resultx = (pxh*posDist->GetSideRefVec1().x())
|
||||
+ (pyh*posDist->GetSideRefVec2().x())
|
||||
+ (pzh*posDist->GetSideRefVec3().x());
|
||||
|
||||
G4double resulty = (pxh*posDist->GetSideRefVec1().y()) + (pyh*posDist->GetSideRefVec2().y()) +
|
||||
(pzh*posDist->GetSideRefVec3().y());
|
||||
G4double resulty = (pxh*posDist->GetSideRefVec1().y())
|
||||
+ (pyh*posDist->GetSideRefVec2().y())
|
||||
+ (pzh*posDist->GetSideRefVec3().y());
|
||||
|
||||
G4double resultz = (pxh*posDist->GetSideRefVec1().z()) + (pyh*posDist->GetSideRefVec2().z()) +
|
||||
(pzh*posDist->GetSideRefVec3().z());
|
||||
G4double resultz = (pxh*posDist->GetSideRefVec1().z())
|
||||
+ (pyh*posDist->GetSideRefVec2().z())
|
||||
+ (pzh*posDist->GetSideRefVec3().z());
|
||||
|
||||
G4double ResMag = std::sqrt((resultx*resultx) + (resulty*resulty) + (resultz*resultz));
|
||||
G4double ResMag = std::sqrt((resultx*resultx)
|
||||
+ (resulty*resulty)
|
||||
+ (resultz*resultz));
|
||||
resultx = resultx/ResMag;
|
||||
resulty = resulty/ResMag;
|
||||
resultz = resultz/ResMag;
|
||||
@@ -539,125 +637,140 @@ void G4SPSAngDistribution::GenerateUserDefFlux(G4ParticleMomentum& mom)
|
||||
}
|
||||
|
||||
// particle_momentum_direction now contains unit momentum vector.
|
||||
|
||||
if(verbosityLevel > 0 )
|
||||
{
|
||||
G4cout << "Final User Defined momentum vector " << particle_momentum_direction << G4endl;
|
||||
}
|
||||
{
|
||||
G4cout << "Final User Defined momentum vector "
|
||||
<< particle_momentum_direction << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4SPSAngDistribution::GenerateUserDefTheta()
|
||||
{
|
||||
// Create cumulative histogram if not already done so. Then use RandFlat
|
||||
//::shoot to generate the output Theta value.
|
||||
// Create cumulative histogram if not already done so.
|
||||
// Then use RandFlat::shoot to generate the output Theta value.
|
||||
|
||||
if(UserDistType == "NULL" || UserDistType == "phi")
|
||||
{
|
||||
// No user defined theta distribution
|
||||
G4cout << "Error ***********************" << G4endl;
|
||||
G4cout << "UserDistType = " << UserDistType << G4endl;
|
||||
return (0.);
|
||||
}
|
||||
{
|
||||
// No user defined theta distribution
|
||||
G4cout << "Error ***********************" << G4endl;
|
||||
G4cout << "UserDistType = " << UserDistType << G4endl;
|
||||
return (0.);
|
||||
}
|
||||
else
|
||||
{
|
||||
// UserDistType = theta or both and so a theta distribution
|
||||
// is defined. This should be integrated if not already done.
|
||||
G4AutoLock l(&mutex);
|
||||
if(IPDFThetaExist == false)
|
||||
{
|
||||
// UserDistType = theta or both and so a theta distribution
|
||||
// is defined. This should be integrated if not already done.
|
||||
G4AutoLock l(&mutex);
|
||||
if(IPDFThetaExist == false)
|
||||
// IPDF has not been created, so create it
|
||||
//
|
||||
G4double bins[1024],vals[1024], sum;
|
||||
G4int ii;
|
||||
G4int maxbin = G4int(UDefThetaH.GetVectorLength());
|
||||
bins[0] = UDefThetaH.GetLowEdgeEnergy(std::size_t(0));
|
||||
vals[0] = UDefThetaH(std::size_t(0));
|
||||
sum = vals[0];
|
||||
for(ii=1; ii<maxbin; ++ii)
|
||||
{
|
||||
// IPDF has not been created, so create it
|
||||
G4double bins[1024],vals[1024], sum;
|
||||
G4int ii;
|
||||
G4int maxbin = G4int(UDefThetaH.GetVectorLength());
|
||||
bins[0] = UDefThetaH.GetLowEdgeEnergy(size_t(0));
|
||||
vals[0] = UDefThetaH(size_t(0));
|
||||
sum = vals[0];
|
||||
for(ii=1;ii<maxbin;ii++)
|
||||
{
|
||||
bins[ii] = UDefThetaH.GetLowEdgeEnergy(size_t(ii));
|
||||
vals[ii] = UDefThetaH(size_t(ii)) + vals[ii-1];
|
||||
sum = sum + UDefThetaH(size_t(ii));
|
||||
}
|
||||
for(ii=0;ii<maxbin;ii++)
|
||||
{
|
||||
vals[ii] = vals[ii]/sum;
|
||||
IPDFThetaH.InsertValues(bins[ii], vals[ii]);
|
||||
}
|
||||
// Make IPDFThetaExist = true
|
||||
IPDFThetaExist = true;
|
||||
bins[ii] = UDefThetaH.GetLowEdgeEnergy(std::size_t(ii));
|
||||
vals[ii] = UDefThetaH(std::size_t(ii)) + vals[ii-1];
|
||||
sum = sum + UDefThetaH(std::size_t(ii));
|
||||
}
|
||||
l.unlock();
|
||||
// IPDF has been create so carry on
|
||||
G4double rndm = G4UniformRand();
|
||||
return(IPDFThetaH.GetEnergy(rndm));
|
||||
for(ii=0; ii<maxbin; ++ii)
|
||||
{
|
||||
vals[ii] = vals[ii]/sum;
|
||||
IPDFThetaH.InsertValues(bins[ii], vals[ii]);
|
||||
}
|
||||
IPDFThetaExist = true;
|
||||
}
|
||||
l.unlock();
|
||||
|
||||
// IPDF has been created so carry on
|
||||
//
|
||||
G4double rndm = G4UniformRand();
|
||||
return(IPDFThetaH.GetEnergy(rndm));
|
||||
}
|
||||
}
|
||||
|
||||
G4double G4SPSAngDistribution::GenerateUserDefPhi()
|
||||
{
|
||||
// Create cumulative histogram if not already done so. Then use RandFlat
|
||||
//::shoot to generate the output Theta value.
|
||||
// Create cumulative histogram if not already done so.
|
||||
// Then use RandFlat::shoot to generate the output Theta value.
|
||||
|
||||
if(UserDistType == "NULL" || UserDistType == "theta")
|
||||
{
|
||||
// No user defined phi distribution
|
||||
G4cout << "Error ***********************" << G4endl;
|
||||
G4cout << "UserDistType = " << UserDistType << G4endl;
|
||||
return(0.);
|
||||
}
|
||||
{
|
||||
// No user defined phi distribution
|
||||
G4cout << "Error ***********************" << G4endl;
|
||||
G4cout << "UserDistType = " << UserDistType << G4endl;
|
||||
return(0.);
|
||||
}
|
||||
else
|
||||
{
|
||||
// UserDistType = phi or both and so a phi distribution
|
||||
// is defined. This should be integrated if not already done.
|
||||
G4AutoLock l(&mutex);
|
||||
if(IPDFPhiExist == false)
|
||||
{
|
||||
// IPDF has not been created, so create it
|
||||
G4double bins[1024],vals[1024], sum;
|
||||
G4int ii;
|
||||
G4int maxbin = G4int(UDefPhiH.GetVectorLength());
|
||||
bins[0] = UDefPhiH.GetLowEdgeEnergy(size_t(0));
|
||||
vals[0] = UDefPhiH(size_t(0));
|
||||
sum = vals[0];
|
||||
for(ii=1;ii<maxbin;ii++)
|
||||
{
|
||||
bins[ii] = UDefPhiH.GetLowEdgeEnergy(size_t(ii));
|
||||
vals[ii] = UDefPhiH(size_t(ii)) + vals[ii-1];
|
||||
sum = sum + UDefPhiH(size_t(ii));
|
||||
}
|
||||
for(ii=0;ii<maxbin;ii++)
|
||||
{
|
||||
vals[ii] = vals[ii]/sum;
|
||||
IPDFPhiH.InsertValues(bins[ii], vals[ii]);
|
||||
}
|
||||
// Make IPDFPhiExist = true
|
||||
IPDFPhiExist = true;
|
||||
}
|
||||
l.unlock();
|
||||
// IPDF has been create so carry on
|
||||
G4double rndm = G4UniformRand();
|
||||
return(IPDFPhiH.GetEnergy(rndm));
|
||||
}
|
||||
}
|
||||
//
|
||||
void G4SPSAngDistribution::ReSetHist(G4String atype)
|
||||
{
|
||||
{
|
||||
// UserDistType = phi or both and so a phi distribution
|
||||
// is defined. This should be integrated if not already done.
|
||||
G4AutoLock l(&mutex);
|
||||
if (atype == "theta") {
|
||||
if(IPDFPhiExist == false)
|
||||
{
|
||||
// IPDF has not been created, so create it
|
||||
//
|
||||
G4double bins[1024],vals[1024], sum;
|
||||
G4int ii;
|
||||
G4int maxbin = G4int(UDefPhiH.GetVectorLength());
|
||||
bins[0] = UDefPhiH.GetLowEdgeEnergy(std::size_t(0));
|
||||
vals[0] = UDefPhiH(std::size_t(0));
|
||||
sum = vals[0];
|
||||
for(ii=1; ii<maxbin; ++ii)
|
||||
{
|
||||
bins[ii] = UDefPhiH.GetLowEdgeEnergy(std::size_t(ii));
|
||||
vals[ii] = UDefPhiH(std::size_t(ii)) + vals[ii-1];
|
||||
sum = sum + UDefPhiH(std::size_t(ii));
|
||||
}
|
||||
for(ii=0; ii<maxbin; ++ii)
|
||||
{
|
||||
vals[ii] = vals[ii]/sum;
|
||||
IPDFPhiH.InsertValues(bins[ii], vals[ii]);
|
||||
}
|
||||
IPDFPhiExist = true;
|
||||
}
|
||||
l.unlock();
|
||||
|
||||
// IPDF has been create so carry on
|
||||
//
|
||||
G4double rndm = G4UniformRand();
|
||||
|
||||
return(IPDFPhiH.GetEnergy(rndm));
|
||||
}
|
||||
}
|
||||
|
||||
void G4SPSAngDistribution::ReSetHist(const G4String& atype)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
if (atype == "theta")
|
||||
{
|
||||
UDefThetaH = IPDFThetaH = ZeroPhysVector ;
|
||||
IPDFThetaExist = false ;}
|
||||
else if (atype == "phi"){
|
||||
IPDFThetaExist = false ;
|
||||
}
|
||||
else if (atype == "phi")
|
||||
{
|
||||
UDefPhiH = IPDFPhiH = ZeroPhysVector ;
|
||||
IPDFPhiExist = false ;}
|
||||
else {
|
||||
IPDFPhiExist = false ;
|
||||
}
|
||||
else
|
||||
{
|
||||
G4cout << "Error, histtype not accepted " << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4ParticleMomentum G4SPSAngDistribution::GenerateOne()
|
||||
{
|
||||
//Local copy for thread safety
|
||||
// Local copy for thread safety
|
||||
//
|
||||
G4ParticleMomentum localM = particle_momentum_direction;
|
||||
|
||||
// Angular stuff
|
||||
//
|
||||
if(AngDistType == "iso")
|
||||
GenerateIsotropicFlux(localM);
|
||||
else if(AngDistType == "cos")
|
||||
@@ -674,12 +787,3 @@ G4ParticleMomentum G4SPSAngDistribution::GenerateOne()
|
||||
G4cout << "Error: AngDistType has unusual value" << G4endl;
|
||||
return localM;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+1805
-1705
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -23,27 +23,13 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4SingleParticleSource source implementation
|
||||
//
|
||||
// Author: Fan Lei, QinetiQ ltd. - 05/02/2004
|
||||
// Customer: ESA/ESTEC
|
||||
// Revision: Andrea Dotti, SLAC
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MODULE: G4SingleParticleSource.hh
|
||||
//
|
||||
// Version: 1.0
|
||||
// Date: 5/02/04
|
||||
// Author: Fan Lei
|
||||
// Organisation: QinetiQ ltd.
|
||||
// Customer: ESA/ESTEC
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CHANGE HISTORY
|
||||
// --------------
|
||||
//
|
||||
// Version 1.0, 05/02/2004, Fan Lei, Created.
|
||||
// Based on the G4GeneralParticleSource class in Geant4 v6.0
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#include <cmath>
|
||||
|
||||
#include "G4SingleParticleSource.hh"
|
||||
@@ -61,128 +47,140 @@
|
||||
#include "G4Track.hh"
|
||||
#include "G4AutoLock.hh"
|
||||
|
||||
G4SingleParticleSource::part_prop_t::part_prop_t() {
|
||||
//definition = G4Geantino::GeantinoDefinition();
|
||||
G4SingleParticleSource::part_prop_t::part_prop_t()
|
||||
{
|
||||
momentum_direction = G4ParticleMomentum(1,0,0);
|
||||
energy = 1.*MeV;
|
||||
position = G4ThreeVector();
|
||||
}
|
||||
|
||||
G4SingleParticleSource::G4SingleParticleSource() {
|
||||
// // Initialise all variables
|
||||
// // Position distribution Variables
|
||||
//
|
||||
NumberOfParticlesToBeGenerated = 1;
|
||||
definition = G4Geantino::GeantinoDefinition();
|
||||
// G4ThreeVector zero;
|
||||
// particle_momentum_direction = G4ParticleMomentum(1, 0, 0);
|
||||
// particle_energy = 1.0 * MeV;
|
||||
// particle_position = zero;
|
||||
// particle_time = 0.0;
|
||||
// particle_polarization = zero;
|
||||
charge = 0.0;
|
||||
time = 0;
|
||||
polarization = G4ThreeVector();
|
||||
G4SingleParticleSource::G4SingleParticleSource()
|
||||
{
|
||||
// Initialise all variables
|
||||
// Position distribution Variables
|
||||
|
||||
biasRndm = new G4SPSRandomGenerator();
|
||||
posGenerator = new G4SPSPosDistribution();
|
||||
posGenerator->SetBiasRndm(biasRndm);
|
||||
angGenerator = new G4SPSAngDistribution();
|
||||
angGenerator->SetPosDistribution(posGenerator);
|
||||
angGenerator->SetBiasRndm(biasRndm);
|
||||
eneGenerator = new G4SPSEneDistribution();
|
||||
eneGenerator->SetBiasRndm(biasRndm);
|
||||
NumberOfParticlesToBeGenerated = 1;
|
||||
definition = G4Geantino::GeantinoDefinition();
|
||||
|
||||
// verbosity
|
||||
verbosityLevel = 0;
|
||||
charge = 0.0;
|
||||
time = 0;
|
||||
polarization = G4ThreeVector();
|
||||
|
||||
biasRndm = new G4SPSRandomGenerator();
|
||||
posGenerator = new G4SPSPosDistribution();
|
||||
posGenerator->SetBiasRndm(biasRndm);
|
||||
angGenerator = new G4SPSAngDistribution();
|
||||
angGenerator->SetPosDistribution(posGenerator);
|
||||
angGenerator->SetBiasRndm(biasRndm);
|
||||
eneGenerator = new G4SPSEneDistribution();
|
||||
eneGenerator->SetBiasRndm(biasRndm);
|
||||
|
||||
verbosityLevel = 0;
|
||||
|
||||
G4MUTEXINIT(mutex);
|
||||
|
||||
G4MUTEXINIT(mutex);
|
||||
}
|
||||
|
||||
G4SingleParticleSource::~G4SingleParticleSource() {
|
||||
delete biasRndm;
|
||||
delete posGenerator;
|
||||
delete angGenerator;
|
||||
delete eneGenerator;
|
||||
G4MUTEXDESTROY(mutex);
|
||||
G4SingleParticleSource::~G4SingleParticleSource()
|
||||
{
|
||||
delete biasRndm;
|
||||
delete posGenerator;
|
||||
delete angGenerator;
|
||||
delete eneGenerator;
|
||||
|
||||
G4MUTEXDESTROY(mutex);
|
||||
}
|
||||
|
||||
void G4SingleParticleSource::SetVerbosity(int vL) {
|
||||
G4AutoLock l(&mutex);
|
||||
verbosityLevel = vL;
|
||||
posGenerator->SetVerbosity(vL);
|
||||
angGenerator->SetVerbosity(vL);
|
||||
eneGenerator->SetVerbosity(vL);
|
||||
//G4cout << "Verbosity Set to: " << verbosityLevel << G4endl;
|
||||
void G4SingleParticleSource::SetVerbosity(G4int vL)
|
||||
{
|
||||
G4AutoLock l(&mutex);
|
||||
verbosityLevel = vL;
|
||||
posGenerator->SetVerbosity(vL);
|
||||
angGenerator->SetVerbosity(vL);
|
||||
eneGenerator->SetVerbosity(vL);
|
||||
}
|
||||
|
||||
void G4SingleParticleSource::SetParticleDefinition(
|
||||
G4ParticleDefinition* aParticleDefinition) {
|
||||
definition = aParticleDefinition;
|
||||
charge = aParticleDefinition->GetPDGCharge();
|
||||
void G4SingleParticleSource::
|
||||
SetParticleDefinition(G4ParticleDefinition* aParticleDefinition)
|
||||
{
|
||||
definition = aParticleDefinition;
|
||||
charge = aParticleDefinition->GetPDGCharge();
|
||||
}
|
||||
|
||||
void G4SingleParticleSource::GeneratePrimaryVertex(G4Event *evt) {
|
||||
void G4SingleParticleSource::GeneratePrimaryVertex(G4Event* evt)
|
||||
{
|
||||
if (definition == nullptr)
|
||||
{
|
||||
// TODO: Should this rise an exception???
|
||||
return;
|
||||
}
|
||||
|
||||
//G4AutoLock l(&mutex);
|
||||
//part_prop_t& pp = ParticleProperties.Get();
|
||||
if (definition == NULL) {
|
||||
//TODO: Should this rise an exception???
|
||||
return ;
|
||||
}
|
||||
//return;
|
||||
if (verbosityLevel > 1)
|
||||
{
|
||||
G4cout << " NumberOfParticlesToBeGenerated: "
|
||||
<< NumberOfParticlesToBeGenerated << G4endl;
|
||||
}
|
||||
|
||||
if (verbosityLevel > 1)
|
||||
G4cout << " NumberOfParticlesToBeGenerated: "
|
||||
<<NumberOfParticlesToBeGenerated << G4endl;
|
||||
part_prop_t& pp = ParticleProperties.Get();
|
||||
|
||||
part_prop_t& pp = ParticleProperties.Get();
|
||||
// Position stuff
|
||||
pp.position = posGenerator->GenerateOne();
|
||||
// Position stuff
|
||||
pp.position = posGenerator->GenerateOne();
|
||||
|
||||
// create a new vertex
|
||||
G4PrimaryVertex* vertex = new G4PrimaryVertex(pp.position,time);
|
||||
// Create a new vertex
|
||||
G4PrimaryVertex* vertex = new G4PrimaryVertex(pp.position,time);
|
||||
|
||||
for (G4int i = 0; i < NumberOfParticlesToBeGenerated; i++) {
|
||||
// Angular stuff
|
||||
pp.momentum_direction = angGenerator->GenerateOne();
|
||||
// Energy stuff
|
||||
pp.energy = eneGenerator->GenerateOne(definition);
|
||||
for (G4int i=0; i<NumberOfParticlesToBeGenerated; ++i)
|
||||
{
|
||||
// Angular stuff
|
||||
pp.momentum_direction = angGenerator->GenerateOne();
|
||||
|
||||
if (verbosityLevel >= 2)
|
||||
G4cout << "Creating primaries and assigning to vertex" << G4endl;
|
||||
// create new primaries and set them to the vertex
|
||||
G4double mass = definition->GetPDGMass();
|
||||
G4PrimaryParticle* particle =
|
||||
new G4PrimaryParticle(definition);
|
||||
particle->SetKineticEnergy(pp.energy );
|
||||
particle->SetMass( mass );
|
||||
particle->SetMomentumDirection( pp.momentum_direction );
|
||||
particle->SetCharge( charge );
|
||||
particle->SetPolarization(polarization.x(),
|
||||
polarization.y(),
|
||||
polarization.z());
|
||||
if (verbosityLevel > 1) {
|
||||
G4cout << "Particle name: "
|
||||
<< definition->GetParticleName() << G4endl;
|
||||
G4cout << " Energy: " << pp.energy << G4endl;
|
||||
G4cout << " Position: " << pp.position << G4endl;
|
||||
G4cout << " Direction: " << pp.momentum_direction
|
||||
<< G4endl;
|
||||
}
|
||||
// Set bweight equal to the multiple of all non-zero weights
|
||||
G4double weight = eneGenerator->GetWeight()*biasRndm->GetBiasWeight();
|
||||
// pass it to primary particle
|
||||
particle->SetWeight(weight);
|
||||
// Energy stuff
|
||||
pp.energy = eneGenerator->GenerateOne(definition);
|
||||
|
||||
vertex->SetPrimary(particle);
|
||||
if (verbosityLevel >= 2)
|
||||
{
|
||||
G4cout << "Creating primaries and assigning to vertex" << G4endl;
|
||||
}
|
||||
|
||||
}
|
||||
// now pass the weight to the primary vertex. CANNOT be used here!
|
||||
// vertex->SetWeight(particle_weight);
|
||||
evt->AddPrimaryVertex(vertex);
|
||||
if (verbosityLevel > 1)
|
||||
G4cout << " Primary Vetex generated !" << G4endl;
|
||||
// Create new primaries and set them to the vertex
|
||||
//
|
||||
G4double mass = definition->GetPDGMass();
|
||||
G4PrimaryParticle* particle = new G4PrimaryParticle(definition);
|
||||
particle->SetKineticEnergy(pp.energy );
|
||||
particle->SetMass( mass );
|
||||
particle->SetMomentumDirection( pp.momentum_direction );
|
||||
particle->SetCharge( charge );
|
||||
particle->SetPolarization(polarization.x(),
|
||||
polarization.y(),
|
||||
polarization.z());
|
||||
if (verbosityLevel > 1)
|
||||
{
|
||||
G4cout << "Particle name: " << definition->GetParticleName() << G4endl;
|
||||
G4cout << " Energy: " << pp.energy << G4endl;
|
||||
G4cout << " Position: " << pp.position << G4endl;
|
||||
G4cout << " Direction: " << pp.momentum_direction << G4endl;
|
||||
}
|
||||
|
||||
// Set bweight equal to the multiple of all non-zero weights
|
||||
//
|
||||
G4double weight = eneGenerator->GetWeight()*biasRndm->GetBiasWeight();
|
||||
|
||||
if(eneGenerator->IfApplyEnergyWeight())
|
||||
{
|
||||
weight *= eneGenerator->GetArbEneWeight(pp.energy);
|
||||
}
|
||||
|
||||
// Pass it to primary particle
|
||||
//
|
||||
particle->SetWeight(weight);
|
||||
vertex->SetPrimary(particle);
|
||||
}
|
||||
|
||||
// Now pass the weight to the primary vertex. CANNOT be used here!
|
||||
// vertex->SetWeight(particle_weight);
|
||||
evt->AddPrimaryVertex(vertex);
|
||||
|
||||
if (verbosityLevel > 1)
|
||||
{
|
||||
G4cout << " Primary Vetex generated !" << G4endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// Author: S.Kamperis - 04/Oct/12
|
||||
// G4SmartTrackStack class implementation
|
||||
//
|
||||
// Author: S.Kamperis - 4 October 2012
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4SmartTrackStack.hh"
|
||||
|
||||
@@ -23,46 +23,52 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4StackChecker
|
||||
//
|
||||
//
|
||||
|
||||
// Author: Makoto Asai, 2003
|
||||
// --------------------------------------------------------------------
|
||||
#include "G4StackChecker.hh"
|
||||
#include "G4Track.hh"
|
||||
#include "G4EventManager.hh"
|
||||
#include "G4Event.hh"
|
||||
#include "G4ios.hh"
|
||||
|
||||
G4StackChecker::G4StackChecker():
|
||||
nullDirection(G4ThreeVector(0.0,0.0,0.0))
|
||||
G4StackChecker::G4StackChecker()
|
||||
: nullDirection(G4ThreeVector(0.0,0.0,0.0))
|
||||
{}
|
||||
|
||||
G4StackChecker::~G4StackChecker()
|
||||
{}
|
||||
|
||||
G4ClassificationOfNewTrack G4StackChecker::ClassifyNewTrack
|
||||
(const G4Track* track)
|
||||
G4ClassificationOfNewTrack
|
||||
G4StackChecker::ClassifyNewTrack(const G4Track* track)
|
||||
{
|
||||
G4ClassificationOfNewTrack result = fUrgent;
|
||||
G4double e = track->GetKineticEnergy();
|
||||
if ( (!(e < 0.0) && !(e > 0.0) && !(e == 0.0)) ||
|
||||
track->GetMomentumDirection() == nullDirection)
|
||||
{
|
||||
result = fKill;
|
||||
G4String nam = track->GetDefinition()->GetParticleName();
|
||||
G4cout << "### G4StackChecker: event# "
|
||||
<< (G4EventManager::GetEventManager())->GetConstCurrentEvent()->GetEventID()
|
||||
<< " unacceptable " << nam << " is killed in the stack" << G4endl;
|
||||
G4cout << "### " << nam << " have been produced by the process "
|
||||
<< track->GetCreatorProcess()->GetProcessName()
|
||||
<< " trackID= " << track->GetTrackID()
|
||||
<< " parentID= " << track->GetParentID()
|
||||
<< G4endl;
|
||||
G4cout << "### E= " << track->GetKineticEnergy()
|
||||
<< " position= " << track->GetPosition()
|
||||
<< " direction= " << track->GetMomentumDirection()
|
||||
<< " time= " << track->GetGlobalTime()
|
||||
<< G4endl;
|
||||
}
|
||||
if ( (!(e < 0.0) && !(e > 0.0) && !(e == 0.0))
|
||||
|| track->GetMomentumDirection() == nullDirection)
|
||||
{
|
||||
result = fKill;
|
||||
G4String nam = track->GetDefinition()->GetParticleName();
|
||||
G4cout << "### G4StackChecker: event# "
|
||||
<< (G4EventManager::GetEventManager())->GetConstCurrentEvent()->GetEventID()
|
||||
<< " unacceptable " << nam << " is killed in the stack" << G4endl;
|
||||
G4cout << "### " << nam << " have been produced by the process "
|
||||
<< track->GetCreatorProcess()->GetProcessName()
|
||||
<< " trackID= " << track->GetTrackID()
|
||||
<< " parentID= " << track->GetParentID()
|
||||
<< G4endl;
|
||||
G4cout << "### E= " << track->GetKineticEnergy()
|
||||
<< " position= " << track->GetPosition()
|
||||
<< " direction= " << track->GetMomentumDirection()
|
||||
<< " time= " << track->GetGlobalTime()
|
||||
<< G4endl;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void G4StackChecker::NewStage()
|
||||
{}
|
||||
|
||||
void G4StackChecker::PrepareNewEvent()
|
||||
{}
|
||||
|
||||
+205
-118
@@ -23,28 +23,34 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4StackManager class implementation
|
||||
//
|
||||
//
|
||||
//
|
||||
// Last Modification : 09/Dec/96 M.Asai
|
||||
//
|
||||
// Author: Makoto Asai, 1996
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4StackManager.hh"
|
||||
#include "G4StackingMessenger.hh"
|
||||
#include "G4VTrajectory.hh"
|
||||
#include "evmandefs.hh"
|
||||
#include "G4ios.hh"
|
||||
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VProcess.hh"
|
||||
|
||||
// Needed for temporal service
|
||||
//
|
||||
#include "G4ParticleTable.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4ProcessVector.hh"
|
||||
|
||||
G4StackManager::G4StackManager()
|
||||
:userStackingAction(0),verboseLevel(0),numberOfAdditionalWaitingStacks(0)
|
||||
{
|
||||
theMessenger = new G4StackingMessenger(this);
|
||||
#ifdef G4_USESMARTSTACK
|
||||
urgentStack = new G4SmartTrackStack;
|
||||
// G4cout<<"+++ G4StackManager uses G4SmartTrackStack. +++"<<G4endl;
|
||||
// G4cout << "+++ G4StackManager uses G4SmartTrackStack. +++" << G4endl;
|
||||
#else
|
||||
urgentStack = new G4TrackStack(5000);
|
||||
// G4cout<<"+++ G4StackManager uses ordinary G4TrackStack. +++"<<G4endl;
|
||||
// G4cout << "+++ G4StackManager uses ordinary G4TrackStack. +++" << G4endl;
|
||||
#endif
|
||||
waitingStack = new G4TrackStack(1000);
|
||||
postponeStack = new G4TrackStack(1000);
|
||||
@@ -52,7 +58,7 @@ G4StackManager::G4StackManager()
|
||||
|
||||
G4StackManager::~G4StackManager()
|
||||
{
|
||||
if(userStackingAction) delete userStackingAction;
|
||||
if(userStackingAction) { delete userStackingAction; }
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if(verboseLevel>0)
|
||||
@@ -66,45 +72,40 @@ G4StackManager::~G4StackManager()
|
||||
delete waitingStack;
|
||||
delete postponeStack;
|
||||
delete theMessenger;
|
||||
if(numberOfAdditionalWaitingStacks>0) {
|
||||
for(int i=0;i<numberOfAdditionalWaitingStacks;i++) {
|
||||
if(numberOfAdditionalWaitingStacks>0)
|
||||
{
|
||||
for(G4int i=0; i<numberOfAdditionalWaitingStacks; ++i)
|
||||
{
|
||||
delete additionalWaitingStacks[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const G4StackManager & G4StackManager::operator=
|
||||
(const G4StackManager &) { return *this; }
|
||||
G4bool G4StackManager::operator==(const G4StackManager &)
|
||||
const{ return false; }
|
||||
G4bool G4StackManager::operator!=(const G4StackManager &)
|
||||
const{ return true; }
|
||||
|
||||
#include "G4ParticleDefinition.hh"
|
||||
#include "G4VProcess.hh"
|
||||
|
||||
//Needed for temporal service
|
||||
#include "G4ParticleTable.hh"
|
||||
#include "G4ProcessManager.hh"
|
||||
#include "G4ProcessVector.hh"
|
||||
|
||||
G4int G4StackManager::PushOneTrack(G4Track *newTrack,G4VTrajectory *newTrajectory)
|
||||
G4int G4StackManager::
|
||||
PushOneTrack(G4Track* newTrack, G4VTrajectory* newTrajectory)
|
||||
{
|
||||
const G4ParticleDefinition* pd = newTrack->GetParticleDefinition();
|
||||
if(pd->GetParticleDefinitionID() < 0)
|
||||
{
|
||||
G4ExceptionDescription ED;
|
||||
ED << "A track without proper process manager is pushed into the track stack.\n"
|
||||
ED << "A track without proper process manager is pushed \
|
||||
into the track stack.\n"
|
||||
<< " Particle name : " << pd->GetParticleName() << " -- ";
|
||||
if(newTrack->GetParentID()<0)
|
||||
{ ED << "created by a primary particle generator."; }
|
||||
{
|
||||
ED << "created by a primary particle generator.";
|
||||
}
|
||||
else
|
||||
{
|
||||
const G4VProcess* vp = newTrack->GetCreatorProcess();
|
||||
if(vp)
|
||||
{ ED << "created by " << vp->GetProcessName() << "."; }
|
||||
{
|
||||
ED << "created by " << vp->GetProcessName() << ".";
|
||||
}
|
||||
else
|
||||
{ ED << "creaded by unknown process."; }
|
||||
{
|
||||
ED << "creaded by unknown process.";
|
||||
}
|
||||
}
|
||||
G4Exception("G4StackManager::PushOneTrack","Event10051",
|
||||
FatalException,ED);
|
||||
@@ -112,9 +113,11 @@ G4int G4StackManager::PushOneTrack(G4Track *newTrack,G4VTrajectory *newTrajector
|
||||
return GetNUrgentTrack();
|
||||
}
|
||||
|
||||
G4ClassificationOfNewTrack classification = DefaultClassification( newTrack );
|
||||
if(userStackingAction)
|
||||
{ classification = userStackingAction->ClassifyNewTrack( newTrack ); }
|
||||
G4ClassificationOfNewTrack classification = DefaultClassification( newTrack );
|
||||
if(userStackingAction != nullptr)
|
||||
{
|
||||
classification = userStackingAction->ClassifyNewTrack( newTrack );
|
||||
}
|
||||
|
||||
if(classification==fKill) // delete newTrack without stacking
|
||||
{
|
||||
@@ -122,8 +125,8 @@ G4int G4StackManager::PushOneTrack(G4Track *newTrack,G4VTrajectory *newTrajector
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4cout << " ---> G4Track " << newTrack << " (trackID "
|
||||
<< newTrack->GetTrackID() << ", parentID "
|
||||
<< newTrack->GetParentID() << ") is not to be stored." << G4endl;
|
||||
<< newTrack->GetTrackID() << ", parentID "
|
||||
<< newTrack->GetParentID() << ") is not to be stored." << G4endl;
|
||||
}
|
||||
#endif
|
||||
delete newTrack;
|
||||
@@ -145,55 +148,71 @@ G4int G4StackManager::PushOneTrack(G4Track *newTrack,G4VTrajectory *newTrajector
|
||||
break;
|
||||
default:
|
||||
G4int i = classification - 10;
|
||||
if(i<1||i>numberOfAdditionalWaitingStacks) {
|
||||
if(i<1 || i>numberOfAdditionalWaitingStacks)
|
||||
{
|
||||
G4ExceptionDescription ED;
|
||||
ED << "invalid classification " << classification << G4endl;
|
||||
G4Exception("G4StackManager::PushOneTrack","Event0051",
|
||||
FatalException,ED);
|
||||
} else {
|
||||
G4Exception("G4StackManager::PushOneTrack", "Event0051",
|
||||
FatalException,ED);
|
||||
}
|
||||
else
|
||||
{
|
||||
additionalWaitingStacks[i-1]->PushToStack( newStackedTrack );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return GetNUrgentTrack();
|
||||
}
|
||||
|
||||
|
||||
G4Track * G4StackManager::PopNextTrack(G4VTrajectory**newTrajectory)
|
||||
G4Track* G4StackManager::PopNextTrack(G4VTrajectory** newTrajectory)
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4cout << "### pop requested out of "
|
||||
<< GetNUrgentTrack() << " stacked tracks." << G4endl;
|
||||
<< GetNUrgentTrack() << " stacked tracks." << G4endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
while( GetNUrgentTrack() == 0 )
|
||||
{
|
||||
#ifdef G4VERBOSE
|
||||
if( verboseLevel > 1 ) G4cout << "### " << GetNWaitingTrack()
|
||||
<< " waiting tracks are re-classified to" << G4endl;
|
||||
if( verboseLevel > 1 )
|
||||
{
|
||||
G4cout << "### " << GetNWaitingTrack()
|
||||
<< " waiting tracks are re-classified to" << G4endl;
|
||||
}
|
||||
#endif
|
||||
waitingStack->TransferTo(urgentStack);
|
||||
if(numberOfAdditionalWaitingStacks>0) {
|
||||
for(int i=0;i<numberOfAdditionalWaitingStacks;i++) {
|
||||
if(i==0) {
|
||||
if(numberOfAdditionalWaitingStacks>0)
|
||||
{
|
||||
for(G4int i=0; i<numberOfAdditionalWaitingStacks; ++i)
|
||||
{
|
||||
if(i==0)
|
||||
{
|
||||
additionalWaitingStacks[0]->TransferTo(waitingStack);
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
additionalWaitingStacks[i]->TransferTo(additionalWaitingStacks[i-1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(userStackingAction) userStackingAction->NewStage();
|
||||
if(userStackingAction != nullptr)
|
||||
{
|
||||
userStackingAction->NewStage();
|
||||
}
|
||||
|
||||
#ifdef G4VERBOSE
|
||||
if( verboseLevel > 1 ) G4cout << " " << GetNUrgentTrack()
|
||||
<< " urgent tracks and " << GetNWaitingTrack()
|
||||
<< " waiting tracks." << G4endl;
|
||||
if( verboseLevel > 1 )
|
||||
G4cout << " " << GetNUrgentTrack()
|
||||
<< " urgent tracks and " << GetNWaitingTrack()
|
||||
<< " waiting tracks." << G4endl;
|
||||
#endif
|
||||
if( ( GetNUrgentTrack()==0 ) && ( GetNWaitingTrack()==0 ) ) return 0;
|
||||
if( ( GetNUrgentTrack()==0 ) && ( GetNWaitingTrack()==0 ) )
|
||||
return 0;
|
||||
}
|
||||
|
||||
G4StackedTrack selectedStackedTrack = urgentStack->PopFromStack();
|
||||
@@ -219,7 +238,7 @@ void G4StackManager::ReClassify()
|
||||
G4StackedTrack aStackedTrack;
|
||||
G4TrackStack tmpStack;
|
||||
|
||||
if( !userStackingAction ) return;
|
||||
if( userStackingAction == nullptr ) return;
|
||||
if( GetNUrgentTrack() == 0 ) return;
|
||||
|
||||
urgentStack->TransferTo(&tmpStack);
|
||||
@@ -245,12 +264,15 @@ void G4StackManager::ReClassify()
|
||||
break;
|
||||
default:
|
||||
G4int i = classification - 10;
|
||||
if(i<1||i>numberOfAdditionalWaitingStacks) {
|
||||
if(i<1||i>numberOfAdditionalWaitingStacks)
|
||||
{
|
||||
G4ExceptionDescription ED;
|
||||
ED << "invalid classification " << classification << G4endl;
|
||||
G4Exception("G4StackManager::ReClassify","Event0052",
|
||||
FatalException,ED);
|
||||
} else {
|
||||
G4Exception("G4StackManager::ReClassify", "Event0052",
|
||||
FatalException, ED);
|
||||
}
|
||||
else
|
||||
{
|
||||
additionalWaitingStacks[i-1]->PushToStack( aStackedTrack );
|
||||
}
|
||||
break;
|
||||
@@ -260,9 +282,15 @@ void G4StackManager::ReClassify()
|
||||
|
||||
G4int G4StackManager::PrepareNewEvent()
|
||||
{
|
||||
if(userStackingAction) userStackingAction->PrepareNewEvent();
|
||||
if(userStackingAction)
|
||||
{
|
||||
userStackingAction->PrepareNewEvent();
|
||||
}
|
||||
|
||||
urgentStack->clearAndDestroy(); // Set the urgentStack in a defined state. Not doing it would affect reproducibility.
|
||||
// Set the urgentStack in a defined state. Not doing it would
|
||||
// affect reproducibility
|
||||
//
|
||||
urgentStack->clearAndDestroy();
|
||||
|
||||
G4int n_passedFromPrevious = 0;
|
||||
|
||||
@@ -288,9 +316,13 @@ G4int G4StackManager::PrepareNewEvent()
|
||||
aTrack->SetParentID(-1);
|
||||
G4ClassificationOfNewTrack classification;
|
||||
if(userStackingAction)
|
||||
{ classification = userStackingAction->ClassifyNewTrack( aTrack ); }
|
||||
{
|
||||
classification = userStackingAction->ClassifyNewTrack( aTrack );
|
||||
}
|
||||
else
|
||||
{ classification = DefaultClassification( aTrack ); }
|
||||
{
|
||||
classification = DefaultClassification( aTrack );
|
||||
}
|
||||
|
||||
if(classification==fKill)
|
||||
{
|
||||
@@ -313,12 +345,15 @@ G4int G4StackManager::PrepareNewEvent()
|
||||
break;
|
||||
default:
|
||||
G4int i = classification - 10;
|
||||
if(i<1||i>numberOfAdditionalWaitingStacks) {
|
||||
if(i<1||i>numberOfAdditionalWaitingStacks)
|
||||
{
|
||||
G4ExceptionDescription ED;
|
||||
ED << "invalid classification " << classification << G4endl;
|
||||
G4Exception("G4StackManager::PrepareNewEvent","Event0053",
|
||||
FatalException,ED);
|
||||
} else {
|
||||
G4Exception("G4StackManager::PrepareNewEvent", "Event0053",
|
||||
FatalException, ED);
|
||||
}
|
||||
else
|
||||
{
|
||||
additionalWaitingStacks[i-1]->PushToStack( aStackedTrack );
|
||||
}
|
||||
break;
|
||||
@@ -326,7 +361,6 @@ G4int G4StackManager::PrepareNewEvent()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n_passedFromPrevious;
|
||||
}
|
||||
|
||||
@@ -334,7 +368,7 @@ void G4StackManager::SetNumberOfAdditionalWaitingStacks(G4int iAdd)
|
||||
{
|
||||
if(iAdd > numberOfAdditionalWaitingStacks)
|
||||
{
|
||||
for(int i=numberOfAdditionalWaitingStacks;i<iAdd;i++)
|
||||
for(G4int i=numberOfAdditionalWaitingStacks; i<iAdd; ++i)
|
||||
{
|
||||
G4TrackStack* newStack = new G4TrackStack;
|
||||
additionalWaitingStacks.push_back(newStack);
|
||||
@@ -343,22 +377,24 @@ void G4StackManager::SetNumberOfAdditionalWaitingStacks(G4int iAdd)
|
||||
}
|
||||
else if (iAdd < numberOfAdditionalWaitingStacks)
|
||||
{
|
||||
for(int i=numberOfAdditionalWaitingStacks;i>iAdd;i--)
|
||||
for(G4int i=numberOfAdditionalWaitingStacks; i>iAdd; --i)
|
||||
{
|
||||
delete additionalWaitingStacks[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void G4StackManager::TransferStackedTracks(G4ClassificationOfNewTrack origin, G4ClassificationOfNewTrack destination)
|
||||
void G4StackManager::
|
||||
TransferStackedTracks(G4ClassificationOfNewTrack origin,
|
||||
G4ClassificationOfNewTrack destination)
|
||||
{
|
||||
if(origin==destination) return;
|
||||
if(origin==fKill) return;
|
||||
G4TrackStack* originStack = 0;
|
||||
G4TrackStack* originStack = nullptr;
|
||||
switch(origin)
|
||||
{
|
||||
case fUrgent:
|
||||
originStack = 0;
|
||||
originStack = nullptr;
|
||||
break;
|
||||
case fWaiting:
|
||||
originStack = waitingStack;
|
||||
@@ -367,25 +403,32 @@ void G4StackManager::TransferStackedTracks(G4ClassificationOfNewTrack origin, G4
|
||||
originStack = postponeStack;
|
||||
break;
|
||||
default:
|
||||
int i = origin - 10;
|
||||
if(i<=numberOfAdditionalWaitingStacks) originStack = additionalWaitingStacks[i-1];
|
||||
G4int i = origin - 10;
|
||||
if(i<=numberOfAdditionalWaitingStacks)
|
||||
{
|
||||
originStack = additionalWaitingStacks[i-1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(destination==fKill)
|
||||
{
|
||||
if(originStack)
|
||||
{ originStack->clearAndDestroy(); }
|
||||
if(originStack != nullptr)
|
||||
{
|
||||
originStack->clearAndDestroy();
|
||||
}
|
||||
else
|
||||
{ urgentStack->clearAndDestroy(); }
|
||||
{
|
||||
urgentStack->clearAndDestroy();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
G4TrackStack* targetStack = 0;
|
||||
G4TrackStack* targetStack = nullptr;
|
||||
switch(destination)
|
||||
{
|
||||
case fUrgent:
|
||||
targetStack = 0;
|
||||
targetStack = nullptr;
|
||||
break;
|
||||
case fWaiting:
|
||||
targetStack = waitingStack;
|
||||
@@ -394,32 +437,43 @@ void G4StackManager::TransferStackedTracks(G4ClassificationOfNewTrack origin, G4
|
||||
targetStack = postponeStack;
|
||||
break;
|
||||
default:
|
||||
int i = destination - 10;
|
||||
if(i<=numberOfAdditionalWaitingStacks) targetStack = additionalWaitingStacks[i-1];
|
||||
G4int i = destination - 10;
|
||||
if(i<=numberOfAdditionalWaitingStacks)
|
||||
{
|
||||
targetStack = additionalWaitingStacks[i-1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(originStack)
|
||||
if(originStack != nullptr)
|
||||
{
|
||||
if(targetStack)
|
||||
{ originStack->TransferTo(targetStack); }
|
||||
if(targetStack != nullptr)
|
||||
{
|
||||
originStack->TransferTo(targetStack);
|
||||
}
|
||||
else
|
||||
{ originStack->TransferTo(urgentStack); }
|
||||
{
|
||||
originStack->TransferTo(urgentStack);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ urgentStack->TransferTo(targetStack); }
|
||||
{
|
||||
urgentStack->TransferTo(targetStack);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void G4StackManager::TransferOneStackedTrack(G4ClassificationOfNewTrack origin, G4ClassificationOfNewTrack destination)
|
||||
void G4StackManager::
|
||||
TransferOneStackedTrack(G4ClassificationOfNewTrack origin,
|
||||
G4ClassificationOfNewTrack destination)
|
||||
{
|
||||
if(origin==destination) return;
|
||||
if(origin==fKill) return;
|
||||
G4TrackStack* originStack = 0;
|
||||
G4TrackStack* originStack = nullptr;
|
||||
switch(origin)
|
||||
{
|
||||
case fUrgent:
|
||||
originStack = 0;
|
||||
originStack = nullptr;
|
||||
break;
|
||||
case fWaiting:
|
||||
originStack = waitingStack;
|
||||
@@ -428,20 +482,25 @@ void G4StackManager::TransferOneStackedTrack(G4ClassificationOfNewTrack origin,
|
||||
originStack = postponeStack;
|
||||
break;
|
||||
default:
|
||||
int i = origin - 10;
|
||||
if(i<=numberOfAdditionalWaitingStacks) originStack = additionalWaitingStacks[i-1];
|
||||
G4int i = origin - 10;
|
||||
if(i<=numberOfAdditionalWaitingStacks)
|
||||
{
|
||||
originStack = additionalWaitingStacks[i-1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
G4StackedTrack aStackedTrack;
|
||||
if(destination==fKill)
|
||||
{
|
||||
if( originStack && originStack->GetNTrack() ) {
|
||||
if( originStack != nullptr && originStack->GetNTrack() )
|
||||
{
|
||||
aStackedTrack = originStack->PopFromStack();
|
||||
delete aStackedTrack.GetTrack();
|
||||
delete aStackedTrack.GetTrajectory();
|
||||
}
|
||||
else if (urgentStack->GetNTrack() ) {
|
||||
else if (urgentStack->GetNTrack() )
|
||||
{
|
||||
aStackedTrack = urgentStack->PopFromStack();
|
||||
delete aStackedTrack.GetTrack();
|
||||
delete aStackedTrack.GetTrajectory();
|
||||
@@ -449,11 +508,11 @@ void G4StackManager::TransferOneStackedTrack(G4ClassificationOfNewTrack origin,
|
||||
}
|
||||
else
|
||||
{
|
||||
G4TrackStack* targetStack = 0;
|
||||
G4TrackStack* targetStack = nullptr;
|
||||
switch(destination)
|
||||
{
|
||||
case fUrgent:
|
||||
targetStack = 0;
|
||||
targetStack = nullptr;
|
||||
break;
|
||||
case fWaiting:
|
||||
targetStack = waitingStack;
|
||||
@@ -462,16 +521,21 @@ void G4StackManager::TransferOneStackedTrack(G4ClassificationOfNewTrack origin,
|
||||
targetStack = postponeStack;
|
||||
break;
|
||||
default:
|
||||
int i = destination - 10;
|
||||
if(i<=numberOfAdditionalWaitingStacks) targetStack = additionalWaitingStacks[i-1];
|
||||
G4int i = destination - 10;
|
||||
if(i<=numberOfAdditionalWaitingStacks)
|
||||
{
|
||||
targetStack = additionalWaitingStacks[i-1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(originStack && originStack->GetNTrack()) {
|
||||
if(originStack && originStack->GetNTrack())
|
||||
{
|
||||
aStackedTrack = originStack->PopFromStack();
|
||||
if(targetStack) { targetStack->PushToStack(aStackedTrack); }
|
||||
else { urgentStack->PushToStack(aStackedTrack); }
|
||||
}
|
||||
else if(urgentStack->GetNTrack()) {
|
||||
else if(urgentStack->GetNTrack())
|
||||
{
|
||||
aStackedTrack = urgentStack->PopFromStack();
|
||||
if(targetStack) { targetStack->PushToStack(aStackedTrack); }
|
||||
else { urgentStack->PushToStack(aStackedTrack); }
|
||||
@@ -484,7 +548,10 @@ void G4StackManager::clear()
|
||||
{
|
||||
ClearUrgentStack();
|
||||
ClearWaitingStack();
|
||||
for(int i=1;i<=numberOfAdditionalWaitingStacks;i++) {ClearWaitingStack(i);}
|
||||
for(G4int i=1; i<=numberOfAdditionalWaitingStacks; ++i)
|
||||
{
|
||||
ClearWaitingStack(i);
|
||||
}
|
||||
}
|
||||
|
||||
void G4StackManager::ClearUrgentStack()
|
||||
@@ -492,12 +559,18 @@ void G4StackManager::ClearUrgentStack()
|
||||
urgentStack->clearAndDestroy();
|
||||
}
|
||||
|
||||
void G4StackManager::ClearWaitingStack(int i)
|
||||
void G4StackManager::ClearWaitingStack(G4int i)
|
||||
{
|
||||
if(i==0) {
|
||||
if(i==0)
|
||||
{
|
||||
waitingStack->clearAndDestroy();
|
||||
} else {
|
||||
if(i<=numberOfAdditionalWaitingStacks) additionalWaitingStacks[i-1]->clearAndDestroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(i<=numberOfAdditionalWaitingStacks)
|
||||
{
|
||||
additionalWaitingStacks[i-1]->clearAndDestroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,8 +581,13 @@ void G4StackManager::ClearPostponeStack()
|
||||
|
||||
G4int G4StackManager::GetNTotalTrack() const
|
||||
{
|
||||
int n = urgentStack->GetNTrack() + waitingStack->GetNTrack() + postponeStack->GetNTrack();
|
||||
for(int i=1;i<=numberOfAdditionalWaitingStacks;i++) {n += additionalWaitingStacks[i-1]->GetNTrack();}
|
||||
G4int n = urgentStack->GetNTrack()
|
||||
+ waitingStack->GetNTrack()
|
||||
+ postponeStack->GetNTrack();
|
||||
for(G4int i=1; i<=numberOfAdditionalWaitingStacks; ++i)
|
||||
{
|
||||
n += additionalWaitingStacks[i-1]->GetNTrack();
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -520,9 +598,16 @@ G4int G4StackManager::GetNUrgentTrack() const
|
||||
|
||||
G4int G4StackManager::GetNWaitingTrack(int i) const
|
||||
{
|
||||
if(i==0) { return waitingStack->GetNTrack(); }
|
||||
else {
|
||||
if(i<=numberOfAdditionalWaitingStacks) { return additionalWaitingStacks[i-1]->GetNTrack();}
|
||||
if(i==0)
|
||||
{
|
||||
return waitingStack->GetNTrack();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(i<=numberOfAdditionalWaitingStacks)
|
||||
{
|
||||
return additionalWaitingStacks[i-1]->GetNTrack();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -539,18 +624,20 @@ void G4StackManager::SetVerboseLevel( G4int const value )
|
||||
|
||||
void G4StackManager::SetUserStackingAction(G4UserStackingAction* value)
|
||||
{
|
||||
userStackingAction = value;
|
||||
if(userStackingAction) userStackingAction->SetStackManager(this);
|
||||
userStackingAction = value;
|
||||
if(userStackingAction)
|
||||
{
|
||||
userStackingAction->SetStackManager(this);
|
||||
}
|
||||
}
|
||||
|
||||
G4ClassificationOfNewTrack G4StackManager::DefaultClassification(G4Track *aTrack)
|
||||
G4ClassificationOfNewTrack G4StackManager::
|
||||
DefaultClassification(G4Track* aTrack)
|
||||
{
|
||||
G4ClassificationOfNewTrack classification = fUrgent;
|
||||
if( aTrack->GetTrackStatus() == fPostponeToNextEvent )
|
||||
{ classification = fPostpone; }
|
||||
{
|
||||
classification = fPostpone;
|
||||
}
|
||||
return classification;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4StackingMessenger class implementation
|
||||
//
|
||||
//
|
||||
// Author: Makoto Asai, 1996
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4StackingMessenger.hh"
|
||||
@@ -34,8 +35,8 @@
|
||||
#include "G4UIcmdWithAnInteger.hh"
|
||||
#include "G4ios.hh"
|
||||
|
||||
G4StackingMessenger::G4StackingMessenger(G4StackManager * fCont)
|
||||
:fContainer(fCont)
|
||||
G4StackingMessenger::G4StackingMessenger(G4StackManager* fCont)
|
||||
: fContainer(fCont)
|
||||
{
|
||||
stackDir = new G4UIdirectory("/event/stack/");
|
||||
stackDir->SetGuidance("Stack control commands.");
|
||||
@@ -61,7 +62,6 @@ G4StackingMessenger::G4StackingMessenger(G4StackManager * fCont)
|
||||
verboseCmd->SetGuidance(" 1 : Minimum statistics");
|
||||
verboseCmd->SetGuidance(" 2 : Detailed reports");
|
||||
verboseCmd->SetGuidance("Note - this value is overwritten by /event/verbose command.");
|
||||
|
||||
}
|
||||
|
||||
G4StackingMessenger::~G4StackingMessenger()
|
||||
@@ -72,15 +72,20 @@ G4StackingMessenger::~G4StackingMessenger()
|
||||
delete stackDir;
|
||||
}
|
||||
|
||||
void G4StackingMessenger::SetNewValue(G4UIcommand * command,G4String newValues)
|
||||
void G4StackingMessenger::SetNewValue(G4UIcommand* command, G4String newValues)
|
||||
{
|
||||
if( command==statusCmd )
|
||||
{
|
||||
G4cout << "========================== Current status of the stack =====" << G4endl;
|
||||
G4cout << " Number of tracks in the stack" << G4endl;
|
||||
G4cout << " Urgent stack : " << fContainer->GetNUrgentTrack() << G4endl;
|
||||
G4cout << " Waiting stack : " << fContainer->GetNWaitingTrack() << G4endl;
|
||||
G4cout << " Postponed stack : " << fContainer->GetNPostponedTrack() << G4endl;
|
||||
G4cout << "========================== Current status of the stack ====="
|
||||
<< G4endl;
|
||||
G4cout << " Number of tracks in the stack"
|
||||
<< G4endl;
|
||||
G4cout << " Urgent stack : " << fContainer->GetNUrgentTrack()
|
||||
<< G4endl;
|
||||
G4cout << " Waiting stack : " << fContainer->GetNWaitingTrack()
|
||||
<< G4endl;
|
||||
G4cout << " Postponed stack : " << fContainer->GetNPostponedTrack()
|
||||
<< G4endl;
|
||||
}
|
||||
else if( command==clearCmd )
|
||||
{
|
||||
@@ -109,4 +114,3 @@ void G4StackingMessenger::SetNewValue(G4UIcommand * command,G4String newValues)
|
||||
fContainer->SetVerboseLevel(verboseCmd->GetNewIntValue(newValues));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4TrackStack class implementation
|
||||
//
|
||||
// Author: Makoto Asai (SLAC)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
@@ -55,7 +57,7 @@ void G4TrackStack::TransferTo(G4TrackStack* aStack)
|
||||
clear();
|
||||
}
|
||||
|
||||
void G4TrackStack::TransferTo(G4SmartTrackStack * aStack)
|
||||
void G4TrackStack::TransferTo(G4SmartTrackStack* aStack)
|
||||
{
|
||||
while (size())
|
||||
{
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4TrajectoryContainer class implementation
|
||||
//
|
||||
// Author: Makoto Asai (SLAC)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4UserEventAction class implementation
|
||||
//
|
||||
//
|
||||
// Author: Makoto Asai (SLAC)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4UserEventAction.hh"
|
||||
#include "G4Event.hh"
|
||||
@@ -51,6 +53,11 @@ G4UserEventAction::G4UserEventAction()
|
||||
G4UserEventAction::~G4UserEventAction()
|
||||
{;}
|
||||
|
||||
void G4UserEventAction::SetEventManager(G4EventManager* value)
|
||||
{
|
||||
fpEventManager = value;
|
||||
}
|
||||
|
||||
void G4UserEventAction::BeginOfEventAction(const G4Event*)
|
||||
{;}
|
||||
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4UserStackingAction class implementation
|
||||
//
|
||||
//
|
||||
// Author: Makoto Asai (SLAC)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
#include "G4UserStackingAction.hh"
|
||||
#include "G4Track.hh"
|
||||
@@ -32,29 +34,28 @@
|
||||
#include "G4ParticleTable.hh"
|
||||
#include "globals.hh"
|
||||
|
||||
|
||||
G4UserStackingAction::G4UserStackingAction()
|
||||
{
|
||||
if(!(G4ParticleTable::GetParticleTable()->GetReadiness()))
|
||||
{
|
||||
G4String msg;
|
||||
msg = " You are instantiating G4UserStackingAction BEFORE your\n";
|
||||
msg += "G4VUserPhysicsList is instantiated and assigned to G4RunManager.\n";
|
||||
msg += " Such an instantiation is prohibited by Geant4 version 8.0. To fix this problem,\n";
|
||||
msg += "please make sure that your main() instantiates G4VUserPhysicsList AND\n";
|
||||
msg += "set it to G4RunManager before instantiating other user action classes\n";
|
||||
msg += "such as G4UserStackingAction.";
|
||||
G4Exception("G4UserStackingAction::G4UserStackingAction()",
|
||||
"Event0031",FatalException,msg);
|
||||
}
|
||||
if(!(G4ParticleTable::GetParticleTable()->GetReadiness()))
|
||||
{
|
||||
G4String msg;
|
||||
msg = "You are instantiating G4UserStackingAction BEFORE your \n";
|
||||
msg += "G4VUserPhysicsList is instantiated and assigned to G4RunManager.\n";
|
||||
msg += "Such an instantiation is prohibited since Geant4 version 8.0.\n";
|
||||
msg += "To fix this problem, please make sure that your main() \n";
|
||||
msg += "instantiates G4VUserPhysicsList AND set it to G4RunManager \n";
|
||||
msg += "before instantiating other user action classes such as \n";
|
||||
msg += "G4UserStackingAction.";
|
||||
G4Exception("G4UserStackingAction::G4UserStackingAction()",
|
||||
"Event0031", FatalException, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
G4UserStackingAction::~G4UserStackingAction()
|
||||
{;}
|
||||
|
||||
G4ClassificationOfNewTrack G4UserStackingAction::ClassifyNewTrack
|
||||
(const G4Track*)
|
||||
G4ClassificationOfNewTrack
|
||||
G4UserStackingAction::ClassifyNewTrack(const G4Track*)
|
||||
{
|
||||
return fUrgent;
|
||||
}
|
||||
@@ -64,5 +65,3 @@ void G4UserStackingAction::NewStage()
|
||||
|
||||
void G4UserStackingAction::PrepareNewEvent()
|
||||
{;}
|
||||
|
||||
|
||||
|
||||
@@ -23,34 +23,31 @@
|
||||
// * acceptance of all terms of the Geant4 Software license. *
|
||||
// ********************************************************************
|
||||
//
|
||||
// G4VPrimaryGenerator class implementation
|
||||
//
|
||||
//
|
||||
// Author: Makoto Asai (SLAC)
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// G4VPrimaryGenerator
|
||||
#include "G4VPrimaryGenerator.hh"
|
||||
|
||||
G4VPrimaryGenerator::G4VPrimaryGenerator() : particle_time(0.)
|
||||
{;}
|
||||
|
||||
G4VPrimaryGenerator::~G4VPrimaryGenerator()
|
||||
{;}
|
||||
|
||||
#include "G4TransportationManager.hh"
|
||||
#include "G4Navigator.hh"
|
||||
#include "G4VPhysicalVolume.hh"
|
||||
#include "G4VSolid.hh"
|
||||
|
||||
G4bool G4VPrimaryGenerator::CheckVertexInsideWorld
|
||||
(const G4ThreeVector& pos)
|
||||
G4VPrimaryGenerator::G4VPrimaryGenerator()
|
||||
{;}
|
||||
|
||||
G4VPrimaryGenerator::~G4VPrimaryGenerator()
|
||||
{;}
|
||||
|
||||
G4bool G4VPrimaryGenerator::CheckVertexInsideWorld(const G4ThreeVector& pos)
|
||||
{
|
||||
G4Navigator* navigator= G4TransportationManager::GetTransportationManager()
|
||||
-> GetNavigatorForTracking();
|
||||
|
||||
G4VPhysicalVolume* world= navigator-> GetWorldVolume();
|
||||
G4VSolid* solid= world-> GetLogicalVolume()-> GetSolid();
|
||||
EInside qinside= solid-> Inside(pos);
|
||||
G4VSolid* solid = world-> GetLogicalVolume()-> GetSolid();
|
||||
EInside qinside = solid-> Inside(pos);
|
||||
|
||||
if( qinside != kInside) return false;
|
||||
else return true;
|
||||
return (qinside != kInside) ? false : true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user