Skip to content

Cropped tissues

Cropped tissues: what a crop face is, and what inference does with it.

The problem

A tissue imaged in part, or cropped from a larger image, has cells that the image boundary cuts. The mesh closes them with triangles lying on the boundary: crop faces, labelled (0, c) like contact with the medium, although nothing beyond them was observed. Read as medium contact, they make three kinds of error:

  • a tension unknown for an interface that does not exist (the crop), and a fake junction line (0, a, b) wherever the crop meets a cell-cell interface (a, b), with angles set by the crop plane rather than by the tissue;
  • force balances written at vertices on the crop, where the tissue that was cut away pulled;
  • a pressure for every cut cell, from a volume that is partly the crop.

Measured on 433 plane crops of the 47 benchmark tissues (YoungDupre, median over the 42 equilibrium cases of the relative error of the gauge-matched tensions of the interfaces that touch the crop): 13 %, 33 % and 40 % error with 10 %, 25 % and 40 % of the tissue cropped away when crop faces are read as medium contact, against 10 %, 9 % and 12 % when they are kept out; every one of the 13 tension methods improves at 25 % and 40 %, and LogLami stops failing on 25 of the crops. The interfaces away from the crop are affected too: at 40 % their error was 17 points above the uncropped tissue's, and 2 points above it with the crop kept out.

What inference does with a crop face

A mesh carries its crop as a mask of faces (DcelData(..., crop_faces=...)), never as a reserved label. Then, in every tension method:

  • a crop face carries no tension unknown and enters no equation; an interface made only of crop faces (DcelData.crop_interfaces) is absent from the tension map, never a number;
  • a junction edge with a vertex on a crop face gives no equation; the rest of a junction line that ends on the crop still does (the angle-reading methods exclude such edges from the line mean, as foambryo.wedge_refusal.WedgeRefusalPolicy.ExcludeEdgeFromLineMean does for a folded edge, and both reasons combine);
  • a vertex on a crop face gives no force balance (the Variational and ForceBalance* methods drop its three rows; Equilibrium drops the edges that touch it);
  • an interface left with no equation is nan, as an interface with no junction line already is.

And in the pressure methods, a cut cell (DcelData.cut_cells: a cell with a crop face or a vertex on one) keeps its pressure as an unknown, so that its force is not pushed into anyone else's, but the pressure is not reported: it comes back nan, with a CutCellPressureWarning naming the cells. On the benchmark crops the cut cells' pressures read as measurements had 15 % to 46 % error; withholding them leaves the other cells' pressures as accurate as without the crop.

What has no formulation for crop faces yet refuses a cropped mesh with a ValueError, rather than read the crop as medium: the two Laplace pressure methods (PressureComputationMethod.Laplace and WeightedLaplace; PressureComputationMethod.has_crop_face_formulation says which methods accept a cropped mesh), foambryo.compute_inference_diagnostics and foambryo.infer_tensions_with_uncertainty. infer_force_balance follows the rules above.

On a mesh without crop faces none of this runs.

Where crop faces come from

delaunay-watershed-3d (dw3d) marks them during the reconstruction: the triangles a cell has on a face of the image box that the cell reaches in the mask, unless that face is declared physical (a coverslip); a mask none of whose cells reaches the image box has none. They reach foambryo through dcel_mesh_from_segmentation_mask, or through a .rec file whose metadata appendix records crop_faces = <first row> <count> (dw3d writes them as the last rows), or a .vtk file with a crop_face cell array. A file written before crop faces were recorded carries no such record; when its mesh has faces that look like a crop, dcel_mesh_from_file warns (UnrecordedCropFacesWarning) instead of silently reading them as medium contact.

CutCellPressureWarning

Bases: UserWarning

Emitted when a pressure inference withholds the pressures of cut cells, reported as nan.

A cut cell has a crop face, or a vertex on one: part of its surface and volume lie outside the imaged volume. Its pressure is solved for, so that its force does not end up in the other cells' pressures, but it is not a measurement and is reported as nan. The other cells' pressures are unaffected.

UnrecordedCropFacesWarning

Bases: UserWarning

Emitted when a mesh read from a file looks cropped but the file records no crop faces.

Such a mesh has triangles (0, c) lying flat on a face of its own bounding box, like the faces a reconstruction places where the image boundary cuts a cell. Without a record of which they are, they are read as contact with the medium, which puts large errors on the tensions near them and on the pressures of the cells they close. Re-export the mesh with a current delaunay-watershed-3d, or pass the crop faces explicitly (DcelData(..., crop_faces=...)).

crop_edges

crop_edges(mesh: DcelData) -> frozenset[GeometricEdge]

Every mesh edge with a vertex on a crop face, as (min, max) vertex-key pairs.

A superset of the junction edges that touch the crop: the estimators match it against their own junction edges only, so the other edges it holds are never consulted.

Parameters:

Name Type Description Default
mesh DcelData

the mesh.

required

Returns:

Type Description
frozenset[GeometricEdge]

frozenset[GeometricEdge]: empty when the mesh has no crop face.

vertex_rows_off_the_crop

vertex_rows_off_the_crop(mesh: DcelData, excluded: NDArray[integer] | None = None) -> NDArray[np.intp]

Row indices 3v, 3v + 1, 3v + 2 of every vertex on no crop face and not in excluded.

The rows a vertex-wise force balance keeps on a cropped mesh: a vertex on a crop face is held by the tissue that was cut away, so its balance is not an observation.

Parameters:

Name Type Description Default
mesh DcelData

the mesh.

required
excluded NDArray | None

further vertex keys to leave out.

None

Returns:

Type Description
NDArray[intp]

NDArray[np.intp]: ascending row indices into a (3 nv, ...) operator.

warn_on_cut_cell_pressures

warn_on_cut_cell_pressures(cells: tuple[int, ...], stacklevel: int = 4) -> None

Emit CutCellPressureWarning naming the cut cells whose pressure is reported as nan.

Parameters:

Name Type Description Default
cells tuple[int, ...]

labels of the cut cells (nothing is emitted if empty).

required
stacklevel int

passed to warnings.warn. Defaults to 4.

4

require_no_crop_faces

require_no_crop_faces(mesh: DcelData, what: str) -> None

Refuse a cropped mesh in a computation that has no crop-aware formulation yet.

A crop face read as contact with the medium is the error this module exists to prevent, so a computation that would read it that way raises instead of returning a number.

Parameters:

Name Type Description Default
mesh DcelData

the mesh.

required
what str

the computation's name, for the message.

required

Raises:

Type Description
ValueError

if the mesh has crop faces.

border_like_faces

border_like_faces(points: NDArray[floating], triangles: NDArray[integer], labels: NDArray[integer]) -> NDArray[np.bool_]

Triangles that look like crop faces although nothing says they are.

A crop face, as a reconstruction writes it, is a triangle between the medium and a cell lying flat on a face of the volume, so on a face of the mesh's own bounding box. A triangle counts here when its labels are (0, c) in either order and its three vertices have exactly the bounding box's minimum or maximum coordinate on one axis; and a bounding-box face counts only when such triangles span at least BORDER_LIKE_MIN_SPAN of its extent on both of its other axes and the largest patch of them connected through shared edges covers at least BORDER_LIKE_MIN_PATCH_AREA of the face, so that the few scattered flat triangles an uncropped tissue has at its extremes do not count.

A heuristic, used only to decide whether to warn: it misses the few crop-face vertices a junction relocation moved off the plane, and it cannot tell a crop from a large flat contact that coincides with the bounding box.

Parameters:

Name Type Description Default
points NDArray[floating]

(nv, 3) vertex positions.

required
triangles NDArray[integer]

(nf, 3) triangles.

required
labels NDArray[integer]

(nf, 2) the two materials of each triangle.

required

Returns:

Type Description
NDArray[bool_]

NDArray[np.bool_]: (nf,), True on the triangles that look like crop faces.

warn_if_crop_faces_unrecorded

warn_if_crop_faces_unrecorded(points: NDArray[floating], triangles: NDArray[integer], labels: NDArray[integer], source: str, stacklevel: int = 3) -> None

Emit UnrecordedCropFacesWarning when a mesh with no crop record has border-like faces.

Parameters:

Name Type Description Default
points NDArray[floating]

(nv, 3) vertex positions, as read.

required
triangles NDArray[integer]

(nf, 3) triangles, as read.

required
labels NDArray[integer]

(nf, 2) the two materials of each triangle, as read.

required
source str

where the mesh came from, for the message.

required
stacklevel int

passed to warnings.warn. Defaults to 3.

3

remove_crop_interfaces

remove_crop_interfaces(solution, crop_interfaces: tuple[tuple[int, int], ...])

A tension solution without its crop interfaces, which must have come out undetermined.

Works on any solution dataclass with tensions (aligned with dict_tensions' keys), dict_tensions, component_of, undetermined, fragmented and n_components (junction_graph.ComponentTensionSolution, per_edge_tension_inference.YoungDupreLocalResult). A crop interface has no equation, so it is undetermined in the solve; removing it changes no other value. fragmented is re-read without it, so a mesh is not reported fragmented only because its crop is.

Parameters:

Name Type Description Default
solution ComponentTensionSolution | YoungDupreLocalResult

the solution as the estimator returned it.

required
crop_interfaces tuple[tuple[int, int], ...]

DcelData.crop_interfaces.

required

Returns:

Type Description

ComponentTensionSolution | YoungDupreLocalResult: a copy of solution (dataclasses.replace) without the crop interfaces, or solution itself when there are none.

Raises:

Type Description
RuntimeError

if a crop interface received a finite tension, which would mean an equation read the crop: a defect, never a result.

remove_crop_interfaces_from_map

remove_crop_interfaces_from_map(dict_tensions: dict[tuple[int, int], float], crop_interfaces: tuple[tuple[int, int], ...]) -> tuple[NDArray[np.float64], dict[tuple[int, int], float]]

remove_crop_interfaces for a method that returns a plain map: (array, map) without them.

Parameters:

Name Type Description Default
dict_tensions dict[tuple[int, int], float]

interface -> tension, in the method's own (sorted) key order.

required
crop_interfaces tuple[tuple[int, int], ...]

DcelData.crop_interfaces.

required

Returns:

Name Type Description
tuple NDArray[float64]

the tensions as an array in the map's key order, and the map, both without the

dict[tuple[int, int], float]

crop interfaces.

Raises:

Type Description
RuntimeError

if a crop interface received a finite tension.