mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-06-11 06:47:14 +02:00
first draft of hdf5, reads master metadata, reads data dims, process of hyperslab
This commit is contained in:
@ -34,6 +34,31 @@ set( PYTHON_FILES
|
||||
aare/utils.py
|
||||
)
|
||||
|
||||
# Conditionally add HDF5-related Python files
|
||||
# HDF5
|
||||
# if (AARE_HDF5)
|
||||
# find_package(h5py REQUIRED)
|
||||
|
||||
# find_package(HDF5 1.10 COMPONENTS CXX REQUIRED)
|
||||
# add_definitions(
|
||||
# ${HDF5_DEFINITIONS}
|
||||
# )
|
||||
# list(APPEND PYTHON_FILES
|
||||
# aare/Hdf5File.py
|
||||
# )
|
||||
# if(HDF5_FOUND)
|
||||
# target_sources(_aare PRIVATE
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/src/Hdf5File.cpp
|
||||
# ${CMAKE_CURRENT_SOURCE_DIR}/src/Hdf5MasterFile.cpp
|
||||
# )
|
||||
# target_link_libraries(_aare PUBLIC ${HDF5_LIBRARIES})
|
||||
# target_include_directories(_aare PUBLIC ${HDF5_INCLUDE_DIRS})
|
||||
# endif()
|
||||
# if(H5PY_FOUND)
|
||||
# set(H5PY_INCLUDE_DIRS ${H5PY_INCLUDE_DIR})
|
||||
# set(H5PY_LIBRARIES ${PYTHON_LIBRARIES})
|
||||
# endif()
|
||||
|
||||
# Copy the python files to the build directory
|
||||
foreach(FILE ${PYTHON_FILES})
|
||||
configure_file(${FILE} ${CMAKE_BINARY_DIR}/${FILE} )
|
||||
|
66
python/aare/Hdf5File.py
Normal file
66
python/aare/Hdf5File.py
Normal file
@ -0,0 +1,66 @@
|
||||
from . import _aare
|
||||
import numpy as np
|
||||
#from .ScanParameters import ScanParameters
|
||||
|
||||
class Hdf5File(_aare.Hdf5File):
|
||||
def __init__(self, fname, chunk_size = 1):
|
||||
super().__init__(fname)
|
||||
self._chunk_size = chunk_size
|
||||
|
||||
|
||||
def read(self) -> tuple:
|
||||
"""Read the entire file.
|
||||
Seeks to the beginning of the file before reading.
|
||||
|
||||
Returns:
|
||||
tuple: header, data
|
||||
"""
|
||||
self.seek(0)
|
||||
return self.read_n(self.total_frames)
|
||||
|
||||
# @property
|
||||
# def scan_parameters(self):
|
||||
# """Return the scan parameters.
|
||||
|
||||
# Returns:
|
||||
# ScanParameters: Scan parameters.
|
||||
# """
|
||||
# return ScanParameters(self.master.scan_parameters)
|
||||
|
||||
@property
|
||||
def master(self):
|
||||
"""Return the master file.
|
||||
|
||||
Returns:
|
||||
Hdf5MasterFile: Master file.
|
||||
"""
|
||||
return super().master
|
||||
|
||||
def __len__(self) -> int:
|
||||
"""Return the number of frames in the file.
|
||||
|
||||
Returns:
|
||||
int: Number of frames in file.
|
||||
"""
|
||||
return super().frames_in_file
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
pass
|
||||
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
try:
|
||||
if self._chunk_size == 1:
|
||||
return self.read_frame()
|
||||
else:
|
||||
return self.read_n(self._chunk_size)
|
||||
|
||||
|
||||
except RuntimeError:
|
||||
# TODO! find a good way to check that we actually have the right exception
|
||||
raise StopIteration
|
@ -11,4 +11,22 @@ from .CtbRawFile import CtbRawFile
|
||||
from .RawFile import RawFile
|
||||
from .ScanParameters import ScanParameters
|
||||
|
||||
from .utils import random_pixels, random_pixel
|
||||
from .utils import random_pixels, random_pixel
|
||||
|
||||
try:
|
||||
import h5py
|
||||
HDF5_FOUND = True
|
||||
except ImportError:
|
||||
HDF5_FOUND = False
|
||||
|
||||
if HDF5_FOUND:
|
||||
from ._aare import Hdf5MasterFile
|
||||
from .Hdf5File import Hdf5File
|
||||
else:
|
||||
class Hdf5MasterFile:
|
||||
def __init__(self, *args, **kwargs):
|
||||
raise ImportError("h5py library not found. HDF5 Master File is not available.")
|
||||
|
||||
class Hdf5File:
|
||||
def __init__(self, *args, **kwargs):
|
||||
raise ImportError("h5py library not found. HDF5 File is not available.")
|
||||
|
@ -5,6 +5,11 @@
|
||||
#include "aare/RawMasterFile.hpp"
|
||||
#include "aare/RawSubFile.hpp"
|
||||
|
||||
#ifdef HDF5_FOUND
|
||||
#include "aare/Hdf5File.hpp"
|
||||
#include "aare/Hdf5MasterFile.hpp"
|
||||
#endif
|
||||
|
||||
#include "aare/defs.hpp"
|
||||
// #include "aare/fClusterFileV2.hpp"
|
||||
|
||||
|
105
python/src/hdf5_file.hpp
Normal file
105
python/src/hdf5_file.hpp
Normal file
@ -0,0 +1,105 @@
|
||||
#include "aare/File.hpp"
|
||||
#include "aare/Frame.hpp"
|
||||
#include "aare/Hdf5File.hpp"
|
||||
#include "aare/Hdf5MasterFile.hpp"
|
||||
|
||||
#include "aare/defs.hpp"
|
||||
// #include "aare/fClusterFileV2.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <pybind11/iostream.h>
|
||||
#include <pybind11/numpy.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/stl/filesystem.h>
|
||||
#include <string>
|
||||
|
||||
namespace py = pybind11;
|
||||
using namespace ::aare;
|
||||
|
||||
void define_hdf5_file_io_bindings(py::module &m) {
|
||||
py::class_<Hdf5File>(m, "Hdf5File")
|
||||
.def(py::init<const std::filesystem::path &>())
|
||||
.def("read_frame",
|
||||
[](Hdf5File &self) {
|
||||
py::array image;
|
||||
std::vector<ssize_t> shape;
|
||||
shape.reserve(2);
|
||||
shape.push_back(self.rows());
|
||||
shape.push_back(self.cols());
|
||||
|
||||
// return headers from all subfiles
|
||||
py::array_t<DetectorHeader> header(self.n_mod());
|
||||
|
||||
const uint8_t item_size = self.bytes_per_pixel();
|
||||
if (item_size == 1) {
|
||||
image = py::array_t<uint8_t>(shape);
|
||||
} else if (item_size == 2) {
|
||||
image = py::array_t<uint16_t>(shape);
|
||||
} else if (item_size == 4) {
|
||||
image = py::array_t<uint32_t>(shape);
|
||||
}
|
||||
self.read_into(
|
||||
reinterpret_cast<std::byte *>(image.mutable_data()),
|
||||
header.mutable_data());
|
||||
|
||||
return py::make_tuple(header, image);
|
||||
})
|
||||
.def(
|
||||
"read_n",
|
||||
[](Hdf5File &self, size_t n_frames) {
|
||||
// adjust for actual frames left in the file
|
||||
n_frames =
|
||||
std::min(n_frames, self.total_frames() - self.tell());
|
||||
if (n_frames == 0) {
|
||||
throw std::runtime_error("No frames left in file");
|
||||
}
|
||||
std::vector<size_t> shape{n_frames, self.rows(), self.cols()};
|
||||
|
||||
// return headers from all subfiles
|
||||
py::array_t<DetectorHeader> header;
|
||||
if (self.n_mod() == 1) {
|
||||
header = py::array_t<DetectorHeader>(n_frames);
|
||||
} else {
|
||||
header =
|
||||
py::array_t<DetectorHeader>({self.n_mod(), n_frames});
|
||||
}
|
||||
// py::array_t<DetectorHeader> header({self.n_mod(), n_frames});
|
||||
|
||||
py::array image;
|
||||
const uint8_t item_size = self.bytes_per_pixel();
|
||||
if (item_size == 1) {
|
||||
image = py::array_t<uint8_t>(shape);
|
||||
} else if (item_size == 2) {
|
||||
image = py::array_t<uint16_t>(shape);
|
||||
} else if (item_size == 4) {
|
||||
image = py::array_t<uint32_t>(shape);
|
||||
}
|
||||
self.read_into(
|
||||
reinterpret_cast<std::byte *>(image.mutable_data()),
|
||||
n_frames, header.mutable_data());
|
||||
|
||||
return py::make_tuple(header, image);
|
||||
},
|
||||
R"(
|
||||
Read n frames from the file.
|
||||
)")
|
||||
.def("frame_number", &Hdf5File::frame_number)
|
||||
.def_property_readonly("bytes_per_frame", &Hdf5File::bytes_per_frame)
|
||||
.def_property_readonly("pixels_per_frame", &Hdf5File::pixels_per_frame)
|
||||
.def_property_readonly("bytes_per_pixel", &Hdf5File::bytes_per_pixel)
|
||||
.def("seek", &Hdf5File::seek, R"(
|
||||
Seek to a frame index in file.
|
||||
)")
|
||||
.def("tell", &Hdf5File::tell, R"(
|
||||
Return the current frame number.)")
|
||||
.def_property_readonly("total_frames", &Hdf5File::total_frames)
|
||||
.def_property_readonly("rows", &Hdf5File::rows)
|
||||
.def_property_readonly("cols", &Hdf5File::cols)
|
||||
.def_property_readonly("bitdepth", &Hdf5File::bitdepth)
|
||||
.def_property_readonly("geometry", &Hdf5File::geometry)
|
||||
.def_property_readonly("n_mod", &Hdf5File::n_mod)
|
||||
.def_property_readonly("detector_type", &Hdf5File::detector_type)
|
||||
.def_property_readonly("master", &Hdf5File::master);
|
||||
}
|
86
python/src/hdf5_master_file.hpp
Normal file
86
python/src/hdf5_master_file.hpp
Normal file
@ -0,0 +1,86 @@
|
||||
|
||||
#include "aare/File.hpp"
|
||||
#include "aare/Frame.hpp"
|
||||
#include "aare/Hdf5File.hpp"
|
||||
#include "aare/Hdf5MasterFile.hpp"
|
||||
|
||||
#include "aare/defs.hpp"
|
||||
// #include "aare/fClusterFileV2.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <pybind11/iostream.h>
|
||||
#include <pybind11/numpy.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/stl/filesystem.h>
|
||||
#include <string>
|
||||
|
||||
namespace py = pybind11;
|
||||
using namespace ::aare;
|
||||
|
||||
void define_hdf5_master_file_bindings(py::module &m) {
|
||||
py::class_<Hdf5MasterFile>(m, "Hdf5MasterFile")
|
||||
.def(py::init<const std::filesystem::path &>())
|
||||
.def("data_fname", &Hdf5MasterFile::data_fname, R"(
|
||||
|
||||
Parameters
|
||||
------------
|
||||
module_index : int
|
||||
module index (d0, d1 .. dN)
|
||||
file_index : int
|
||||
file index (f0, f1 .. fN)
|
||||
|
||||
Returns
|
||||
----------
|
||||
os.PathLike
|
||||
The name of the data file.
|
||||
|
||||
)")
|
||||
.def_property_readonly("version", &Hdf5MasterFile::version)
|
||||
.def_property_readonly("detector_type", &Hdf5MasterFile::detector_type)
|
||||
.def_property_readonly("timing_mode", &Hdf5MasterFile::timing_mode)
|
||||
.def_property_readonly("image_size_in_bytes",
|
||||
&Hdf5MasterFile::image_size_in_bytes)
|
||||
.def_property_readonly("frames_in_file",
|
||||
&Hdf5MasterFile::frames_in_file)
|
||||
.def_property_readonly("pixels_y", &Hdf5MasterFile::pixels_y)
|
||||
.def_property_readonly("pixels_x", &Hdf5MasterFile::pixels_x)
|
||||
.def_property_readonly("max_frames_per_file",
|
||||
&Hdf5MasterFile::max_frames_per_file)
|
||||
.def_property_readonly("bitdepth", &Hdf5MasterFile::bitdepth)
|
||||
.def_property_readonly("frame_padding", &Hdf5MasterFile::frame_padding)
|
||||
.def_property_readonly("frame_discard_policy",
|
||||
&Hdf5MasterFile::frame_discard_policy)
|
||||
|
||||
.def_property_readonly("total_frames_expected",
|
||||
&Hdf5MasterFile::total_frames_expected)
|
||||
.def_property_readonly("geometry", &Hdf5MasterFile::geometry)
|
||||
.def_property_readonly("analog_samples",
|
||||
&Hdf5MasterFile::analog_samples, R"(
|
||||
Number of analog samples
|
||||
|
||||
Returns
|
||||
----------
|
||||
int | None
|
||||
The number of analog samples in the file (or None if not enabled)
|
||||
)")
|
||||
.def_property_readonly("digital_samples",
|
||||
&Hdf5MasterFile::digital_samples, R"(
|
||||
Number of digital samples
|
||||
|
||||
Returns
|
||||
----------
|
||||
int | None
|
||||
The number of digital samples in the file (or None if not enabled)
|
||||
)")
|
||||
|
||||
.def_property_readonly("transceiver_samples",
|
||||
&Hdf5MasterFile::transceiver_samples)
|
||||
.def_property_readonly("number_of_rows",
|
||||
&Hdf5MasterFile::number_of_rows)
|
||||
.def_property_readonly("quad", &Hdf5MasterFile::quad)
|
||||
.def_property_readonly("scan_parameters",
|
||||
&Hdf5MasterFile::scan_parameters)
|
||||
.def_property_readonly("roi", &Hdf5MasterFile::roi);
|
||||
}
|
@ -3,6 +3,10 @@
|
||||
#include "raw_file.hpp"
|
||||
#include "ctb_raw_file.hpp"
|
||||
#include "raw_master_file.hpp"
|
||||
#ifdef HDF5_FOUND
|
||||
#include "hdf5_file.hpp"
|
||||
#include "hdf5_master_file.hpp"
|
||||
#endif
|
||||
#include "var_cluster.hpp"
|
||||
#include "pixel_map.hpp"
|
||||
#include "pedestal.hpp"
|
||||
@ -20,6 +24,10 @@ PYBIND11_MODULE(_aare, m) {
|
||||
define_raw_file_io_bindings(m);
|
||||
define_ctb_raw_file_io_bindings(m);
|
||||
define_raw_master_file_bindings(m);
|
||||
#ifdef HDF5_FOUND
|
||||
define_hdf5_file_io_bindings(m);
|
||||
define_hdf5_master_file_bindings(m);
|
||||
#endif
|
||||
define_var_cluster_finder_bindings(m);
|
||||
define_pixel_map_bindings(m);
|
||||
define_pedestal_bindings<double>(m, "Pedestal");
|
||||
|
Reference in New Issue
Block a user