Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
105 commits
Select commit Hold shift + click to select a range
f92cb44
feat(orchestration): Snakemake workflow for the real-data pipeline (#…
cailmdaley Jul 16, 2026
187950c
fix(orchestration): resolve {threads} at rule level, not inside param…
cailmdaley Jul 16, 2026
ac6bddd
fix(orchestration): carry original exposure names through the index; …
cailmdaley Jul 16, 2026
9b0456e
fix(orchestration): exposure-name pass-through, star-cat dirs, P0 run…
cailmdaley Jul 16, 2026
6fe141f
fix(orchestration): {output} placeholder inside params.cmd survives l…
cailmdaley Jul 16, 2026
a110d89
fix(orchestration): shard the exposure forest — the module glob's sha…
cailmdaley Jul 16, 2026
28c10d8
fix(orchestration): carry a wrapper-scripts content hash into every r…
cailmdaley Jul 16, 2026
a273e76
fix(orchestration): keep snakemake state and index off /project (hard…
Jul 16, 2026
0010def
fix(orchestration): drop exp_mask's dead per-unit star-cat input
Jul 17, 2026
833aa93
fix(orchestration): nibi-flavor completeness counts; file-level attri…
Jul 31, 2026
20cc506
feat(ngmix): env-expanded chunk fields; position-seeded RNG becomes t…
Jul 31, 2026
d1c0afb
feat(orchestration): committed workflow configs — no wrapper, no runt…
Jul 31, 2026
1b22b98
feat(orchestration): manifests become the DAG's currency — completene…
cailmdaley Jul 31, 2026
83d26f2
feat(orchestration): the rules rewrite — manifests as DAG currency, s…
cailmdaley Jul 31, 2026
b149e18
fix(orchestration): harden the rewrite against its adversarial review
cailmdaley Jul 31, 2026
12ecfc2
feat(orchestration): clean_exposure becomes an in-DAG rule with tombs…
Jul 31, 2026
e677f67
feat(orchestration): nibi profile goes slurm-executor (#848 D4, S6)
Jul 31, 2026
96c78cd
fix(orchestration): stop the clean_exposure cascade; report reads tom…
Jul 31, 2026
4d28897
docs(orchestration): profile comment tells the truth about the clean/…
Jul 31, 2026
831a127
run: point the quad at a fresh smk-g3 run dir (old smk-p0 tree is uns…
Jul 31, 2026
f82e7f4
fix(orchestration): slurm_account is the association name (def-mjhuds…
Jul 31, 2026
5cfdc04
fix(orchestration): index build is the main compute parse's alone
Aug 15, 2026
acfb91a
fix(orchestration): sp pins --snakefile; works from any cwd
Aug 15, 2026
dedc1f0
docs(orchestration): a failed tile pins ~8 exposures, not ~80
Aug 15, 2026
2a24d34
fix(orchestration): manifests are success-only DAG currency
Aug 15, 2026
a1d4dfa
feat(orchestration): star-cat creation moves into the DAG
Aug 15, 2026
6a8e71a
fix(orchestration): the verdict composes counts with shapepipe_run's rc
Aug 16, 2026
7341012
fix(orchestration): exp_star_cat stops trusting what it cannot see
Aug 16, 2026
cba14de
fix(orchestration): reclaim the star-cat farm, stop the home-quota leak
Aug 16, 2026
30567ac
run(smk-g3): flip clean on — quad validated, batch1 append needs the …
Aug 24, 2026
fadc277
run(smk-g3): the campaign appends the first 30 batch1 tiles
Aug 24, 2026
93c7b4e
Move failure evidence onto snakemake's native log: directive
cailmdaley Aug 28, 2026
b2cfa3b
Fetch star catalogues by sky chunk, not by exposure
cailmdaley Aug 29, 2026
f2cf65b
feat(container): sp container — per-user image layers and resolution
cailmdaley Aug 29, 2026
1ed2537
Fuse the short rules into per-unit group jobs
cailmdaley Aug 29, 2026
aee48dc
Derive merge_sep_cats chunk paths from the run-directory name
cailmdaley Aug 29, 2026
d5c208e
Fail loudly on an unset SP_PHASE and an unresolvable container
cailmdaley Aug 29, 2026
15c4e6c
Group tile_exp_forest with tile_merge_headers
cailmdaley Aug 29, 2026
109739d
fix(psf): deterministic star train/validation split; align tile STAR_…
Aug 29, 2026
9078209
fix(configs): the workflow's own PiViVi config takes STAR_THRESH 22 too
cailmdaley Aug 29, 2026
43987f6
feat(orchestration): the persistent root D5 always described
cailmdaley Aug 29, 2026
a0311c2
feat(orchestration): the shape chain becomes one node-local job
cailmdaley Aug 30, 2026
fb28e7a
fix(orchestration): derive the node-local path, do not try to pass it
cailmdaley Aug 30, 2026
7b34c9e
docs(profile): the $SLURM_TMPDIR passthrough is disproven, say so
cailmdaley Aug 30, 2026
6224206
fix(orchestration): tile_ngmix runtime scales with attempt
cailmdaley Aug 30, 2026
b2163e0
perf(orchestration): stage the WCS sqlite node-local with the vignett…
cailmdaley Aug 30, 2026
af772ea
perf(orchestration): tile_ngmix mem_mb 14000 -> 5000, measured across…
cailmdaley Aug 30, 2026
7302a2d
fix(orchestration): make the WCS staging atomic; correct two memory c…
cailmdaley Aug 30, 2026
234b2c3
run(smk-g5): a one-tile paired control for the two unvalidated fixes
cailmdaley Aug 30, 2026
a8ec764
perf(orchestration): split ngmix chunks by epoch-weighted cost, not o…
cailmdaley Aug 30, 2026
4f389ea
feat(orchestration): reclaim a finished tile's scratch store
cailmdaley Aug 30, 2026
dc9101a
Merge branches 'dev/chunk-balance' and 'dev/clean-tile' into dev/gate…
cailmdaley Aug 30, 2026
f196fa1
docs(orchestration): range_hash is safe to add only at a campaign bou…
cailmdaley Aug 30, 2026
731f8cc
fix(report): reclamation must not edit a tile's verdict
cailmdaley Aug 30, 2026
cfe62ed
docs(orchestration): say which half of the range_hash hazard was obse…
cailmdaley Aug 30, 2026
503c083
docs(orchestration): mark the Snakefile half of the deletion claim as…
cailmdaley Aug 30, 2026
4b96eff
run(smk-g6): point the campaign at a fresh 64-tile root
cailmdaley Aug 30, 2026
acaeb0b
docs(orchestration): the final_cat deletion is now observed, not derived
cailmdaley Aug 30, 2026
5daa82c
Merge origin/develop: uberseg blend handling + WCS-derived pixel scal…
cailmdaley Aug 30, 2026
fd91365
refactor(smk): one script_hash helper, unit_pre derives its level, st…
cailmdaley Aug 30, 2026
9ca1800
refactor(smk): sp_shell composes the two special tile bodies
cailmdaley Aug 30, 2026
8610c0a
perf(scripts): drop dead stage-table rows, bound the report's globs, …
cailmdaley Aug 30, 2026
725a8b0
refactor(star-cats): one atomic write and one focal-plane geometry, i…
cailmdaley Aug 30, 2026
b158cb9
chore(launcher): parse config.yaml with yaml, flag the profile's one …
cailmdaley Aug 30, 2026
07f799d
workflow/config/cfis: symlink the 11 byte-identical data files to exa…
cailmdaley Aug 30, 2026
db95741
docs(smk): one home per concept in the Snakefile, rules and profile
cailmdaley Aug 30, 2026
928297e
docs(scripts): point the reclamation and report scripts at their one …
cailmdaley Aug 30, 2026
c2763f8
docs(ngmix): position_seed owns the position-seeded RNG story
cailmdaley Aug 30, 2026
8726e9b
feat(ngmix): materialise the chunk partition once per tile
cailmdaley Aug 30, 2026
bedf996
feat(sp): snapshot the code at launch so edits cannot reach a running…
cailmdaley Aug 30, 2026
84435c4
ngmix: hoist per-object sqlitedict reads out of the epoch loop
cailmdaley Aug 30, 2026
cad7eb5
feat(mask): declare healsparse + hpgeom dependencies
cailmdaley Jul 16, 2026
3bb39e3
feat(mask_ext): rasterize external healsparse masks to pipeline flag …
cailmdaley Jul 16, 2026
6baa474
feat(make_cat): per-band MASK_<BAND> columns from external healsparse…
cailmdaley Jul 16, 2026
ba20d53
feat(mask_ext): fail fast on boolean masks with non-1 bits
cailmdaley Jul 16, 2026
f554e2b
Add MASK_EXT_PATHS example to make_cat config
cailmdaley Jul 30, 2026
eb93838
refactor(mask): delete internal mask generation and its star catalogues
cailmdaley Aug 31, 2026
659168a
feat(mask_query): flag exposure detections against external healspars…
cailmdaley Aug 31, 2026
51f25a5
refactor(pipeline): rewire the chains around the query design
cailmdaley Aug 31, 2026
1bceb2d
docs(mask): describe the query design, drop the deps only masking used
cailmdaley Aug 31, 2026
897febc
feat(mask_query): narrow the shipped PSF-star diet to the star-body map
cailmdaley Aug 31, 2026
ba2271a
fix(mask): address review — CI smoke, SEGMENTATION checkimage, canfar…
cailmdaley Aug 31, 2026
f7d1fd6
perf(mask_query): read only the coverage pixels a catalogue touches
cailmdaley Aug 31, 2026
2cc82ee
revert(scripts): restore collate_star_cat — it is PSF validation, not…
cailmdaley Aug 31, 2026
ed376f7
fix(mask_query): public sentinel, empty-coverage guard, real product …
cailmdaley Aug 31, 2026
c7c9e82
refactor(random_cat): delete — randoms come from healsparse map algeb…
cailmdaley Aug 31, 2026
edec546
fix(config): the 2026 DR6 products are named mask_ugriz_* — point the…
cailmdaley Aug 31, 2026
97c44b7
feat(mask_query): ship permissive — flag PSF-star candidates, cut not…
cailmdaley Aug 31, 2026
43c32cd
feat(mask_query): ship the query off by default, rename FLAG_EXT to M…
cailmdaley Aug 31, 2026
d5c73a1
ngmix: clarify position seed rationale
cailmdaley Sep 5, 2026
899763a
ngmix: remove obsolete seed configuration
cailmdaley Sep 5, 2026
6890d8a
workflow: rename tile merge catalogue config
cailmdaley Sep 5, 2026
d82f214
workflow: standardize tile catalogue run names
cailmdaley Sep 5, 2026
cbf7e11
workflow: simplify explanatory prose
cailmdaley Sep 5, 2026
4ceb91a
tests: mark UNIONS-specific tile pruning test
cailmdaley Sep 5, 2026
455583b
workflow: centralize configured inputs and outputs
cailmdaley Sep 5, 2026
98bc085
workflow: select PSF model from configuration
cailmdaley Sep 5, 2026
4e130a8
Remove completeness count floors
cailmdaley Sep 5, 2026
c7509af
clean_exposure: update exp_psf run name in docstring
cailmdaley Sep 5, 2026
94c7a86
Merge feat/snakemake-orchestration into feat/healsparse-external-masks
cailmdaley Sep 6, 2026
8ce3416
Merge pull request #847 from CosmoStat/feat/healsparse-external-masks
cailmdaley Sep 6, 2026
e32c4fb
example/cfis: retire configs superseded by the Snakemake workflow
cailmdaley Sep 9, 2026
3840fee
docs: add Snakemake workflow page, drop obsolete VOspace retrieval page
cailmdaley Sep 9, 2026
7e2036d
scripts: remove unreferenced canfar/vos helper scripts
cailmdaley Sep 9, 2026
ec0617e
Merge remote-tracking branch 'origin/develop' into feat/snakemake-orc…
cailmdaley Sep 9, 2026
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
3 changes: 1 addition & 2 deletions .github/workflows/deploy-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,11 @@ jobs:

# Smoke-test the binaries baked into the runtime image. Catches the
# class of regression where the image builds but a runtime tool
# (sextractor, weightwatcher) is missing or unrunnable.
# (sextractor, psfex) is missing or unrunnable.
- name: Test runtime — binaries
run: |
IMAGE=$(echo "${{ steps.meta-runtime.outputs.tags }}" | head -n1)
docker run --rm "$IMAGE" source-extractor --version
docker run --rm "$IMAGE" weightwatcher --version
docker run --rm "$IMAGE" psfex --version

- name: Test runtime — shapepipe entry point (read-only fs)
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -139,3 +139,4 @@ code
# .felt here is a machine-local symlink into it. Never track it in this repo.
/.felt/
/.felt
.snakemake/
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
COVERAGE_FILE=/tmp/.coverage

# System dependencies — three categories:
# - astromatic binaries (psfex, source-extractor, weightwatcher) ship as
# - astromatic binaries (psfex, source-extractor) ship as
# Debian packages on bookworm; preferred over building from source.
# - compilers and dev libs needed to build the heavier wheels (galsim,
# mpi4py, python-pysap, fitsio).
Expand All @@ -55,7 +55,7 @@
libcfitsio-dev \
libproj-dev proj-bin \
libgl1-mesa-glx \
psfex source-extractor weightwatcher && \
psfex source-extractor && \
apt-get clean && rm -rf /var/lib/apt/lists/*

# OpenMPI from source — required for hybrid Apptainer MPI on HPC clusters.
Expand Down Expand Up @@ -89,7 +89,7 @@
--disable-dlopen --disable-sphinx && \
make -j"$(nproc)" && make install && \
cd / && rm -rf /tmp/openmpi-*
ENV PATH="/opt/ompi/bin:${PATH}" \

Check warning on line 92 in Dockerfile

View workflow job for this annotation

GitHub Actions / build-test-publish

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$LD_LIBRARY_PATH' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/

Check warning on line 92 in Dockerfile

View workflow job for this annotation

GitHub Actions / build-test-publish

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$LD_LIBRARY_PATH' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/

Check warning on line 92 in Dockerfile

View workflow job for this annotation

GitHub Actions / build-test-publish

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$LD_LIBRARY_PATH' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/

Check warning on line 92 in Dockerfile

View workflow job for this annotation

GitHub Actions / build-test-publish

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$LD_LIBRARY_PATH' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/

Check warning on line 92 in Dockerfile

View workflow job for this annotation

GitHub Actions / Deploy API Documentation

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$LD_LIBRARY_PATH' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/

Check warning on line 92 in Dockerfile

View workflow job for this annotation

GitHub Actions / build-test-publish

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$LD_LIBRARY_PATH' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/

Check warning on line 92 in Dockerfile

View workflow job for this annotation

GitHub Actions / build-test-publish

Variables should be defined before their use

UndefinedVar: Usage of undefined variable '$LD_LIBRARY_PATH' More info: https://docs.docker.com/go/dockerfile/rule/undefined-var/
LD_LIBRARY_PATH="/opt/ompi/lib:${LD_LIBRARY_PATH}"

# uv — fast reproducible Python deps installer. pyproject.toml + uv.lock
Expand Down
6 changes: 3 additions & 3 deletions docs/source/container.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ The Dockerfile does **not** duplicate Python deps — those come from
The asymmetry is deliberate: Python deps go through pyproject + lockfile
(reproducible, auditable), system deps go through Dockerfile (Debian's
versioning). Don't `apt install` something that has a Python wheel; don't
`pip install` something Debian packages directly (e.g. `weightwatcher`).
`pip install` something Debian packages directly (e.g. `source-extractor`).

## Why this shape

Expand All @@ -175,8 +175,8 @@ versioning). Don't `apt install` something that has a Python wheel; don't
- **`uv sync --frozen`** at build time means the image is bit-exactly
reproducible from a tagged commit, and impossible to ship with a stale
lockfile.
- **Astromatic binaries from Debian** (`psfex`, `source-extractor`,
`weightwatcher`) instead of source builds — Debian carries the
- **Astromatic binaries from Debian** (`psfex`, `source-extractor`)
instead of source builds — Debian carries the
GCC-compatibility patches that the previous Dockerfile had to apply
inline with `sed`.
- **Two targets** so canfar batch deployments stay slim while interactive
Expand Down
1 change: 0 additions & 1 deletion docs/source/dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ packages (no source builds), plus the MPI stack:
|---------|------------|
| [Source Extractor](https://www.astromatic.net/software/sextractor/) | {cite:p}`bertin:96` |
| [PSFEx](https://www.astromatic.net/software/psfex/) | {cite:p}`bertin:11` |
| [WeightWatcher](https://www.astromatic.net/software/weightwatcher/) | {cite:p}`marmo:08` |
| OpenMPI (5.0.x) | |

Python dependencies themselves are managed with [uv](https://docs.astral.sh/uv/);
Expand Down
4 changes: 2 additions & 2 deletions docs/source/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ docker pull ghcr.io/cosmostat/shapepipe:develop-runtime
We do not currently build images for Apple Silicon/amr64; however the amd64 images should work on these systems, albeit with reduced performance.
```

The image bundles the astromatic binaries (`source-extractor`, `psfex`,
`weightwatcher`), MPI (`mpi4py` + OpenMPI), and every Python dependency, so
The image bundles the astromatic binaries (`source-extractor`, `psfex`),
MPI (`mpi4py` + OpenMPI), and every Python dependency, so
there is nothing else to install or build. To process data on a cluster with
MPI, run the pipeline through Apptainer the same way you would any MPI job.

Expand Down
50 changes: 12 additions & 38 deletions docs/source/pipeline_canfar.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,22 +170,16 @@ The downloaded tile weights are compressed. The following call uncompresses all.
shapepipe_run -c cfis/config_tile_Uz.ini
```

### Mask tiles
### Masks

This step is done globally for all tiles. There might be job failures or interruptions. The following
command to the `ShapePipe` job script can be run repeatedly; already created masks will be skipped.

```bash
job_sp_canfar.bash -p $psf -n $OMP_NUM_THREADS -j 4
```

If masks were created in more than one run, i.e. situated in more than one output directory, these have to be
combined for subsequent pipeline module runs. This is done by creating a new output directory with symbolic
links, using the script

```bash
combine_runs.bash -c flag_tile
```
There is no masking step. `ShapePipe` generates no masks: the sky-fixed
healsparse maps are queried once per object, by `mask_query` on the exposure
catalogues (`MASK_EXT`, recorded but not cut on) and by `make_cat` on the tile
catalogue (`MASK_<band>` columns). Point the `MASK_PATHS` / `MASK_EXT_PATHS`
config entries at the maps and nothing else is needed — no star-catalogue
download, no rasterization, no `combine_runs.bash -c flag_*`. The only mask that
touches pixels is the instrument flag image shipped with each exposure, which
`split_exp` splits per CCD.

## Tile detection

Expand All @@ -205,7 +199,7 @@ canfar_submit_job -j 16 -f tile_numbers.txt -P N_PAR -v -J JMAX

### Exposure Processing

#### Option 0: Global split and exp masks (deprecated; used for earlier v1.x patch runs)
#### Option 0: Global split (deprecated; used for earlier v1.x patch runs)

For this option, set `sp_local=0`.

Expand All @@ -217,21 +211,7 @@ For `sp_local=-` both `mh_local` (0, 1) are ok:
export mh_local=0
```

#### Option 0: Mask exposures (deprecated)

Run repeatedly if necessary:

```bash
job_sp_canfar.bash -p $psf -n $OMP_NUM_THREADS -j 8
```

Combine all runs:

```bash
combine_runs.bash -c flag_exp
```

### Option 1: Local split and mask exposures (recommended)
### Option 1: Local split exposures (recommended)

Optional: Enable flags for local split processing and merge header runs as

Expand All @@ -258,12 +238,6 @@ First, determine the number of maximum jobs with the option `-s` (see above). Th
canfar_submit_job -j 2 -v -f exp_shdu.txt -v -P N_PAR -J JMAX
```

### Mask exposures

```bash
canfar_submit_job -j 8 -f exp_shdu.txt -v -P N_PAR -J JMAX
```

### Exposure detection

```bash
Expand Down Expand Up @@ -400,7 +374,7 @@ Rename to general PSF and star catalogue used for all ("a") sub-versions:


```bash
cp output/run_sp_Ms/merge_starcat_runner/output/full_starcat-0000000.fits \
cp output/run_sp_tile_Ms/merge_starcat_runner/output/full_starcat-0000000.fits \
unions_shapepipe_psf_2024_v1.6.a.fits
```

Expand Down
81 changes: 48 additions & 33 deletions docs/source/pipeline_tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ Naming and numbering of the input files can closely follow the original image na
A stacked image is also called *tile*. These files are used on input by `ShapePipe`.
The pixel data can contain the observed image, a weight map, or a flag map. Tile images and weights are created in the
case of CFIS by Stephen Gwyn using a combination of `swarp` and his own software. Examples of file names are
`CFIS.316.246.r.fits`, `CFIS.205.267.r.weight.fits.fz`, the latter is a compressed FITS file, see below. Tile flag files
are created the mask module of `ShapePipe` (see [Mask images](#mask-images)). The tile ID needs to be modified such that the `.` between the two tile numbers (RA and DEC indicator) is not mistaken for a file extension delimiter. For the same reason, the extension `.fits.fz` is changed to `.fitzfz`. In addition, for
`CFIS.316.246.r.fits`, `CFIS.205.267.r.weight.fits.fz`, the latter is a compressed FITS file, see below. Tiles have no flag file
(see [Masks](#masks)). The tile ID needs to be modified such that the `.` between the two tile numbers (RA and DEC indicator) is not mistaken for a file extension delimiter. For the same reason, the extension `.fits.fz` is changed to `.fitzfz`. In addition, for
clarity, we include the string `image` for a tile image type.
Default convention: **<image_type>-<tile_number>.fits**
Examples: `CFIS_image-277-282.fits`, `CFIS_weight-274-282.fitsfz`, `pipeline_flag-239-293.fits`
Examples: `CFIS_image-277-282.fits`, `CFIS_weight-274-282.fitsfz`

- Database catalogue files
For very large files that combine information from multiple tiles or single exposures, `ShapePipe` creates `sqlite`
Expand Down Expand Up @@ -128,8 +128,6 @@ for all options.
This script creates the subdirectory `$SP_RUN/output` to store all pipeline outputs
(log files, diagnostics, statistics, output images, catalogues, single-exposure headers with WCS information).

Optionally, the subdir `output_star_cat` is created by the used to store the external star catalogues for masking. This is only necessary if the pipeline is run on a cluster without internet connection to access star catalogues. In that case, the star catalogues need to be retrieved outside the pipeline, for example on a login node, and copied to `output_star_cat`.

The job script automaticall performs a number of subsequent calls to the `ShapePipe` executable `shapepipe_run`, as
```bash
shapepipe_run -c $SP_CONFIG/<config>.ini
Expand Down Expand Up @@ -189,32 +187,49 @@ Finally, the headers of all single-exposure single-CCD files are merged into a s
Two output directories are created, `run_sp_Uz` for `uncompress_fits`, and `run_sp_exp_SpMh` for the output of the modules
`split_exp` (`Sp`) and `merge_headers` (`Mh`).

## Mask images

Run
```bash
job_sp TILE_ID -j 4
```
to mask tile and single-exposure single-CCD images. Both tasks are performed by two calls to the `mask` runner.

Note that internet access is required for this step, since a reference star catalogue is downloaded.

The output of both masking runs are stored in the output directory `run_sp_MaMa`, with run 1 (2) of
`mask` corresponding to tiles (exposures).

**Diagnostics:** Open a single-exposure single-CCD image and the corresponding pipeline flag
in `ds9`, and display both frames next to each other. Example
```bash
ds9 image-2113737-10.fits pipeline_flag-2113737-10.fits
```
Choose `zoom fit` for both frames, click `scale zscale` for the image, and `color aips0` for the flag, to display something like this:

<img width="250" src="img/diag_mask.png">

By eye the correspondence between the different flag types and the image can be
seen. Note that the two frames might not match perfectly, since (a) WCS
information is not available in the flag file FITS headers; (b) the image can
have a zero-padded pixel border, which is not accounted for by `ds9`.
## Masks

`ShapePipe` does not generate masks. Sky-fixed masks — star halos, stars,
manual masks for large galaxies, per-band coverage, MaxiMask defects — are
supplied as [healsparse](https://healsparse.readthedocs.io) maps and are
consumed by *querying them at object positions*, never by rasterizing them onto
pixels. Two modules do the querying, from the same shared lookup
(`shapepipe.utilities.mask_query`): `mask_query` runs between `sextractor` and
`setools` on the single-exposure single-CCD catalogues and writes one integer
`MASK_EXT` column (0 = clean), recording the star-body map (bit 2) against every
detection; `make_cat` writes one
`MASK_<band>` column per band onto the final tile catalogue, carrying the map
value verbatim so downstream selections choose their own cuts. Map paths and
bit selections live in the config files (`MASK_PATHS` / `MASK_BITS` and
`MASK_EXT_PATHS`), so regenerated mask products cost a config edit and no code.

The distinction that drives all of this is what a mask *means*. An **instrument
flag** marks a corrupted measurement — the pixels carry no usable signal — so
these are the only masks that reject anything inside the pipeline. The
**healsparse masks** are sky-fixed location flags: they say where an object
sits, not that its pixels are broken, so what to do about one is an analysis
decision and is made downstream.

**Nothing in the pipeline cuts on the queried columns**, and on exposures the
query ships off entirely: `MASK_PATHS` is commented out, which makes
`mask_query` a strict no-op that passes the catalogue through with no
`MASK_EXT` column (the module stays in the chain, so enabling it is
uncommenting one line). `star_selection.setools` rejects on `IMAFLAGS_ISO == 0`
and nothing else, deliberately starting from outlier rejection alone, and the
final catalogue's `MASK_<band>` columns are written unfiltered. `MASK_EXT` is
the configurable pickup if outlier rejection proves insufficient: add
`MASK_EXT == 0` beside each `IMAFLAGS_ISO == 0`, one line per mask block, as
that file's header documents.

No internet access is needed at any point, and there is no reference star
catalogue to download.

The one mask that still reaches pixels is the **instrument flag image**
(`<exp>p.flag.fits.fz`) delivered with each exposure, which records bad columns
and saturation. `split_exp` splits it per CCD beside the image and weight,
`sextractor` reads it as `IMAFLAGS_ISO`, and `ngmix` zero-weights flagged
pixels in its postage stamps. Tiles have no such image, so tile detection runs
with `FLAG_IMAGE = False`.

## Detect objects on tiles and process stars on single exposures

Expand Down Expand Up @@ -328,8 +343,8 @@ Included are galaxy detection and basic measurement parameters, the PSF model at
galaxy positions, the spread-model classification, and the shape measurement.

Two output directories are created.
The first one is `run_sp_Ms` for the `merge_sep` run.
The second is `run_sp_Mc` for the `make_cat` task; the name is the same for both the `MCCD` and `PSFEx` PSF model.
The first one is `run_sp_tile_Ms` for the `merge_sep` run.
The second is `run_sp_tile_Mc` for the `make_cat` task; the name is the same for both the `MCCD` and `PSFEx` PSF model.


## Upload results
Expand Down
7 changes: 1 addition & 6 deletions docs/source/post_processing.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@ catalogue via _metacalibration_), a joint star catalogue, and PSF diagnostic plo



---

If main ShapePipe processing happened at the old canfar VM system (e.g. CFIS v0 and v1), go
[here](vos_retrieve.md) for details how to retrieve the ShapePipe output files.

---

```{note}
Expand Down Expand Up @@ -76,6 +71,6 @@ The following steps were used for pre-v1.4 runs performed on the canfar VM syste
```
Choose as input directory `input_dir` the `make_cat` output of the runs
being combined. A default parameter file `<param_file>` is
`/path/to/shapepipe/example/cfis/final_cat.param`.
`/path/to/shapepipe/workflow/config/cfis/final_cat.param`.
On success, the file `./final_cat.npy` is created. Depending on the number of
input tiles, this file can be several tens of Gb large.
Loading