spacr.crop_source¶
Where a classifier’s training images come from.
TWO NAMES FOR THE ONE CHOICE, and they are the same two every other panel in
spaCR asks it with – LOAD IMAGES and STREAM IMAGES. Training used to ask the
same question in a private vocabulary (pre_generated / on_demand),
which is one idea in two spellings: a user reading the annotation panel and
the training panel could not tell they were being asked the same thing, and
the two halves of the code could not tell either.
png— load pre-generated images (default)Read crops previously written by the measurement workflow.
path_stringfilters paths by substring andfile_typefilters by image extension. This source performs no cropping.merged— stream imagesExtract crops during training from
merged/*.npyarrays.extract_channelsselects the intensity planes andobject_arrayselects the labelled mask plane that defines each object’s extent. Whencoordinate_columnsare configured, database coordinates instead define fixed bounding-box crops.generate— generate images, then load themMaterialize a complete crop set on disk before training, then read it through the same file-backed path as
png. This is a preprocessing action rather than a streaming source.
The stored values did not change. png and merged are what
spacr.crops.resolve_crop_source has always read, so a settings file
written under either vocabulary means what it always meant:
pre_generated, load_images and auto all arrive as LOAD IMAGES,
on_demand and stream_images as STREAM IMAGES. CROP_SOURCE_ALIASES
is that migration, in one place, and it is what stops a panel that has been
renamed from handing this module a word it refuses.
Why streaming exists. Pre-cutting every crop writes a copy of the dataset to disk before a single epoch runs, and every change of crop size or channel selection writes another. Cutting as training runs costs a slice per object and no disk at all.
Bounding box versus object. A bounding box is the smallest rectangle containing the object; an object crop masks everything outside it away. Both are useful – the background around a cell is sometimes signal and sometimes contamination – so it is a setting. Database-sourced objects can only ever be bounding boxes: a coordinate has no outline to mask against.
Exceptions¶
A crop source that cannot produce images, and why. |
Functions¶
|
Cut a fixed box centred on a coordinate. |
|
Cut one object out of a merged array. |
|
Every object's crop from one merged array. |
|
Settings belonging to the OTHER sources -- what the panel greys out. |
|
Which plane of the merged array holds |
|
Whether one crop belongs in the dataset. |
|
The extension |
|
|
|
Which crop source a settings dict asks for, in the two names. |
|
The crops a settings dict selects, in the order given. |
|
Which planes of a merged array become image channels, by either name. |
|
Check a settings dict can actually produce crops. Returns the source. |
Module Contents¶
- exception spacr.crop_source.CropSourceError[source]¶
Bases:
ValueErrorA crop source that cannot produce images, and why.
Initialize self. See help(type(self)) for accurate signature.
- spacr.crop_source.crop_at(array: numpy.ndarray, row: float, column: float, *, channels: Sequence[int], size: int) numpy.ndarray | None[source]¶
Cut a fixed box centred on a coordinate.
The database path. Only a bounding box is possible here and that is not a limitation to be worked around: a coordinate has no outline, so there is nothing to mask against, and a crop that claimed to be object-shaped would be a rectangle wearing the wrong name.
- Parameters:
array – the merged stack,
(H, W, planes). Its rank is not checked ascrop_object()checks it, so a 2-D image raisesIndexErrorfrom the slice rather than aCropSourceError.row – centre on the FIRST axis – an image row, not
y. Floats are rounded half-to-even, Python’s rule, so a centroid of2.5lands on row 2 while3.5lands on row 4.column – centre on the second axis; rounded the same way.
channels – which planes become image channels, in the order given, so
[2, 0]returns them swapped. A bare int counts as a one-plane list. NOT bounds-checked here as it is incrop_object(): a plane the array does not have raisesIndexError, and a negative one silently counts back from the last plane. An empty list yields a zero-channel crop rather than None.size – the positive side length returned. Odd sizes keep the rounded coordinate at index
size // 2. A box crossing an array edge is zero-padded rather than clipped or rescaled, preserving its centre and pixel scale.
- Returns:
(size, size, len(channels))as float32, or None when the box falls entirely off the array.- Raises:
CropSourceError –
channelsis None or is not planes, orsizeis not positive.
- spacr.crop_source.crop_object(array: numpy.ndarray, mask: numpy.ndarray, label: int, *, channels: Sequence[int], shape: str = 'bounding_box', size: int | None = None, padding: int = 0) numpy.ndarray | None[source]¶
Cut one object out of a merged array.
- Parameters:
array – the merged stack,
(H, W, planes).mask – the plane holding this object’s labels.
label – which object.
channels – which planes become image channels, in order.
shape –
bounding_boxkeeps the rectangle’s contents;objectzeroes everything outside the object itself. The background around a cell is sometimes signal and sometimes contamination, which is why this is a choice rather than a default.size – resize the result to
size × sizewhen given. It must be positive;Nonepreserves the object’s natural bounding box.
- Returns:
(h, w, len(channels)), or None if the object is not there.- Raises:
CropSourceError – a plane the array does not have, or an explicit
sizethat is not positive.
- spacr.crop_source.crops_from_merged(array: numpy.ndarray, settings: Mapping[str, Any], *, labels: Sequence[int] | None = None) List[Tuple[int, numpy.ndarray]][source]¶
Every object’s crop from one merged array.
- Parameters:
array – merged
(height, width, planes)image whose configured object-mask plane supplies the labels and whose other planes supply the crop pixels.settings – crop settings used to choose the object mask, extracted channels, crop shape and optional fixed image size.
labels – only these objects; by default every label in the mask.
- Returns:
(label, image)pairs, skipping objects that are not present.- Raises:
CropSourceError – a setting that makes cutting impossible.
- spacr.crop_source.inapplicable_settings(source: str) Tuple[str, ...][source]¶
Settings belonging to the OTHER sources – what the panel greys out.
Greyed, never removed (INVARIANTS 6): a key absent from the dict makes the pipeline fall back to its own default, which can differ from the value the module needs and says nothing when it does.
Any spelling
CROP_SOURCE_ALIASESknows is accepted, because what a panel has in hand is the value stored in the settings file, not the name this module resolved it to.- Parameters:
source – the crop source whose settings stay active; any spelling in
CROP_SOURCE_ALIASES, matched case-insensitively. An unknown source raisesCropSourceError.
- spacr.crop_source.mask_plane_for(object_array: str, settings: Mapping[str, Any]) int[source]¶
Which plane of the merged array holds
object_array’s masks.Read from the
*_mask_dimsettings the mask step already writes, so the two cannot disagree about which plane is which.- Parameters:
object_array – the object name (e.g.
cell,nucleus); lower-cased and used to build the<name>_mask_dimsetting key.settings – the settings mapping the
<name>_mask_dimplane index is read from.
- Raises:
CropSourceError – the object has no mask plane, naming the setting that would give it one.
- spacr.crop_source.matches_path(path: str, *, path_string: str = '', file_type: Any = '') bool[source]¶
Whether one crop belongs in the dataset.
Two independent tests, which is the whole point of splitting them: WHICH OBJECT the crop is of (a substring of its path, e.g.
cell_png) and WHAT FORMAT it is in (its extension). One setting could never express “every nucleus crop, whatever format” or “every TIFF, whatever object”.- Parameters:
path – the crop’s file path, tested as a string for the
path_stringsubstring and for its extension.
- spacr.crop_source.normalise_extension(file_type: Any) str[source]¶
The extension
file_typenames, without its dot and lower-cased.It used to hold
'cell_png'– a path substring wearing a file type’s name, duplicatingpng_type. Now it is an extension and only that, so'.TIF','tif'and'tiff'all mean what they look like.- Parameters:
file_type – an extension such as
'.TIF','tif'or'cell_png'(only the part after the last underscore is kept); empty or None gives''.- Raises:
CropSourceError – an extension spaCR cannot read, named alongside the ones it can.
- spacr.crop_source.object_bounds(mask: numpy.ndarray, label: int) Tuple[int, int, int, int] | None[source]¶
(row0, row1, col0, col1)of one labelled object, or None if absent.Half-open on the far edge, like every other slice in Python, so the caller can index with it directly rather than remembering to add one.
- Parameters:
mask – 2-D label image holding the object.
label – the label value of the object to bound.
- spacr.crop_source.resolve_source(settings: Mapping[str, Any]) str[source]¶
Which crop source a settings dict asks for, in the two names.
Every spelling in
CROP_SOURCE_ALIASESresolves, so a settings file from any panel spaCR has shipped answers this question. Unset means LOAD IMAGES, which is the default everywhere the question is asked.- Parameters:
settings – the settings mapping; its
crop_sourcevalue is looked up inCROP_SOURCE_ALIASES, and an empty value meanspng.- Raises:
CropSourceError – an unrecognised source. Guessing would train on a different set of images than was asked for and report success.
- spacr.crop_source.select_crops(paths: Iterable[str], settings: Mapping[str, Any]) List[str][source]¶
The crops a settings dict selects, in the order given.
- Parameters:
paths – candidate crop file paths.
settings – the settings mapping;
path_string(or, failing that,png_type) andfile_typeare passed tomatches_path().
- spacr.crop_source.stream_planes(settings: Mapping[str, Any]) List[int][source]¶
Which planes of a merged array become image channels, by either name.
channel_arraysis the current spelling andextract_channelsthe older one; both are a list of plane indices and both are still written to settings files, so both are read here. The current spelling wins when a file carries both, because that is the one the panel is editing.- Parameters:
settings – the settings mapping;
channel_arraysis read first, thenextract_channels.- Raises:
CropSourceError – neither is set, naming the one to set.
- spacr.crop_source.validate(settings: Mapping[str, Any]) str[source]¶
Check a settings dict can actually produce crops. Returns the source.
Run before training rather than during it: discovering that the planes were never named after an hour of dataset building is a worse failure than refusing at the start, and the message here names the setting to fix.
- Parameters:
settings – the training settings mapping to check: the crop source, plus
file_typeforpngor the plane, crop-shape, coordinate and mask settings for a streamed source.- Raises:
CropSourceError – with what to change.