Geant4 11.3.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4AccumulableManager.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26
27// Author: Ivana Hrivnacova, IJCLab IN2P3/CNRS, 18/06/2013
28
31#include "G4Threading.hh"
32#include "G4AutoLock.hh"
33
34// mutex in a file scope
35
36namespace {
37 //Mutex to lock master manager when merging accumulables
38 G4Mutex mergeMutex = G4MUTEX_INITIALIZER;
39
40 void RangeException(const G4String& where, const G4String& message)
41 {
42 G4ExceptionDescription description;
43 description << "Invalid range " << message;
44 G4String method("G4AccumulableManager::");
45 method.append(where);
46 G4Exception(where, "Analysis_W001", JustWarning, description);
47 }
48}
49
50//_____________________________________________________________________________
51G4AccumulableManager* G4AccumulableManager::Instance()
52{
54 return instance.Instance();
55}
56
57//_____________________________________________________________________________
58G4AccumulableManager::G4AccumulableManager()
59{
61 fgMasterInstance = this;
62 }
63}
64
65//_____________________________________________________________________________
67{
68 // delete only accumulables create by the mager itself
69 for ( auto it : fAccumulablesToDelete ) {
70 delete it;
71 }
72}
73
74//
75// private methods
76//
77
78//_____________________________________________________________________________
79G4String G4AccumulableManager::GenerateName() const
80{
81 G4String name = kBaseName;
82 std::ostringstream os;
83 os << fVector.size();
84 name.append("_");
85 name.append(os.str());
86 return name;
87}
88
89//_____________________________________________________________________________
90G4bool G4AccumulableManager::CheckName(
91 const G4String& name, const G4String& where) const
92{
93 if (fMap.find(name) == fMap.end()) {
94 return true;
95 }
96
97 G4ExceptionDescription description;
98 description << "Name " << name << " is already used." << G4endl;
99 description << "Parameter will be not created/registered.";
100 G4String method("G4AccumulableManager::");
101 method.append(where);
102 G4Exception(method, "Analysis_W001", JustWarning, description);
103 return false;
104}
105
106//_____________________________________________________________________________
107G4bool G4AccumulableManager::CheckType(
108 G4VAccumulable* accumulable, G4AccType type, G4bool warn) const
109{
110 if (accumulable->GetType() != type) {
111 if (warn) {
112 G4ExceptionDescription description;
113 description << " " << accumulable->GetName() << ": Incompatible type.";
114 G4Exception("G4AccumulableManager::CheckType",
115 "Analysis_W001", JustWarning, description);
116 }
117 return false;
118 }
119 return true;
120}
121
122//
123// public methods
124//
125
126//_____________________________________________________________________________
128{
129 auto name = accumulable->GetName();
130
131 if (G4Accumulables::VerboseLevel > 1 ) {
132 G4cout << "Going to register accumulable \"" << name << "\"" << G4endl;
133 }
134
135 // do not accept name if it is already used
136 if (!CheckName(name, "RegisterAccumulable")) {
137 return false;
138 }
139
140 // generate name if empty
141 if (name.length() == 0u) {
142 name = GenerateName();
143 accumulable->SetName(name);
144 }
145
146 // set Id
147 accumulable->SetId((G4int)fVector.size());
148
149 fMap[name] = accumulable;
150 fVector.push_back(accumulable);
151
152 if (G4Accumulables::VerboseLevel > 0 ) {
153 G4cout << "Accumulable registered as \"" << accumulable->GetName() << "\"" << G4endl;
154 }
155
156 return true;
157}
158
159// Deprecated functions with long name
160//_____________________________________________________________________________
162{
163 return Register(accumulable);
164}
165
166//_____________________________________________________________________________
169{
170 // get G4VParammeter from the map
171 auto it = fMap.find(name);
172 if ( it == fMap.end() ) {
173 if ( warn) {
174 G4ExceptionDescription description;
175 description << "Accumulable " << name << " does not exist.";
176 G4Exception("G4AccumulableManager::GetAccumulable",
177 "Analysis_W001", JustWarning, description);
178 }
179 return nullptr;
180 }
181
182 return it->second;
183}
184
185//_____________________________________________________________________________
188{
189 // get G4VParammeter from the vector
190 if ( id < 0 || id >= G4int(fVector.size()) ) {
191 if ( warn) {
192 G4ExceptionDescription description;
193 description << "Accumulable " << id << " does not exist.";
194 G4Exception("G4AccumulableManager::GetAccumulable",
195 "Analysis_W001", JustWarning, description);
196 }
197 return nullptr;
198 }
199
200 return fVector[id];
201}
202
203//_____________________________________________________________________________
205{
206 // Do nothing if there are no accumulables registered
207 // or if master thread
208 if ((fVector.size() == 0u) || (!G4Threading::IsWorkerThread())) {
209 return;
210 }
211
212 // The manager on mastter must exist
213 if (fgMasterInstance == nullptr) {
214 G4ExceptionDescription description;
215 description
216 << "No master G4AccumulableManager instance exists." << G4endl
217 << "Accumulables will not be merged.";
218 G4Exception("G4AccumulableManager::Merge()",
219 "Analysis_W001", JustWarning, description);
220 return;
221 }
222
223 // The worker manager just merges its accumulables to the master
224 // This operation needs a lock
225 // G4cout << "Go to merge accumulables" << G4endl;
226 G4AutoLock lock(&mergeMutex);
227
228 // the other manager has the vector with the "same" accumulables
229 auto it = fVector.begin();
230 for ( auto itMaster : fgMasterInstance->fVector ) {
231 // G4VAccumulable* masterAccumulable = itMaster;
232 // G4VAccumulable* accumulable = *(it++);
233 // masterAccumulable->Merge(*(accumulable));
234 itMaster->Merge(*(*(it++)));
235 }
236 lock.unlock();
237}
238
239//_____________________________________________________________________________
241{
242// Reset all accummulables
243
244 for ( auto it : fVector ) {
245 it->Reset();
246 }
247}
248
249//_____________________________________________________________________________
251{
252 for ( auto it : fVector ) {
253 it->Print(options);
254 }
255}
256
257//_____________________________________________________________________________
259 G4int startId, G4int count, G4PrintOptions options) const
260{
261 // check if range is within limits
262 if ( startId < 0 || startId >= G4int(fVector.size()) ||
263 count <= 0 || startId + count > G4int(fVector.size()) ) {
264 RangeException("Print",
265 std::to_string(startId) + ", " + std::to_string(count));
266 return;
267 }
268
269 for ( auto id = startId; id < startId + count; ++id ) {
270 fVector[id]->Print(options);
271 }
272}
273
274//_____________________________________________________________________________
276 std::vector<G4VAccumulable*>::iterator startIt,
277 std::vector<G4VAccumulable*>::iterator endIt,
278 G4PrintOptions options) const
279{
280 // check if range is within limits
281 if ( startIt == fVector.end() || endIt == fVector.end() ) {
282 RangeException("Print", "[startIt, endIt]");
283 return;
284 }
285
286 for ( auto it = startIt; it != endIt; ++it ) {
287 (*it)->Print(options);
288 }
289}
290
291//_____________________________________________________________________________
293 std::vector<G4VAccumulable*>::iterator startIt, std::size_t count,
294 G4PrintOptions options) const
295{
296 Print(startIt, startIt+count, options);
297}
G4AccType
Definition G4AccType.hh:38
G4TemplateAutoLock< G4Mutex > G4AutoLock
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4TemplateRNGHelper< G4long > * G4TemplateRNGHelper< G4long >::instance
#define G4MUTEX_INITIALIZER
std::mutex G4Mutex
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
G4bool Register(G4AccValue< T > &accumulable)
G4bool RegisterAccumulable(G4AccValue< T > &accumulable)
static G4AccumulableManager * Instance()
G4VAccumulable * GetAccumulable(const G4String &name, G4bool warn=true) const
void Print(G4PrintOptions options=G4PrintOptions()) const
void SetName(const G4String &name)
G4String GetName() const
virtual G4AccType GetType() const
void SetId(G4int id)
const char * name(G4int ptype)
G4bool IsWorkerThread()