Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions include/npy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,78 @@ inline npy_data<Scalar> read_npy(std::istream &in) {
return data;
}

template <typename Scalar>
inline npy_data<Scalar> read_npy_partial(std::istream &in,shape_t shape_requested,std::size_t byte_offset) {
std::string header_s = read_header(in);

// parse header
const header_t header = parse_header(header_s);

// check if the typestring matches the given one
const dtype_t dtype = dtype_map.at(std::type_index(typeid(Scalar)));

if (header.dtype.tie() != dtype.tie()) {
throw std::runtime_error("formatting error: typestrings not matching");
}

// compute the data size based on the shape the user requested
const auto requested_size=static_cast<size_t>(comp_size(shape_requested));

npy_data<Scalar> data;

data.shape = shape_requested;
data.fortran_order = header.fortran_order;

data.data.resize(requested_size);

// read the data
if (byte_offset>0){
in.seekg(byte_offset,std::ios::beg);
}
in.read(reinterpret_cast<char *>(data.data.data()), sizeof(Scalar) * requested_size);
if (!in){
std::cerr<<"ERROR: partial read failed!"<<std::endl;
}
return data;
}

template <typename Scalar>
inline void read_npy_into(std::istream &in, npy_data<Scalar> &data) {
std::string header_s = read_header(in);

// parse header
header_t header = parse_header(header_s);

// check if the typestring matches the given one
const dtype_t dtype = dtype_map.at(std::type_index(typeid(Scalar)));

if (header.dtype.tie() != dtype.tie()) {
throw std::runtime_error("formatting error: typestrings not matching");
}

// compute the data size based on the shape
auto size = static_cast<size_t>(comp_size(header.shape));

data.shape = header.shape;
data.fortran_order = header.fortran_order;

// This will now do nothing
if (data.data.size() != size) {
data.data.resize(size);
}

// read the data
in.read(reinterpret_cast<char *>(data.data.data()), sizeof(Scalar) * size);
return;
}


inline shape_t read_npy_shape(std::istream& in) {
std::string header_s = read_header(in);
header_t header = parse_header(header_s);
return header.shape;
}

template <typename Scalar>
inline npy_data<Scalar> read_npy(const std::string &filename) {
std::ifstream stream(filename, std::ifstream::binary);
Expand All @@ -513,6 +585,35 @@ inline npy_data<Scalar> read_npy(const std::string &filename) {
return read_npy<Scalar>(stream);
}

template <typename Scalar>
inline npy_data<Scalar> read_npy_partial(const std::string &filename,shape_t shape,std::size_t byte_offset) {
std::ifstream stream(filename, std::ifstream::binary);
if (!stream) {
throw std::runtime_error("io error: failed to open a file.");
}

return read_npy_partial<Scalar>(stream, shape, byte_offset);
}

inline shape_t read_npy_shape(const std::string &filename) {
std::ifstream stream(filename, std::ifstream::binary);
if (!stream) {
throw std::runtime_error("io error: failed to open a file.");
}

return read_npy_shape(stream);
}

template <typename Scalar>
inline void read_npy_into(const std::string &filename, npy_data<Scalar> &data) {
std::ifstream stream(filename, std::ifstream::binary);
if (!stream) {
throw std::runtime_error("io error: failed to open a file.");
}
read_npy_into<Scalar>(stream, data);
return;
}

template <typename Scalar>
inline void write_npy(std::ostream &out, const npy_data<Scalar> &data) {
// static_assert(has_typestring<Scalar>::value, "scalar type not
Expand Down