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:

  1. Undifferentiated — no per-point object identity. All points in a chunk form a single vertex group. No object_index.

  2. Per-point objects — each point is its own object (e.g. cell centroids). One vertex group per point per chunk. Object index maps point ID → (chunk, vg_index).

  3. Multi-point objects — many points per object (e.g. transcript spots grouped into cells). Points sharing an object_id are stored in one vertex group 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.

  • attribute_filter (dict[str, Any] | None)

  • backend (str | None)

Returns:

  • positions: (M, D) array of vertex positions

  • attributes: {name: array} of per-vertex attributes

  • object_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, groups=None, group_attributes=None, dtype='float32', backend=None, chunk_by_attribute=None, out_of_bounds='raise', 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 deprecated attributes kwarg.)

  • 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}.

  • 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.

  • bounds (tuple[list[float], list[float]] | None)

  • backend (str | None)

  • attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None)

Returns:

Summary dict.

Return type:

dict[str, Any]

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 vertex groups 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:
Returns:

  • endpoints: (M, 2, D) array of line endpoints

  • line_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', 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; replaces attributes.)

  • object_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None) – Per-line (per-object) attributes as {name: (N,) or (N, C)}. (Spec name; replaces line_attributes.)

  • dtype (str) – Numpy dtype string for positions.

  • bin_shape (tuple[float, ...] | None)

  • bounds (tuple[list[float], list[float]] | None)

  • backend (str | None)

  • chunk_by_attribute (str | None)

  • out_of_bounds (str)

  • 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:

dict[str, Any]

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), chunks crops at the segment level: only vertex groups 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 output polyline_count can exceed the input object_count. AND-ed with bbox when 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.

  • attribute_filter (dict[str, Any] | None)

  • 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, groups=None, group_attributes=None, dtype='float32', geometry_type='streamline', backend=None, chunk_by_attribute=None, out_of_bounds='raise')[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.

  • 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".

  • bin_shape (tuple[float, ...] | None)

  • bounds (tuple[list[float], list[float]] | None)

  • backend (str | None)

  • chunk_by_attribute (str | None)

  • out_of_bounds (str)

Returns:

Summary dict.

Return type:

dict[str, Any]

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) and cross_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.

  • object_ids (list[int] | None) – Optional object ID filter.

  • 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 bbox and object_ids. Edges spanning a listed chunk and an unlisted chunk are dropped. chunks=[] yields an empty result; chunks=None (default) applies no filter.

  • attribute_filter (dict[str, Any] | None)

  • backend (str | None)

Returns:

  • positions: (N, D) node positions

  • edges: (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, object_ids=None, dtype='float32', backend=None, chunk_by_attribute=None, out_of_bounds='raise', 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 boolean is_tree kwarg.

  • vertex_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None) – Per-node attributes {name: (N,) or (N,C)}. (Spec name; replaces node_attributes.)

  • link_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None) – Per-edge attributes {name: (M,) or (M,C)}. (Spec name; replaces edge_attributes.)

  • 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.

  • bin_shape (tuple[float, ...] | None)

  • bounds (tuple[list[float], list[float]] | None)

  • object_attributes (dict[str, ndarray[tuple[Any, ...], dtype[_ScalarT]]] | None)

  • backend (str | None)

  • chunk_by_attribute (str | None)

  • out_of_bounds (str)

  • 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:

dict[str, Any]

Meshes

Mesh I/O for zarr vectors stores.

Supports two encoding modes:

  • Raw: vertex positions in vertices/, face indices in links/ (L=3 for triangles, L=4 for quads). Faces spanning chunk boundaries go into cross_chunk_links/.

  • Draco: each vertex group 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.

  • object_ids (list[int] | None) – Optional object ID filter.

  • chunks (list[tuple[int, ...]] | None) – Optional whitelist of chunk coordinate tuples; only data in those chunks is returned. AND-ed with bbox and object_ids. chunks=[] yields an empty result; chunks=None (default) applies no chunk filter.

  • attribute_filter (dict[str, Any] | None)

  • backend (str | None)

Returns:

  • vertices: (V, D) positions

  • faces: (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')[source]

Write a mesh to a new zarr vectors store.

Parameters:
Returns:

Summary dict.

Return type:

dict[str, Any]

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), ...] where factors[i] is applied to produce level i+1 from level i. Either factor at 1.0 opts 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:
  • store_path (str | Path) – Path to the store with level 0.

  • 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_shape to derive each target level’s chunk_shape. Aligned with factors (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 root chunk_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 ±N per pair (or +N only when cross_level_storage='implicit'), -1 = walk all available level pairs. Default 1.

  • 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:

dict[str, Any]

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:
  • store_path (str | Path) – Path to the zarr vectors store.

  • 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.0 is the identity (no aggregation).

  • sparsity_factor (float) – Object-dropping factor (≥ 1). Survivors keep their OIDs; dropped objects leave empty manifest slots. 1.0 is the identity (no drop).

  • chunk_scale_factor (int | tuple[int, ...]) – Per-axis multiplier applied to the source level’s chunk_shape to derive the target level’s chunk_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’s LevelMetadata.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_pyramid this is threaded through to enable inline ±1 cross-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:

dict[str, Any]

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 the bin_shape instead.

  • 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:

ndarray[tuple[Any, …], dtype[int64]]

zarr_vectors.multiresolution.object_selection.compute_polyline_lengths(polylines)[source]

Compute Euclidean path length for each polyline.

Parameters:

polylines (list[ndarray[tuple[Any, ...], dtype[floating]]]) – List of (N_k, D) arrays.

Returns:

(N,) float64 array of path lengths.

Return type:

ndarray[tuple[Any, …], dtype[float64]]

zarr_vectors.multiresolution.object_selection.compute_representative_points(polylines)[source]

Compute the midpoint of each polyline (representative point).

Parameters:

polylines (list[ndarray[tuple[Any, ...], dtype[floating]]]) – List of (N_k, D) arrays.

Returns:

(N, D) array of midpoints.

Return type:

ndarray[tuple[Any, …], dtype[floating]]

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:
  • attribute_values (ndarray[tuple[Any, ...], dtype[floating]]) – (N,) array of per-object values.

  • target_count (int) – Number of objects to keep.

  • mode (str) – "max" keeps highest values, "min" keeps lowest.

Returns:

(target_count,) sorted array of kept object indices.

Raises:

ValueError – If mode is not "max" or "min".

Return type:

ndarray[tuple[Any, …], dtype[int64]]

zarr_vectors.multiresolution.object_selection.select_by_length(lengths, target_count)[source]

Select objects with the greatest lengths.

For streamlines, length is the sum of segment Euclidean distances. For graphs, total edge length. For any geometry, a scalar measure of object size.

Parameters:
Returns:

(target_count,) sorted array of kept object indices.

Return type:

ndarray[tuple[Any, …], dtype[int64]]

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_count budget across bins proportional to each bin’s object density, ensuring every occupied bin keeps at least one representative.

Parameters:
  • representative_points (ndarray[tuple[Any, ...], dtype[floating]]) – (N, D) — one point per object.

  • bin_shape (tuple[float, ...] | float) – Spatial bin edge lengths for coverage assessment.

  • target_count (int) – Number of objects to keep.

Returns:

(target_count,) sorted array of kept object indices.

Raises:

ValueError – If target_count is invalid.

Return type:

ndarray[tuple[Any, …], dtype[int64]]

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 fixed target_count budget 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:

ndarray[tuple[Any, …], dtype[int64]]

zarr_vectors.multiresolution.object_selection.select_random(n_objects, target_count, *, seed=None)[source]

Select objects uniformly at random.

Reproducible with a fixed seed.

Parameters:
  • n_objects (int) – Total number of objects.

  • target_count (int) – Number to keep.

  • seed (int | None) – Random seed for reproducibility.

Returns:

(target_count,) sorted array of kept object indices.

Return type:

ndarray[tuple[Any, …], dtype[int64]]