cellmap_flow.pipeline_spec

One description of a normalization + postprocessing chain.

A chain travels as data far more often than it runs: in every layer URL’s args blob (read by inference servers that may be older or newer than the dashboard), in model YAMLs’ json_data, in the finetune manifest, and in what the dashboard remembers between requests. Each of those used to build and read the {"input_norm": [...], "postprocess": [...]} form on its own. PipelineSpec is that form, with the readers for every shape it arrives in.

A step is a flat {"name": <class name>, **constructor arguments} dict, kept as given: values are not coerced (the dashboard’s forms send strings, and the constructors parse them), and the step is never nested as {"name", "params"} on the wire, because older servers pass every key but name straight to the constructor.

Importing this module is cheap: the op classes (and the libraries some of them need) are imported only when a spec is built.

Classes

PipelineSpec

An input-normalization chain and a postprocessing chain, as data.

Functions

normalize_steps(→ tuple)

A chain in the ordered ({"name", **params}, ...) form.

builder_steps(→ tuple)

Steps from the pipeline builder's [{"name", "params", ...}] nodes.

chain_output_dtype(postprocess, model_dtype)

The dtype the client receives: the last step's that declares one,

chain_num_channels(→ int)

How many channels the client receives, after e.g. ChannelSelection.

chain_is_segmentation(→ Optional[bool])

Whether the output is labels: the last step's that says.

Module Contents

cellmap_flow.pipeline_spec.normalize_steps(steps) → tuple

A chain in the ordered ({"name", **params}, ...) form.

Accepts the ordered list (copied; each step dict is copied too), the older {Name: {params}} dict (one step per key, in the dict’s order), or nothing (None, {}, []). In the dict form the key names the class, as it did for the reader that dict was written for, so it wins over a name inside the params.

A list element that is not a dict is kept as it is; the op readers skip it with a warning, as before.

cellmap_flow.pipeline_spec.builder_steps(nodes) → tuple

Steps from the pipeline builder’s [{"name", "params", ...}] nodes.

Built as {**params, "name": name}, the key order /api/pipeline/apply has always stored. Nodes that are not dicts or have no name are skipped; the builder’s own validation rejects those before they get here.

class cellmap_flow.pipeline_spec.PipelineSpec

An input-normalization chain and a postprocessing chain, as data.

Both are tuples of step dicts in the order they run. Build the live op instances with build(); those can hold state (SimpleBlockwiseMerger’s equivalences), so a spec is never a substitute for the instances a server or the dashboard already has.

input_norm: tuple = ()
postprocess: tuple = ()
classmethod from_json_data(data, strict: bool = False) → PipelineSpec

From a json_data dict (or its JSON text).

Either chain may be in the list or the legacy dict form. By default a missing or null chain is empty. strict instead requires both keys (KeyError) and a list or dict under each (ValueError), which is what the readers before PipelineSpec enforced, and what the blockwise precheck relies on to reject a misspelt json_data.

classmethod from_steps(input_norms=(), postprocess=()) → PipelineSpec

From live normalizer/postprocessor instances, via their to_dict().

classmethod from_builder(input_normalizers=(), postprocessors=()) → PipelineSpec

From the pipeline builder’s normalizer and postprocessor nodes.

classmethod from_url_blob(blob: str)

(spec, extras) from a layer URL’s args blob.

extras is every other key the blob carries (dashboard_url, digest, and time from older dashboards).

to_json_data() → dict

{"input_norm": [...], "postprocess": [...]}, in that order.

to_url_blob(**extras) → str

The args blob for a layer URL. Extras follow the two chains.

digest() → str

A short hash of the chains’ content, stable across processes.

Keys are sorted, so two specs that differ only in the order of a step’s parameters share a digest; the order of the steps counts.

build()

(input_norms, postprocess): new op instances for both chains.

is_empty() → bool
cellmap_flow.pipeline_spec.chain_output_dtype(postprocess, model_dtype)

The dtype the client receives: the last step’s that declares one, else the model’s own.

cellmap_flow.pipeline_spec.chain_num_channels(postprocess, model_channels) → int

How many channels the client receives, after e.g. ChannelSelection.

cellmap_flow.pipeline_spec.chain_is_segmentation(postprocess) → bool | None

Whether the output is labels: the last step’s that says.

False for an empty chain (raw model output is never labels), None when steps are present but none of them says.