Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4RootAnalysisManager.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 "G4RootFileManager.hh"
32#include "G4AnalysisVerbose.hh"
35
36#include "G4Threading.hh"
37#include "G4AutoLock.hh"
38
39#include <iostream>
40#include <cstdio>
41
42using namespace G4Analysis;
43
44// mutex in a file scope
45
46namespace {
47 //Mutex to lock master manager when merging H1 histograms
48 G4Mutex mergeH1Mutex = G4MUTEX_INITIALIZER;
49 //Mutex to lock master manager when merging H1 histograms
50 G4Mutex mergeH2Mutex = G4MUTEX_INITIALIZER;
51 //Mutex to lock master manager when merging H1 histograms
52 G4Mutex mergeH3Mutex = G4MUTEX_INITIALIZER;
53 //Mutex to lock master manager when merging P1 profiles
54 G4Mutex mergeP1Mutex = G4MUTEX_INITIALIZER;
55 //Mutex to lock master manager when merging P2 profiles
56 G4Mutex mergeP2Mutex = G4MUTEX_INITIALIZER;
57}
58
59G4RootAnalysisManager* G4RootAnalysisManager::fgMasterInstance = nullptr;
60G4ThreadLocal G4RootAnalysisManager* G4RootAnalysisManager::fgInstance = nullptr;
61
62//_____________________________________________________________________________
64{
65 if ( fgInstance == nullptr ) {
67 fgInstance = new G4RootAnalysisManager(isMaster);
68 }
69
70 return fgInstance;
71}
72
73//_____________________________________________________________________________
75{
76 return ( fgInstance != nullptr );
77}
78
79//_____________________________________________________________________________
81 : G4ToolsAnalysisManager("Root", isMaster),
82 fFileManager(nullptr),
83 fNtupleFileManager(nullptr)
84{
85 if ( ( isMaster && fgMasterInstance ) || ( fgInstance ) ) {
86 G4ExceptionDescription description;
87 description
88 << " "
89 << "G4RootAnalysisManager already exists."
90 << "Cannot create another instance.";
91 G4Exception("G4RootAnalysisManager::G4RootAnalysisManager()",
92 "Analysis_F001", FatalException, description);
93 }
94 if ( isMaster ) fgMasterInstance = this;
95 fgInstance = this;
96
97 // File manager
98 fFileManager = std::make_shared<G4RootFileManager>(fState);
99 SetFileManager(fFileManager);
100 fFileManager->SetBasketSize(fgkDefaultBasketSize);
101 fFileManager->SetBasketEntries(fgkDefaultBasketEntries);
102
103 // Ntuple file manager
104 fNtupleFileManager = std::make_shared<G4RootNtupleFileManager>(fState);
105 fNtupleFileManager->SetFileManager(fFileManager);
106 fNtupleFileManager->SetBookingManager(fNtupleBookingManager);
107}
108
109//_____________________________________________________________________________
111{
112 if ( fState.GetIsMaster() ) fgMasterInstance = nullptr;
113 fgInstance = nullptr;
114}
115
116//
117// private methods
118//
119
120//_____________________________________________________________________________
121G4bool G4RootAnalysisManager::WriteH1()
122{
123 auto h1Vector = fH1Manager->GetH1Vector();
124 auto hnVector = fH1Manager->GetHnVector();
125
126 if ( ! h1Vector.size() ) return true;
127
128 auto result = true;
129
130 if ( ! G4Threading::IsWorkerThread() ) {
131 result = WriteT(h1Vector, hnVector, "h1");
132 }
133 else {
134 // The worker manager just adds its histograms to the master
135 // This operation needs a lock
136 G4AutoLock lH1(&mergeH1Mutex);
137 fgMasterInstance->fH1Manager->AddH1Vector(h1Vector);
138 lH1.unlock();
139 }
140
141 return result;
142}
143
144//_____________________________________________________________________________
145G4bool G4RootAnalysisManager::WriteH2()
146{
147 auto h2Vector = fH2Manager->GetH2Vector();
148 auto hnVector = fH2Manager->GetHnVector();
149
150 if ( ! h2Vector.size() ) return true;
151
152 auto result = true;
153
154 if ( ! G4Threading::IsWorkerThread() ) {
155 result = WriteT(h2Vector, hnVector, "h2");
156 }
157 else {
158 // The worker manager just adds its histograms to the master
159 // This operation needs a lock
160 G4AutoLock lH2(&mergeH2Mutex);
161 fgMasterInstance->fH2Manager->AddH2Vector(h2Vector);
162 lH2.unlock();
163 }
164
165 return result;
166}
167
168//_____________________________________________________________________________
169G4bool G4RootAnalysisManager::WriteH3()
170{
171 auto h3Vector = fH3Manager->GetH3Vector();
172 auto hnVector = fH3Manager->GetHnVector();
173
174 if ( ! h3Vector.size() ) return true;
175
176 auto result = true;
177
178 if ( ! G4Threading::IsWorkerThread() ) {
179 result = WriteT(h3Vector, hnVector, "h3");
180 }
181 else {
182 // The worker manager just adds its histograms to the master
183 // This operation needs a lock
184 G4AutoLock lH3(&mergeH3Mutex);
185 fgMasterInstance->fH3Manager->AddH3Vector(h3Vector);
186 lH3.unlock();
187 }
188
189 return result;
190}
191
192//_____________________________________________________________________________
193G4bool G4RootAnalysisManager::WriteP1()
194{
195 auto p1Vector = fP1Manager->GetP1Vector();
196 auto hnVector = fP1Manager->GetHnVector();
197
198 if ( ! p1Vector.size() ) return true;
199
200 auto result = true;
201
202 if ( ! G4Threading::IsWorkerThread() ) {
203 result = WriteT(p1Vector, hnVector, "p1");
204 }
205 else {
206 // The worker manager just adds its histograms to the master
207 // This operation needs a lock
208 G4AutoLock lP1(&mergeP1Mutex);
209 fgMasterInstance->fP1Manager->AddP1Vector(p1Vector);
210 lP1.unlock();
211 }
212
213 return result;
214}
215
216//_____________________________________________________________________________
217G4bool G4RootAnalysisManager::WriteP2()
218{
219 auto p2Vector = fP2Manager->GetP2Vector();
220 auto hnVector = fP2Manager->GetHnVector();
221
222 if ( ! p2Vector.size() ) return true;
223
224 auto result = true;
225
226 if ( ! G4Threading::IsWorkerThread() ) {
227 result = WriteT(p2Vector, hnVector, "p2");
228 }
229 else {
230 // The worker manager just adds its histograms to the master
231 // This operation needs a lock
232 G4AutoLock lP2(&mergeP2Mutex);
233 fgMasterInstance->fP2Manager->AddP2Vector(p2Vector);
234 lP2.unlock();
235 }
236
237 return result;
238}
239
240//_____________________________________________________________________________
242{
243// Reset histograms and ntuple
244
245 auto finalResult = true;
246
247 auto result = G4ToolsAnalysisManager::Reset();
248 finalResult = finalResult && result;
249
250 result = fNtupleFileManager->Reset();
251 finalResult = result && finalResult;
252
253 return finalResult;
254}
255
256//
257// protected methods
258//
259
260//_____________________________________________________________________________
262{
263 // Create ntuple manager(s)
264 // and set it to base class which takes then their ownership
265 SetNtupleManager(fNtupleFileManager->CreateNtupleManager());
266
267 auto finalResult = true;
268
269 // Open file
270 if ( fNtupleFileManager->GetMergeMode() != G4NtupleMergeMode::kSlave ) {
271 auto result = fFileManager->OpenFile(fileName);
272 finalResult = finalResult && result;
273 }
274
275 // Open ntuple file(s) and create ntuples from bookings
276 auto result = fNtupleFileManager->ActionAtOpenFile(fFileManager->GetFullFileName());
277 finalResult = finalResult && result;
278
279 return finalResult;
280}
281
282//_____________________________________________________________________________
284{
285
286 auto finalResult = true;
287
288#ifdef G4VERBOSE
289 if ( fState.GetVerboseL4() )
290 fState.GetVerboseL4()->Message("write", "files", "");
291#endif
292
293 if ( ! fgMasterInstance &&
294 ( ( ! fH1Manager->IsEmpty() ) || ( ! fH2Manager->IsEmpty() ) ||
295 ( ! fH3Manager->IsEmpty() ) || ( ! fP1Manager->IsEmpty() ) ||
296 ( ! fP2Manager->IsEmpty() ) ) ) {
297 G4ExceptionDescription description;
298 description
299 << " " << "No master G4RootAnalysisManager instance exists."
300 << G4endl
301 << " " << "Histogram/profile data will not be merged.";
302 G4Exception("G4RootAnalysisManager::Write()",
303 "Analysis_W031", JustWarning, description);
304 }
305
306 // H1
307 auto result = WriteH1();
308 finalResult = finalResult && result;
309
310 // H2
311 result = WriteH2();
312 finalResult = finalResult && result;
313
314 // H3
315 result = WriteH3();
316 finalResult = finalResult && result;
317
318 // P1
319 result = WriteP1();
320 finalResult = finalResult && result;
321
322 // P2
323 result = WriteP2();
324 finalResult = finalResult && result;
325
326 // Ntuples
327 result = fNtupleFileManager->ActionAtWrite();
328 finalResult = finalResult && result;
329
330 // File
331 if ( fNtupleFileManager->GetMergeMode() != G4NtupleMergeMode::kSlave ) {
332 // write all open files
333 result = fFileManager->WriteFiles();
334 finalResult = finalResult && result;
335 }
336
337 // Write ASCII if activated
338 if ( IsAscii() ) {
339 result = WriteAscii(fFileManager->GetFileName());
340 finalResult = finalResult && result;
341 }
342
343#ifdef G4VERBOSE
344 if ( fState.GetVerboseL2() ) {
345 fState.GetVerboseL2()->Message("write", "files", "", finalResult);
346 }
347#endif
348
349 return finalResult;
350}
351
352//_____________________________________________________________________________
354{
355 auto finalResult = true;
356
357#ifdef G4VERBOSE
358 if ( fState.GetVerboseL4() )
359 fState.GetVerboseL4()->Message("close", "files", "");
360#endif
361
362 auto result = true;
363 if ( reset ) {
364 result = Reset();
365 if ( ! result ) {
366 G4ExceptionDescription description;
367 description << " " << "Resetting data failed";
368 G4Exception("G4RootAnalysisManager::CloseFile()",
369 "Analysis_W021", JustWarning, description);
370 }
371 }
372 finalResult = finalResult && result;
373
374 result = fNtupleFileManager->ActionAtCloseFile(reset);
375 finalResult = finalResult && result;
376
377 if ( fNtupleFileManager->GetMergeMode() != G4NtupleMergeMode::kSlave ) {
378 // close all open files
379 result = fFileManager->CloseFiles();
380 finalResult = finalResult && result;
381 }
382
383 // No files clean-up in sequential mode
384 if ( ! G4Threading::IsMultithreadedApplication() ) return finalResult;
385
386 G4bool isNtupleManagerEmpty = fNtupleBookingManager->IsEmpty();
387
388 // Delete files if empty in MT mode
389 if ( ( fState.GetIsMaster() &&
391 fP1Manager->IsEmpty() && fP2Manager->IsEmpty() && isNtupleManagerEmpty ) ||
392 ( ( ! fState.GetIsMaster() ) && isNtupleManagerEmpty &&
393 fNtupleFileManager->GetMergeMode() == G4NtupleMergeMode::kNone ) ) {
394
395 result = ! std::remove(fFileManager->GetFullFileName());
396 // std::remove returns 0 when success
397 if ( ! result ) {
398 G4ExceptionDescription description;
399 description << " " << "Removing file "
400 << fFileManager->GetFullFileName() << " failed";
401 G4Exception("G4RootAnalysisManager::CloseFile()",
402 "Analysis_W021", JustWarning, description);
403 }
404 finalResult = finalResult && result;
405#ifdef G4VERBOSE
406 if ( fState.GetVerboseL1() )
408 ->Message("delete", "empty file", fFileManager->GetFullFileName());
409#endif
410 }
411 else {
412#ifdef G4VERBOSE
413 if ( fState.GetVerboseL2() )
415 ->Message("close", "files", "");
416#endif
417 }
418
419 return finalResult;
420}
421
422//
423// public methods
424//
425
426//_____________________________________________________________________________
428 G4int nofNtupleFiles)
429{
430 fNtupleFileManager->SetNtupleMerging(mergeNtuples, nofNtupleFiles);
431}
432
433//_____________________________________________________________________________
435{
436 fNtupleFileManager->SetNtupleRowWise(rowWise, rowMode);
437}
438
439//_____________________________________________________________________________
440void G4RootAnalysisManager::SetBasketSize(unsigned int basketSize)
441{
442 fFileManager->SetBasketSize(basketSize);
443}
444
445//_____________________________________________________________________________
446void G4RootAnalysisManager::SetBasketEntries(unsigned int basketEntries)
447{
448 fFileManager->SetBasketEntries(basketEntries);
449}
@ 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
const G4AnalysisVerbose * GetVerboseL2() const
const G4AnalysisVerbose * GetVerboseL1() const
const G4AnalysisVerbose * GetVerboseL4() const
void Message(const G4String &action, const G4String &object, const G4String &objectName, G4bool success=true) const
const std::vector< G4HnInformation * > & GetHnVector() const
const std::vector< tools::histo::h1d * > & GetH1Vector() const
void AddH1Vector(const std::vector< tools::histo::h1d * > &h1Vector)
const std::vector< tools::histo::h2d * > & GetH2Vector() const
const std::vector< G4HnInformation * > & GetHnVector() const
void AddH2Vector(const std::vector< tools::histo::h2d * > &h2Vector)
void AddH3Vector(const std::vector< tools::histo::h3d * > &h3Vector)
const std::vector< G4HnInformation * > & GetHnVector() const
const std::vector< tools::histo::h3d * > & GetH3Vector() const
const std::vector< G4HnInformation * > & GetHnVector() const
void AddP1Vector(const std::vector< tools::histo::p1d * > &p1Vector)
const std::vector< tools::histo::p1d * > & GetP1Vector() const
const std::vector< G4HnInformation * > & GetHnVector() const
const std::vector< tools::histo::p2d * > & GetP2Vector() const
void AddP2Vector(const std::vector< tools::histo::p2d * > &p2Vector)
virtual void SetBasketSize(unsigned int basketSize) override
virtual void SetNtupleMerging(G4bool mergeNtuples, G4int nofReducedNtupleFiles=0) override
virtual G4bool CloseFileImpl(G4bool reset) override
static G4RootAnalysisManager * Instance()
virtual G4bool WriteImpl() override
G4RootAnalysisManager(G4bool isMaster=true)
virtual G4bool OpenFileImpl(const G4String &fileName) override
virtual void SetNtupleRowWise(G4bool rowWise, G4bool rowMode=true) override
virtual void SetBasketEntries(unsigned int basketEntries) override
G4bool IsEmpty() const
static constexpr unsigned int fgkDefaultBasketSize
std::shared_ptr< G4NtupleBookingManager > fNtupleBookingManager
G4AnalysisManagerState fState
void SetFileManager(std::shared_ptr< G4VFileManager > fileManager)
G4bool WriteAscii(const G4String &fileName)
void SetNtupleManager(std::shared_ptr< G4VNtupleManager > ntupleManager)
static constexpr unsigned int fgkDefaultBasketEntries
G4bool IsWorkerThread()
Definition: G4Threading.cc:123
G4bool IsMultithreadedApplication()
Definition: G4Threading.cc:130
#define G4ThreadLocal
Definition: tls.hh:77