BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSGeometryComponent.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 "BDSExtent.hh"
21#include "BDSGeometryComponent.hh"
22#include "BDSSDManager.hh"
23#include "BDSSDType.hh"
24
25#include "globals.hh"
26#include "G4AssemblyVolume.hh"
27#include "G4LogicalVolume.hh"
28#include "G4RotationMatrix.hh"
29#include "G4UserLimits.hh"
30#include "G4VisAttributes.hh"
31#include "G4VPhysicalVolume.hh"
32#include "G4VSolid.hh"
33
34#include <algorithm>
35#include <map>
36#include <set>
37
38class G4VSensitiveDetector;
39
40BDSGeometryComponent::BDSGeometryComponent(G4VSolid* containerSolidIn,
41 G4LogicalVolume* containerLVIn,
42 const BDSExtent& extentIn,
43 const BDSExtent& innerExtentIn,
44 const G4ThreeVector& placementOffsetIn,
45 G4RotationMatrix* placementRotationIn):
46 containerIsAssembly(false),
47 containerSolid(containerSolidIn),
48 containerLogicalVolume(containerLVIn),
49 containerAssembly(nullptr),
50 outerExtent(extentIn),
51 innerExtent(innerExtentIn),
52 overrideSensitivity(false),
53 placementOffset(placementOffsetIn),
54 placementRotation(placementRotationIn),
55 lvsExcludedFromBiasing(nullptr)
56{;}
57
58BDSGeometryComponent::BDSGeometryComponent(G4AssemblyVolume* containerAssemblyIn,
59 const BDSExtent& extentIn,
60 const BDSExtent& innerExtentIn,
61 const G4ThreeVector& placementOffsetIn,
62 G4RotationMatrix* placementRotationIn):
63 containerIsAssembly(true),
64 containerSolid(nullptr),
65 containerLogicalVolume(nullptr),
66 containerAssembly(containerAssemblyIn),
67 outerExtent(extentIn),
68 innerExtent(innerExtentIn),
69 overrideSensitivity(false),
70 placementOffset(placementOffsetIn),
71 placementRotation(placementRotationIn),
72 lvsExcludedFromBiasing(nullptr)
73{;}
74
75BDSGeometryComponent::BDSGeometryComponent(const BDSGeometryComponent& component):
76 containerIsAssembly(component.containerIsAssembly),
77 containerSolid(component.containerSolid),
78 containerLogicalVolume(component.containerLogicalVolume),
79 containerAssembly(component.containerAssembly),
80 outerExtent(component.outerExtent),
81 innerExtent(component.innerExtent),
82 allLogicalVolumes(component.allLogicalVolumes),
83 sensitivity(component.sensitivity),
84 overrideSensitivity(component.overrideSensitivity),
85 allPhysicalVolumes(component.allPhysicalVolumes),
86 placementOffset(component.placementOffset),
87 placementRotation(component.placementRotation),
88 lvsExcludedFromBiasing(nullptr)
89{;}
90
91BDSGeometryComponent::~BDSGeometryComponent()
92{
93 for (auto daughter : allDaughters)
94 {delete daughter;}
95
96 // we let Geant4 handle the deletion of physical volumes, logical volumes and solids
97
98 for (auto rm : allRotationMatrices)
99 {delete rm;}
100
101 for (auto vis : allVisAttributes)
102 {delete vis;}
103
104 for (auto ul : allUserLimits)
105 {delete ul;}
106
107 delete placementRotation;
108}
109
111{
112 outerExtent = anotherComponent->GetExtent();
113 innerExtent = anotherComponent->GetInnerExtent();
114}
115
117 const G4ThreeVector &offset)
118{
119 outerExtent = anotherComponent->GetExtent().Translate(offset);
120 innerExtent = anotherComponent->GetInnerExtent().Translate(offset);
121}
122
123void BDSGeometryComponent::RegisterSolid(const std::set<G4VSolid*>& solids)
124{
125 for (auto solid : solids)
126 {RegisterSolid(solid);}
127}
128
129void BDSGeometryComponent::RegisterLogicalVolume(const std::set<G4LogicalVolume*>& logicalVolumes)
130{
131 for (auto lv : logicalVolumes)
133}
134
135void BDSGeometryComponent::RegisterPhysicalVolume(const std::set<G4VPhysicalVolume*>& physicalVolumes)
136{
137 for (auto pv : physicalVolumes)
139}
140
141void BDSGeometryComponent::RegisterRotationMatrix(const std::set<G4RotationMatrix*>& rotationMatrices)
142{
143 for (auto rm : rotationMatrices)
145}
146
147void BDSGeometryComponent::RegisterSensitiveVolume(G4LogicalVolume* sensitiveVolume,
148 BDSSDType sensitivityType)
149{
150 if (!sensitiveVolume)
151 {return;} // can't register nullptr
152#ifdef BDSDEBUG
153 G4cout << __METHOD_NAME__ << sensitiveVolume->GetName() << " : " << sensitivityType << G4endl;
154#endif
155
156 // check and ensure the logical volume is registered in this component
157 RegisterLogicalVolume(sensitiveVolume);
158
159 // this may overwrite it if it's already in the map
160 sensitivity[sensitiveVolume] = sensitivityType;
161}
162
163void BDSGeometryComponent::RegisterSensitiveVolume(const std::set<G4LogicalVolume*>& sensitiveVolumes,
164 BDSSDType sensitivityType)
165{
166 for (auto sv : sensitiveVolumes)
167 {RegisterSensitiveVolume(sv, sensitivityType);}
168}
169
170void BDSGeometryComponent::RegisterSensitiveVolume(const std::map<G4LogicalVolume*, BDSSDType>& sensitiveVolumes)
171{
172 sensitivity.insert(sensitiveVolumes.begin(), sensitiveVolumes.end());
173}
174
175void BDSGeometryComponent::RegisterVisAttributes(const std::set<G4VisAttributes*>& visAttributes)
176{
177 for (auto va : visAttributes)
179}
180
181void BDSGeometryComponent::RegisterUserLimits(const std::set<G4UserLimits*>& userLimits)
182{
183 for (auto ul : userLimits)
184 {RegisterUserLimits(ul);}
185}
186
197
198std::set<G4LogicalVolume*> BDSGeometryComponent::GetAllLogicalVolumes() const
199{
200 std::set<G4LogicalVolume*> result(allLogicalVolumes);
201 for (auto it : allDaughters)
202 {
203 auto dLVs = it->GetAllLogicalVolumes();
204 result.insert(dLVs.begin(), dLVs.end());
205 }
206 return result;
207}
208
209std::set<G4LogicalVolume*> BDSGeometryComponent::GetAllBiasingVolumes() const
210{
211 std::set<G4LogicalVolume*> result(allLogicalVolumes);
212
213 for (auto it : allDaughters) // do the same recursively for daughters
214 {
215 auto dLVs = it->GetAllBiasingVolumes();
216 result.insert(dLVs.begin(), dLVs.end());
217 }
218
220 {
221 for (const auto vol : *lvsExcludedFromBiasing)
222 {result.erase(vol);}
223 }
224 return result;
225}
226
227std::map<G4LogicalVolume*, BDSSDType> BDSGeometryComponent::GetAllSensitiveVolumes() const
228{
229 // start by copy sensitive volumes belonging to this object
230 std::map<G4LogicalVolume*, BDSSDType> result(sensitivity);
231 for (auto it : allDaughters)
232 {
233 auto dSVs = it->GetAllSensitiveVolumes();
234 result.insert(dSVs.begin(), dSVs.end()); // copy into result map
235 }
236 return result;
237}
238
240{
241 BDSSDManager* sdm = BDSSDManager::Instance();
242 for (auto mapping : sensitivity)
243 {mapping.first->SetSensitiveDetector(sdm->SensitiveDetector(mapping.second, !overrideSensitivity));}
244 for (auto daughter : allDaughters)
245 {daughter->AttachSensitiveDetectors();}
246}
247
249{
250 if (allLogicalVolumes.find(lv) == allLogicalVolumes.end())
251 {
252 throw BDSException(__METHOD_NAME__, "excluding volume \"" + lv->GetName()
253 + "\" from component \"" + GetName()
254 + "\" but it's not a member of this piece of geometry or its daughters.");
255 }
256
258 {lvsExcludedFromBiasing = new std::set<G4LogicalVolume*>();}
259 lvsExcludedFromBiasing->insert(lv);
260}
261
263{
265 {return;}
266 containerAssembly = new G4AssemblyVolume();
267 for (G4int i = 0; i < (G4int)containerLogicalVolume->GetNoDaughters(); i++)
268 {
269 auto daughterPV = containerLogicalVolume->GetDaughter(i);
270 auto daughterLV = daughterPV->GetLogicalVolume();
271 auto translation = daughterPV->GetObjectTranslation();
272 auto rotation = daughterPV->GetObjectRotation(); // could be nullptr
273 G4RotationMatrix* rm = rotation ? new G4RotationMatrix(*(rotation)) : nullptr;
274 containerAssembly->AddPlacedVolume(daughterLV, translation, rm);
275 }
276 containerIsAssembly = true;
277}
278
280 G4UserLimits* ul)
281{
282 std::set<G4LogicalVolume*> lvSet;
283 auto it = av->GetVolumesIterator();
284 for (G4int i = 0; i < (G4int)av->TotalImprintedVolumes(); i++, it++)
285 {lvSet.insert((*it)->GetLogicalVolume());}
286 for (auto& lv : lvSet)
287 {lv->SetUserLimits(ul);}
288}
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions.
Definition BDSExtent.hh:38
BDSExtent Translate(const G4ThreeVector &offset) const
Provide a new copy of this extent with an offset applied.
Definition BDSExtent.hh:124
A generic geometry component for a bdsim model.
void InheritExtents(BDSGeometryComponent const *const anotherComponent)
Update the extents of this object with those of another object.
BDSExtent GetExtent() const
Accessor - see member for more info.
virtual G4String GetName() const
Accessor - see member for more info.
void RegisterRotationMatrix(G4RotationMatrix *rotationMatrix)
std::set< G4UserLimits * > allUserLimits
registry of all user limits belonging to this component
std::set< G4LogicalVolume * > * lvsExcludedFromBiasing
Volumes that should not be included when return GetAllBiasingVolumes().
virtual std::set< G4RotationMatrix * > GetAllRotationMatrices() const
Accessor - see member for more info.
virtual void AttachSensitiveDetectors()
Attach a sensitive detector class to all registered sensitive volumes in this component.
virtual std::set< G4LogicalVolume * > GetAllBiasingVolumes() const
Return all logical volumes that should be used for biasing minus any that are in the excluded set.
void RegisterLogicalVolume(G4LogicalVolume *logicalVolume)
virtual std::set< G4UserLimits * > GetAllUserLimits() const
Accessor - see member for more info.
std::map< G4LogicalVolume *, BDSSDType > sensitivity
virtual std::map< G4LogicalVolume *, BDSSDType > GetAllSensitiveVolumes() const
Access all sensitive volumes belonging to this component.
virtual std::set< G4LogicalVolume * > GetAllLogicalVolumes() const
Access all logical volumes belonging to this component.
void InheritObjects(BDSGeometryComponent *component)
static void AttachUserLimitsToAssembly(G4AssemblyVolume *av, G4UserLimits *ul)
Utility function to apply user limits to an assembly volume as there's not interface.
virtual std::set< G4VisAttributes * > GetAllVisAttributes() const
Accessor - see member for more info.
void RegisterPhysicalVolume(G4VPhysicalVolume *physicalVolume)
virtual std::set< G4VSolid * > GetAllSolids() const
Accessor - see member for more info.
std::set< BDSGeometryComponent * > allDaughters
registry of all daughter geometry components
void RegisterUserLimits(G4UserLimits *userLimit)
virtual void ExcludeLogicalVolumeFromBiasing(G4LogicalVolume *lv)
void StripOuterAndMakeAssemblyVolume()
Change from a container logical volume to an assembly volume.
std::set< G4VisAttributes * > allVisAttributes
registry of all visualisation attributes belonging to this component
std::set< G4RotationMatrix * > allRotationMatrices
registry of all rotation matrices belonging to this component
BDSExtent GetInnerExtent() const
Accessor - see member for more info.
virtual std::set< G4VPhysicalVolume * > GetAllPhysicalVolumes() const
Accessor - see member for more info.
void RegisterVisAttributes(G4VisAttributes *visAttribute)
void RegisterSolid(G4VSolid *solid)
G4RotationMatrix * placementRotation
G4bool containerIsAssembly
True if the 'container' is really an assembly; false if an LV.
void RegisterSensitiveVolume(G4LogicalVolume *sensitiveVolume, BDSSDType sensitivityType)
A singleton class that holds all required sensitive detector class instances.
G4VSensitiveDetector * SensitiveDetector(const BDSSDType sdType, G4bool applyOptions=false) const
Improve type-safety of native enum data type in C++.