Skip to content

Bake flat-field profiles to a self-contained file store - #720

Merged
marcinz606 merged 2 commits into
marcinz606:mainfrom
seanharding:flatfield-baked-profiles
Aug 1, 2026
Merged

Bake flat-field profiles to a self-contained file store#720
marcinz606 merged 2 commits into
marcinz606:mainfrom
seanharding:flatfield-baked-profiles

Conversation

@seanharding

Copy link
Copy Markdown
Contributor

Flat-field correction relied on the original reference image staying put: the per-image edit stored its filesystem path and the gain map was re-decoded from that file every render, so moving or deleting the reference silently dropped the correction. Bake it instead, following the sensor/crosstalk file-store pattern.

  • New FlatFieldProfiles service: one .npz per profile in APP_CONFIG.flatfield_dir holding the baked per-channel gain map plus k1, display name and provenance. Keyed by an opaque id (name lives inside the file) so renames and cross-machine name collisions never break the per-image reference.
  • FlatFieldConfig.reference_path -> profile_id. The numpy logic layer stays storage-free: apply_flatfield/flatfield_token resolve gains through an injected provider (set_gain_provider), wired to the store in main.py and cached; the source-hash token is profile_id + a content hash of the gain.
  • One-shot startup migration bakes legacy flatfield_profiles DB rows into npz files, rewrites edits' reference_path -> profile_id, remaps the active profile setting, and drops the retired table. reference_path added to DROPPED_KEYS for stragglers.
  • Retired the flatfield_profiles table, repo methods and DB-dialog row; profiles now live on disk like sensor/crosstalk, so Reset Everything leaves them alone.
  • Tests for the store and migration; docs updated (USER_GUIDE, PIPELINE, CLAUDE invariant on the provider seam).

Flat-field correction relied on the original reference image staying put:
the per-image edit stored its filesystem path and the gain map was
re-decoded from that file every render, so moving or deleting the
reference silently dropped the correction. Bake it instead, following the
sensor/crosstalk file-store pattern.

- New FlatFieldProfiles service: one <uuid>.npz per profile in
  APP_CONFIG.flatfield_dir holding the baked per-channel gain map plus k1,
  display name and provenance. Keyed by an opaque id (name lives inside the
  file) so renames and cross-machine name collisions never break the
  per-image reference.
- FlatFieldConfig.reference_path -> profile_id. The numpy logic layer stays
  storage-free: apply_flatfield/flatfield_token resolve gains through an
  injected provider (set_gain_provider), wired to the store in main.py and
  cached; the source-hash token is profile_id + a content hash of the gain.
- One-shot startup migration bakes legacy flatfield_profiles DB rows into
  npz files, rewrites edits' reference_path -> profile_id, remaps the active
  profile setting, and drops the retired table. reference_path added to
  DROPPED_KEYS for stragglers.
- Retired the flatfield_profiles table, repo methods and DB-dialog row;
  profiles now live on disk like sensor/crosstalk, so Reset Everything
  leaves them alone.
- Tests for the store and migration; docs updated (USER_GUIDE, PIPELINE,
  CLAUDE invariant on the provider seam).
Two follow-ups to the file-store profiles.

- get()/list_profiles() read only the small metadata members of the npz
  (a zip — untouched members aren't decompressed), never the ~MB gain
  array. The sidebar rebuilds the profile list on every config sync, so
  the old full read decompressed every profile's gain on each settled
  edit; metadata-only reads keep it cheap. load_gain()/set_k1() still
  read the gain.
- Show a wait cursor while "Add…" bakes a profile: it decodes the
  reference RAW synchronously on the GUI thread, a brief blocking beat.
@marcinz606
marcinz606 merged commit 6956add into marcinz606:main Aug 1, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants