Simulation#
simulate#
- minisim.simulate(spec, *, until=None, perf=None)[source]#
Run a full recording specification and return the typed
Recording.Seeds the RNG from
spec.seed(so a spec + seed fully determines the output), sizes the motion margin, runs the steps inspec.stepsorder - already the canonical pipeline order, sinceSpecsorts the list on construction, so the order a caller listed them in is irrelevant - optionally snapshots each movie stage, and finalizes.untilstops after the named stage: it matches either astep.name(e.g."vignette") or the step’s speckind(e.g."composite", whose stage name is the less obvious"cells_only"), so both spellings work. Anuntilthat matches no step raises rather than silently running the whole pipeline.Pass a
PerfTrackerasperfto record per-step (andfinalize) wall time; it is a no-op whenNone(the default), so an un-profiled run pays nothing for the instrumentation.
simulate_cached#
- minisim.simulate_cached(spec, *, root=None)[source]
Return the recording for
spec, loading from cache or simulating on a miss.- Parameters:
spec (Spec) – The recording spec; its
cache_keyis the cache key.root (str | Path | None) – Cache directory. Defaults to
cache_dir()($MINISIM_CACHEor~/.cache/minisim).
- Return type:
Notes
The cache is keyed by filename (
{cache_key}.zarr): a changed spec serializes to a new key, hence a new filename and a clean miss, so the cache never serves a recording for the wrong spec. A hit is served byRecording.load(); a miss runssimulate()and persists the result withRecording.save()before returning it.
simulate_video#
- minisim.simulate_video(spec, path, *, chunk_frames=None, fps=None, vmin=0.0, vmax=None, codec='Y800', progress=True, perf=None)[source]#
Simulate
specstraight to a grayscale video atpath, streaming to disk.Renders and digitizes the recording in frame chunks and writes each to an incrementally-opened
cv2.VideoWriter, so the whole movie is never held in memory (unlikesimulate(spec).observed, which is). The produced counts matchsimulate(spec).observedexactly.vmaxsets the count mapped to white (vmin→ black); it defaults to the sensor’s full ADC range (2**bit_depth - 1) when the spec has asensorstep, so the file faithfully shows the true ADC utilization (a dim, honest frame). For a sensorless (continuous-intensity) spec there is no natural scale, sovmaxmust be given.codecis a 4-character opencv fourcc; it defaults to"Y800": uncompressed 8-bit grayscale, so the file carries the exact counts with no compression artifacts (large: ~``n_frames * H * W`` bytes). For a small lossy file pass"MJPG". Writing uses opencv’s bundled ffmpeg, so no system ffmpeg ormediapyextra is needed. Returnspath.Pass a
PerfTrackerasperfto record where the streamed write spends its time: the one-offsetup(cell steps + footprint build), each per-chunk render sub-phase (composite,neuropil,motion_crop,photon_field,leakage,digitize), and theencode+writetail. It is a no-op whenNone(the default).
sweep#
- minisim.sweep(base, axes)[source]#
Yield one validated
SweptSpecper point in the Cartesian product ofaxes.- Parameters:
base (Spec) – The spec every combination starts from; never mutated.
Maps a dotted override path to the list of values to sweep it over. Path forms:
"acquisition.optics.na"- walk nested models;"steps.<kind>.<field>"- address the step with that (unique)kind, e.g."steps.place_neurons.density_per_mm3";"seed"- a top-level field.
- Yields:
SweptSpec – The base with this combination of overrides applied and all cross-field validators re-run - an axis value that yields an invalid combination (
na=-1, a soma larger than the FOV, …) raises here. An emptyaxesyields the base once withaxes={}.- Raises:
ValueError – For a path naming an unknown field, an unknown step kind, or one that descends into a non-model (scalar) field.
- Return type:
- pydantic model minisim.SweptSpec[source]#
Bases:
SpecA
Spectagged with the sweep-axis values that produced it.A genuine
Specsubclass, so it drops intosimulate()andRecordingunchanged.axesis excluded from serialization, so it never reachesmodel_dump_jsonand therefore leavesSpec.cache_key()identical to the equivalent plain spec - sweeping does not perturb cache dedup, and the tag simply vanishes when a recording is persisted.- Fields:
axes (dict)