Commit 2aac3367 authored by Alejandro Homs Puron's avatar Alejandro Homs Puron
Browse files

[IO] Add H5 reader file_frame_slice support

parent 9e1c9852
......@@ -43,8 +43,7 @@ namespace io::h5
using params_t = loading_params;
using file_exists_policy_t = read_file_exists_policy;
reader(std::filesystem::path const& filename, params_t const& params = {}) :
m_nb_frames(params.nb_frames_per_file)
reader(std::filesystem::path const& filename, params_t const& params = {}) : m_frame_slice(params.frame_slice)
{
bool is_nexus = (params.file_type == file_type_enum::nexus);
const char* type_str = is_nexus ? "Nexus" : "HDF5";
......@@ -77,11 +76,13 @@ namespace io::h5
LIMA_THROW_EXCEPTION(lima::hdf5_error("Error querying H5 dataset dimensions")
<< boost::errinfo_h5_path(dataset_path));
if (m_nb_frames == 0)
m_nb_frames = dims[0];
else if (dims[0] < m_nb_frames)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Mismatch in number of frames in dataset")
<< boost::errinfo_h5_path(dataset_path));
m_frame_slice.count = m_frame_slice.calc_count(dims[0]);
if (params.nb_frames_per_file != 0) {
if (params.nb_frames_per_file > m_frame_slice.count)
LIMA_THROW_EXCEPTION(lima::invalid_argument("Reader frame_slice.count / frames_per_file mismatch"));
m_frame_slice.count = std::min(params.nb_frames_per_file, m_frame_slice.count);
}
m_frame_dims = dimensions_t(dims[2], dims[1]);
......@@ -115,7 +116,7 @@ namespace io::h5
template <typename View>
void read_view(View const& v, hsize_t frame_idx = 0)
{
if (frame_idx >= m_nb_frames)
if (frame_idx >= m_frame_slice.count)
LIMA_THROW_EXCEPTION(lima::hdf5_error("Frame number out of bound")
<< boost::errinfo_frame_idx(frame_idx));
else if (v.dimensions() != m_frame_dims)
......@@ -125,7 +126,8 @@ namespace io::h5
dataspace file_space = m_dset.space();
if (m_nb_dims == 3) {
hsize_t mem_offset[] = {0, 0, 0};
hsize_t file_offset[] = {frame_idx, 0, 0};
hsize_t file_idx = frame_idx * m_frame_slice.stride + m_frame_slice.start;
hsize_t file_offset[] = {file_idx, 0, 0};
hsize_t count[] = {1, 1, 1};
hsize_t block[] = {1, hsize_t(m_frame_dims.y), hsize_t(m_frame_dims.x)};
mem_space.select_hyperslab(H5S_SELECT_SET, mem_offset, nullptr, count, block);
......@@ -140,10 +142,10 @@ namespace io::h5
protected:
dataset m_dset; //!< The dataset
dimensions_t m_frame_dims; //!< The dimensions of data frame
hsize_t m_nb_dims; //!< The number of dimensions of the dataset
hsize_t m_nb_frames; //!< The number of frames in the dataset
pixel_enum m_pixel; //!< The pixel type
dimensions_t m_frame_dims; //!< The dimensions of data frame
hsize_t m_nb_dims; //!< The number of dimensions of the dataset
file_frame_slice m_frame_slice; //!< The frame slice in the dataset
pixel_enum m_pixel; //!< The pixel type
};
} //namespace io::h5
......
......@@ -68,7 +68,23 @@ namespace io
LIMA_IO_DESCRIBE_FILENAME(filename_loading_params)
BOOST_DESCRIBE_STRUCT(loading_params, (filename_loading_params), (start_number, nb_frames_per_file))
BOOST_DESCRIBE_STRUCT(file_frame_slice, (), (start, count, stride))
// clang-format off
BOOST_ANNOTATE_MEMBER(file_frame_slice, start,
(desc, "start"),
(doc, "First frame of the slice"))
BOOST_ANNOTATE_MEMBER(file_frame_slice, count,
(desc, "count"),
(doc, "Number of frames in the slice [0 = container-limited]"))
BOOST_ANNOTATE_MEMBER(file_frame_slice, stride,
(desc, "stride"),
(doc, "Frame index step the slice"))
// clang-format on
BOOST_DESCRIBE_STRUCT(loading_params, (filename_loading_params), (start_number, nb_frames_per_file, frame_slice))
// clang-format off
BOOST_ANNOTATE_MEMBER(loading_params, start_number,
......@@ -78,6 +94,10 @@ namespace io
BOOST_ANNOTATE_MEMBER(loading_params, nb_frames_per_file,
(desc, "nb frames per file"),
(doc, "Number of frames per file [0 = autodetect]"))
BOOST_ANNOTATE_MEMBER(loading_params, frame_slice,
(desc, "frame slice"),
(doc, "Slice selecting the frames to load"))
// clang-format on
} //namespace io
......
......@@ -9,6 +9,8 @@
#include <filesystem>
#include <string>
#include <lima/exceptions.hpp>
#include <lima/io/const.hpp>
#include <lima/io/enums.hpp>
......@@ -70,10 +72,53 @@ namespace io
};
using filename_loading_params = filename_params_base<DefaultLoadingValues>;
struct file_frame_slice
{
int start = 0;
int count = 0; //!< End of slice given by container
int stride = 1;
void check() const
{
if ((start < 0) || (count < 0) || (stride < 1))
LIMA_THROW_EXCEPTION(lima::invalid_argument("Invalid file frame slice"));
}
int calc_count(int nb_frames) const
{
check();
if (start >= nb_frames)
LIMA_THROW_EXCEPTION(lima::invalid_argument("Invalid file frame slice start/nb_frames"));
auto slice_frames = (nb_frames - start - 1) / stride + 1;
if (count == 0)
return slice_frames;
else if (count <= slice_frames)
return count;
else
LIMA_THROW_EXCEPTION(lima::invalid_argument("Invalid file frame slice count/nb_frames"));
}
void apply_sub_slice(file_frame_slice const& o)
{
check();
o.check();
start += o.start * stride;
stride *= o.stride;
if (o.count == 0)
return;
if ((count == 0) || (count >= o.count))
count = o.count;
else
LIMA_THROW_EXCEPTION(lima::invalid_argument("Sub-slice larger than original one"));
}
};
struct loading_params : filename_loading_params
{
int start_number = 0;
int nb_frames_per_file = 0; //!< Automatic detection
file_frame_slice frame_slice;
};
} //namespace io
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment