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 >> 47 //_____________________________________________________________________________ >> 48 const G4String G4Hdf5FileManager::fgkDefaultDirectoryName = "default"; 46 49 47 //____________________________________________ 50 //_____________________________________________________________________________ 48 G4Hdf5FileManager::G4Hdf5FileManager(const G4A 51 G4Hdf5FileManager::G4Hdf5FileManager(const G4AnalysisManagerState& state) 49 : G4VTFileManager<G4Hdf5File>(state) << 52 : G4VTFileManager<G4Hdf5File>(state), >> 53 fBasketSize(0) // TO DO: check default value !! (433 in test) 50 { 54 { 51 // Create helpers defined in the base class 55 // Create helpers defined in the base class 52 fH1FileManager = std::make_shared<G4Hdf5HnFi 56 fH1FileManager = std::make_shared<G4Hdf5HnFileManager<histo::h1d>>(this); 53 fH2FileManager = std::make_shared<G4Hdf5HnFi 57 fH2FileManager = std::make_shared<G4Hdf5HnFileManager<histo::h2d>>(this); 54 fH3FileManager = std::make_shared<G4Hdf5HnFi 58 fH3FileManager = std::make_shared<G4Hdf5HnFileManager<histo::h3d>>(this); 55 fP1FileManager = std::make_shared<G4Hdf5HnFi 59 fP1FileManager = std::make_shared<G4Hdf5HnFileManager<histo::p1d>>(this); 56 fP2FileManager = std::make_shared<G4Hdf5HnFi << 60 fP2FileManager = std::make_shared<G4Hdf5HnFileManager<histo::p2d>>(this); 57 } 61 } 58 62 59 // << 63 //_____________________________________________________________________________ >> 64 G4Hdf5FileManager::~G4Hdf5FileManager() >> 65 {} >> 66 >> 67 // 60 // private methods 68 // private methods 61 // 69 // 62 70 63 //____________________________________________ 71 //_____________________________________________________________________________ 64 hid_t G4Hdf5FileManager::CreateDirectory(hid_t 72 hid_t G4Hdf5FileManager::CreateDirectory(hid_t& file, 65 const G4String& directoryName, const G4Strin 73 const G4String& directoryName, const G4String& objectType) 66 { 74 { 67 // Method for both histograms and ntuples dire 75 // Method for both histograms and ntuples directories. 68 76 69 // return if no file provided 77 // return if no file provided 70 if (file < 0) return kInvalidId; << 78 if ( file < 0 ) return false; 71 79 72 // use default directory name if not provide 80 // use default directory name if not provided 73 auto newDirectoryName = directoryName; 81 auto newDirectoryName = directoryName; 74 if ( newDirectoryName == "" ) { 82 if ( newDirectoryName == "" ) { 75 newDirectoryName = fgkDefaultDirectoryNa 83 newDirectoryName = fgkDefaultDirectoryName; 76 newDirectoryName += "_"; 84 newDirectoryName += "_"; 77 newDirectoryName += objectType; 85 newDirectoryName += objectType; 78 } 86 } 79 87 80 Message(kVL4, "create", "directory for " + o << 88 #ifdef G4VERBOSE >> 89 if ( fState.GetVerboseL4() ) { >> 90 fState.GetVerboseL4() >> 91 ->Message("create", "directory for " + objectType, newDirectoryName); >> 92 } >> 93 #endif 81 94 82 auto success = true; 95 auto success = true; 83 96 84 // create directory 97 // create directory 85 auto directory = toolx_H5Gcreate(file, newDi << 98 auto directory = tools_H5Gcreate(file, newDirectoryName, 0); 86 // 0 seems to be an optional parameter. 99 // 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 100 // 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. 101 // default value is taken. 89 if ( directory < 0 ) { 102 if ( directory < 0 ) { 90 Warn("Cannot create directory " + director << 103 G4ExceptionDescription description; 91 fkClass, "CreateDirectory"); << 104 description << " " >> 105 << "cannot create directory " << directoryName; >> 106 G4Exception("G4Hdf5FileManager::CreateDirectory()", >> 107 "Analysis_W001", JustWarning, description); 92 success = false; 108 success = false; 93 } 109 } 94 else { 110 else { 95 // write atb (header?) 111 // write atb (header?) 96 auto result = toolx::hdf5::write_atb(direc << 112 auto result = hdf5::write_atb(directory, "type", "directory"); 97 if ( !result) { 113 if ( !result) { 98 Warn("Write_atb class failed for " + dir << 114 G4ExceptionDescription description; 99 fkClass, "CreateDirectory"); << 115 description << " " >> 116 << "write_atb class failed for " << directoryName; >> 117 G4Exception("G4Hdf5FileManager::CreateDirectory()", >> 118 "Analysis_W001", JustWarning, description); 100 success = false; 119 success = false; 101 } 120 } 102 } 121 } 103 122 104 Message(kVL2, "create", "directory for " + o << 123 #ifdef G4VERBOSE 105 << 124 if ( fState.GetVerboseL2() ) { >> 125 fState.GetVerboseL2() >> 126 ->Message("create", "directory for " + objectType, newDirectoryName, success); >> 127 } >> 128 #endif 106 return directory; 129 return directory; 107 } 130 } 108 131 109 //____________________________________________ 132 //_____________________________________________________________________________ 110 G4String G4Hdf5FileManager::GetNtupleFileName( 133 G4String G4Hdf5FileManager::GetNtupleFileName(Hdf5NtupleDescription* ntupleDescription) 111 { 134 { 112 // get ntuple file name << 135 // get ntuple file name 113 auto ntupleFileName = ntupleDescription->Get << 136 auto ntupleFileName = ntupleDescription->fFileName; 114 if (ntupleFileName.size() != 0u) { << 137 if ( ntupleFileName.size() ) { 115 // update filename per object per thread 138 // update filename per object per thread 116 ntupleFileName = GetTnFileName(ntupleFileN 139 ntupleFileName = GetTnFileName(ntupleFileName, GetFileType()); 117 } << 140 } else { 118 else { << 119 // get default file name 141 // get default file name 120 ntupleFileName = GetFullFileName(); 142 ntupleFileName = GetFullFileName(); 121 } 143 } 122 return ntupleFileName; 144 return ntupleFileName; 123 } << 145 } 124 146 125 // << 147 // 126 // protected methods 148 // protected methods 127 // 149 // 128 150 129 //____________________________________________ 151 //_____________________________________________________________________________ 130 std::shared_ptr<G4Hdf5File> G4Hdf5FileManager: 152 std::shared_ptr<G4Hdf5File> G4Hdf5FileManager::CreateFileImpl(const G4String& fileName) 131 { 153 { 132 // create a new file 154 // create a new file 133 hid_t file = ::H5Fcreate(fileName, H5F_ACC_T 155 hid_t file = ::H5Fcreate(fileName, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); 134 156 135 // Do nothing if there is no file 157 // Do nothing if there is no file 136 // (the error should be handled by caller) 158 // (the error should be handled by caller) 137 if ( file < 0 ) { 159 if ( file < 0 ) { 138 Warn("::H5Fcreate failed " + fileName, fkC << 160 G4ExceptionDescription description; >> 161 description << " " << "::H5Fcreate failed " << fileName; >> 162 G4Exception("G4Hdf5AnalysisManager::CreateFileImpl()", >> 163 "Analysis_W001", JustWarning, description); 139 return std::make_shared<G4Hdf5File>(-1, -1 164 return std::make_shared<G4Hdf5File>(-1, -1, -1); 140 } 165 } 141 166 142 // create a header with general infos 167 // create a header with general infos 143 if(!toolx::hdf5::write_header(file)) { << 168 if(!tools::hdf5::write_header(file)) { 144 Warn("toolx::hdf5::write_header() failed f << 169 G4ExceptionDescription description; 145 fkClass, "CreateFileImpl"); << 170 description << " " << "tools::hdf5::write_header() failed for " << fileName; >> 171 G4Exception("G4Hdf5AnalysisManager::CreateFileImpl()", >> 172 "Analysis_W001", JustWarning, description); 146 return std::make_shared<G4Hdf5File>(-1, -1 173 return std::make_shared<G4Hdf5File>(-1, -1, -1); 147 } 174 } 148 175 149 // create histo directory 176 // create histo directory 150 auto hdirectory 177 auto hdirectory 151 = CreateDirectory(file, fHistoDirectoryNam 178 = CreateDirectory(file, fHistoDirectoryName, "histograms"); 152 if ( hdirectory < 0 ) { 179 if ( hdirectory < 0 ) { 153 // Warning is issued in CreateDirectory << 180 // Warnin is issued in CreateDirectory 154 return std::make_shared<G4Hdf5File>(-1, -1 181 return std::make_shared<G4Hdf5File>(-1, -1, -1); 155 } 182 } 156 183 157 // create ntuple directory 184 // create ntuple directory 158 auto ndirectory 185 auto ndirectory 159 = CreateDirectory(file, fNtupleDirectoryNa 186 = CreateDirectory(file, fNtupleDirectoryName, "ntuples"); 160 if ( ndirectory < 0 ) { 187 if ( ndirectory < 0 ) { 161 // Warnin is issued in CreateDirectory 188 // Warnin is issued in CreateDirectory 162 return std::make_shared<G4Hdf5File>(-1, -1 189 return std::make_shared<G4Hdf5File>(-1, -1, -1); 163 } 190 } 164 191 165 return std::make_shared<G4Hdf5File>(file, hd 192 return std::make_shared<G4Hdf5File>(file, hdirectory, ndirectory); 166 } 193 } 167 194 168 //____________________________________________ 195 //_____________________________________________________________________________ 169 G4bool G4Hdf5FileManager::WriteFileImpl(std::s 196 G4bool G4Hdf5FileManager::WriteFileImpl(std::shared_ptr<G4Hdf5File> /*file*/) 170 { 197 { 171 // Nothing to be done here 198 // Nothing to be done here 172 return true; 199 return true; 173 } 200 } 174 201 175 //____________________________________________ 202 //_____________________________________________________________________________ 176 G4bool G4Hdf5FileManager::CloseFileImpl(std::s 203 G4bool G4Hdf5FileManager::CloseFileImpl(std::shared_ptr<G4Hdf5File> file) 177 { 204 { 178 if ( ! file ) return false; 205 if ( ! file ) return false; 179 206 180 G4AutoLock lock(&closeFileMutex); 207 G4AutoLock lock(&closeFileMutex); 181 208 182 ::H5Gclose(std::get<1>(*file)); 209 ::H5Gclose(std::get<1>(*file)); 183 ::H5Gclose(std::get<2>(*file)); 210 ::H5Gclose(std::get<2>(*file)); 184 ::H5Fclose(std::get<0>(*file)); 211 ::H5Fclose(std::get<0>(*file)); 185 212 186 lock.unlock(); 213 lock.unlock(); 187 214 188 return true; 215 return true; 189 } 216 } 190 217 191 // 218 // 192 // public methods 219 // public methods 193 // 220 // 194 221 195 //____________________________________________ 222 //_____________________________________________________________________________ 196 G4bool G4Hdf5FileManager::OpenFile(const G4Str 223 G4bool G4Hdf5FileManager::OpenFile(const G4String& fileName) 197 { 224 { 198 // Keep file name 225 // Keep file name 199 fFileName = fileName; 226 fFileName = fileName; 200 auto name = GetFullFileName(); 227 auto name = GetFullFileName(); 201 228 202 if ( fFile ) { 229 if ( fFile ) { 203 Warn("File " + fileName + " already exists << 230 G4ExceptionDescription description; >> 231 description >> 232 << "File " << fileName << " already exists."; >> 233 G4Exception("G4Hdf5FileManager::OpenFile()", >> 234 "Analysis_W001", JustWarning, description); 204 fFile.reset(); 235 fFile.reset(); 205 } 236 } 206 237 207 // create new file 238 // create new file 208 fFile = CreateTFile(name); 239 fFile = CreateTFile(name); 209 if ( ! fFile ) { 240 if ( ! fFile ) { 210 Warn("Failed to create file " + fileName, << 241 G4ExceptionDescription description; >> 242 description << "Failed to create file " << fileName; >> 243 G4Exception("G4Hdf5FileManager::OpenFile()", >> 244 "Analysis_W001", JustWarning, description); 211 return false; 245 return false; 212 } 246 } 213 247 214 LockDirectoryNames(); << 248 fLockDirectoryNames = true; 215 fIsOpenFile = true; 249 fIsOpenFile = true; 216 250 217 return true; 251 return true; 218 } 252 } 219 << 253 220 //____________________________________________ 254 //_____________________________________________________________________________ 221 G4bool G4Hdf5FileManager::CreateNtupleFile( 255 G4bool G4Hdf5FileManager::CreateNtupleFile( 222 Hdf5NtupleDescription* ntupleDescription) 256 Hdf5NtupleDescription* ntupleDescription) 223 { 257 { 224 // get ntuple file name per object 258 // get ntuple file name per object 225 auto ntupleFileName = GetNtupleFileName(ntup 259 auto ntupleFileName = GetNtupleFileName(ntupleDescription); 226 260 227 auto file = GetTFile(ntupleFileName, false); 261 auto file = GetTFile(ntupleFileName, false); 228 if (! file) { 262 if (! file) { 229 file = CreateTFile(ntupleFileName); 263 file = CreateTFile(ntupleFileName); 230 } 264 } 231 ntupleDescription->SetFile(file); << 265 ntupleDescription->fFile = file; 232 266 233 return (ntupleDescription->GetFile() != null << 267 return (ntupleDescription->fFile != nullptr); 234 } 268 } 235 269 236 //____________________________________________ 270 //_____________________________________________________________________________ 237 G4bool G4Hdf5FileManager::CloseNtupleFile( 271 G4bool G4Hdf5FileManager::CloseNtupleFile( 238 Hdf5NtupleDescription* ntupleDescription) 272 Hdf5NtupleDescription* ntupleDescription) 239 { 273 { >> 274 // Do nothing if there is no file >> 275 if ( ! ntupleDescription->fFile ) return true; >> 276 >> 277 // Ntuple files will be closed with CloseFiles() calls >> 278 ntupleDescription->fFile.reset(); >> 279 240 // Notify not empty file 280 // Notify not empty file 241 auto ntupleFileName = GetNtupleFileName(ntup 281 auto ntupleFileName = GetNtupleFileName(ntupleDescription); 242 auto result = SetIsEmpty(ntupleFileName, ! n << 282 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 283 248 return result; 284 return result; 249 } 285 } 250 286 251 //____________________________________________ 287 //_____________________________________________________________________________ 252 hid_t G4Hdf5FileManager::GetHistoDirectory() c 288 hid_t G4Hdf5FileManager::GetHistoDirectory() const 253 { 289 { 254 if ( ! fFile ) return kInvalidId; 290 if ( ! fFile ) return kInvalidId; 255 291 256 return std::get<1>(*fFile); 292 return std::get<1>(*fFile); 257 } 293 } 258 294 259 //____________________________________________ 295 //_____________________________________________________________________________ 260 hid_t G4Hdf5FileManager::GetNtupleDirectory() 296 hid_t G4Hdf5FileManager::GetNtupleDirectory() const 261 { 297 { 262 if ( ! fFile ) return kInvalidId; 298 if ( ! fFile ) return kInvalidId; 263 299 264 return std::get<2>(*fFile); 300 return std::get<2>(*fFile); 265 } 301 } 266 302