BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSPSCellFluxScaled3D.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) BDSIM Collaboration, 2001 - 2026.
3
4This file is part of BDSIM.
5
6BDSIM is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published
8by the Free Software Foundation version 3 of the License.
9
10BDSIM is distributed in the hope that it will be useful, but
11WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
17*/
18#include "BDSDebug.hh"
19#include "BDSException.hh"
20#include "BDSHistBinMapper.hh"
21#include "BDSScorerConversionLoader.hh"
22#include "BDSPSCellFluxScaled3D.hh"
23#include "BDSUtilities.hh"
24
25#include "G4PhysicsVector.hh"
26#include "G4String.hh"
27#include "G4SystemOfUnits.hh"
28#include "G4Types.hh"
29#include "G4VSolid.hh"
30#include "G4VPhysicalVolume.hh"
31#include "G4VPVParameterisation.hh"
32#include "G4UnitsTable.hh"
33
34#include <fstream>
35#include <string>
36
37#ifdef USE_GZSTREAM
38#include "src-external/gzstream/gzstream.h"
39#endif
40
42 const BDSHistBinMapper* mapperIn,
43 const G4String& unitIn,
44 G4int ni,
45 G4int nj,
46 G4int nk,
47 G4int depi,
48 G4int depj,
49 G4int depk):
50 G4VPrimitiveScorer(scorerName),
51 HCID3D(-1),
52 evtMap3D(nullptr),
53 fDepthi(depi),fDepthj(depj),fDepthk(depk),
54 conversionFactor(nullptr),
55 mapper(mapperIn)
56{
58 CheckAndSetUnit(unitIn, "Per Unit Surface");
59 fNi = ni; // set base class members
60 fNj = nj;
61 fNk = nk;
62}
63
65 const BDSHistBinMapper* mapperIn,
66 const G4String& filename,
67 const G4String& unitIn,
68 G4int ni,
69 G4int nj,
70 G4int nk,
71 G4int depi,
72 G4int depj,
73 G4int depk):
74 BDSPSCellFluxScaled3D(scorerName, mapperIn, unitIn, ni, nj, nk, depi, depj, depk)
75{
76 if (filename.empty())
77 {throw BDSException(__METHOD_NAME__, "no conversionFactorFile provided for \"" + scorerName + "\" - required");}
78
79 G4String filePath = BDS::GetFullPath(filename);
80 if (filePath.rfind("gz") != std::string::npos)
81 {
82#ifdef USE_GZSTREAM
84 conversionFactor = loader.Load(filePath);
85#else
86 throw BDSException(__METHOD_NAME__, "Compressed file loading - but BDSIM not compiled with ZLIB.");
87#endif
88 }
89 else
90 {
92 conversionFactor = loader.Load(filePath);
93 }
94}
95
96BDSPSCellFluxScaled3D::~BDSPSCellFluxScaled3D()
97{
98 delete conversionFactor;
99}
100
101G4bool BDSPSCellFluxScaled3D::ProcessHits(G4Step* aStep, G4TouchableHistory*)
102{
103 G4double stepLength = aStep->GetStepLength();
104 G4double radiationQuantity = 0;
105
106 if (!BDS::IsFinite(stepLength))
107 {return false;}
108
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())
114 {// cache the volume of the volume to avoid repeated calculation
115 // this is simple for a cube, but expensive for a cuttubs
116 cubicVolume = solid->GetCubicVolume();
117 volumeCache[solid] = cubicVolume;
118 }
119 else
120 {cubicVolume = search->second;}
121
122 G4double cellFlux = stepLength / cubicVolume;
123 cellFlux *= aStep->GetPreStepPoint()->GetWeight();
124
125 G4double kineticEnergy = aStep->GetPreStepPoint()->GetKineticEnergy();
126 G4double factor = GetConversionFactor(aStep->GetTrack()->GetDefinition()->GetPDGEncoding(), kineticEnergy);
127 radiationQuantity = cellFlux * factor;
128 G4int index = GetIndex(aStep);
129
130 evtMap3D->add(index, radiationQuantity);
131 return true;
132}
133
134G4double BDSPSCellFluxScaled3D::GetConversionFactor(G4int /*particleID*/,
135 G4double kineticEnergy) const
136{
137 return conversionFactor ? conversionFactor->Value(kineticEnergy) : 1.0;
138}
139
140void BDSPSCellFluxScaled3D::Initialize(G4HCofThisEvent* HCE)
141{
142 evtMap3D = new G4THitsMap<G4double>(detector->GetName(),
143 GetName());
144 if (HCID3D < 0)
145 {HCID3D = GetCollectionID(0);}
146 HCE->AddHitsCollection(HCID3D, evtMap3D);
147}
148
149void BDSPSCellFluxScaled3D::EndOfEvent(G4HCofThisEvent* /*HEC*/)
150{;}
151
152void BDSPSCellFluxScaled3D::clear()
153{
154 evtMap3D->clear();
155}
156
157G4int BDSPSCellFluxScaled3D::GetIndex(G4Step* aStep)
158{
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);
163
164 if (i<0 || j<0 || k<0)
165 {
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);
174 }
175
176 G4int globalIndex = mapper->GlobalFromIJKLIndex(i,j,k); // x,y,z
177 //G4int oldResult = i*fNj*fNk+j*fNk+k;
178 return globalIndex;
179}
180
182{
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));
186}
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.
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.
Definition parserROOT.cc:37