Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 26 27 // Author: Ivana Hrivnacova, 20/07/2017 (ivana 27 // Author: Ivana Hrivnacova, 20/07/2017 (ivana@ipno.in2p3.fr) 28 28 29 #include "G4Hdf5FileManager.hh" 29 #include "G4Hdf5FileManager.hh" 30 #include "G4Hdf5HnFileManager.hh" 30 #include "G4Hdf5HnFileManager.hh" 31 #include "G4AnalysisManagerState.hh" 31 #include "G4AnalysisManagerState.hh" 32 #include "G4AnalysisUtilities.hh" 32 #include "G4AnalysisUtilities.hh" 33 #include "G4AutoLock.hh" 33 #include "G4AutoLock.hh" 34 34 35 #include "toolx/hdf5/h2file" << 35 #include "tools/hdf5/h2file" 36 36 37 using namespace G4Analysis; 37 using namespace G4Analysis; 38 using namespace tools; 38 using namespace tools; 39 39 40 //using namespace G4Analysis; 40 //using namespace G4Analysis; 41 41 42 namespace { 42 namespace { 43 //Mutex to lock master manager when closing 43 //Mutex to lock master manager when closing a file 44 G4Mutex closeFileMutex = G4MUTEX_INITIALIZER 44 G4Mutex closeFileMutex = G4MUTEX_INITIALIZER; 45 } 45 } 46 46 47 //____________________________________________ 47 //_____________________________________________________________________________ 48 G4Hdf5FileManager::G4Hdf5FileManager(const G4A 48 G4Hdf5FileManager::G4Hdf5FileManager(const G4AnalysisManagerState& state) 49 : G4VTFileManager<G4Hdf5File>(state) 49 : G4VTFileManager<G4Hdf5File>(state) 50 { 50 { 51 // Create helpers defined in the base class 51 // Create helpers defined in the base class 52 fH1FileManager = std::make_shared<G4Hdf5HnFi 52 fH1FileManager = std::make_shared<G4Hdf5HnFileManager<histo::h1d>>(this); 53 fH2FileManager = std::make_shared<G4Hdf5HnFi 53 fH2FileManager = std::make_shared<G4Hdf5HnFileManager<histo::h2d>>(this); 54 fH3FileManager = std::make_shared<G4Hdf5HnFi 54 fH3FileManager = std::make_shared<G4Hdf5HnFileManager<histo::h3d>>(this); 55 fP1FileManager = std::make_shared<G4Hdf5HnFi 55 fP1FileManager = std::make_shared<G4Hdf5HnFileManager<histo::p1d>>(this); 56 fP2FileManager = std::make_shared<G4Hdf5HnFi 56 fP2FileManager = std::make_shared<G4Hdf5HnFileManager<histo::p2d>>(this); 57 } 57 } 58 58 59 // 59 // 60 // private methods 60 // private methods 61 // 61 // 62 62 63 //____________________________________________ 63 //_____________________________________________________________________________ 64 hid_t G4Hdf5FileManager::CreateDirectory(hid_t 64 hid_t G4Hdf5FileManager::CreateDirectory(hid_t& file, 65 const G4String& directoryName, const G4Strin 65 const G4String& directoryName, const G4String& objectType) 66 { 66 { 67 // Method for both histograms and ntuples dire 67 // Method for both histograms and ntuples directories. 68 68 69 // return if no file provided 69 // return if no file provided 70 if (file < 0) return kInvalidId; << 70 if ( file < 0 ) return false; 71 71 72 // use default directory name if not provide 72 // use default directory name if not provided 73 auto newDirectoryName = directoryName; 73 auto newDirectoryName = directoryName; 74 if ( newDirectoryName == "" ) { 74 if ( newDirectoryName == "" ) { 75 newDirectoryName = fgkDefaultDirectoryNa 75 newDirectoryName = fgkDefaultDirectoryName; 76 newDirectoryName += "_"; 76 newDirectoryName += "_"; 77 newDirectoryName += objectType; 77 newDirectoryName += objectType; 78 } 78 } 79 79 80 Message(kVL4, "create", "directory for " + o 80 Message(kVL4, "create", "directory for " + objectType, newDirectoryName); 81 81 82 auto success = true; 82 auto success = true; 83 83 84 // create directory 84 // create directory 85 auto directory = toolx_H5Gcreate(file, newDi << 85 auto directory = tools_H5Gcreate(file, newDirectoryName, 0); 86 // 0 seems to be an optional parameter. 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 i 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. 88 // default value is taken. 89 if ( directory < 0 ) { 89 if ( directory < 0 ) { 90 Warn("Cannot create directory " + director 90 Warn("Cannot create directory " + directoryName, 91 fkClass, "CreateDirectory"); 91 fkClass, "CreateDirectory"); 92 success = false; 92 success = false; 93 } 93 } 94 else { 94 else { 95 // write atb (header?) 95 // write atb (header?) 96 auto result = toolx::hdf5::write_atb(direc << 96 auto result = hdf5::write_atb(directory, "type", "directory"); 97 if ( !result) { 97 if ( !result) { 98 Warn("Write_atb class failed for " + dir 98 Warn("Write_atb class failed for " + directoryName, 99 fkClass, "CreateDirectory"); 99 fkClass, "CreateDirectory"); 100 success = false; 100 success = false; 101 } 101 } 102 } 102 } 103 103 104 Message(kVL2, "create", "directory for " + o 104 Message(kVL2, "create", "directory for " + objectType, newDirectoryName, success); 105 105 106 return directory; 106 return directory; 107 } 107 } 108 108 109 //____________________________________________ 109 //_____________________________________________________________________________ 110 G4String G4Hdf5FileManager::GetNtupleFileName( 110 G4String G4Hdf5FileManager::GetNtupleFileName(Hdf5NtupleDescription* ntupleDescription) 111 { 111 { 112 // get ntuple file name 112 // get ntuple file name 113 auto ntupleFileName = ntupleDescription->Get << 113 auto ntupleFileName = ntupleDescription->fFileName; 114 if (ntupleFileName.size() != 0u) { << 114 if ( ntupleFileName.size() ) { 115 // update filename per object per thread 115 // update filename per object per thread 116 ntupleFileName = GetTnFileName(ntupleFileN 116 ntupleFileName = GetTnFileName(ntupleFileName, GetFileType()); 117 } << 117 } else { 118 else { << 119 // get default file name 118 // get default file name 120 ntupleFileName = GetFullFileName(); 119 ntupleFileName = GetFullFileName(); 121 } 120 } 122 return ntupleFileName; 121 return ntupleFileName; 123 } 122 } 124 123 125 // 124 // 126 // protected methods 125 // protected methods 127 // 126 // 128 127 129 //____________________________________________ 128 //_____________________________________________________________________________ 130 std::shared_ptr<G4Hdf5File> G4Hdf5FileManager: 129 std::shared_ptr<G4Hdf5File> G4Hdf5FileManager::CreateFileImpl(const G4String& fileName) 131 { 130 { 132 // create a new file 131 // create a new file 133 hid_t file = ::H5Fcreate(fileName, H5F_ACC_T 132 hid_t file = ::H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); 134 133 135 // Do nothing if there is no file 134 // Do nothing if there is no file 136 // (the error should be handled by caller) 135 // (the error should be handled by caller) 137 if ( file < 0 ) { 136 if ( file < 0 ) { 138 Warn("::H5Fcreate failed " + fileName, fkC 137 Warn("::H5Fcreate failed " + fileName, fkClass, "CreateFileImpl"); 139 return std::make_shared<G4Hdf5File>(-1, -1 138 return std::make_shared<G4Hdf5File>(-1, -1, -1); 140 } 139 } 141 140 142 // create a header with general infos 141 // create a header with general infos 143 if(!toolx::hdf5::write_header(file)) { << 142 if(!tools::hdf5::write_header(file)) { 144 Warn("toolx::hdf5::write_header() failed f << 143 Warn("tools::hdf5::write_header() failed for " + fileName, 145 fkClass, "CreateFileImpl"); 144 fkClass, "CreateFileImpl"); 146 return std::make_shared<G4Hdf5File>(-1, -1 145 return std::make_shared<G4Hdf5File>(-1, -1, -1); 147 } 146 } 148 147 149 // create histo directory 148 // create histo directory 150 auto hdirectory 149 auto hdirectory 151 = CreateDirectory(file, fHistoDirectoryNam 150 = CreateDirectory(file, fHistoDirectoryName, "histograms"); 152 if ( hdirectory < 0 ) { 151 if ( hdirectory < 0 ) { 153 // Warning is issued in CreateDirectory 152 // Warning is issued in CreateDirectory 154 return std::make_shared<G4Hdf5File>(-1, -1 153 return std::make_shared<G4Hdf5File>(-1, -1, -1); 155 } 154 } 156 155 157 // create ntuple directory 156 // create ntuple directory 158 auto ndirectory 157 auto ndirectory 159 = CreateDirectory(file, fNtupleDirectoryNa 158 = CreateDirectory(file, fNtupleDirectoryName, "ntuples"); 160 if ( ndirectory < 0 ) { 159 if ( ndirectory < 0 ) { 161 // Warnin is issued in CreateDirectory 160 // Warnin is issued in CreateDirectory 162 return std::make_shared<G4Hdf5File>(-1, -1 161 return std::make_shared<G4Hdf5File>(-1, -1, -1); 163 } 162 } 164 163 165 return std::make_shared<G4Hdf5File>(file, hd 164 return std::make_shared<G4Hdf5File>(file, hdirectory, ndirectory); 166 } 165 } 167 166 168 //____________________________________________ 167 //_____________________________________________________________________________ 169 G4bool G4Hdf5FileManager::WriteFileImpl(std::s 168 G4bool G4Hdf5FileManager::WriteFileImpl(std::shared_ptr<G4Hdf5File> /*file*/) 170 { 169 { 171 // Nothing to be done here 170 // Nothing to be done here 172 return true; 171 return true; 173 } 172 } 174 173 175 //____________________________________________ 174 //_____________________________________________________________________________ 176 G4bool G4Hdf5FileManager::CloseFileImpl(std::s 175 G4bool G4Hdf5FileManager::CloseFileImpl(std::shared_ptr<G4Hdf5File> file) 177 { 176 { 178 if ( ! file ) return false; 177 if ( ! file ) return false; 179 178 180 G4AutoLock lock(&closeFileMutex); 179 G4AutoLock lock(&closeFileMutex); 181 180 182 ::H5Gclose(std::get<1>(*file)); 181 ::H5Gclose(std::get<1>(*file)); 183 ::H5Gclose(std::get<2>(*file)); 182 ::H5Gclose(std::get<2>(*file)); 184 ::H5Fclose(std::get<0>(*file)); 183 ::H5Fclose(std::get<0>(*file)); 185 184 186 lock.unlock(); 185 lock.unlock(); 187 186 188 return true; 187 return true; 189 } 188 } 190 189 191 // 190 // 192 // public methods 191 // public methods 193 // 192 // 194 193 195 //____________________________________________ 194 //_____________________________________________________________________________ 196 G4bool G4Hdf5FileManager::OpenFile(const G4Str 195 G4bool G4Hdf5FileManager::OpenFile(const G4String& fileName) 197 { 196 { 198 // Keep file name 197 // Keep file name 199 fFileName = fileName; 198 fFileName = fileName; 200 auto name = GetFullFileName(); 199 auto name = GetFullFileName(); 201 200 202 if ( fFile ) { 201 if ( fFile ) { 203 Warn("File " + fileName + " already exists 202 Warn("File " + fileName + " already exists.", fkClass, "OpenFile"); 204 fFile.reset(); 203 fFile.reset(); 205 } 204 } 206 205 207 // create new file 206 // create new file 208 fFile = CreateTFile(name); 207 fFile = CreateTFile(name); 209 if ( ! fFile ) { 208 if ( ! fFile ) { 210 Warn("Failed to create file " + fileName, 209 Warn("Failed to create file " + fileName, fkClass, "OpenFile"); 211 return false; 210 return false; 212 } 211 } 213 212 214 LockDirectoryNames(); 213 LockDirectoryNames(); 215 fIsOpenFile = true; 214 fIsOpenFile = true; 216 215 217 return true; 216 return true; 218 } 217 } 219 218 220 //____________________________________________ 219 //_____________________________________________________________________________ 221 G4bool G4Hdf5FileManager::CreateNtupleFile( 220 G4bool G4Hdf5FileManager::CreateNtupleFile( 222 Hdf5NtupleDescription* ntupleDescription) 221 Hdf5NtupleDescription* ntupleDescription) 223 { 222 { 224 // get ntuple file name per object 223 // get ntuple file name per object 225 auto ntupleFileName = GetNtupleFileName(ntup 224 auto ntupleFileName = GetNtupleFileName(ntupleDescription); 226 225 227 auto file = GetTFile(ntupleFileName, false); 226 auto file = GetTFile(ntupleFileName, false); 228 if (! file) { 227 if (! file) { 229 file = CreateTFile(ntupleFileName); 228 file = CreateTFile(ntupleFileName); 230 } 229 } 231 ntupleDescription->SetFile(file); << 230 ntupleDescription->fFile = file; 232 231 233 return (ntupleDescription->GetFile() != null << 232 return (ntupleDescription->fFile != nullptr); 234 } 233 } 235 234 236 //____________________________________________ 235 //_____________________________________________________________________________ 237 G4bool G4Hdf5FileManager::CloseNtupleFile( 236 G4bool G4Hdf5FileManager::CloseNtupleFile( 238 Hdf5NtupleDescription* ntupleDescription) 237 Hdf5NtupleDescription* ntupleDescription) 239 { 238 { >> 239 // Do nothing if there is no file >> 240 if ( ntupleDescription->fFile == nullptr ) return true; >> 241 >> 242 // Ntuple files will be closed with CloseFiles() calls >> 243 ntupleDescription->fFile.reset(); >> 244 240 // Notify not empty file 245 // Notify not empty file 241 auto ntupleFileName = GetNtupleFileName(ntup 246 auto ntupleFileName = GetNtupleFileName(ntupleDescription); 242 auto result = SetIsEmpty(ntupleFileName, ! n << 247 auto result = SetIsEmpty(ntupleFileName, ! ntupleDescription->fHasFill); 243 << 244 // Ntuple files are registered in file manag << 245 // they will be closed with CloseFiles() cal << 246 ntupleDescription->GetFile().reset(); << 247 248 248 return result; 249 return result; 249 } 250 } 250 251 251 //____________________________________________ 252 //_____________________________________________________________________________ 252 hid_t G4Hdf5FileManager::GetHistoDirectory() c 253 hid_t G4Hdf5FileManager::GetHistoDirectory() const 253 { 254 { 254 if ( ! fFile ) return kInvalidId; 255 if ( ! fFile ) return kInvalidId; 255 256 256 return std::get<1>(*fFile); 257 return std::get<1>(*fFile); 257 } 258 } 258 259 259 //____________________________________________ 260 //_____________________________________________________________________________ 260 hid_t G4Hdf5FileManager::GetNtupleDirectory() 261 hid_t G4Hdf5FileManager::GetNtupleDirectory() const 261 { 262 { 262 if ( ! fFile ) return kInvalidId; 263 if ( ! fFile ) return kInvalidId; 263 264 264 return std::get<2>(*fFile); 265 return std::get<2>(*fFile); 265 } 266 } 266 267