19#include "BDSException.hh"
20#include "BDSHistBinMapper.hh"
21#include "BDSScorerConversionLoader.hh"
22#include "BDSPSCellFluxScaled3D.hh"
23#include "BDSUtilities.hh"
25#include "G4PhysicsVector.hh"
27#include "G4SystemOfUnits.hh"
30#include "G4VPhysicalVolume.hh"
31#include "G4VPVParameterisation.hh"
32#include "G4UnitsTable.hh"
38#include "src-external/gzstream/gzstream.h"
43 const G4String& unitIn,
50 G4VPrimitiveScorer(scorerName),
53 fDepthi(depi),fDepthj(depj),fDepthk(depk),
54 conversionFactor(nullptr),
58 CheckAndSetUnit(unitIn,
"Per Unit Surface");
66 const G4String& filename,
67 const G4String& unitIn,
77 {
throw BDSException(__METHOD_NAME__,
"no conversionFactorFile provided for \"" + scorerName +
"\" - required");}
80 if (filePath.rfind(
"gz") != std::string::npos)
86 throw BDSException(__METHOD_NAME__,
"Compressed file loading - but BDSIM not compiled with ZLIB.");
96BDSPSCellFluxScaled3D::~BDSPSCellFluxScaled3D()
101G4bool BDSPSCellFluxScaled3D::ProcessHits(G4Step* aStep, G4TouchableHistory*)
103 G4double stepLength = aStep->GetStepLength();
104 G4double radiationQuantity = 0;
109 const G4VTouchable* touchable = aStep->GetPreStepPoint()->GetTouchable();
110 G4VSolid* solid = touchable->GetSolid();
111 G4double cubicVolume = 1;
112 auto search = volumeCache.find(solid);
113 if (search == volumeCache.end())
116 cubicVolume = solid->GetCubicVolume();
117 volumeCache[solid] = cubicVolume;
120 {cubicVolume = search->second;}
122 G4double cellFlux = stepLength / cubicVolume;
123 cellFlux *= aStep->GetPreStepPoint()->GetWeight();
125 G4double kineticEnergy = aStep->GetPreStepPoint()->GetKineticEnergy();
126 G4double factor = GetConversionFactor(aStep->GetTrack()->GetDefinition()->GetPDGEncoding(), kineticEnergy);
127 radiationQuantity = cellFlux * factor;
128 G4int index = GetIndex(aStep);
130 evtMap3D->add(index, radiationQuantity);
134G4double BDSPSCellFluxScaled3D::GetConversionFactor(G4int ,
135 G4double kineticEnergy)
const
140void BDSPSCellFluxScaled3D::Initialize(G4HCofThisEvent* HCE)
145 {
HCID3D = GetCollectionID(0);}
149void BDSPSCellFluxScaled3D::EndOfEvent(G4HCofThisEvent* )
152void BDSPSCellFluxScaled3D::clear()
157G4int BDSPSCellFluxScaled3D::GetIndex(G4Step* aStep)
159 const G4VTouchable* touchable = aStep->GetPreStepPoint()->GetTouchable();
160 G4int i = touchable->GetReplicaNumber(
fDepthi);
161 G4int j = touchable->GetReplicaNumber(
fDepthj);
162 G4int k = touchable->GetReplicaNumber(
fDepthk);
164 if (i<0 || j<0 || k<0)
166 G4ExceptionDescription ED;
167 ED <<
"GetReplicaNumber is negative" << G4endl
168 <<
"touchable->GetReplicaNumber(fDepthi) returns i,j,k = "
169 << i <<
"," << j <<
"," << k <<
" for volume "
170 << touchable->GetVolume(
fDepthi)->GetName() <<
","
171 << touchable->GetVolume(
fDepthj)->GetName() <<
","
172 << touchable->GetVolume(
fDepthk)->GetName() << G4endl;
173 G4Exception(
"BDSPSCellFluxScaled3D::GetIndex",
"DetPS0006",JustWarning,ED);
176 G4int globalIndex =
mapper->GlobalFromIJKLIndex(i,j,k);
183 new G4UnitDefinition(
"percentimeter2",
"percm2",
"Per Unit Surface", (1./CLHEP::cm2));
184 new G4UnitDefinition(
"permillimeter2",
"permm2",
"Per Unit Surface", (1./CLHEP::mm2));
185 new G4UnitDefinition(
"permeter2",
"perm2",
"Per Unit Surface", (1./CLHEP::m2));
General exception with possible name of object and message.
Mapping from axis indices to 1D index.
Primitive scorer for cell flux in a 3D mesh with a conversion factor.
G4THitsMap< G4double > * evtMap3D
Hits map.
const BDSHistBinMapper * mapper
Mapping from coordinate systems in mesh to global replica number.
G4int fDepthk
Depth in replica to look for each dimension.
G4PhysicsVector * conversionFactor
Conversion factor interpolator object.
G4int fDepthi
Depth in replica to look for each dimension.
G4int fDepthj
Depth in replica to look for each dimension.
void DefineUnitAndCategory() const
Define units -> taken from G4PSCellFlux.
G4int HCID3D
Collection ID.
BDSPSCellFluxScaled3D(const G4String &scorerName, const BDSHistBinMapper *mapperIn, const G4String &unitIn="percm2", G4int ni=1, G4int nj=1, G4int nk=1, G4int depi=2, G4int depj=1, G4int depk=0)
Loader for scoring conversion tables as function of energy.
G4PhysicsVector * Load(const G4String &fileName, G4bool silent=false)
Load the file.
G4String GetFullPath(G4String filename, bool excludeNameFromPath=false, bool useCWDForPrefix=false)
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())
const char * GetName(int)
Name of element.