cellmap_flow.dashboard.routes.pipeline

The dashboard’s chain, and the settings the pipeline builder keeps here.

  • PUT /api/pipeline: set the chain and redraw the viewer through it (the dashboard page’s Apply, and the pipeline builder after each edit).

  • GET /api/raw/channels: the raw’s channels, which the Processing tab’s Channel picks among (the chain’s ChannelSelector).

  • set_declared_input_norm(): a model’s start sets the input normalization it declares, or its kind of model’s convention, when the chain has none (services.launch.update_run_models).

  • set_needed_postprocess(): a model’s start sets the postprocessing its output needs, a sigmoid for logits, when the chain has none, once its server’s probe says (services.launch.run_model).

  • POST /api/process and POST /api/pipeline/apply: the two routes it replaced, kept for one release as its deprecated aliases.

  • /api/blockwise-config: the builder’s blockwise settings.

  • /update/equivalences: a segmentation layer’s merged ids.

Attributes

logger

pipeline_bp

Classes

BuilderCanvas

The pipeline builder's canvas as it sends it: its nodes by type, and

PipelineUpdate

The body of PUT /api/pipeline.

Functions

validate_pipeline_config(config)

/api/pipeline/apply's check of the builder's nodes: {"valid": True},

update_equivalences()

Show a merging postprocessor's merged ids (an Equivalences) in its

start_input_norm(model_config, raw_dtype, raw_range)

What model_config's start sets on a chain with no input

set_declared_input_norm(model_configs) → Optional[str]

Set the input normalization a model declares as the chain's, or the

input_norm_set_by(model_configs)

The first of model_configs whose start sets the chain's input

set_needed_postprocess(job) → bool

Set the postprocessing job's model needs to show a good prediction

postprocess_set_by(model_names)

The model of model_names whose settings the chain's

put_pipeline()

Set the chain, and redraw the viewer through it.

get_raw_channels()

The raw's channels, for the Processing tab's Channel:

process()

Submit's route before PUT /api/pipeline.

apply_pipeline()

The pipeline builder's route before PUT /api/pipeline, answering as it did.

blockwise_config_api()

Get or set the blockwise settings.

Module Contents

cellmap_flow.dashboard.routes.pipeline.logger
cellmap_flow.dashboard.routes.pipeline.pipeline_bp
cellmap_flow.dashboard.routes.pipeline.validate_pipeline_config(config)

/api/pipeline/apply’s check of the builder’s nodes: {"valid": True}, or {"valid": False, "error"} for the first node that names no registered op, or for a body it cannot read.

class cellmap_flow.dashboard.routes.pipeline.BuilderCanvas(/, **data: Any)

The pipeline builder’s canvas as it sends it: its nodes by type, and its edges, each a list (a missing one is empty). The dashboard keeps it for the builder’s next load, and each model node’s config for a model node that comes back without one; the chain is not read from it.

inputs: list[dict] = []
outputs: list[dict] = []
edges: list[dict] = []
normalizers: list[dict] = []
models: list[dict] = []
postprocessors: list[dict] = []
class cellmap_flow.dashboard.routes.pipeline.PipelineUpdate(/, **data: Any)

The body of PUT /api/pipeline.

input_norm and postprocess are the two chains, each a list of {"name": <op class>, **its parameters} steps in the order they run (pipeline_spec’s form). Both are required, [] for none, and every step must name a registered op of its kind. builder is the pipeline builder’s canvas (BuilderCanvas); only the builder sends it.

input_norm: list[dict]
postprocess: list[dict]
builder: BuilderCanvas | None = None
cellmap_flow.dashboard.routes.pipeline.update_equivalences()

Show a merging postprocessor’s merged ids (an Equivalences) in its segmentation layer. Its inference server posts them as it merges.

cellmap_flow.dashboard.routes.pipeline.start_input_norm(model_config, raw_dtype, raw_range)

What model_config’s start sets on a chain with no input normalization, for raw data of raw_dtype spanning raw_range: (the chain steps, whether the model declares them). Its declaration (_declared_steps), else the convention for its kind of model, a CellMap or DaCapo model’s [-1, 1] (the model advice’s suggestion at medium confidence, model_advice.input_norm_suggestion). ([], False) for a model nothing is known of, whose suggestion of the range assumed stays a suggestion, and without the raw data’s range (no dataset open), where the convention’s MinMaxNormalizer would be a guess. The Finetune tab’s ranking reads a model through these steps too (finetune/rank_routes.py), whatever the chain has.

cellmap_flow.dashboard.routes.pipeline.set_declared_input_norm(model_configs) → str | None

Set the input normalization a model declares as the chain’s, or the convention for its kind of model when it declares none, as part of starting it, when the chain has none. Returns the name of the model whose input normalization it is, or None when nothing changed.

The Models tab’s Submit (services.launch.update_run_models) calls this with the models it is about to start, in the tab’s order, before their layers are drawn, so they are drawn through it. The first of them with any steps to set (start_input_norm: declared, or a CellMap or DaCapo model’s convention) gives them, and the postprocessing stays as it is; the chain is set through _set_chain_and_redraw, as PUT /api/pipeline sets it, so the layers of the models already running are redrawn through it too. A chain that has input normalizers already (a YAML’s, the user’s Apply) is left alone, and after this only Apply changes it: the Processing tab’s input list shows the chain as set (GET /api/models/loaded’s pipeline, which the page reads after every model change) and the notice that says where it came from. A model with nothing to set (one nothing is known of) changes nothing. Steps that name an op the registry does not have, or a value its class refuses, are skipped with a warning, and the next model’s are tried.

The browser’s twin is web/src/backend/serving.ts setDeclaredInputNorm, whose models all declare theirs (their manifests).

cellmap_flow.dashboard.routes.pipeline.input_norm_set_by(model_configs)

The first of model_configs whose start sets the chain’s input part as it stands, step for step (start_input_norm), as (its name, whether the model declares the steps); (None, None) when none does, or the chain has no input normalizers.

GET /api/models/loaded answers them beside the chain, so the page can say where an input normalization a model’s start set came from (set_declared_input_norm sets the steps as they are).

cellmap_flow.dashboard.routes.pipeline.set_needed_postprocess(job) → bool

Set the postprocessing job’s model needs to show a good prediction as the chain’s, as part of starting it, when the chain has none: the sigmoid its output needs when it is logits (portable/rank.py needed_postprocess, with no threshold; an affinity model’s too). Returns whether it set any.

services.launch.run_model calls this once the model’s server has its host, before the model’s layer is drawn: every start goes through it (the Models tab’s Submit, Add a model, the Finetune tab’s Use this model). Unlike the input normalization (set_declared_input_norm), which a model’s config says, its output is known only from its server’s probe (serving/client.fetch_model_info’s output_class), so this comes after its job starts. The chain is set through _set_chain_and_redraw, as PUT /api/pipeline sets it, so every layer is redrawn through it, this model’s among them; and so it is not set when it would show another model being served wrong (a sigmoid on top of an output that has one already). A chain with postprocessing (a YAML’s, the user’s Apply, the ranking’s) is left alone: the first model started into an empty chain that needs any gives it, and after that only Apply changes it. The session remembers which model’s start it was (Session.start_postprocess, which postprocess_set_by reads).

The browser’s twin is web/src/backend/serving.ts, at serve, from the manifest’s declared output.

cellmap_flow.dashboard.routes.pipeline.postprocess_set_by(model_names)

The model of model_names whose settings the chain’s postprocessing is, step for step, as (its name, whether the ranking fitted them to the paint); (None, None) when it is none’s, or the chain has none.

The ranking’s (Session.rank_fits: what Use this model, Fit to Paint and Use these settings set, a sigmoid and the threshold the paint is fitted best at), else a model’s start’s (Session.start_postprocess: set_needed_postprocess, the sigmoid its logits need). GET /api/models/loaded answers them beside the chain, as it answers where the input normalization came from (input_norm_set_by).

cellmap_flow.dashboard.routes.pipeline.put_pipeline()

Set the chain, and redraw the viewer through it.

The body is a PipelineUpdate. The answer is {"success": true, "pipeline": {"input_norm", "postprocess"}, "digest", "layers"}: the chain as it is now configured, its digest (which names the layers’ source, so the same chain sent again leaves neuroglancer’s chunks and each server’s built chain as they are), and the prediction layers drawn. A body that is not a PipelineUpdate, a step its op’s class refuses, or a ChannelSelector past the raw’s channels (_channel_problems), is a 400 {"success": false, "error"} that changes nothing.

cellmap_flow.dashboard.routes.pipeline.get_raw_channels()

The raw’s channels, for the Processing tab’s Channel: {"success": true, "channels", "labels", "selected"}. channels is how many there are (1 for a raw with no channel axis, or no dataset open), labels their names (io.raw.raw_channels: an OME-Zarr’s omero labels) or null, and selected the one the models read, the chain’s ChannelSelector’s, else 0. A raw that cannot be read is a 400 {"success": false, "error"}. The browser’s twin answers the same.

cellmap_flow.dashboard.routes.pipeline.process()

Submit’s route before PUT /api/pipeline.

The body is {"input_norm", "postprocess"}, either chain in the list or the older dict form. The answer is {"message", "received_data"}, the body with the dashboard’s address and the chain’s digest added; the older answer’s found_custom_normalizer and received_data.time, which nothing read, are gone. An op it does not know is kept in the chain and skipped where it is built; a body without both chains, or a step its class refuses, is a 500.

cellmap_flow.dashboard.routes.pipeline.apply_pipeline()

The pipeline builder’s route before PUT /api/pipeline, answering as it did.

The body is the builder’s nodes by type (input_normalizers, postprocessors, models, inputs, outputs) and its edges. The chain is taken from the normalizer and postprocessor nodes, each {"name", "params"}; everything is kept as the builder’s canvas. The answer is {"message", "normalizers_applied", "postprocessors_applied"}. A node that names no registered op is a 400 {"valid": false, "error"}, and anything else that goes wrong a 500 {"error"}.

cellmap_flow.dashboard.routes.pipeline.blockwise_config_api()

Get or set the blockwise settings.