Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4RootPNtupleManager.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, 04/10/2016 ([email protected])
28
32
33#include "tools/wroot/file"
34#include "tools/wroot/ntuple"
35
36using namespace G4Analysis;
37using std::to_string;
38
39// mutex in a file scope
40namespace {
41
42//Mutex to lock master manager when adding ntuple row and ending fill
43G4Mutex pntupleMutex = G4MUTEX_INITIALIZER;
44//Mutex to lock master manager when createing main ntuples at new cycle
45G4Mutex createMainMutex = G4MUTEX_INITIALIZER;
46
47//_____________________________________________________________________________
48void 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//_____________________________________________________________________________
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//_____________________________________________________________________________
73{
74 for ( auto ntupleDescription : fNtupleDescriptionVector ) {
75 delete ntupleDescription;
76 }
77}
78
79//
80// private functions
81//
82
83//_____________________________________________________________________________
85G4RootPNtupleManager::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//_____________________________________________________________________________
100tools::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//_____________________________________________________________________________
117tools::wroot::ntuple*
118G4RootPNtupleManager::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//_____________________________________________________________________________
139void G4RootPNtupleManager::CreateNtupleFromMain(
140 G4RootPNtupleDescription* ntupleDescription,
141 tools::wroot::ntuple* mainNtuple)
142{
143 Message(kVL4, "create from main", "pntuple", mainNtuple->name());
144
145 auto file = fMainNtupleManager->GetNtupleFile(&ntupleDescription->GetDescription());
146 if ( ! file ) {
147 Warn("Cannot create pntuple. Main ntuple file does not exist.",
148 fkClass, "CreateNtupleFromMain");
149 return;
150 }
151
152 ntupleDescription->GetDescription().SetFile(file);
153
154 // Get parameters from ntupleDescription
155 mainNtuple->get_branches(ntupleDescription->GetMainBranches());
156
157 auto rfile = std::get<0>(*file);
158 G4bool verbose = true;
159 if ( fRowWise ) {
160 auto mainBranch = mainNtuple->get_row_wise_branch();
161 auto mtNtuple
162 = new tools::wroot::mt_ntuple_row_wise(
163 G4cout, rfile->byte_swap(), rfile->compression(),
164 mainNtuple->dir().seek_directory(),
165 *mainBranch, mainBranch->basket_size(),
166 ntupleDescription->GetDescription().GetNtupleBooking(), verbose);
167
168 ntupleDescription->SetNtuple(
169 static_cast<tools::wroot::imt_ntuple*>(mtNtuple));
170 ntupleDescription->SetBasePNtuple(
171 static_cast<tools::wroot::base_pntuple*>(mtNtuple));
172 }
173 else {
174 std::vector<tools::uint32> basketSizes;
175 tools_vforcit(tools::wroot::branch*, ntupleDescription->GetMainBranches(), it) {
176 basketSizes.push_back((*it)->basket_size());
177 }
178 auto basketEntries = fMainNtupleManager->GetBasketEntries();
179
180 auto mtNtuple =
181 new tools::wroot::mt_ntuple_column_wise(
182 G4cout, rfile->byte_swap(), rfile->compression(),
183 mainNtuple->dir().seek_directory(),
184 ntupleDescription->GetMainBranches(), basketSizes,
185 ntupleDescription->GetDescription().GetNtupleBooking(),
186 fRowMode, basketEntries, verbose);
187
188 ntupleDescription->SetNtuple(
189 static_cast<tools::wroot::imt_ntuple*>(mtNtuple));
190 ntupleDescription->SetBasePNtuple(
191 static_cast<tools::wroot::base_pntuple*>(mtNtuple));
192 }
193
194 ntupleDescription->GetDescription().SetIsNtupleOwner(true);
195 // // pntuple object is not deleted automatically
196 fNtupleVector.push_back(ntupleDescription->GetNtuple());
197
198 Message(kVL3, "create from main", "pntuple", mainNtuple->name());
199}
200
201//_____________________________________________________________________________
202void G4RootPNtupleManager::CreateNtupleDescriptionsFromBooking()
203{
204// Create ntuple descriptions from booking.
205// This function is called from the first Fill call.
206
207 // Create pntuple descriptions from ntuple booking.
208 auto g4NtupleBookings = fBookingManager->GetNtupleBookingVector();
209
210 for ( auto g4NtupleBooking : g4NtupleBookings ) {
211 auto ntupleDescription = new G4RootPNtupleDescription(g4NtupleBooking);
212 // Save g4booking, activation in pntuple booking
213 fNtupleDescriptionVector.push_back(ntupleDescription);
214 }
215}
216
217//_____________________________________________________________________________
218void G4RootPNtupleManager::CreateNtuplesFromMain()
219{
220// Create slave ntuples from main ntuple.
221// This function is called from the first Fill call.
222
223 auto& mainNtupleVector = fMainNtupleManager->GetNtupleVector();
224
225 G4int lcounter = 0;
226 for ( auto mainNtuple : mainNtupleVector ) {
227 auto& ntupleDescription = fNtupleDescriptionVector[lcounter++];
228 CreateNtupleFromMain(ntupleDescription, mainNtuple);
229 }
230}
231
232//_____________________________________________________________________________
233void G4RootPNtupleManager::CreateNtuplesIfNeeded()
234{
235// The ntuples on workers are created at first FillColumn or AddRow
236// (if only columns of vector type) call.
237// When writing multiple times in teh same file, the main ntuples have
238// to be recreated as well.
239
240 // G4cout << "G4RootPNtupleManager::CreateNtuplesIfNeeded: "
241 // << " fCreateNtuple: " << fCreateNtuples << " "
242 // << " fNewCycle: " << fNewCycle
243 // << " fMainNtupleManager->GetNewCycle(): " << fMainNtupleManager->GetNewCycle()
244 // << " fNtupleDescriptionVector.size(): " << fNtupleDescriptionVector.size()
245 // << " fNtupleVector.size(): " << fNtupleVector.size()
246 // << G4endl;
247
248 if (fCreateNtuples) {
249 // create ntuple descriptions
250 CreateNtupleDescriptionsFromBooking();
251
252 // create main ntuples if needed
253 G4AutoLock lock(&createMainMutex);
254 if (fMainNtupleManager->GetNewCycle()) {
255 fMainNtupleManager->CreateNtuplesFromBooking();
256 }
257 lock.unlock();
258
259 // create slave ntuples
260 CreateNtuplesFromMain();
261 fCreateNtuples = false;
262 }
263
264 if (fNewCycle) {
265 // create main ntuples if needed
266 G4AutoLock lock(&createMainMutex);
267 if (fMainNtupleManager->GetNewCycle()) {
268 fMainNtupleManager->CreateNtuplesFromBooking();
269 }
270 lock.unlock();
271
272 // create slave ntuples
273 CreateNtuplesFromMain();
274 fNewCycle = false;
275 }
276}
277
278//_____________________________________________________________________________
279G4int G4RootPNtupleManager::CreateNtuple(G4NtupleBooking* /*booking*/)
280{
281// Create pntuple from g4 ntuple booking.
282// Nothing to be done here.
283
285}
286
287//_____________________________________________________________________________
288G4bool G4RootPNtupleManager::FillNtupleIColumn(
289 G4int ntupleId, G4int columnId, G4int value)
290{
291 return FillNtupleTColumn<int>(ntupleId, columnId, value);
292}
293
294//_____________________________________________________________________________
295G4bool G4RootPNtupleManager::FillNtupleFColumn(
296 G4int ntupleId, G4int columnId, G4float value)
297{
298 return FillNtupleTColumn<float>(ntupleId, columnId, value);
299}
300
301//_____________________________________________________________________________
302G4bool G4RootPNtupleManager::FillNtupleDColumn(
303 G4int ntupleId, G4int columnId, G4double value)
304{
305 return FillNtupleTColumn<double>(ntupleId, columnId, value);
306}
307
308//_____________________________________________________________________________
309G4bool G4RootPNtupleManager::FillNtupleSColumn(
310 G4int ntupleId, G4int columnId, const G4String& value)
311{
312 return FillNtupleTColumn<std::string>(ntupleId, columnId, value);
313}
314
315//_____________________________________________________________________________
316G4bool G4RootPNtupleManager::AddNtupleRow(G4int ntupleId)
317{
318 if ( fState.GetIsActivation() && ( ! GetActivation(ntupleId) ) ) {
319 //G4cout << "Skipping AddNtupleRow for " << ntupleId << G4endl;
320 return false;
321 }
322
323 if ( IsVerbose(kVL4) ) {
324 Message(kVL4, "add", "pntuple row", " ntupleId " + to_string(ntupleId));
325 }
326
327 // Creating ntuples on workers is triggered with the first FillColumn
328 // or AddRow (in only columns of vector type call)
329 CreateNtuplesIfNeeded();
330
331 auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "AddNtupleRow");
332 if (ntupleDescription == nullptr) return false;
333
334 auto rfile = std::get<0>(*ntupleDescription->GetDescription().GetFile());
335
336 G4AutoLock lock(&pntupleMutex);
337 lock.unlock();
338 mutex toolsLock(lock);
339 auto result
340 = ntupleDescription->GetNtuple()->add_row(toolsLock, *rfile);
341
342 if ( ! result ) {
343 Warn("NtupleId " + to_string(ntupleId) + "adding row failed.",
344 fkClass, "AddNtupleRow");
345 }
346
347 ntupleDescription->GetDescription().SetHasFill(true);
348
349 if ( IsVerbose(kVL3) ) {
350 Message(kVL3, "add", "pntuple row", " ntupleId " + to_string(ntupleId));
351 }
352
353
354 return true;
355}
356
357//_____________________________________________________________________________
358G4bool G4RootPNtupleManager::Merge()
359{
360 for ( auto ntupleDescription : fNtupleDescriptionVector) {
361
362 // skip inactivated ntuples
363 if (! ntupleDescription->GetDescription().GetActivation() ||
364 (ntupleDescription->GetNtuple() == nullptr)) {
365 // G4cout << "skipping inactive ntuple " << G4endl;
366 continue;
367 }
368
369 if ( IsVerbose(kVL4) ) {
370 Message(kVL4, "merge", "pntuple",
371 ntupleDescription->GetDescription().GetNtupleBooking().name());
372 }
373
374 auto rfile = std::get<0>(*ntupleDescription->GetDescription().GetFile());
375
376 G4AutoLock lock(&pntupleMutex);
377 lock.unlock();
378 mutex toolsLock(lock);
379 auto result
380 = ntupleDescription->GetNtuple()->end_fill(toolsLock, *rfile);
381
382 if ( ! result ) {
383 Warn("Ntuple " + ntupleDescription->GetDescription().GetNtupleBooking().name() +
384 "end fill has failed.", fkClass, "Merge");
385 }
386
387 if ( IsVerbose(kVL3) ) {
388 Message(kVL3, "merge", "pntuple",
389 ntupleDescription->GetDescription().GetNtupleBooking().name());
390 }
391
392 }
393
394 // Set new cycle
395 fNewCycle = true;
396
397 return true;
398}
399
400//_____________________________________________________________________________
401G4bool G4RootPNtupleManager::Reset()
402{
403 // Reset ntuple description, this will delete ntuple if present and
404 // we have its ownership.
405 // The ntuples will be recreated with new cycle or new open file.
406
407 for ( auto ntupleDescription : fNtupleDescriptionVector ) {
408 ntupleDescription->Reset();
409 }
410
411 fNtupleVector.clear();
412
413 return true;
414}
415
416//_____________________________________________________________________________
417void G4RootPNtupleManager::Clear()
418{
419 for ( auto ntupleDescription : fNtupleDescriptionVector ) {
420 delete ntupleDescription->GetNtuple();
421 }
422
423 fNtupleDescriptionVector.clear();
424 fNtupleVector.clear();
425
426 Message(kVL2, "clear", "pntuples");
427}
428
429//_____________________________________________________________________________
430
431void G4RootPNtupleManager::SetActivation(
432 G4bool activation)
433{
434 for ( auto ntupleDescription : fNtupleDescriptionVector ) {
435 ntupleDescription->GetDescription().SetActivation(activation);
436 }
437}
438
439//_____________________________________________________________________________
440
441void G4RootPNtupleManager::SetActivation(
442 G4int ntupleId, G4bool activation)
443{
444 auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "SetActivation");
445 if (ntupleDescription == nullptr) return;
446
447 ntupleDescription->GetDescription().SetActivation(activation);
448}
449
450//_____________________________________________________________________________
451G4bool G4RootPNtupleManager::GetActivation(
452 G4int ntupleId) const
453{
454 auto ntupleDescription = GetNtupleDescriptionInFunction(ntupleId, "GetActivation");
455 if (ntupleDescription == nullptr) return false;
456
457 return ntupleDescription->GetDescription().GetActivation();
458}
459
460//_____________________________________________________________________________
461void G4RootPNtupleManager::SetNewCycle(G4bool value)
462{
463 fNewCycle = value;
464}
465
466//_____________________________________________________________________________
467G4bool G4RootPNtupleManager::GetNewCycle() const
468{
469 return fNewCycle;
470}
471
472//_____________________________________________________________________________
473G4int G4RootPNtupleManager::GetNofNtuples() const
474{
475 return (G4int)fNtupleVector.size();
476}
477
478//_____________________________________________________________________________
479void G4RootPNtupleManager::SetNtupleRowWise(G4bool rowWise, G4bool rowMode)
480{
481 fRowWise = rowWise;
482 fRowMode = rowMode;
483}
484
485//_____________________________________________________________________________
486G4bool G4RootPNtupleManager::List(std::ostream& /*output*/, G4bool /*onlyIfActive*/)
487{
488 Warn("Not implemented.", fkClass, "List");
489 return false;
490}
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:85
std::mutex G4Mutex
Definition: G4Threading.hh:81
float G4float
Definition: G4Types.hh:84
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
G4GLOB_DLL std::ostream G4cout
void Message(G4int level, const G4String &action, const G4String &objectType, const G4String &objectName="", G4bool success=true) const
const G4AnalysisManagerState & fState
G4bool IsVerbose(G4int verboseLevel) const
tools::wroot::imt_ntuple * GetNtuple() const
void SetNtuple(tools::wroot::imt_ntuple *intuple)
std::vector< tools::wroot::branch * > & GetMainBranches()
void SetBasePNtuple(tools::wroot::base_pntuple *basePNtuple)
RootNtupleDescription & GetDescription()
G4RootPNtupleManager()=delete
void SetFile(std::shared_ptr< FT > file)
const tools::ntuple_booking & GetNtupleBooking() const
void SetIsNtupleOwner(G4bool isNtupleOwner)
void SetActivation(G4bool activation)
std::shared_ptr< FT > GetFile() const
void SetHasFill(G4bool hasFill)
constexpr G4int kVL2
constexpr G4int kVL3
constexpr G4int kVL4
constexpr G4int kInvalidId
void Warn(const G4String &message, const std::string_view inClass, const std::string_view inFunction)