The command line, from a mask to the figures¶
Examples/command_line_example.sh runs every sub-command of foambryo on a doublet at equilibrium (two equal spheres split by a plane), whose three tensions are all 1 and whose pressures are 2/R = 0.133 per um: foambryo mesh (from a .npz that records its voxel size, and from a .npy stack with --spacing), foambryo infer (with --diagnostics basic, and --no-pressures), foambryo view (--colour-bars without a window, --figure with one) and foambryo infer-over-seeds.
pip install "foambryo[viewing]"
sh command_line_example.sh

foambryo view doublet.rec --results results --figure results/figure.png --no-show: the doublet's tensions and pressures (shown by the tensions), with the colour bars.
Output of one run¶
mask, for information (nothing is changed): 2 cells; 0 touch the image box (cut cells); 0 in several pieces; 0 pieces of medium enclosed by the tissue; 0 smaller than 5% of the median cell (4771.4 voxels)
wrote doublet.rec: 310 points, 630 triangles, 2 cells (0 cut by the image boundary)
mask, for information (nothing is changed): 2 cells; 0 touch the image box (cut cells); 0 in several pieces; 0 pieces of medium enclosed by the tissue; 0 smaller than 5% of the median cell (2385.7 voxels)
wrote doublet_from_the_stack.rec: 304 points, 625 triangles, 2 cells (0 cut by the image boundary)
wrote results/tensions.csv
wrote results/pressures.csv
wrote results/solves.csv
wrote results/run.json
wrote results-tensions-only/tensions.csv
wrote results-tensions-only/run.json
wrote results/colour_bars.png: tension 0.918712 to 1.08129, pressure 0 to 0.135339
wrote results/figure.png
wrote results-over-seeds/tensions.csv
wrote results-over-seeds/tensions_per_seed.csv
wrote results-over-seeds/run.json
label_1,label_2,tension
0,1,1.0365525429421798
0,2,1.0578284456386409
1,2,0.9056190114191799
label,pressure
0,0.0
1,0.13027858293102407
2,0.13533901454340083
index,system,solver,n_rows,n_unknowns,rank,residual_norm,condition_number,condition_number_source,seconds,lsqr_istop,lsqr_iterations,spectrum_seconds,spectrum_note,n_singular_values
0,YoungDupre tension system,dense lstsq,4,3,3,6.628683812140618e-16,1.2754666092060924,singular values of dense lstsq (2-norm),0.00010391700016043615,,,,,3
1,Variational pressure system,dense inv,2,2,2,0.0,1.393096799960001,SVD of the cells x cells matrix (2-norm; computed for diagnostics only),0.002161542000976624,,,,,2
label_1,label_2,tension
0,1,1.1035926439473065
0,2,1.1080629833257924
1,2,0.788344372726901
label_1,label_2,tension,tension_seed_sd,n_seeds_found,found_by_fewer_than_half_the_seeds
0,1,1.068962417273275,0.029247815548050605,8,false
0,2,1.0764760355509257,0.021868788532474117,8,false
1,2,0.854561547175799,0.04443751792585566,8,false
The script¶
#!/bin/sh
# The foambryo command, from a mask to the figures, on a synthetic mask whose answer is known.
#
# pip install "foambryo[viewing]"
# sh command_line_example.sh
#
# Everything is written into ./foambryo-command-example/. The mask is a doublet at equilibrium: two
# equal spheres of radius R = 30 voxels whose centres are R apart, split by the plane between them,
# so that the three surfaces meet at 120 degrees. All three tensions are then equal (1, with the
# default mean tension of 1) and each cell's pressure is 2 / R = 0.133 per um on voxels of 0.5 um
# (R = 15 um). The inferred values come within about 10 % of these: the gap is the cost of
# meshing a voxel mask at this size.
#
# The steps:
# 1. foambryo mesh the mask's mesh, in um (a .npz that records its voxel size; then a
# stack with voxels twice as long along z, whose size is given with --spacing)
# 2. foambryo infer tensions.csv, pressures.csv, run.json, and solves.csv with --diagnostics
# 3. foambryo infer --no-pressures the tensions only
# 4. foambryo view the colour bars without a window (--colour-bars, --no-show), and the
# view itself as a figure (--figure; needs Polyscope and a display)
# 5. foambryo infer-over-seeds the tensions over eight reconstructions, with their spread
set -e
mkdir -p foambryo-command-example
cd foambryo-command-example
python - <<'EOF'
import numpy as np
n, radius = 102, 30
z, y, x = np.indices((n, n, n))
c = (n - 1) / 2
left = (z - c) ** 2 + (y - c) ** 2 + (x - (c - radius / 2)) ** 2 <= radius**2
right = (z - c) ** 2 + (y - c) ** 2 + (x - (c + radius / 2)) ** 2 <= radius**2
mask = np.where(left | right, np.where(x < c, 1, 2), 0).astype(np.uint16)
np.savez("doublet.npz", mask=mask, spacing=np.array([0.5, 0.5, 0.5]), spacing_unit=np.array("um"))
np.save("doublet_every_second_z_slice.npy", mask[::2]) # no voxel size in the file
EOF
# 1. The .npz records its spacing, so --spacing is not needed. The .npy records none: --spacing is
# required (there is no default), and a stack with longer voxels along z is resampled to cubic
# voxels before meshing (a message says so).
foambryo mesh doublet.npz -o doublet.rec --overwrite
foambryo mesh doublet_every_second_z_slice.npy --spacing 1.0 0.5 0.5 --spacing-unit um \
-o doublet_from_the_stack.rec --overwrite
# 2. Tensions and pressures, with the defaults of the library (bit for bit those of infer_forces),
# and one row per linear solve in solves.csv.
foambryo infer doublet.rec -o results --diagnostics basic --overwrite
# 3. The tensions only (no pressures.csv; run.json says the pressures were not computed).
foambryo infer doublet_from_the_stack.rec -o results-tensions-only --no-pressures --overwrite
# 4. The colour bars need neither a display nor Polyscope. The figure (the view with its colour bars
# and length scale bar) needs both; without a display, this step says so and the script goes on.
foambryo view doublet.rec --results results --colour-bars results/colour_bars.png --no-show
foambryo view doublet.rec --results results --figure results/figure.png --no-show \
|| echo "no figure: 'foambryo view --figure' needs Polyscope and a display"
# 5. The same mask reconstructed at the dither seeds 0 to 7, and the tensions averaged over them:
# tensions.csv gains the spread over the seeds, and tensions_per_seed.csv holds each seed's own
# values. The spread is a lower bound on the error, not an error bar.
foambryo infer-over-seeds doublet.npz -o results-over-seeds --seeds 8 --overwrite
cat results/tensions.csv
cat results/pressures.csv
cat results/solves.csv
cat results-tensions-only/tensions.csv
cat results-over-seeds/tensions.csv
# To look at the tissue in the window (needs a display):
# foambryo view doublet.rec --results results
# or start from the mask, and reconstruct and infer in the window:
# foambryo view doublet.npz
Every option, file, column, exit code and message: the command-line specification.