1 /** 2 * \file RMF/HDF5/DataSetD.h 3 * \brief Handle read/write of Model data from/to files. 4 * 5 * Copyright 2007-2021 IMP Inventors. All rights reserved. 6 * 7 */ 8 9 #ifndef RMF_HDF5_DATA_SET_D_H 10 #define RMF_HDF5_DATA_SET_D_H 11 12 #include "RMF/config.h" 13 #include "types.h" 14 #include "Object.h" 15 #include "MutableAttributes.h" 16 #include "ConstDataSetD.h" 17 #include "infrastructure_macros.h" 18 #include <algorithm> 19 20 RMF_ENABLE_WARNINGS 21 namespace RMF { 22 namespace HDF5 { 23 24 /** Wrap an HDF5 data set. Typedefs and python types are provided for 25 data sets in 1,2, and 3 dimensions with all the supported types. They are 26 named as 27 RMF::HDF5::IndexDataSet2D (or RMF.HDF5.IndexDataSet2). 28 See 29 \external{https://support.hdfgroup.org/HDF5/doc/RM/RM_H5D.html, 30 the HDF5 manual} for more information. 31 */ 32 template <class TypeTraits, unsigned int D> 33 class DataSetD : public MutableAttributes<ConstDataSetD<TypeTraits, D> > { 34 typedef MutableAttributes<ConstDataSetD<TypeTraits, D> > P; 35 friend class Group; 36 37 protected: 38 typedef DataSetCreationPropertiesD<TypeTraits, D> CreationProperties; 39 typedef DataSetAccessPropertiesD<TypeTraits, D> AccessProperties; 40 DataSetD(boost::shared_ptr<SharedHandle> parent,std::string name,CreationProperties props)41 DataSetD(boost::shared_ptr<SharedHandle> parent, std::string name, 42 CreationProperties props) 43 : P(parent, name, props) {} DataSetD(boost::shared_ptr<SharedHandle> parent,std::string name,AccessProperties props)44 DataSetD(boost::shared_ptr<SharedHandle> parent, std::string name, 45 AccessProperties props) 46 : P(parent, name, props) {} 47 48 public: 49 #if !defined(SWIG) && !defined(RMF_DOXYGEN) DataSetD(hid_t file,std::string name,AccessProperties props)50 DataSetD(hid_t file, std::string name, AccessProperties props) 51 : P(file, name, props) {} 52 #endif 53 typedef DataSetIndexD<D> Index; DataSetD()54 DataSetD() {} 55 set_value(const DataSetIndexD<D> & ijk,typename TypeTraits::Type value)56 void set_value(const DataSetIndexD<D>& ijk, typename TypeTraits::Type value) { 57 RMF_IF_CHECK { P::check_index(ijk); } 58 // RMF_HDF5_HANDLE(sel, H5Dget_space(h_->get_hid()), &H5Sclose); 59 RMF_HDF5_CALL(H5Sselect_hyperslab(P::get_data_space(), H5S_SELECT_SET, 60 ijk.get(), P::get_ones(), P::get_ones(), 61 NULL)); 62 TypeTraits::write_value_dataset(Object::get_handle(), 63 P::get_input_data_space().get_hid(), 64 P::get_data_space(), value); 65 } 66 RMF_SHOWABLE(DataSetD, "DataSet" << D << "D " << P::get_name()); 67 #ifndef SWIG 68 typedef DataSetIndexD<D - 1> RowIndex; set_row(const RowIndex & ijkr,const typename TypeTraits::Types & value)69 void set_row(const RowIndex& ijkr, const typename TypeTraits::Types& value) { 70 DataSetIndexD<D> ijk; 71 std::copy(ijkr.begin(), ijkr.end(), ijk.begin()); 72 ijk[D - 1] = 0; 73 RMF_IF_CHECK { P::check_index(ijk); } 74 hsize_t size[D]; 75 std::fill(size, size + D - 1, 1); 76 size[D - 1] = P::get_size()[D - 1]; // set last to size of row 77 // RMF_HDF5_HANDLE(sel, H5Dget_space(h_->get_hid()), &H5Sclose); 78 RMF_HDF5_CALL(H5Sselect_hyperslab(P::get_data_space(), H5S_SELECT_SET, 79 ijk.get(), P::get_ones(), &size[0], 80 NULL)); 81 TypeTraits::write_values_dataset(Object::get_handle(), 82 P::get_row_data_space().get_hid(), 83 P::get_data_space(), value); 84 } 85 #endif 86 //! Write a rectangular block starting at ln of size size set_block(const Index & lb,const Index & size,const typename TypeTraits::Types & value)87 void set_block(const Index& lb, const Index& size, 88 const typename TypeTraits::Types& value) { 89 RMF_IF_CHECK { 90 P::check_index(lb); 91 Index last = lb; 92 // offset size by one and check... 93 unsigned int total = 1; 94 for (unsigned int i = 0; i < D; ++i) { 95 total *= size[i]; 96 last[i] += size[i] - 1; 97 } 98 RMF_USAGE_CHECK(total == value.size(), 99 RMF::internal::get_error_message( 100 "Block has size ", total, " but found ", value.size(), 101 " values")); 102 P::check_index(last); 103 } 104 // RMF_HDF5_HANDLE(sel, H5Dget_space(h_->get_hid()), &H5Sclose); 105 RMF_HDF5_CALL(H5Sselect_hyperslab(P::get_data_space(), H5S_SELECT_SET, 106 lb.get(), P::get_ones(), size.get(), 107 NULL)); 108 hsize_t sz = value.size(); 109 RMF_HDF5_HANDLE(input, H5Screate_simple(1, &sz, NULL), &H5Sclose); 110 TypeTraits::write_values_dataset(Object::get_handle(), input, 111 P::get_data_space(), value); 112 } set_size(const DataSetIndexD<D> & ijk)113 void set_size(const DataSetIndexD<D>& ijk) { 114 hsize_t nd[D]; 115 std::copy(ijk.begin(), ijk.end(), nd); 116 ; 117 RMF_HDF5_CALL(H5Dset_extent(Object::get_handle(), &nd[0])); 118 P::initialize_handles(); 119 } 120 }; 121 122 #ifndef RMF_DOXYGEN 123 124 #define RMF_HDF5_DECLARE_DATA_SET(lcname, Ucname, PassValue, ReturnValue, \ 125 PassValues, ReturnValues) \ 126 typedef DataSetD<Ucname##Traits, 1> Ucname##DataSet1D; \ 127 typedef std::vector<Ucname##DataSet1D> Ucname##DataSet1Ds; \ 128 typedef DataSetD<Ucname##Traits, 2> Ucname##DataSet2D; \ 129 typedef std::vector<Ucname##DataSet2D> Ucname##DataSet2Ds; \ 130 typedef DataSetD<Ucname##Traits, 3> Ucname##DataSet3D; \ 131 typedef std::vector<Ucname##DataSet3D> Ucname##DataSet3Ds; \ 132 typedef MutableAttributes<Ucname##DataSet1D> Ucname##DataSet1DAttributes; \ 133 typedef MutableAttributes<Ucname##DataSet2D> Ucname##DataSet2DAttributes; \ 134 typedef MutableAttributes<Ucname##DataSet3D> Ucname##DataSet3DAttributes; \ 135 typedef std::vector<Ucname##DataSet1DAttributes> \ 136 Ucname##DataSet1DAttributesList; \ 137 typedef std::vector<Ucname##DataSet2DAttributes> \ 138 Ucname##DataSet2DAttributesList; \ 139 typedef std::vector<Ucname##DataSet3DAttributes> \ 140 Ucname##DataSet3DAttributesList 141 142 /** \name Basic data set types 143 \ingroup hdf5 144 @{ 145 */ 146 RMF_HDF5_FOREACH_TYPE(RMF_HDF5_DECLARE_DATA_SET); 147 /** @} */ 148 #endif 149 150 } /* namespace HDF5 */ 151 } /* namespace RMF */ 152 153 RMF_DISABLE_WARNINGS 154 155 #endif /* RMF_HDF5_DATA_SET_D_H */ 156