diff --git a/RELEASE.md b/RELEASE.md index 29beb5ae..25ba39f3 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -74,6 +74,9 @@ - ``TimingMode::Auto`` changed to ``TimingMode::AUTO_TIMING``, ``TimingMode::Trigger`` changed to ``TimingMode::TRIGGER_EXPOSURE`` ### Bugfixes: +- Fixed ``CtbRawFile.read_frame(index)`` and reads after ``seek(index)`` at + subfile boundaries skipping a subfile, returning the wrong frame or raising + ``Subfile index out of range``. - ``Pedestal`` reports mismatched frame shapes with exceptions in all push overloads, including Debug builds, instead of aborting on assertions. - Python ``Pedestal`` constructors reject negative dimensions and sample diff --git a/docs/src/python/file/pyCtbRawFile.rst b/docs/src/python/file/pyCtbRawFile.rst index 75d83550..f0676e6d 100644 --- a/docs/src/python/file/pyCtbRawFile.rst +++ b/docs/src/python/file/pyCtbRawFile.rst @@ -6,6 +6,10 @@ Read analog, digital and transceiver samples from a raw file containing data from the Chip Test Board. Uses :mod:`aare.transform` to decode the data into a format that the user can work with. +``read_frame(index)`` reads the frame at the zero-based index across the raw +subfiles and advances the position to ``index + 1``. A subsequent +``read_frame()`` reads the following frame, including across subfile boundaries. + .. code:: python import aare @@ -22,4 +26,4 @@ data into a format that the user can work with. :members: :undoc-members: :show-inheritance: - :inherited-members: \ No newline at end of file + :inherited-members: diff --git a/python/tests/test_CtbRawFile.py b/python/tests/test_CtbRawFile.py new file mode 100644 index 00000000..6485b076 --- /dev/null +++ b/python/tests/test_CtbRawFile.py @@ -0,0 +1,58 @@ + + +import pytest +import numpy as np +from aare import CtbRawFile + + +@pytest.mark.withdata +def test_basic_properites(test_data_path): + f = CtbRawFile(test_data_path/'raw/ctb/run_master_0.json') + assert f.total_frames == 47 + assert f.image_size_in_bytes == 640 + assert f.master.analog_samples == 10 + assert f.master.digital_samples is None + assert f.master.transceiver_samples is None + + +@pytest.mark.withdata +def test_seek_and_read(test_data_path): + f = CtbRawFile(test_data_path/'raw/ctb/run_master_0.json') + f.seek(0) + header, raw_data = f.read_frame() + assert header['frameNumber'] == 48 #we know that the first frame in this file is 48 + + #Seek a multiple of frames in file + f.seek(9) + header, raw_data = f.read_frame() + assert header['frameNumber'] == 57 + +@pytest.mark.withdata +def test_read_all_frames_direct_and_iterate(test_data_path): + """ + We want to make sure that iterating and reading give the same result. + """ + f0 = CtbRawFile(test_data_path/'raw/ctb/run_master_0.json') + f1 = CtbRawFile(test_data_path/'raw/ctb/run_master_0.json') + + for h0, d0 in f0: + h1, d1 = f1.read_frame() + assert h0 == h1 + assert np.all(d0 == d1) + +@pytest.mark.withdata +def test_read_all_frames_with_index_and_iterate(test_data_path): + """ + We want to make sure that iterating and reading give the same result. + """ + f0 = CtbRawFile(test_data_path/'raw/ctb/run_master_0.json') + f1 = CtbRawFile(test_data_path/'raw/ctb/run_master_0.json') + + frames_read = 0 + for i,(h0, d0) in enumerate(f0): + h1, d1 = f1.read_frame(i) + assert h0 == h1 + assert np.all(d0 == d1) + frames_read += 1 + + assert frames_read == f0.total_frames diff --git a/src/CtbRawFile.cpp b/src/CtbRawFile.cpp index 260ab668..e4d0b958 100644 --- a/src/CtbRawFile.cpp +++ b/src/CtbRawFile.cpp @@ -24,9 +24,9 @@ void CtbRawFile::read_into(std::byte *image_buf, DetectorHeader *header) { throw std::runtime_error(LOCATION + " End of file reached"); } - if (m_current_frame != 0 && - m_current_frame % m_master.max_frames_per_file() == 0) { - open_data_file(m_current_subfile + 1); + const auto index = sub_file_index(m_current_frame); + if (index != m_current_subfile) { + open_data_file(index); } if (header) { @@ -79,4 +79,4 @@ void CtbRawFile::open_data_file(size_t subfile_index) { } } -} // namespace aare \ No newline at end of file +} // namespace aare