Improved ClusterFile API (#358)
Build on RHEL9 / build (push) Successful in 2m49s
Build on RHEL8 / build (push) Successful in 3m23s
Run tests using data on local RHEL8 / build (push) Successful in 4m23s
Build on local RHEL8 / build (push) Successful in 3m5s

Improved API for ClusterFile

- read_frame now returns a std::optional<ClusterVector> to differentiate
between an empty frame and end of file
- f.frames() produces an iterator over frames
- f.chunks() produces an iterator reading chunks of clusters
This commit is contained in:
Erik Fröjdh authored and GitHub committed 2026-09-14 16:01:25 +02:00
1 parent 86db375948
commit b0875106e3
16 files changed
+1687 -308

No files matched your search

+63 -11
View File
@@ -1,26 +1,78 @@
ClusterFile
============
===========
The :func:`ClusterFile` factory is the main interface for reading and writing
cluster files. Use ``mode="r"`` to read, ``mode="w"`` to truncate and
write, or ``mode="a"`` to append.
The :class:`ClusterFile` class is the main interface to read and write clusters in aare. Unfortunately the
old file format does not include metadata like the cluster size and the data type. This means that the
user has to know this information from other sources. Specifying the wrong cluster size or data type
will lead to garbage data being read.
The format does not store the cluster dimensions, value type, coordinate type,
padding, or byte order. The ``cluster_size`` and ``dtype`` arguments must match
the writer; otherwise the bytes are interpreted incorrectly.
Use ``frames()`` when frame boundaries and the frame number matter:
.. code-block:: python
with ClusterFile("clusters.clust") as file:
for frame in file.frames():
print(frame.frame_number, frame.size)
Each stored frame is yielded, including empty frames and frames whose clusters
are all rejected by filtering. Missing frame numbers are not synthesized.
The explicit ``read_frame()`` method returns one frame or ``None`` at EOF.
Use ``chunks()`` to iterate over chunks of ``chunk_size`` clusters. Per default
the chunk size defined in the constructor is used. Alternatively one can pass
an explicit chunk size to the function for that specific traversal:
.. code-block:: python
with ClusterFile("clusters.clust", chunk_size=1000) as file:
for clusters in file.chunks(10000):
process(clusters)
Chunk sizes must be positive and count selected clusters after filtering.
``file.chunks(10000)`` does not overwrite the constructor argument ``chunk_size``
. Iterating directly
over ``file`` or calling ``next(file)`` still reads chunks using that default.
Chunks and ``read_clusters(n_clusters)`` may split or combine frames, so their
frame numbers are not reliable per-cluster metadata. Empty chunks are not
yielded.
Chunk reads and iteration raise an error if they encounter an incomplete frame
header or cluster record, including when ROI or noise filtering is enabled.
They return fewer clusters than requested only at a clean end of file.
Both iterators consume the current file position without rewinding. Creating
an iterator does not read; each ``next()`` reads one result without prefetching
the following result. Use one traversal at a time and separate readers for
independent cursors. Switching to frames after a chunk stops partway through a
frame raises an error until the remaining clusters in that frame have been
read. Exhausted iterators continue to raise ``StopIteration``.
Iterators keep their file object alive, but explicitly closing the file or
leaving its ``with`` block prevents further reads. Every yielded
``ClusterVector`` owns its storage and can be retained after iteration advances
or the file closes. NumPy views also remain valid across those operations;
as usual, resizing or modifying the allocation of their backing vector can
invalidate them.
When a gain map is configured, it is applied to every cluster whose complete
footprint lies inside the map. Clusters whose footprint extends beyond the
gain-map boundaries remain in the returned cluster vector, but all their data
values are set to zero.
.. py:currentmodule:: aare
.. autoclass:: ClusterFile
:members:
:undoc-members:
:inherited-members:
.. autofunction:: ClusterFile
Below is the API of the ClusterFile_Cluster3x3i but all variants share the same API.
Below is the API of ``ClusterFile_Cluster3x3i``; all compiled variants share the
same API.
.. autoclass:: aare._aare.ClusterFile_Cluster3x3i
:special-members: __init__
:members:
:undoc-members:
:show-inheritance:
:inherited-members:
:inherited-members: