Skip to content

perf: retro-optimize committed markdown PNGs; decide ellipse/modeling render #247

Description

@Jammy2211

Overview

Two deferred items from the batch-2a markdown-renderings rollout (autolens_workspace#264). Investigation before planning corrected the prompt's framing on both:

PNG size. optimize_pngs() already exists in PyAutoHands/autohands/generate_markdown.py:240 and runs after every extraction (:379) — it is forward-only by construction and never touches previously committed images. So the leftover is not "add an optimize step"; it is a one-off retro pass over already-committed PNGs. pngquant is the wrong tool: reusing optimize_pngs keeps retro-optimized files byte-identical to what a future re-render produces.

Measured across the six workspaces: 405 of 429 committed markdown PNGs are still RGBA (unoptimized); the 24 P-mode ones were rendered after PR #200. Running a 25-file sample through the existing algorithm: 88.4 MB → ~23 MB (26.1%) — roughly 65 MB saved, no quality loss beyond the 256-colour quantize already shipping.

Repo PNGs RGBA (to fix) markdown/
autolens_workspace 207 196 61 M
autogalaxy_workspace 122 115 22 M
HowToGalaxy 57 57 3.9 M
HowToFit 31 31 1.5 M
autofit_workspace 6 6 568 K
HowToLens 94 0 3.1 M (already done)

Caveat on the record: this shrinks the working tree and future clone-of-tip, not .git history — the old blobs stay in the pack. No history rewrite is on the table.

ellipse/modeling. autogalaxy_workspace/scripts/ellipse/modeling.py runs 22 sequential fits (2 x 10 DynestyStatic + 2 Drawer, lines 445-583), split across two notebook cells by the """ section markers — so it is two multi-hour cells, not one. There is currently no output/ellipse* in the workspace, so a render starts from zero. Rather than gamble on a bumped per-cell timeout, pre-run the script outside nbconvert so the fits land in output/, then let the render resume them near-instantly (the module docstring guarantees PyAutoFit completed-run resume). The max_minutes bump becomes a safety margin rather than a bet.

Plan

  • Add a --optimize-only mode to generate_markdown.py that reuses the existing optimize_pngs() over already-committed markdown/**/*_files/, and run it across all six workspaces — one deterministic ~65 MB win.
  • No dpi knob: quantize already delivers 74%, and a dpi drop would degrade every future render's readability for a smaller marginal gain.
  • For ellipse/modeling.py, measure one fit first; if the extrapolated 22-fit cost is under a 2-hour ceiling, pre-run the script to populate output/, then render via the resume path. Above the ceiling, leave the page out (as the prompt permits) and replace the yaml's "tracked as a follow-up" comment with a settled decision recording the measured cost.
  • Ship library-first (PyAutoHands), then the workspace commits.
Detailed implementation plan

Work Classification

Library (PyAutoHands tool change first; workspace commits follow).

Affected Repositories

  • PyAutoLabs/PyAutoHands (primary)
  • PyAutoLabs/autolens_workspace
  • PyAutoLabs/autogalaxy_workspace
  • PyAutoLabs/autofit_workspace
  • PyAutoLabs/HowToGalaxy
  • PyAutoLabs/HowToFit
  • PyAutoLabs/HowToLens (expected near-no-op)

Branch Survey

Repository Current Branch Dirty?
./PyAutoHands main clean
./autogalaxy_workspace main clean
./autolens_workspace main clean
./autofit_workspace main clean
./HowToGalaxy main clean
./HowToFit main clean
./HowToLens main clean

worktree_list_claimed empty; worktree_check_conflict exit 0 (no conflict). Unregistered-work warning: autogalaxy_workspace has a local feature/stored-sample-reconstruction-guard branch, not checked out and not claimed — not a conflict.

Suggested branch: feature/markdown-renderings-2a-leftovers
Worktree root: ~/Code/PyAutoLabs-wt/markdown-renderings-2a-leftovers/

Implementation Steps

Phase A — PyAutoHands (library)

  1. autohands/generate_markdown.py: add --optimize-only to the argparse block (:439). When set, skip load_examples / render / write_index; walk Path.cwd()/markdown for *_files/ dirs, call the existing optimize_pngs(files_dir) on each, print a per-repo before/after byte total. ~20 lines, no new dependency (Pillow already imported inside optimize_pngs).
  2. Do not add a dpi knob.
  3. Update the module docstring and docs/internals.md (if it documents this tool) to note the retro mode.

Phase B — PNG retro pass (workspaces, mechanical)

  1. Per repo in autolens_workspace, autogalaxy_workspace, autofit_workspace, HowToGalaxy, HowToFit, HowToLens, from the workspace root: python ../PyAutoHands/autohands/generate_markdown.py <project> --optimize-only.
  2. Verify: re-run the PNG mode census (expect all P), spot-check 3 rendered pages per repo, and confirm git status shows only markdown/**/*.png modified — nothing outside markdown/.
  3. HowToLens is expected to be a near-no-op; if it produces zero changes, no commit there.

Phase C — ellipse/modeling (measure, then decide)

  1. From autogalaxy_workspace, time a single fit in isolation (fit_0 of the Multiple-Ellipses loop, n_live=50, 2 free params) and extrapolate x22. Note this machine is WSL with a throttled nproc, so the script's number_of_cores=4 may itself be the cost driver — check that before blaming the sampler. Ceiling: 2 hours for the full 22-fit pre-run.
  2. If under the ceiling: run python scripts/ellipse/modeling.py directly to populate output/, then git status and restore any tracked file the script mutated — running outside generate_markdown.py loses its tracked-file protection, and dataset/imaging/ellipse does not currently exist so the auto-simulator will fire. Then add the entry to config/build/markdown_examples.yaml with max_minutes: 360, run generate_markdown.py autogalaxy --only ellipse/modeling (resume path), and replace the exclusion comment.
  3. If over the ceiling: leave the page out, and rewrite the yaml comment from "Tracked as a follow-up" to a closed decision recording the measured cost — so this does not come back a third time.

Phase D — ship

  1. ship_library for PyAutoHands, then ship_workspace for the workspace commits behind the library-first merge gate. ship_workspace has a known binary-leak trap — this task is all binaries by design, so state explicitly that markdown/**/*.png is the intended payload and check nothing else rides along.

Key Files

  • PyAutoHands/autohands/generate_markdown.pyoptimize_pngs() at :240, called at :379; main()/argparse at :439
  • autogalaxy_workspace/config/build/markdown_examples.yaml — curated list; ellipse/modeling exclusion comment
  • autogalaxy_workspace/scripts/ellipse/modeling.py — 22-fit Multiple Ellipses + Masking sections, lines 445-583
  • <workspace>/markdown/**/*_files/*.png — the 405 RGBA images to retro-optimize

Testing approach

No unit tests exist for generate_markdown.py. Verification is empirical: the PNG mode census before/after, byte totals per repo, git status scoped to markdown/, and visual spot-checks of rendered pages on the PR.

Original Prompt

Click to expand starting prompt
# Markdown renderings batch 2a — leftovers (ellipse/modeling + PNG size)

Type: docs
Target: workspaces
Difficulty: small
Autonomy: safe
Priority: low
Status: formalised

Two deferred items from batch 2a ([[markdown-example-renderings]] rollout,
autolens_workspace#264):

1. **autogalaxy `ellipse/modeling.py`** — excluded from the curated set because
   its "Multiple Ellipses" section runs many sequential DynestyStatic/Drawer
   fits that exceed nbconvert's per-cell timeout (CellTimeoutError at 7200s;
   confirmed a timeout, NOT a bug — corner works, imaging/modeling renders
   fine). To add it: bump its `max_minutes` in
   `autogalaxy_workspace/config/build/markdown_examples.yaml` to something
   generous (try 360+; the multi-fit cell is genuinely multi-hour) and run
   `generate_markdown.py autogalaxy --only ellipse/modeling`. If it's still
   impractical, leave it out — ellipse/simulator + ellipse/fit already showcase
   the dataset and a fit.

2. **PNG size** — batch 2a committed large image galleries (autolens markdown/
   ~61M total incl. phase-1's 19M; autogalaxy ~22M) at generate_markdown's
   default dpi. If repo size becomes a concern, do a single optimization pass
   across ALL markdown/*_files/*.png in every workspace (pngquant lossy ~60-70%
   reduction, visually fine for plots) — or add a dpi/optimize step to
   generate_markdown.py so it's consistent going forward (would also cover the
   phase-1 autolens pages). Do it repo-wide for consistency, not piecemeal.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions