BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSScorerFactory.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 "BDSScorerFactory.hh"
21#include "BDSScorerInfo.hh"
22#include "BDSPSCellFluxScaledPerParticle3D.hh"
23#include "BDSPSPopulationScaled.hh"
24#include "BDSPSBLMEnergyDeposit.hh"
25#include "BDSPSCellFluxScaled3D.hh"
26#include "BDSSDFilterAnd.hh"
27#include "BDSSDFilterLogicalVolume.hh"
28#include "BDSSDFilterMaterial.hh"
29#include "BDSSDFilterPrimary.hh"
30#include "BDSSDFilterTime.hh"
31#include "BDSScorerType.hh"
32#include "BDSUtilities.hh"
33
34#include "G4PSCellCharge.hh"
35#include "G4PSCellCharge3D.hh"
36#include "G4PSCellFlux.hh"
37#include "G4PSCellFlux3D.hh"
38#include "BDSPSCellFlux4D.hh"
39#include "G4PSDoseDeposit.hh"
40#include "G4PSDoseDeposit3D.hh"
41#include "G4PSEnergyDeposit.hh"
42#include "G4PSEnergyDeposit3D.hh"
43#include "G4PSPopulation.hh"
44#include "G4PSPopulation3D.hh"
45#include "G4SDParticleWithEnergyFilter.hh"
46#include "G4String.hh"
47#include "G4Types.hh"
48#include "G4VPrimitiveScorer.hh"
49
50BDSScorerFactory::BDSScorerFactory()
51{;}
52
53G4VPrimitiveScorer* BDSScorerFactory::CreateScorer(const BDSScorerInfo* info,
54 const BDSHistBinMapper* mapper,
55 G4double* unit,
56 G4LogicalVolume* worldLV)
57{
58 // here we create the scorer with the information from BDSScorerInfo.
59 G4VPrimitiveScorer* primitiveScorer = GetAppropriateScorer(*info, mapper, unit);
60
61 BDSSDFilterAnd* filter = CreateFilter(info->name + "_scorer_filter", info, worldLV);
62 if (filter)
63 {primitiveScorer->SetFilter(filter);}
64
65 return primitiveScorer;
66}
67
69 const BDSHistBinMapper* mapper,
70 G4double* unit)
71{
72 G4VPrimitiveScorer* result = nullptr;
73 switch (info.scorerType.underlying())
74 {// if adding new 3D ones, remember to update the 3D upgrade mapping in BDSScorerInfo
75 case BDSScorerType::cellcharge:
76 {result = new G4PSCellCharge(info.name); break;}
77 case BDSScorerType::cellcharge3d:
78 {result = new G4PSCellCharge3D(info.name); break;}
79 case BDSScorerType::depositeddose:
80 {result = new G4PSDoseDeposit(info.name); break;}
81 case BDSScorerType::depositeddose3d:
82 {result = new G4PSDoseDeposit3D(info.name); break;}
83 case BDSScorerType::depositedenergy:
84 {result = new G4PSEnergyDeposit(info.name, "GeV"); break;}
85 case BDSScorerType::depositedenergyblm:
86 {result = new BDSPSBLMEnergyDeposit(info.name, "GeV"); break;}
87 case BDSScorerType::depositedenergy3d:
88 {result = new G4PSEnergyDeposit3D(info.name, "GeV"); break;}
89 case BDSScorerType::population:
90 {
91 G4PSPopulation* scorer = new G4PSPopulation(info.name);
92 scorer->Weighted(true);
93 result = scorer;
94 break;
95 }
96 case BDSScorerType::population3d:
97 {
98 G4PSPopulation3D* scorer = new G4PSPopulation3D(info.name);
99 scorer->Weighted(true);
100 result = scorer;
101 break;
102 }
103 case BDSScorerType::populationscaled:
104 {result = new BDSPSPopulationScaled(info.name, info.pathname); break;}
105 case BDSScorerType::cellflux:
106 {
107 G4PSCellFlux* scorer = new G4PSCellFlux(info.name, "percm2");
108 scorer->Weighted(true);
109 result = scorer;
110 break;
111 }
112 case BDSScorerType::cellflux3d:
113 {
114 G4PSCellFlux3D* scorer = new G4PSCellFlux3D(info.name, "percm2");
115 scorer->Weighted(true);
116 result = scorer;
117 break;
118 }
119 case BDSScorerType::cellflux4d:
120 {
121 BDSPSCellFlux4D* scorer = new BDSPSCellFlux4D(info.name, mapper, "percm2");
122 scorer->Weighted(true);
123 result = scorer;
124 break;
125 }
126 case BDSScorerType::cellfluxscaledperparticle3d:
127 {result = new BDSPSCellFluxScaledPerParticle3D(info.name, mapper, info.pathname); break;}
128 case BDSScorerType::cellfluxscaled3d:
129 {result = new BDSPSCellFluxScaled3D(info.name, mapper, info.filename, "percm2"); break;}
130 case BDSScorerType::cellfluxscaled:
131 case BDSScorerType::cellfluxscaledperparticle:
132 {
133 throw BDSException(__METHOD_NAME__, "unimplemented scorer \"" + info.scorerType.ToString() + "\"");
134 break;
135 }
136 default:
137 {
138 throw BDSException(__METHOD_NAME__, "unknown scorer type \"" + info.scorerType.ToString() + "\"");
139 break;
140 }
141 }
142 if (unit)
143 {*unit = result->GetUnitValue();}
144 return result;
145}
146
148 const BDSScorerInfo* info,
149 G4LogicalVolume* worldLV) const
150{
151 BDSSDFilterAnd* result = new BDSSDFilterAnd(name, /*ownsFilters=*/true);
152
153 if (info->particle)
154 {
155 G4String particleName = info->particle->GetParticleName();
156 auto pwkef = new G4SDParticleWithEnergyFilter("particle_filter",
157 info->minimumKineticEnergy,
158 info->maximumKineticEnergy);
159 pwkef->add(particleName);
160 result->RegisterFilter(pwkef);
161 }
162 if (BDS::IsFinite(info->maximumTime) || BDS::IsFinite(info->minimumTime))
163 {
164 auto timeFilter = new BDSSDFilterTime("time_filter",
165 info->minimumTime,
166 info->maximumTime);
167 result->RegisterFilter(timeFilter);
168 }
169 if (!(info->materialsToInclude.empty()))
170 {
171 auto materialFilterInc = new BDSSDFilterMaterial("material_filter_include",
172 info->materialsToInclude,
173 /*inclusive*/true);
174 result->RegisterFilter(materialFilterInc);
175 }
176 if (!(info->materialsToExclude.empty()))
177 {
178 auto materialFilterExc = new BDSSDFilterMaterial("material_filter_exclude",
179 info->materialsToExclude,
180 /*inclusive*/false);
181 result->RegisterFilter(materialFilterExc);
182 }
183 if (info->worldVolumeOnly)
184 {
185 auto worldLVFilter = new BDSSDFilterLogicalVolume("world_lv_only", worldLV);
186 result->RegisterFilter(worldLVFilter);
187 }
188 if (info->primariesOnly)
189 {
190 auto primaryFilter = new BDSSDFilterPrimary("primary_filter");
191 result->RegisterFilter(primaryFilter);
192 }
193
194 // if we didn't register any filters, just delete it
195 if (result->size() == 0)
196 {
197 delete result;
198 return nullptr;
199 }
200 return result;
201}
General exception with possible name of object and message.
Mapping from axis indices to 1D index.
Primitive scorer for energy deposition in BLMs.
Primitive scorer for cell flux in a 4D mesh.
Primitive scorer for cell flux in a 3D mesh with a conversion factor.
Primitive scorer for a 3D mesh with a conversion factor.
Primitive scorer for population in a volume with a conversion factor based on angle and kinetic energ...
Filter that applies AND to a vector of filters.
void RegisterFilter(G4VSDFilter *filterIn)
Register the filter.
size_t size() const
Accessor.
SD filter for a particular volume.
SD filter for a particular volume.
Filter for only primary particles.
Filter for time value for a sensitive detector.
BDSSDFilterAnd * CreateFilter(const G4String &name, const BDSScorerInfo *info, G4LogicalVolume *worldLV=nullptr) const
Create a combined filter with AND logic for the scorer.
G4VPrimitiveScorer * CreateScorer(const BDSScorerInfo *info, const BDSHistBinMapper *mapper, G4double *unit=nullptr, G4LogicalVolume *worldLV=nullptr)
Main function to create a scorer.
G4VPrimitiveScorer * GetAppropriateScorer(const BDSScorerInfo &info, const BDSHistBinMapper *mapper, G4double *unit=nullptr)
Construct the primitive scorer required.
Recipe class for scorer. Checks values.
BDSScorerType scorerType
Scorer type.
G4bool worldVolumeOnly
Which materials to exclude for scoring.
std::vector< G4Material * > materialsToExclude
Which materials to include for scoring.
G4String name
Scorer name.
G4String filename
Name of the conversion factor file.
G4String pathname
Path of the conversion factor file (for ambient dose)
G4ParticleDefinition * particle
Particle filter.
type underlying() const
return underlying value (can be used in switch statement)
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())