Skip to content

Coverage mask - #699

Closed
martinkilbinger wants to merge 25 commits into
CosmoStat:developfrom
martinkilbinger:coverage
Closed

Coverage mask#699
martinkilbinger wants to merge 25 commits into
CosmoStat:developfrom
martinkilbinger:coverage

Conversation

@martinkilbinger

@martinkilbinger martinkilbinger commented Jan 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Added library files and classes to create healsparse coverage mask files.
The following steps can be performed:

  • Download exposure FITS headers from VOSpace
  • Extract CCD corner coordinates
  • Create hsp coverage map

Wait for #702 .

Closes #700 .

Reviewer Checklist

Reviewers should tick the following boxes before approving and merging the PR.

  • The PR targets the develop branch
  • The PR is assigned to the developer
  • The PR has appropriate labels
  • The PR is included in appropriate projects and/or milestones
  • The PR includes a clear description of the proposed changes
  • If the PR addresses an open issue the description includes "closes #"
  • The code and documentation style match the current standards
  • Documentation has been added/updated consistently with the code
  • All CI tests are passing
  • API docs have been built and checked at least once (if relevant)
  • All changed files have been checked and comments provided to the developer
  • All of the reviewer's comments have been satisfactorily addressed by the developer

@martinkilbinger martinkilbinger self-assigned this Jan 16, 2026
@martinkilbinger
martinkilbinger marked this pull request as ready for review January 16, 2026 07:18
@cailmdaley

Copy link
Copy Markdown
Contributor

Merged latest develop into this branch (no force-push — just a merge commit). This absorbs #702, shrinking the effective PR diff from 43 files / ~29.6k lines to 11 files / +2036 / -165, which makes the genuinely new coverage-mask code reviewable.

Conflicts resolved:

  • pyproject.toml — kept both sides: fitsio extra from develop + plot in dev from this branch
  • docs/source/pipeline_canfar.md — kept develop's new "Create matched star catalogue" section; kept this branch's richer "Create coverage mask" docs (including the -d headers_v1.3 symlink-reuse notes and full build_coverage_map command)

Nothing structural was touched. Full review to follow.

@cailmdaley

Copy link
Copy Markdown
Contributor

Review of coverage-mask work

Good overall — the division of labor between this PR (builds coverage from exposure polygons) and sp_validation (consumes/applies/validates masks) is clean, and using cs_util.plots.FootprintPlotter for plotting is the right factoring.

Note on scope: after merging develop into this branch, the effective diff is 11 files / +2036 / −165 — concentrated on the 8 genuinely new files.

Blocking

  • coverage_run.py:97–139run_pipeline can't work as written. All three stages (run_download_headers, run_extract_corners, run_build_coverage) are called with the same args, but each uses -i/-o/etc. with different meanings. The coverage_pipeline entry point in pyproject.toml therefore runs only the first stage correctly. Either prefix options per stage, or drive the pipeline from a config file.
  • coverage_map_builder.py:19 vs :321 contradict. Module-level from shapepipe.utilities.coverage_plotter import CoveragePlotter runs at import time — if the plot stack is missing, the whole module fails before reaching the except ImportError at L321. That try/except is unreachable. Either move the import into the try block, or drop the try entirely.
  • coverage_map_builder.py:323 — wrong dependency in error message. Says "Install sp_validation package for plotting support". Should say cs_utilCoveragePlotter's hard dep is cs_util.plots.FootprintPlotter, not sp_validation.
  • field_corners_extractor.py:135expnum = int(path[end - 6 : end]) hardcodes 6-digit exposure numbers. Silently corrupts if an exposure number ever exceeds 999999. Parse by the - separator in the CCD filename, or use a regex.

Non-blocking but worth fixing

  • field_corners_extractor.py:149–152 — the hardcoded MegaCam HDU indices (0, 8, 35, 27) and pixel coords (2079, 0, 32) work but are magic. At minimum a short comment naming the MegaCam corner convention.
  • field_corners_extractor.py has two copies of the same WCS-parsing logic — process_single_header (static, L113–162, exists only so multiprocessing can pickle it) and get_wcs_from_header (L164–195). Extract to a module-level helper.
  • coverage_plotter.py:237FootprintPlotter._regions[region] reaches into a single-underscore private attribute. Fragile. Either cs_util should expose a public accessor for region lookup, or duplicate the dict locally.
  • coverage_map_builder.py:175new_hsp = hsp_map + 0 is an opaque copy idiom. Use .copy() if healsparse has it, otherwise a one-line comment explaining why +0.
  • coverage_map_builder.py:224verbose = self._params["verbose"] but verbose is never declared in params_default. Relies on cs_util.args.parse_options injecting it. Declare it explicitly in params_default so the contract is local.
  • header_downloader.py:36vospace_path = "vos:cfis/pitcairn" is a fine default but CFIS-specific. Worth a prominent note in help string or docs.
  • build_and_plot_coverage_maps.shBUILD_NSIDE=131072 (~0.1″ resolution). The Python class default in coverage_map_builder.py:39 is nside=2048. The docs say 131072 matches the bit-mask resolution — could you confirm that's the intended pairing, and maybe note it in a comment at the top of the bash script?

Tests

No tests for any of the new modules. Same gap as #702. A small test at least for CoverageMapBuilder.median_filter and FieldCornersExtractor.process_single_header would catch a lot. Not a blocker for merge, but worth tracking.

Side note on FootprintPlotter

Not a concern for this PR (you correctly import from cs_util), but flagging: sp_validation has a stale copy of FootprintPlotter at src/sp_validation/plots.py:402 that has diverged from cs_util's. Opening a separate cleanup PR on sp_validation to delete the local copy and import from cs_util.

@martinkilbinger

Copy link
Copy Markdown
Contributor Author

I fixed some of the problems:

  • coverage_run.py:97–139 — run_pipeline: Fixed, removed this non-functioning pipeline runner.
  • coverage_map_builder.py: Fixed.

And added comments for the hard-coded MegaCAM/UNIONS stuff.

For the rest I think claude can do a better job than me to fix.

martinkilbinger and others added 4 commits April 21, 2026 15:39
- Extract _expnum_from_path, _parse_header_to_wcs, _megacam_field_corners
  as module-level helpers. process_single_header (static, for
  multiprocessing) and the instance methods now share one implementation.
- Remove dead get_wcs_from_header and get_megacam_field (duplicated
  logic that had already been inlined into process_single_header).
- Fix re.search(r'(\d+)\.txt') missing its subject string. The new
  helper also replaces the hard-coded p[end-6:end] exposure-number
  extraction in run(), so exposure numbers of any length work.
- Declare verbose in params_default so the contract is local instead
  of relying on cs_util.args.parse_options to inject it.

Addresses review feedback on CosmoStat#699.
- Replace hsp_map + 0 with hsp_map.copy() (healsparse supports .copy
  since at least 1.x; more explicit intent).
- Declare verbose in params_default; currently populated only by
  cs_util.args.parse_options auto-injection.
- Fix typo: "Install te cs_util" -> "Install the cs_util".

Addresses review feedback on CosmoStat#699.
- coverage_plotter, header_downloader: declare verbose explicitly in
  params_default.
- coverage_plotter: comment acknowledging that FootprintPlotter._regions
  is a private cs_util attribute; refactor to public accessor when
  cs_util exposes one.
- header_downloader: expand the vos:cfis/pitcairn comment to flag it as
  UNIONS/CFIS-specific and document override.
- build_and_plot_coverage_maps.sh: explain the BUILD_NSIDE=131072 choice
  (matches UNIONS bit-mask pixel scale, ~0.1"), and note the
  CoverageMapBuilder default of 2048 for lighter use.

Addresses review feedback on CosmoStat#699.
@cailmdaley

Copy link
Copy Markdown
Contributor

Thanks @martinkilbinger — your three fixes close out the blocking items (the bogus run_pipeline, the unreachable ImportError guard, the sp_validation→cs_util error string). I walked through the rest; current state:

Addressed on this branch:

  • field_corners_extractor.py — regex bug fixed; process_single_header and get_wcs_from_header consolidated into one helper; MegaCam HDU/pixel conventions commented (bbe53c5)
  • coverage_map_builder.pyhsp_map + 0.copy() (134a79f)
  • coverage_map_builder.pyverbose declared explicitly in params_default; header_downloader.py vospace default noted as CFIS-specific; build_and_plot_coverage_maps.sh has a comment explaining BUILD_NSIDE=131072 matches UNIONS bit-mask resolution vs the class default of 2048 for lighter-weight offline use (9a574e9)

Left as-is (with comment):

  • coverage_plotter.py:166, 241 still reaches into FootprintPlotter._regions. I added a comment at L161–163 flagging it and pointing at cs_util; the real fix is upstream (expose regions as a public accessor). Not worth duplicating the 3-region dict locally given cs_util should be the single source of truth.

Non-blocking gap to track (not in this PR):

  • No tests for the new coverage modules. Targets worth covering later: CoverageMapBuilder.median_filter and FieldCornersExtractor.process_single_header — a small synthetic header + tiny hsp map would lock in the load-bearing numerics. Happy to file an issue or pick it up after this merges, whichever you prefer.

From my side the PR is ready for a final review / merge. LMK if you want me to touch anything else.

@martinkilbinger
martinkilbinger requested review from cailmdaley and removed request for sfarrens April 23, 2026 12:49
@martinkilbinger

Copy link
Copy Markdown
Contributor Author

Code Review

Overview

This PR adds a full coverage-mask pipeline for UNIONS/CFIS: five new utility classes (CcdPsfHandler, HeaderDownloader, FieldCornersExtractor, CoverageMapBuilder, CoveragePlotter), new CLI entry points, a batch shell script, and refactors the old monolithic get_ccds_with_psf.py script. The code is well-structured and consistently follows the class-based pattern used elsewhere in shapepipe.utilities.


Critical Issues

1. Broken coverage_pipeline entry point (pyproject.toml:72, coverage_run.py)

pyproject.toml registers:

coverage_pipeline = "shapepipe.coverage_run:run_pipeline"

but coverage_run.py has no run_pipeline function — only main() which returns 0 immediately. This will cause an AttributeError when the entry point is called. Either implement run_pipeline or remove the entry point.

2. Missing vos dependency (pyproject.toml, header_downloader.py:8)

import vos is at module level in header_downloader.py, but vos is not listed in pyproject.toml dependencies. A fresh install will fail with ModuleNotFoundError as soon as any coverage tool is imported.


Significant Issues

3. Debug print left in production code (ccd_psf_handler.py:831)

print("MKDEBUG stat file ", stat_file, " does not exist")

This is unconditional and will pollute stdout in production. The nearby #print("MKDEBUG ...) lines were commented out but this one was missed.

4. healsparse/skyproj as hard core dependencies (pyproject.toml:47-48)

Both are added to dependencies (i.e., required for all users), but they are only needed for the coverage pipeline. They are large, non-trivial packages. They should be moved to an optional group, e.g.:

[project.optional-dependencies]
coverage = ["healsparse", "skyproj"]

skyproj also appears redundantly in the new plot optional group.

5. Accessing private attribute FootprintPlotter._regions (coverage_plotter.py:1419-1424)

The comment acknowledges this is fragile — any rename in cs_util breaks this silently. A safer approach: let FootprintPlotter raise on an invalid region and catch it, rather than reaching into a private attribute.


Minor Issues

6. args variable shadowed in _process_parallel (field_corners_extractor.py:1961)

args = [(p, verbose) for p in todo]

Shadows the method's args parameter. Rename to e.g. worker_args.

7. Global matplotlib state mutation (coverage_plotter.py:1480-1484)

matplotlib.rc(...) and rcParams are set globally in plot_coverage_map, affecting any subsequent plots in the same session. Use with matplotlib.rc_context({...}): instead.

8. Hardcoded fallback ra_0 = 130.0 (coverage_plotter.py:1510)

The RA wraparound fallback is silently UNIONS-specific. Add a comment explaining it, or make it a configurable parameter.

9. Edge artifact in median_filter (coverage_map_builder.py:1100)

n = np.where(n >= 0, n, 0)

Invalid neighbours (boundary pixels, index = -1) are replaced with pixel 0, causing boundary pixels to over-weight their own value in the median. This could bias coverage depths at survey edges. Worth documenting the choice, or using masked arrays.

10. Misleading error message on missing plot dependency (coverage_map_builder.py:1244-1245)

print("Install the cs_util package for plotting support.")

The ImportError here would come from skyproj/FootprintPlotter, not cs_util. The message is incorrect.

11. No tests

None of the five new classes have unit tests. Given these tools produce the survey footprint mask — which feeds downstream science — even minimal tests (mock file I/O for FieldCornersExtractor, a small toy map for CoverageMapBuilder) would be valuable.


Small Nits

  • get_ccds_with_psf_method_v1_3: the n_CCD parameter is documented as unused; prefix with _ or remove it (ccd_psf_handler.py:776)
  • get_lines has no need for self; could be a @staticmethod (ccd_psf_handler.py:650)
  • check_params in CcdPsfHandler is a bare pass — fine as a stub, but could be removed
  • SGC_DEC_MIN=18 / SGC_DEC_MAX=40 in the shell script: labelling a positive-dec equatorial strip "SGC" is non-standard; a comment clarifying the UNIONS-specific definition would help

Summary

Must-fix before merge: the broken coverage_pipeline entry point (#1) and missing vos dependency (#2). The debug print (#3) and promoting healsparse/skyproj to optional dependencies (#4) are also strong candidates to address. The rest can be handled in follow-up.

@cailmdaley

Copy link
Copy Markdown
Contributor

@martinkilbinger is this superseded by #797?

@martinkilbinger

Copy link
Copy Markdown
Contributor Author

@martinkilbinger is this superseded by #797?

Looks like the current and #797 are the same PR from two versions of the same branch coverage. Can we check for consistency both branches before merging into develop?

@cailmdaley

Copy link
Copy Markdown
Contributor

Checked: #797 continues this same branch (this tip is an ancestor of #797's), so nothing here is lost by closing — the review fixes from this thread are all on #797. Closing in favor of #797.

— Claude on behalf of Cail

@cailmdaley cailmdaley closed this Aug 24, 2026
cailmdaley added a commit that referenced this pull request Sep 5, 2026
* removed tmp files

* Moved get_ccds script to pipeline runner and library script

* class to download eposure headers (for coverage)

* coverage mask: scripts and plotter; using cs_util

* coverage code: added Mike Hudson as co-author

* documentation (in pipeline_canfar.md) on coverage mask scripts and classes

* CCD PSF Handler: Added version for v1.3

* fixed coverage plots

* header downloads (coverage): account for existing downloads

* canfar-changes

* PR: remove non-functioning coverage pipeline function

* PR: coverage_map_builder; moved import into try block

* PR: field_corners_extractor.py; fixed exp number extraction

* PR: added comment

* PR: added comment

* refactor: consolidate field_corners_extractor helpers; fix regex

- Extract _expnum_from_path, _parse_header_to_wcs, _megacam_field_corners
  as module-level helpers. process_single_header (static, for
  multiprocessing) and the instance methods now share one implementation.
- Remove dead get_wcs_from_header and get_megacam_field (duplicated
  logic that had already been inlined into process_single_header).
- Fix re.search(r'(\d+)\.txt') missing its subject string. The new
  helper also replaces the hard-coded p[end-6:end] exposure-number
  extraction in run(), so exposure numbers of any length work.
- Declare verbose in params_default so the contract is local instead
  of relying on cs_util.args.parse_options to inject it.

Addresses review feedback on #699.

* refactor: coverage_map_builder cleanup

- Replace hsp_map + 0 with hsp_map.copy() (healsparse supports .copy
  since at least 1.x; more explicit intent).
- Declare verbose in params_default; currently populated only by
  cs_util.args.parse_options auto-injection.
- Fix typo: "Install te cs_util" -> "Install the cs_util".

Addresses review feedback on #699.

* docs: declare verbose and annotate survey-specific defaults

- coverage_plotter, header_downloader: declare verbose explicitly in
  params_default.
- coverage_plotter: comment acknowledging that FootprintPlotter._regions
  is a private cs_util attribute; refactor to public accessor when
  cs_util exposes one.
- header_downloader: expand the vos:cfis/pitcairn comment to flag it as
  UNIONS/CFIS-specific and document override.
- build_and_plot_coverage_maps.sh: explain the BUILD_NSIDE=131072 choice
  (matches UNIONS bit-mask pixel scale, ~0.1"), and note the
  CoverageMapBuilder default of 2048 for lighter use.

Addresses review feedback on #699.

* chore: uv lock — register healsparse + skyproj as shapepipe deps

The coverage feature adds healsparse (map building) and skyproj (plotting) to
pyproject. healsparse was already resolved transitively via cs_util; this pins
skyproj 2.5.0 and records both as shapepipe's own direct dependencies so
'uv lock --check' passes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvP7uKkfDU2PvWC7YmbuMW

* fix: coverage console scripts handle -h; drop dead entry point

The five coverage/get-ccds runners fell back to `args = sys.argv` (the full
argv, including argv[0]) instead of `sys.argv[1:]`, so under the entry-point
smoke test's `python -c "...; run_*()" -h` the parser read the program slot as
the integer `-c` option and exited non-zero (`invalid integer value: '-h'`).
Slice argv[1:] to match cs_util.args.parse_options' own convention.

Also drop the `coverage_pipeline` console script, whose target
`coverage_run:run_pipeline` was removed in an earlier commit (dangling entry
point -> AttributeError on invocation), and declare `hpgeom` explicitly
(imported directly by coverage_map_builder, previously only transitive via
healsparse). Together these fix all six entry-point test failures.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvP7uKkfDU2PvWC7YmbuMW

* test: unit + property tests for the coverage-mask feature

Cover the pure and lightly-fixtured logic: exposure-number parsing, the
CCD-list -> unique-exposure reduction, the MegaCam field-corner convention,
the multi-HDU header -> WCS split, power-of-two nside validation, and a
regression guard for the -h/argv handling of the console runners.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvP7uKkfDU2PvWC7YmbuMW

* fix(coverage): subtract missing CCDs in get_ccds_with_psf

The v>=1.4 path built the full set of exposure single-HDU IDs but never
removed the CCDs whose PSF model is missing, so every candidate CCD was
reported as valid. Subtract the missing set so the result is the CCDs
that actually have a valid PSF, and report the three counts.

* feat(coverage): extract per-CCD corners with optional CCD-list filter

Replace the whole-MegaCam-field corner extraction with per-CCD
extraction: for each HDU's WCS, build the 4 corners from the CCD pixel
bounds (read from pixel_shape, i.e. NAXIS1/NAXIS2) using pixel edges so
the quadrilateral covers the full CCD area. Emit one row per CCD keyed on
the '<expnum>-<ccd_idx>' ID.

Add an optional --ccd_list/-l option: when given, only CCDs in that file
(the output of get_ccds_with_psf) are written, so the coverage mask is
built from single CCDs with a valid PSF. Resume still keys the done-set
on exposure number, now parsed from the CCD-ID first column.

Drop the dead _megacam_field_corners whole-field path; keep
_parse_header_to_wcs and the multiprocessing structure.

* feat(coverage): build maps from per-CCD rows with RA-wrap and pole guards

Parse the new per-CCD row format (string CCD ID in column 0, then 8 float
corner columns). Add an RA-wrap guard that unwraps polygons straddling
the RA=0 seam onto a common branch, and a pole guard that skips polygons
reaching |dec| >= 89 deg with a warning (CCD footprints never reach
there). Since the CCDs of one exposure do not overlap, accumulating value
1 per CCD polygon still counts exposures-with-valid-PSF per pixel.

* fix(coverage): download headers atomically via temp-file rename

Copy each header to a '.part' file in the same directory and os.rename
on success. An interrupted transfer can no longer leave a partial file
that resume treats as complete; the temp file is removed on failure.

* docs,build(coverage): align interfaces to the per-CCD flow

Fix the console-script name typo (get_ccd_with_psfs -> get_ccds_with_psf)
so it matches the docs and script. Harden the build/plot script with
'set -euo pipefail' and document the per-CCD chain (step 0
get_ccds_with_psf feeding extract_field_corners --ccd_list). Update the
canfar docs: restore the coverage helpers as shipped, align filenames
(ccds_with_psf_<version>.txt, exp_ra_dec_<version>.txt), and describe the
per-CCD workflow including step 0.

* test(coverage): cover per-CCD extraction, filtering, guards, atomic download

Rewrite the coverage tests for the per-CCD design: handler missing-CCD
subtraction; per-CCD corner extraction and pixel-shape error; --ccd_list
filtering end to end; builder parsing of the new row format; RA-wrap
unwrap (a CCD straddling RA=0 fills a small patch, not the complement);
pole-guard skip; and atomic-download rename behaviour with a mocked copy.
Drop the tests that pinned the removed whole-field convention.

* fix(coverage): read true CCD dims from ZNAXIS and resume per-CCD

Two correctness fixes in the per-CCD extractor:

- Image dimensions: header_downloader fetches fpack tile-compressed
  headers where NAXIS1/NAXIS2 describe the compressed binary table (byte
  width, row count), so WCS.pixel_shape reports e.g. (8, 4612) instead of
  the true (2080, 4612). Read ZNAXIS1/ZNAXIS2 when ZIMAGE is set, falling
  back to NAXIS1/NAXIS2. _parse_header_to_wcs now returns (wcs, shape)
  pairs since the WCS drops the Z-keywords; _ccd_corners takes the shape
  explicitly.

- Resume: key the done-set on individual CCD IDs, not exposure numbers.
  A write interrupted mid-exposure previously left a partial exposure
  that a -r rerun skipped forever (silent undercount); an expanded
  --ccd_list rerun skipped exposures whose new CCDs were never written.
  get_done_ccds reads the present CCD IDs and run() drops only those,
  so partial exposures are completed and new CCDs added, never
  duplicating a row.

* fix(coverage): single-line CCD list, runner docstrings, plot doc example

- header_downloader.get_exposures: wrap the text-format loadtxt in
  np.atleast_1d so a single-line CCD list (0-d array) does not crash on
  iteration.
- coverage_run: update the extract/build runner docstrings from
  whole-field 'field corner coordinates' to per-CCD language.
- pipeline_canfar docs: add a runnable plot_coverage_map example (the SGC
  region command) covering the flags build_and_plot_coverage_maps.sh
  uses.

* test(coverage): compressed-header dims, resume path, nexp value contract

Extend the coverage tests for the confirmed findings:

- fpack-compressed header fixture; assert ZNAXIS dims are recovered and
  corners span the true CCD width, not the 8-byte compressed NAXIS1.
- resume run() path: a new exposure is appended without duplicating
  existing rows, and a partial exposure (interrupted mid-write) is
  completed rather than skipped.
- the nexp contract on pixel values: two overlapping CCDs from different
  exposures give value 2 in the overlap and 1 outside.
- single-row builder file (atleast_1d/2d guards); single-line
  get_exposures; RA-wrap strengthened to a positional-parity check
  (seam CCD vs the same CCD shifted +10 deg agree in pixel count);
  get_ccds_with_psf subtraction pinned against the real get_all_shdus.

* feat(coverage): accept catalogue version v2.0 (9-patch footprint, as v1.6)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MqH9wjbJicVmaQdhZ4kBYr

* feat(coverage): v2.0 defaults to 10 patches; -p overrides the version map

The v2 footprint is still growing (>5000 deg2 per the 2026-07 Paris
meeting, new Dec<30 region); the newest patch definitions
(auxdir/CFIS/tiles_202510) include P10. Default v2.0 to 10 patches and
add an explicit -p/--n_patch override so the handler tracks evolving
patch layouts without code changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MqH9wjbJicVmaQdhZ4kBYr

* fix(coverage): v2.0 is patch-less — read summaries from the run root

Martin (PR #812 review): the patch concept is removed in v2.0. For
-V v2.0 the handler reads summary/missing_job_32_all.txt and
exp_numbers.txt relative to the run root instead of iterating P1..P9;
-p restores an explicit P1..P<n> layout when needed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MqH9wjbJicVmaQdhZ4kBYr

* docs: state the patch convention per catalogue version (v2.0 is patch-less)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MqH9wjbJicVmaQdhZ4kBYr

* feat(coverage): default get_ccds_with_psf -V to v2.0 (patch-less)

Align with the collate_star_cat convention (PR #812): v2.0 (patch-less) is
now the default catalogue version. Older, patched layouts are selected
explicitly with -V. Help text and the pipeline_canfar.md invocations updated;
the v2.0 call drops the flag, v1.x shows -V v1.6. Tests set the version
explicitly, so none pinned the old default.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqNFhq9uGpDpprYeuGeb8k

* chore: remove accidentally committed pytest log artifact

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* coverage: drop the v2.0 patch-less path — v2.0 coverage moves to the Snakemake stack

Martin (review, 2026-09-04): the v2.0 pipeline is Snakemake-orchestrated,
has no sky patches, and will not use the summary class or its outputs —
so summary/missing_job_32_all.txt and exp_numbers.txt simply won't exist
at a v2.0 run root. The patch-less path added in July was built on files
that are not going to be there.

This PR therefore lands as the v1.x tool. Reverts the v2.0 work
(15401d9, a3aa4ec, ae10176, 46214c7, 1ffcd4b) and restores the pre-July
contract of CcdPsfHandler:

  - accepted versions are v1.3, v1.4, v1.5, v1.6 again; -V v2.0 now
    fails loudly with "Invalid version v2.0"
  - -V default back to v1.6 (was flipped to v2.0 in 1ffcd4b)
  - the n_patch = 0 / patches = ["."] "patch-less" semantics are gone;
    patches are always P1..P<n> from the version map (7/7/8/9)
  - the -p/--n_patch CLI override is dropped: it was introduced in
    a3aa4ec purely to let the evolving v2.0 footprint be overridden, and
    the v1.x patch counts are fixed history

Docs lose the "Patch convention by catalogue version" note and the
patch-less get_ccds_with_psf invocation; the two v2.0 tests
(test_v2_is_patchless, test_n_patch_option_overrides_version_default)
are removed. The v1.x version->patch-count parametrisation and the
invalid-version test stay.

Everything else from the July rework is untouched: per-CCD extraction,
RA-wrap and pole guards, atomic downloads, resume, ZNAXIS dims.

v2.0 coverage will be a separate PR against the Snakemake stack.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* chore: relock cs_util to develop 1b15a55 (restores FootprintPlotter.plot_area)

---------

Co-authored-by: martinkilbinger <martinkilbinger@cea.fr>
Co-authored-by: Cail Daley <cail.daley@cea.fr>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Cail McLean Daley <cailmdaley@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: To do

Development

Successfully merging this pull request may close these issues.

[NEW FEATURE] Create coverage masks for UNIONS

2 participants