7 #include <blitz/array.h> 8 #include <boost/shared_ptr.hpp> 49 {
return is_present(Objname, *h); }
57 template<
int D> blitz::TinyVector<int,D>
read_shape(
58 const std::string& Dataname)
const;
59 template<
class T,
int D> blitz::Array<T, D>
read_field(
60 const std::string& Dataname)
const;
62 const std::string& Dataname)
const;
64 const std::string& Dataname,
const Unit& Default_unit)
const;
66 const std::string& Dataname,
67 const blitz::TinyVector<int,D>& Start,
68 const blitz::TinyVector<int,D>& Size)
const;
70 const std::string& Dataname,
const Unit& Default_unit,
71 const blitz::TinyVector<int,D>& Start,
72 const blitz::TinyVector<int,D>& Size)
const;
73 template<
class T,
int D> blitz::Array<T, D>
read_field(
74 const std::string& Dataname,
75 const blitz::TinyVector<int,D>& Start,
76 const blitz::TinyVector<int,D>& Size)
const;
78 const std::string& Dataname)
const;
79 template<
class T,
int D> blitz::Array<T, D>
81 template<
class T> T
read_attribute(
const std::string& Aname)
const;
83 const blitz::Array<T, D>& Data);
87 template<
class T,
int D>
void write_field(
const std::string& Dataname,
88 const blitz::Array<T, D>& Data);
89 template<
int D>
inline void write_field(
const std::string& Dataname,
90 const blitz::Array<std::string, D>& Data);
91 template<
int D>
inline void write_field(
const std::string& Dataname,
92 const blitz::Array<const char *, D>& Data);
93 template<
class T>
void write_field(
const std::string& Dataname,
96 const std::string& Data);
99 template<
class T>
void write_field(
const std::string& Dataname,
102 template<
class T,
int D>
void write_field(
const std::string& Dataname,
103 const blitz::Array<T, D>& Data,
106 const std::string& Description,
108 void shape_metadata(
const std::string& Name,
const std::string& Dim1);
109 void shape_metadata(
const std::string& Name,
const std::string& Dim1,
110 const std::string& Dim2);
111 void shape_metadata(
const std::string& Name,
const std::string& Dim1,
112 const std::string& Dim2,
const std::string& Dim3);
137 static bool is_hdf(
const std::string& Fname)
140 return H5::H5File::isHdf5(Fname);
141 }
catch(
const H5::FileIException& e) {
143 err <<
"Error determining if file: " 144 << Fname <<
" is an HDF file: " 151 template<
class T> H5::PredType
pred_arr()
const;
153 template<
class T> H5::PredType
pred_data()
const;
154 void print(std::ostream& Os)
const;
156 const H5::H5File&
h5_file()
const {
return *h; };
163 #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR >= 10 && H5_VERS_RELEASE >= 1 164 void create_group_if_needed(
const std::string& Dataname,
165 H5::H5Location& Parent);
167 void create_group_if_needed(
const std::string& Dataname,
168 H5::CommonFG& Parent);
170 H5::Attribute open_attribute(
const std::string& Aname)
const;
171 H5::Attribute create_attribute(
const std::string& Aname,
172 const H5::DataSpace& Ds,
const H5::DataType& P);
173 bool is_group(
const std::string& Objname)
const;
174 #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR >= 10 && H5_VERS_RELEASE >= 1 175 bool is_present(
const std::string& Objname,
176 const H5::H5Location& Parent)
const;
178 bool is_present(
const std::string& Objname,
179 const H5::CommonFG& Parent)
const;
181 void write_type(
const std::string& Dataname,
const H5::DataType& P);
184 template<>
inline H5::PredType HdfFile::pred_arr<int>()
const 185 {
return H5::PredType::NATIVE_INT;}
186 template<>
inline H5::PredType HdfFile::pred_arr<int64_t>()
const 187 {
return H5::PredType::NATIVE_INT64;}
188 template<>
inline H5::PredType HdfFile::pred_arr<double>()
const 189 {
return H5::PredType::NATIVE_DOUBLE;}
190 template<>
inline H5::PredType HdfFile::pred_arr<float>()
const 191 {
return H5::PredType::NATIVE_FLOAT;}
192 template<>
inline H5::PredType HdfFile::pred_data<int>()
const 193 {
return H5::PredType::NATIVE_INT32;}
194 template<>
inline H5::PredType HdfFile::pred_data<int64_t>()
const 195 {
return H5::PredType::NATIVE_INT64;}
196 template<>
inline H5::PredType HdfFile::pred_data<double>()
const 197 {
return H5::PredType::NATIVE_DOUBLE;}
198 template<>
inline H5::PredType HdfFile::pred_data<float>()
const 199 {
return H5::PredType::NATIVE_FLOAT;}
205 template<
class T,
int D>
inline blitz::Array<T, D>
210 Attribute a = open_attribute(Aname);
211 DataSpace ds = a.getSpace();
212 if(ds.getSimpleExtentNdims() != D) {
214 e <<
"Attribute " << Aname <<
" does not have the expected rank of " 219 ds.getSimpleExtentDims(dims, NULL);
220 blitz::TinyVector<int,D> dims2;
221 for(
int i = 0; i < D; ++i)
222 dims2(i) = (int) dims[i];
223 blitz::Array<T, D> res(dims2);
224 a.read(pred_arr<T>(), res.dataFirst());
226 }
catch(
const H5::Exception& e) {
228 en <<
"While reading attribute " << Aname
229 <<
" for the file '" << fname
230 <<
"' a HDF 5 Exception thrown:\n" 231 <<
" " << e.getDetailMsg();
240 template<
class T>
inline T
243 return read_attribute<T, 1>(Aname)(0);
250 template<>
inline std::string HdfFile::read_attribute<std::string>(
const 251 std::string& Aname)
const 255 Attribute a = open_attribute(Aname);
257 a.read(a.getStrType(),res);
259 size_t t = res.find_last_not_of(
" ");
260 if(t != std::string::npos)
263 }
catch(
const H5::Exception& e) {
265 en <<
"While reading attribute " << Aname
266 <<
" for the file '" << fname
267 <<
"' a HDF 5 Exception thrown:\n" 268 <<
" " << e.getDetailMsg();
277 template<>
inline std::vector<std::string>
278 HdfFile::read_attribute<std::vector<std::string> >(
const 279 std::string& Aname)
const 283 Attribute a = open_attribute(Aname);
284 DataSpace ds = a.getSpace();
285 if(ds.getSimpleExtentNdims() != 1) {
287 e <<
"Attribute " << Aname <<
" does not have the expected rank of 1";
291 ds.getSimpleExtentDims(dims, NULL);
292 int nelem = (int) dims[0];
293 std::vector<char*> ptr(nelem);
294 a.read(a.getStrType(),&(*ptr.begin()));
295 std::vector<std::string> res(nelem);
296 for(
int i = 0; i < nelem; ++i) {
297 res[i] = std::string(ptr[i]);
299 size_t t = res[i].find_last_not_of(
" ");
300 if(t != std::string::npos)
304 }
catch(
const H5::Exception& e) {
306 en <<
"While reading attribute " << Aname
307 <<
" for the file '" << fname
308 <<
"' a HDF 5 Exception thrown:\n" 309 <<
" " << e.getDetailMsg();
321 template<
int D>
class HdfFilePartialDimHelper {
326 const std::string& Dataname)
const 330 DataSet d = h.openDataSet(Dataname);
331 DataSpace ds = d.getSpace();
332 if(ds.getSimpleExtentNdims() != D) {
334 e <<
"Dataset " << Dataname <<
" does not have the expected rank of " 339 ds.getSimpleExtentDims(dims, NULL);
340 blitz::TinyVector<int,D> dims2;
341 for(
int i = 0; i < D; ++i)
342 dims2(i) = (int) dims[i];
344 }
catch(
const H5::Exception& e) {
346 en <<
"While reading shape " << Dataname
348 <<
"' a HDF 5 Exception thrown:\n" 349 <<
" " << e.getDetailMsg();
356 template<
class T,
int D>
class HdfFilePartialSpecialHelper {
361 const std::string& Dataname)
const 365 DataSet d = h.openDataSet(Dataname);
366 DataSpace ds = d.getSpace();
367 if(ds.getSimpleExtentNdims() != D) {
369 e <<
"Dataset " << Dataname <<
" does not have the expected rank of " 374 ds.getSimpleExtentDims(dims, NULL);
375 blitz::TinyVector<int,D> dims2;
376 for(
int i = 0; i < D; ++i)
377 dims2(i) = (int) dims[i];
378 blitz::Array<T, D> res(dims2);
379 d.read(res.dataFirst(), hf.
pred_arr<T>());
381 }
catch(
const H5::Exception& e) {
383 en <<
"While reading field " << Dataname
385 <<
"' a HDF 5 Exception thrown:\n" 386 <<
" " << e.getDetailMsg();
393 const std::string& Dataname,
394 const blitz::TinyVector<hsize_t,D>& Start,
395 const blitz::TinyVector<hsize_t,D>& Size)
const 399 DataSet d = h.openDataSet(Dataname);
400 DataSpace ds = d.getSpace();
401 if(ds.getSimpleExtentNdims() != D) {
403 e <<
"Dataset " << Dataname <<
" does not have the expected rank of " 407 DataSpace ms(D, &Size[0]);
408 ds.selectHyperslab(H5S_SELECT_SET, &Size[0], &Start[0]);
409 blitz::Array<T, D> res(Size);
410 d.read(res.dataFirst(), hf.
pred_arr<T>(), ms, ds);
412 }
catch(
const H5::Exception& e) {
414 en <<
"While reading field " << Dataname
416 <<
"' a HDF 5 Exception thrown:\n" 417 <<
" " << e.getDetailMsg();
424 template<
int D>
class HdfFilePartialSpecialHelper<std::string, D> {
428 const std::string& Dataname)
const 432 DataSet d = h.openDataSet(Dataname);
433 DataSpace ds = d.getSpace();
434 if(ds.getSimpleExtentNdims() != D) {
436 e <<
"Dataset " << Dataname <<
" does not have the expected rank of " 441 ds.getSimpleExtentDims(dims, NULL);
442 blitz::TinyVector<int,D> dims2;
443 for(
int i = 0; i < D; ++i)
444 dims2(i) = (int) dims[i];
446 DataType dt = d.getDataType();
447 blitz::Array<std::string, D> result_data(dims2);
448 if(dt.isVariableStr()) {
449 blitz::Array<const char*, D> read_data(result_data.shape());
450 StrType st(PredType::C_S1, H5T_VARIABLE);
451 d.read(read_data.dataFirst(), st);
453 typename blitz::Array<const char*, D>::const_iterator i1;
454 typename blitz::Array<std::string, D>::iterator i2 = result_data.begin();
455 for(i1 = read_data.begin(); i1 != read_data.end(); ++i1, ++i2)
456 *i2 = std::string(*i1);
459 for(
int i = 0; i < D; i++)
460 flat_size *= dims2[i];
461 flat_size *= dt.getSize();
462 blitz::Array<char, 1> read_data(flat_size);
463 d.read(read_data.dataFirst(), d.getStrType());
465 char* i1 = read_data.dataFirst();
466 typename blitz::Array<std::string, D>::iterator i2;
467 for(i2 = result_data.begin(); i2 != result_data.end();
468 ++i2, i1 += dt.getSize()) {
471 std::string
s(i1, i1 + dt.getSize());
472 *i2 = std::string(
s.c_str());
476 }
catch(
const H5::Exception& e) {
478 en <<
"While reading field " << Dataname
480 <<
"' a HDF 5 Exception thrown:\n" 481 <<
" " << e.getDetailMsg();
488 const std::string& Dataname,
489 const blitz::TinyVector<hsize_t,D>& Start,
490 const blitz::TinyVector<hsize_t,D>& Size)
const 494 DataSet d = h.openDataSet(Dataname);
495 DataSpace ds = d.getSpace();
496 if(ds.getSimpleExtentNdims() != D) {
498 e <<
"Dataset " << Dataname <<
" does not have the expected rank of " 502 DataSpace ms(D, &Size[0]);
503 ds.selectHyperslab(H5S_SELECT_SET, &Size[0], &Start[0]);
504 DataType dt = d.getDataType();
505 blitz::Array<std::string, D> result_data(Size);
506 if(dt.isVariableStr()) {
507 blitz::Array<const char*, D> read_data(result_data.shape());
508 StrType st(PredType::C_S1, H5T_VARIABLE);
509 d.read(read_data.dataFirst(), st, ms, ds);
511 typename blitz::Array<const char*, D>::const_iterator i1;
512 typename blitz::Array<std::string, D>::iterator i2 = result_data.begin();
513 for(i1 = read_data.begin(); i1 != read_data.end(); ++i1, ++i2)
514 *i2 = std::string(*i1);
517 for(
int i = 0; i < D; i++)
518 flat_size *= Size(i);
519 flat_size *= dt.getSize();
520 blitz::Array<char, 1> read_data(flat_size);
521 d.read(read_data.dataFirst(), d.getStrType(), ms, ds);
523 char* i1 = read_data.dataFirst();
524 typename blitz::Array<std::string, D>::iterator i2;
525 for(i2 = result_data.begin(); i2 != result_data.end();
526 ++i2, i1 += dt.getSize()) {
529 std::string
s(i1, i1 + dt.getSize());
530 *i2 = std::string(
s.c_str());
534 }
catch(
const H5::Exception& e) {
536 en <<
"While reading field " << Dataname
538 <<
"' a HDF 5 Exception thrown:\n" 539 <<
" " << e.getDetailMsg();
552 template<
int D>
inline blitz::TinyVector<int,D>
555 HdfFilePartialDimHelper<D> helper;
556 return helper.read_shape(*
this, *h, Dataname);
563 template<
class T,
int D>
inline blitz::Array<T, D>
566 HdfFilePartialSpecialHelper<T,D> helper;
567 return helper.read_field(*
this, *h, Dataname);
578 res.
value.reference(read_field<T, D>(Dataname));
590 const blitz::TinyVector<int,D>& Start,
591 const blitz::TinyVector<int,D>& Size)
const 594 res.data.reference(read_field<T, D>(Dataname, Start, Size));
608 (
const std::string& Dataname,
const Unit& Default_unit)
const 611 res.
value.reference(read_field<T, D>(Dataname));
614 res.
units = Default_unit;
626 (
const std::string& Dataname,
const Unit& Default_unit,
627 const blitz::TinyVector<int,D>& Start,
628 const blitz::TinyVector<int,D>& Size)
const 631 res.
value.reference(read_field<T, D>(Dataname, Start, Size));
634 res.
units = Default_unit;
645 template<
class T,
int D> blitz::Array<T, D>
647 const std::string& Dataname,
648 const blitz::TinyVector<int,D>& Start,
649 const blitz::TinyVector<int,D>& Size)
const 651 HdfFilePartialSpecialHelper<T,D> helper;
652 blitz::TinyVector<hsize_t, D> start2, size2;
655 return helper.read_field(*
this, *h, Dataname, start2, size2);
663 template<
class T>
inline 668 DataSet d = h->openDataSet(Dataname);
669 DataSpace ds = d.getSpace();
671 d.read(&res, pred_arr<T>());
673 }
catch(
const H5::Exception& e) {
675 en <<
"While reading field " << Dataname
677 <<
"' a HDF 5 Exception thrown:\n" 678 <<
" " << e.getDetailMsg();
686 return read_field<std::string, 1>(Dataname)(0);
693 template<
class T,
int D>
inline 695 const blitz::Array<T, D>& Data)
701 for(
int i = 0; i < D; ++i)
702 dim[i] = Data.extent(i);
703 DataSpace ds(D, dim);
704 Attribute a = create_attribute(Aname, ds, pred_data<T>());
705 a.write(pred_arr<T>(), data2.dataFirst());
706 }
catch(
const H5::Exception& e) {
708 en <<
"While writing attribute " << Aname
709 <<
" for the file '" << fname
710 <<
"' a HDF 5 Exception thrown:\n" 711 <<
" " << e.getDetailMsg();
720 template<
class T>
inline 726 hsize_t dim[1] = {1};
727 DataSpace ds(1, dim);
728 Attribute a = create_attribute(Aname, ds, pred_data<T>());
729 a.write(pred_arr<T>(), &Data);
730 }
catch(
const H5::Exception& e) {
732 en <<
"While writing attribute " << Aname
733 <<
" for the file '" << fname
734 <<
"' a HDF 5 Exception thrown:\n" 735 <<
" " << e.getDetailMsg();
745 void HdfFile::write_attribute<std::string>(
const std::string& Aname,
746 const std::string& Data)
750 hsize_t dim[1] = {1};
751 DataSpace ds(1, dim);
752 StrType st(PredType::C_S1, H5T_VARIABLE);
753 Attribute a = create_attribute(Aname, ds, st);
755 }
catch(
const H5::Exception& e) {
757 en <<
"While writing attribute " << Aname
758 <<
" for the file '" << fname
759 <<
"' a HDF 5 Exception thrown:\n" 760 <<
" " << e.getDetailMsg();
770 void HdfFile::write_attribute<std::vector<std::string> >(
const 771 std::string& Aname,
const std::vector<std::string>& Data)
775 int nelem = (int) Data.size();
776 hsize_t dim[1] = {Data.size()};
777 DataSpace ds(1, dim);
778 StrType st(PredType::C_S1, H5T_VARIABLE);
779 Attribute a = create_attribute(Aname, ds, st);
780 std::vector<const char*> ptr(nelem);
781 for(
int i = 0; i < nelem; ++i)
782 ptr[i] = Data[i].c_str();
783 a.write(st, &(*ptr.begin()));
784 }
catch(
const H5::Exception& e) {
786 en <<
"While writing attribute " << Aname
787 <<
" for the file '" << fname
788 <<
"' a HDF 5 Exception thrown:\n" 789 <<
" " << e.getDetailMsg();
799 template<
class T,
int D>
inline void 801 const blitz::Array<T, D>& Data)
806 template<
int D>
inline void 808 const blitz::Array<std::string, D>& Data)
812 create_group_if_needed(Dataname, *h);
814 for(
int i = 0; i < D; ++i)
815 dim[i] = Data.extent(i);
816 DataSpace ds(D, dim);
817 StrType st(H5::PredType::C_S1, H5T_VARIABLE);
818 DataSet d = h->createDataSet(Dataname, st, ds);
820 blitz::Array<const char*, D> data3(data2.shape());
821 typename blitz::Array<std::string, D>::const_iterator i1;
822 typename blitz::Array<const char*, D>::iterator i2 = data3.begin();
823 for(i1 = data2.begin(); i1 != data2.end(); ++i1, ++i2)
825 d.write(data3.dataFirst(), st);
827 }
catch(
const H5::Exception& e) {
829 en <<
"While writing field " << Dataname
830 <<
" for the file '" << fname
831 <<
"' a HDF 5 Exception thrown:\n" 832 <<
" " << e.getDetailMsg();
837 template<
int D>
inline void 839 const blitz::Array<const char*, D>& Data)
847 typename blitz::Array<const char*, D>::const_iterator i1;
848 for(i1 = Data.begin(); i1 != Data.end(); ++i1)
849 max_len = std::max((
int) strlen(*i1), max_len);
851 H5::StrType dtype = H5::StrType(H5::PredType::C_S1, max_len + 1);
853 create_group_if_needed(Dataname, *h);
856 for(
int i = 0; i < D; ++i) {
857 dim[i] = Data.extent(i);
858 flat_size *= Data.extent(i);
861 DataSpace ds(D, dim);
862 DataSet d = h->createDataSet(Dataname, dtype, ds);
866 blitz::Array<char, 2> data2(flat_size, max_len + 1);
868 data2(blitz::Range::all(), max_len) =
'\0';
869 typename blitz::Array<char, 2>::iterator i2 = data2.begin();
870 for(i1 = Data.begin(); i1 != Data.end(); ++i1) {
872 for(
int j = 0; j < max_len + 1; j++)
876 d.write(data2.dataFirst(), dtype);
877 write_type(Dataname, dtype);
878 }
catch(
const H5::Exception& e) {
880 en <<
"While writing field " << Dataname
881 <<
" for the file '" << fname
882 <<
"' a HDF 5 Exception thrown:\n" 883 <<
" " << e.getDetailMsg();
899 template<
class T,
int D>
inline void 901 const blitz::Array<T, D>& Data,
906 create_group_if_needed(Dataname, *h);
908 for(
int i = 0; i < D; ++i)
909 dim[i] = Data.extent(i);
910 DataSpace ds(D, dim);
911 DataSet d = h->createDataSet(Dataname, P, ds);
913 d.write(data2.dataFirst(), pred_arr<T>());
914 write_type(Dataname, P);
915 }
catch(
const H5::Exception& e) {
917 en <<
"While writing field " << Dataname
918 <<
" for the file '" << fname
919 <<
"' a HDF 5 Exception thrown:\n" 920 <<
" " << e.getDetailMsg();
941 const std::string& Data)
945 create_group_if_needed(Dataname, *h);
946 hsize_t dim[1] = {1};
947 DataSpace ds(1, dim);
948 StrType st(PredType::C_S1, H5T_VARIABLE);
949 DataSet d = h->createDataSet(Dataname, st, ds);
950 const char* data2 = Data.c_str();
953 }
catch(
const H5::Exception& e) {
955 en <<
"While writing field " << Dataname
956 <<
" for the file '" << fname
957 <<
"' a HDF 5 Exception thrown:\n" 958 <<
" " << e.getDetailMsg();
968 create_group_if_needed(Dataname, *h);
969 hsize_t dim[1] = {1};
970 DataSpace ds(1, dim);
973 H5::StrType dtype = H5::StrType(H5::PredType::C_S1, strlen(Data) + 1);
974 DataSet d = h->createDataSet(Dataname, dtype, ds);
975 d.write(Data, dtype);
976 write_type(Dataname, dtype);
977 }
catch(
const H5::Exception& e) {
979 en <<
"While writing field " << Dataname
980 <<
" for the file '" << fname
981 <<
"' a HDF 5 Exception thrown:\n" 982 <<
" " << e.getDetailMsg();
1002 create_group_if_needed(Dataname, *h);
1003 hsize_t dim[1] = {1};
1004 DataSpace ds(1, dim);
1005 DataSet d = h->createDataSet(Dataname, P, ds);
1006 d.write(&Data, pred_arr<T>());
1007 write_type(Dataname, P);
1008 }
catch(
const H5::Exception& e) {
1010 en <<
"While writing field " << Dataname
1011 <<
" for the file '" << fname
1012 <<
"' a HDF 5 Exception thrown:\n" 1013 <<
" " << e.getDetailMsg();
blitz::TinyVector< int, D > read_shape(const std::string &Dataname) const
Reads the shape of a dataset.
const Unit s("s", 1.0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
We frequently have a array of numbers with units associated with them.
blitz::Array< T, D > read_field(const std::string &Dataname) const
Read a given field.
void close()
Close the underlying file.
H5::PredType pred_arr() const
void write_field(const std::string &Dataname, const blitz::Array< T, D > &Data)
Write a given field.
bool has_object(const std::string &Objname) const
Check to see if an object (such as a Dataset) is in the file.
void print(std::ostream &Os) const
Unit read_units(const std::string &Dataname) const
Read the units for a dataset.
This is the base of the exception hierarchy for Full Physics code.
static bool is_hdf(const std::string &Fname)
Return true if the given file is an HDF file.
blitz::Array< T, D > to_c_order_const(const blitz::Array< T, D > &In)
Ensure that a given blitz::Array is contiguous, not reversed, and in C RowMajorArray format...
This is a Mixin for classes that can be printed.
blitz::Array< T, D > value
This class reads and writes a HDF5 file.
void dimension_metadata(const std::string &Name, const std::string &Description, int Size)
The SDOS products have a particular metadata convention where the information about each of the Dimen...
H5::PredType pred_data() const
Mode mode() const
Mode file was opened with.
void write_attribute(const std::string &Aname, const blitz::Array< T, D > &Data)
Write attribute to file.
const std::string & file_name() const
File name.
Libraries such as boost::units allow unit handling where we know the units at compile time...
blitz::Array< T, D > read_attribute(const std::string &Aname) const
Read the given attribute attached to a group or dataset.
HdfFile(const std::string &Fname, Mode M=READ)
Open the given file with the given mode.
Contains classes to abstract away details in various Spurr Radiative Transfer software.
ArrayWithUnit< T, D > read_field_with_unit(const std::string &Dataname) const
Read a given field, along with metadata describing the units.
void shape_metadata(const std::string &Name, const std::string &Dim1)
The SDOS products have a particular metadata convention where the information about each of the Shape...
const H5::H5File & h5_file() const
bool has_attribute(const std::string &Aname) const
Check to see if a attribute is in the file.