Scene construction#
The scene layer is the mutable working state that pipeline steps read and write
(canvas, movie, per-cell footprints). Most users never touch it directly; it is
public so step authors and notebooks can. finalize() turns a
built Scene into a Recording.
Scene#
.. py:class:: Scene(acq, rng, cells=
Bases: :py:class:object
The mutable working state a pipeline of steps mutates in place.
Holds the acquisition (which owns every µm↔px / s↔frame conversion), the RNG
every stochastic step draws from, the movie being built, the per-cell
records, the per-effect ground-truth side channel, and the optional
per-stage snapshots. Unlike a Spec it is not frozen - mutation is the
point.
The working movie is held in float64: effects accumulate additively
and multiplicatively across ~10 steps in honest radiometric units, and only
the final sensor step quantizes to integer counts. The downcast to
Output.store_dtype happens in finalize(), not here.
.. py:property:: Scene.movie :module: minisim :type: ~xarray.core.dataarray.DataArray
The working movie, materialized on first access (lazy; see fields above).
.. py:property:: Scene.has_movie :module: minisim :type: bool
Whether a movie buffer exists yet - ``True`` once a pixel step (or a
``.movie`` read) has materialized it. ``finalize`` uses this to skip the
observed-movie cast for a cell-domain-only partial build.
.. py:property:: Scene.canvas_shape :module: minisim :type: tuple[int, int]
The tissue-canvas ``(height, width)`` **without** materializing the movie.
Equals the movie's spatial shape once one exists (so a hand-set oversized
canvas is honored); otherwise the sensor FOV padded by the motion margin.
Lets cell-domain steps (``place_neurons``, ``optics``) size their grid
without forcing the buffer into existence.
.. py:method:: Scene.zeros(acq, rng=None, margin_px=0) :module: minisim :classmethod:
A blank scene whose movie is all zeros - the base for additive builds.
.. py:method:: Scene.ones(acq, rng=None, margin_px=0) :module: minisim :classmethod:
A scene whose movie is all ones - the substrate for multiplicative-field tests.
A ``vignette`` or ``leakage`` step applied to an all-ones movie yields the
bare field, which is exactly what a single-step test inspects.
Cell#
.. py:class:: Cell(center_um, footprint_planted=None, observed_sigma_px=None, observed_gain=None, trace=None, spikes=None, amplitude=None, bleach=None, in_focus=None, optical_brightness=None, detectable=None) :module: minisim :canonical: minisim.scene.Cell
Bases: :py:class:object
One simulated neuron - the per-cell record steps fill in, pre-composite.
The fields mirror the per-cell structural columns of the eventual
GroundTruth output one-for-one, so finalize() can
stack them with no remapping. Each is populated by the step that owns it and
is None until then:
center_um- set byplace_neurons(the cell exists once it has a location). Placement is now purely spatial; brightness is not set here.footprint_planted- the sharp, peak-normalized soma mask, also fromplace_neurons; the ideal CNMF target.trace/spikes/amplitude- the noise-free calcium traceC, spike trainS, and the per-cell brightness/expression gain that scales the whole trace, all fromcell_activity. The gain is biology (how much fluorescence this cell emits per spike); measurement noise, and hence any SNR, emerges later fromopticsandsensor, not here.bleach- the intact-fluorophore envelopeB(t)from the optionalbleachingstep;compositeemitstrace · bleach, leavingtracethe clean calcium.Noneuntil/unless bleaching runs.observed_sigma_px/observed_gain/in_focus/optical_brightness- from theopticsstep. The observed (optically degraded) footprint is not stored: it is a deterministic functiongain · (planted ⊛ Gaussian(sigma_px))of the planted footprint (see :func:minisim.footprint.degrade_footprint), so the optics step keeps only the two scalars andcomposite/GroundTruth.A_observedregenerate the footprint on demand.in_focusis the geometric in-focus flag andoptical_brightnessthe depth-driven peak-brightness scalar.detectableis not an optics-only property and so is not set by the optics step: it is a whole-pipeline flag (optical brightness × illumination falloff, judged against the sensor noise floor) assembled infinalize().
center_um is (z, y, x) in µm (depth first); pixel coordinates are a
conversion away via acq.um_to_px and are not stored, to avoid drift.
.. py:method:: Cell.observed_footprint() :module: minisim
The optically degraded footprint, regenerated from the planted one.
Returns the planted footprint blurred + dimmed by the optics step's
scalars (``observed_sigma_px``/``observed_gain``), or the planted footprint
unchanged when the optics step has not run, or ``None`` if the cell has no
footprint yet. Regenerated, not stored: it is a deterministic function of
the planted footprint (see :func:`minisim.footprint.degrade_footprint`),
and deep cells' observed footprints are near-full-canvas, so storing them
would dominate memory. ``composite`` and ``GroundTruth.A_observed`` call this.
GroundTruthBuilder#
.. py:class:: GroundTruthBuilder(shifts=None, illumination=None, vignette=None, leakage=None, neuropil_temporal=None, neuropil_spatial=None, neuropil_population=None, focal_depth_um=None) :module: minisim :canonical: minisim.scene.GroundTruthBuilder
Bases: :py:class:object
Per-effect ground-truth side channel - each non-cell step writes its own.
The per-cell truth lives on :attr:Scene.cells; this accumulator holds the
per-effect fields that have no natural per-cell home. Each is
None until the step that produces it runs, so a None value is the
honest signal that the effect is absent from this recording:
shifts- rigid (dy, dx) per frame, frombrain_motion.illumination/vignette/leakage- the static (height, width) optical fields (excitation falloff, collection falloff, additive glow).neuropil_temporal/neuropil_spatial- the diffuse-background components;neuropil_population- the (frame,) population driver that modulates them (Nonewhen no cells were active to drive it).
The steps that fill these slots live in :mod:minisim.steps, and
finalize() reads them into the frozen GroundTruth.