Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4RootNtupleFileManager.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, 15/09/2020 ([email protected])
28
30#include "G4RootFileManager.hh"
34#include "G4VAnalysisManager.hh"
35#include "G4AnalysisVerbose.hh"
38
39#include "G4Threading.hh"
40#include "G4AutoLock.hh"
41
42#include <iostream>
43#include <cstdio>
44
45namespace {
46
47void MergingException(const G4String& functionName,
48 G4ExceptionDescription& description)
49{
50 G4String inFunction = "G4RootNtupleFileManager::" + functionName;
51 G4Exception(inFunction, "Analysis_W013", JustWarning, description);
52}
53
54}
55
56using namespace G4Analysis;
57using std::make_shared;
58
59G4RootNtupleFileManager* G4RootNtupleFileManager::fgMasterInstance = nullptr;
60
61//_____________________________________________________________________________
63 : G4VNtupleFileManager(state, "root"),
64 fIsInitialized(false),
65 fNofNtupleFiles(0),
66 fNtupleRowWise(false),
67 fNtupleRowMode(true),
68 fNtupleMergeMode(G4NtupleMergeMode::kNone),
69 fNtupleManager(nullptr),
70 fSlaveNtupleManager(nullptr),
71 fFileManager(nullptr)
72{
73 if ( G4Threading::IsMasterThread() && fgMasterInstance ) {
74 G4ExceptionDescription description;
75 description
76 << " "
77 << "G4RootNtupleFileManager already exists."
78 << "Cannot create another instance.";
79 G4Exception("G4RootNtupleFileManager::G4RootNtupleFileManager()",
80 "Analysis_F001", FatalException, description);
81 }
82 if ( G4Threading::IsMasterThread() ) fgMasterInstance = this;
83
84 // Do not merge ntuples by default
85 // Merging may require user code migration as analysis manager
86 // must be created both on master and workers.
87 auto mergeNtuples = false;
88 SetNtupleMergingMode(mergeNtuples, fNofNtupleFiles);
89}
90
91//_____________________________________________________________________________
93{
94 if ( fState.GetIsMaster() ) fgMasterInstance = nullptr;
95}
96
97//
98// private methods
99//
100
101//_____________________________________________________________________________
102void G4RootNtupleFileManager::SetNtupleMergingMode(G4bool mergeNtuples,
103 G4int nofNtupleFiles)
104
105{
106#ifdef G4VERBOSE
107 if ( fState.GetVerboseL4() ) {
108 fState.GetVerboseL4()->Message("set", "ntuple merging mode", "");
109 }
110#endif
111
112 auto canMerge = true;
113
114 // Illegal situations
115 if ( mergeNtuples && ( ! G4Threading::IsMultithreadedApplication() ) ) {
116 G4ExceptionDescription description;
117 description
118 << "Merging ntuples is not applicable in sequential application." << G4endl
119 << "Setting was ignored.";
120 MergingException("SetNtupleMergingMode", description);
121 canMerge = false;
122 }
123
124 // Illegal situations
125 if ( mergeNtuples && G4Threading::IsMultithreadedApplication() &&
126 ( ! fgMasterInstance ) ) {
127 G4ExceptionDescription description;
128 description
129 << "Merging ntuples requires G4AnalysisManager instance on master." << G4endl
130 << "Setting was ignored.";
131 MergingException("SetNtupleMergingMode", description);
132 canMerge = false;
133 }
134
135 G4String mergingMode;
136 if ( ( ! mergeNtuples ) || ( ! canMerge ) ) {
137 fNtupleMergeMode = G4NtupleMergeMode::kNone;
138 mergingMode = "G4NtupleMergeMode::kNone";
139 }
140 else {
141 // Set the number of reduced ntuple files
142 fNofNtupleFiles = nofNtupleFiles;
143
144 // Check the number of reduced ntuple files
145 if ( fNofNtupleFiles < 0 ) {
146 G4ExceptionDescription description;
147 description
148 << "Number of reduced files must be [0, nofThreads]." << G4endl
149 << "Cannot set " << nofNtupleFiles << " files" << G4endl
150 << "Ntuples will be merged in a single file.";
151 MergingException("SetNtupleMergingMode", description);
152 fNofNtupleFiles = 0;
153 }
154
155 // Forced merging mode
156 G4bool isMaster = ! G4Threading::IsWorkerThread();
157 if ( isMaster ) {
158 fNtupleMergeMode = G4NtupleMergeMode::kMain;
159 mergingMode = "G4NtupleMergeMode::kMain";
160 } else {
161 fNtupleMergeMode = G4NtupleMergeMode::kSlave;
162 mergingMode = "G4NtupleMergeMode::kSlave";
163 }
164 }
165
166#ifdef G4VERBOSE
167 if ( fState.GetVerboseL2() ) {
168 fState.GetVerboseL2()->Message("set", "ntuple merging mode", mergingMode);
169 }
170#endif
171}
172
173//_____________________________________________________________________________
174G4int G4RootNtupleFileManager::GetNtupleFileNumber()
175{
176 if ( ! fNofNtupleFiles ) return 0;
177
178 G4int nofMainManagers = fNofNtupleFiles;
179 if ( ! nofMainManagers ) nofMainManagers = 1;
180
181 auto fileNumber = G4Threading::G4GetThreadId() % nofMainManagers;
182 return fileNumber;
183}
184
185//_____________________________________________________________________________
186G4bool G4RootNtupleFileManager::CloseNtupleFiles()
187{
188 // Close ntuple files
189
190 auto finalResult = true;
191 auto ntupleVector = fNtupleManager->GetNtupleDescriptionVector();
192 for ( auto ntupleDescription : ntupleVector) {
193 auto result = fFileManager->CloseNtupleFile(ntupleDescription);
194 finalResult = finalResult && result;
195 }
196
197 return finalResult;
198}
199
200//
201// public methods
202//
203
204//_____________________________________________________________________________
206 G4int nofNtupleFiles)
207
208{
209 if ( fIsInitialized ) {
210 G4ExceptionDescription description;
211 description
212 << "Cannot change merging mode." << G4endl
213 << "The function must be called before OpenFile().";
214 MergingException("SetNtupleMerging", description);
215 return;
216 }
217
218 // Set ntuple merging mode
219 SetNtupleMergingMode(mergeNtuples, nofNtupleFiles);
220}
221
222//_____________________________________________________________________________
224{
225#ifdef G4VERBOSE
226 // Print info even when setting makes no effect
227 // (as we do not get printed the default setting in the output)
228 G4String rowWiseMode;
229 if ( rowWise ) {
230 rowWiseMode = "row-wise with extra branch";
231 }
232 else if ( rowMode ) {
233 rowWiseMode = "row-wise";
234 }
235 else {
236 rowWiseMode = "column-wise";
237 }
238
239 if ( fState.GetVerboseL1() )
241 ->Message("set", "ntuple merging row mode", rowWiseMode);
242#endif
243
244 // Do nothing if the mode is not changed
245 if ( fNtupleRowWise == rowWise && fNtupleRowMode == rowMode ) return;
246
247 fNtupleRowWise = rowWise;
248 fNtupleRowMode = rowMode;
249
250 if ( fNtupleManager ) {
251 fNtupleManager->SetNtupleRowWise(rowWise, rowMode);
252 }
253
254 if ( fSlaveNtupleManager ) {
255 fSlaveNtupleManager->SetNtupleRowWise(rowWise, rowMode);
256 }
257}
258
259//_____________________________________________________________________________
260void G4RootNtupleFileManager::SetBasketSize(unsigned int basketSize)
261{
262 fFileManager->SetBasketSize(basketSize);
263}
264
265//_____________________________________________________________________________
266void G4RootNtupleFileManager::SetBasketEntries(unsigned int basketEntries)
267{
268 fFileManager->SetBasketEntries(basketEntries);
269}
270
271//_____________________________________________________________________________
272std::shared_ptr<G4VNtupleManager> G4RootNtupleFileManager::CreateNtupleManager()
273{
274// Create and return ntuple manager.
275// If ntuple merging is activated, managers of different types are created
276// on master/worker.
277
278#ifdef G4VERBOSE
279 if ( fState.GetVerboseL4() )
280 fState.GetVerboseL4()->Message("create", "ntuple manager", "");
281#endif
282
283 // Check that file manager and anaysis manager are set !
284
285 std::shared_ptr<G4VNtupleManager> activeNtupleManager = nullptr;
286 switch ( fNtupleMergeMode )
287 {
288 case G4NtupleMergeMode::kNone:
289 fNtupleManager
290 = make_shared<G4RootNtupleManager>(
291 fState, fBookingManager, 0, 0, fNtupleRowWise, fNtupleRowMode);
292 fNtupleManager->SetFileManager(fFileManager);
293 activeNtupleManager = fNtupleManager;
294 break;
295
296 case G4NtupleMergeMode::kMain: {
297 G4int nofMainManagers = fNofNtupleFiles;
298 if ( ! nofMainManagers ) nofMainManagers = 1;
299 // create one manager if merging required into the histos & profiles files
300 fNtupleManager
301 = make_shared<G4RootNtupleManager>(
302 fState, fBookingManager, nofMainManagers, fNofNtupleFiles, fNtupleRowWise, fNtupleRowMode);
303 fNtupleManager->SetFileManager(fFileManager);
304 activeNtupleManager = fNtupleManager;
305 break;
306 }
307
308 case G4NtupleMergeMode::kSlave:
309 fNtupleManager = fgMasterInstance->fNtupleManager;
310 // The master class is used only in Get* functions
311 auto mainNtupleManager
312 = fNtupleManager->GetMainNtupleManager(GetNtupleFileNumber());
313 fSlaveNtupleManager
314 = make_shared<G4RootPNtupleManager>(
315 fState, fgMasterInstance->fBookingManager, mainNtupleManager, fNtupleRowWise, fNtupleRowMode);
316 activeNtupleManager = fSlaveNtupleManager;
317 break;
318 }
319
320#ifdef G4VERBOSE
321 if ( fState.GetVerboseL3() ) {
322 G4String mergeMode;
323 switch ( fNtupleMergeMode ) {
324 case G4NtupleMergeMode::kNone:
325 mergeMode = "";
326 break;
327 case G4NtupleMergeMode::kMain:
328 mergeMode = "main ";
329 break;
330 case G4NtupleMergeMode::kSlave:
331 mergeMode = "slave ";
332 break;
333 }
334 fState.GetVerboseL3()->Message("create", mergeMode + "ntuple manager", "");
335 }
336#endif
337
338 fIsInitialized = true;
339
340 return activeNtupleManager;
341}
342
343//_____________________________________________________________________________
344#ifdef G4VERBOSE
346#else
348#endif
349{
350 // Check if fNtupleBookingManager is set
351
352 auto finalResult = true;
353
354 if ( fNtupleMergeMode == G4NtupleMergeMode::kNone ||
355 fNtupleMergeMode == G4NtupleMergeMode::kMain ) {
356
357#ifdef G4VERBOSE
358 G4String objectType = "analysis file";
359 if ( fNtupleMergeMode == G4NtupleMergeMode::kMain ) {
360 objectType = "main analysis file";
361 }
362 if ( fState.GetVerboseL4() )
363 fState.GetVerboseL4()->Message("open", objectType, fileName);
364#endif
365
366 // Creating files is triggered from CreateNtuple
367 fNtupleManager->CreateNtuplesFromBooking(
368 fBookingManager->GetNtupleBookingVector());
369
370#ifdef G4VERBOSE
371 if ( fState.GetVerboseL1() ) {
372 fState.GetVerboseL1()->Message("open", objectType, fileName, finalResult);
373 }
374#endif
375 }
376
377 if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave ) {
378 // G4cout << "Going to create slave ntuples from main" << G4endl;
379 fSlaveNtupleManager->CreateNtuplesFromMain();
380 }
381
382 return finalResult;
383}
384
385//_____________________________________________________________________________
387{
388 if ( fNtupleMergeMode == G4NtupleMergeMode::kNone ) {
389 return true;
390 }
391
392 auto finalResult = true;
393
394 G4String ntupleType;
395 if ( fNtupleMergeMode == G4NtupleMergeMode::kMain ) ntupleType = "main ntuples";
396 if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave ) ntupleType = "slave ntuples";
397
398#ifdef G4VERBOSE
399 if ( fState.GetVerboseL4() )
400 fState.GetVerboseL4()->Message("merge", ntupleType, "");
401#endif
402
403 if ( fNtupleMergeMode == G4NtupleMergeMode::kMain ) {
404 auto result = fNtupleManager->Merge();
405 finalResult = result && finalResult;
406 }
407
408 if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave ) {
409 auto result = fSlaveNtupleManager->Merge();
410 finalResult = result && finalResult;
411 }
412
413#ifdef G4VERBOSE
414 if ( fState.GetVerboseL1() )
415 fState.GetVerboseL1()->Message("merge", ntupleType, "");
416#endif
417
418 return finalResult;
419}
420
421//_____________________________________________________________________________
423{
424 auto finalResult = true;
425
426 // close files
427 if ( fNtupleMergeMode != G4NtupleMergeMode::kSlave ) {
428 auto result = CloseNtupleFiles();
429 finalResult = finalResult && result;
430 }
431
432 if ( ! reset ) {
433 // The ntuples must be always reset when closing file)
434 auto result = Reset();
435 if ( ! result ) {
436 G4ExceptionDescription description;
437 description << " " << "Resetting data failed";
438 G4Exception("G4RootNtupleFileManager::CloseFile()",
439 "Analysis_W021", JustWarning, description);
440 }
441 finalResult = finalResult && result;
442 }
443
444 return finalResult;
445}
446
447//_____________________________________________________________________________
449{
450// Reset ntuples
451
452 auto result = true;
453
454 if ( fNtupleMergeMode == G4NtupleMergeMode::kNone ||
455 fNtupleMergeMode == G4NtupleMergeMode::kMain ) {
456 result = fNtupleManager->Reset(false);
457 }
458
459 return result;
460}
@ 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
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
const G4AnalysisVerbose * GetVerboseL3() const
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
virtual void SetNtupleMerging(G4bool mergeNtuples, G4int nofReducedNtupleFiles=0) override
virtual void SetNtupleRowWise(G4bool rowWise, G4bool rowMode=true) override
virtual void SetBasketSize(unsigned int basketSize) override
G4RootNtupleFileManager(const G4AnalysisManagerState &state)
virtual std::shared_ptr< G4VNtupleManager > CreateNtupleManager() override
virtual G4bool ActionAtCloseFile(G4bool reset) override
virtual G4bool ActionAtWrite() override
virtual void SetBasketEntries(unsigned int basketEntries) override
virtual G4bool Reset() override
virtual G4bool ActionAtOpenFile(const G4String &fileName) override
std::shared_ptr< G4NtupleBookingManager > fBookingManager
const G4AnalysisManagerState & fState
G4bool IsWorkerThread()
Definition: G4Threading.cc:123
G4bool IsMultithreadedApplication()
Definition: G4Threading.cc:130
G4bool IsMasterThread()
Definition: G4Threading.cc:124
G4int G4GetThreadId()
Definition: G4Threading.cc:122