hdf5: dataset: some reorganization + group: add general add/get member functions

This commit is contained in:
Christian Zimmermann 2024-10-30 18:05:10 -07:00
parent 1e4daf8691
commit f597254d5d
5 changed files with 98 additions and 34 deletions

View file

@ -22,8 +22,6 @@ namespace CNORXZ
Dataset& Dataset::init(const ArrayBase<T>& data)
{
const hid_t tid = getTypeId(*data.data());
//VCHECK(tid);
//init(data.range(), tid);
if(data.begin().formatIsTrivial()){
init(data.range(), tid, data.data());
}
@ -41,7 +39,7 @@ namespace CNORXZ
template <typename T>
MArray<T> SDataset<T>::read() const
{
MArray<T> out(mDataRange);
MArray<T> out(mFileRange);
readbase(out.data(), nullptr, nullptr);
return out;
}
@ -50,12 +48,12 @@ namespace CNORXZ
template <class I, typename M>
MArray<T> SDataset<T>::read(const IndexInterface<I,M>& idx) const
{
CXZ_ASSERT(idx.dim() == mDataRange->dim(), "got index of inconsistent dimension, got"
<< idx.dim() << ", expected " << mDataRange->dim());
CXZ_ASSERT(idx.dim() == mFileRange->dim(), "got index of inconsistent dimension, got"
<< idx.dim() << ", expected " << mFileRange->dim());
const RangePtr outrange = idx.range();
CXZ_ASSERT(outrange->size() == mDataRange->size(),
CXZ_ASSERT(outrange->size() == mFileRange->size(),
"got index of range of inconsistent size, expected "
<< mDataRange->size() << ", got " << outrange->size());
<< mFileRange->size() << ", got " << outrange->size());
MArray<T> out(outrange);
readbase(out.data(), outrange, nullptr);
return out;
@ -65,8 +63,8 @@ namespace CNORXZ
template <class I, typename M>
MArray<T> SDataset<T>::read(const IndexInterface<I,M>& beg, const IndexInterface<I,M>& end) const
{
CXZ_ASSERT(beg.dim() == mDataRange->dim(), "got index of inconsistent dimension, got"
<< beg.dim() << ", expected " << mDataRange->dim());
CXZ_ASSERT(beg.dim() == mFileRange->dim(), "got index of inconsistent dimension, got"
<< beg.dim() << ", expected " << mFileRange->dim());
const RangePtr outrange = beg.prange(end);
MArray<T> out(outrange);
readbase(out.data(), outrange, toYptr(beg));

View file

@ -57,6 +57,13 @@ namespace CNORXZ
*/
virtual Dataset& init(const RangePtr& dataRange, hid_t type, const void* data);
/** Write data into dataset.
@param dataRange A potentially multi-dimensional range characterizing the format of the data to be written.
@param pos Position on target.
@param data Pointer to raw data to be writte.
*/
virtual Dataset& writebase(const RangePtr& dataRange, Sptr<YIndex> pos, const void* data);
/** Read the dataset.
@param dest Pointer to destination.
@param readrange Range of the destination data.
@ -78,14 +85,14 @@ namespace CNORXZ
protected:
Vector<hsize_t> mkOff(const Sptr<YIndex>& beg) const;
RangePtr mDataRange; /**< The data range. */
RangePtr mFileRange; /**< The range of the dataset. */
hid_t mType; /**< The data type identifier. */
hid_t mFilespace; /**< The hdf5 file space identifier. */
};
/** ****
Class to handle hdf5 datasets, the value type is known at compile time.
Class to handle hdf5 datasets, the value type is assumed to be known at compile time.
@tparam T Dataset value type.
*/
template <typename T>

View file

@ -39,6 +39,13 @@ namespace CNORXZ
return pos - beg;
}
template <class F>
decltype(auto) Group::get(const String& name, F&& f)
{
auto i = this->getIndexTo(name);
return f(*i);
}
template <typename... Ts>
Sptr<STable<Ts...>> Group::getTable(const String& name, Tuple<Ts...> proto)
{
@ -108,6 +115,17 @@ namespace CNORXZ
return *this;
}
template <class F, typename... Args>
Group& Group::add(const String& name, F&& f, const Args&... args)
{
CXZ_ASSERT(this->isOpen(), "tried to extend closed group");
Vector<String> nvec({name});
mCont.extend( URangeFactory<String>( nvec ).create() );
auto ii = getIndexTo(name);
*ii = f(args...);
return *this;
}
template <class F>
decltype(auto) Group::iter(F&& f) const
{

View file

@ -96,6 +96,13 @@ namespace CNORXZ
*/
const MArray<ContentPtr>& get() const;
/** Get object contained by this group.
@param name Object name.
@param f Function to interpret the object.
*/
template <class F>
decltype(auto) get(const String& name, F&& f);
/** Add a new group to this group.
@param name Name of the created group.
*/
@ -119,6 +126,13 @@ namespace CNORXZ
template <typename T>
Group& addDataset(const String& name, const ArrayBase<T>& data);
/** Add new object to this group.
@param name Object name.
@param f Function used to create the object.
*/
template <class F, typename... Args>
Group& add(const String& name, F&& f, const Args&... args);
/** Iterate over all group elements (const).
@param f function object to be executed on each group element.
*/

View file

@ -53,7 +53,7 @@ namespace CNORXZ
for(SizeT i = 0; i != ndims; ++i){
rs[i] = CRangeFactory(dims[i]).create();
}
mDataRange = yrange(rs);
mFileRange = yrange(rs);
}
return *this;
}
@ -84,18 +84,18 @@ namespace CNORXZ
return H5Lexists(mParent->id(), mName.c_str(), H5P_DEFAULT) > 0;
}
Dataset& Dataset::init(const RangePtr& dataRange, hid_t type)
Dataset& Dataset::init(const RangePtr& fileRange, hid_t type)
{
CXZ_ASSERT(not isOpen(), "tried to initialize dataset that is already extisting");
mDataRange = dataRange;
mFileRange = fileRange;
const H5T_class_t tc = H5Tget_class(type);
CXZ_ASSERT(tc != H5T_NO_CLASS, "id does not correspond to a data type"); // (did not found anythng better to check if type id is valid)...
const hid_t dcpl_id = H5Pcreate(H5P_DATASET_CREATE);
// TODO: all sub-ranges explicity!!!:
const SizeT ndim = dataRange->dim();
const SizeT ndim = mFileRange->dim();
Vector<hsize_t> exts(ndim);
for(SizeT i = 0; i != ndim; ++i){
exts[i] = static_cast<hsize_t>( dataRange->sub(i)->size() );
exts[i] = static_cast<hsize_t>( mFileRange->sub(i)->size() );
}
mFilespace = H5Screate_simple(ndim, exts.data(), NULL);
mType = type;
@ -105,37 +105,64 @@ namespace CNORXZ
return *this;
}
Dataset& Dataset::init(const RangePtr& dataRange, hid_t type, const void* data)
Dataset& Dataset::init(const RangePtr& writeRange, hid_t type, const void* data)
{
init(dataRange, type);
Vector<hsize_t> dims(mDataRange->dim());
for(SizeT i = 0; i != dims.size(); ++i){
dims[i] = mDataRange->sub(i)->size();
}
const hid_t memspace = H5Screate_simple(dims.size(), dims.data(), NULL);
H5Dwrite(mId, mType, memspace, mFilespace, H5P_DEFAULT, data);
H5Sclose(memspace);
init(writeRange, type);
writebase(writeRange, std::make_shared<YIndex>(mFileRange), data);
return *this;
}
void Dataset::readbase(void* dest, RangePtr readrange, Sptr<YIndex> beg) const
Dataset& Dataset::writebase(const RangePtr& writeRange, Sptr<YIndex> pos, const void* data)
{
// TODO: Check if readrange is compatible with mDataRange!!!
if(not readrange){
readrange = mDataRange;
}
Vector<hsize_t> dims(readrange->dim());
//CXZ_ERROR("TODO!!!");
CXZ_ASSERT(writeRange->dim() == mFileRange->dim(), "dimension of data range ("
<< writeRange->dim() << ") different from dimension of file range ("
<< mFileRange->dim() << ")");
Vector<hsize_t> dims(writeRange->dim());
for(SizeT i = 0; i != dims.size(); ++i){
dims[i] = readrange->sub(i)->size();
dims[i] = writeRange->sub(i)->size();
}
if(pos){
CXZ_ASSERT(pos->range()->dim() == mFileRange->dim(), "dimension of position index ("
<< pos->range()->dim() << ") different from dimension of file range ("
<< mFileRange->dim() << ")");
const Vector<hsize_t> fpos = mkOff(pos);
H5Sselect_hyperslab(mFilespace, H5S_SELECT_SET, fpos.data(), NULL, dims.data(), NULL);
}
const hid_t memspace = H5Screate_simple(dims.size(), dims.data(), NULL);
const hid_t xfer_plist_id = H5Pcreate(H5P_DATASET_XFER);
H5Dwrite(mId, mType, memspace, mFilespace, xfer_plist_id, data);
H5Pclose(xfer_plist_id);
H5Sclose(memspace);
return *this;
}
void Dataset::readbase(void* dest, RangePtr readRange, Sptr<YIndex> beg) const
{
// TODO: Check if readRange is compatible with mFileRange!!!
if(not readRange){
readRange = mFileRange;
}
else {
CXZ_ASSERT(readRange->dim() == mFileRange->dim(), "dimension of data range ("
<< readRange->dim() << ") different from dimension of file range ("
<< mFileRange->dim() << ")");
}
Vector<hsize_t> dims(readRange->dim());
for(SizeT i = 0; i != dims.size(); ++i){
dims[i] = readRange->sub(i)->size();
}
if(beg){
CXZ_ASSERT(beg->range()->dim() == mFileRange->dim(), "dimension of position index ("
<< beg->range()->dim() << ") different from dimension of file range ("
<< mFileRange->dim() << ")");
const Vector<hsize_t> fpos = mkOff(beg);
H5Sselect_hyperslab(mFilespace, H5S_SELECT_SET, fpos.data(), NULL, dims.data(), NULL);
}
const hid_t mem_space_id = H5Screate_simple(static_cast<hsize_t>(dims.size()),
dims.data(), nullptr);
const hid_t xfer_plist_id = H5Pcreate(H5P_DATASET_XFER);
//MArray<T> out(readrange);
//MArray<T> out(readRange);
const herr_t err = H5Dread(mId, mType, mem_space_id, mFilespace, xfer_plist_id, dest);
CXZ_ASSERT(err >= 0, "error while reading dataset '" << mName
<< "', errorcode :" << err);
@ -145,7 +172,7 @@ namespace CNORXZ
const RangePtr& Dataset::dataRange() const
{
return mDataRange;
return mFileRange;
}
Vector<hsize_t> Dataset::mkOff(const Sptr<YIndex>& beg) const