Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/analysis/root/src/G4RootPNtupleManager.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, 04/10/2016  (ivana@ipno.in2p3.fr)
 28 
 29 #include "G4NtupleBookingManager.hh"
 30 #include "G4RootPNtupleManager.hh"
 31 #include "G4AnalysisUtilities.hh"
 32 
 33 #include "tools/wroot/file"
 34 #include "tools/wroot/ntuple"
 35 
 36 using namespace G4Analysis;
 37 using std::to_string;
 38 
 39 // mutex in a file scope
 40 namespace {
 41 
 42 //Mutex to lock master manager when adding ntuple row and ending fill
 43 G4Mutex pntupleMutex = G4MUTEX_INITIALIZER;
 44 //Mutex to lock master manager when createing main ntuples at new cycle
 45 G4Mutex createMainMutex = G4MUTEX_INITIALIZER;
 46 
 47 //_____________________________________________________________________________
 48 void NotExistWarning(const G4String& what, G4int id,
 49                      std::string_view className,
 50                      std::string_view functionName)
 51 {
 52   Warn(what + " id= " + to_string(id) + " does not exist.",
 53     className, functionName);
 54 
 55 }
 56 
 57 }
 58 
 59 //_____________________________________________________________________________
 60 G4RootPNtupleManager::G4RootPNtupleManager(const G4AnalysisManagerState& state,
 61                         std::shared_ptr<G4NtupleBookingManager> bookingManger,
 62                         std::shared_ptr<G4RootMainNtupleManager> main,
 63                         G4bool rowWise, G4bool rowMode)
 64  : G4BaseNtupleManager(state),
 65    fBookingManager(std::move(bookingManger)),
 66    fMainNtupleManager(std::move(main)),
 67    fRowWise(rowWise),
 68    fRowMode(rowMode)
 69 {}
 70 
 71 //_____________________________________________________________________________
 72 G4RootPNtupleManager::~G4RootPNtupleManager()
 73 {
 74   for ( auto ntupleDescription : fNtupleDescriptionVector ) {
 75     delete ntupleDescription;
 76   }
 77 }
 78 
 79 //
 80 // private functions
 81 //
 82 
 83 //_____________________________________________________________________________
 84 G4RootPNtupleDescription*
 85 G4RootPNtupleManager::GetNtupleDescriptionInFunction(
 86   G4int id, std::string_view functionName, G4bool warn) const
 87 {
 88   auto index = id - fFirstId;
 89   if ( index < 0 || index >= G4int(fNtupleDescriptionVector.size()) ) {
 90     if ( warn) {
 91       NotExistWarning("ntuple description", id, fkClass, functionName);
 92     }
 93     return nullptr;
 94   }
 95 
 96   return fNtupleDescriptionVector[index];
 97 }
 98 
 99 //_____________________________________________________________________________
100 tools::wroot::base_pntuple*
101  G4RootPNtupleManager::GetNtupleInFunction(
102   G4int id, std::string_view functionName, G4bool warn) const
103 {
104   auto ntupleDescription = GetNtupleDescriptionInFunction(id, functionName);
105   if (ntupleDescription == nullptr) return nullptr;
106 
107   if (ntupleDescription->GetBasePNtuple() == nullptr) {
108     if ( warn ) {
109       NotExistWarning("ntuple", id, fkClass, functionName);
110     }
111     return nullptr;
112   }
113   return ntupleDescription->GetBasePNtuple();
114 }
115 
116 //_____________________________________________________________________________
117 tools::wroot::ntuple*
118 G4RootPNtupleManager::GetMainNtupleInFunction(
119   G4int id, std::string_view functionName, G4bool warn) const
120 {
121   auto& mainNtupleVector = fMainNtupleManager->GetNtupleVector();
122 
123   auto index = id - fFirstId;
124   if ( index < 0 || index >= G4int(mainNtupleVector.size()) ) {
125     if ( warn) {
126       NotExistWarning("main ntuple", id, fkClass, functionName);
127     }
128     return nullptr;
129   }
130 
131   return mainNtupleVector[index];
132 }
133 
134 //
135 // protected functions
136 //
137 
138 //_____________________________________________________________________________
139 void G4RootPNtupleManager::CreateNtupleFromMain(
140                              G4RootPNtupleDescription* ntupleDescription,
141                              tools::wroot::ntuple* mainNtuple)
142 {
143   // Do not create pntuple if ntuple was deleted
144   if (mainNtuple == nullptr) {
145     ntupleDescription->SetNtuple(nullptr);
146     ntupleDescription->SetBasePNtuple(nullptr);
147     return;
148   }
149 
150   Message(kVL4, "create from main", "pntuple", mainNtuple->name());
151 
152   auto file = fMainNtupleManager->GetNtupleFile(&ntupleDescription->GetDescription());
153   if ( ! file ) {
154     Warn("Cannot create pntuple. Main ntuple file does not exist.",
155       fkClass, "CreateNtupleFromMain");
156     return;
157   }
158 
159   ntupleDescription->GetDescription().SetFile(file);
160 
161   // Get parameters from ntupleDescription
162   mainNtuple->get_branches(ntupleDescription->GetMainBranches());
163 
164   auto rfile = std::get<0>(*file);
165   G4bool verbose = true;
166   if ( fRowWise ) {
167     auto mainBranch = mainNtuple->get_row_wise_branch();
168     auto mtNtuple
169       = new tools::wroot::mt_ntuple_row_wise(
170               G4cout, rfile->byte_swap(), rfile->compression(),
171               mainNtuple->dir().seek_directory(),
172               *mainBranch, mainBranch->basket_size(),
173               ntupleDescription->GetDescription().GetNtupleBooking(), verbose);
174 
175     ntupleDescription->SetNtuple(
176       static_cast<tools::wroot::imt_ntuple*>(mtNtuple));
177     ntupleDescription->SetBasePNtuple(
178       static_cast<tools::wroot::base_pntuple*>(mtNtuple));
179   }
180   else {
181     std::vector<tools::uint32> basketSizes;
182     tools_vforcit(tools::wroot::branch*, ntupleDescription->GetMainBranches(), it) {
183       basketSizes.push_back((*it)->basket_size());
184     }
185     auto basketEntries = fMainNtupleManager->GetBasketEntries();
186 
187     auto mtNtuple =
188       new tools::wroot::mt_ntuple_column_wise(
189             G4cout, rfile->byte_swap(), rfile->compression(),
190             mainNtuple->dir().seek_directory(),
191             ntupleDescription->GetMainBranches(), basketSizes,
192             ntupleDescription->GetDescription().GetNtupleBooking(),
193             fRowMode, basketEntries, verbose);
194 
195     ntupleDescription->SetNtuple(
196       static_cast<tools::wroot::imt_ntuple*>(mtNtuple));
197     ntupleDescription->SetBasePNtuple(
198       static_cast<tools::wroot::base_pntuple*>(mtNtuple));
199   }
200 
201   ntupleDescription->GetDescription().SetIsNtupleOwner(true);
202   //        // pntuple object is not deleted automatically
203   fNtupleVector.push_back(ntupleDescription->GetNtuple());
204 
205   Message(kVL3, "create from main", "pntuple", mainNtuple->name());
206 }
207 
208 //_____________________________________________________________________________
209 void G4RootPNtupleManager::CreateNtupleDescriptionsFromBooking()
210 {
211 // Create ntuple descriptions from booking.
212 // This function is called from the first Fill call.
213 
214   // Create pntuple descriptions from ntuple booking.
215   auto g4NtupleBookings = fBookingManager->GetNtupleBookingVector();
216 
217   for ( auto g4NtupleBooking : g4NtupleBookings ) {
218     auto ntupleDescription = new G4RootPNtupleDescription(g4NtupleBooking);
219     // Save g4booking, activation in pntuple booking
220     fNtupleDescriptionVector.push_back(ntupleDescription);
221   }
222 }
223 
224 //_____________________________________________________________________________
225 void G4RootPNtupleManager::CreateNtuplesFromMain()
226 {
227 // Create slave ntuples from  main ntuple.
228 // This function is called from the first Fill call.
229 
230   auto& mainNtupleVector = fMainNtupleManager->GetNtupleVector();
231 
232   G4int lcounter = 0;
233   for ( auto mainNtuple : mainNtupleVector ) {
234     auto& ntupleDescription = fNtupleDescriptionVector[lcounter++];
235     CreateNtupleFromMain(ntupleDescription, mainNtuple);
236   }
237 }
238 
239 //_____________________________________________________________________________
240 void G4RootPNtupleManager::CreateNtuplesIfNeeded()
241 {
242 // The ntuples on workers are created at first FillColumn or AddRow
243 // (if only columns of vector type) call.
244 // When writing multiple times in teh same file, the main ntuples have
245 // to be recreated as well.
246 
247   // G4cout << "G4RootPNtupleManager::CreateNtuplesIfNeeded: "
248   //   << " fCreateNtuple: " << fCreateNtuples << " "
249   //   << " fNewCycle: " << fNewCycle
250   //   << " fMainNtupleManager->GetNewCycle(): " << fMainNtupleManager->GetNewCycle()
251   //   << " fNtupleDescriptionVector.size(): " << fNtupleDescriptionVector.size()
252   //   << " fNtupleVector.size(): " << fNtupleVector.size()
253   //   << G4endl;
254 
255   if (fCreateNtuples) {
256     // create ntuple descriptions
257     CreateNtupleDescriptionsFromBooking();
258 
259     // create main ntuples if needed
260     G4AutoLock lock(&createMainMutex);
261     if (fMainNtupleManager->GetNewCycle()) {
262       fMainNtupleManager->CreateNtuplesFromBooking();
263     }
264     lock.unlock();
265 
266     // create slave ntuples
267     CreateNtuplesFromMain();
268     fCreateNtuples = false;
269   }
270 
271   if (fNewCycle) {
272     // create main ntuples if needed
273     G4AutoLock lock(&createMainMutex);
274     if (fMainNtupleManager->GetNewCycle()) {
275       fMainNtupleManager->CreateNtuplesFromBooking();
276     }
277     lock.unlock();
278 
279     // create slave ntuples
280     CreateNtuplesFromMain();
281     fNewCycle = false;
282   }
283 }
284 
285 //_____________________________________________________________________________
286 G4int G4RootPNtupleManager::CreateNtuple(G4NtupleBooking* /*booking*/)
287 {
288 // Create pntuple from g4 ntuple booking.
289 // Nothing to be done here.
290 
291   return G4Analysis::kInvalidId;
292 }
293 
294 //_____________________________________________________________________________
295 G4bool G4RootPNtupleManager::FillNtupleIColumn(
296   G4int ntupleId, G4int columnId, G4int value)
297 {
298   return FillNtupleTColumn<int>(ntupleId, columnId, value);
299 }
300 
301 //_____________________________________________________________________________
302 G4bool G4RootPNtupleManager::FillNtupleFColumn(
303   G4int ntupleId, G4int columnId, G4float value)
304 {
305   return FillNtupleTColumn<float>(ntupleId, columnId, value);
306 }
307 
308 //_____________________________________________________________________________
309 G4bool G4RootPNtupleManager::FillNtupleDColumn(
310   G4int ntupleId, G4int columnId, G4double value)
311 {
312   return FillNtupleTColumn<double>(ntupleId, columnId, value);
313 }
314 
315 //_____________________________________________________________________________
316 G4bool G4RootPNtupleManager::FillNtupleSColumn(
317   G4int ntupleId, G4int columnId, const G4String& value)
318 {
319   return FillNtupleTColumn<std::string>(ntupleId, columnId, value);
320 }
321 
322 //_____________________________________________________________________________
323 G4bool G4RootPNtupleManager::AddNtupleRow(G4int ntupleId)
324 {
325   if ( fState.GetIsActivation() && ( ! GetActivation(ntupleId) ) ) {
326     //G4cout << "Skipping AddNtupleRow for " << ntupleId << G4endl;
327     return false;
328   }
329 
330   if ( IsVerbose(kVL4) ) {
331     Message(kVL4, "add", "pntuple row", " ntupleId " + to_string(ntupleId));
332   }
333 
334   // Creating ntuples on workers is triggered with the first FillColumn
335   // or AddRow (in only columns of vector type call)
336   CreateNtuplesIfNeeded();
337 
338   auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "AddNtupleRow");
339   if (ntupleDescription == nullptr) return false;
340 
341   auto rfile = std::get<0>(*ntupleDescription->GetDescription().GetFile());
342 
343   G4AutoLock lock(&pntupleMutex);
344   lock.unlock();
345   mutex toolsLock(lock);
346   auto result
347     = ntupleDescription->GetNtuple()->add_row(toolsLock, *rfile);
348 
349   if ( ! result ) {
350     Warn("NtupleId " + to_string(ntupleId) + "adding row failed.",
351       fkClass, "AddNtupleRow");
352   }
353 
354   ntupleDescription->GetDescription().SetHasFill(true);
355 
356   if ( IsVerbose(kVL3) ) {
357     Message(kVL3, "add", "pntuple row", " ntupleId " + to_string(ntupleId));
358   }
359 
360 
361   return true;
362 }
363 
364 //_____________________________________________________________________________
365 G4bool G4RootPNtupleManager::Merge()
366 {
367   for ( auto ntupleDescription : fNtupleDescriptionVector) {
368 
369     // skip inactivated ntuples
370     if (! ntupleDescription->GetDescription().GetActivation() ||
371         (ntupleDescription->GetNtuple() == nullptr)) {
372       // G4cout << "skipping inactive ntuple " << G4endl;
373       continue;
374     }
375 
376     if ( IsVerbose(kVL4) ) {
377       Message(kVL4, "merge", "pntuple",
378         ntupleDescription->GetDescription().GetNtupleBooking().name());
379     }
380 
381     auto rfile = std::get<0>(*ntupleDescription->GetDescription().GetFile());
382 
383     G4AutoLock lock(&pntupleMutex);
384     lock.unlock();
385     mutex toolsLock(lock);
386     auto result
387       = ntupleDescription->GetNtuple()->end_fill(toolsLock, *rfile);
388 
389     if ( ! result ) {
390       Warn("Ntuple " + ntupleDescription->GetDescription().GetNtupleBooking().name() +
391            "end fill has failed.", fkClass, "Merge");
392     }
393 
394     if ( IsVerbose(kVL3) ) {
395       Message(kVL3, "merge", "pntuple",
396         ntupleDescription->GetDescription().GetNtupleBooking().name());
397     }
398 
399   }
400 
401   // Set new cycle
402   fNewCycle = true;
403 
404   return true;
405 }
406 
407 //_____________________________________________________________________________
408 G4bool G4RootPNtupleManager::Reset()
409 {
410   // Reset ntuple description, this will delete ntuple if present and
411   // we have its ownership.
412   // The ntuples will be recreated with new cycle or new open file.
413 
414   for ( auto ntupleDescription : fNtupleDescriptionVector ) {
415     ntupleDescription->Reset();
416   }
417 
418   fNtupleVector.clear();
419 
420   return true;
421 }
422 
423 //_____________________________________________________________________________
424 void G4RootPNtupleManager::Clear()
425 {
426   for ( auto ntupleDescription : fNtupleDescriptionVector ) {
427     delete ntupleDescription->GetNtuple();
428   }
429 
430   fNtupleDescriptionVector.clear();
431   fNtupleVector.clear();
432 
433   Message(kVL2, "clear", "pntuples");
434 }
435 
436 //_____________________________________________________________________________
437 G4bool G4RootPNtupleManager::Delete(G4int id)
438 {
439   if ( IsVerbose(G4Analysis::kVL4) ) {
440     Message(G4Analysis::kVL4, "delete", "pntuple ntupleId " + to_string(id));
441   }
442 
443   auto ntupleDescription = GetNtupleDescriptionInFunction(id, "Delete", true);
444 
445   if (ntupleDescription == nullptr) return false;
446 
447   // Delete/clear ntuple data
448   delete ntupleDescription->GetNtuple();
449   ntupleDescription->SetNtuple(nullptr);
450   ntupleDescription->SetBasePNtuple(nullptr);
451   ntupleDescription->GetMainBranches().clear();
452 
453   // Update ntuple vector
454   auto index = id - GetFirstId();
455   fNtupleVector[index] = nullptr;
456 
457   Message(G4Analysis::kVL2, "delete", "pntuple ntupleId " + to_string(id));
458 
459   return true;
460 }
461 
462 //_____________________________________________________________________________
463 
464 void  G4RootPNtupleManager::SetActivation(
465   G4bool activation)
466 {
467   for ( auto ntupleDescription : fNtupleDescriptionVector ) {
468     ntupleDescription->GetDescription().SetActivation(activation);
469   }
470 }
471 
472 //_____________________________________________________________________________
473 
474 void  G4RootPNtupleManager::SetActivation(
475   G4int ntupleId, G4bool activation)
476 {
477   auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "SetActivation");
478   if (ntupleDescription == nullptr) return;
479 
480   ntupleDescription->GetDescription().SetActivation(activation);
481 }
482 
483 //_____________________________________________________________________________
484 G4bool  G4RootPNtupleManager::GetActivation(
485   G4int ntupleId) const
486 {
487   auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "GetActivation");
488   if (ntupleDescription == nullptr) return false;
489 
490   return ntupleDescription->GetDescription().GetActivation();
491 }
492 
493 //_____________________________________________________________________________
494 void G4RootPNtupleManager::SetNewCycle(G4bool value)
495 {
496   fNewCycle = value;
497 }
498 
499 //_____________________________________________________________________________
500 G4bool G4RootPNtupleManager::GetNewCycle() const
501 {
502   return fNewCycle;
503 }
504 
505 //_____________________________________________________________________________
506 void G4RootPNtupleManager::SetNtupleRowWise(G4bool rowWise, G4bool rowMode)
507 {
508   fRowWise = rowWise;
509   fRowMode = rowMode;
510 }
511