Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 #ifndef toolx_hdf5_h2file 5 #define toolx_hdf5_h2file 6 7 #include "tools" 8 #include "T_tools" 9 10 #include <tools/histo/histo_data> 11 #include <tools/sout> 12 #include <ostream> 13 14 namespace toolx { 15 namespace hdf5 { 16 17 }} 18 19 #include <map> 20 21 namespace toolx { 22 namespace hdf5 { 23 24 inline bool write_std_map_ss(hid_t a_loc,const std::string& a_name,const std::map<std::string,std::string>& a_map, 25 unsigned int /*a_chunked*/ = 0,unsigned int /*a_compress*/ = 0) { 26 if(!write_scalar<tools::uint64>(a_loc,a_name+"_size",a_map.size())) return false; 27 unsigned int count = 0; //uint for num2s. 28 std::string scount; 29 tools_mforcit(std::string,std::string,a_map,it) { 30 tools::num2s(count,scount); 31 if(!write_string(a_loc,a_name+"_elem_"+scount+"_first",(*it).first)) return false; 32 if(!write_string(a_loc,a_name+"_elem_"+scount+"_secon",(*it).second)) return false; 33 count++; 34 } 35 return true; 36 } 37 38 inline bool read_std_map_ss(hid_t a_loc,const std::string& a_name,std::map<std::string,std::string>& a_map, 39 unsigned int /*a_chunked*/ = 0,unsigned int /*a_compress*/ = 0) { 40 a_map.clear(); 41 tools::uint64 sz; 42 if(!read_scalar<tools::uint64>(a_loc,a_name+"_size",sz)) return false; 43 std::string scount,key,value; 44 for(tools::uint64 count=0;count<sz;count++) { 45 tools::num2s(count,scount); 46 if(!read_string(a_loc,a_name+"_elem_"+scount+"_first",key)) return false; 47 if(!read_string(a_loc,a_name+"_elem_"+scount+"_secon",value)) return false; 48 a_map[key] = value; 49 } 50 return true; 51 } 52 53 typedef tools::histo::histo_data<double,unsigned int,unsigned int,double> histo_data_t; 54 55 inline bool write_hdata(hid_t a_loc,const histo_data_t& a_hdata) { 56 57 if(!write_string(a_loc,"title",a_hdata.m_title)) return false; 58 if(!write_scalar<unsigned int>(a_loc,"dimension",a_hdata.m_dimension)) return false; 59 if(!write_scalar<unsigned int>(a_loc,"bin_number",a_hdata.m_bin_number)) return false; 60 61 if(!write_std_vec<unsigned int>(a_loc,"bin_entries",a_hdata.m_bin_entries)) return false; 62 if(!write_std_vec<double>(a_loc,"bin_Sw",a_hdata.m_bin_Sw)) return false; 63 if(!write_std_vec<double>(a_loc,"bin_Sw2",a_hdata.m_bin_Sw2)) return false; 64 if(!write_std_vec_vec<double>(a_loc,"bin_Sxw",a_hdata.m_bin_Sxw)) return false; 65 if(!write_std_vec_vec<double>(a_loc,"bin_Sx2w",a_hdata.m_bin_Sx2w)) return false; 66 67 // axes : 68 {std::string name,saxis; 69 for(unsigned int iaxis=0;iaxis<a_hdata.m_dimension;iaxis++) { 70 tools::num2s(iaxis,saxis); 71 name = "axis_"+saxis+"_"; 72 const histo_data_t::axis_t& _axis = a_hdata.m_axes[iaxis]; 73 if(!write_scalar<unsigned int>(a_loc,name+"offset",_axis.m_offset)) return false; 74 if(!write_scalar<unsigned int>(a_loc,name+"number_of_bins",_axis.m_number_of_bins)) return false; 75 if(!write_scalar<double>(a_loc,name+"minimum_value",_axis.m_minimum_value)) return false; 76 if(!write_scalar<double>(a_loc,name+"maximum_value",_axis.m_maximum_value)) return false; 77 if(!write_scalar<bool>(a_loc,name+"fixed",_axis.m_fixed)) return false; 78 if(!write_scalar<double>(a_loc,name+"bin_width",_axis.m_bin_width)) return false; 79 if(!write_std_vec<double>(a_loc,name+"edges",_axis.m_edges)) return false; 80 }} 81 82 // etc : 83 if(!write_std_vec<double>(a_loc,"in_range_plane_Sxyw",a_hdata.m_in_range_plane_Sxyw)) return false; 84 85 // m_annotations : 86 if(!write_std_map_ss(a_loc,"annotations",a_hdata.m_annotations)) return false; 87 88 return true; 89 } 90 91 template <class HISTO> 92 inline bool write_histo(std::ostream& a_out,hid_t a_loc,const std::string& a_name,const HISTO& a_histo) { 93 94 hid_t histo = toolx_H5Gcreate(a_loc,a_name.c_str(),0); 95 if(histo<0) { 96 a_out << "toolx::hdf5::write_histo : can't create group for histo " << tools::sout(a_name) << "." << std::endl; 97 ::H5Gclose(histo); 98 return false; 99 } 100 101 if(!write_atb(histo,"type","object")) { 102 a_out << "toolx::hdf5::write_histo : write_atb() class failed." << std::endl; 103 ::H5Gclose(histo); 104 return false; 105 } 106 if(!write_atb(histo,"class",a_histo.s_cls())) { 107 a_out << "toolx::hdf5::write_histo : write_atb() class failed." << std::endl; 108 ::H5Gclose(histo); 109 return false; 110 } 111 int v = 1; 112 if(!write_scalar_atb<int>(histo,"version",v)) { 113 a_out << "toolx::hdf5::write_histo : write_scalar_atb() version failed." << std::endl; 114 ::H5Gclose(histo); 115 return false; 116 } 117 118 if(!write_hdata(histo,a_histo.dac())) {::H5Gclose(histo);return false;} 119 120 ::H5Gclose(histo); 121 122 a_histo.not_a_profile(); //trick to be sure to use this function on an histo and not a profile. 123 124 return true; 125 } 126 127 template <class PROFILE> 128 inline bool write_profile(std::ostream& a_out,hid_t a_loc,const std::string& a_name,const PROFILE& a_histo) { 129 130 hid_t histo = toolx_H5Gcreate(a_loc,a_name.c_str(),0); 131 if(histo<0) { 132 a_out << "toolx::hdf5::write_profile : can't create group for histo " << tools::sout(a_name) << "." << std::endl; 133 ::H5Gclose(histo); 134 return false; 135 } 136 137 if(!write_atb(histo,"type","object")) { 138 a_out << "toolx::hdf5::write_profile : write_atb() class failed." << std::endl; 139 ::H5Gclose(histo); 140 return false; 141 } 142 if(!write_atb(histo,"class",a_histo.s_cls())) { 143 a_out << "toolx::hdf5::write_profile : write_atb() class failed." << std::endl; 144 ::H5Gclose(histo); 145 return false; 146 } 147 int v = 1; 148 if(!write_scalar_atb<int>(histo,"version",v)) { 149 a_out << "toolx::hdf5::write_profile : write_scalar_atb() version failed." << std::endl; 150 ::H5Gclose(histo); 151 return false; 152 } 153 154 typename PROFILE::pd_t pdata = a_histo.get_histo_data(); 155 156 if(!write_hdata(histo,pdata)) {::H5Gclose(histo);return false;} 157 158 if(!write_bool(histo,"is_profile",pdata.m_is_profile)) {::H5Gclose(histo);return false;} 159 if(!write_std_vec<double>(histo,"bin_Svw",pdata.m_bin_Svw)) {::H5Gclose(histo);return false;} 160 if(!write_std_vec<double>(histo,"bin_Sv2w",pdata.m_bin_Sv2w)) {::H5Gclose(histo);return false;} 161 if(!write_bool(histo,"cut_v",pdata.m_cut_v)) {::H5Gclose(histo);return false;} 162 if(!write_scalar<double>(histo,"min_v",pdata.m_min_v)) {::H5Gclose(histo);return false;} 163 if(!write_scalar<double>(histo,"max_v",pdata.m_max_v)) {::H5Gclose(histo);return false;} 164 165 ::H5Gclose(histo); 166 167 return true; 168 } 169 170 inline bool read_hdata(hid_t a_loc,histo_data_t& a_hdata) { 171 if(!read_string(a_loc,"title",a_hdata.m_title)) return false; 172 if(!read_scalar<unsigned int>(a_loc,"dimension",a_hdata.m_dimension)) return false; 173 if(!read_scalar<unsigned int>(a_loc,"bin_number",a_hdata.m_bin_number)) return false; 174 175 if(!read_std_vec<unsigned int>(a_loc,"bin_entries",a_hdata.m_bin_entries)) return false; 176 if(!read_std_vec<double>(a_loc,"bin_Sw",a_hdata.m_bin_Sw)) return false; 177 if(!read_std_vec<double>(a_loc,"bin_Sw2",a_hdata.m_bin_Sw2)) return false; 178 179 if(!read_std_vec_vec<double>(a_loc,"bin_Sxw",a_hdata.m_bin_Sxw)) return false; 180 if(!read_std_vec_vec<double>(a_loc,"bin_Sx2w",a_hdata.m_bin_Sx2w)) return false; 181 182 // axes : 183 {a_hdata.m_axes.resize(a_hdata.m_dimension); 184 std::string name,saxis; 185 for(unsigned int iaxis=0;iaxis<a_hdata.m_dimension;iaxis++) { 186 tools::num2s(iaxis,saxis); 187 name = "axis_"+saxis+"_"; 188 histo_data_t::axis_t& _axis = a_hdata.m_axes[iaxis]; 189 if(!read_scalar<unsigned int>(a_loc,name+"offset",_axis.m_offset)) return false; 190 if(!read_scalar<unsigned int>(a_loc,name+"number_of_bins",_axis.m_number_of_bins)) return false; 191 if(!read_scalar<double>(a_loc,name+"minimum_value",_axis.m_minimum_value)) return false; 192 if(!read_scalar<double>(a_loc,name+"maximum_value",_axis.m_maximum_value)) return false; 193 if(!read_scalar<bool>(a_loc,name+"fixed",_axis.m_fixed)) return false; 194 if(!read_scalar<double>(a_loc,name+"bin_width",_axis.m_bin_width)) return false; 195 if(!read_std_vec<double>(a_loc,name+"edges",_axis.m_edges)) return false; 196 }} 197 198 // etc : 199 if(!read_std_vec<double>(a_loc,"in_range_plane_Sxyw",a_hdata.m_in_range_plane_Sxyw)) return false; 200 201 // m_annotations : 202 if(!read_std_map_ss(a_loc,"annotations",a_hdata.m_annotations)) return false; 203 204 return true; 205 } 206 207 template <class HISTO> 208 inline bool read_histo(std::ostream& a_out,hid_t a_loc,const std::string& a_name,HISTO*& a_histo,bool a_verb_class = true) { 209 a_histo = 0; 210 211 //if(::H5Gget_objinfo(a_loc,a_name.c_str(),0,NULL)<0) {return false;} 212 213 hid_t histo = toolx_H5Gopen(a_loc,a_name.c_str()); 214 if(histo<0) { 215 a_out << "toolx::hdf5::read_histo : can't open group." << std::endl; 216 return false; 217 } 218 219 std::string sclass; 220 if(!read_atb(histo,"class",sclass)) { 221 a_out << "toolx::hdf5::read_histo : can't read_atb() class." << std::endl; 222 ::H5Gclose(histo); 223 return false; 224 } 225 226 if(sclass!=HISTO::s_class()) { 227 if(a_verb_class) { 228 a_out << "toolx::hdf5::read_histo :" 229 << " read class " << tools::sout(sclass) << " not " << tools::sout(HISTO::s_class()) << std::endl; 230 } 231 ::H5Gclose(histo); 232 return false; 233 } 234 235 int v; 236 if(!read_atb(histo,"version",v)) { 237 a_out << "toolx::hdf5::read_histo : read_atb version failed." << std::endl; 238 ::H5Gclose(histo); 239 return false; 240 } 241 242 histo_data_t hdata; 243 244 if(!read_hdata(histo,hdata)) {::H5Gclose(histo);return false;} 245 246 ::H5Gclose(histo); 247 248 hdata.update_fast_getters(); 249 250 a_histo = new HISTO; 251 a_histo->copy_from_data(hdata); 252 a_histo->not_a_profile(); //trick to be sure to use this function on an histo and not a profile. 253 return true; 254 } 255 256 template <class PROFILE> 257 inline bool read_profile(std::ostream& a_out,hid_t a_loc,const std::string& a_name,PROFILE*& a_histo,bool a_verb_class = true) { 258 a_histo = 0; 259 260 hid_t histo = toolx_H5Gopen(a_loc,a_name.c_str()); 261 if(histo<0) { 262 a_out << "toolx::hdf5::read_profile : can't open group." << std::endl; 263 return false; 264 } 265 266 std::string sclass; 267 if(!read_atb(histo,"class",sclass)) { 268 a_out << "toolx::hdf5::read_profile : can't read_atb() class." << std::endl; 269 ::H5Gclose(histo); 270 return false; 271 } 272 273 if(sclass!=PROFILE::s_class()) { 274 if(a_verb_class) { 275 a_out << "toolx::hdf5::read_profile :" 276 << " read class " << tools::sout(sclass) << " not " << tools::sout(PROFILE::s_class()) << std::endl; 277 } 278 ::H5Gclose(histo); 279 return false; 280 } 281 282 int v; 283 if(!read_atb(histo,"version",v)) { 284 a_out << "toolx::hdf5::read_profile : read_atb version failed." << std::endl; 285 ::H5Gclose(histo); 286 return false; 287 } 288 289 typename PROFILE::pd_t pdata; 290 291 if(!read_hdata(histo,pdata)) {::H5Gclose(histo);return false;} 292 293 if(!read_bool(histo,"is_profile",pdata.m_is_profile)) {::H5Gclose(histo);return false;} 294 if(!read_std_vec<double>(histo,"bin_Svw",pdata.m_bin_Svw)) {::H5Gclose(histo);return false;} 295 if(!read_std_vec<double>(histo,"bin_Sv2w",pdata.m_bin_Sv2w)) {::H5Gclose(histo);return false;} 296 if(!read_bool(histo,"cut_v",pdata.m_cut_v)) {::H5Gclose(histo);return false;} 297 if(!read_scalar<double>(histo,"min_v",pdata.m_min_v)) {::H5Gclose(histo);return false;} 298 if(!read_scalar<double>(histo,"max_v",pdata.m_max_v)) {::H5Gclose(histo);return false;} 299 300 ::H5Gclose(histo); 301 302 pdata.update_fast_getters(); 303 304 a_histo = new PROFILE; 305 a_histo->copy_from_data(pdata); 306 return true; 307 } 308 309 inline bool read_class_version(std::ostream& a_out,hid_t a_loc,const std::string& a_name, 310 std::string& a_class,int& a_version,bool a_verbose = true) { 311 hid_t id = toolx_H5Gopen(a_loc,a_name.c_str()); 312 if(id<0) { 313 if(a_verbose) a_out << "toolx::hdf5::read_class_version : can't open group." << std::endl; 314 a_class.clear(); 315 a_version = 0; 316 return false; 317 } 318 319 if(!read_atb(id,"class",a_class)) { 320 if(a_verbose) a_out << "toolx::hdf5::read_class_version : can't read_atb() class." << std::endl; 321 ::H5Gclose(id); 322 a_class.clear(); 323 a_version = 0; 324 return false; 325 } 326 327 if(!read_atb(id,"version",a_version)) { 328 if(a_verbose) a_out << "toolx::hdf5::read_class_version : read_atb version failed." << std::endl; 329 ::H5Gclose(id); 330 a_class.clear(); 331 a_version = 0; 332 return false; 333 } 334 335 ::H5Gclose(id); 336 return true; 337 } 338 339 }} 340 341 342 #endif