Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
28b0b92
test(ngmix): specify defect fill, epoch cuts and shear recovery near …
cailmdaley Sep 26, 2026
cd8b321
feat(ngmix): noise-fill defects under every BLEND_HANDLING, veto cent…
cailmdaley Sep 26, 2026
7777181
ngmix: read each epoch's OFFSET from the object dict in hand
cailmdaley Sep 26, 2026
9f0ea44
tests: name the none-mode uberseg test for none, not noisefill
cailmdaley Sep 26, 2026
a92a747
test(ngmix): specify DEFECT_FILL = interpolate and its shear recovery
cailmdaley Sep 26, 2026
1bb6437
feat(ngmix): DEFECT_FILL = interpolate, with a fill-dependent central…
cailmdaley Sep 26, 2026
ccbd195
Merge origin/develop into feat/defect-fill-veto
cailmdaley Sep 28, 2026
3e2c76f
Merge origin/feat/defect-fill-veto into feat/defect-interpolation
cailmdaley Sep 28, 2026
576f9c9
Merge origin/develop into rebuild/masked-pixels
cailmdaley Sep 29, 2026
b9d92a9
ngmix: restore the BLEND_HANDLING name noisefill
cailmdaley Sep 29, 2026
23cc5cb
test(ngmix): specify neighbour markers apart from defects
cailmdaley Sep 29, 2026
2517887
fix(ngmix): keep SExtractor's neighbour markers out of the defect set
cailmdaley Sep 29, 2026
7faa9e7
fix(ngmix): off-tile pixels are defects, not neighbours
cailmdaley Sep 29, 2026
f065405
fix(ngmix): interpolate defects from the pixels the image keeps
cailmdaley Sep 29, 2026
b27eca8
fix(ngmix): the defect fill keeps the stamp's dtype
cailmdaley Sep 29, 2026
dcec8c4
Merge remote-tracking branch 'origin/develop' into rebuild/masked-pixels
cailmdaley Sep 29, 2026
a5bfef1
fix(ngmix): off-tile pixels are the marked rows and columns at the st…
cailmdaley Sep 30, 2026
633425d
docs: -1e30 tile-VIGNET markers come from SExtractor or the catalogue…
cailmdaley Sep 30, 2026
d35af2e
Expand ${VAR:-default} in config values
cailmdaley Sep 29, 2026
540a220
Write SEG_VIGNET from the catalogue-mode converter
cailmdaley Sep 29, 2026
13f02c2
Write SEG_VIGNET from the tile SExtractor run
cailmdaley Sep 29, 2026
a4d6880
ngmix: read UberSeg's seg stamps from the tile catalogue's SEG_VIGNET
cailmdaley Sep 29, 2026
22cdd19
Carry blend_handling to tile_detect and ngmix as two prologue exports
cailmdaley Sep 29, 2026
0eb2cfb
make_cat: leave SEG_VIGNET out of final_cat, with VIGNET
cailmdaley Sep 29, 2026
f4e9515
astra.yaml: UberSeg reads the tile catalogue's SEG_VIGNET
cailmdaley Sep 29, 2026
d55abc8
Drop inherited blend variables before any rule
cailmdaley Sep 29, 2026
54807b6
Centre SExtractor-mode SEG_VIGNET on X/Y_IMAGE_DBL
cailmdaley Sep 29, 2026
60ae234
Point the stale SEG_VIGNET_PATH message and astra note at SEG_VIGNET
cailmdaley Sep 29, 2026
c704e63
Make UberSeg the default blend handling
cailmdaley Sep 30, 2026
cbec30f
Measure windowed centroids for UNIONS-catalogue tiles
cailmdaley Sep 30, 2026
da14676
Windowed centroid: mirror no-data pixels, guard NaN and wild FLUX_RADIUS
cailmdaley Sep 30, 2026
e167e0f
Revert the windowed-centroid port
cailmdaley Oct 1, 2026
4c25095
Merge origin/develop into fix/dr6-windowed-positions
cailmdaley Oct 1, 2026
a57e8ef
Config values expand ${VAR:-default}
cailmdaley Oct 1, 2026
cca72e0
sextractor_runner: join detections to an external catalogue
cailmdaley Oct 1, 2026
8274d99
Detect tiles with SExtractor on data too; drop the catalogue converter
cailmdaley Oct 1, 2026
f8b2e7b
Merge origin/develop into fix/dr6-windowed-positions
cailmdaley Oct 1, 2026
2a1fd49
sextractor_runner: single-image SExtractor without a detection image
cailmdaley Oct 1, 2026
7ac9884
match_catalogue: two-sided pairing guard; record the eight-tile valid…
cailmdaley Oct 1, 2026
e02f1f8
Config expansion rejects malformed ${ forms
cailmdaley Oct 1, 2026
c6725a7
tile_detect: 1 core, 4 GB, 20 min from eight measured tiles
cailmdaley Oct 1, 2026
5779c07
Update the params pin for this campaign boundary
cailmdaley Oct 1, 2026
6a8ee50
Tile SExtractor: MEMORY_PIXSTACK 3000000, so no object is truncated
cailmdaley Oct 1, 2026
5983208
match_catalogue: guard at 2% beyond 20 unpaired per side
cailmdaley Oct 1, 2026
976810c
Merge origin/feat/uberseg-seg-vignet (#925) onto #933's tile detection
cailmdaley Oct 1, 2026
2a058c0
SEG_VIGNET keeps own-vs-other through the DR6 join
cailmdaley Oct 1, 2026
45eef5d
tile_detect: 3000 MB more under uberseg for SEG_VIGNET
cailmdaley Oct 1, 2026
ed6a3db
Update the params pins for UberSeg on #933's detection
cailmdaley Oct 1, 2026
b152c76
tile.smk: keep the catalogue path on one line, as the tile-detection …
cailmdaley Oct 2, 2026
55af8dc
SEG_VIGNET centres as SExtractor centres VIGNET: (int)(mx + 0.49999)
cailmdaley Oct 2, 2026
3f5a263
match_catalogue: refuse NUMBERs the int32 columns cannot hold
cailmdaley Oct 2, 2026
a45b70e
Merge origin/develop (#933 squashed, #927) into feat/uberseg-seg-vignet
cailmdaley Oct 2, 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
133 changes: 78 additions & 55 deletions astra.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1421,22 +1421,25 @@ analyses:
defect_fill:
label: Image content of defect pixels before metacal
rationale: >-
A defect pixel (nonzero instrument flag, zero exposure weight or
invalid background RMS) gets weight 0 in prepare_ngmix_weights. Its
A defect pixel (nonzero instrument flag, zero exposure weight,
invalid background RMS, or off-tile) gets weight 0 in prepare_ngmix_weights. Its
image value still matters: ngmix's metacal deconvolves, shears and
reconvolves an InterpolatedImage of the whole image and copies the
weights through, so a zero-weight pixel's content spreads into the
weighted pixels within about a PSF width. DES's ngmixer fills for
that reason: "it may be important for codes that take moments or use
FFTs". In the committed default (`BLEND_HANDLING = noisefill`),
masked pixels are replaced with independent noise at the per-pixel
background RMS when supplied, or the stamp's robust noise scale
otherwise. With `BLEND_HANDLING = uberseg`, the image is left
untouched and weights are zeroed on defects and neighbour-side
pixels. [LINT] the prepare_ngmix_weights docstring says noisefill
keeps the weight of filled pixels (the code zeroes it), and the
ngmix_runner comment says noisefill fills neighbour pixels (it fills
flagged pixels and leaves neighbours untouched). The committed fill
FFTs". Under every BLEND_HANDLING, the committed uberseg included,
and the default DEFECT_FILL =
noise, defect pixels are replaced with independent noise at the
per-pixel background RMS when supplied, or the stamp's robust noise
scale otherwise. The tile VIGNET holds -1e30 on other detections'
footprints and beyond the tile's edge (written by SExtractor). The runs of entirely -1e30 stamp
rows and columns that start at a stamp border (the off-image part of
a rectangle clip) are off-tile: the epoch holds the object's own
light there, so they are defects, flagged 2**10. The other markers,
including a neighbour footprint that completes an interior row
beside an off-tile band, are neighbour pixels, not defects;
blend_handling decides their treatment. The committed fill
uses the unsymmetrized defect set: DES symmetrized its masks, but
four-fold symmetrization quadruples m and still leaves an additive c1
(symmetrized_4fold_noise). The cost of not symmetrizing, a hole in
Expand All @@ -1458,7 +1461,11 @@ analyses:
interpolate:
label: Interpolate short bounded runs; noise-fill the rest
description: >-
Not implemented. PR #916 measures c1 = -1.3e-3 for a column
DEFECT_FILL = interpolate: row or column runs of at most
MAX_INTERPOLATED_RUN = 3 defect pixels that stop short of the
stamp border are Clough-Tocher interpolated from the clean pixels
within SUPPORT_RADIUS = 4 px; other defects are noise-filled.
PR #916 measures c1 = -1.3e-3 for a column
8 px from a 0.5 arcsec galaxy and +2e-6 when the weight is also
zeroed on its quarter-turn orbit. For a 3-px bleed 6 px from that
galaxy, PR #916 measures m11 = +0.89% when the fill is
Expand All @@ -1476,11 +1483,11 @@ analyses:
with symmetrization against 0.7e-4 without it.
insights: [mask_bad_column_symmetrize, mask_des_defect_practice, mask_fixed_orientation]
raw:
label: "No fill: raw defect values (BLEND_HANDLING = uberseg)"
label: "No fill: raw defect values"
description: >-
With BLEND_HANDLING = uberseg, defect pixels keep weight 0 but
their image values stay untouched in the image that metacal
deconvolves, shears and reconvolves.
Defect pixels keep weight 0 but their image values stay
untouched in the image that metacal deconvolves, shears and
reconvolves.
excluded: true
excluded_reason: >-
Metacal acts on every pixel regardless of weight, so raw defects
Expand All @@ -1490,12 +1497,15 @@ analyses:
blend_handling:
label: Neighbour treatment before metacal
rationale: >-
Covers only pixels shared with a neighbour; defect_fill is coupled to
it through BLEND_HANDLING. noisefill (the default; the committed
config sets no key) leaves neighbours fully weighted and untouched.
uberseg zeroes the weight of pixels nearer a neighbour's coadd
segmentation footprint than the target's (DILATE_NEIGHBOUR, default 1)
and leaves the image untouched, as official uberseg does:
Covers only pixels shared with a neighbour; defect_fill does not
depend on it: defects are filled the same way under every
BLEND_HANDLING, and the epoch cuts never count neighbour pixels.
The committed choice is uberseg (the workflow's default
blend_handling), which ignores the -1e30 neighbour markers in the
tile VIGNET and zeroes the weight of pixels nearer a neighbour's
coadd segmentation footprint than the target's (DILATE_NEIGHBOUR,
default 1), leaving the neighbour side's image untouched, as
official uberseg does:
esheldon/meds get_uberseg returns a weight map (a
nearest-segment-pixel Voronoi split). DES Y1's fiducial metacal and
the last Y3 config ran on uberseg-weighted stamps with raw neighbour
Expand All @@ -1512,24 +1522,31 @@ analyses:
with simulations (mask_des_y1_uberseg_only,
mask_blend_bias_detection). Noise-filling the neighbour side would
instead cut the target's own light along an unsheared boundary, a
sharp edge that rings in the FFTs. The recommended comparison arm is
uberseg (weight-only), with defect_fill held equal across arms.
default: none
sharp edge that rings in the FFTs. The alternative, noisefill
(ngmix's own default, and the workflow's blend_handling:
noisefill), gives weight 0 to the pixels marked -1e30 in the tile
VIGNET on other detections' footprints (about 93% of
neighbour-footprint pixels on a simulated tile), excluding the
off-tile rows and columns, which are defects, and replaces them with
noise; unmarked neighbour pixels keep their weight and light. It is
the comparison arm, with defect_fill held equal across arms.
default: uberseg
options:
none:
label: No neighbour treatment (BLEND_HANDLING = noisefill)
noisefill:
label: Noise-fill the marked neighbour pixels (BLEND_HANDLING = noisefill)
description: >-
Neighbour pixels keep their full weight and image values, so the
fit sees all neighbour light, which biases shapes toward
neighbours (Jarvis et al. 2016); this masks less than even their
plain segmentation map. A candidate cause of the FLAGS=2 B-modes
Pixels marked -1e30 in the tile VIGNET get weight 0 and noise.
The fill stops at the marked footprint, so unmarked neighbour
pixels and the neighbour's wings keep their weight and light,
which biases shapes toward neighbours (Jarvis et al. 2016). A
candidate cause of the FLAGS=2 B-modes
investigated in #814.
insights: [mask_uberseg_neighbour_bias]
uberseg:
label: UberSeg, weight-only
description: >-
As in DES Y1/Y3. Needs the coadd segmentation stamp
(SEG_VIGNET_PATH). DILATE_NEIGHBOUR absorbs the coadd-vs-epoch
As in DES Y1/Y3. Needs the coadd segmentation stamp (the tile
catalogue's SEG_VIGNET). DILATE_NEIGHBOUR absorbs the coadd-vs-epoch
overlay offset: ShapePipe reuses one coadd seg stamp for every
epoch where MEDS reprojects it.
insights: [mask_uberseg_weight_only, mask_uberseg_neighbour_bias, mask_des_y1_uberseg_only, mask_blend_bias_detection]
Expand All @@ -1553,11 +1570,13 @@ analyses:
central_defect_veto:
label: Per-epoch veto on a defect near the stamp centre
rationale: >-
Not on develop; implemented on feat/defect-fill-veto (7777181b).
There an epoch is dropped when a defect pixel lies strictly closer
to the stamp centre than its fill's radius, beside the
masked-fraction cut in the epoch loop. The veto reads only the
defect mask, so it selects on nothing shear-responsive; for the same
An epoch is dropped when a defect pixel lies strictly closer to the
stamp centre than its fill's radius, beside the masked-fraction cut
in the epoch loop; EPOCH_CENTRAL_DEFECT_RADIUS = 0 disables it.
The tile VIGNET's -1e30 neighbour markers are not defects: all epochs
share the tile VIGNET, so a neighbour inside the radius would drop
every epoch. Off-tile pixels are defects, so an object near the
tile edge is vetoed. The veto reads only the defect mask, so it selects on nothing shear-responsive; for the same
reason the radii are fixed rather than scaled by galaxy size: 10 px
for noise-filled pixels (EPOCH_CENTRAL_DEFECT_RADIUS) and 7 px for
interpolated ones (EPOCH_INTERPOLATED_DEFECT_RADIUS,
Expand All @@ -1568,16 +1587,18 @@ analyses:
wide defects through the elliptical PSF sit at the 1% bound (m11 =
-0.98%; -0.24% at 11 px), and noise fill needs 14 px for 0.7 and 0.9
arcsec galaxies. Measured on feat/defect-fill-veto and
feat/defect-interpolation.
default: disabled
feat/defect-interpolation. The 7 px radius applies only under
DEFECT_FILL = interpolate; with the committed noise fill every defect
takes the 10 px radius.
Values:
EPOCH_CENTRAL_DEFECT_RADIUS = 10;
EPOCH_INTERPOLATED_DEFECT_RADIUS = 7.
default: fixed_radii
options:
disabled:
label: No central veto (committed code)
label: No central veto (EPOCH_CENTRAL_DEFECT_RADIUS = 0)
fixed_radii:
label: Fixed radii, 10 px for noise-filled and 7 px for interpolated defects
description: >-
Implemented on feat/defect-fill-veto and feat/defect-interpolation,
not on develop.
size_scaled_radius:
label: Veto radius scaled by galaxy size
excluded: true
Expand All @@ -1587,14 +1608,16 @@ analyses:
epoch_masked_fraction_cut:
label: Per-epoch masked-fraction cut
rationale: >-
[HARDCODED] on develop, an epoch whose stamp has more than 1/3 of its
pixels flagged (any nonzero flag bit, including the tile-coverage bit
2**10 set where the tile vignet is off-image) is dropped from the
multi-epoch fit; an object with no surviving epoch has no shape.
Zero-weight and invalid-RMS pixels are not counted. On
feat/defect-fill-veto the cut counts the raw, unsymmetrized defect
set (flagged, zero-weight and invalid-RMS pixels) against
EPOCH_MASKED_FRACTION_CUT, default 1/3. Before the cut, an epoch is
An epoch whose stamp has more than EPOCH_MASKED_FRACTION_CUT
(default 1/3) of its pixels in the raw, unsymmetrized defect set is
dropped from the multi-epoch fit: flagged pixels (any nonzero
exposure flag bit), zero-weight pixels, invalid-RMS pixels and
off-tile pixels (whole -1e30 rows and columns at the tile VIGNET's
border, flag 2**10), the set defect_fill fills. On a 51-px stamp an object
within about 8.5 px of the tile edge fails the 1/3 cut. The other
-1e30 markers, neighbour footprints, are not counted: every epoch
shares the tile VIGNET, so a large neighbour would drop them all. An object with no surviving epoch has no
shape. Before the cut, an epoch is
dropped silently if its galaxy stamp is all zeros or its
background-subtracted sigma_mad is not positive. DES was stricter:
Y1 rejected any epoch with a masked or zero-weight pixel, or with
Expand All @@ -1610,12 +1633,12 @@ analyses:
label: 1/3 of the stamp in the defect set
description: >-
Drop an epoch only if more than 1/3 of the stamp pixels are
defects (on develop, flagged pixels).
defects.
ten_percent:
label: 10% (DES Y3 / Y6)
description: >-
Not a default; EPOCH_MASKED_FRACTION_CUT = 0.1 on
feat/defect-fill-veto. Matches DES Y3 max_zero_weight_frac and
Not a default; EPOCH_MASKED_FRACTION_CUT = 0.1. Matches DES Y3
max_zero_weight_frac and
Y6 max_masked_fraction.
insights: [mask_multi_epoch_drop]
any_masked:
Expand Down
4 changes: 3 additions & 1 deletion src/shapepipe/modules/make_cat_package/make_cat.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ def save_sextractor_data(final_cat_file, sexcat_path, remove_vignet=True):
sexcat_path : str
Path to SExtractor catalogue to save
remove_vignet : bool
If ``True`` will not save the ``VIGNET`` field into the final catalogue
If ``True`` will not save the ``VIGNET`` and ``SEG_VIGNET`` stamp
fields into the final catalogue

Returns
-------
Expand All @@ -127,6 +128,7 @@ def save_sextractor_data(final_cat_file, sexcat_path, remove_vignet=True):
data = np.copy(sexcat_file.get_data())
if remove_vignet:
data = remove_field_name(data, "VIGNET")
data = remove_field_name(data, "SEG_VIGNET")
cat_size = len(data)

tile_name = os.path.basename(sexcat_path)
Expand Down
Loading
Loading