acia.notebook#
Jupyter notebook visualization mixin for image sequence sources.
- acia.notebook.normalize_to_uint8(image_array)[source]#
Normalize an image array to the uint8
[0, 255]range.A
uint8array is passed through unchanged; any other dtype is min-max scaled to[0, 255]. A flat array (max == min) maps to all zeros.
- class acia.notebook.JupyterVisualizationMixin[source]#
Bases:
objectMixin providing interactive Jupyter notebook visualization for image sequences.
This mixin expects the host class to implement the ImageSequenceSource interface with these properties/methods: - size_t: int - number of time frames - num_channels: int - number of channels - get_frame(frame: int) -> BaseImage
- Example usage:
- class MyImageSource(ImageSequenceSource, JupyterVisualizationMixin):
…
- class acia.notebook.ROICropper[source]#
Bases:
AnyWidgetInteractive rotated-rectangle ROI selector over frame 0 (anywidget).
Draw/drag/resize/rotate a rectangle over the first frame of an
ImageSequenceSourceand emit aRotatedCropSpec. Two ways to set the box, both feeding the same synced traits:Click >=3 points around the ROI (the
pointstrait); an observer runsfit_to_points()(cv2.minAreaRect) to seed the tightest oriented rectangle. The geometry lives in Python, so it is unit-tested.Drag the box / corner handles / rotate knob in the ESM
render().
ROI coordinates are kept in parent image pixels so
specplugs straight intocrop_rotated().Works in Jupyter/Colab and in marimo via
mo.ui.anywidget(cropper)(it IS-A ipywidgetsDOMWidget). The ESM JavaScript is best-effort and is verified only by a real notebook run, not by the headless test-suite.- center_x#
A float trait.
- center_y#
A float trait.
- width#
An integer trait.
- height#
An integer trait.
- angle#
A float trait.
- points#
An instance of a Python list.
- image_b64#
A trait for unicode strings.
- image_w#
An integer trait.
- image_h#
An integer trait.
- __init__(source, *, width=None, height=None, channel=None, **kwargs)[source]#
Build the widget from a source’s frame 0.
- Parameters:
source – The
ImageSequenceSourceto crop.width (int | None) – Default ROI width (px). Defaults to
frame_w // 2.height (int | None) – Default ROI height (px). Defaults to
frame_h // 2.channel (int | None) – Display channel for a multi-channel frame. Defaults to channel
0.**kwargs – Forwarded to
anywidget.AnyWidget.
- Return type:
None
- fit_to_points(points=None)[source]#
Fit the tightest oriented rectangle to
pointsand set traits.Uses
cv2.minAreaRecton the given (or thepointstrait’s)[x, y]image-px points, then normalizes the angle into(-45, 45]degrees (CCW, OpenCVgetRotationMatrix2D/RotatedCropSpecconvention), swapping width and height with each 90-degree step so the round-tripfit_to_points -> crop_rotatedstraightens the region. Sizes are rounded to positive ints.- Parameters:
points –
[[x, y], ...]image-px points. Defaults to the currentpointstrait whenNone.- Raises:
ValueError – If fewer than 3 points are supplied, or if the points are collinear/duplicate (degenerate rectangle).
- property spec#
Return the current ROI as a
RotatedCropSpec.
- save(dataset_dir, **kwargs)[source]#
Persist the crop via
save_crop_capture().- Parameters:
dataset_dir – Directory the capture is written to.
**kwargs – Forwarded to
save_crop_capture(frame,channel,clip_percentiles,source_ref).
- Returns:
dict – The
save_crop_captureresult.
- class acia.notebook.FilterExplorer[source]#
Bases:
AnyWidgetInteractive cell-filter threshold explorer with live mask preview.
Auto-builds one (min, max) slider per filter from the passed
filterslist (modular – add aCellFilterand it appears) and live-recolours the contour overlay (kept = green, dropped = red) as the handles move. The live filtering runs entirely client-side: each contour’s value under each filter is precomputed once in Python (reusing the goal-Evalue()calibration) and shipped to the browser, so dragging a slider needs no kernel round-trip (the workflow’s “reactive, no observer wiring”). All control ranges/handles are in each filter’s physical unit (µm, µm², dimensionless).The widget previews a single frame (
frame=0by default), drawing only that frame’s contours over that frame’s image.paramsandconfigured_filters()emit/restore frame-independent thresholds;filtered_overlay()applies them across the whole overlay viaapply_cell_filters().Works in Jupyter/Colab and in marimo via
mo.ui.anywidget(explorer). The ESM JavaScript is best-effort, verified by the headless Playwright suite (and a real notebook run), not by the pure-Python tests.- image_b64#
A trait for unicode strings.
- image_w#
An integer trait.
- image_h#
An integer trait.
- filter_specs#
An instance of a Python list.
- contours#
An instance of a Python list.
- selection#
An instance of a Python list.
- __init__(overlay, images, filters, properties, *, frame=0, channel=None, **kwargs)[source]#
Build the explorer from an overlay, a calibrated source and filters.
- Parameters:
overlay – The
Overlayto filter.images – The calibrated
ImageSequenceSource(must expose a non-Nonepixel_size).filters – A list of
CellFilterinstances – one slider control is built per filter.properties – The extractor table for
overlay(seeexecute()). Each filter’s slider is seeded from its own column, so it must contain a column named after every filter passed in.frame (int) – Frame to preview (image + its contours). Defaults to
0.channel (int | None) – Display channel for a multi-channel frame. Defaults to 0.
**kwargs – Forwarded to
anywidget.AnyWidget.
- Raises:
ValueError – If
imagesisNoneor itspixel_sizeisNone(physical-unit thresholds need calibration).- Return type:
None
- property params#
Current thresholds as
[{name, vmin, vmax}]pintQuantitys.A handle parked at its track extreme is reported as
None(open on that side), so a one-sided filter round-trips faithfully.
- configured_filters()[source]#
Update each passed filter’s
vmin/vmaxfrom the sliders.Mutates the filter instances supplied to
__init__in place (a handle at its extreme sets that bound toNone) and returns the list, ready forapply_cell_filters()or the scaled batch run.
- save(path)[source]#
Write the current thresholds to
pathasfilter_params.json.Serializes
[{name, unit, vmin, vmax}](magnitudes;Nonefor an open side) – a small spec the scaled batch run reloads to rebuild the filters.- Parameters:
path – Destination JSON file path.
- Returns:
list[dict] – The serialized filter parameters.
- class acia.notebook.SequenceDashboard[source]#
Bases:
AnyWidgetCurate positions + ROIs across a multi-position acquisition (anywidget).
A three-pane UI (position gallery / ROI editor / selection list) over a
SequenceFile. Browse positions, mark ROIs (draw or point-fit), and emit aSelectionManifest. Frames are read lazily from the source and pushed to the browser as PNG bytes; the widget never loads the whole (possibly hundreds-of-GB) file.Works in Jupyter/Colab and in marimo via
mo.ui.anywidget(dash). The ESM is best-effort and verified only by a real notebook run (or the Playwright suite in the devcontainer), not by the headless Python test-suite.- metadata#
An instance of a Python dict.
One or more traits can be passed to the constructor to validate the keys and/or values of the dict. If you need more detailed validation, you may use a custom validator method.
Changed in version 5.0: Added key_trait for validating dict keys.
Changed in version 5.0: Deprecated ambiguous
trait,traitsargs in favor ofvalue_trait,per_key_traits.
- positions#
An instance of a Python list.
- selections#
An instance of a Python list.
- roi_mode#
A trait for unicode strings.
- view_size#
An integer trait.
- auto_save#
A boolean (True, False) trait.
- preview_frame#
An integer trait.
- __init__(source, *, roi_mode='single', save_dir=None, preview_frame=None, **kwargs)[source]#
Build the dashboard from a source (no pixel reads at construction).
- Parameters:
source – A
SequenceFile, or a path/str that is opened viaopen_sequence().roi_mode (str) –
"single"(<=1 ROI/position) or"multi".save_dir – Default output directory for
save()(and hence for auto-save, which is on by default).Nonekeeps the previous behaviour of writing into the current working directory.preview_frame (int | None) – Which frame the gallery thumbnails and the ROI editor open on.
None(the default) picks the middle frame,num_timepoints // 2: in a growing culture frame 0 is typically empty, so opening there gives no indication whether a chamber holds cells at all. Clamped into range. Note this indexes the source’s timepoints – if a later export step truncates the sequence, pick a frame inside that range (seeanchor_frame).**kwargs – Forwarded to
anywidget.AnyWidget(e.g.auto_saveto start with auto-save switched off).
- Raises:
traitlets.TraitError – If
preview_frameis negative.- Return type:
None
- property manifest#
Build a
SelectionManifestfrom current state.
- save(directory=None)[source]#
Write
selection.json(+ previews) viasave_selection().- Parameters:
directory – Output dir; defaults to the
save_dirpassed to the constructor, and failing that to the current working directory (the notebook’s dir at run time).- Returns:
The path to the written
selection.json.- Return type:
- classmethod resume(manifest_or_path, source=None, **kwargs)[source]#
Reopen a dashboard pre-populated from a saved
selection.json.Lets a curation session be saved with
save()and continued later in a fresh dashboard, instead of starting over.- Parameters:
manifest_or_path – A path to a
selection.jsonfile (or its containing directory), or an already-loadedSelectionManifest.source –
Noneto reopen the manifest’s own source path, a path/str to apply the selections to a different file, or an already-openSequenceFile– same convention asload_selection().**kwargs – Forwarded to the constructor (e.g.
roi_modeto override the manifest’s saved mode).
- Returns:
A
SequenceDashboardwith.selectionsrestored.- Raises:
ValueError – If a selection’s position is out of range for
source.- Return type:
- class acia.notebook.RegistrationDashboard[source]#
Bases:
AnyWidgetPick + verify + batch-apply a drift-correction method (anywidget).
Pick one of the 5
RegistrationMethodimplementations (default"GradientECC"), verify it on sampled frames of a single position (drift trajectory + before/after), then batch-apply it across every position/frame of the acquisition with live progress and resumability. Frames are read lazily from the source; the widget never loads a whole (possibly hundreds-of-GB) file, and batch-apply holds at most one position’s frames in memory at a time.MaskedTemplateCorrelationadditionally needs amask_rect(RotatedCropSpec): themask_*traits and the ESM’s mask editor portROICropper’s click-to-fit + drag/resize/rotate interaction model (_fit_rotated_rect()is the same geometry helperSequenceDashboard’s point-fit tool uses) –ROICropperitself is not touched.Works in Jupyter/Colab and in marimo via
mo.ui.anywidget(dash). The ESM is best-effort and verified only by a real notebook run, not by the headless Python test-suite (no ESM/Playwright suite for this widget in v1, per the spec).- metadata#
An instance of a Python dict.
One or more traits can be passed to the constructor to validate the keys and/or values of the dict. If you need more detailed validation, you may use a custom validator method.
Changed in version 5.0: Added key_trait for validating dict keys.
Changed in version 5.0: Deprecated ambiguous
trait,traitsargs in favor ofvalue_trait,per_key_traits.
- positions#
An instance of a Python list.
- method_name#
A trait for unicode strings.
- n_sample_frames#
An integer trait.
- mask_center_x#
A float trait.
- mask_center_y#
A float trait.
- mask_width#
An integer trait.
- mask_height#
An integer trait.
- mask_angle#
A float trait.
- mask_points#
An instance of a Python list.
- mask_image_b64#
A trait for unicode strings.
- mask_image_w#
An integer trait.
- mask_image_h#
An integer trait.
- batch_running#
A boolean (True, False) trait.
- __init__(source, *, method_name='GradientECC', method_kwargs=None, reference_mode='reanchor', low_confidence='keep', **kwargs)[source]#
Build the dashboard from a source (no pixel reads at construction).
- Parameters:
source – A
SequenceFile, or a path/str that is opened viaopen_sequence().method_name (str) – The initially-selected
RegistrationMethodname; one of_REGISTRATION_METHOD_NAMES.method_kwargs (dict | None) – Constructor keyword arguments for the chosen method, e.g.
{"min_confidence": 0.8}or{"exclude_rects": [...]}forGradientECC. Deliberately a plain attribute rather than a synced trait: arbitrary Python objects (RotatedCropSpecinstances) must not be pushed across the widget comm.reference_mode (str) – The reference policy batch-apply registers under; one of
MODES. Defaults to"reanchor", which only changes what happens to a frame that would otherwise be recorded as a failure. Pass"fixed"to always compare against frame 0.low_confidence (str) – What the registration method does with a fit scoring below its own confidence threshold; one of
LOW_CONFIDENCE_POLICIES. Defaults to"keep", so every frame ends up with a stored transform and a weak fit is reported through itsconfidence(and a warning) rather than by being missing. Pass"reject"to record those frames infailed_framesinstead, leaving them without a transform. Forwarded to the method ason_low_confidence; an expliciton_low_confidenceinmethod_kwargswins. Methods with no confidence gate ignore it.**kwargs – Forwarded to
anywidget.AnyWidget.
- Raises:
ValueError – If
reference_modeorlow_confidenceis not a known value.- Return type:
None
- property mask_rect: RotatedCropSpec | None#
The current mask rect, or
Noneif none has been drawn yet.
- batch_apply(directory=None, positions=None, sources=None, method_kwargs=None)[source]#
Estimate transforms for every (or a subset of) position, live.
For the currently-selected
method_name, processes every position inpositions(default: all), one at a time, estimating aFrameTransformper frame against that position’s own frame 0. Sends a"progress"message (with best-effortelapsed_seconds/eta_seconds) after every frame, and persists the manifest both after every position and periodically within a position (everyCHECKPOINT_INTERVALnewly-estimated frames), so an interrupted run can be resumed. A position already fully complete (every frame accounted for intransforms/failed_frames) is skipped; a partial one resumes from its first uncomputed frame instead of being re-skipped or fully redone. A prior record recorded under a differentmethod_nameis never treated as resume/skip data for the currently-selected method – the position is processed from scratch instead of silently merging frames across methods. A whole-position failure (whether from_register_positionitself or from the resume/skip bookkeeping above it, e.g. asize_tlookup) never aborts the rest of the run, and never discards progress already checkpointed for that position in this or a prior run – the failure is recorded as a note on top of whatever record (checkpointed or pre-existing) is already known, not as a fresh empty one.Because a complete position is skipped and a partial one resumes by count, re-running over an existing
registration_transforms.jsonnever re-estimates frames a previous run already recorded – including ones it recorded as failures. Changinglow_confidence(or any method setting) therefore does not retroactively fix an existing file: delete it, or the affected records, and register those positions again.- Parameters:
directory – Output directory for
registration_transforms.json; defaults to the current working directory. Also the path consulted for already-completed positions to skip.positions – Optional subset of position indices to process; defaults to every position in the acquisition.
sources – Optional
{position: ImageSequenceSource}override – when a position has an entry, that source is registered instead ofself._file.position(position), and its ownsize_t(not the full position’s) is what “already complete” is checked against. Lets a caller limit registration to a sub-range via the lazy numpy-style indexing everyImageSequenceSourcealready supports, e.g.sources={2: seqfile.position(2)[:30]}to register only the first 30 frames of position 2. A position absent fromsources(or whensourcesisNone) falls back to the whole position, unchanged from before.method_kwargs – Constructor overrides for the registration method, applied to this call only and layered over the dashboard’s own
method_kwargs. The intended use is settings that differ per position – calling this once per position with that position’s ownGradientECCexclude_rects. Not recorded in the manifest:method_paramsis a single manifest-level dict, so per-position settings have nowhere to go without mislabelling one position’s values as another’s.
- Returns:
dict –
{"num_positions", "completed", "skipped", "failed_positions", "path"}.- Raises:
RuntimeError – If a batch-apply run is already in progress.
ValueError – If
method_nameis unknown, orMaskedTemplateCorrelationis selected without a mask rect.
- Return type:
- property manifest: RegistrationManifest#
Build a
RegistrationManifestfrom the accumulatedRegistrationRecordresults (mirrorsSequenceDashboard.manifestbuilding aSelectionManifest).