mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-06-12 23:37:13 +02:00
Developer (#164)
- State before merging the new cluster vector API --------- Co-authored-by: Patrick <patrick.sieberer@psi.ch> Co-authored-by: JulianHeymes <julian.heymes@psi.ch> Co-authored-by: Dhanya Thattil <dhanya.thattil@psi.ch> Co-authored-by: Xiangyu Xie <45243914+xiangyuxie@users.noreply.github.com> Co-authored-by: xiangyu.xie <xiangyu.xie@psi.ch> Co-authored-by: siebsi <sieb.patr@gmail.com>
This commit is contained in:
@ -1,12 +1,13 @@
|
||||
|
||||
find_package (Python 3.10 COMPONENTS Interpreter Development REQUIRED)
|
||||
find_package (Python 3.10 COMPONENTS Interpreter Development.Module REQUIRED)
|
||||
set(PYBIND11_FINDPYTHON ON) # Needed for RH8
|
||||
|
||||
# Download or find pybind11 depending on configuration
|
||||
if(AARE_FETCH_PYBIND11)
|
||||
FetchContent_Declare(
|
||||
pybind11
|
||||
GIT_REPOSITORY https://github.com/pybind/pybind11
|
||||
GIT_TAG v2.13.0
|
||||
GIT_TAG v2.13.6
|
||||
)
|
||||
FetchContent_MakeAvailable(pybind11)
|
||||
else()
|
||||
@ -58,10 +59,16 @@ endforeach(FILE ${PYTHON_EXAMPLES})
|
||||
|
||||
|
||||
if(AARE_INSTALL_PYTHONEXT)
|
||||
install(TARGETS _aare
|
||||
install(
|
||||
TARGETS _aare
|
||||
EXPORT "${TARGETS_EXPORT_NAME}"
|
||||
LIBRARY DESTINATION aare
|
||||
COMPONENT python
|
||||
)
|
||||
|
||||
install(FILES ${PYTHON_FILES} DESTINATION aare)
|
||||
install(
|
||||
FILES ${PYTHON_FILES}
|
||||
DESTINATION aare
|
||||
COMPONENT python
|
||||
)
|
||||
endif()
|
@ -2,7 +2,7 @@
|
||||
from . import _aare
|
||||
|
||||
|
||||
from ._aare import File, RawMasterFile, RawSubFile
|
||||
from ._aare import File, RawMasterFile, RawSubFile, JungfrauDataFile
|
||||
from ._aare import Pedestal_d, Pedestal_f, ClusterFinder, VarClusterFinder
|
||||
from ._aare import DetectorType
|
||||
from ._aare import ClusterFile
|
||||
@ -13,11 +13,15 @@ from ._aare import ClusterFinderMT, ClusterCollector, ClusterFileSink, ClusterVe
|
||||
|
||||
from ._aare import fit_gaus, fit_pol1
|
||||
from ._aare import Interpolator
|
||||
|
||||
|
||||
from ._aare import apply_custom_weights
|
||||
|
||||
from .CtbRawFile import CtbRawFile
|
||||
from .RawFile import RawFile
|
||||
from .ScanParameters import ScanParameters
|
||||
|
||||
from .utils import random_pixels, random_pixel, flat_list
|
||||
from .utils import random_pixels, random_pixel, flat_list, add_colorbar
|
||||
|
||||
|
||||
#make functions available in the top level API
|
||||
|
@ -1,4 +1,6 @@
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from mpl_toolkits.axes_grid1 import make_axes_locatable
|
||||
|
||||
def random_pixels(n_pixels, xmin=0, xmax=512, ymin=0, ymax=1024):
|
||||
"""Return a list of random pixels.
|
||||
@ -24,4 +26,11 @@ def random_pixel(xmin=0, xmax=512, ymin=0, ymax=1024):
|
||||
|
||||
def flat_list(xss):
|
||||
"""Flatten a list of lists."""
|
||||
return [x for xs in xss for x in xs]
|
||||
return [x for xs in xss for x in xs]
|
||||
|
||||
def add_colorbar(ax, im, size="5%", pad=0.05):
|
||||
"""Add a colorbar with the same height as the image."""
|
||||
divider = make_axes_locatable(ax)
|
||||
cax = divider.append_axes("right", size=size, pad=pad)
|
||||
plt.colorbar(im, cax=cax)
|
||||
return ax, im, cax
|
@ -10,6 +10,8 @@
|
||||
#include "aare/decode.hpp"
|
||||
// #include "aare/fClusterFileV2.hpp"
|
||||
|
||||
#include "np_helper.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <pybind11/iostream.h>
|
||||
@ -65,35 +67,54 @@ m.def("adc_sar_04_decode64to16", [](py::array_t<uint8_t> input) {
|
||||
return output;
|
||||
});
|
||||
|
||||
py::class_<CtbRawFile>(m, "CtbRawFile")
|
||||
.def(py::init<const std::filesystem::path &>())
|
||||
.def("read_frame",
|
||||
[](CtbRawFile &self) {
|
||||
size_t image_size = self.image_size_in_bytes();
|
||||
py::array image;
|
||||
std::vector<ssize_t> shape;
|
||||
shape.reserve(2);
|
||||
shape.push_back(1);
|
||||
shape.push_back(image_size);
|
||||
m.def(
|
||||
"apply_custom_weights",
|
||||
[](py::array_t<uint16_t, py::array::c_style | py::array::forcecast> &input,
|
||||
py::array_t<double, py::array::c_style | py::array::forcecast>
|
||||
&weights) {
|
||||
|
||||
|
||||
py::array_t<DetectorHeader> header(1);
|
||||
// Create new array with same shape as the input array (uninitialized values)
|
||||
py::buffer_info buf = input.request();
|
||||
py::array_t<double> output(buf.shape);
|
||||
|
||||
// always read bytes
|
||||
image = py::array_t<uint8_t>(shape);
|
||||
// Use NDViews to call into the C++ library
|
||||
auto weights_view = make_view_1d(weights);
|
||||
NDView<uint16_t, 1> input_view(input.mutable_data(), {input.size()});
|
||||
NDView<double, 1> output_view(output.mutable_data(), {output.size()});
|
||||
|
||||
self.read_into(
|
||||
reinterpret_cast<std::byte *>(image.mutable_data()),
|
||||
header.mutable_data());
|
||||
apply_custom_weights(input_view, output_view, weights_view);
|
||||
return output;
|
||||
});
|
||||
|
||||
return py::make_tuple(header, image);
|
||||
})
|
||||
.def("seek", &CtbRawFile::seek)
|
||||
.def("tell", &CtbRawFile::tell)
|
||||
.def("master", &CtbRawFile::master)
|
||||
py::class_<CtbRawFile>(m, "CtbRawFile")
|
||||
.def(py::init<const std::filesystem::path &>())
|
||||
.def("read_frame",
|
||||
[](CtbRawFile &self) {
|
||||
size_t image_size = self.image_size_in_bytes();
|
||||
py::array image;
|
||||
std::vector<ssize_t> shape;
|
||||
shape.reserve(2);
|
||||
shape.push_back(1);
|
||||
shape.push_back(image_size);
|
||||
|
||||
.def_property_readonly("image_size_in_bytes",
|
||||
&CtbRawFile::image_size_in_bytes)
|
||||
py::array_t<DetectorHeader> header(1);
|
||||
|
||||
.def_property_readonly("frames_in_file", &CtbRawFile::frames_in_file);
|
||||
// always read bytes
|
||||
image = py::array_t<uint8_t>(shape);
|
||||
|
||||
}
|
||||
self.read_into(reinterpret_cast<std::byte *>(image.mutable_data()),
|
||||
header.mutable_data());
|
||||
|
||||
return py::make_tuple(header, image);
|
||||
})
|
||||
.def("seek", &CtbRawFile::seek)
|
||||
.def("tell", &CtbRawFile::tell)
|
||||
.def("master", &CtbRawFile::master)
|
||||
|
||||
.def_property_readonly("image_size_in_bytes",
|
||||
&CtbRawFile::image_size_in_bytes)
|
||||
|
||||
.def_property_readonly("frames_in_file", &CtbRawFile::frames_in_file);
|
||||
|
||||
}
|
||||
|
@ -20,6 +20,9 @@
|
||||
namespace py = pybind11;
|
||||
using namespace ::aare;
|
||||
|
||||
|
||||
|
||||
|
||||
//Disable warnings for unused parameters, as we ignore some
|
||||
//in the __exit__ method
|
||||
#pragma GCC diagnostic push
|
||||
@ -214,36 +217,9 @@ void define_file_io_bindings(py::module &m) {
|
||||
|
||||
|
||||
|
||||
py::class_<RawSubFile>(m, "RawSubFile")
|
||||
.def(py::init<const std::filesystem::path &, DetectorType, size_t,
|
||||
size_t, size_t>())
|
||||
.def_property_readonly("bytes_per_frame", &RawSubFile::bytes_per_frame)
|
||||
.def_property_readonly("pixels_per_frame",
|
||||
&RawSubFile::pixels_per_frame)
|
||||
.def("seek", &RawSubFile::seek)
|
||||
.def("tell", &RawSubFile::tell)
|
||||
.def_property_readonly("rows", &RawSubFile::rows)
|
||||
.def_property_readonly("cols", &RawSubFile::cols)
|
||||
.def("read_frame",
|
||||
[](RawSubFile &self) {
|
||||
const uint8_t item_size = self.bytes_per_pixel();
|
||||
py::array image;
|
||||
std::vector<ssize_t> shape;
|
||||
shape.reserve(2);
|
||||
shape.push_back(self.rows());
|
||||
shape.push_back(self.cols());
|
||||
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);
|
||||
}
|
||||
fmt::print("item_size: {} rows: {} cols: {}\n", item_size, self.rows(), self.cols());
|
||||
self.read_into(
|
||||
reinterpret_cast<std::byte *>(image.mutable_data()));
|
||||
return image;
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
// py::class_<ClusterHeader>(m, "ClusterHeader")
|
||||
|
116
python/src/jungfrau_data_file.hpp
Normal file
116
python/src/jungfrau_data_file.hpp
Normal file
@ -0,0 +1,116 @@
|
||||
|
||||
#include "aare/JungfrauDataFile.hpp"
|
||||
#include "aare/defs.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;
|
||||
|
||||
// Disable warnings for unused parameters, as we ignore some
|
||||
// in the __exit__ method
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
auto read_dat_frame(JungfrauDataFile &self) {
|
||||
py::array_t<JungfrauDataHeader> header(1);
|
||||
py::array_t<uint16_t> image({
|
||||
self.rows(),
|
||||
self.cols()
|
||||
});
|
||||
|
||||
self.read_into(reinterpret_cast<std::byte *>(image.mutable_data()),
|
||||
header.mutable_data());
|
||||
|
||||
return py::make_tuple(header, image);
|
||||
}
|
||||
|
||||
auto read_n_dat_frames(JungfrauDataFile &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");
|
||||
}
|
||||
|
||||
py::array_t<JungfrauDataHeader> header(n_frames);
|
||||
py::array_t<uint16_t> image({
|
||||
n_frames, self.rows(),
|
||||
self.cols()});
|
||||
|
||||
self.read_into(reinterpret_cast<std::byte *>(image.mutable_data()),
|
||||
n_frames, header.mutable_data());
|
||||
|
||||
return py::make_tuple(header, image);
|
||||
}
|
||||
|
||||
void define_jungfrau_data_file_io_bindings(py::module &m) {
|
||||
// Make the JungfrauDataHeader usable from numpy
|
||||
PYBIND11_NUMPY_DTYPE(JungfrauDataHeader, framenum, bunchid);
|
||||
|
||||
py::class_<JungfrauDataFile>(m, "JungfrauDataFile")
|
||||
.def(py::init<const std::filesystem::path &>())
|
||||
.def("seek", &JungfrauDataFile::seek,
|
||||
R"(
|
||||
Seek to the given frame index.
|
||||
)")
|
||||
.def("tell", &JungfrauDataFile::tell,
|
||||
R"(
|
||||
Get the current frame index.
|
||||
)")
|
||||
.def_property_readonly("rows", &JungfrauDataFile::rows)
|
||||
.def_property_readonly("cols", &JungfrauDataFile::cols)
|
||||
.def_property_readonly("base_name", &JungfrauDataFile::base_name)
|
||||
.def_property_readonly("bytes_per_frame",
|
||||
&JungfrauDataFile::bytes_per_frame)
|
||||
.def_property_readonly("pixels_per_frame",
|
||||
&JungfrauDataFile::pixels_per_frame)
|
||||
.def_property_readonly("bytes_per_pixel",
|
||||
&JungfrauDataFile::bytes_per_pixel)
|
||||
.def_property_readonly("bitdepth", &JungfrauDataFile::bitdepth)
|
||||
.def_property_readonly("current_file", &JungfrauDataFile::current_file)
|
||||
.def_property_readonly("total_frames", &JungfrauDataFile::total_frames)
|
||||
.def_property_readonly("n_files", &JungfrauDataFile::n_files)
|
||||
.def("read_frame", &read_dat_frame,
|
||||
R"(
|
||||
Read a single frame from the file.
|
||||
)")
|
||||
.def("read_n", &read_n_dat_frames,
|
||||
R"(
|
||||
Read maximum n_frames frames from the file.
|
||||
)")
|
||||
.def(
|
||||
"read",
|
||||
[](JungfrauDataFile &self) {
|
||||
self.seek(0);
|
||||
auto n_frames = self.total_frames();
|
||||
return read_n_dat_frames(self, n_frames);
|
||||
},
|
||||
R"(
|
||||
Read all frames from the file. Seeks to the beginning before reading.
|
||||
)")
|
||||
.def("__enter__", [](JungfrauDataFile &self) { return &self; })
|
||||
.def("__exit__",
|
||||
[](JungfrauDataFile &self,
|
||||
const std::optional<pybind11::type> &exc_type,
|
||||
const std::optional<pybind11::object> &exc_value,
|
||||
const std::optional<pybind11::object> &traceback) {
|
||||
// self.close();
|
||||
})
|
||||
.def("__iter__", [](JungfrauDataFile &self) { return &self; })
|
||||
.def("__next__", [](JungfrauDataFile &self) {
|
||||
try {
|
||||
return read_dat_frame(self);
|
||||
} catch (std::runtime_error &e) {
|
||||
throw py::stop_iteration();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
@ -10,6 +10,9 @@
|
||||
#include "cluster_file.hpp"
|
||||
#include "fit.hpp"
|
||||
#include "interpolation.hpp"
|
||||
#include "raw_sub_file.hpp"
|
||||
|
||||
#include "jungfrau_data_file.hpp"
|
||||
|
||||
//Pybind stuff
|
||||
#include <pybind11/pybind11.h>
|
||||
@ -20,6 +23,7 @@ namespace py = pybind11;
|
||||
PYBIND11_MODULE(_aare, m) {
|
||||
define_file_io_bindings(m);
|
||||
define_raw_file_io_bindings(m);
|
||||
define_raw_sub_file_io_bindings(m);
|
||||
define_ctb_raw_file_io_bindings(m);
|
||||
define_raw_master_file_bindings(m);
|
||||
define_var_cluster_finder_bindings(m);
|
||||
@ -33,5 +37,6 @@ PYBIND11_MODULE(_aare, m) {
|
||||
define_cluster_file_sink_bindings(m);
|
||||
define_fit_bindings(m);
|
||||
define_interpolation_bindings(m);
|
||||
define_jungfrau_data_file_io_bindings(m);
|
||||
|
||||
}
|
110
python/src/raw_sub_file.hpp
Normal file
110
python/src/raw_sub_file.hpp
Normal file
@ -0,0 +1,110 @@
|
||||
#include "aare/CtbRawFile.hpp"
|
||||
#include "aare/File.hpp"
|
||||
#include "aare/Frame.hpp"
|
||||
#include "aare/RawFile.hpp"
|
||||
#include "aare/RawMasterFile.hpp"
|
||||
#include "aare/RawSubFile.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;
|
||||
|
||||
auto read_frame_from_RawSubFile(RawSubFile &self) {
|
||||
py::array_t<DetectorHeader> header(1);
|
||||
const uint8_t item_size = self.bytes_per_pixel();
|
||||
std::vector<ssize_t> shape{static_cast<ssize_t>(self.rows()),
|
||||
static_cast<ssize_t>(self.cols())};
|
||||
|
||||
py::array image;
|
||||
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);
|
||||
}
|
||||
|
||||
auto read_n_frames_from_RawSubFile(RawSubFile &self, size_t n_frames) {
|
||||
py::array_t<DetectorHeader> header(n_frames);
|
||||
const uint8_t item_size = self.bytes_per_pixel();
|
||||
std::vector<ssize_t> shape{
|
||||
static_cast<ssize_t>(n_frames),
|
||||
static_cast<ssize_t>(self.rows()),
|
||||
static_cast<ssize_t>(self.cols())
|
||||
};
|
||||
|
||||
py::array image;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
//Disable warnings for unused parameters, as we ignore some
|
||||
//in the __exit__ method
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
void define_raw_sub_file_io_bindings(py::module &m) {
|
||||
py::class_<RawSubFile>(m, "RawSubFile")
|
||||
.def(py::init<const std::filesystem::path &, DetectorType, size_t,
|
||||
size_t, size_t>())
|
||||
.def_property_readonly("bytes_per_frame", &RawSubFile::bytes_per_frame)
|
||||
.def_property_readonly("pixels_per_frame",
|
||||
&RawSubFile::pixels_per_frame)
|
||||
.def_property_readonly("bytes_per_pixel", &RawSubFile::bytes_per_pixel)
|
||||
.def("seek", &RawSubFile::seek)
|
||||
.def("tell", &RawSubFile::tell)
|
||||
.def_property_readonly("rows", &RawSubFile::rows)
|
||||
.def_property_readonly("cols", &RawSubFile::cols)
|
||||
.def_property_readonly("frames_in_file", &RawSubFile::frames_in_file)
|
||||
.def("read_frame", &read_frame_from_RawSubFile)
|
||||
.def("read_n", &read_n_frames_from_RawSubFile)
|
||||
.def("read", [](RawSubFile &self){
|
||||
self.seek(0);
|
||||
auto n_frames = self.frames_in_file();
|
||||
return read_n_frames_from_RawSubFile(self, n_frames);
|
||||
})
|
||||
.def("__enter__", [](RawSubFile &self) { return &self; })
|
||||
.def("__exit__",
|
||||
[](RawSubFile &self,
|
||||
const std::optional<pybind11::type> &exc_type,
|
||||
const std::optional<pybind11::object> &exc_value,
|
||||
const std::optional<pybind11::object> &traceback) {
|
||||
})
|
||||
.def("__iter__", [](RawSubFile &self) { return &self; })
|
||||
.def("__next__", [](RawSubFile &self) {
|
||||
try {
|
||||
return read_frame_from_RawSubFile(self);
|
||||
} catch (std::runtime_error &e) {
|
||||
throw py::stop_iteration();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
29
python/tests/conftest.py
Normal file
29
python/tests/conftest.py
Normal file
@ -0,0 +1,29 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
import pytest
|
||||
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption(
|
||||
"--files", action="store_true", default=False, help="run slow tests"
|
||||
)
|
||||
|
||||
|
||||
def pytest_configure(config):
|
||||
config.addinivalue_line("markers", "files: mark test as needing image files to run")
|
||||
|
||||
|
||||
def pytest_collection_modifyitems(config, items):
|
||||
if config.getoption("--files"):
|
||||
return
|
||||
skip = pytest.mark.skip(reason="need --files option to run")
|
||||
for item in items:
|
||||
if "files" in item.keywords:
|
||||
item.add_marker(skip)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def test_data_path():
|
||||
return Path(os.environ["AARE_TEST_DATA"])
|
||||
|
36
python/tests/test_RawSubFile.py
Normal file
36
python/tests/test_RawSubFile.py
Normal file
@ -0,0 +1,36 @@
|
||||
import pytest
|
||||
import numpy as np
|
||||
from aare import RawSubFile, DetectorType
|
||||
|
||||
|
||||
@pytest.mark.files
|
||||
def test_read_a_jungfrau_RawSubFile(test_data_path):
|
||||
with RawSubFile(test_data_path / "raw/jungfrau/jungfrau_single_d0_f1_0.raw", DetectorType.Jungfrau, 512, 1024, 16) as f:
|
||||
assert f.frames_in_file == 3
|
||||
|
||||
headers, frames = f.read()
|
||||
|
||||
assert headers.size == 3
|
||||
assert frames.shape == (3, 512, 1024)
|
||||
|
||||
# Frame numbers in this file should be 4, 5, 6
|
||||
for i,h in zip(range(4,7,1), headers):
|
||||
assert h["frameNumber"] == i
|
||||
|
||||
# Compare to canned data using numpy
|
||||
data = np.load(test_data_path / "raw/jungfrau/jungfrau_single_0.npy")
|
||||
assert np.all(data[3:6] == frames)
|
||||
|
||||
@pytest.mark.files
|
||||
def test_iterate_over_a_jungfrau_RawSubFile(test_data_path):
|
||||
|
||||
data = np.load(test_data_path / "raw/jungfrau/jungfrau_single_0.npy")
|
||||
|
||||
with RawSubFile(test_data_path / "raw/jungfrau/jungfrau_single_d0_f0_0.raw", DetectorType.Jungfrau, 512, 1024, 16) as f:
|
||||
i = 0
|
||||
for header, frame in f:
|
||||
assert header["frameNumber"] == i+1
|
||||
assert np.all(frame == data[i])
|
||||
i += 1
|
||||
assert i == 3
|
||||
assert header["frameNumber"] == 3
|
92
python/tests/test_jungfrau_dat_files.py
Normal file
92
python/tests/test_jungfrau_dat_files.py
Normal file
@ -0,0 +1,92 @@
|
||||
import pytest
|
||||
import numpy as np
|
||||
from aare import JungfrauDataFile
|
||||
|
||||
@pytest.mark.files
|
||||
def test_jfungfrau_dat_read_number_of_frames(test_data_path):
|
||||
with JungfrauDataFile(test_data_path / "dat/AldoJF500k_000000.dat") as dat_file:
|
||||
assert dat_file.total_frames == 24
|
||||
|
||||
with JungfrauDataFile(test_data_path / "dat/AldoJF250k_000000.dat") as dat_file:
|
||||
assert dat_file.total_frames == 53
|
||||
|
||||
with JungfrauDataFile(test_data_path / "dat/AldoJF65k_000000.dat") as dat_file:
|
||||
assert dat_file.total_frames == 113
|
||||
|
||||
|
||||
@pytest.mark.files
|
||||
def test_jfungfrau_dat_read_number_of_file(test_data_path):
|
||||
with JungfrauDataFile(test_data_path / "dat/AldoJF500k_000000.dat") as dat_file:
|
||||
assert dat_file.n_files == 4
|
||||
|
||||
with JungfrauDataFile(test_data_path / "dat/AldoJF250k_000000.dat") as dat_file:
|
||||
assert dat_file.n_files == 7
|
||||
|
||||
with JungfrauDataFile(test_data_path / "dat/AldoJF65k_000000.dat") as dat_file:
|
||||
assert dat_file.n_files == 7
|
||||
|
||||
|
||||
@pytest.mark.files
|
||||
def test_read_module(test_data_path):
|
||||
"""
|
||||
Read all frames from the series of .dat files. Compare to canned data in npz format.
|
||||
"""
|
||||
|
||||
# Read all frames from the .dat file
|
||||
with JungfrauDataFile(test_data_path / "dat/AldoJF500k_000000.dat") as f:
|
||||
header, data = f.read()
|
||||
|
||||
#Sanity check
|
||||
n_frames = 24
|
||||
assert header.size == n_frames
|
||||
assert data.shape == (n_frames, 512, 1024)
|
||||
|
||||
# Read reference data using numpy
|
||||
with np.load(test_data_path / "dat/AldoJF500k.npz") as f:
|
||||
ref_header = f["headers"]
|
||||
ref_data = f["frames"]
|
||||
|
||||
# Check that the data is the same
|
||||
assert np.all(ref_header == header)
|
||||
assert np.all(ref_data == data)
|
||||
|
||||
@pytest.mark.files
|
||||
def test_read_half_module(test_data_path):
|
||||
|
||||
# Read all frames from the .dat file
|
||||
with JungfrauDataFile(test_data_path / "dat/AldoJF250k_000000.dat") as f:
|
||||
header, data = f.read()
|
||||
|
||||
n_frames = 53
|
||||
assert header.size == n_frames
|
||||
assert data.shape == (n_frames, 256, 1024)
|
||||
|
||||
# Read reference data using numpy
|
||||
with np.load(test_data_path / "dat/AldoJF250k.npz") as f:
|
||||
ref_header = f["headers"]
|
||||
ref_data = f["frames"]
|
||||
|
||||
# Check that the data is the same
|
||||
assert np.all(ref_header == header)
|
||||
assert np.all(ref_data == data)
|
||||
|
||||
|
||||
@pytest.mark.files
|
||||
def test_read_single_chip(test_data_path):
|
||||
|
||||
# Read all frames from the .dat file
|
||||
with JungfrauDataFile(test_data_path / "dat/AldoJF65k_000000.dat") as f:
|
||||
header, data = f.read()
|
||||
|
||||
n_frames = 113
|
||||
assert header.size == n_frames
|
||||
assert data.shape == (n_frames, 256, 256)
|
||||
|
||||
# Read reference data using numpy
|
||||
with np.load(test_data_path / "dat/AldoJF65k.npz") as f:
|
||||
ref_header = f["headers"]
|
||||
ref_data = f["frames"]
|
||||
|
||||
# Check that the data is the same
|
||||
assert np.all(ref_header == header)
|
||||
assert np.all(ref_data == data)
|
Reference in New Issue
Block a user