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 // $Id$ 26 27 27 // Author: Ivana Hrivnacova, 20/07/2017 (ivana 28 // Author: Ivana Hrivnacova, 20/07/2017 (ivana@ipno.in2p3.fr) 28 29 29 #include "G4Hdf5FileManager.hh" 30 #include "G4Hdf5FileManager.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" << 34 33 35 #include "toolx/hdf5/h2file" << 34 #include "tools/hdf5/h2file" 36 35 37 using namespace G4Analysis; 36 using namespace G4Analysis; 38 using namespace tools; << 39 37 40 //using namespace G4Analysis; << 38 //_____________________________________________________________________________ 41 << 39 const G4String G4Hdf5FileManager::fgkDefaultDirectoryName = "default"; 42 namespace { << 43 //Mutex to lock master manager when closing << 44 G4Mutex closeFileMutex = G4MUTEX_INITIALIZER << 45 } << 46 40 47 //____________________________________________ 41 //_____________________________________________________________________________ 48 G4Hdf5FileManager::G4Hdf5FileManager(const G4A 42 G4Hdf5FileManager::G4Hdf5FileManager(const G4AnalysisManagerState& state) 49 : G4VTFileManager<G4Hdf5File>(state) << 43 : G4VFileManager(state), 50 { << 44 fFile(kInvalidId), 51 // Create helpers defined in the base class << 45 fHistoDirectory(kInvalidId), 52 fH1FileManager = std::make_shared<G4Hdf5HnFi << 46 fNtupleDirectory(kInvalidId), 53 fH2FileManager = std::make_shared<G4Hdf5HnFi << 47 fBasketSize(0) // TO DO: check default value !! (433 in test) 54 fH3FileManager = std::make_shared<G4Hdf5HnFi << 48 {} 55 fP1FileManager = std::make_shared<G4Hdf5HnFi << 56 fP2FileManager = std::make_shared<G4Hdf5HnFi << 57 } << 58 49 59 // << 50 //_____________________________________________________________________________ >> 51 G4Hdf5FileManager::~G4Hdf5FileManager() >> 52 {} >> 53 >> 54 // 60 // private methods 55 // private methods 61 // 56 // 62 57 63 //____________________________________________ 58 //_____________________________________________________________________________ 64 hid_t G4Hdf5FileManager::CreateDirectory(hid_t << 59 G4bool G4Hdf5FileManager::CreateDirectory(const G4String& directoryType, 65 const G4String& directoryName, const G4Strin << 60 const G4String& directoryName, hid_t& directory) 66 { 61 { 67 // Method for both histograms and ntuples dire 62 // Method for both histograms and ntuples directories. >> 63 // For histos: CreateDirectory("histograms", fHistoDirectoryName, fHistoDirectory) >> 64 // For ntples: CreateDirectory("ntuples", fNtupleDirectoryName, fNtupleDirectory) 68 65 69 // return if no file provided << 70 if (file < 0) return kInvalidId; << 71 << 72 // use default directory name if not provide << 73 auto newDirectoryName = directoryName; 66 auto newDirectoryName = directoryName; >> 67 74 if ( newDirectoryName == "" ) { 68 if ( newDirectoryName == "" ) { >> 69 // if ( fDefaultDirectory > 0 ) { >> 70 // // Return the default directory if the name is not set and the default directory >> 71 // // already exists >> 72 // directory = fDefaultDirectory; >> 73 // return true; >> 74 // } else { >> 75 // Create the default directory if the name is not set and the default directory >> 76 // does not yet exist 75 newDirectoryName = fgkDefaultDirectoryNa 77 newDirectoryName = fgkDefaultDirectoryName; 76 newDirectoryName += "_"; 78 newDirectoryName += "_"; 77 newDirectoryName += objectType; << 79 newDirectoryName += directoryType; 78 } 80 } 79 << 81 80 Message(kVL4, "create", "directory for " + o << 82 #ifdef G4VERBOSE 81 << 83 if ( fState.GetVerboseL4() ) { 82 auto success = true; << 84 G4String message = "directory for "; 83 << 85 message += directoryType; 84 // create directory << 86 fState.GetVerboseL4()->Message("create", message, newDirectoryName); 85 auto directory = toolx_H5Gcreate(file, newDi << 87 } >> 88 #endif >> 89 >> 90 directory = tools_H5Gcreate(fFile, newDirectoryName, 0); 86 // 0 seems to be an optional parameter. 91 // 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 92 // 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. 93 // default value is taken. >> 94 89 if ( directory < 0 ) { 95 if ( directory < 0 ) { 90 Warn("Cannot create directory " + director << 96 G4ExceptionDescription description; 91 fkClass, "CreateDirectory"); << 97 description << " " 92 success = false; << 98 << "cannot create directory " << directoryName; 93 } << 99 G4Exception("G4Hdf5FileManager::CreateDirectory()", >> 100 "Analysis_W001", JustWarning, description); >> 101 return false; >> 102 } >> 103 #ifdef G4VERBOSE 94 else { 104 else { 95 // write atb (header?) << 105 if ( fState.GetVerboseL2() ) { 96 auto result = toolx::hdf5::write_atb(direc << 106 G4String message = "directory for "; 97 if ( !result) { << 107 message += directoryType; 98 Warn("Write_atb class failed for " + dir << 108 fState.GetVerboseL2()->Message("create", message, newDirectoryName); 99 fkClass, "CreateDirectory"); << 100 success = false; << 101 } 109 } 102 } << 110 } 103 << 111 #endif 104 Message(kVL2, "create", "directory for " + o << 112 return true; 105 << 106 return directory; << 107 } 113 } 108 114 109 //____________________________________________ 115 //_____________________________________________________________________________ 110 G4String G4Hdf5FileManager::GetNtupleFileName( << 116 #ifdef G4VERBOSE 111 { << 117 G4bool G4Hdf5FileManager::WriteDirectory(const G4String& directoryType, 112 // get ntuple file name << 118 const G4String& directoryName, hid_t& directory) 113 auto ntupleFileName = ntupleDescription->Get << 119 #else 114 if (ntupleFileName.size() != 0u) { << 120 G4bool G4Hdf5FileManager::WriteDirectory(const G4String& /*directoryType*/, 115 // update filename per object per thread << 121 const G4String& directoryName, hid_t& directory) 116 ntupleFileName = GetTnFileName(ntupleFileN << 122 #endif 117 } << 123 { >> 124 #ifdef G4VERBOSE >> 125 if ( fState.GetVerboseL4() ) { >> 126 G4String message = "directory for "; >> 127 message += directoryType; >> 128 fState.GetVerboseL4() >> 129 ->Message("write", message, directoryName); >> 130 } >> 131 #endif >> 132 >> 133 auto result >> 134 = tools::hdf5::write_atb(directory, "type", "directory"); >> 135 >> 136 if ( ! result ) { >> 137 G4ExceptionDescription description; >> 138 description << " " >> 139 << "cannot write directory " << directoryName; >> 140 G4Exception("G4Hdf5FileManager::WriteDirectory()", >> 141 "Analysis_W001", JustWarning, description); >> 142 // close >> 143 // ::H5Gclose(histos); >> 144 // ::H5Fclose(file); >> 145 >> 146 return false; >> 147 } >> 148 #ifdef G4VERBOSE 118 else { 149 else { 119 // get default file name << 150 if ( fState.GetVerboseL2() ) { 120 ntupleFileName = GetFullFileName(); << 151 G4String message = "directory for "; 121 } << 152 message += directoryType; 122 return ntupleFileName; << 153 fState.GetVerboseL2()->Message("write", message, fHistoDirectoryName); 123 } << 154 } >> 155 } >> 156 #endif 124 157 125 // << 158 return result; 126 // protected methods << 159 } >> 160 >> 161 // >> 162 // public methods 127 // 163 // 128 164 129 //____________________________________________ 165 //_____________________________________________________________________________ 130 std::shared_ptr<G4Hdf5File> G4Hdf5FileManager: << 166 G4bool G4Hdf5FileManager::OpenFile(const G4String& fileName) 131 { 167 { 132 // create a new file << 168 // Keep file name 133 hid_t file = ::H5Fcreate(fileName, H5F_ACC_T << 169 fFileName = fileName; 134 << 170 auto name = GetFullFileName(); 135 // Do nothing if there is no file << 171 136 // (the error should be handled by caller) << 172 // delete previous file if exists 137 if ( file < 0 ) { << 173 //if ( fFile ) delete fFile; 138 Warn("::H5Fcreate failed " + fileName, fkC << 139 return std::make_shared<G4Hdf5File>(-1, -1 << 140 } << 141 174 142 // create a header with general infos << 175 // create new file 143 if(!toolx::hdf5::write_header(file)) { << 176 fFile = ::H5Fcreate(name, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); 144 Warn("toolx::hdf5::write_header() failed f << 177 if ( fFile < 0 ) { 145 fkClass, "CreateFileImpl"); << 178 G4ExceptionDescription description; 146 return std::make_shared<G4Hdf5File>(-1, -1 << 179 description << " " << "Cannot open file " << fileName; >> 180 G4Exception("G4Hdf5AnalysisManager::OpenFile()", >> 181 "Analysis_W001", JustWarning, description); >> 182 return false; 147 } 183 } 148 184 149 // create histo directory << 185 // Create directories 150 auto hdirectory << 186 if ( ! CreateDirectory("histograms", fHistoDirectoryName, fHistoDirectory) ) return false; 151 = CreateDirectory(file, fHistoDirectoryNam << 187 if ( ! CreateDirectory("ntuples", fNtupleDirectoryName, fNtupleDirectory) ) return false; 152 if ( hdirectory < 0 ) { << 188 153 // Warning is issued in CreateDirectory << 189 // // Open ntuple files 154 return std::make_shared<G4Hdf5File>(-1, -1 << 190 // OpenNtupleFiles(); 155 } << 191 >> 192 // Write directories >> 193 if ( ! WriteHistoDirectory() ) return false; >> 194 if ( ! WriteNtupleDirectory() ) return false; >> 195 >> 196 fLockFileName = true; >> 197 fLockHistoDirectoryName = true; >> 198 fLockNtupleDirectoryName = true; 156 199 157 // create ntuple directory << 200 fIsOpenFile = true; 158 auto ndirectory << 159 = CreateDirectory(file, fNtupleDirectoryNa << 160 if ( ndirectory < 0 ) { << 161 // Warnin is issued in CreateDirectory << 162 return std::make_shared<G4Hdf5File>(-1, -1 << 163 } << 164 201 165 return std::make_shared<G4Hdf5File>(file, hd << 202 return true; 166 } 203 } 167 << 204 168 //____________________________________________ 205 //_____________________________________________________________________________ 169 G4bool G4Hdf5FileManager::WriteFileImpl(std::s << 206 G4bool G4Hdf5FileManager::WriteFile() 170 { 207 { 171 // Nothing to be done here 208 // Nothing to be done here 172 return true; 209 return true; 173 } 210 } 174 211 175 //____________________________________________ 212 //_____________________________________________________________________________ 176 G4bool G4Hdf5FileManager::CloseFileImpl(std::s << 213 G4bool G4Hdf5FileManager::CloseFile() 177 { 214 { 178 if ( ! file ) return false; << 215 // Do nothing if there is no file 179 << 216 if ( fFile < 0 ) return true; 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 217 195 //____________________________________________ << 218 #ifdef G4VERBOSE 196 G4bool G4Hdf5FileManager::OpenFile(const G4Str << 219 if ( fState.GetVerboseL4() ) 197 { << 220 fState.GetVerboseL4()->Message("close", "file", GetFullFileName()); 198 // Keep file name << 221 #endif 199 fFileName = fileName; << 200 auto name = GetFullFileName(); << 201 222 202 if ( fFile ) { << 223 if ( fHistoDirectory >= 0 ) { 203 Warn("File " + fileName + " already exists << 224 ::H5Gclose(fHistoDirectory); 204 fFile.reset(); << 205 } 225 } 206 << 226 if ( fNtupleDirectory >= 0 ) { 207 // create new file << 227 ::H5Gclose(fNtupleDirectory); 208 fFile = CreateTFile(name); << 209 if ( ! fFile ) { << 210 Warn("Failed to create file " + fileName, << 211 return false; << 212 } 228 } >> 229 ::H5Fclose(fFile); 213 230 214 LockDirectoryNames(); << 231 fLockFileName = false; 215 fIsOpenFile = true; << 232 fIsOpenFile = false; >> 233 >> 234 #ifdef G4VERBOSE >> 235 if ( fState.GetVerboseL1() ) >> 236 fState.GetVerboseL1()->Message("close", "file", GetFullFileName(), true); >> 237 #endif >> 238 >> 239 // CHECK >> 240 // the result not returned from hdf5 216 241 217 return true; 242 return true; 218 } 243 } 219 244 220 //____________________________________________ 245 //_____________________________________________________________________________ 221 G4bool G4Hdf5FileManager::CreateNtupleFile( << 246 G4bool G4Hdf5FileManager::WriteHistoDirectory() 222 Hdf5NtupleDescription* ntupleDescription) << 223 { 247 { 224 // get ntuple file name per object << 248 return WriteDirectory("histograms", fHistoDirectoryName, fHistoDirectory); 225 auto ntupleFileName = GetNtupleFileName(ntup << 226 << 227 auto file = GetTFile(ntupleFileName, false); << 228 if (! file) { << 229 file = CreateTFile(ntupleFileName); << 230 } << 231 ntupleDescription->SetFile(file); << 232 << 233 return (ntupleDescription->GetFile() != null << 234 } 249 } 235 250 236 //____________________________________________ 251 //_____________________________________________________________________________ 237 G4bool G4Hdf5FileManager::CloseNtupleFile( << 252 G4bool G4Hdf5FileManager::WriteNtupleDirectory() 238 Hdf5NtupleDescription* ntupleDescription) << 239 { 253 { 240 // Notify not empty file << 254 return WriteDirectory("ntuples", fNtupleDirectoryName, fNtupleDirectory); 241 auto ntupleFileName = GetNtupleFileName(ntup << 242 auto result = SetIsEmpty(ntupleFileName, ! n << 243 << 244 // Ntuple files are registered in file manag << 245 // they will be closed with CloseFiles() cal << 246 ntupleDescription->GetFile().reset(); << 247 << 248 return result; << 249 } 255 } 250 256 251 //____________________________________________ 257 //_____________________________________________________________________________ 252 hid_t G4Hdf5FileManager::GetHistoDirectory() c << 258 void G4Hdf5FileManager::CloseAfterHnWrite() 253 { 259 { 254 if ( ! fFile ) return kInvalidId; << 260 if ( fHistoDirectory >= 0 ) { 255 << 261 ::H5Gclose(fHistoDirectory); 256 return std::get<1>(*fFile); << 262 } >> 263 ::H5Fclose(fFile); 257 } 264 } 258 265 259 //____________________________________________ << 260 hid_t G4Hdf5FileManager::GetNtupleDirectory() << 261 { << 262 if ( ! fFile ) return kInvalidId; << 263 266 264 return std::get<2>(*fFile); << 267 265 } << 266 268