Geometry types¶
Read and write functions for each ZVF geometry type. All write functions
accept either a local path string, a zarr.storage.Store object, or
an fsspec mapper as the first argument. All read functions return a typed
result dictionary documented on each function’s page.
Point clouds¶
Point cloud I/O for ZV (Zarr Vectors) stores.
Supports three point cloud variants:
Undifferentiated — no per-point object identity. All points in a chunk form a single fragment. No object_index.
Per-point objects — each point is its own object (e.g. cell centroids). One fragment per point per chunk. Object index maps point ID → (chunk, fragment_index).
Multi-point objects — many points per object (e.g. transcript spots grouped into cells). Points sharing an object_id are stored in one fragment per chunk. Object index maps object → chunks.
- zarr_vectors.types.points.read_points(store_path, *, level=0, bbox=None, object_ids=None, group_ids=None, chunks=None, attribute_names=None, attribute_filter=None, backend=None)[source]¶
Read point cloud data from a ZV store.
Supports filtering by bounding box, object ID, group ID, or chunk whitelist. Filters AND together — every filter that is supplied must accept a point for it to appear in the output.
- Parameters:
store_path (str) – Path to the ZV store.
level (int) – Resolution level to read (default 0).
bbox (tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]] | None) – Optional bounding box filter as
(min_corner, max_corner).object_ids (list[int] | None) – Optional list of object IDs to read.
group_ids (list[int] | None) – Optional list of group IDs — expands to their object IDs.
chunks (list[tuple[int, ...]] | None) – Optional whitelist of chunk coordinate tuples; only data in those chunks is returned.
chunks=[]yields an empty result;chunks=None(default) applies no chunk filter.attribute_names (list[str] | None) – Optional list of attribute names to read. If None, reads all available attributes.
backend (str | None)
- Returns:
positions:(M, D)array of vertex positionsattributes:{name: array}of per-vertex attributesobject_ids:(M,)array of object IDs per vertex (if objects exist)vertex_count: total vertices returned
- Return type:
Dict with keys
- zarr_vectors.types.points.write_points(store_path, positions, *, chunk_shape=None, bin_shape=None, bounds=None, vertex_attributes=None, object_ids=None, object_attributes=None, fragment_attributes=None, groups=None, group_attributes=None, dtype='float32', backend=None, chunk_by_attribute=None, out_of_bounds='raise', compressor=None, shard_shape=None, attributes=None)[source]¶
Write a point cloud to a new ZV store.
- Parameters:
store_path (str) – Path for the new store (must not exist).
positions (ndarray[tuple[Any, ...], dtype[floating]]) –
(N, D)vertex positions.chunk_shape (tuple[float, ...] | None) – Spatial chunk size per dimension. If None, a single chunk containing all points is used.
bin_shape (tuple[float, ...] | None) – Supervoxel bin edge lengths. If None, defaults to
chunk_shape(one bin per chunk — backward compatible).vertex_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None) – Per-vertex attributes
{name: array}. (Spec name; replaces the deprecatedattributeskwarg.)object_ids (ndarray[tuple[Any, ...], dtype[integer]] | None) –
(N,)integer per-point object assignment.object_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None) – Per-object attributes
{name: array}.fragment_attributes (dict[str, dict[tuple[int, ...], ndarray[tuple[Any, ...], dtype[_ScalarT]]]] | None) – Per-fragment attributes, keyed per chunk:
{name: {chunk_coords: ndarray}}. Each per-chunk ndarray has shape(num_fragments_in_chunk,)or(num_fragments_in_chunk, C)and is aligned with the fragment ordering this writer produces for that chunk. Use case (opt-in): materialize per-fragment parent-IDs (e.g. the OID owning each fragment asobject_id).groups (dict[int, list[int]] | None) – Group memberships
{group_id: [object_id, ...]}.group_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None) – Per-group attributes
{name: array}.dtype (str) – Numpy dtype string for vertex positions.
chunk_by_attribute (str | None) – If set, the named per-vertex categorical attribute (which must appear in
vertex_attributes) becomes the leading chunk axis. Chunk keys gain a prefix, e.g.gene_bin.z.y.x. Vertices with mixed values within the same object are split across multiple attribute chunks. v1 supports integer / string dtypes only.out_of_bounds (str) – Policy for vertices outside the store’s current
bounds."raise"(default) rejects the write,"ignore"drops out-of-bounds vertices (and their aligned per-vertex data),"expand"grows the store’s bounds to include all input vertices.backend (str | None)
compressor (Any)
attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None)
- Returns:
Summary dict.
- Return type:
Lines¶
Finite line and vector I/O for zarr vectors stores.
A finite line is two endpoints stored as a two-vertex object.
Connectivity is implicit sequential (vertex 0 → vertex 1), so no
links array is needed.
Lines that cross a chunk boundary are split into two single-vertex
fragments in their respective chunks, with the object_index
tracking both and a cross_chunk_links entry bridging them.
- zarr_vectors.types.lines.read_lines(store_path, *, level=0, object_ids=None, bbox=None, attribute_filter=None, backend=None)[source]¶
Read finite lines from a zarr vectors store.
- Parameters:
store_path (str) – Path to the store.
level (int) – Resolution level.
object_ids (list[int] | None) – Optional list of line (object) IDs to read.
bbox (tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]] | None) – Optional bounding box filter (lines with any endpoint inside the box are returned).
backend (str | None)
- Returns:
endpoints:(M, 2, D)array of line endpointsline_count: number of lines returned
- Return type:
Dict with
- zarr_vectors.types.lines.write_lines(store_path, endpoints, *, chunk_shape, bin_shape=None, bounds=None, vertex_attributes=None, object_attributes=None, dtype='float32', backend=None, chunk_by_attribute=None, out_of_bounds='raise', compressor=None, shard_shape=None, attributes=None, line_attributes=None)[source]¶
Write finite line segments to a new zarr vectors store.
- Parameters:
store_path (str) – Path for the new store.
endpoints (ndarray[tuple[Any, ...], dtype[floating]]) –
(N, 2, D)array — N lines, each with 2 endpoints of D dimensions.chunk_shape (tuple[float, ...]) – Spatial chunk size per dimension.
vertex_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None) – Per-vertex attributes as
{name: (N, 2) or (N, 2, C)}. Two values per line (one per endpoint). (Spec name; replacesattributes.)object_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None) – Per-line (per-object) attributes as
{name: (N,) or (N, C)}. (Spec name; replacesline_attributes.)dtype (str) – Numpy dtype string for positions.
backend (str | None)
chunk_by_attribute (str | None)
out_of_bounds (str)
compressor (Any)
attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None)
line_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None)
- Returns:
Summary dict with
line_count,chunk_count,cross_chunk_count.- Return type:
Polylines and streamlines¶
Polyline and streamline I/O for zarr vectors stores.
A polyline is an ordered sequence of vertices forming a connected path. Streamlines (from tractography) are polylines with additional per-object attributes like termination regions.
Polylines that cross chunk boundaries are split into segments. The
object_index stores the ordered segment sequence for each polyline,
and cross_chunk_links connects the last vertex of one segment to
the first vertex of the next. Within each segment, connectivity is
implicit sequential (vertex i → vertex i+1).
- zarr_vectors.types.polylines.read_polylines(store_path, *, level=0, object_ids=None, group_ids=None, bbox=None, chunks=None, attribute_filter=None, backend=None)[source]¶
Read polylines/streamlines from a zarr vectors store.
- Parameters:
store_path (str) – Path to the store.
level (int) – Resolution level.
object_ids (list[int] | None) – Optional list of polyline (object) IDs.
group_ids (list[int] | None) – Optional group IDs — expands to their object IDs.
bbox (tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]] | None) – Optional bounding box filter. Returns polylines that have at least one segment in a matching chunk.
chunks (list[tuple[int, ...]] | None) – Optional whitelist of chunk coordinate tuples. Unlike
bbox(which keeps the whole polyline if any segment matches),chunkscrops at the segment level: only fragments stored in listed chunks are returned, and each surviving contiguous run becomes its own output polyline. A polyline whose middle segments lie in unlisted chunks may therefore appear in the result as multiple shorter polylines — the outputpolyline_countcan exceed the inputobject_count. AND-ed withbboxwhen both are given (the effective whitelist is the intersection of the two chunk sets).chunks=[]yields an empty result;chunks=None(default) applies no chunk filter.backend (str | None)
- Returns:
polylines: list of lists of arrays.polylines[i]is a list of segment arrays for polyline i (concatenate for full path).polyline_count: number of polylines returned.vertex_count: total vertices across all returned polylines.
- Return type:
Dict with
- zarr_vectors.types.polylines.write_polylines(store_path, polylines, *, chunk_shape, bin_shape=None, bounds=None, vertex_attributes=None, object_attributes=None, fragment_attributes=None, groups=None, group_attributes=None, dtype='float32', geometry_type='streamline', backend=None, chunk_by_attribute=None, out_of_bounds='raise', compressor=None, shard_shape=None)[source]¶
Write polylines/streamlines to a new zarr vectors store.
- Parameters:
store_path (str) – Path for the new store.
polylines (list[ndarray[tuple[Any, ...], dtype[floating]]]) – List of arrays, each
(N_k, D)— one per polyline.chunk_shape (tuple[float, ...]) – Spatial chunk size per dimension.
vertex_attributes (dict[str, list[ndarray[tuple[Any, ...], dtype[_ScalarT]]]] | None) – Per-vertex attributes aligned with polylines.
{name: [array_for_polyline_0, array_for_polyline_1, ...]}where each array is(N_k,)or(N_k, C).object_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None) – Per-polyline attributes.
{name: (O,) or (O, C)}where O = number of polylines.fragment_attributes (dict[str, dict[tuple[int, ...], ndarray[tuple[Any, ...], dtype[_ScalarT]]]] | None) – Per-fragment attributes, keyed per chunk:
{name: {chunk_coords: ndarray}}. Each per-chunk ndarray has shape(num_fragments_in_chunk,)or(num_fragments_in_chunk, C)and is aligned with the fragment ordering this writer produces for that chunk.groups (dict[int, list[int]] | None) – Group memberships
{group_id: [polyline_indices]}.group_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None) – Per-group attributes
{name: (G,) or (G,C)}.dtype (str) – Numpy dtype for positions.
geometry_type (str) –
"streamline"or"polyline".backend (str | None)
chunk_by_attribute (str | None)
out_of_bounds (str)
compressor (Any)
- Returns:
Summary dict.
- Return type:
Graphs and skeletons¶
Graph and skeleton I/O for zarr vectors stores.
Supports two modes:
General graph: arbitrary undirected/directed edges. All edges stored explicitly in
links/(intra-chunk) andcross_chunk_links/(inter-chunk).links_convention: "explicit".Skeleton (tree): nodes reordered depth-first, parent links mostly sequential. Only branch points (parent ≠ i−1) stored in
links/.links_convention: "implicit_sequential_with_branches".
Edge attributes (weight, type, etc.) are stored in link_attributes/
parallel to the links/ array.
- zarr_vectors.types.graphs.read_graph(store_path, *, level=0, object_ids=None, bbox=None, chunks=None, attribute_filter=None, backend=None)[source]¶
Read a graph or skeleton from a zarr vectors store.
- Parameters:
store_path (str) – Path to the store.
level (int) – Resolution level.
bbox (tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]] | None) – Optional bounding box filter.
chunks (list[tuple[int, ...]] | None) – Optional whitelist of chunk coordinate tuples; only nodes (and intra-chunk edges) in those chunks are returned. AND-ed with
bboxandobject_ids. Edges spanning a listed chunk and an unlisted chunk are dropped.chunks=[]yields an empty result;chunks=None(default) applies no filter.backend (str | None)
- Returns:
positions:(N, D)node positionsedges:(M, 2)edge list (remapped to output indices)node_count,edge_count
- Return type:
Dict with
- zarr_vectors.types.graphs.write_graph(store_path, positions, edges, *, chunk_shape, bin_shape=None, bounds=None, kind='graph', vertex_attributes=None, link_attributes=None, object_attributes=None, fragment_attributes=None, object_ids=None, dtype='float32', backend=None, chunk_by_attribute=None, out_of_bounds='raise', compressor=None, shard_shape=None, is_tree=None, node_attributes=None, edge_attributes=None)[source]¶
Write a graph or skeleton to a new zarr vectors store.
- Parameters:
store_path (str) – Path for the new store.
positions (ndarray[tuple[Any, ...], dtype[floating]]) –
(N, D)node positions.edges (ndarray[tuple[Any, ...], dtype[integer]]) –
(M, 2)edge list (global vertex indices).chunk_shape (tuple[float, ...]) – Spatial chunk size per dimension.
kind (str) –
"graph"(default — general graph, explicit links convention) or"skeleton"(depth-first reorder, implicit sequential with branches convention). Replaces the booleanis_treekwarg.vertex_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None) – Per-node attributes
{name: (N,) or (N,C)}. (Spec name; replacesnode_attributes.)link_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None) – Per-edge attributes
{name: (M,) or (M,C)}. (Spec name; replacesedge_attributes.)fragment_attributes (dict[str, dict[tuple[int, ...], ndarray[tuple[Any, ...], dtype[_ScalarT]]]] | None) – Per-fragment attributes, keyed per chunk:
{name: {chunk_coords: ndarray}}. Each per-chunk ndarray has shape(num_fragments_in_chunk,)or(num_fragments_in_chunk, C)and is aligned with the fragment ordering this writer produces for that chunk.object_ids (ndarray[tuple[Any, ...], dtype[integer]] | None) –
(N,)array assigning nodes to objects. If None, all nodes belong to object 0.dtype (str) – Numpy dtype for positions.
object_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None)
backend (str | None)
chunk_by_attribute (str | None)
out_of_bounds (str)
compressor (Any)
is_tree (bool | None)
node_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None)
edge_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None)
- Returns:
Summary dict.
- Return type:
Meshes¶
Mesh I/O for zarr vectors stores.
Supports two encoding modes:
Raw: vertex positions in
vertices/, face indices inlinks/(L=3 for triangles, L=4 for quads). Faces spanning chunk boundaries go intocross_chunk_links/.Draco: each fragment is encoded as a Draco bitstream containing both positions and faces.
links/may be omitted.
- zarr_vectors.types.meshes.read_mesh(store_path, *, level=0, bbox=None, object_ids=None, chunks=None, attribute_filter=None, backend=None)[source]¶
Read a mesh from a zarr vectors store.
- Parameters:
store_path (str) – Path to the store.
level (int) – Resolution level.
bbox (tuple[ndarray[tuple[Any, ...], dtype[floating]], ndarray[tuple[Any, ...], dtype[floating]]] | None) – Optional bounding box filter.
chunks (list[tuple[int, ...]] | None) – Optional whitelist of chunk coordinate tuples; only data in those chunks is returned. AND-ed with
bboxandobject_ids.chunks=[]yields an empty result;chunks=None(default) applies no chunk filter.backend (str | None)
- Returns:
vertices:(V, D)positionsfaces:(F, L)face indices (remapped to output vertex order)vertex_count,face_count
- Return type:
Dict with
- zarr_vectors.types.meshes.write_mesh(store_path, vertices, faces, *, chunk_shape, bin_shape=None, bounds=None, encoding='raw', vertex_attributes=None, object_attributes=None, object_ids=None, dtype='float32', draco_quantization_bits=11, backend=None, chunk_by_attribute=None, out_of_bounds='raise', compressor=None, shard_shape=None)[source]¶
Write a mesh to a new zarr vectors store.
- Parameters:
store_path (str) – Path for the new store.
vertices (ndarray[tuple[Any, ...], dtype[floating]]) –
(V, D)vertex positions.faces (ndarray[tuple[Any, ...], dtype[integer]]) –
(F, L)face index array (L=3 triangles, L=4 quads).chunk_shape (tuple[float, ...]) – Spatial chunk size per dimension.
encoding (str) –
"raw"or"draco".vertex_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None) – Per-vertex attributes
{name: (V,) or (V,C)}.object_ids (ndarray[tuple[Any, ...], dtype[integer]] | None) –
(V,)array assigning vertices to mesh objects. If None, all vertices belong to object 0.dtype (str) – Numpy dtype for positions.
draco_quantization_bits (int) – For Draco encoding only.
object_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None)
backend (str | None)
chunk_by_attribute (str | None)
out_of_bounds (str)
compressor (Any)
- Returns:
Summary dict.
- Return type:
Multi-resolution coarsening¶
Multi-resolution pyramid construction orchestrator.
Two entry points (use one):
build_pyramid(store, factors=[(cf_1, sf_1), ...])builds every coarser level in sequence, optionally emitting cross-level link arrays (cross_level_storage="implicit"or"explicit").coarsen_level(store, source, target, coarsen_factor=..., sparsity_factor=...)writes a single coarser level for callers that want manual control.
Both use the per-object pyramid: each surviving object’s vertices are aggregated into bin centroids (metavertices) that may be shared between objects, and per-object OIDs are preserved across levels.
- zarr_vectors.multiresolution.coarsen.build_pyramid(store_path, *, factors, chunk_scale_factors=None, sparsity_strategy='random', sparsity_seed=None, cross_level_depth=1, cross_level_storage='explicit')[source]¶
Build a multi-resolution pyramid for an existing store.
Pass
factors=[(coarsen_2, sparsity_3), ...]wherefactors[i]is applied to produce leveli+1from leveli. Either factor at1.0opts out of that axis. Uses the per-object pyramid: each surviving object’s vertices are aggregated into bin centroids (metavertices); metavertices may be shared between objects and OIDs are preserved across levels.- Parameters:
factors (list[tuple[float, float]]) – List of
(coarsen_factor, sparsity_factor)tuples, one per coarser level.chunk_scale_factors (list[int | tuple[int, ...]] | None) – Optional per-level multipliers applied to the source level’s
chunk_shapeto derive each target level’schunk_shape. Aligned withfactors(same length). Each entry is either a scalar int (uniform per axis) or a per-axis tuple.None(default) means all-ones: every level inherits rootchunk_shape.sparsity_strategy (str) – Object selection strategy.
sparsity_seed (int | None) – Random seed.
cross_level_depth (int) – Maximum absolute level delta for materialized cross-pyramid-level link arrays.
0= none,N= up to±Nper pair (or+Nonly whencross_level_storage='implicit'),-1= walk all available level pairs. Default1.cross_level_storage (str) –
"none"/"implicit"/"explicit"."explicit"materializes both+N(at the finer level) and-N(at the coarser level);"implicit"writes only+N. Default"explicit".
- Returns:
Summary dict.
- Return type:
- zarr_vectors.multiresolution.coarsen.coarsen_level(store_path, source_level, target_level, *, coarsen_factor=1.0, sparsity_factor=1.0, chunk_scale_factor=1, sparsity_strategy='random', sparsity_seed=None, cross_level_storage='none')[source]¶
Coarsen a single level and write it to the store.
Per-object vertex aggregation with stable OIDs across levels. A metavertex’s source vertices may come from multiple source objects; the resulting metavertex appears in each of those objects’ manifests at the coarser level.
- Parameters:
source_level (int) – Level to read from.
target_level (int) – Level to write to (must not exist).
coarsen_factor (float) – Per-object vertex aggregation factor (≥ 1).
1.0is the identity (no aggregation).sparsity_factor (float) – Object-dropping factor (≥ 1). Survivors keep their OIDs; dropped objects leave empty manifest slots.
1.0is the identity (no drop).chunk_scale_factor (int | tuple[int, ...]) – Per-axis multiplier applied to the source level’s
chunk_shapeto derive the target level’schunk_shape.1(default) keeps the chunk grid unchanged. Scalar values apply uniformly to every axis; tuples set per-axis multipliers. Each multiplier must be a positive integer (nested chunk grids). When the resulting target chunk_shape differs from the root chunk_shape it is stamped on the target level’sLevelMetadata.chunk_shape; otherwise the target inherits from root.sparsity_strategy (str) – Object selection strategy.
sparsity_seed (int | None) – Random seed.
cross_level_storage (str) – When called via
build_pyramidthis is threaded through to enable inline±1cross-level link emission. Standalone callers should leave it at the"none"default.
- Returns:
Summary dict. Always includes
method,preserves_object_ids,vertex_count.- Return type:
Object selection strategies for multi-resolution sparsity.
Each strategy selects a subset of objects to retain at a coarser
resolution level. All functions return kept_indices — an array
of integer indices into the original object list.
Four strategies:
Spatial coverage: greedy selection maximising spatial spread
Length: keep the longest objects (streamlines, skeletons)
Attribute: keep objects with highest/lowest attribute values
Random: uniform random selection (reproducible with seed)
- zarr_vectors.multiresolution.object_selection.apply_sparsity(n_objects, sparsity, strategy='random', *, seed=None, lengths=None, attribute_values=None, attribute_mode='max', representative_points=None, bin_shape=None)[source]¶
Convenience wrapper: compute target count from sparsity and dispatch.
- Parameters:
n_objects (int) – Total number of objects.
sparsity (float) – Fraction to keep, in (0, 1]. Ignored by the
"point_thinning"strategy, which derives the survivor count from thebin_shapeinstead.strategy (str) – One of
"random","length","attribute","spatial_coverage","point_thinning".seed (int | None) – Random seed (for
"random"/"point_thinning").lengths (ndarray[tuple[Any, ...], dtype[_ScalarT]] | None) – Per-object lengths (for
"length"strategy).attribute_values (ndarray[tuple[Any, ...], dtype[_ScalarT]] | None) – Per-object values (for
"attribute"strategy).attribute_mode (str) –
"max"or"min"(for"attribute").representative_points (ndarray[tuple[Any, ...], dtype[_ScalarT]] | None) –
(N, D)points (for"spatial_coverage"and"point_thinning").bin_shape (tuple[float, ...] | float | None) – Bin shape for spatial coverage / point thinning.
- Returns:
Sorted array of kept object indices.
- Raises:
ValueError – If required data for the strategy is missing.
- Return type:
- zarr_vectors.multiresolution.object_selection.compute_polyline_lengths(polylines)[source]¶
Compute Euclidean path length for each polyline.
- zarr_vectors.multiresolution.object_selection.compute_representative_points(polylines)[source]¶
Compute the midpoint of each polyline (representative point).
- zarr_vectors.multiresolution.object_selection.select_by_attribute(attribute_values, target_count, *, mode='max')[source]¶
Select objects with the highest or lowest attribute values.
Generic selection by any scalar per-object attribute (FA, volume, importance score, etc.).
- Parameters:
- Returns:
(target_count,)sorted array of kept object indices.- Raises:
ValueError – If mode is not
"max"or"min".- Return type:
- zarr_vectors.multiresolution.object_selection.select_by_length(lengths, target_count)[source]¶
Select objects with the greatest lengths.
For streamlines,
lengthis the sum of segment Euclidean distances. For graphs, total edge length. For any geometry, a scalar measure of object size.
- zarr_vectors.multiresolution.object_selection.select_by_spatial_coverage(representative_points, bin_shape, target_count)[source]¶
Select objects that maximise spatial coverage.
Assigns each object to a spatial bin by its representative point (e.g. midpoint for polylines, centroid for meshes). Distributes the
target_countbudget across bins proportional to each bin’s object density, ensuring every occupied bin keeps at least one representative.- Parameters:
- Returns:
(target_count,)sorted array of kept object indices.- Raises:
ValueError – If target_count is invalid.
- Return type:
- zarr_vectors.multiresolution.object_selection.select_point_thinning(positions, bin_shape, *, seed=None)[source]¶
Spatially-aware point thinning: ≤1 point retained per spatial bin.
Distinct from
select_by_spatial_coverage(): that function distributes a fixedtarget_countbudget proportionally to each bin’s density; this one enforces a max of one survivor per bin and the resulting count is determined by the bin layout (≤ number of occupied bins). Useful for point-cloud levels where the goal is uniform density, not a target object count.- Parameters:
positions (ndarray[tuple[Any, ...], dtype[floating]]) –
(N, D)point positions.bin_shape (tuple[float, ...] | float) – Spatial bin edge lengths. Larger bins → fewer survivors.
seed (int | None) – Optional seed for selecting the survivor when a bin contains multiple candidates. When
None, the lowest-index candidate is kept (deterministic).
- Returns:
Sorted array of kept point indices, one per occupied bin.
- Return type: