Skip to content

The Polyscope viewer

The Polyscope viewer: a mesh coloured by its tensions and pressures, in a window with their colour bars.

Sacha Ichbiah 2021 Matthieu Perez 2024

This module needs Polyscope (pip install "foambryo[viewing]"), and its viewers need a display. The colour bars alone are written without either by save_colour_bars (also in foambryo.colour_scales).

The three force viewers (plot_force_inference, plot_tension_inference, plot_pressure_inference) draw the mesh coloured with the library's colour functions (foambryo.colour_scales):

  • tensions: coolwarm (blue for low, light grey for the mean tension, red for high), over a range centred on the mean of the finite tensions and symmetric around it, its half-width the farther of the alpha and 1 - alpha quantiles from the mean;
  • pressures: magma, reversed (light for low) and trimmed to its 10-90 % range, from 0 to the 1 - alpha quantile of the pressures over the surface's triangles;
  • undetermined values (nan): green, #1b9e77 (UNDETERMINED_COLOR). In the tension view an interface whose tension is undetermined is drawn as its outline in this green, without fill; a cell whose pressure is undetermined is filled green;
  • crop faces (where the image box cut the tissue): see-through glass with its edges drawn; they carry no value;
  • other quantities drawn on the surface (a seed spread, the sphere-fit residual, the curvatures) keep jet.

With tensions and pressures, the surface shows the tensions first. The viewers with tensions also draw a graph of the tissue (a node at each cell's centroid, an edge per interface coloured by its tension; with pressures, the nodes coloured by pressure) and, with pressures, each cell's principal stresses. Polyscope's window gets a panel, "foambryo", that shows:

  • the colour bars of what is drawn: the library's colours over the library's ranges (the ones save_colour_bars writes), with a green swatch when a value is undetermined and a glass one for crop faces. Polyscope is handed the colours, not the values: its own scalar colour maps would draw nan in their top colour;
  • which values the colours show: the inference call that produced them (the library's options are the viewers' own, mode_tension, mode_pressure, mean_tension, base_pressure, solver, with the library's defaults), or where they were read from;
  • with tensions and pressures, which one colours the surface (the tensions by default);
  • a length scale bar when the mesh's unit is known (length_unit): a segment of round length in the scene, its length written beside it; and an optional x, y, z frame, three labelled segments along the mesh's columns (z, y, x);
  • the background: white (Polyscope's), light grey, dark grey or black (BACKGROUND_COLOURS, the napari plugin's choices too), or a custom colour; on a dark one, the scale bar, the frame, their labels and the graph's black nodes are drawn light;
  • Explode (the scattered view: each cell moved away from the tissue's centre by a coefficient; the graph's nodes stay on their exploded cells) and Cut (a scene slice plane normal to z, y or x, at a chosen position, keeping either side);
  • Save figure (the view with its colour bars and scale bar, PNG / PDF / SVG), Save colour bars, and Export: foambryo infer's files for the values shown (tensions.csv, pressures.csv, solves.csv, run.json, colour_bars.png), in a folder; a file is never overwritten without asking;
  • a choice of tension method, pressure method or no pressures, solver and diagnostics, Recompute, and the foambryo infer command line that gives the same numbers.

view_mask opens the window on a segmentation mask instead (foambryo view MASK --spacing DZ DY DX): the mask first, then its reconstruction and the inference, run in child processes that the panel follows and can cancel.

save_figure=PATH writes the same figure from Python, without keeping the window open when show=False (Polyscope still needs a display to render the view).

plot_force_inference

plot_force_inference(mesh: DcelData, dict_tensions: dict[tuple[int, int], float] | None = None, dict_pressure: dict[int, float] | None = None, alpha: float = 0.05, scalar_quantities: bool = False, scattered: bool = False, scatter_coeff: float = DEFAULT_SCATTER_COEFF, *, mean_tension: float = _INFER_FORCES_DEFAULTS['mean_tension'], base_pressure: float = _INFER_FORCES_DEFAULTS['base_pressure'], mode_tension: TensionComputationMethod = _INFER_FORCES_DEFAULTS['mode_tension'], mode_pressure: PressureComputationMethod = _INFER_FORCES_DEFAULTS['mode_pressure'], solver: str = _INFER_FORCES_DEFAULTS['solver'], length_unit: str | None = None, scale_bar: bool | float = True, save_figure: str | PathLike[str] | None = None, show: bool = True, values_from: str | None = None, mesh_file: str | None = None) -> None

Show a mesh's tensions and pressures in Polyscope's window, with their colour bars; what foambryo view opens.

The surface is coloured by the tensions first (coolwarm, centred on the mean tension); the panel switches it to the pressures (reversed magma, trimmed to its 10-90 % range). An undetermined tension (nan) is drawn as its interface's green outline, without fill, and an undetermined pressure fills its cell green; crop faces are see-through glass. The graph of the tissue and each cell's principal stresses are drawn too. The module docstring lists what the panel offers.

Needs Polyscope (pip install "foambryo[viewing]") and a display, also with show=False (Polyscope renders the figure). Returns when the window is closed.

Parameters:

Name Type Description Default
mesh DcelData

the mesh, in its own length unit.

required
dict_tensions dict[tuple[int, int], float] | None

tension per interface, keyed (label_1, label_2) with label_1 < label_2 (0 is the medium). Defaults to None: the tensions and the pressures are inferred with infer_forces and the options below.

None
dict_pressure dict[int, float] | None

pressure per label, the medium (0) included. Defaults to None: inferred with infer_forces, or, when dict_tensions is given, with infer_pressures from those tensions and the options below.

None
alpha float

the quantile clipped at each end of the colour scales, in [0, 0.5): the tension range reaches the farther of the alpha and 1 - alpha quantiles from the mean, the pressure range runs from 0 to the 1 - alpha quantile. Defaults to 0.05.

0.05
scalar_quantities bool

also add the sphere-fit residual, the area and volume derivatives and the curvatures as surface quantities (jet). Defaults to False.

False
scattered bool

open the window exploded: each cell moved away from the tissue's centre by scatter_coeff times (its centroid - the tissue's centroid). The panel changes it. Defaults to False.

False
scatter_coeff float

the explode coefficient. Defaults to 0.2 (DEFAULT_SCATTER_COEFF).

DEFAULT_SCATTER_COEFF
mean_tension float

the mean the tensions are gauged to. Defaults to 1. Keyword-only.

_INFER_FORCES_DEFAULTS['mean_tension']
base_pressure float

the pressure of the medium, label 0. Defaults to 0. Keyword-only.

_INFER_FORCES_DEFAULTS['base_pressure']
mode_tension TensionComputationMethod

the tension method. Defaults to YoungDupre. Keyword-only.

_INFER_FORCES_DEFAULTS['mode_tension']
mode_pressure PressureComputationMethod

the pressure method. Defaults to Variational. Keyword-only.

_INFER_FORCES_DEFAULTS['mode_pressure']
solver str

"auto", "dense" or "sparse". Defaults to "auto". Keyword-only. These five are infer_forces' options, with its defaults, passed to it unchanged when the viewer infers (bitwise foambryo infer's numbers); the panel names the call that produced the colours.

_INFER_FORCES_DEFAULTS['solver']
length_unit str | None

the unit of the mesh's coordinates ("um", ...); with a unit, a length scale bar is drawn. Defaults to None: no scale bar. Keyword-only.

None
scale_bar bool | float

draw the scale bar (True, its length 1, 2 or 5 times a power of ten, at most a quarter of the tissue's largest side), not (False), or with this length, in length_unit. Defaults to True. Keyword-only.

True
save_figure str | PathLike | None

write the first view, with its colour bars and scale bar, to this file (.png, .pdf, .svg; matplotlib chooses the format from the suffix), before the window is shown. Defaults to None. Keyword-only.

None
show bool

open the window; False with save_figure only writes the figure. Defaults to True. Keyword-only.

True
values_from str | None

where given values come from, shown in the panel and under a saved figure. Defaults to None. Keyword-only.

None
mesh_file str | None

the mesh's file name, for the foambryo infer command line the panel shows for values inferred in the window. Defaults to None (no command line). Keyword-only.

None

Raises:

Type Description
ValueError

when the viewer infers and the library refuses the tensions or the pressures (the library's message; UndeterminedTensionError, a ValueError, when the given tensions are not all finite on a mesh without crop faces).

plot_pressure_inference

plot_pressure_inference(mesh: DcelData, dict_pressure: dict[int, float] | None = None, alpha: float = 0.05, scattered: bool = False, scatter_coeff: float = DEFAULT_SCATTER_COEFF, *, mean_tension: float = _INFER_FORCES_DEFAULTS['mean_tension'], base_pressure: float = _INFER_FORCES_DEFAULTS['base_pressure'], mode_tension: TensionComputationMethod = _INFER_FORCES_DEFAULTS['mode_tension'], mode_pressure: PressureComputationMethod = _INFER_FORCES_DEFAULTS['mode_pressure'], solver: str = _INFER_FORCES_DEFAULTS['solver'], length_unit: str | None = None, scale_bar: bool | float = True, save_figure: str | PathLike[str] | None = None, show: bool = True, values_from: str | None = None) -> None

Show a mesh's cell pressures in Polyscope's window, with their colour bar.

Each triangle carries the pressure of the higher-labelled of its two materials, coloured with reversed magma trimmed to its 10-90 % range, from 0 to the 1 - alpha quantile over the triangles (negative pressures drawn as 0). An undetermined pressure (nan) fills its cell green; crop faces are see-through glass. Polyscope's structures are removed first.

Needs Polyscope (pip install "foambryo[viewing]") and a display, also with show=False (Polyscope renders the figure). Returns when the window is closed.

Parameters:

Name Type Description Default
mesh DcelData

the mesh, in its own length unit.

required
dict_pressure dict[int, float] | None

pressure per label, the medium (0) included. Defaults to None: the tensions and pressures are inferred with infer_forces and the options below, and the pressures are shown.

None
alpha float

the quantile clipped at the top of the pressure scale. Defaults to 0.05.

0.05
scattered bool

open the window exploded: each cell moved away from the tissue's centre by scatter_coeff times (its centroid - the tissue's centroid). Defaults to False.

False
scatter_coeff float

the explode coefficient. Defaults to 0.2 (DEFAULT_SCATTER_COEFF).

DEFAULT_SCATTER_COEFF
mean_tension float

the mean the tensions are gauged to. Defaults to 1. Keyword-only.

_INFER_FORCES_DEFAULTS['mean_tension']
base_pressure float

the pressure of the medium, label 0. Defaults to 0. Keyword-only.

_INFER_FORCES_DEFAULTS['base_pressure']
mode_tension TensionComputationMethod

the tension method. Defaults to YoungDupre. Keyword-only.

_INFER_FORCES_DEFAULTS['mode_tension']
mode_pressure PressureComputationMethod

the pressure method. Defaults to Variational. Keyword-only.

_INFER_FORCES_DEFAULTS['mode_pressure']
solver str

"auto", "dense" or "sparse". Defaults to "auto". Keyword-only. These five are infer_forces' options, with its defaults, passed to it unchanged when the viewer infers; the panel names the call that produced the colours. Unused when dict_pressure is given.

_INFER_FORCES_DEFAULTS['solver']
length_unit str | None

the unit of the mesh's coordinates ("um", ...); with a unit, a length scale bar is drawn. Defaults to None: no scale bar. Keyword-only.

None
scale_bar bool | float

draw the scale bar (True, its length chosen round), not (False), or with this length, in length_unit. Defaults to True. Keyword-only.

True
save_figure str | PathLike | None

write the first view, with its colour bar and scale bar, to this file (.png, .pdf, .svg), before the window is shown. Defaults to None. Keyword-only.

None
show bool

open the window; False with save_figure only writes the figure. Defaults to True. Keyword-only.

True
values_from str | None

where given values come from, shown in the panel and under a saved figure. Defaults to None. Keyword-only.

None

Raises:

Type Description
ValueError

when the viewer infers and the library refuses the tensions or the pressures (the library's message).

plot_tension_inference

plot_tension_inference(mesh: DcelData, dict_tensions: dict[tuple[int, int], float] | None = None, alpha: float = 0.05, scalar_quantities: bool = False, scattered: bool = False, scatter_coeff: float = DEFAULT_SCATTER_COEFF, *, mean_tension: float = _INFER_FORCES_DEFAULTS['mean_tension'], mode_tension: TensionComputationMethod = _INFER_FORCES_DEFAULTS['mode_tension'], solver: str = _INFER_FORCES_DEFAULTS['solver'], seed_ensemble: SeedEnsembleMaps | None = None, length_unit: str | None = None, scale_bar: bool | float = True, save_figure: str | PathLike[str] | None = None, show: bool = True, values_from: str | None = None, mesh_file: str | None = None) -> None

Show a mesh's surface tensions in Polyscope's window, with their colour bar.

The surface is coloured with coolwarm over a range centred on the mean tension and symmetric around it; an undetermined tension (nan), or an interface absent from the map, is drawn as its interface's green outline, without fill; crop faces are see-through glass. The graph of the tissue is drawn too, its edges coloured by tension. Polyscope's structures are removed first.

Needs Polyscope (pip install "foambryo[viewing]") and a display, also with show=False (Polyscope renders the figure). Returns when the window is closed.

Parameters:

Name Type Description Default
mesh DcelData

the mesh, in its own length unit.

required
dict_tensions dict[tuple[int, int], float] | None

tension per interface, keyed (label_1, label_2) with label_1 < label_2 (0 is the medium). Defaults to None: inferred with infer_tensions and the options below.

None
alpha float

the quantile at each end of the colour scale, in [0, 0.5): the range reaches the farther of the alpha and 1 - alpha quantiles from the mean. Defaults to 0.05.

0.05
scalar_quantities bool

also add the sphere-fit residual, the area and volume derivatives and the curvatures as surface quantities (jet). Defaults to False.

False
scattered bool

open the window exploded: each cell moved away from the tissue's centre by scatter_coeff times (its centroid - the tissue's centroid). Defaults to False.

False
scatter_coeff float

the explode coefficient. Defaults to 0.2 (DEFAULT_SCATTER_COEFF).

DEFAULT_SCATTER_COEFF
mean_tension float

the mean the tensions are gauged to. Defaults to 1. Keyword-only.

_INFER_FORCES_DEFAULTS['mean_tension']
mode_tension TensionComputationMethod

the tension method. Defaults to YoungDupre. Keyword-only.

_INFER_FORCES_DEFAULTS['mode_tension']
solver str

"auto", "dense" or "sparse". Defaults to "auto". Keyword-only. These three are infer_forces' tension options, with its defaults, passed to infer_tensions unchanged when the viewer infers.

_INFER_FORCES_DEFAULTS['solver']
seed_ensemble SeedEnsembleMaps | None

tensions combined over several reconstructions of the mesh's mask (foambryo.infer_tensions_over_seeds' result, or any object with its tensions, tension_seed_sd and found_by_fewer_than_half_the_seeds maps). They are drawn on this mesh's interfaces, matched by label pair (the mesh's other interfaces drawn as undetermined); the seeds' spread is a second quantity with its own colour bar (jet, between the alpha and 1 - alpha quantiles); the interfaces found by fewer than half of the seeds are drawn over the surface in magenta (their triangles' edges). Not with dict_tensions. Defaults to None. Keyword-only.

None
length_unit str | None

the unit of the mesh's coordinates ("um", ...); with a unit, a length scale bar is drawn. Defaults to None: no scale bar. Keyword-only.

None
scale_bar bool | float

draw the scale bar (True, its length chosen round), not (False), or with this length, in length_unit. Defaults to True. Keyword-only.

True
save_figure str | PathLike | None

write the first view, with its colour bars and scale bar, to this file (.png, .pdf, .svg), before the window is shown. Defaults to None. Keyword-only.

None
show bool

open the window; False with save_figure only writes the figure. Defaults to True. Keyword-only.

True
values_from str | None

where given values come from, shown in the panel and under a saved figure. Defaults to None. Keyword-only.

None
mesh_file str | None

the mesh's file name, for the foambryo infer command line the panel shows for values inferred in the window. Defaults to None (no command line). Keyword-only.

None

Raises:

Type Description
ValueError

if both dict_tensions and seed_ensemble are given, or when the viewer infers and the library refuses the tensions (the library's message).

view_mask

view_mask(mask: ndarray, spacing: tuple[float, float, float], *, spacing_unit: str = 'um', min_distance: int | None = None, mean_tension: float = _INFER_FORCES_DEFAULTS['mean_tension'], base_pressure: float = _INFER_FORCES_DEFAULTS['base_pressure'], mode_tension: TensionComputationMethod = _INFER_FORCES_DEFAULTS['mode_tension'], mode_pressure: PressureComputationMethod = _INFER_FORCES_DEFAULTS['mode_pressure'], solver: str = _INFER_FORCES_DEFAULTS['solver'], pressures: bool = True, scattered: bool = False, scatter_coeff: float = DEFAULT_SCATTER_COEFF, scale_bar: bool | float = True, mask_name: str = 'mask.npz') -> None

Open the viewer on a segmentation mask: the window foambryo view MASK --spacing DZ DY DX opens.

The mask is shown first (each cell's voxels as points in its own colour); the panel reconstructs it as foambryo mesh does (foambryo.io.reconstruct_mask) and infers as foambryo infer does (infer_tensions_then_pressures) or foambryo infer-over-seeds (infer_tensions_over_seeds), each in a child process with its elapsed time, the estimate (foambryo.reconstruction_cost) and Cancel; the values are then drawn with their colour bars, explode, cut and export, as by plot_force_inference. Returns when the window is closed (a job still running is cancelled then).

Needs Polyscope (pip install "foambryo[viewing]"), delaunay-watershed-3d and a display.

Parameters:

Name Type Description Default
mask ndarray

the segmentation, a 3-D array of non-negative integer labels, axis 0 = z, axis 1 = y, axis 2 = x, 0 the medium (check_segmentation_mask's checks).

required
spacing tuple[float, float, float]

the voxel size (dz, dy, dx), three finite numbers > 0, in spacing_unit; an anisotropic mask is resampled to cubic voxels of the shortest spacing before meshing, as by foambryo mesh (only one axis may be longer than the other two). There is no default: a wrong spacing changes every angle.

required
spacing_unit str

the spacing's unit, the mesh's length unit, written on the scale bar (--spacing-unit). Defaults to "um". Keyword-only.

'um'
min_distance int | None

the reconstruction's --min-distance, in cubic voxels of the shortest spacing; None (the default) is delaunay-watershed-3d's default (3). The panel changes it. Keyword-only.

None
mean_tension float

infer_forces' option, with its default (1); the panel starts with it. Keyword-only.

_INFER_FORCES_DEFAULTS['mean_tension']
base_pressure float

likewise (default 0). Keyword-only.

_INFER_FORCES_DEFAULTS['base_pressure']
mode_tension TensionComputationMethod

likewise (default TensionComputationMethod.YoungDupre). Keyword-only.

_INFER_FORCES_DEFAULTS['mode_tension']
mode_pressure PressureComputationMethod

likewise (default PressureComputationMethod.Variational). Keyword-only.

_INFER_FORCES_DEFAULTS['mode_pressure']
solver str

likewise (default "auto"). Keyword-only.

_INFER_FORCES_DEFAULTS['solver']
pressures bool

False infers the tensions only (--no-pressures). Defaults to True. Keyword-only.

True
scattered bool

draw the values exploded (--scattered). Defaults to False. Keyword-only.

False
scatter_coeff float

by this coefficient (--scattered COEFF). Defaults to 0.2. Keyword-only.

DEFAULT_SCATTER_COEFF
scale_bar bool | float

as for plot_force_inference, in spacing_unit. Defaults to True. Keyword-only.

True
mask_name str

the mask's file name in the equivalent command lines the panel shows and in the messages of a refused mask. Defaults to "mask.npz". Keyword-only.

'mask.npz'

Raises:

Type Description
ValueError

if the mask or the spacing is refused (the messages of foambryo mesh's checks; a refused mask raises foambryo.segmentation_masks.SegmentationMaskError, a ValueError).

plot_valid_junctions

plot_valid_junctions(mesh: DcelData, dict_tensions: dict[tuple[int, int], float] | None = None) -> None

Show in Polyscope's window which triple lines the tensions can balance: green if they can, red if not.

At a triple line between cells a, b and c, three tensions can balance only if each is at most the sum of the other two (they form a triangle). A line where one tension exceeds the sum of the other two is drawn red ("bad trijunctions"), every other line green ("valid trijunctions"), over the mesh drawn white and mostly see-through (opacity 0.1). A line with a crop interface (absent from the tension map) is not judged and is drawn green. When every line is judged and bad, only the red lines are drawn. Used to check an inference. When no line is judged (the mesh has no triple line, or every line has a crop interface), no line is drawn: the window shows the mesh alone, with a UserWarning that says so.

Needs Polyscope (pip install "foambryo[viewing]") and a display. Polyscope's structures are removed first; returns when the window is closed, and removes them then.

Parameters:

Name Type Description Default
mesh DcelData

the mesh.

required
dict_tensions dict[tuple[int, int], float] | None

tension per interface, keyed (label_1, label_2) with label_1 < label_2. Defaults to None: infer_tensions(mesh, mean_tension=1), with that function's default method.

None

Warns:

Type Description
UserWarning

when no triple line can be judged, and none is drawn.

plot_residual_junctions

plot_residual_junctions(mesh: DcelData, dict_tensions: dict[tuple[int, int], float] | None = None, alpha: float = 0.05) -> None

Show in Polyscope's window how far each triple line is from force balance under the tensions.

The residuals are foambryo.tension_inference.compute_residual_junctions_dict(mesh, dict_tensions, alpha) (read with the chord angle reading): per triple line, the sum of the squared residuals of its three balance equations, each clipped between the alpha and 1 - alpha quantiles over all lines. The lines are coloured with jet from 0 to the largest residual, over the mesh drawn white and mostly see-through (opacity 0.1); the range is printed.

Needs Polyscope (pip install "foambryo[viewing]") and a display. Polyscope's structures are removed first; returns when the window is closed, and removes them then.

Parameters:

Name Type Description Default
mesh DcelData

the mesh.

required
dict_tensions dict[tuple[int, int], float] | None

tension per interface, keyed (label_1, label_2) with label_1 < label_2. Defaults to None: infer_tensions(mesh, mean_tension=1), with that function's default method.

None
alpha float

the quantile at which the residuals are clipped at each end. Defaults to 0.05.

0.05