Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4Hdf5FileManager.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, 20/07/2017 (ivana@ipno.in2p3.fr)
28
29#include "G4Hdf5FileManager.hh"
33#include "G4AutoLock.hh"
34
35#include "toolx/hdf5/h2file"
36
37using namespace G4Analysis;
38using namespace tools;
39
40//using namespace G4Analysis;
41
42namespace {
43 //Mutex to lock master manager when closing a file
44 G4Mutex closeFileMutex = G4MUTEX_INITIALIZER;
45}
46
47//_____________________________________________________________________________
50{
51 // Create helpers defined in the base class
52 fH1FileManager = std::make_shared<G4Hdf5HnFileManager<histo::h1d>>(this);
53 fH2FileManager = std::make_shared<G4Hdf5HnFileManager<histo::h2d>>(this);
54 fH3FileManager = std::make_shared<G4Hdf5HnFileManager<histo::h3d>>(this);
55 fP1FileManager = std::make_shared<G4Hdf5HnFileManager<histo::p1d>>(this);
56 fP2FileManager = std::make_shared<G4Hdf5HnFileManager<histo::p2d>>(this);
57}
58
59//
60// private methods
61//
62
63//_____________________________________________________________________________
64hid_t G4Hdf5FileManager::CreateDirectory(hid_t& file,
65 const G4String& directoryName, const G4String& objectType)
66{
67// Method for both histograms and ntuples directories.
68
69 // return if no file provided
70 if (file < 0) return kInvalidId;
71
72 // use default directory name if not provided
73 auto newDirectoryName = directoryName;
74 if ( newDirectoryName == "" ) {
75 newDirectoryName = fgkDefaultDirectoryName;
76 newDirectoryName += "_";
77 newDirectoryName += objectType;
78 }
79
80 Message(kVL4, "create", "directory for " + objectType, newDirectoryName);
81
82 auto success = true;
83
84 // create directory
85 auto directory = toolx_H5Gcreate(file, newDirectoryName, 0);
86 // 0 seems to be an optional parameter. The web doc does not say what should
87 // be the default value but 0 is what is found in examples, and in the code, if we pass 0, clearly some
88 // default value is taken.
89 if ( directory < 0 ) {
90 Warn("Cannot create directory " + directoryName,
91 fkClass, "CreateDirectory");
92 success = false;
93 }
94 else {
95 // write atb (header?)
96 auto result = toolx::hdf5::write_atb(directory, "type", "directory");
97 if ( !result) {
98 Warn("Write_atb class failed for " + directoryName,
99 fkClass, "CreateDirectory");
100 success = false;
101 }
102 }
103
104 Message(kVL2, "create", "directory for " + objectType, newDirectoryName, success);
105
106 return directory;
107}
108
109//_____________________________________________________________________________
110G4String G4Hdf5FileManager::GetNtupleFileName(Hdf5NtupleDescription* ntupleDescription)
111{
112 // get ntuple file name
113 auto ntupleFileName = ntupleDescription->GetFileName();
114 if (ntupleFileName.size() != 0u) {
115 // update filename per object per thread
116 ntupleFileName = GetTnFileName(ntupleFileName, GetFileType());
117 }
118 else {
119 // get default file name
120 ntupleFileName = GetFullFileName();
121 }
122 return ntupleFileName;
123}
124
125//
126// protected methods
127//
128
129//_____________________________________________________________________________
130std::shared_ptr<G4Hdf5File> G4Hdf5FileManager::CreateFileImpl(const G4String& fileName)
131{
132 // create a new file
133 hid_t file = ::H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
134
135 // Do nothing if there is no file
136 // (the error should be handled by caller)
137 if ( file < 0 ) {
138 Warn("::H5Fcreate failed " + fileName, fkClass, "CreateFileImpl");
139 return std::make_shared<G4Hdf5File>(-1, -1, -1);
140 }
141
142 // create a header with general infos
143 if(!toolx::hdf5::write_header(file)) {
144 Warn("toolx::hdf5::write_header() failed for " + fileName,
145 fkClass, "CreateFileImpl");
146 return std::make_shared<G4Hdf5File>(-1, -1, -1);
147 }
148
149 // create histo directory
150 auto hdirectory
151 = CreateDirectory(file, fHistoDirectoryName, "histograms");
152 if ( hdirectory < 0 ) {
153 // Warning is issued in CreateDirectory
154 return std::make_shared<G4Hdf5File>(-1, -1, -1);
155 }
156
157 // create ntuple directory
158 auto ndirectory
159 = CreateDirectory(file, fNtupleDirectoryName, "ntuples");
160 if ( ndirectory < 0 ) {
161 // Warnin is issued in CreateDirectory
162 return std::make_shared<G4Hdf5File>(-1, -1, -1);
163 }
164
165 return std::make_shared<G4Hdf5File>(file, hdirectory, ndirectory);
166}
167
168//_____________________________________________________________________________
169G4bool G4Hdf5FileManager::WriteFileImpl(std::shared_ptr<G4Hdf5File> /*file*/)
170{
171 // Nothing to be done here
172 return true;
173}
174
175//_____________________________________________________________________________
176G4bool G4Hdf5FileManager::CloseFileImpl(std::shared_ptr<G4Hdf5File> file)
177{
178 if ( ! file ) return false;
179
180 G4AutoLock lock(&closeFileMutex);
181
182 ::H5Gclose(std::get<1>(*file));
183 ::H5Gclose(std::get<2>(*file));
184 ::H5Fclose(std::get<0>(*file));
185
186 lock.unlock();
187
188 return true;
189}
190
191//
192// public methods
193//
194
195//_____________________________________________________________________________
197{
198 // Keep file name
199 fFileName = fileName;
200 auto name = GetFullFileName();
201
202 if ( fFile ) {
203 Warn("File " + fileName + " already exists.", fkClass, "OpenFile");
204 fFile.reset();
205 }
206
207 // create new file
208 fFile = CreateTFile(name);
209 if ( ! fFile ) {
210 Warn("Failed to create file " + fileName, fkClass, "OpenFile");
211 return false;
212 }
213
215 fIsOpenFile = true;
216
217 return true;
218}
219
220//_____________________________________________________________________________
222 Hdf5NtupleDescription* ntupleDescription)
223{
224 // get ntuple file name per object
225 auto ntupleFileName = GetNtupleFileName(ntupleDescription);
226
227 auto file = GetTFile(ntupleFileName, false);
228 if (! file) {
229 file = CreateTFile(ntupleFileName);
230 }
231 ntupleDescription->SetFile(file);
232
233 return (ntupleDescription->GetFile() != nullptr);
234}
235
236//_____________________________________________________________________________
238 Hdf5NtupleDescription* ntupleDescription)
239{
240 // Notify not empty file
241 auto ntupleFileName = GetNtupleFileName(ntupleDescription);
242 auto result = SetIsEmpty(ntupleFileName, ! ntupleDescription->GetHasFill());
243
244 // Ntuple files are registered in file manager map.
245 // they will be closed with CloseFiles() calls
246 ntupleDescription->GetFile().reset();
247
248 return result;
249}
250
251//_____________________________________________________________________________
253{
254 if ( ! fFile ) return kInvalidId;
255
256 return std::get<1>(*fFile);
257}
258
259//_____________________________________________________________________________
261{
262 if ( ! fFile ) return kInvalidId;
263
264 return std::get<2>(*fFile);
265}
std::tuple< hid_t, hid_t, hid_t > G4Hdf5File
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:85
std::mutex G4Mutex
Definition: G4Threading.hh:81
bool G4bool
Definition: G4Types.hh:86
G4String GetFullFileName(const G4String &baseFileName="", G4bool isPerThread=true) const
void Message(G4int level, const G4String &action, const G4String &objectType, const G4String &objectName="", G4bool success=true) const
G4bool CloseFileImpl(std::shared_ptr< G4Hdf5File > file) final
G4String GetFileType() const final
hid_t GetNtupleDirectory() const
G4bool OpenFile(const G4String &fileName) final
G4bool CreateNtupleFile(Hdf5NtupleDescription *ntupleDescription)
std::shared_ptr< G4Hdf5File > CreateFileImpl(const G4String &fileName) final
hid_t GetHistoDirectory() const
G4bool CloseNtupleFile(Hdf5NtupleDescription *ntupleDescription)
G4bool WriteFileImpl(std::shared_ptr< G4Hdf5File > file) final
G4Hdf5FileManager()=delete
std::shared_ptr< FT > GetTFile(const G4String &fileName, G4bool warn=true) const
std::shared_ptr< FT > CreateTFile(const G4String &fileName)
void SetFile(std::shared_ptr< FT > file)
std::shared_ptr< FT > GetFile() const
G4String GetFileName() const
std::shared_ptr< G4VTHnFileManager< tools::histo::h3d > > fH3FileManager
std::shared_ptr< G4VTHnFileManager< tools::histo::h1d > > fH1FileManager
std::shared_ptr< G4VTHnFileManager< tools::histo::p1d > > fP1FileManager
G4String fNtupleDirectoryName
std::shared_ptr< G4VTHnFileManager< tools::histo::p2d > > fP2FileManager
void LockDirectoryNames()
std::shared_ptr< G4VTHnFileManager< tools::histo::h2d > > fH2FileManager
G4String fHistoDirectoryName
G4bool SetIsEmpty(const G4String &fileName, G4bool isEmpty) final
std::shared_ptr< G4Hdf5File > fFile
constexpr G4int kVL2
G4String GetTnFileName(const G4String &fileName, const G4String &fileType, G4int cycle=0)
constexpr G4int kVL4
constexpr G4int kInvalidId
void Warn(const G4String &message, const std::string_view inClass, const std::string_view inFunction)