Geant4 Cross Reference |
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" 30 #include "G4Hdf5HnFileManager.hh" 31 #include "G4AnalysisManagerState.hh" 32 #include "G4AnalysisUtilities.hh" 33 #include "G4AutoLock.hh" 34 35 #include "toolx/hdf5/h2file" 36 37 using namespace G4Analysis; 38 using namespace tools; 39 40 //using namespace G4Analysis; 41 42 namespace { 43 //Mutex to lock master manager when closing a file 44 G4Mutex closeFileMutex = G4MUTEX_INITIALIZER; 45 } 46 47 //_____________________________________________________________________________ 48 G4Hdf5FileManager::G4Hdf5FileManager(const G4AnalysisManagerState& state) 49 : G4VTFileManager<G4Hdf5File>(state) 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 //_____________________________________________________________________________ 64 hid_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 //_____________________________________________________________________________ 110 G4String 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 //_____________________________________________________________________________ 130 std::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 //_____________________________________________________________________________ 169 G4bool G4Hdf5FileManager::WriteFileImpl(std::shared_ptr<G4Hdf5File> /*file*/) 170 { 171 // Nothing to be done here 172 return true; 173 } 174 175 //_____________________________________________________________________________ 176 G4bool 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 //_____________________________________________________________________________ 196 G4bool G4Hdf5FileManager::OpenFile(const G4String& fileName) 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 214 LockDirectoryNames(); 215 fIsOpenFile = true; 216 217 return true; 218 } 219 220 //_____________________________________________________________________________ 221 G4bool G4Hdf5FileManager::CreateNtupleFile( 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 //_____________________________________________________________________________ 237 G4bool G4Hdf5FileManager::CloseNtupleFile( 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 //_____________________________________________________________________________ 252 hid_t G4Hdf5FileManager::GetHistoDirectory() const 253 { 254 if ( ! fFile ) return kInvalidId; 255 256 return std::get<1>(*fFile); 257 } 258 259 //_____________________________________________________________________________ 260 hid_t G4Hdf5FileManager::GetNtupleDirectory() const 261 { 262 if ( ! fFile ) return kInvalidId; 263 264 return std::get<2>(*fFile); 265 } 266