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 thealphaand1 - alphaquantiles from the mean; - pressures:
magma, reversed (light for low) and trimmed to its 10-90 % range, from 0 to the1 - alphaquantile 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_barswrites), 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 drawnanin 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 infercommand 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
|
None
|
dict_pressure
|
dict[int, float] | None
|
pressure per label, the medium (0) included. Defaults
to None: inferred with |
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 |
0.05
|
scalar_quantities
|
bool
|
also add the sphere-fit residual, the area and volume derivatives
and the curvatures as surface quantities ( |
False
|
scattered
|
bool
|
open the window exploded: each cell moved away from the tissue's centre by
|
False
|
scatter_coeff
|
float
|
the explode coefficient. Defaults to 0.2 ( |
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 |
_INFER_FORCES_DEFAULTS['mode_tension']
|
mode_pressure
|
PressureComputationMethod
|
the pressure method. Defaults to |
_INFER_FORCES_DEFAULTS['mode_pressure']
|
solver
|
str
|
|
_INFER_FORCES_DEFAULTS['solver']
|
length_unit
|
str | None
|
the unit of the mesh's coordinates ( |
None
|
scale_bar
|
bool | float
|
draw the scale bar ( |
True
|
save_figure
|
str | PathLike | None
|
write the first view, with its colour bars and scale
bar, to this file ( |
None
|
show
|
bool
|
open the window; |
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 |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
when the viewer infers and the library refuses the tensions or the pressures (the library's
message; |
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 |
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
|
False
|
scatter_coeff
|
float
|
the explode coefficient. Defaults to 0.2 ( |
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 |
_INFER_FORCES_DEFAULTS['mode_tension']
|
mode_pressure
|
PressureComputationMethod
|
the pressure method. Defaults to |
_INFER_FORCES_DEFAULTS['mode_pressure']
|
solver
|
str
|
|
_INFER_FORCES_DEFAULTS['solver']
|
length_unit
|
str | None
|
the unit of the mesh's coordinates ( |
None
|
scale_bar
|
bool | float
|
draw the scale bar ( |
True
|
save_figure
|
str | PathLike | None
|
write the first view, with its colour bar and scale
bar, to this file ( |
None
|
show
|
bool
|
open the window; |
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
|
None
|
alpha
|
float
|
the quantile at each end of the colour scale, in [0, 0.5): the range reaches the
farther of the |
0.05
|
scalar_quantities
|
bool
|
also add the sphere-fit residual, the area and volume derivatives
and the curvatures as surface quantities ( |
False
|
scattered
|
bool
|
open the window exploded: each cell moved away from the tissue's centre by
|
False
|
scatter_coeff
|
float
|
the explode coefficient. Defaults to 0.2 ( |
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 |
_INFER_FORCES_DEFAULTS['mode_tension']
|
solver
|
str
|
|
_INFER_FORCES_DEFAULTS['solver']
|
seed_ensemble
|
SeedEnsembleMaps | None
|
tensions combined over several reconstructions of
the mesh's mask ( |
None
|
length_unit
|
str | None
|
the unit of the mesh's coordinates ( |
None
|
scale_bar
|
bool | float
|
draw the scale bar ( |
True
|
save_figure
|
str | PathLike | None
|
write the first view, with its colour bars and scale
bar, to this file ( |
None
|
show
|
bool
|
open the window; |
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 |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
if both |
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 ( |
required |
spacing
|
tuple[float, float, float]
|
the voxel size |
required |
spacing_unit
|
str
|
the spacing's unit, the mesh's length unit, written on the scale bar ( |
'um'
|
min_distance
|
int | None
|
the reconstruction's |
None
|
mean_tension
|
float
|
|
_INFER_FORCES_DEFAULTS['mean_tension']
|
base_pressure
|
float
|
likewise (default 0). Keyword-only. |
_INFER_FORCES_DEFAULTS['base_pressure']
|
mode_tension
|
TensionComputationMethod
|
likewise (default |
_INFER_FORCES_DEFAULTS['mode_tension']
|
mode_pressure
|
PressureComputationMethod
|
likewise (default |
_INFER_FORCES_DEFAULTS['mode_pressure']
|
solver
|
str
|
likewise (default |
_INFER_FORCES_DEFAULTS['solver']
|
pressures
|
bool
|
|
True
|
scattered
|
bool
|
draw the values exploded ( |
False
|
scatter_coeff
|
float
|
by this coefficient ( |
DEFAULT_SCATTER_COEFF
|
scale_bar
|
bool | float
|
as for |
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'
|
Raises:
| Type | Description |
|---|---|
ValueError
|
if the mask or the spacing is refused (the messages of |
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
|
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
|
None
|
alpha
|
float
|
the quantile at which the residuals are clipped at each end. Defaults to 0.05. |
0.05
|