spacr.object_settings_table¶
The repeated per-object settings, as one row per question.
78 of Mask’s 201 settings are the SAME 20 questions asked once per object
type – cell_diameter, nucleus_diameter, pathogen_diameter,
organelle_diameter and so on across twenty shapes. A table was chosen
over tabs and over leaving the names flat.
WHY A TABLE IS NOT A COSMETIC CHOICE. The organelle count is arbitrary, up to spacr.organelle_types.MAX_ORGANELLES of 26. A
flat vocabulary grows by TWENTY SETTINGS per organelle, so the module would
be asking several hundred questions at the ceiling. In a table a new
organelle is a new COLUMN and the number of questions does not move. The two
instructions meet exactly here, and this is the shape that lets 326 land.
WHAT THIS MODULE IS AND IS NOT. It is the MODEL: it reads a flat settings
dict into a table and writes a table back out, losslessly. It draws nothing.
A GUI renders to_table() and calls from_table() on edit, and the
headless path never has to know the table exists – the stored keys are
unchanged, so no settings file, notebook or tutorial migrates.
THAT IS THE WHOLE POINT OF DOING IT THIS WAY. The obvious alternative – storing a nested
{question: {object: value}}structure – would be a file-format change, and every saved settings file, every published tutorial, and the headlessspacr-runpath would have to move with it. The presentation is what was wrong, so only the presentation changes.
Functions¶
|
What a column header reads. |
|
|
|
Flatten a table back to settings keys, over |
|
The distinct questions in |
|
Read a flat settings dict as |
|
Add a column for |
Module Contents¶
- spacr.object_settings_table.column_label(obj: str) str[source]¶
What a column header reads.
organellebis a storage spelling, not a thing a user recognises. The letter suffixes exist because object types are embedded in underscore-separated object keys andorganelle2is ambiguous with label 2 – an implementation constraint that has no business appearing in a column header.- Parameters:
obj – an object name from
OBJECT_ORDER, e.g."cell"or"organelleb". Organelle slots get their numbered label; any other name has underscores turned into spaces and is capitalised.
- spacr.object_settings_table.families(keys: Iterable[str]) Dict[str, List[str]][source]¶
{question: [objects that ask it]}, objects in display order.- Parameters:
keys – flat settings names such as
"cell_min_area"; names that do not start with a known object followed by_are skipped.
- spacr.object_settings_table.from_table(table: Mapping[str, Mapping[str, object]], base: Mapping[str, object] | None = None) Dict[str, object][source]¶
Flatten a table back to settings keys, over
baseif given.LOSSLESS WITH
to_table(), which is what makes the table safe to use as an editing surface: what the user sees is the settings file, rearranged and not transformed. A test round-trips every default settings dict.- Parameters:
table –
{question: {object: value}}.base – the settings the table came from. Keys the table does not cover are carried through unchanged, so a caller can edit the per-object half without holding the rest.
- spacr.object_settings_table.questions(keys: Iterable[str]) List[str][source]¶
The distinct questions in
keys, in first-seen order.ONE ENTRY PER SHAPE, however many objects ask it.
cell_diameterandnucleus_diameterare one question, which is the entire saving.- Parameters:
keys – flat settings names such as
"cell_diameter"; names that do not start with a known object followed by_are skipped.
- spacr.object_settings_table.to_table(settings: Mapping[str, object]) Dict[str, Dict[str, object]][source]¶
Read a flat settings dict as
{question: {object: value}}.Only the keys that ARE per-object questions are taken. Everything else –
src,verbose,n_jobs– is not a table row and is left where it is; a caller wanting the whole settings dict back usesfrom_table()with the original.A question a given object does not ask is ABSENT from its row rather than present as
None.cytoplasmhas no channel, no diameter and no detection method because it is derived rather than found in a channel, and a blank cell says that where aNonewould read as “not set yet”.- Parameters:
settings – a flat settings dict, e.g. Mask’s settings; it is only read.
- spacr.object_settings_table.widen(table: Mapping[str, Mapping[str, object]], obj: str, *, like: str | None = None) Dict[str, Dict[str, object]][source]¶
Add a column for
obj, copyinglike’s answers where it has them.THE OPERATION 326 NEEDS, and the reason the table exists. Adding an organelle is one call that adds one column; in the flat vocabulary it is twenty new settings that every consumer, tooltip table and translation catalog has to learn.
- Parameters:
obj – the object to add, e.g.
'organellec'.like – an existing object whose answers to copy as the starting point. Defaults to the first organelle when
objis one, because a second mitochondrion should start where the first one is rather than at a global default nobody chose.
Nested helpers¶
- _filter_text._num(value)¶
One bound as compact text; blank for an unset bound.
spacr/object_settings_table.py:178
- _parse_filter_text._side(value)¶
One side of the range as a number;
Nonewhen left blank.spacr/object_settings_table.py:218