Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/analysis/root/src/G4RootNtupleFileManager.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 (ivana@ipno.in2p3.fr)
 28 
 29 #include "G4RootNtupleFileManager.hh"
 30 #include "G4RootFileManager.hh"
 31 #include "G4RootNtupleManager.hh"
 32 #include "G4RootMainNtupleManager.hh"
 33 #include "G4RootPNtupleManager.hh"
 34 #include "G4VAnalysisManager.hh"
 35 #include "G4AnalysisManagerState.hh"
 36 #include "G4AnalysisUtilities.hh"
 37 
 38 #include "G4Threading.hh"
 39 #include "G4AutoLock.hh"
 40 
 41 using namespace G4Analysis;
 42 using std::make_shared;
 43 using std::to_string;
 44 
 45 
 46 
 47 G4RootNtupleFileManager* G4RootNtupleFileManager::fgMasterInstance = nullptr;
 48 
 49 //_____________________________________________________________________________
 50 G4RootNtupleFileManager::G4RootNtupleFileManager(const G4AnalysisManagerState& state)
 51  : G4VNtupleFileManager(state, "root")
 52 {
 53   if ( G4Threading::IsMasterThread() ) fgMasterInstance = this;
 54 
 55   // Do not merge ntuples by default
 56   // Merging may require user code migration as analysis manager
 57   // must be created both on master and workers.
 58   auto mergeNtuples = false;
 59   SetNtupleMergingMode(mergeNtuples, fNofNtupleFiles);
 60 }
 61 
 62 //_____________________________________________________________________________
 63 G4RootNtupleFileManager::~G4RootNtupleFileManager()
 64 {
 65   if ( fState.GetIsMaster() ) fgMasterInstance = nullptr;
 66 }
 67 
 68 //
 69 // private methods
 70 //
 71 
 72 //_____________________________________________________________________________
 73 void G4RootNtupleFileManager::SetNtupleMergingMode(G4bool mergeNtuples,
 74                                                  G4int nofNtupleFiles)
 75 
 76 {
 77   Message(kVL4, "set", "ntuple merging mode");
 78 
 79   auto canMerge = true;
 80 
 81   // Illegal situations
 82   if ( mergeNtuples && ( ! G4Threading::IsMultithreadedApplication() ) ) {
 83     Warn("Merging ntuples is not applicable in sequential application.\n"
 84          "Setting was ignored.",
 85          fkClass, "SetNtupleMergingMode");
 86     canMerge = false;
 87   }
 88 
 89   // Illegal situations
 90   if (mergeNtuples && G4Threading::IsMultithreadedApplication() && (fgMasterInstance == nullptr)) {
 91     Warn("Merging ntuples requires G4AnalysisManager instance on master.\n"
 92          "Setting was ignored.",
 93          fkClass, "SetNtupleMergingMode");
 94     canMerge = false;
 95   }
 96 
 97   G4String mergingMode;
 98   if ( ( ! mergeNtuples ) || ( ! canMerge ) ) {
 99     fNtupleMergeMode = G4NtupleMergeMode::kNone;
100     mergingMode = "G4NtupleMergeMode::kNone";
101   }
102   else {
103     // Set the number of reduced ntuple files
104     fNofNtupleFiles = nofNtupleFiles;
105 
106     // Check the number of reduced ntuple files
107     if ( fNofNtupleFiles < 0  ) {
108       Warn("Number of reduced files must be [0, nofThreads].\n"
109            "Cannot set  " + to_string(nofNtupleFiles) +" files.\n" +
110            "Setting was ignored.",
111            fkClass, "SetNtupleMergingMode");
112       fNofNtupleFiles = 0;
113     }
114 
115     // Forced merging mode
116     G4bool isMaster = ! G4Threading::IsWorkerThread();
117     // G4bool isMaster = fState.GetIsMaster();
118     if ( isMaster ) {
119       fNtupleMergeMode = G4NtupleMergeMode::kMain;
120       mergingMode = "G4NtupleMergeMode::kMain";
121     } else {
122       fNtupleMergeMode = G4NtupleMergeMode::kSlave;
123       mergingMode = "G4NtupleMergeMode::kSlave";
124     }
125   }
126 
127   Message(kVL2, "set", "ntuple merging mode", mergingMode);
128 }
129 
130 //_____________________________________________________________________________
131 G4int G4RootNtupleFileManager::GetNtupleFileNumber()
132 {
133   if (fNofNtupleFiles == 0) return 0;
134 
135   G4int nofMainManagers = fNofNtupleFiles;
136   if (nofMainManagers == 0) nofMainManagers = 1;
137 
138   auto fileNumber = G4Threading::G4GetThreadId() % nofMainManagers;
139   return fileNumber;
140 }
141 
142 //_____________________________________________________________________________
143 G4bool G4RootNtupleFileManager::CloseNtupleFiles()
144 {
145   // Take into account main ntuple files if present
146   auto mainNumber = ( fNofNtupleFiles > 0 ) ? 0 : -1;
147 
148   auto result = true;
149   auto ntupleVector = fNtupleManager->GetNtupleDescriptionVector();
150   for ( auto ntupleDescription : ntupleVector) {
151     for (G4int i = mainNumber; i < fNofNtupleFiles; ++i ) {
152       result &= fFileManager->CloseNtupleFile(ntupleDescription, i);
153     }
154   }
155   return result;
156 }
157 
158 //
159 // public methods
160 //
161 
162 //_____________________________________________________________________________
163 void G4RootNtupleFileManager::SetNtupleMerging(G4bool mergeNtuples,
164                                                G4int  nofNtupleFiles)
165 
166 {
167   if ( fIsInitialized ) {
168     Warn("Cannot change merging mode.\n"
169          "The function must be called before OpenFile().",
170          fkClass, "SetNtupleMerging");
171     return;
172   }
173 
174   // Set ntuple merging mode
175   SetNtupleMergingMode(mergeNtuples, nofNtupleFiles);
176 }
177 
178 //_____________________________________________________________________________
179 void G4RootNtupleFileManager::SetNtupleRowWise(G4bool rowWise, G4bool rowMode)
180 {
181 
182   // Print info even when setting makes no effect
183   // (as we do not get printed the default setting in the output)
184   G4String rowWiseMode;
185   if ( rowWise ) {
186     rowWiseMode = "row-wise with extra branch";
187   }
188   else if ( rowMode ) {
189     rowWiseMode = "row-wise";
190   }
191   else {
192     rowWiseMode = "column-wise";
193   }
194 
195   Message(kVL1, "set", "ntuple merging row mode", rowWiseMode);
196 
197   // Do nothing if the mode is not changed
198   if ( fNtupleRowWise == rowWise && fNtupleRowMode == rowMode ) return;
199 
200   fNtupleRowWise = rowWise;
201   fNtupleRowMode = rowMode;
202 
203   if ( fNtupleManager ) {
204     fNtupleManager->SetNtupleRowWise(rowWise, rowMode);
205   }
206 
207   if ( fSlaveNtupleManager ) {
208     fSlaveNtupleManager->SetNtupleRowWise(rowWise, rowMode);
209   }
210 }
211 
212 //_____________________________________________________________________________
213 void G4RootNtupleFileManager::SetBasketSize(unsigned int basketSize)
214 {
215   fFileManager->SetBasketSize(basketSize);
216 }
217 
218 //_____________________________________________________________________________
219 void G4RootNtupleFileManager::SetBasketEntries(unsigned int basketEntries)
220 {
221   fFileManager->SetBasketEntries(basketEntries);
222 }
223 
224 //_____________________________________________________________________________
225 std::shared_ptr<G4VNtupleManager> G4RootNtupleFileManager::CreateNtupleManager()
226 {
227 // Create and return ntuple manager.
228 // If ntuple merging is activated, managers of different types are created
229 // on master/worker.
230 
231   Message(kVL4, "create", "ntuple manager");
232 
233   // Check that file manager and anaysis manager are set !
234 
235   std::shared_ptr<G4VNtupleManager> activeNtupleManager = nullptr;
236   switch ( fNtupleMergeMode )
237   {
238     case G4NtupleMergeMode::kNone:
239       fNtupleManager
240         = make_shared<G4RootNtupleManager>(
241             fState, fBookingManager, 0, 0, fNtupleRowWise, fNtupleRowMode);
242       fNtupleManager->SetFileManager(fFileManager);
243       activeNtupleManager = fNtupleManager;
244       break;
245 
246     case G4NtupleMergeMode::kMain: {
247       G4int nofMainManagers = fNofNtupleFiles;
248       if (nofMainManagers == 0) {
249         // create one manager if merging required into the histos & profiles files
250         nofMainManagers = 1;
251       }
252       fNtupleManager
253         = make_shared<G4RootNtupleManager>(
254             fState, fBookingManager, nofMainManagers, fNofNtupleFiles, fNtupleRowWise, fNtupleRowMode);
255       fNtupleManager->SetFileManager(fFileManager);
256       activeNtupleManager = fNtupleManager;
257       break;
258     }
259 
260     case G4NtupleMergeMode::kSlave:
261       fNtupleManager = fgMasterInstance->fNtupleManager;
262         // The master class is used only in Get* functions
263       auto mainNtupleManager
264         = fNtupleManager->GetMainNtupleManager(GetNtupleFileNumber());
265       fSlaveNtupleManager
266         = make_shared<G4RootPNtupleManager>(
267             fState, fBookingManager, mainNtupleManager, fNtupleRowWise, fNtupleRowMode);
268       activeNtupleManager = fSlaveNtupleManager;
269       break;
270   }
271 
272   G4String mergeMode;
273   switch ( fNtupleMergeMode ) {
274     case G4NtupleMergeMode::kNone:
275       mergeMode = "";
276       break;
277     case G4NtupleMergeMode::kMain:
278       mergeMode = "main ";
279       break;
280     case G4NtupleMergeMode::kSlave:
281       mergeMode = "slave ";
282       break;
283   }
284   Message(kVL3, "create", mergeMode + "ntuple manager");
285 
286   fIsInitialized = true;
287 
288   return activeNtupleManager;
289 }
290 
291 //_____________________________________________________________________________
292 G4bool G4RootNtupleFileManager::ActionAtOpenFile([[maybe_unused]] const G4String& fileName)
293 {
294   // Check if fNtupleBookingManager is set
295 
296   if ( fNtupleMergeMode == G4NtupleMergeMode::kNone ||
297        fNtupleMergeMode == G4NtupleMergeMode::kMain )  {
298 
299     G4String objectType = "analysis file";
300     if ( fNtupleMergeMode == G4NtupleMergeMode::kMain ) {
301       objectType = "main analysis file";
302     }
303     Message(kVL4, "open", objectType, fileName);
304 
305     // Creating files is triggered from CreateNtuple
306     fNtupleManager->CreateNtuplesFromBooking(
307       fBookingManager->GetNtupleBookingVector());
308 
309     Message(kVL1, "open", objectType, fileName);
310   }
311 
312   // Creating ntuples from main is triggered from the first Fill call
313   // if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave )  {
314   //   // G4cout << "Going to create slave ntuples from main" << G4endl;
315   //   fSlaveNtupleManager->CreateNtuplesFromMain();
316   // }
317 
318   return true;
319 }
320 
321 //_____________________________________________________________________________
322 G4bool G4RootNtupleFileManager::ActionAtWrite()
323 {
324   if ( fNtupleMergeMode == G4NtupleMergeMode::kNone ) {
325     return true;
326   }
327 
328   auto result = true;
329 
330   G4String ntupleType;
331   if ( fNtupleMergeMode == G4NtupleMergeMode::kMain ) ntupleType = "main ntuples";
332   if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave ) ntupleType = "slave ntuples";
333 
334   Message(kVL4, "merge", ntupleType);
335 
336   if ( fNtupleMergeMode == G4NtupleMergeMode::kMain )  {
337     result &= fNtupleManager->Merge();
338   }
339 
340   if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave ) {
341     result &= fSlaveNtupleManager->Merge();
342   }
343 
344   Message(kVL2, "merge", ntupleType, "", result);
345 
346   return result;
347 }
348 
349 //_____________________________________________________________________________
350 G4bool G4RootNtupleFileManager::ActionAtCloseFile()
351 {
352   if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave)  {
353     fSlaveNtupleManager->SetNewCycle(false);
354     return true;
355   }
356 
357   return CloseNtupleFiles();
358 }
359 
360 //_____________________________________________________________________________
361 G4bool G4RootNtupleFileManager::Reset()
362 {
363 // Reset ntuples
364 
365   auto result = true;
366 
367   if ( fNtupleMergeMode == G4NtupleMergeMode::kNone ||
368        fNtupleMergeMode == G4NtupleMergeMode::kMain )  {
369     result &= fNtupleManager->Reset();
370   }
371 
372   if ( fNtupleMergeMode == G4NtupleMergeMode::kSlave ) {
373     fSlaveNtupleManager->Reset();
374   }
375 
376   return result;
377 }
378