BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
BDSAcceleratorComponentRegistry.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2022.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSAcceleratorComponentRegistry.hh"
20#include "BDSDebug.hh"
21#include "BDSLine.hh"
22
23#include <ostream>
24#include <iomanip>
25#include <ios>
26#include <map>
27
29
31{
32 if (!instance)
34 return instance;
35}
36
38{;}
39
41{
42#ifdef BDSDEBUG
43 G4cout << __METHOD_NAME__ << "size of registry " << registry.size() << G4endl;
44#endif
45 for (auto& i : registry)
46 {delete i.second;}
47 for (auto ac : allocatedComponents)
48 {delete ac;}
49 for (auto ac : curvilinearComponents)
50 {delete ac;}
51 for (auto ac : tunnelComponents)
52 {delete ac;}
53
54 instance = nullptr;
55}
56
58 bool isModified)
59{
60 // If the component was modified beyond its original element definition in the parser,
61 // ie a drift was modified to match a pole face of a bend, then store if for memory
62 // management, but not in the registry
63 if (isModified)
64 {
65 if (IsRegisteredAllocated(component))
66 {return;}
67
68 allocatedComponents.insert(component);
69 // add to registry for unique components only
70 registryForAllocated[component->GetName()] = component;
71 if (BDSLine* line = dynamic_cast<BDSLine*>(component))
72 {// if line then also add constituents
73 for (const auto element : *line)
74 {RegisterComponent(element, true);}
75 }
76 return;
77 }
78
79 if (IsRegistered(component))
80 {return;} // don't register something that's already registered
81
82 // in both cases we register the BDSLine* object as it doesn't own its constituents
83 registry[component->GetName()] = component;
84 // increment counter for each component type
85 ++typeCounter[component->GetType()];
86 if (BDSLine* line = dynamic_cast<BDSLine*>(component))
87 {
88 for (const auto element : *line)
89 {RegisterComponent(element, false);}
90 }
91#ifdef BDSDEBUG
92 G4cout << __METHOD_NAME__ << "size of registry " << registry.size() << G4endl;
93#endif
94}
95
97{
98 return IsRegistered(component->GetName());
99}
100
102{
103 return std::find(allocatedComponents.begin(), allocatedComponents.end(), component) != allocatedComponents.end();
104}
105
107{
108 auto search = registry.find(name);
109 return !(search == registry.end());
110}
111
113{
114 try
115 {return registry.at(name);}
116 catch (const std::out_of_range& /*oor*/)
117 {
118 G4cerr << __METHOD_NAME__ << "unknown component named: \"" << name << "\"" << G4endl;
119 return nullptr;
120 }
121}
122
124{
125 curvilinearComponents.insert(component);
126}
127
129{
130 tunnelComponents.insert(component);
131}
132
133std::map<G4String, BDSAcceleratorComponent*> BDSAcceleratorComponentRegistry::AllComponentsIncludingUnique() const
134{
135 std::map<G4String, BDSAcceleratorComponent*> result;
136 result.insert(registry.begin(), registry.end());
137 result.insert(registryForAllocated.begin(), registryForAllocated.end());
138 return result;
139}
140
141std::ostream& operator<< (std::ostream &out, BDSAcceleratorComponentRegistry const &r)
142{
143 // save flags since std::left changes the stream
144 std::ios_base::fmtflags ff = out.flags();
145 out << "Accelerator Component Registry:" << G4endl;
146 for (const auto& it : r.registry)
147 {out << std::left << std::setw(15) << it.second->GetType() << " \"" << it.first << "\"" << G4endl;}
148 out.flags(ff); // reset flags
149 return out;
150}
151
153{
154 G4cout << __METHOD_NAME__ << G4endl;
155 for (const auto& kv : typeCounter)
156 {G4cout << std::setw(20) << kv.first << " : " << kv.second << G4endl;}
157}
A registry of constructed BDSAcceleratorComponent instances that can be searched.
void RegisterCurvilinearComponent(BDSAcceleratorComponent *component)
static BDSAcceleratorComponentRegistry * Instance()
Singleton accessor.
std::map< G4String, BDSAcceleratorComponent * > AllComponentsIncludingUnique() const
void RegisterTunnelComponent(BDSAcceleratorComponent *component)
void RegisterComponent(BDSAcceleratorComponent *component, bool isModified=false)
std::set< BDSAcceleratorComponent * > allocatedComponents
Set of created components not in registry, for memory management.
std::set< BDSAcceleratorComponent * > curvilinearComponents
Set of curvilinear components - purely for memory management.
static BDSAcceleratorComponentRegistry * instance
The singleton instance.
G4bool IsRegisteredAllocated(const BDSAcceleratorComponent *componentName) const
Check if a unique component is registered in the allocatedComponents.
void PrintNumberOfEachType() const
Print out the number of each type of component registered.
BDSAcceleratorComponent * GetComponent(const G4String &name)
std::unordered_map< std::string, int > typeCounter
G4bool IsRegistered(BDSAcceleratorComponent *component)
Check whether an accelerator component is already registered.
BDSAcceleratorComponentRegistry()
Default constructor is private as singleton.
RegistryMap registry
Registry is a map - note 'register' is a protected keyword.
RegistryMap registryForAllocated
A map for absolutely everything including components that are unique.
Abstract class that represents a component of an accelerator.
virtual G4String GetName() const
The name of the component without modification.
G4String GetType() const
Get a string describing the type of the component.
A class that hold multiple accelerator components.
Definition: BDSLine.hh:38