Repository navigation
Consistent shear response, weights and additive bias (DES case d) - #425
Open
cailmdaley wants to merge 36 commits into
Open
cailmdaley wants to merge 36 commits into
cailmdaley wants to merge 36 commits into
Conversation
The ShapePipe pipeline stage's ngmix ini (which owns METACAL_PSF) is resolved from the shapepipe worktree's example/cfis_image_sims via run_job's self-computed config_dir, so nothing in the run config could select a different ini -- an A/B on the metacal reconvolution PSF needed a separate worktree per arm. Add an optional operational key `pipeline_config_dir`. When set it is passed to run_job as `-c DIR`, redirecting the pipeline stage's whole ShapePipe config tree (ngmix ini included) at a per-arm copy; when empty (the default) no `-c` is passed and run_job self-computes exactly as before, so runs predating this key reproduce bit-exact. Merge/final_cat still read the top-level cfis symlink (config_dir), untouched. Candidate upstream PR for the image-sims orchestration branch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XSWPiisH6y7NFFbjHqthuC
ImageSimMBias.load_catalogs hardcoded the '_grid_' infix between branch
name and run number, so blended arms ({branch}_{num} dirs) hit
FileNotFoundError on a '{branch}_grid_{num}' path that never existed.
Derive the suffix from sims_type (defaulting to grid for backward
compat and the synthetic-recovery tests), mirroring the workflow's own
_SUFFIX contract. Emit sims_type into the generated m_bias_config, and
bump im_mbias mem to 8G since blended catalogues are ~5x grid size and
OOM the snakemake 1000M default.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HubFhoU6bH8ij6hcTWxw7s
…lization
Add an optional `exp_num` config key so the exposure input can be pulled from a
different SKiLLS realization than the tiles. Tiles stay on `{branch}_{num}`;
exposures resolve `{branch}_{exp_num}` via a new SIM_EXP_BASE mapping, consumed
by rule im_init's `sim_exp` symlink source. Unset `exp_num` defaults to `num`,
reproducing prior behaviour bit-for-bit. Guarded to non-grid sims (grid names
embed sims_type; the pathology this addresses is a blended-family concern).
Motivation: the blended-family realizations _1.._4 carry stale cross-linked
SP_exp (grid-sims exposures symlinked in, signal-free); _5 is the clean all-real
exposure set. This reproduces Fabian's production split (exposures from _5, tiles
from _1), unblocking the blended smoke arms whose ngmix flux collapsed ~10x on
the contaminated z-branch exposures.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HubFhoU6bH8ij6hcTWxw7s
…flow im_pipeline shelled out per tile to the legacy bash runner (run_job_sp_canfar_v2.0.bash -t image_sims) over example/cfis_image_sims, configs frozen before the real-data chain gained background-RMS vignets, PIXEL_SCALE, chunked ngmix and the new flags. An m measured that way does not calibrate the pipeline that makes the real catalogue. im_shapepipe replaces it: one localrule per shear branch writes a ShapePipe run config (input_type: image_sims, psf_model, tile list, the branch's SP_tiles/SP_exp, run_dir = grids_base/<sim>) and runs `sp run`, whose jobs ShapePipe submits through its own profile. The output is a campaign record (ShapePipe commit, resolved image, final_cat count) that im_merge consumes. im_init no longer stages input_tiles/input_exp; its cfis link now points at the checkout's workflow/config/cfis_image_sims, and it writes tiles_<sim>.txt, which is both the campaign's tile_list and params.py's tile-ID file. Config: drop config_dir, pipeline_config_dir and n_smp (dead with the bash runner; an A/B of the ngmix ini is now a ShapePipe config change); add sp_profile, sp_jobs, clean_exposures; psf_model defaults to fake, the true PSF of the star-free grid sims. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSjZrhgsGCLAJCLb5Zjmc3
…ecutor Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSjZrhgsGCLAJCLb5Zjmc3
…omounts Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSjZrhgsGCLAJCLb5Zjmc3
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSjZrhgsGCLAJCLb5Zjmc3
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSjZrhgsGCLAJCLb5Zjmc3
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSjZrhgsGCLAJCLb5Zjmc3
…iles im_shapepipe recorded the ShapePipe commit and dirty state by asking the live checkout when the campaign ENDED -- hours after sp run snapshotted the code it actually ran, so an edit or commit in between put the wrong code in the record. It now copies sp's own launch snapshot (<run_dir>-state/code/snapshot.json: source, branch, head, dirty, taken_at). im_mbias's provenance adds those per-branch records (commit, image, tile and final_cat counts) as shapepipe_campaigns, beside the checkout the merge stage reads; the records are now declared inputs. config.yaml: tile_ids must leave out tiles without data. A tile with no detections fails its ShapePipe campaign and so im_shapepipe; the SKiLLS coadds of grid_1 248.288, grid_2 259.285, grid_3 265.285 and grid_4 281.281/282.281 are all zeros, and 1m2z_2's 257.289 is truncated. The psf_model comment no longer offers *_star_grid (inputs for 1z2z only). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VSU9pPZjpBjzWorAL88aKQ
…r run null (the default) keeps the profile's node-local store and leaves the key out of the branch run configs, so earlier campaigns keep their params. The star sims set it to NFS: candide's 31 GB node /tmp cannot hold their ~5 GB tile stores. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qv5MwRiVKa8wnH665dWBia
…l's real-data workflow A from-scratch, one-tile-scale port of the image-sims chain onto the per-unit manifest/completeness pattern from shapepipe/workflow/ (calling shapepipe_run directly, no run_job_sp_canfar_v2.0.bash), built and verified step by step (prepare -> exposure -> tile chain -> tile_ngmix -> tile_make_cat) against the 240.291 reference tile from grid_1, plus clean_exposure/clean_tile reclamation reusing shapepipe's own scripts unmodified. Kept separate from feat/imsims-shapepipe-workflow (the more mature, overlay-config-based port already in progress there) -- this is an independent, simpler exploration, not meant to replace it.
run.sh's mktemp targeted /tmp directly -- a small node-local disk shared by every job/user on the node (candide policy), and this runs on the login node besides. Use a gitignored .batch/ dir alongside the workflow instead.
…atch Node-local /scratch (the previous fix's instinct, per CLAUDE.md's per-job scratch pattern) doesn't actually work here: verified empirically that a login-node /scratch path is invisible from the compute node the job lands on, so both the job's own stdout file and a file it tried to write there silently never appeared. This script runs before the job exists (login node) and its log is written from a not-yet-chosen compute node, so it needs network storage -- CLAUDE.md's own fallback for anything that must be visible beyond one node -- not /scratch, not /tmp, and not the repository directory either. Moved to /n17data/$USER/.im_sims_batch/.
TIME[compute]=02:00:00 was sized for the original single reference-tile run (~80 min end to end). COMPUTE runs the whole tile list in one --cores 8 allocation, so its wall clock has to cover the campaign, not one tile: at 40 tiles (1z2z_grid_1) the 2h cap timed out at 40/376 steps with no ngmix job finished (candide job 867554). 47h leaves margin under comp/pscomp's 48h MaxTime.
The 47h compute job hung on n23 with zero CPU for ~30 min after tile_merge_headers; shapepipe's candide profile already excludes n23 for past job failures. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013NzWDtdQbsK1VhvYbDnmTo
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013NzWDtdQbsK1VhvYbDnmTo
…o /tmp - scripts/run_config_sims.py: $name in any run-config value expands to the top-level scalar key `name` (my_base_dir, sim, ...), repeatedly; an unexpanded $name is an error rather than a literal directory. Used by the Snakefile and by status_sims.py. - config.yaml: container, psf_dict and shapepipe_repo become shared defaults, so a run config need not repeat them (it may still override them). - status_sims.py: optional -c/--config reads outputs.run_dir and outputs.products_dir from the run config; final_cat is counted on the products root, not under run_dir. - run.sh: TMPDIR is /n23data1/mkilbing/tmp, passed to snakemake (--default-resources tmpdir=) and into the container (--env TMPDIR, plus a bind), since --cleanenv drops the host value. Nothing writes to the node's /tmp any more, per ~/CLAUDE.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013NzWDtdQbsK1VhvYbDnmTo
Brings the image-sims m-bias changes of imsims_workflow onto develop: pipeline_config_dir, sims_type naming, exp_num, ShapePipe processing through ShapePipe's own workflow (sp), campaign provenance, tile_store_root, and the candide profile's latency-wait 60 / job cap. The native shapepipe_run prototype (workflow/image_sims/native) is left out: ShapePipe's unified workflow superseded it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e's sp
- spv run -c RUN_CONFIG [-t TARGET] [snakemake args]: the main config
(workflow/image_sims/config.yaml) plus the user's run config, default
target im_mbias. The code is snapshotted into <grids_base>/spv-state/code
and the run executes out of it (image_sims.sp_validation_repo is set to the
snapshot), so editing the checkout cannot reach running jobs.
- On candide TMPDIR/APPTAINER_TMPDIR must be set outside /tmp and /scratch
(the slurm executor exports the head's TMPDIR to every job, and Slurm
falls back to the node's /tmp when it cannot be created); the snapshot's
profile passes the same directory into the container.
- spv status -c sp_*.yaml | DIR: disk-scan status of ShapePipe campaigns,
workflow/scripts/status_sims.py (from the native prototype's script, which
already read the unified layout; now with its own $name/${name} reader).
- The image-sims Snakefile loads its config next to itself, not relative to
the working directory; im_mbias_config.py reads repo provenance from a
snapshot's snapshot.json when there is no .git.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The state the grid m-bias runs actually used (sp_validation_imsims_workflow
working tree, 2026-10-02), so that spv runs it: the image_sims.smk chain on
top of ShapePipe's own workflow (init -> extract -> calibrate -> m-bias), the
matching workflow/image_sims/config.yaml, the per-tile response jackknife and
related calibration/m-bias changes with their tests, and the mask configs
mask_v1.X.10_im_sim{,_R_now}.yaml. Tests: test_calibration.py and
test_image_sims.py pass (20) in the m-bias image.
Left out: the profile's `config: image_sims={"sif": ...}` -- the image is a
per-user choice and goes in the run config (image_sims.sif). Added: n35 to
the candide excludes (its /tmp was filled on 2026-09-30).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
config_mask.yaml was a symlink into the sp_validation checkout the run came
from. Removing that checkout left every run dir's link dangling, and the next
launch failed at DAG time ("config_mask.yaml seems to be a broken symlink",
evaluating im_calibrate's mem_mb from its input sizes). With spv the source
is the code snapshot, which each launch refreshes. A copy keeps the mask the
run dir was calibrated with.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
n34 hit the per-user thread limit during the image-sims runs, as did n35. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The merge of the uncommitted imsims_workflow work (b268fd6) dropped exp_num from the recognised keys while EXP_NUM still reads it and config.yaml still documents it for the star sims (tiles from *_N, exposures from *_5), so a star-sim run config naming it died at parse as an unknown key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
✅ ruff is clean — nothing to fix here. |
Science files keep this branch's versions (calibration.py,
calibrate_comprehensive_cat.py, image_sims.py, compute_m_bias_image_sims.py
and their tests): the case-d response and shared-tile jackknife supersede
spv-launcher's response_jackknife, R_joint and R_selection_std.
Re-applied from spv-launcher: sims_type picks the sim-dir suffix in
ImageSimMBias.load_catalogs (blended sims are {branch}_{num}).
Kept from spv-launcher: workflow/bin/spv, status_sims.py, exp_num,
tile_store_root, campaign caps, candide profile, snapshot provenance,
mask_v1.X.10_im_sim configs. im_init stages the mask config with
stage_image_sim_config.py (a copy, never a link).
scripts/validation/wdes_response/: the #395 scripts that define case d,
from /n23data1/mkilbing/imsim_wdes_response; docs now point there.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pushed by the lint gate.
Each weighted mean is divided by its own weight sum over its own selection, so R is the response of the ratio <e>_w that it calibrates, including the normalisation term of its derivative. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cailmdaley
force-pushed
the
feat/consistent-response-weights
branch
from
October 26, 2026 19:41
3912954 to
8473903
Compare
cailmdaley
marked this pull request as ready for review
October 26, 2026 19:41
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01114SG5cvfj1gob7zMSQi8A
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Goal: one definition of the galaxy weights, the metacal shear response R = R_shear + R_sel, the image-sim residual multiplicative bias m and the additive bias c, used end to end on data and image sims. One knob,
metacal.weight_scheme: des | iv, sets all four.Findings:
Figures are hosted on the orphan branch
pr-assets/425, outside the PR's history. Definitions:docs/source/response_calibration.md. Reproduction:scripts/validation/response/README.md.Terms
wdes_response.py.What the PR contains
pair_match: true.des_weight_source: selfremains as a diagnostic.workflow/bin/spvlauncher,workflow/scripts/status_sims.py, the image-sims Snakefile/config, and his Global shear response is IV-weighted while shear statistics are w_des-weighted #395 reference scripts inscripts/validation/wdes_response/.Results
All four unblinded grids are combined as inverse-variance means, assuming the grids are independent. m is given as (m1, m2) × 10⁻³.
Estimator
m split into shear-response and selection parts
m_shear-only calibrates with R_shear alone. δm_sel is the change from adding R_sel, at fixed numerator and population, so m = m_shear-only + δm_sel. Grids are combined with the total-m weights so the split stays additive.
Martin's check (top row). Every retained object passes all five branch masks, so R_sel is exactly zero.
Under production cuts and weights, the negative residual sits in the shear-response part, and the selection part partly cancels it. Changing cuts or weights also changes the numerator, so comparing rows is not a physical split into measurement bias and selection bias.
Open: a −1% residual, concentrated at low SNR
The terciles are set by the v2 data's SNR distribution.
A release's m must be measured with that release's own table.
v2 data: what catalogue users feel
Global calibration of v2 data at d604206, with #424 (halo masks dropped):
Follow-ups
mbias_cumulative.yamlandplot_convergenceremain.Closes #395, Closes #156, Closes #21, Closes #22. Refs #23, #346, #382.
Claude (Opus) on behalf of Cail
🤖 Generated with Claude Code