Skip to content

Result files

The result files of the foambryo command, for every front end that writes or reads them.

foambryo infer and foambryo infer-over-seeds write CSV tables and a JSON run record, run.json (schema 1); the napari plugin writes the same files. Both use this module, so a table written by either reads back as the library's 64-bit numbers, and a run record has the same keys:

  • the tables: write_tension_table / read_tension_table, write_pressure_table / read_pressure_table, the seed ensemble's write_ensemble_tension_table and write_per_seed_tension_table and their readers, the solve diagnostics' write_solve_table / read_solve_table (solves.csv, one row per linear solve) and write_spectra (spectra.npz), and format_float, the shortest decimal string that reads back as the same float. The file names are TENSION_TABLE, PRESSURE_TABLE, SOLVE_TABLE, SPECTRA, RUN_RECORD, ...; the readers and writers take a pathlib.Path;
  • the run record: infer_run_record and ensemble_run_record build it, write_run_record writes it, read_run_record reads it; RUN_RECORD_SCHEMA is its schema number;
  • what a run record names: the methods by their command-line spellings (option_name, TENSION_METHODS, PRESSURE_METHODS, DIAGNOSTICS), the versions (library_versions), and the warnings raised, each once with its count (WarningCollector).

The tables and the record's writers are implemented in foambryo._result_tables; this module is their public interface. Changing a column, or a run-record key's name or meaning, makes a new schema.

WarningCollector

WarningCollector()

Catch the warnings raised inside a block, and count each distinct one.

Use it as a context manager (with WarningCollector() as collector: ...). DeprecationWarning, PendingDeprecationWarning, ImportWarning and ResourceWarning are ignored inside the block (neither shown nor counted); every other warning is caught, wherever it is raised, rather than once per code location, so a count is the number of times it was raised. Caught warnings are not shown. After the block, summary holds one entry per distinct warning (same category and message), {"category": ..., "message": ..., "count": ...} with the category's class name, in the order they were first raised: a run record's warnings.

Start with an empty summary.

file_sha256

file_sha256(path: Path) -> str

The SHA-256 of a file's bytes (path, a pathlib.Path), as 64 hexadecimal digits.

format_float

format_float(value: float) -> str

The shortest decimal string that reads back as the same float (nan, inf, -inf as such).

json_safe

json_safe(value: Any) -> Any

Convert numpy scalars and arrays, tuples and non-finite floats into plain JSON values.

Non-finite floats become the strings "nan", "inf", "-inf": JSON has no such numbers, and a reader that meets a bare NaN token (which Python's json would write) may refuse the file.

read_ensemble_tension_table

read_ensemble_tension_table(path: Path) -> dict[tuple[int, int], tuple[float, float, int, bool]]

Read foambryo infer-over-seeds' tensions.csv.

Parameters:

Name Type Description Default
path Path

the file (a pathlib.Path).

required

Returns:

Name Type Description
dict dict[tuple[int, int], tuple[float, float, int, bool]]

(label_1, label_2) -> (tension, tension_seed_sd, n_seeds_found, found_by_fewer_than_half_the_seeds).

Raises:

Type Description
ValueError

if the header is not ENSEMBLE_TENSION_COLUMNS or a row cannot be parsed.

read_per_seed_tension_table

read_per_seed_tension_table(path: Path) -> dict[int, dict[tuple[int, int], float]]

Read tensions_per_seed.csv back into seed -> {(label_1, label_2): tension}, in file order.

Parameters:

Name Type Description Default
path Path

the file (a pathlib.Path).

required

Returns:

Type Description
dict[int, dict[tuple[int, int], float]]

dict[int, dict[tuple[int, int], float]]: each seed's tensions.

Raises:

Type Description
ValueError

if the header is not seed,label_1,label_2,tension or a row cannot be parsed.

read_pressure_table

read_pressure_table(path: Path) -> dict[int, float]

Read a pressures.csv back into the library's map label -> pressure.

Parameters:

Name Type Description Default
path Path

the file (a pathlib.Path).

required

Returns:

Type Description
dict[int, float]

dict[int, float]: the pressures, bitwise the numbers written.

Raises:

Type Description
ValueError

if the header is not label,pressure or a row cannot be parsed.

read_run_record

read_run_record(path: Path) -> dict[str, Any]

Read a run record (path, a pathlib.Path).

Returns:

Name Type Description
dict dict[str, Any]

the record as written; non-finite numbers stay the strings "nan", "inf", "-inf".

Raises:

Type Description
ValueError

if the file is not valid JSON.

TypeError

if it is not a JSON object.

read_solve_table

read_solve_table(path: Path) -> list[dict[str, Any]]

Read solves.csv back: one dict per solve, integers and floats as such, empty fields as None.

Parameters:

Name Type Description Default
path Path

the file (a pathlib.Path).

required

Returns:

Type Description
list[dict[str, Any]]

list[dict[str, Any]]: one dict per row, keyed by SOLVE_COLUMNS, in file order; equal field by field to

list[dict[str, Any]]

the run's solves in run.json, the floats bitwise.

Raises:

Type Description
ValueError

if the header is not SOLVE_COLUMNS or a row cannot be parsed.

read_tension_table

read_tension_table(path: Path) -> dict[tuple[int, int], float]

Read a tensions.csv back into the library's map (label_1, label_2) -> tension.

Parameters:

Name Type Description Default
path Path

the file (a pathlib.Path).

required

Returns:

Type Description
dict[tuple[int, int], float]

dict[tuple[int, int], float]: the tensions, bitwise the numbers written.

Raises:

Type Description
ValueError

if the header is not label_1,label_2,tension or a row cannot be parsed.

write_ensemble_tension_table

write_ensemble_tension_table(path: Path, result: Any) -> None

Write foambryo infer-over-seeds' tensions.csv: one row per interface of the ensemble, sorted by label pair.

Columns ENSEMBLE_TENSION_COLUMNS: the ensemble tension and its seed SD in the shortest exact float format, the number of seeds that found the interface, and true/false for the flag.

Parameters:

Name Type Description Default
path Path

the file (a pathlib.Path), replaced if it exists.

required
result Any

a foambryo.seed_ensembles.SeedEnsembleResult (its tensions, tension_seed_sd, n_seeds_found and found_by_fewer_than_half_the_seeds maps).

required

write_per_seed_tension_table

write_per_seed_tension_table(path: Path, per_seed_tensions: dict[int, dict[tuple[int, int], float]]) -> None

Write tensions_per_seed.csv: seed,label_1,label_2,tension, each seed's own tensions.

Parameters:

Name Type Description Default
path Path

the file (a pathlib.Path), replaced if it exists.

required
per_seed_tensions dict[int, dict[tuple[int, int], float]]

seed -> {(label_1, label_2): tension}; the seeds are written in the map's order, each seed's interfaces sorted by label pair.

required

write_pressure_table

write_pressure_table(path: Path, dict_pressures: dict[int, float]) -> None

Write pressures.csv: label,pressure, one row per material (the medium, 0, included), sorted by label.

Parameters:

Name Type Description Default
path Path

the file (a pathlib.Path), replaced if it exists.

required
dict_pressures dict[int, float]

pressure per label; a nan pressure is written nan. Floats are written exactly (format_float).

required

write_run_record

write_run_record(path: Path, record: dict[str, Any]) -> None

Write the run record to path (a pathlib.Path) as indented JSON (UTF-8), non-finite numbers as strings.

Parameters:

Name Type Description Default
path Path

the file, replaced if it exists.

required
record dict[str, Any]

the record (infer_run_record or ensemble_run_record); converted by json_safe.

required

write_solve_table

write_solve_table(path: Path, records: list[Any]) -> None

Write solves.csv: one row per linear solve, in the order they ran (SOLVE_COLUMNS).

index is the solve's position (as in run.json's solves and spectra.npz's names). A value the solve does not have (the rank of a sparse solve, lsqr's counts on a dense one) is an empty field; floats are written exactly (format_float), a non-finite one as nan / inf. The run's warnings are not per solve: they are in run.json's warnings.

Parameters:

Name Type Description Default
path Path

the file (a pathlib.Path), replaced if it exists.

required
records list[Any]

the solves' foambryo.linear_solves.SolveRecords (an InferenceOutcome's records, or a SolveDiagnostics' records).

required

write_spectra

write_spectra(path: Path, singular_values: list[ndarray | None]) -> None

Write the singular values of the solves that have them, as foambryo.save_solve_diagnostics does.

Parameters:

Name Type Description Default
path Path

the .npz file, replaced if it exists.

required
singular_values list[ndarray | None]

per solve, in the order of the run record's solves, its singular values or None; solve i's are stored under singular_values_<i>.

required

write_tension_table

write_tension_table(path: Path, dict_tensions: dict[tuple[int, int], float]) -> None

Write tensions.csv: label_1,label_2,tension, one row per interface, sorted by the label pair.

Parameters:

Name Type Description Default
path Path

the file (a pathlib.Path), replaced if it exists.

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

tension per interface, keyed (label_1, label_2) with label_1 < label_2; a nan tension is written nan. Floats are written exactly (format_float).

required

option_name

option_name(member: Enum) -> str

The command-line spelling of a method: its enumeration name in lower case, hyphenated.

YoungDupre -> young-dupre, ForceBalanceMAP -> force-balance-map, WeightedLaplace -> weighted-laplace.

library_versions

library_versions(extra: Iterable[str] = ()) -> dict[str, str]

The versions a run record names: Python, foambryo, delaunay-watershed-3d, NumPy, SciPy, then extra.

Parameters:

Name Type Description Default
extra Iterable[str]

further distributions to name, for example a front end's own ("napari").

()

Returns:

Type Description
dict[str, str]

dict[str, str]: distribution -> version, "not installed" when it is not.

read_rec_metadata

read_rec_metadata(path: Path) -> dict[str, Any] | None

A .rec file's metadata appendix as delaunay-watershed-3d reads it, its _version key renamed.

Parameters:

Name Type Description Default
path Path

the mesh file (a pathlib.Path); only the suffixes .rec and .arec are read.

required

Returns:

Type Description
dict[str, Any] | None

dict | None: the appendix with _version as appendix_version; None for another suffix, a file without

dict[str, Any] | None

an appendix, or a delaunay-watershed-3d that cannot read one.

infer_units

infer_units(mean_tension: float, metadata: dict[str, Any] | None) -> dict[str, str]

The units a run record states: tensions relative to their mean, pressures in tension per mesh length.

Parameters:

Name Type Description Default
mean_tension float

the mean the tensions were gauged to.

required
metadata dict[str, Any] | None

the mesh file's appendix (read_rec_metadata), which says whether the mesh is in physical units.

required

Returns:

Type Description
dict[str, str]

dict[str, str]: {"tension": "relative, gauged to a mean tension of <T>", "pressure": "tension per <unit>"},

dict[str, str]

the unit being the appendix's spacing_unit for physical coordinates, voxel for voxel coordinates,

dict[str, str]

else mesh length unit (not recorded in the mesh file).

count_undetermined

count_undetermined(values: dict | None) -> int | None

How many values of a map (key -> float) are not finite; None when the map itself is None.

infer_run_record

infer_run_record(*, command: str, arguments: Sequence[str], date: str, elapsed_seconds: float, input_record: dict[str, Any], options: dict[str, Any], mesh: DcelData, outcome: InferenceOutcome, units: dict[str, str], warnings_summary: list[dict[str, Any]], outputs: list[str], versions: dict[str, str] | None = None) -> dict[str, Any]

The run record of an inference on one mesh, schema 1, as foambryo infer writes it.

Parameters:

Name Type Description Default
command str

the command that ran ("foambryo infer", or a front end's name).

required
arguments Sequence[str]

its arguments.

required
date str

when it started, ISO 8601.

required
elapsed_seconds float

how long it took.

required
input_record dict[str, Any]

the mesh file: path, sha256, bytes, metadata.

required
options dict[str, Any]

the options by their command-line names (tension_method, pressure_method, mean_tension, base_pressure, solver, diagnostics), the methods spelled as option_name spells them; diagnostics is required ("none", "basic" or "spectrum").

required
mesh DcelData

the mesh inferred on.

required
outcome InferenceOutcome

what foambryo.infer_tensions_then_pressures returned.

required
units dict[str, str]

infer_units.

required
warnings_summary list[dict[str, Any]]

WarningCollector.summary.

required
outputs list[str]

the files written beside the record, the record included.

required
versions dict[str, str] | None

library_versions() by default.

None

Returns:

Name Type Description
dict dict[str, Any]

the record, for write_run_record: schema, command, arguments, date, elapsed_seconds,

dict[str, Any]

versions, input, options, library_call, mesh (counts and cut cells), results (counts of the

dict[str, Any]

values and of the undetermined ones), units, status, error, warnings, solves (None with

dict[str, Any]

diagnostics "none") and outputs.

Raises:

Type Description
KeyError

if options has no diagnostics.

ensemble_library_call

ensemble_library_call(*, n_seeds: int, min_distance: int, mode: TensionComputationMethod, angle_reading: str, combine: str, max_workers: int, spacing: tuple[float, float, float]) -> str

The infer_tensions_over_seeds call of a seed ensemble over the seeds 0..N-1, as text (run.json's).

Every argument is keyword-only and is written into the call as given: n_seeds as seeds=range(N), mode by its enumeration name, spacing as (dz, dy, dx).

ensemble_run_record

ensemble_run_record(*, command: str, arguments: Sequence[str], date: str, elapsed_seconds: float, input_record: dict[str, Any], options: dict[str, Any], seeds: list[int], library_call: str, result: SeedEnsembleResult | None, length_unit: str, status: str, error: str | None, warnings_summary: list[dict[str, Any]], outputs: list[str], versions: dict[str, str] | None = None) -> dict[str, Any]

The run record of a seed ensemble, schema 1, as foambryo infer-over-seeds writes it.

Parameters:

Name Type Description Default
command str

the command that ran.

required
arguments Sequence[str]

its arguments.

required
date str

when it started, ISO 8601.

required
elapsed_seconds float

how long it took.

required
input_record dict[str, Any]

the mask: path, sha256, bytes, shape, spacing, spacing_unit, spacing_from.

required
options dict[str, Any]

seeds (N), combine, angle_reading, tension_method, min_distance, max_workers.

required
seeds list[int]

the seeds, 0..N-1.

required
library_call str

ensemble_library_call.

required
result SeedEnsembleResult | None

what infer_tensions_over_seeds returned, or None when it refused.

required
length_unit str

the unit of the spacing.

required
status str

"complete" or "failed".

required
error str | None

the library's message when it refused, else None.

required
warnings_summary list[dict[str, Any]]

WarningCollector.summary.

required
outputs list[str]

the files written beside the record, the record included.

required
versions dict[str, str] | None

library_versions() by default.

None

Returns:

Name Type Description
dict dict[str, Any]

the record, for write_run_record: schema, command, arguments, date, elapsed_seconds,

dict[str, Any]

versions, input, options, seeds, library_call, reconstructions (one entry per seed: seed,

dict[str, Any]

points, triangles, crop_faces, seconds; None when refused), results (counts), units,

dict[str, Any]

status, error, warnings and outputs.