VMC Version 2.2
Loading...
Searching...
No Matches
TMCRootManager.cxx
Go to the documentation of this file.
1//------------------------------------------------
2// The Geant4 Virtual Monte Carlo package
3// Copyright (C) 2013 - 2018 Ivana Hrivnacova
4// All rights reserved.
5//
6// For the licensing terms see geant4_vmc/LICENSE.
7// Contact: root-vmc@cern.ch
8//-------------------------------------------------
9
14
15#include "TMCRootManager.h"
16#include "Riostream.h"
17#include "TError.h"
18#include "TFile.h"
19#include "TMCAutoLock.h"
20#include "TThread.h"
21#include "TTree.h"
22
23#include <atomic>
24#include <cstdio>
25#include <thread>
26#include <vector>
27
28
29namespace {
30// Define mutexes per operation which modify shared data
31TMCMutex createMutex = TMCMUTEX_INITIALIZER;
32TMCMutex deleteMutex = TMCMUTEX_INITIALIZER;
33
34// A global counter to assign numbers sequentially
35std::atomic<int> global_thread_counter{0};
36
37int get_clean_thread_id() {
38 // This variable is unique to each thread.
39 // It initializes ONLY the first time this function is called on that thread.
40 thread_local int my_id = global_thread_counter++;
41 return my_id;
42}
43
44void threadWorker() {
45 // No arguments passed, but the thread can still get its 0, 1, 2 ID
46 std::cout << "Thread " << std::this_thread::get_id()
47 << " assigned itself Custom ID: " << get_clean_thread_id() << "\n";
48}
49
50
51
52} // namespace
53
54//
55// static data, methods
56//
57
59Bool_t TMCRootManager::fgDebug = false;
61
62//_____________________________________________________________________________
69
70//
71// ctors, dtor
72//
73
74//_____________________________________________________________________________
75TMCRootManager::TMCRootManager(const char *projectName, TMCRootManager::FileMode fileMode, Int_t threadRank)
76 : fFile(0), fTree(0), fIsClosed(false)
77{
82
83 if (fgDebug)
84 printf("TMCRootManager::TMCRootManager %p \n", this);
85
86 // lock mutex
87 TMCAutoLock lk(&createMutex);
88
89 // Set Id
90 fId = fgCounter;
91
92 // Increment counter
93 ++fgCounter;
94
95 // singleton instance
96 if (fgInstance) {
97 Fatal("TMCRootManager", "Attempt to create two instances of singleton.");
98 return;
99 }
100
101 fgInstance = this;
102
103 // open file and create a tree
104 OpenFile(projectName, fileMode, threadRank);
105
106 // unlock mutex
107 lk.unlock();
108
109 if (fgDebug)
110 printf("Done TMCRootManagerMT::TMCRootManagerMT %p \n", this);
111}
112
113//_____________________________________________________________________________
115{
117
118 if (fgDebug)
119 printf("TMCRootManager::~TMCRootManager %p \n", this);
120
121 // lock mutex
122 TMCAutoLock lk(&deleteMutex);
123
124 if (fFile && !fIsClosed)
125 fFile->Close();
126 delete fFile;
127
128 --fgCounter;
129
130 // unlock mutex
131 lk.unlock();
132
133 if (fgDebug)
134 printf("Done TMCRootManager::~TMCRootManager %p \n", this);
135}
136
137//
138// privatemethods
139//
140
141//_____________________________________________________________________________
142void TMCRootManager::OpenFile(const char *projectName, FileMode fileMode, Int_t threadRank)
143{
144 TString fileName(projectName);
145 if (threadRank > 0) {
146 Int_t threadId = get_clean_thread_id();
147 fileName += "_";
148 fileName += threadId;
149 }
150 fileName += ".root";
151
152 TString treeTitle(projectName);
153 treeTitle += " tree";
154
155 switch (fileMode) {
157 fFile = new TFile(fileName);
158 fTree = (TTree *)fFile->Get(projectName);
159 break;
160
162 if (fgDebug)
163 printf("Going to create Root file \n");
164 fFile = new TFile(fileName, "recreate");
165 if (fgDebug)
166 printf("Done: file %p \n", fFile);
167
168 if (fgDebug)
169 printf("Going to create TTree \n");
170 fTree = new TTree(projectName, treeTitle);
171 if (fgDebug)
172 printf("Done: TTree %p \n", fTree);
173 ;
174 ;
175 }
176}
177
178//
179// public methods
180//
181
182//_____________________________________________________________________________
183void TMCRootManager::Register(const char *name, const char *className, void *objAddress)
184{
189
190 fFile->cd();
191 if (!fTree->GetBranch(name))
192 fTree->Branch(name, className, objAddress, 32000, 99);
193 else
194 fTree->GetBranch(name)->SetAddress(objAddress);
195}
196
197//_____________________________________________________________________________
198void TMCRootManager::Register(const char *name, const char *className, const void *objAddress)
199{
204
205 Register(name, className, const_cast<void *>(objAddress));
206}
207
208//_____________________________________________________________________________
210{
212
213 fFile->cd();
214 fTree->Fill();
215}
216
217//_____________________________________________________________________________
219{
221
222 fFile->cd();
223 fFile->Write();
224}
225
226//_____________________________________________________________________________
228{
230
231 if (fIsClosed) {
232 Error("Close", "The file was already closed.");
233 return;
234 }
235
236 fFile->cd();
237 fFile->Close();
238 fIsClosed = true;
239}
240
241//_____________________________________________________________________________
243{
245
246 WriteAll();
247 Close();
248}
249
250//_____________________________________________________________________________
252{
255
256 fTree->GetEntry(i);
257}
std::mutex TMCMutex
TMCTemplateAutoLock< TMCMutex > TMCAutoLock
#define TMCMUTEX_INITIALIZER
Definition of the TMCRootManager class.
The Root IO manager for VMC examples for both sequential and multi-threaded applications.
void OpenFile(const char *projectName, FileMode fileMode, Int_t threadRank)
void ReadEvent(Int_t i)
static TMCThreadLocal TMCRootManager * fgInstance
FileMode
Root file mode.
static Bool_t fgDebug
void Register(const char *name, const char *className, void *objAddress)
virtual ~TMCRootManager()
static Int_t fgCounter
static TMCRootManager * Instance()
TMCRootManager(const char *projectName, FileMode fileMode=kWrite, Int_t threadRank=-1)