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