Geant4 10.7.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, 18/06/2013 ([email protected])
28
30#include "G4Threading.hh"
31#include "G4AutoLock.hh"
32
33// mutex in a file scope
34
35namespace {
36 //Mutex to lock master manager when merging accumulables
37 G4Mutex mergeMutex = G4MUTEX_INITIALIZER;
38}
39
40G4AccumulableManager* G4AccumulableManager::fgMasterInstance = nullptr;
41G4ThreadLocal G4AccumulableManager* G4AccumulableManager::fgInstance = nullptr;
42
43//_____________________________________________________________________________
45{
46 if ( fgInstance == nullptr ) {
48 fgInstance = new G4AccumulableManager(isMaster);
49 }
50
51 return fgInstance;
52}
53
54//_____________________________________________________________________________
55G4AccumulableManager::G4AccumulableManager(G4bool isMaster)
56 : fVector(),
57 fMap()
58{
59 if ( ( isMaster && fgMasterInstance ) || ( fgInstance ) ) {
60 G4ExceptionDescription description;
61 description
62 << " "
63 << "G4AccumulableAnalysisManager already exists."
64 << "Cannot create another instance.";
65 G4Exception("G4AccumulableAnalysisManager::G4AccumulableAnalysisManager()",
66 "Analysis_F001", FatalException, description);
67 }
68 if ( isMaster ) fgMasterInstance = this;
69 fgInstance = this;
70}
71
72//_____________________________________________________________________________
74{
75 // delete only accumulables create by the mager itself
76 for ( auto it : fAccumulablesToDelete ) {
77 delete it;
78 }
79}
80
81//
82// private methods
83//
84
85//_____________________________________________________________________________
86G4String G4AccumulableManager::GenerateName() const
87{
88 G4String name = kBaseName;
89 std::ostringstream os;
90 os << fVector.size();
91 name.append("_");
92 name.append(os.str());
93 return name;
94}
95
96//_____________________________________________________________________________
97G4bool G4AccumulableManager::CheckName(const G4String& name, const G4String& where) const
98{
99 if ( fMap.find(name) == fMap.end() ) return true;
100
101 G4ExceptionDescription description;
102 description << " " << "Name " << name << " is already used." << G4endl;
103 description << " " << "Parameter will be not created/registered.";
104 G4String method("G4AccumulableManager::");
105 method.append(where);
106 G4Exception(method, "Analysis_W002", JustWarning, description);
107 return false;
108}
109
110//
111// public methods
112//
113
114//_____________________________________________________________________________
116{
117 auto name = accumulable->GetName();
118
119 // do not accept name if it is already used
120 if ( ! CheckName(name, "RegisterAccumulable") ) return false;
121
122 // generate name if empty
123 if ( ! name.length() ) {
124 name = GenerateName();
125 accumulable->fName = name;
126 }
127
128 fMap[name] = accumulable;
129 fVector.push_back(accumulable);
130 return true;
131}
132
133//_____________________________________________________________________________
136{
137 // get G4VParammeter from the map
138 auto it = fMap.find(name);
139 if ( it == fMap.end() ) {
140 if ( warn) {
141 G4ExceptionDescription description;
142 description << " " << "accumulable " << name << " does not exist.";
143 G4Exception("G4AccumulableManager::GetAccumulable",
144 "Analysis_W011", JustWarning, description);
145 }
146 return nullptr;
147 }
148
149 return it->second;
150}
151
152//_____________________________________________________________________________
155{
156 // get G4VParammeter from the vector
157 if ( id < 0 || id >= G4int(fVector.size()) ) {
158 if ( warn) {
159 G4ExceptionDescription description;
160 description << " " << "accumulable " << id << " does not exist.";
161 G4Exception("G4AccumulableManager::GetAccumulable",
162 "Analysis_W011", JustWarning, description);
163 }
164 return nullptr;
165 }
166
167 return fVector[id];
168}
169
170//_____________________________________________________________________________
172{
173 // Do nothing if there are no accumulables registered
174 // or if master thread
175 if ( (! fVector.size()) || (! G4Threading::IsWorkerThread()) ) return;
176
177 // The manager on mastter must exist
178 if ( ! fgMasterInstance ) {
179 G4ExceptionDescription description;
180 description
181 << " " << "No master G4AccumulableManager instance exists."
182 << G4endl
183 << " " << "Accumulables will not be merged.";
184 G4Exception("G4AccumulableManager::Merge()",
185 "Analysis_W031", JustWarning, description);
186 return;
187 }
188
189 // The worker manager just merges its accumulables to the master
190 // This operation needs a lock
191 // G4cout << "Go to merge accumulables" << G4endl;
192 G4AutoLock lock(&mergeMutex);
193
194 // the other manager has the vector with the "same" accumulables
195 auto it = fVector.begin();
196 for ( auto itMaster : fgMasterInstance->fVector ) {
197 // G4VAccumulable* masterAccumulable = itMaster;
198 // G4VAccumulable* accumulable = *(it++);
199 // masterAccumulable->Merge(*(accumulable));
200 itMaster->Merge(*(*(it++)));
201 }
202 lock.unlock();
203}
204
205//_____________________________________________________________________________
207{
208// Reset histograms and profiles
209
210 for ( auto it : fVector ) {
211 it->Reset();
212 }
213}
214
215
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:85
std::mutex G4Mutex
Definition: G4Threading.hh:81
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4Accumulable< T > * GetAccumulable(const G4String &name, G4bool warn=true) const
static G4AccumulableManager * Instance()
G4bool RegisterAccumulable(G4Accumulable< T > &accumulable)
G4String GetName() const
const char * name(G4int ptype)
G4bool IsWorkerThread()
Definition: G4Threading.cc:123
#define G4ThreadLocal
Definition: tls.hh:77