neu_morpho.pipeline

The neu-morpho run pipeline as a library call: seg -> index -> allowlist -> mesh.

plan() validates the arguments against the source’s own pyramid and counts the blocks each stage will process; run() executes a plan, on a dask client or serially in this process. Starting the cluster is the caller’s, between the two, so a dry run never starts one:

p = pipeline.plan(src, dst, work_dir=work, roi=(0, 0, 0, 512, 2048, 2048), roi_scale=2)
summary = pipeline.run(p)               # serial; pass client= to run on dask

dst is the published volume (labels, with meshes and skeletons inside it) and may be an object store; work_dir is a filesystem path for the fragments, the metrics DB and the manifests.

Extra stages. Another package can add a stage that runs after mesh on the same plan: name it in plan(extra_stages={name: scale_index}), so its scale, ROI and block count are planned like the built-in ones, and pass run(runners={name: fn}). This is how neu-skel provides skeletons, which are not built here because the tracers are GPL-licensed; neu-skel run runs only its skel stage, in a work dir that neu-morpho run has indexed. Discovering an installed neu-skel from neu-morpho run itself (an entry point) is a possible later addition, deliberately not made: it would load GPL code into this package’s process.

Runs sharing a work dir. Each run is recorded in full in its own runs/<run id>/, and the work dir’s run_plan.json and run_summary.json show each stage’s latest run, so a work dir built by several commands (neu-morpho run --stages index,mesh, then neu-skel run, then a retry) keeps all of them (run_records).

Attributes

Classes

Plan

What run() will do. Built by plan(); every scale and ROI resolved.

Functions

ng_source(volume_dir) → str

The neuroglancer source URL for a volume — local paths need a file:// prefix.

plan(src, dst, *[, work_dir, stages, block, ...]) → Plan

Resolve and check a run against src's pyramid; logs the plan. Writes nothing.

run(p, *[, client, command, runners]) → dict

Execute p's stages; returns this run's summary.

Module Contents

class neu_morpho.pipeline.Plan

What run() will do. Built by plan(); every scale and ROI resolved.

allowlist: str | None
property allowlist_path: str
block: tuple[int, int, int]
property db_path: str | None
dst: str
extra: dict
finest: Any
limit_bodies: int | None
max_consecutive_failures: int
mesh_smoothing: int = 0
metrics_db: bool
min_voxels: int
occupancy_dilate: int
occupancy_scale: int | None
occupancy_spec: dict | None
occupancy_voxel_size: tuple | None
planned_blocks: dict[str, int]
resume: bool
roi: tuple | None
roi_scale: int | None
rois: dict[str, tuple | None]
scales: dict[str, Any]
seg_encoding: str
seg_scales: list[int] | None
src: str
stages: tuple[str, ...]
work_dir: str
neu_morpho.pipeline.ng_source(volume_dir: str) → str

The neuroglancer source URL for a volume — local paths need a file:// prefix.

neu_morpho.pipeline.plan(src: str, dst: str, *, work_dir: str | None = None, stages: Sequence[str] = DEFAULT_STAGES, block: Sequence[int] = (256, 256, 256), index_scale: int = 2, mesh_scale: int = 2, extra_stages: Mapping[str, int] | None = None, roi: Sequence[int] | None = None, roi_scale: int | None = None, seg_scales: Sequence[int] | None = None, occupancy_scale: int | None = 5, occupancy_dilate: int = 1, allowlist: str | None = None, min_voxels: int = 0, limit_bodies: int | None = None, metrics_db: bool = True, seg_encoding: str = 'compressed_segmentation', max_consecutive_failures: int = 10, resume: bool = True, mesh_smoothing: int = 0, extra: Mapping[str, Any] | None = None) → Plan

Resolve and check a run against src’s pyramid; logs the plan. Writes nothing.

roi is (z0, y0, x0, z1, y1, x1) in the voxels of roi_scale, which is required with it: the same six numbers name a different box at every level. Scales are pyramid indices, their voxel sizes read from the source. occupancy_scale None or negative disables the empty-block prefilter; keep occupancy_dilate at 1 or more, since a coarse scale misses sparse blocks. seg_scales None copies every scale in the seg stage. extra_stages names stages another package runs (see the module docstring), each with its scale index; extra is recorded in run_plan.json. mesh_smoothing is Laplacian passes on each block’s mesh before decimation; over more than one block it also moves the seams, and is warned of.

Raises ValueError for an argument the source or the other arguments rule out.

neu_morpho.pipeline.run(p: Plan, *, client: Any = None, command: str | None = None, runners: Mapping[str, StageRunner] | None = None) → dict

Execute p’s stages; returns this run’s summary.

client is a dask client, or None to run serially in this process. runners runs each extra stage the plan names, after mesh. Per-body failures do not stop a stage; they are counted in n_failed_bodies and retried by the next run. Afterwards the volume’s info is pointed at whichever of the mesh and skeleton subresources exist, so one neuroglancer layer carries all three.

The run is recorded in <work_dir>/runs/<run id>/ (see run_records): its plan when it starts, its summary when it ends, with status "aborted" and the error if a stage raised. The work dir’s run_plan.json and run_summary.json are then rebuilt from every run to the same volume.

neu_morpho.pipeline.DEFAULT_STAGES = ('index', 'mesh')
neu_morpho.pipeline.STAGES = ('seg', 'index', 'mesh')
neu_morpho.pipeline.STAGE_DOC
neu_morpho.pipeline.StageRunner
neu_morpho.pipeline.UNFILTERED_WARN_BODIES = 100000
neu_morpho.pipeline.log