Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4GenericAnalysisManager.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
31#include "G4AnalysisVerbose.hh"
36
37#include <iostream>
38#include <cstdio>
39
40using namespace G4Analysis;
41
42// mutex in a file scope
43
44namespace {
45
46//Mutex to lock master manager when merging histograms
47G4Mutex mergeHnMutex = G4MUTEX_INITIALIZER;
48
49void WriteHnException(const G4String& hnType, G4int id)
50{
51 G4String inFunction = "G4GenericAnalysisManager::Write" + hnType;
52 G4ExceptionDescription description;
53 description << "Failed to get " << hnType << " id " << id << G4endl;
54 G4Exception(inFunction, "Analysis_W022", JustWarning, description);
55}
56
57}
58
59G4GenericAnalysisManager* G4GenericAnalysisManager::fgMasterInstance = nullptr;
60G4ThreadLocal G4GenericAnalysisManager* G4GenericAnalysisManager::fgInstance = nullptr;
61
62//_____________________________________________________________________________
64{
65 if ( fgInstance == nullptr ) {
67 fgInstance = new G4GenericAnalysisManager(isMaster);
68 }
69
70 return fgInstance;
71}
72
73//_____________________________________________________________________________
75{
76 return ( fgInstance != nullptr );
77}
78
79//_____________________________________________________________________________
81 : G4ToolsAnalysisManager("", isMaster),
82 fFileManager(nullptr),
83 fNtupleFileManager(nullptr)
84{
85 if ( ( isMaster && fgMasterInstance ) || ( fgInstance ) ) {
86 G4ExceptionDescription description;
87 description
88 << " "
89 << "G4GenericAnalysisManager already exists."
90 << "Cannot create another instance.";
91 G4Exception("G4GenericAnalysisManager::G4GenericAnalysisManager()",
92 "Analysis_F001", FatalException, description);
93 }
94 if ( isMaster ) fgMasterInstance = this;
95 fgInstance = this;
96
97 // File manager
98 fFileManager = std::make_shared<G4GenericFileManager>(fState);
99 SetFileManager(fFileManager);
100}
101
102//_____________________________________________________________________________
104{
105 if ( fState.GetIsMaster() ) fgMasterInstance = nullptr;
106 fgInstance = nullptr;
107}
108
109//
110// private methods
111//
112
113//_____________________________________________________________________________
114void G4GenericAnalysisManager::CreateNtupleFileManager(const G4String& fileName)
115{
116 if ( fNtupleFileManager ) {
117 G4ExceptionDescription description;
118 description
119 << " "
120 << "The ntuple file manager already exists.";
121 G4Exception("G4GenericAnalysisManager::CreateNtupleFileManager",
122 "Analysis_W002", JustWarning, description);
123 return;
124 }
125
126 auto fileType = GetExtension(fileName);
127 auto output = G4Analysis::GetOutput(fileType);
128 if ( output == G4AnalysisOutput::kNone ) {
129 G4ExceptionDescription description;
130 description
131 << "The file type " << fileType << "is not supported.";
132 G4Exception("G4GenericAnalysisManager::CreateNtupleFileManager",
133 "Analysis_W051", JustWarning, description);
134 return;
135 }
136
137 // Set file type to booked ntuples
138 fNtupleBookingManager->SetFileType(fileType);
139
140#ifdef G4VERBOSE
141 if ( fState.GetVerboseL4() ) {
142 fState.GetVerboseL4()->Message("create", "ntuple file manager", fileType);
143 }
144#endif
145
146 fNtupleFileManager = fFileManager->CreateNtupleFileManager(output);
147 if (fNtupleFileManager) {
148 fNtupleFileManager->SetBookingManager(fNtupleBookingManager);
149 }
150
151 if ( fNtupleFileManager->IsNtupleMergingSupported() ) {
152 // set merginng
153 fNtupleFileManager->SetNtupleMerging(fMergeNtuples, fNofNtupleFiles);
154 fNtupleFileManager->SetNtupleRowWise(fNtupleRowWise, fNtupleRowMode);
155 fNtupleFileManager->SetBasketSize(fBasketSize);
156 fNtupleFileManager->SetBasketEntries(fBasketEntries);
157 }
158 else if ( fIsNtupleMergingSet && fMergeNtuples ) {
159 G4ExceptionDescription description;
160 description
161 << " " << "Ntuple merging is not available with "
162 << fileType << " output." << G4endl
163 << " " << "Setting is ignored.";
164 G4Exception("G4GenericAnalysisManager::CreateNtupleFileManager",
165 "Analysis_W041", JustWarning, description);
166 }
167
168#ifdef G4VERBOSE
169 if ( fState.GetVerboseL3() ) {
170 fState.GetVerboseL3()->Message("create", "ntuple file manager", fileType, true);
171 }
172#endif
173}
174
175//
176// protected methods
177//
178
179//_____________________________________________________________________________
181{
182 // Add file name extension, if missing
183 auto fullFileName = fileName;
184 if ( ! GetExtension(fileName).size() ) {
185 // G4cout << "File type is not defined, using default: " << fFileManager->GetDefaultFileType() << G4endl;
186 fullFileName = fileName + "." + fFileManager->GetDefaultFileType();
187 }
188
189#ifdef G4VERBOSE
190 if ( fState.GetVerboseL4() ) {
191 fState.GetVerboseL4()->Message("open (generic)", "file", fileName);
192 }
193#endif
194
195 // Create ntuple file manager if there are booked ntuples
196 if (! fNtupleFileManager) {
197 CreateNtupleFileManager(fullFileName);
198 }
199
200 // Create ntuple manager
201 // and set it to base class which takes then its ownership
202 if (fNtupleFileManager) {
203 SetNtupleManager(fNtupleFileManager->CreateNtupleManager());
204 }
205
206 auto finalResult = true;
207
208 // Open file for histograms/profiles
209 auto result = fFileManager->OpenFile(fullFileName);
210 finalResult = finalResult && result;
211
212 // Open ntuple file(s) and create ntuples from bookings
213 if (fNtupleFileManager) {
214 result = fNtupleFileManager->ActionAtOpenFile(fullFileName);
215 finalResult = finalResult && result;
216 }
217
218#ifdef G4VERBOSE
219 if ( fState.GetVerboseL3() ) {
220 fState.GetVerboseL3()->Message("open (generic)", "file", fileName, finalResult);
221 }
222#endif
223 return finalResult;
224}
225
226//_____________________________________________________________________________
228{
229#ifdef G4VERBOSE
230 if ( fState.GetVerboseL4() ) {
231 fState.GetVerboseL4()->Message("write (generic)", "files", "");
232 }
233#endif
234
235 auto finalResult = true;
236 auto result = true;
237
238 if ( ! fgMasterInstance &&
239 ( ( ! fH1Manager->IsEmpty() ) || ( ! fH2Manager->IsEmpty() ) ||
240 ( ! fH3Manager->IsEmpty() ) || ( ! fP1Manager->IsEmpty() ) ||
241 ( ! fP2Manager->IsEmpty() ) ) ) {
242 G4ExceptionDescription description;
243 description
244 << " " << "No master G4GenericAnalysisManager instance exists."
245 << G4endl
246 << " " << "Histogram/profile data will not be merged.";
247 G4Exception("G4GenericAnalysisManager::Write()",
248 "Analysis_W031", JustWarning, description);
249 }
250
252 result = Merge();
253 finalResult = finalResult && result;
254 }
255 else {
256 // GO ON
257
258 // Open all files registered with objects
259 fFileManager->OpenFiles();
260
261 // Write all histograms/profile on master
262 //
263 result = fFileManager->WriteT(fH1Manager->GetH1Vector(), fH1Manager->GetHnVector());
264 finalResult = finalResult && result;
265
266 result = fFileManager->WriteT(fH2Manager->GetH2Vector(), fH2Manager->GetHnVector());
267 finalResult = finalResult && result;
268
269 result = fFileManager->WriteT(fH3Manager->GetH3Vector(), fH3Manager->GetHnVector());
270 finalResult = finalResult && result;
271
272 result = fFileManager->WriteT(fP1Manager->GetP1Vector(), fP1Manager->GetHnVector());
273 finalResult = finalResult && result;
274
275 result = fFileManager->WriteT(fP2Manager->GetP2Vector(), fP2Manager->GetHnVector());
276 finalResult = finalResult && result;
277 }
278
279 // Ntuples
280 if (fNtupleFileManager) {
281 result = fNtupleFileManager->ActionAtWrite();
282 finalResult = finalResult && result;
283 }
284
285 // File
286 result = fFileManager->WriteFiles();
287 finalResult = finalResult && result;
288
289 // Write ASCII if activated
290 if ( IsAscii() ) {
291 result = WriteAscii(fFileManager->GetFileName());
292 finalResult = finalResult && result;
293 }
294
295#ifdef G4VERBOSE
296 if ( fState.GetVerboseL3() ) {
297 fState.GetVerboseL3()->Message("write (generic)", "files", "", finalResult);
298 }
299#endif
300
301 return finalResult;
302}
303
304//_____________________________________________________________________________
306{
307 auto finalResult = true;
308
309#ifdef G4VERBOSE
310 if ( fState.GetVerboseL4() ) {
311 fState.GetVerboseL4()->Message("close (generic)", "files", "");
312 }
313#endif
314
315 if (fNtupleFileManager) {
316 auto result = fNtupleFileManager->ActionAtCloseFile(reset);
317 finalResult = finalResult && result;
318 }
319
320 // close file
321 auto result = fFileManager->CloseFiles();
322 if ( ! result ) {
323 G4ExceptionDescription description;
324 description << " " << "Closing files failed";
325 G4Exception("G4GenericAnalysisManager::CloseFile()",
326 "Analysis_W021", JustWarning, description);
327 }
328 finalResult = finalResult && result;
329
330 // delete empty files
331 result = fFileManager->DeleteEmptyFiles();
332 if ( ! result ) {
333 G4ExceptionDescription description;
334 description << " " << "Deleting empty files failed";
335 G4Exception("G4GenericAnalysisManager::CloseFile()",
336 "Analysis_W021", JustWarning, description);
337 }
338 finalResult = finalResult && result;
339
340 if ( reset ) {
341 result = Reset();
342 if ( ! result ) {
343 G4ExceptionDescription description;
344 description << " " << "Resetting data failed";
345 G4Exception("G4GenericAnalysisManager::CloseFile()",
346 "Analysis_W021", JustWarning, description);
347 }
348 }
349 finalResult = finalResult && result;
350
351#ifdef G4VERBOSE
352 if ( fState.GetVerboseL3() ) {
353 fState.GetVerboseL3()->Message("close (generic)", "files", "", finalResult);
354 }
355#endif
356
357 return finalResult;
358}
359
360//_____________________________________________________________________________
362{
363// Reset histograms and ntuple
364
365 auto finalResult = true;
366
367 auto result = G4ToolsAnalysisManager::Reset();
368 finalResult = finalResult && result;
369
370 result = fNtupleFileManager->Reset();
371 finalResult = result && finalResult;
372
373 return finalResult;
374}
375
376//_____________________________________________________________________________
378{
379 // Nothing to be done on master
380 if ( ! G4Threading::IsWorkerThread() ) return false;
381
382#ifdef G4VERBOSE
383 if ( fState.GetVerboseL4() ) {
384 fState.GetVerboseL4()->Message("merge (generic) on worker", "histograms", "");
385 }
386#endif
387
388 // The worker manager just adds its histograms to the master
389 fH1Manager->Merge(mergeHnMutex, fgMasterInstance->fH1Manager);
390 fH2Manager->Merge(mergeHnMutex, fgMasterInstance->fH2Manager);
391 fH3Manager->Merge(mergeHnMutex, fgMasterInstance->fH3Manager);
392 fP1Manager->Merge(mergeHnMutex, fgMasterInstance->fP1Manager);
393 fP2Manager->Merge(mergeHnMutex, fgMasterInstance->fP2Manager);
394
395#ifdef G4VERBOSE
396 if ( fState.GetVerboseL3() ) {
397 fState.GetVerboseL3()->Message("merge (generic) on worker", "histograms", "", true);
398 }
399#endif
400
401 return true;
402}
403
404//_____________________________________________________________________________
406{
407 // Experimental extra write
408
409 // Do not write histo on worker (redundant and fails in hdf5 )
410 // If default file is not used, users have to call Merge from their code
411 if ( G4Threading::IsWorkerThread() ) return false;
412
413 auto h1d = GetH1(id, false);
414 if ( ! h1d ) {
415 WriteHnException("H1", id);
416 return false;
417 }
418
419 auto h1Name = GetH1Name(id);
420 return fFileManager->WriteTExtra<tools::histo::h1d>(fileName, h1d, h1Name);
421}
422
423//_____________________________________________________________________________
425{
426 // Experimental extra write
427
428 // Do not write histo on worker (redundant and fails in hdf5 )
429 // If default file is not used, users have to call Merge from their code
430 if ( G4Threading::IsWorkerThread() ) return false;
431
432 auto h2d = GetH2(id, false);
433 if ( ! h2d ) {
434 WriteHnException("H2", id);
435 return false;
436 }
437
438 auto h2Name = GetH2Name(id);
439 return fFileManager->WriteTExtra<tools::histo::h2d>(fileName, h2d, h2Name);
440}
441//_____________________________________________________________________________
443{
444 // Experimental extra write
445
446 // Do not write histo on worker (redundant and fails in hdf5 )
447 // If default file is not used, users have to call Merge from their code
448 if ( G4Threading::IsWorkerThread() ) return false;
449
450 auto h3d = GetH3(id, false);
451 if ( ! h3d ) {
452 WriteHnException("H3", id);
453 return false;
454 }
455
456 auto h3Name = GetH3Name(id);
457 return fFileManager->WriteTExtra<tools::histo::h3d>(fileName, h3d, h3Name);
458}
459
460//_____________________________________________________________________________
462{
463 // Experimental extra write
464
465 // Do not write histo on worker (redundant and fails in hdf5 )
466 // If default file is not used, users have to call Merge from their code
467 if ( G4Threading::IsWorkerThread() ) return false;
468
469 auto p1d = GetP1(id, false);
470 if ( ! p1d ) {
471 WriteHnException("P1", id);
472 return false;
473 }
474
475 auto p1Name = GetP1Name(id);
476 return fFileManager->WriteTExtra<tools::histo::p1d>(fileName, p1d, p1Name);
477}
478//_____________________________________________________________________________
480{
481 // Experimental extra write
482
483 // Do not write histo on worker (redundant and fails in hdf5 )
484 // If default file is not used, users have to call Merge from their code
485 if ( G4Threading::IsWorkerThread() ) return false;
486
487 auto p2d = GetP2(id, false);
488 if ( ! p2d ) {
489 WriteHnException("P2", id);
490 return false;
491 }
492
493 auto p2Name = GetP2Name(id);
494 return fFileManager->WriteTExtra<tools::histo::p2d>(fileName, p2d, p2Name);
495}
@ 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 * GetVerboseL3() const
const G4AnalysisVerbose * GetVerboseL4() const
void Message(const G4String &action, const G4String &object, const G4String &objectName, G4bool success=true) const
G4bool WriteP2(G4int id, const G4String &fileName)
G4bool WriteH2(G4int id, const G4String &fileName)
virtual G4bool CloseFileImpl(G4bool reset=true) override
G4bool WriteH3(G4int id, const G4String &fileName)
G4bool WriteH1(G4int id, const G4String &fileName)
G4GenericAnalysisManager(G4bool isMaster=true)
virtual G4bool WriteImpl() final
G4bool WriteP1(G4int id, const G4String &fileName)
static G4GenericAnalysisManager * Instance()
virtual G4bool OpenFileImpl(const G4String &fileName) override
const std::vector< G4HnInformation * > & GetHnVector() const
const std::vector< tools::histo::h1d * > & GetH1Vector() const
const std::vector< tools::histo::h2d * > & GetH2Vector() const
const std::vector< G4HnInformation * > & GetHnVector() const
const std::vector< G4HnInformation * > & GetHnVector() const
const std::vector< tools::histo::h3d * > & GetH3Vector() const
const std::vector< G4HnInformation * > & GetHnVector() const
const std::vector< tools::histo::p1d * > & GetP1Vector() const
const std::vector< G4HnInformation * > & GetHnVector() const
const std::vector< tools::histo::p2d * > & GetP2Vector() const
G4bool IsEmpty() const
void Merge(G4Mutex &mergeMutex, G4THnManager< T > *masterInstance)
tools::histo::h3d * GetH3(G4int id, G4bool warn=true, G4bool onlyIfActive=true) const
tools::histo::p1d * GetP1(G4int id, G4bool warn=true, G4bool onlyIfActive=true) const
tools::histo::p2d * GetP2(G4int id, G4bool warn=true, G4bool onlyIfActive=true) const
tools::histo::h2d * GetH2(G4int id, G4bool warn=true, G4bool onlyIfActive=true) const
tools::histo::h1d * GetH1(G4int id, G4bool warn=true, G4bool onlyIfActive=true) const
G4String GetH1Name(G4int id) const
G4String GetH2Name(G4int id) const
G4String GetP2Name(G4int id) const
std::shared_ptr< G4NtupleBookingManager > fNtupleBookingManager
G4AnalysisManagerState fState
G4String GetP1Name(G4int id) const
G4String GetH3Name(G4int id) const
void SetFileManager(std::shared_ptr< G4VFileManager > fileManager)
G4bool WriteAscii(const G4String &fileName)
void SetNtupleManager(std::shared_ptr< G4VNtupleManager > ntupleManager)
G4String GetExtension(const G4String &fileName, const G4String &defaultExtension="")
G4AnalysisOutput GetOutput(const G4String &outputName, G4bool warn=true)
G4bool IsWorkerThread()
Definition: G4Threading.cc:123
#define G4ThreadLocal
Definition: tls.hh:77