neu_morpho.metrics_db¶
Per-body metrics database (SQLite).
One row per body, progressively enriched: the index scan fills bbox / voxel_count / volume; meshing and skeletonization update their columns. Bbox is in full-resolution voxels; consumers convert to their own scale.
Each block’s contribution and its “done” mark land in one transaction, so a crash cannot double-count a summed metric on resume. The driver is the sole writer.
Classes¶
Open the metrics DB. |
Module Contents¶
- class neu_morpho.metrics_db.MetricsDB(path: str, *, read_only: bool = False, busy_timeout_ms: int = 30000)¶
Open the metrics DB.
read_onlyopens it WITHOUT writing to it.A reader must not take a write lock: the default open runs DDL, which locks the DB and can kill a running sweep with
database is locked. Read-only tools passread_only=True, which skips the DDL and opens withmode=ro.A writer waits rather than fails:
busy_timeoutturns contention with a concurrent reader into a pause.- apply_compartment_block(block_key: str, counts) None¶
Merge one block’s
{(body_id, label): voxels}and mark it done, atomically.
- apply_counts_block(block_key: str, counts: Mapping[int, int], voxel_volume_nm3: float) None¶
Merge one block’s
{body_id: voxel_count}and mark it done, atomically.The bbox-free counterpart of
apply_index_block(), for the morphometry sweep, about 10x cheaper per dense block. Rows created here have NULL bbox and skeleton columns: this pass did not measure them.
- apply_index_block(block_key: str, partials: Mapping[int, tuple], voxel_volume_nm3: float) None¶
Merge one block’s {body_id: (z0,y0,x0,z1,y1,x1,count)} and mark it done, atomically.
bbox merges by min/max; voxel_count and volume accumulate. No-op if the block was already applied. A pre-existing row may have a NULL bbox (another stage created it), and SQLite’s
min(NULL, 5)isNULL, hence the explicit NULL check.
- apply_skel_batch(rows) None¶
Apply one batch of
(body_id, status, detail, columns)atomically.
- bodies_by_size(min_voxels: int = 0, limit: int | None = None) list[int]¶
- close() None¶
- commit() None¶
- compartment_counts() dict[int, int]¶
Total voxels per semantic label, across bodies.
- crop_at_scale(body_id: int, factor_zyx: Sequence[int], *, margin_vox: int = 0, clip_shape: Sequence[int] | None = None) tuple | None¶
A body’s bbox at a read scale, as (z0,y0,x0,z1,y1,x1) voxels (+ margin).
factor_zyx= full-res voxels per read-scale voxel.
- done_blocks() set[str]¶
- done_compartment_blocks() set[str]¶
- done_skel_bodies(*, include_failed: bool = False) set[int]¶
Bodies not worth attempting again.
Status is filtered, not tested for presence, so a recorded
failedis retried.absentis terminal: a body with no published skeleton will not grow one.
- done_sweep_blocks() set[str]¶
- get_bbox(body_id: int) tuple | None¶
- read_stage_meta() dict[str, dict]¶
- record_stage_meta(stage: str, *, total: int, block_shape=None, level: int | None = None, voxel_size=None, n_keep: int | None = None) None¶
Record a stage’s task total BEFORE dispatch. See the table comment.
- reset_compartments() set[str]¶
- reset_index() None¶
- reset_skel() set[int]¶
- reset_sweep() set[str]¶
- skel_counts() dict[str, int]¶
- stage_counts() dict[str, int]¶
Blocks completed per block-mapped stage.
- to_csv(path: str) None¶
- update_bodies(rows: Iterable[tuple[int, Mapping]]) int¶
Upsert many bodies in one transaction with one commit.
update_bodycommits per call; in a pipeline that is one fsync per body in the driver, the sole writer, while workers sit idle.
- update_body(body_id: int, **cols) None¶
Set enrichment columns for a body, inserting the row if it is new.
The values go in the INSERT as well as the DO UPDATE, so a body the index scan never saw is inserted with them.
- write_allowlist(path: str, min_voxels: int = 0, limit: int | None = None) int¶
- BLOCK_STAGES¶
- con¶
- read_only = False¶