Geant4 11.2.2
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 // 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//_____________________________________________________________________________
209void 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//_____________________________________________________________________________
225void 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//_____________________________________________________________________________
240void 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//_____________________________________________________________________________
286G4int G4RootPNtupleManager::CreateNtuple(G4NtupleBooking* /*booking*/)
287{
288// Create pntuple from g4 ntuple booking.
289// Nothing to be done here.
290
292}
293
294//_____________________________________________________________________________
295G4bool G4RootPNtupleManager::FillNtupleIColumn(
296 G4int ntupleId, G4int columnId, G4int value)
297{
298 return FillNtupleTColumn<int>(ntupleId, columnId, value);
299}
300
301//_____________________________________________________________________________
302G4bool G4RootPNtupleManager::FillNtupleFColumn(
303 G4int ntupleId, G4int columnId, G4float value)
304{
305 return FillNtupleTColumn<float>(ntupleId, columnId, value);
306}
307
308//_____________________________________________________________________________
309G4bool G4RootPNtupleManager::FillNtupleDColumn(
310 G4int ntupleId, G4int columnId, G4double value)
311{
312 return FillNtupleTColumn<double>(ntupleId, columnId, value);
313}
314
315//_____________________________________________________________________________
316G4bool G4RootPNtupleManager::FillNtupleSColumn(
317 G4int ntupleId, G4int columnId, const G4String& value)
318{
319 return FillNtupleTColumn<std::string>(ntupleId, columnId, value);
320}
321
322//_____________________________________________________________________________
323G4bool 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//_____________________________________________________________________________
365G4bool 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//_____________________________________________________________________________
408G4bool 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//_____________________________________________________________________________
424void 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//_____________________________________________________________________________
437G4bool G4RootPNtupleManager::Delete(G4int id)
438{
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
464void G4RootPNtupleManager::SetActivation(
465 G4bool activation)
466{
467 for ( auto ntupleDescription : fNtupleDescriptionVector ) {
468 ntupleDescription->GetDescription().SetActivation(activation);
469 }
470}
471
472//_____________________________________________________________________________
473
474void 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//_____________________________________________________________________________
484G4bool 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//_____________________________________________________________________________
494void G4RootPNtupleManager::SetNewCycle(G4bool value)
495{
496 fNewCycle = value;
497}
498
499//_____________________________________________________________________________
500G4bool G4RootPNtupleManager::GetNewCycle() const
501{
502 return fNewCycle;
503}
504
505//_____________________________________________________________________________
506void G4RootPNtupleManager::SetNtupleRowWise(G4bool rowWise, G4bool rowMode)
507{
508 fRowWise = rowWise;
509 fRowMode = rowMode;
510}
#define G4MUTEX_INITIALIZER
std::mutex G4Mutex
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)