Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions notebooks/cookbooks/analysis.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,67 @@
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"__Live Quick-Update Visualization__\n",
"\n",
"Non-linear searches in **PyAutoFit** can produce on-the-fly visualization while the fit is still running, so you can\n",
"monitor whether the model is behaving sensibly long before the search finishes.\n",
"\n",
"This is controlled by two parameters on the search:\n",
"\n",
"- `iterations_per_quick_update=N` \u2014 every `N` likelihood evaluations the search calls\n",
" `analysis.perform_quick_update(paths, instance)` with the current maximum-likelihood `instance`. The default\n",
" `perform_quick_update` implementation (on subclasses like `AnalysisImaging` in PyAutoGalaxy / PyAutoLens) renders\n",
" the relevant subplot (`subplot_fit.png` for imaging, `subplot_tracer.png` for tracers, etc.) into the output\n",
" folder so users can refresh their file browser and see how the fit is progressing.\n",
"- `background_quick_update=True` \u2014 runs `perform_quick_update` on a background daemon thread so the sampler is\n",
" never blocked while matplotlib renders and saves PNGs. A latest-only drop policy applies: if a new best-fit\n",
" arrives before the previous render finishes, the older request is silently replaced (we only ever care about the\n",
" most recent state).\n",
"\n",
"**Live in-cell rendering in Jupyter / Colab.** When the search runs inside a Jupyter or Colab notebook kernel, the\n",
"background worker additionally pushes each freshly-written `subplot_fit.png` into the active cell via\n",
"`IPython.display.update_display` with a stable `display_id`. The result: the cell that ran `search.fit(...)`\n",
"shows a **single self-updating image** during the fit, refreshing every `iterations_per_quick_update` evaluations,\n",
"rather than appending stacked frames or requiring you to open PNGs externally. No code change needed by the user\n",
"\u2014 the worker auto-detects the kernel.\n",
"\n",
"**Script mode is unchanged.** When running outside a kernel (e.g. `python my_fit.py` from a terminal), no\n",
"IPython side effects fire. The PNGs still land on disk under the search's output folder as before. `IPython` is\n",
"only imported when actually running inside a kernel.\n",
"\n",
"**Opt-out.** Set `PYAUTO_DISABLE_IPYTHON_DISPLAY=1` to skip the in-cell display step even inside a kernel \u2014\n",
"useful for `papermill` / automated `nbconvert` pipelines that want PNGs on disk but no display side effects.\n",
"\n",
"The API shape looks like this (commented out \u2014 see the workspace `start_here.py` for a runnable end-to-end\n",
"example):\n",
"\n",
"```python\n",
"# search = af.Nautilus(\n",
"# path_prefix=\"cookbooks/quick_update\",\n",
"# name=\"example\",\n",
"# iterations_per_quick_update=50, # call perform_quick_update every 50 likelihood evals\n",
"# background_quick_update=True, # run rendering on a daemon thread\n",
"# number_of_cores=1,\n",
"# )\n",
"# result = search.fit(model=model, analysis=analysis)\n",
"```\n",
"\n",
"When this runs inside a Jupyter cell, the cell output is a single image that refreshes ~once per 50 evaluations\n",
"until the search converges. When run as `python my_fit.py`, the PNGs land at\n",
"`output/.../<search>/image/subplot_fit.png` and update on disk on the same cadence."
]
},
{
"cell_type": "code",
"metadata": {},
"source": [],
"outputs": [],
"execution_count": null
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
52 changes: 52 additions & 0 deletions scripts/cookbooks/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,58 @@ def log_likelihood_function(self, instance):
return log_likelihood


"""
__Live Quick-Update Visualization__

Non-linear searches in **PyAutoFit** can produce on-the-fly visualization while the fit is still running, so you can
monitor whether the model is behaving sensibly long before the search finishes.

This is controlled by two parameters on the search:

- `iterations_per_quick_update=N` — every `N` likelihood evaluations the search calls
`analysis.perform_quick_update(paths, instance)` with the current maximum-likelihood `instance`. The default
`perform_quick_update` implementation (on subclasses like `AnalysisImaging` in PyAutoGalaxy / PyAutoLens) renders
the relevant subplot (`subplot_fit.png` for imaging, `subplot_tracer.png` for tracers, etc.) into the output
folder so users can refresh their file browser and see how the fit is progressing.
- `background_quick_update=True` — runs `perform_quick_update` on a background daemon thread so the sampler is
never blocked while matplotlib renders and saves PNGs. A latest-only drop policy applies: if a new best-fit
arrives before the previous render finishes, the older request is silently replaced (we only ever care about the
most recent state).

**Live in-cell rendering in Jupyter / Colab.** When the search runs inside a Jupyter or Colab notebook kernel, the
background worker additionally pushes each freshly-written `subplot_fit.png` into the active cell via
`IPython.display.update_display` with a stable `display_id`. The result: the cell that ran `search.fit(...)`
shows a **single self-updating image** during the fit, refreshing every `iterations_per_quick_update` evaluations,
rather than appending stacked frames or requiring you to open PNGs externally. No code change needed by the user
— the worker auto-detects the kernel.

**Script mode is unchanged.** When running outside a kernel (e.g. `python my_fit.py` from a terminal), no
IPython side effects fire. The PNGs still land on disk under the search's output folder as before. `IPython` is
only imported when actually running inside a kernel.

**Opt-out.** Set `PYAUTO_DISABLE_IPYTHON_DISPLAY=1` to skip the in-cell display step even inside a kernel —
useful for `papermill` / automated `nbconvert` pipelines that want PNGs on disk but no display side effects.

The API shape looks like this (commented out — see the workspace `start_here.py` for a runnable end-to-end
example):

```python
# search = af.Nautilus(
# path_prefix="cookbooks/quick_update",
# name="example",
# iterations_per_quick_update=50, # call perform_quick_update every 50 likelihood evals
# background_quick_update=True, # run rendering on a daemon thread
# number_of_cores=1,
# )
# result = search.fit(model=model, analysis=analysis)
```

When this runs inside a Jupyter cell, the cell output is a single image that refreshes ~once per 50 evaluations
until the search converges. When run as `python my_fit.py`, the PNGs land at
`output/.../<search>/image/subplot_fit.png` and update on disk on the same cadence.
"""


"""
__Custom Result__

Expand Down
Loading