ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4AccumulableManager.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4AccumulableManager.cc
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 (ivana@ipno.in2p3.fr)
28 
29 #include "G4AccumulableManager.hh"
30 #include "G4Threading.hh"
31 #include "G4AutoLock.hh"
32 
33 // mutex in a file scope
34 
35 namespace {
36  //Mutex to lock master manager when merging accumulables
37  G4Mutex mergeMutex = G4MUTEX_INITIALIZER;
38 }
39 
42 
43 //_____________________________________________________________________________
45 {
46  if ( fgInstance == nullptr ) {
47  G4bool isMaster = ! G4Threading::IsWorkerThread();
48  fgInstance = new G4AccumulableManager(isMaster);
49  }
50 
51  return fgInstance;
52 }
53 
54 //_____________________________________________________________________________
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 //_____________________________________________________________________________
87 {
89  std::ostringstream os;
90  os << fVector.size();
91  name.append("_");
92  name.append(os.str());
93  return name;
94 }
95 
96 //_____________________________________________________________________________
98 {
99  if ( fMap.find(name) == fMap.end() ) return true;
100 
101  G4ExceptionDescription description;
102  description << " " << "Name " << name << " is already used." << G4endl;
103  description << " " << "Paremeter 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