-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathastra.yaml
More file actions
2121 lines (2105 loc) · 104 KB
/
Copy pathastra.yaml
File metadata and controls
2121 lines (2105 loc) · 104 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# ASTRA record of ShapePipe's scientific decisions: the choices embedded in
# the code and the committed workflow configs (workflow/config/cfis/), why
# they stand, and the alternatives. CLAUDE.md says when to amend it.
# workflow/config/cfis_image_sims/ is not yet in scope: its symlinks into
# cfis/ are governed there; its untagged overlays change input naming, the PSF
# model and some governed values (config_tile_Fe.ini COLNUM/EXP_PREFIX,
# final_cat.param columns).
#
# Conventions (`tests/helpers/decisions.py` implements them and documents the
# full value grammar; `tests/unit/test_decisions.py` enforces them):
# * Put `@sc [decision:<id>]` at every code/config site that implements a
# decision. Decision citations have no id or prose; the record is the source
# of rationale. IDs are bare for top-level decisions and dotted for
# sub-analysis decisions; repeat `decision:` metadata to cite several.
# A local constraint adds a stable id and prose, with optional decision
# metadata: `@sc [decision:<id>,label:<kind>] <contract-id>`.
# * In Python, put tags in a def/class docstring or as a comment immediately
# above a module statement. In Snakemake, put a comment immediately above
# the rule/statement. In config, a tag governs the active settings in the
# following paragraph, which ends at the next blank line or `@sc` line.
# Every active key before that boundary is governed. A blank line between a
# tag and its key is an error. To govern a whole section, put the tag
# directly above its `[SECTION]` header; it governs active keys through the
# next section header. A description comment may sit above the tag, and
# `scope:file` governs the whole file.
# * A rationale may end with `Values: <ref> = <value>; ... .`. Every ref must
# resolve to exactly one site tagged for that decision and match its value.
# Use a bare key when it selects one site; qualify it with a path suffix and
# `#` or `::` when needed. `= absent` requires a same-decision tag somewhere
# in the file (in that section or file-wide for INI/SETools) and asserts that
# no active setting exists anywhere in the target scope. INI absence checks
# include keys inherited from `[DEFAULT]`.
# * The checker validates citations in both directions, unique local-contract
# ids, literal values and test `decision` markers. The value grammar is
# documented in the helper module's docstring.
# * A decision's `default` is the option the committed code and configs
# select; universes/committed.yaml pins it.
# * `excluded: true` means considered and rejected. An option the code
# does not implement says so in its description and is not excluded.
# * [HARDCODED]: the committed choice is fixed in code, with no config key.
# [LINT]: the code disagrees with itself or its own documentation.
# * A prior insight repeated inside a sub-analysis carries a `_local`
# suffix, because insight ids are scoped.
version: "0.0.14"
name: ShapePipe scientific decisions
description: >-
Codebase-level decision record for the ShapePipe weak-lensing pipeline
(UNIONS/CFIS) as orchestrated by workflow/Snakefile. Membership test: a
different defensible choice would change which objects enter the shear
catalogue, or the numbers attached to them.
tags: [shapepipe, weak-lensing, unions, codebase-record]
container: ghcr.io/cosmostat/shapepipe:develop
inputs:
- id: tile_images
type: data
source: CFIS/UNIONS r-band MegaPipe tile stacks and single-exposure image/weight/flag triplets (workflow/config.yaml)
description: >-
Tiles and the exposures that built them; each exposure carries its
instrument flag image.
- id: healsparse_masks
type: data
source: UNIONS healsparse mask products (e.g. mask_ugriz_nside131072_n4.hsp)
description: >-
Sky-fixed mask maps, built outside ShapePipe and queried at object
positions; how they are used is the masking sub-analysis.
outputs:
- id: final_cat
type: data
format: fits
description: >-
Per-tile shear catalogue family, the terminal science product
(make_cat_runner).
inputs: [tile_images, healsparse_masks]
decisions: [per_unit_completeness, postage_stamp_size, photometric_zeropoint]
decisions:
# ── cross-cutting ────────────────────────────────────────────────────────
per_unit_completeness:
label: Per-unit completeness gate
rationale: >-
Every shapepipe_run rule checks its products against a per-runner
nominal count (per chunk for tile_ngmix). The unit fails if a
non-warning runner falls short or shapepipe_run exits nonzero, and a
failed unit publishes no manifest for later rules to build on. A tile
needs the exp_psf manifest of every exposure it lists, so one failed
exposure keeps every tile it contributes to out of the catalogue; the
tile does not run with fewer epochs. The one tolerated shortfall is the
exposure-side psfex_interp VALIDATION output. A CCD whose model fails
the acceptance gate (star_selection_psf.psf_acceptance_thresholds)
produces nothing there, and the unit only warns. Science-path PSF
rejection bypasses this table: psfex_interp drops that epoch per object
inside the tile run. The MCCD table (one mask_query catalogue per CCD;
one train and one test catalogue per exposure) warns on every runner,
and the workflow refuses psf_model=mccd.
Values:
COMPLETENESS[exp_psf.psfex.psfex_interp_runner.warn] = True;
COMPLETENESS[exp_psf.mccd.mask_query_runner.expect] = 40;
COMPLETENESS[exp_psf.mccd.mccd_preprocessing_runner.expect] = 2.
default: exact_counts
options:
exact_counts:
label: Nominal count per runner; psfex_interp validation shortfall warns
insights: [des_psf_blacklist, guinot22_star_floor_22]
count_floor:
label: Tolerate recorded attrition down to a per-runner floor
excluded: true
excluded_reason: >-
The floors had no basis: across a 127-exposure, 64-tile campaign
every non-warning runner produced exactly its nominal count, so a
floor below it only admits failed units unremarked.
no_gate:
label: Accept whatever is produced
excluded: true
excluded_reason: >-
A stage producing 2 of 40 CCDs would flow into the catalogue
unremarked.
postage_stamp_size:
label: Postage-stamp size shared by vignets, ngmix stamps and PSF models
rationale: >-
Every stamp width is 51 px (about 9.5 arcsec): the tile VIGNET (cut
by the tile SExtractor run), the multi-epoch vignetmaker stamps
ngmix fits, the exposure SExtractor VIGNET PSFEx trains on, and the
PSFEx model stamp. Only the first two are coupled: ngmix lays the tile
VIGNET's -1e30 neighbour markers over each epoch stamp pixel for pixel,
so they must be the same size. The stamp truncates the wings of large
galaxies. No rationale for 51 px is recorded.
Values:
default_noimaflags.param#VIGNET = 51;
default.param#VIGNET = 51;
VIGNETMAKER_RUNNER_RUN_1.STAMP_SIZE = 51;
VIGNETMAKER_RUNNER_RUN_2.STAMP_SIZE = 51;
PSF_SIZE = 51.
default: px_51
options:
px_51:
label: 51x51 px everywhere
larger_adaptive:
label: Larger or size-adaptive stamps
description: >-
Per-object sizes are not implemented. A larger fixed size is a
config change, provided the tile VIGNET and the multi-epoch stamp
change together.
photometric_zeropoint:
label: Magnitude zero-point convention
rationale: >-
Exposures read the per-image header PHOTZP, so the PSF-star MAG_AUTO
window is on each exposure's own scale. Epochs are multiplied by header
FSCALE before the joint fit, which puts them on zero-point 30 only if
FSCALE = 10^(-0.4 (PHOTZP - 30)). Nothing in the repo checks this, but it
held to 0.02% on a sampled exposure (2114045p). ngmix magnitudes use
MAG_ZP = 30. The tile SExtractor run uses a fixed zero-point of 30
(ZP_FROM_HEADER=False), which assumes the MegaPipe stacks are
calibrated to 30.
Values:
MAG_ZEROPOINT = 30.0;
config_tile_Sx.ini#SEXTRACTOR_RUNNER.ZP_FROM_HEADER = False;
NGMIX_RUNNER.MAG_ZP = 30.0;
config_exp_psfex.ini#SEXTRACTOR_RUNNER.ZP_FROM_HEADER = True;
SEXTRACTOR_RUNNER.ZP_KEY = PHOTZP.
default: fixed_30_tiles_header_exposures
options:
fixed_30_tiles_header_exposures:
label: Tiles fixed 30.0; exposures from header PHOTZP
header_everywhere:
label: Per-image header zero-points on tiles too
description: >-
ZP_FROM_HEADER=True for tile SExtractor; changes tile magnitudes
only where a tile's header zero-point differs from 30. ngmix MAG_ZP
stays 30.
prior_insights:
des_psf_blacklist:
claim: >-
DES blacklists a CCD's PSF model rather than failing the exposure: in
Y3, a CCD with fewer than 25 stars surviving outlier rejection is
excluded downstream (~2% of data removed) and processing proceeds.
created_at: "2026-07-16T00:00:00Z"
evidence:
- id: ev_jarvis_y3
doi: "10.48550/arXiv.2011.03409"
quote:
exact: "we enter it into a"
suffix: " “blacklist” and exclude this CCD"
location: { page: 10 }
guinot22_star_floor_22:
claim: >-
The published ShapePipe/UNIONS analysis applies a per-CCD quality floor
rather than failing whole exposures: a CCD with fewer than 22 selected
stars is discarded for PSF estimation and contributes no epoch to the
shape measurement, while processing continues.
created_at: "2022-04-01T00:00:00Z"
evidence:
- id: ev_guinot22_star_floor
doi: "10.48550/arXiv.2204.04798"
quote:
exact: 'The dashed line represents the cut at 22 stars/CCD below which the CCD is discarded for the PSF estimation.'
location: { page: 4 }
analyses:
# ═════════════════════════════════════════════════════════════════════════
masking:
description: >-
Which external masks reach the measurement, and where. The instrument
flag image delivered with each exposure is the only one that reaches
pixels. Sky-fixed masks (star halos and bodies, manual regions, missing
bands) are healsparse maps built and designed outside ShapePipe, which
only queries them at object positions into catalogue columns that no
stage cuts on.
inputs:
- id: exposure_flags
type: data
source: per-CCD instrument flag images split from each exposure (exp_split family)
- id: sky_masks
type: data
source: UNIONS healsparse mask maps
outputs:
- id: masked_measurement_inputs
type: data
format: fits
description: >-
Exposure detection catalogues carrying IMAFLAGS_ISO (and MASK_EXT when
maps are configured), the flag stamps ngmix reads, and the final
catalogue's optional MASK_<band> columns.
inputs: [exposure_flags, sky_masks]
decisions: [pixel_mask_source, psf_star_mask_veto, sky_mask_application]
decisions:
pixel_mask_source:
label: >-
Of the external masks, only the instrument flag image reaches pixels
rationale: >-
On exposures SExtractor reads the split flag image, producing
IMAFLAGS_ISO, which the PSF star selection requires to be zero. The
multi-epoch vignet run cuts flag stamps from the same image; ngmix
gives flagged pixels weight 0 and drops epochs more than a third
flagged (shape_measurement.defect_fill,
shape_measurement.epoch_masked_fraction_cut). Tiles have no flag
image, and ShapePipe's tile SExtractor run requests no IMAFLAGS_ISO
(detection.detection_source_mode). Neighbour pixels are masked
separately, from the -1e30 markers SExtractor writes into the tile
VIGNET (shape_measurement.blend_handling). Sky-fixed masks never touch
pixels: a star halo changes no stamp.
Values:
config_exp_psfex.ini#SEXTRACTOR_RUNNER.FLAG_IMAGE = True;
VIGNETMAKER_RUNNER_RUN_2.ME_IMAGE_PATTERN = flag, image, weight,
background, background_rms.
default: instrument_flags_only
options:
instrument_flags_only:
label: Instrument flags gate pixels; sky masks stay at catalogue level
rasterised_sky_masks:
label: Rasterise healsparse masks into the pixel flags
insights: [farrens22_pipeline_masks]
excluded: true
excluded_reason: >-
Sky-fixed masks say where an object sits, not that its pixels are
corrupted, so acting on them is an analysis decision.
Rasterising would bake one mask version into every shape.
psf_star_mask_veto:
label: PSF-star candidates rejected on instrument flags only
rationale: >-
Of the masks, star selection cuts only on IMAFLAGS_ISO. mask_query sits
between SExtractor and setools in the exposure chain; when
MASK_PATHS names maps it writes MASK_EXT (0 clean, nonzero flagged,
off-coverage clean) onto each CCD's catalogue. MASK_PATHS ships
commented out, so the module passes catalogues through without
MASK_EXT. The intended map is the UNIONS star-body product (bit 2);
halo bits 0 and 1 are left out because halos say nothing about
whether a star is a good PSF sample.
Values:
MASK:star_selection.IMAFLAGS_ISO = "== 0";
MASK:preselect.IMAFLAGS_ISO = "== 0";
MASK:flag.IMAFLAGS_ISO = "== 0";
MASK:star_selection.MASK_EXT = absent;
MASK:preselect.MASK_EXT = absent;
MASK:flag.MASK_EXT = absent.
default: instrument_flags_only
options:
instrument_flags_only:
label: IMAFLAGS_ISO == 0; no sky map queried
star_body_veto:
label: Also reject candidates on the star-body map (MASK_EXT == 0)
description: >-
Set MASK_PATHS to the star-body map and add MASK_EXT == 0 beside
each IMAFLAGS_ISO cut in star_selection.setools (one line per
mask block). Querying without the cut records MASK_EXT and
changes no star.
star_body_and_halo_veto:
label: Also reject candidates inside star halos
excluded: true
excluded_reason: >-
Halos flag objects for the final catalogue; a star inside another
star's halo is not thereby a bad PSF sample.
sky_mask_application:
label: Object-level sky masking deferred downstream
rationale: >-
The final catalogue ships every detected object. When MASK_EXT_PATHS
lists band:path pairs, make_cat queries each healsparse map at the
object's windowed position and writes the map value verbatim into a
MASK_<band> column; an object off coverage gets the map's sentinel
(False for boolean maps, reading as unmasked; typically -1 for
integer maps). The committed config sets no MASK_EXT_PATHS, so no
mask column is written and all mask cuts happen downstream.
default: deferred_downstream
options:
deferred_downstream:
label: No mask columns; all objects shipped
catalogue_columns:
label: Per-band MASK_<band> columns from MASK_EXT_PATHS, no cut
pipeline_cut:
label: Drop masked objects inside the pipeline
excluded: true
excluded_reason: >-
Location flags are analysis decisions; a pipeline cut would fix
one mask version into the catalogue.
prior_insights:
farrens22_pipeline_masks:
claim: >-
The published ShapePipe pipeline generated its own masks, including
Messier objects and CCD borders, and applied them to the images; the
current pipeline applies no sky-fixed mask to pixels.
created_at: "2022-06-01T00:00:00Z"
evidence:
- id: ev_farrens22_masks
doi: "10.48550/arXiv.2206.14689"
quote:
exact: 'Messier objects, and border regions.'
location: { page: 2 }
# ═════════════════════════════════════════════════════════════════════════
detection:
description: >-
Object detection on r-band tiles (the galaxy sample) and on
single-exposure CCDs (PSF-star candidates), both by ShapePipe's own
SExtractor runs. The tile run follows the MegaPipe parameters of Gwyn's
UNIONS tile catalogue, and in committed data its detections are joined
to that catalogue (tile_detection); exposures keep ShapePipe's stock
values.
inputs:
- id: tile_stack
type: data
source: MegaPipe r-band tile stack + weight (uncompressed, merged headers)
outputs:
- id: tile_sexcat
type: data
format: fits
description: Per-tile SExtractor LDAC catalogue with per-epoch CCD membership.
inputs: [tile_stack]
decisions:
[tile_detection, detection_threshold_policy, deblending_policy,
background_model,
weight_map_usage, zero_weight_interpolation, detection_source_mode,
epoch_membership_ccd_bounds, photometry_parameters,
spurious_detection_cleaning, blend_photometry_mask_type,
saturation_level]
decisions:
tile_detection:
label: Object list and NUMBER of the tile galaxy sample
rationale: >-
Both options run ShapePipe's tile SExtractor, so data and image
simulations share one detection and measurement path: windowed
positions, VIGNET neighbour markers and every SExtractor column.
In real data each detection is then paired with its mutual nearest
neighbour within 1 px in Gwyn's UNIONS per-tile catalogue and takes
its NUMBER, so shape, photometry and photo-z catalogues share one
object list and one ID (TILE_UNIQUE_ID); unpaired detections leave
the catalogue. The catalogue is MegaPipe's SExtractor run on the
same DR6 image with the configuration of default_tile.sex
(detection_threshold_policy), so pairs agree to 4e-5 px at the
median. On tile 186.307 every one of the 41,201 detections pairs;
over eight DR6 tiles spanning a rich cluster, a bright star's halo,
low latitude and the survey edge, at least 99.7% of detections and
99.2% of catalogue objects pair. The catalogue objects with no
detection (0-0.7%, mostly fainter than MAG_AUTO 24.5) are
deblended children that ShapePipe's SExtractor leaves merged,
concentrated around very large objects; they have photometry but
no shape. The join needs the tile image to be the catalogue's
release: on the DR5 image of a tile only ~95% of detections pair.
The run stops when the unpaired detections, or the unpaired
catalogue objects, exceed both 2% of their side and 20 objects: a
margin over deblending near large objects, a stop for other pixels. PSF stars come from the exposure-level
SExtractor run in both options. Image simulations, which have no
UNIONS catalogue, keep SExtractor's own NUMBER.
Values:
input_types.data.tile_detection = unions_catalogue;
config_tile_Sx.ini#SEXTRACTOR_RUNNER.MATCH_RADIUS = 1.0;
config_tile_Sx.ini#SEXTRACTOR_RUNNER.MATCH_MIN_FRACTION = 0.98;
config_tile_Sx.ini#SEXTRACTOR_RUNNER.MATCH_TOLERATED_UNPAIRED = 20.
default: unions_catalogue
options:
unions_catalogue:
label: Tile SExtractor joined to Gwyn's UNIONS per-tile catalogue
sextractor:
label: Tile SExtractor with its own NUMBER
detection_threshold_policy:
label: Detection significance, minimum area, matched filter
rationale: >-
Tile SExtractor uses the MegaPipe tile-catalogue threshold, minimum
area and filter, so that its galaxy sample reproduces the UNIONS
catalogue whose NUMBER committed data adopts (tile_detection). Run
on the DR6 image of tile 186.307, it reproduces the DR6 catalogue to 99.89% completeness
and 100% purity with identical segmentation pixels; the 45 misses
are faint deblended children of bright parents (#929). The pixel
stack (MEMORY_PIXSTACK) holds the largest object on every tested
tile, a bright star's halo included, so no object is truncated.
Unexplained: on tiles with such a large object (a cD galaxy, a
bright star's halo) MAG_AUTO and FLUX_RADIUS differ from the
catalogue by more than 1% for 2-11% of objects, most of them past
the large object in SExtractor's scan order, and on one
low-latitude tile for 2% of objects spread over the tile. The
catalogue's run must differ in a setting not recorded here
(memory, version); shapes use ShapePipe's measurements and
photometry the catalogue's, so for those objects the two differ. This
validates the configuration on data pixels, not detection on
simulated images. The 7x7 Gaussian of FWHM 3 px is
near the CFIS average seeing of 0.65 arcsec (about 3.5 px at
0.187 arcsec/px). Exposures only feed star selection and keep stock
values with the 3x3 FWHM 2 px kernel. The tiles differ from Guinot+22
in all three.
Values:
config_tile_Sx.ini#SEXTRACTOR_RUNNER.DOT_SEX_FILE =
$SP_CONFIG/default_tile.sex;
default_tile.sex#DETECT_THRESH = 1.0;
default_tile.sex#ANALYSIS_THRESH = 1.0;
default_tile.sex#DETECT_MINAREA = 3;
default_tile.sex#FILTER = Y;
default_tile.sex#MEMORY_PIXSTACK = 3000000;
config_tile_Sx.ini#SEXTRACTOR_RUNNER.DOT_CONV_FILE =
$SP_CONFIG/gauss_3.0_7x7.conv;
config_exp_psfex.ini#SEXTRACTOR_RUNNER.DOT_SEX_FILE =
$SP_CONFIG/default_exp.sex;
default_exp.sex#DETECT_THRESH = 1.5;
default_exp.sex#ANALYSIS_THRESH = 1.5;
default_exp.sex#DETECT_MINAREA = 5;
default_exp.sex#FILTER = Y;
config_exp_psfex.ini#SEXTRACTOR_RUNNER.DOT_CONV_FILE =
$SP_CONFIG/default.conv.
default: megapipe_tiles
options:
megapipe_tiles:
label: MegaPipe values on tiles; stock values on exposures
insights: [guinot22_cfis_seeing]
stock_tiles:
label: Stock ShapePipe values on tiles (1.5 sigma, minarea 5, FWHM 2 px)
insights: [guinot22_sextractor_params]
excluded: true
excluded_reason: >-
Triggers spuriously on about 10% of grid-placed Sersic galaxies
in image simulations, and does not match the MegaPipe tile
catalogue.
deblending_policy:
label: Deblending contrast
rationale: >-
Tiles use the MegaPipe DEBLEND_MINCONT; exposures use a lower one,
the value Guinot+22 lists. Both share DEBLEND_NTHRESH. Contrast sets
object count, centroids, and blend contamination in shapes;
matching image simulations must preserve the stage-specific settings.
Values:
default_tile.sex#DEBLEND_MINCONT = 0.002;
default_exp.sex#DEBLEND_MINCONT = 0.001;
default_tile.sex#DEBLEND_NTHRESH = 32;
default_exp.sex#DEBLEND_NTHRESH = 32.
default: megapipe_tiles
options:
megapipe_tiles:
label: MINCONT 0.002 tiles / 0.001 exposures
insights: [guinot22_sextractor_params]
mincont_5em4_tiles:
label: MINCONT 0.0005 on tiles
excluded: true
excluded_reason: >-
Part of the stock tile parameter set rejected in favour of the
MegaPipe values (see detection_threshold_policy).
background_model:
label: Background estimation and photometric background
rationale: >-
Both passes use SExtractor AUTO backgrounds: tiles with the MegaPipe
mesh and filter sizes and a LOCAL photometric background, exposures
with a finer mesh and a GLOBAL one. ngmix subtracts the exposure
BACKGROUND map from each epoch and weights its pixels by
BACKGROUND_RMS (shape_measurement.galaxy_pixel_weights). The header
background path is off. Residual sky offsets propagate into
thresholds, fluxes, completeness and shapes.
Values:
default_tile.sex#BACK_TYPE = AUTO;
default_tile.sex#BACK_SIZE = 512;
default_tile.sex#BACK_FILTERSIZE = 9;
default_tile.sex#BACKPHOTO_TYPE = LOCAL;
BACKPHOTO_THICK = 30;
default_exp.sex#BACK_TYPE = AUTO;
default_exp.sex#BACK_SIZE = 64;
default_exp.sex#BACK_FILTERSIZE = 3;
default_exp.sex#BACKPHOTO_TYPE = GLOBAL;
config_exp_psfex.ini#SEXTRACTOR_RUNNER.BKG_FROM_HEADER = False;
config_tile_Sx.ini#SEXTRACTOR_RUNNER.BKG_FROM_HEADER = False.
default: auto_megapipe_tiles
options:
auto_megapipe_tiles:
label: AUTO everywhere; MegaPipe mesh and LOCAL photometry on tiles
manual_zero_tiles:
label: Tile background fixed to 0, trusting the stack subtraction
excluded: true
excluded_reason: >-
Part of the stock tile parameter set rejected in favour of the
MegaPipe values (see detection_threshold_policy).
weight_map_usage:
label: Weight map as inverse variance for detection
rationale: >-
MAP_WEIGHT on both passes (SExtractor default NONE): the per-pixel
variance sets the effective SNR and so the detection set.
RESCALE_WEIGHTS and WEIGHT_GAIN keep their SExtractor defaults.
Guinot+22 keeps every non-tabulated parameter at its default, which
would mean no weight map.
Values:
default_tile.sex#WEIGHT_TYPE = MAP_WEIGHT;
default_exp.sex#WEIGHT_TYPE = MAP_WEIGHT;
default_tile.sex#RESCALE_WEIGHTS = Y;
default_exp.sex#RESCALE_WEIGHTS = Y;
default_tile.sex#WEIGHT_GAIN = Y;
default_exp.sex#WEIGHT_GAIN = Y;
config_tile_Sx.ini#SEXTRACTOR_RUNNER.WEIGHT_IMAGE = True;
config_exp_psfex.ini#SEXTRACTOR_RUNNER.WEIGHT_IMAGE = True.
default: map_weight
options:
map_weight:
label: MAP_WEIGHT
no_weight:
label: No weight map (SExtractor default)
insights: [guinot22_sextractor_params]
zero_weight_interpolation:
label: Interpolation across zero-weight pixels
rationale: >-
INTERP_TYPE ALL on both passes (SExtractor default NONE): SExtractor
invents flux across zero-weight pixels, changing detections and
photometry near masked regions. Matching image simulations must use
the same interpolation operator; this is not a calibrated pixel repair.
Values:
default_tile.sex#INTERP_TYPE = ALL;
default_exp.sex#INTERP_TYPE = ALL;
default_tile.sex#INTERP_MAXXLAG = 16;
default_tile.sex#INTERP_MAXYLAG = 16;
default_exp.sex#INTERP_MAXXLAG = 16;
default_exp.sex#INTERP_MAXYLAG = 16.
default: interp_all
options:
interp_all:
label: INTERP_TYPE ALL
no_interpolation:
label: INTERP_TYPE NONE
spurious_detection_cleaning:
label: Cleaning of spurious detections
rationale: >-
CLEAN on both passes deletes detections
consistent with being wings of a brighter neighbour, a post-deblend
change to the object list. Keep the same cleaning prescription in
matching image simulations.
Values:
default_tile.sex#CLEAN_PARAM = 1.0;
default_exp.sex#CLEAN_PARAM = 1.0;
default_tile.sex#CLEAN = Y;
default_exp.sex#CLEAN = Y.
default: clean_1
options:
clean_1:
label: CLEAN Y, CLEAN_PARAM 1.0
blend_photometry_mask_type:
label: Neighbour pixels in blend photometry
rationale: >-
MASK_TYPE CORRECT on both passes replaces neighbour pixels by their
mirror across the object centre during photometry, changing blend
fluxes and windowed moments. This SExtractor photometry choice is
separate from ngmix's neighbour-pixel weighting decision.
Values:
default_tile.sex#MASK_TYPE = CORRECT;
default_exp.sex#MASK_TYPE = CORRECT.
default: correct
options:
correct:
label: MASK_TYPE CORRECT
blank:
label: MASK_TYPE BLANK
saturation_level:
label: Saturation level read from each image's header
rationale: >-
Each SExtractor pass takes the image's saturation level from its
SATURATE header card and sets FLAGS bit 4 on objects with saturated
pixels. Neither .sex file sets SATUR_LEVEL, so where the card is
absent SExtractor falls back to its built-in level (50000 ADU per
its documentation). Delivered exposures carry the card (every CCD
of 2114045p: 65535) and split_exp keeps each CCD's header; a sampled
tile (CFIS.186.307) has 9558.7. The PSF-star masks require FLAGS ==
0, so the level can remove bright stars from the PSF sample.
Changing the card or pinning a fixed level requires checking
the resulting bright-star selection.
Values:
default_exp.sex#SATUR_KEY = SATURATE;
default_tile.sex#SATUR_KEY = SATURATE;
MASK:star_selection.FLAGS = "== 0";
MASK:preselect.FLAGS = "== 0";
MASK:flag.FLAGS = "== 0";
default_tile.sex#SATUR_LEVEL = absent;
default_exp.sex#SATUR_LEVEL = absent.
default: header_saturate
options:
header_saturate:
label: SATURATE header card; SExtractor default level where absent
fixed_level:
label: Fixed SATUR_LEVEL set in the .sex files
photometry_parameters:
label: Kron and aperture photometry definitions
rationale: >-
Stock Kron, aperture and flux-fraction settings; no rationale
recorded. On the exposure pass MAG_AUTO is the axis of the
star-selection magnitude windows and FLUX_AUTO is PSFEx's
photometric normalisation, so a different Kron factor moves stars
across those cuts. The reported apertures and flux-fraction
measurements must match the simulated catalogue they are compared
with.
Values:
default_tile.sex#PHOT_AUTOPARAMS = 2.5,3.5;
default_exp.sex#PHOT_AUTOPARAMS = 2.5,3.5;
default_tile.sex#PHOT_APERTURES = 5;
default_exp.sex#PHOT_APERTURES = 5;
default_tile.sex#PHOT_FLUXFRAC = 0.5;
default_exp.sex#PHOT_FLUXFRAC = 0.5;
PHOTFLUX_KEY = FLUX_AUTO.
default: kron_25_35
options:
kron_25_35:
label: Kron 2.5/3.5, aperture 5 px, FLUXFRAC 0.5
detection_source_mode:
label: Single-image, unflagged detection on the r-band tile
rationale: >-
No detection image, no flag image, and the default_noimaflags.param
column list: tiles have no instrument flag image and no detection
coadd exists, so detection sees every tile pixel and the tile
catalogue carries no IMAFLAGS_ISO; final_cat.param, the merge's
exact allow-list, does not request it. Without a detection image
sextractor_runner calls SExtractor in single-image mode, which on
tile 186.307 reproduces the UNIONS catalogue's MAG_AUTO to 0.01 mag
for all but 0.03% of objects. Dual-image mode with the same image
twice is not equivalent: it changes the background, MAG_AUTO and
FLUX_RADIUS of a fifth of the objects (#936).
Values:
SEXTRACTOR_RUNNER.DETECTION_IMAGE = False;
SEXTRACTOR_RUNNER.FLAG_IMAGE = False.
default: sx_nomask_single_image
options:
sx_nomask_single_image:
label: Unflagged single-image r-band detection
insights: [guinot22_stacked_detection]
masked_tile:
label: Detection on a tile masked by rasterised sky masks
description: >-
Not implemented; no tile pixel mask exists (see
masking.pixel_mask_source).
dual_image_coadd:
label: Dual-image mode with a detection coadd
description: Not implemented; no UNIONS detection coadd exists.
epoch_membership_ccd_bounds:
label: Which exposure CCDs an object belongs to (N_EPOCH)
rationale: >-
`all_world2pix(..., 0)` returns 0-based pixels, and the strict test
accepts `33 < x < 2080`. In 1-based FITS coordinates this is x=35
through x=2080 inclusive: it trims DATASEC columns 33 and 34 but
admits its upper endpoint, column 2080. [HARDCODED] The comparisons
are strict in make_post_process; CCD_SIZE sets only the bounds. A
WCS inversion failure skips that CCD, lowering N_EPOCH, which caps
how many exposures enter each galaxy's multi-epoch fit.
Values:
SEXTRACTOR_RUNNER.CCD_SIZE = 33,2080,1,4612;
SEXTRACTOR_RUNNER.MAKE_POST_PROCESS = True.
default: trimmed_bounds_33_2080
options:
trimmed_bounds_33_2080:
label: "x in (33,2080), y in (1,4612), strict"
inclusive_bounds:
label: Same bounds, inclusive
description: Not implemented; make_post_process uses strict comparisons.
prior_insights:
guinot22_sextractor_params:
claim: >-
The published tile detection uses DETECT_THRESH 1.5, DETECT_MINAREA
10, the default 3x3 filter and DEBLEND_MINCONT 0.001, with every
other SExtractor parameter at its default.
created_at: "2022-04-01T00:00:00Z"
evidence:
- id: ev_guinot22_table2
doi: "10.48550/arXiv.2204.04798"
quote:
exact: 'Table 2. SExtractor parametrisation. All other parameters are kept to their default values.'
location: { page: 5 }
- id: ev_guinot22_mincont
doi: "10.48550/arXiv.2204.04798"
quote:
exact: 'DEBLEND_MINCONT 0.001'
location: { page: 5 }
- id: ev_guinot22_minarea
doi: "10.48550/arXiv.2204.04798"
quote:
exact: 'DETECT_MINAREA 10'
location: { page: 5 }
guinot22_cfis_seeing:
claim: >-
CFIS r-band data have an average seeing of 0.65 arcsec.
created_at: "2022-04-01T00:00:00Z"
evidence:
- id: ev_guinot22_seeing
doi: "10.48550/arXiv.2204.04798"
quote:
exact: 'is taking r-band data with an average seeing of 0.65 arcsec'
location: { page: 1 }
guinot22_stacked_detection:
claim: >-
Source extraction in the published analysis is performed on the
stacked tile images, for signal-to-noise and because artefacts are
suppressed relative to single exposures.
created_at: "2022-04-01T00:00:00Z"
evidence:
- id: ev_guinot22_stacked_detection
doi: "10.48550/arXiv.2204.04798"
quote:
exact: 'We do the extraction on stacked images which provide a better signal-to-noise ratio, and most artifacts have a reduced amplitude with respect to single exposures'
location: { page: 5 }
# ═════════════════════════════════════════════════════════════════════════
preparation:
description: >-
How exposures, astrometry, epoch lists and stamps are prepared before
anything is measured.
inputs:
- id: exposure_files
type: data
source: delivered CFIS exposure triplets (image/weight/flag MEF) + tile stacks
outputs:
- id: epoch_stamps
type: data
format: sqlite
description: Per-object multi-epoch vignets + per-CCD WCS log feeding ngmix.
inputs: [exposure_files]
decisions:
[astrometric_solution_source, ccd_split_extent,
epoch_provenance_from_tile_history, object_position_columns,
stamp_positioning_and_padding]
decisions:
astrometric_solution_source:
label: Astrometry taken verbatim from delivered per-CCD headers
rationale: >-
split_exp builds WCS(header) from each delivered CCD header, and
merge_headers stores these per-tile. Every committed world-to-pixel
step on exposures uses that solution: epoch membership,
multi-epoch stamp placement and OFFSET, tile-side PSF interpolation
positions, and the per-epoch ngmix Jacobian. [HARDCODED] No
astrometric re-derivation or refinement exists. A re-fit would shift
stamp centres and Jacobians and could change epoch membership.
default: delivered_headers
options:
delivered_headers:
label: WCS(header) verbatim, stored at split time
insights: [guinot22_gaia_astrometry]
astrometric_refit:
label: Joint astrometric re-solution
description: Not implemented.
ccd_split_extent:
label: All 40 MegaCam HDUs split and carried as candidate epochs
rationale: >-
Any HDU count other than N_HDU raises; every CCD is a candidate
epoch wherever the WCS lands it.
Values:
SPLIT_EXP_RUNNER.N_HDU = 40.
default: all_40_hdus
options:
all_40_hdus:
label: 40 HDUs, hard-fail on any other count
insights: [guinot22_forty_chips]
exclude_ccd_subset:
label: Exclude a subset of CCDs as epochs
description: Not implemented.
epoch_provenance_from_tile_history:
label: Epoch sets parsed from tile FITS HISTORY cards
rationale: >-
The tile's primary-header HISTORY cards are its exposure list, and
two readers parse the same cards. find_exposures takes the file name
in column COLNUM, strips the extension and deduplicates. EXP_PREFIX
is blank, so 2243881p keeps its p. This list decides which exposures
are retrieved, split and merged into the tile's WCS log.
make_post_process re-parses the HISTORY copied into the catalogue
(the digits before an optional p) and builds the EPOCH HDUs and
N_EPOCH that the stamps and ngmix use. It raises if a HISTORY
exposure is missing from the WCS log. A tile whose header or HISTORY
cannot be read fails; it never gets an empty exposure list.
Values:
FIND_EXPOSURES_RUNNER.COLNUM = 3.
default: history_parse
options:
history_parse:
label: HISTORY column 3, no prefix stripped, deduplicated
object_position_columns:
label: Windowed centroids (XWIN/YWIN) define every position
rationale: >-
PSF interpolation sites, tile and multi-epoch stamp centres, epoch
membership and the catalogue position all use the tile SExtractor
run's windowed centroid, in data and image simulations alike: in pixels
for tile stamps and exposure-side PSF validation, in world
coordinates for tile-side PSF interpolation and multi-epoch stamps.
Windowed, isophotal and model centroids differ systematically for
blends and asymmetric galaxies, and the centroid feeds the position
seed and the centroid prior.
Values:
VIGNETMAKER_RUNNER_RUN_1.POSITION_PARAMS = XWIN_IMAGE,YWIN_IMAGE;
VIGNETMAKER_RUNNER_RUN_1.COORD = PIX;
config_tile_PiViVi_psfex.ini#PSFEX_INTERP_RUNNER.POSITION_PARAMS =
XWIN_WORLD,YWIN_WORLD;
VIGNETMAKER_RUNNER_RUN_2.POSITION_PARAMS = XWIN_WORLD,YWIN_WORLD;
VIGNETMAKER_RUNNER_RUN_2.COORD = SPHE;
config_exp_psfex.ini#PSFEX_INTERP_RUNNER.POSITION_PARAMS =
XWIN_IMAGE,YWIN_IMAGE.
default: xwin_windowed
options:
xwin_windowed:
label: Windowed centroids everywhere
isophotal_barycentre:
label: Isophotal barycentre (X_IMAGE/Y_IMAGE)
excluded: true
excluded_reason: >-
Noisier than the windowed centroid and pulled by asymmetric or
deblend-clipped footprints; on the DR6 image of tile 186.307
it sits 0.16 px (median) and 1.6 px (p99) from it for
20 < MAG_AUTO < 24.5, and the image simulations measure the
windowed one.
stamp_positioning_and_padding:
label: Nearest-pixel stamp extraction with zero padding
rationale: >-
[HARDCODED] stamps are cut around the pixel nearest the object's
position, with no sub-pixel interpolation; the sub-pixel remainder
is stored as the stamp's OFFSET, which ngmix uses as the Jacobian
origin (shape_measurement.centroid_source), so extraction and
centroid prior share one rounding. Multi-epoch stamps map the tile
world coordinate through the stored per-CCD WCS. Stamps overrunning
an image edge are kept, zero-filled outside the image; a stamp
centre that rounds outside the image raises and fails the vignet
run for the whole tile.
default: round_and_zero_pad
options:
round_and_zero_pad:
label: Nearest-pixel extraction, zero padding, no edge rejection
prior_insights:
guinot22_gaia_astrometry:
claim: >-
The astrometric solution the analysis relies on is the upstream
MegaPipe/Gaia DR2 calibration, accurate to within 20 mas; no
astrometric re-fit inside the pipeline is described.
created_at: "2022-04-01T00:00:00Z"
evidence:
- id: ev_guinot22_astrometry
doi: "10.48550/arXiv.2204.04798"
quote:
exact: 'An astrometric calibration within 20 mas was achieved using the Gaia DR2 observations'
location: { page: 2 }
guinot22_forty_chips:
claim: >-
Star selection and PSF modelling are carried out independently on
each of the 40 MegaCam chips, with no chip excluded.
created_at: "2022-04-01T00:00:00Z"
evidence:
- id: ev_guinot22_forty_chips
doi: "10.48550/arXiv.2204.04798"
quote:
exact: 'is performed independently on each of the 40 chips that constitute the MegaCAM'
location: { page: 3 }
# ═════════════════════════════════════════════════════════════════════════
star_selection_psf:
description: >-
Which objects constrain the PSF, the PSF model itself, and which CCD
models are good enough to use.
inputs:
- id: exposure_sexcat
type: data
source: per-CCD exposure SExtractor catalogues (default_exp.sex run)
outputs:
- id: psf_model
type: data
format: psf
description: >-
Per-CCD PSF models and the PSFs interpolated at object positions,
with HSM shape diagnostics.
inputs: [exposure_sexcat]
decisions:
[star_selection_box, psf_train_validation_split,
psfex_candidate_vetting, psf_modelling_software,
psf_model_complexity, psf_acceptance_thresholds]
decisions:
star_selection_box:
label: Stellar-locus selection, magnitude window and FWHM window scaled to the locus
rationale: >-
Stars are objects with FLAGS == 0 and IMAFLAGS_ISO == 0 in a
MAG_AUTO window whose FWHM_IMAGE lies within 3 locus widths of the
stellar-locus peak of a looser, size-limited preselection
(FWHM_WORLD 0.3-1.5 arcsec, angular bounds from each exposure's
WCS). mode() is the peak of a Gaussian kernel density
estimate of the preselection FWHM, and locus_width() is that
peak's full width at half maximum as a Gaussian sigma, with the
kernel removed in quadrature. The box scales with the locus
because the locus width varies from 0.06 to 0.26 px per CCD with
seeing and focal-plane position, so a fixed box cuts broad
corner loci (2114045p CCD 35 keeps 39 of 63 bright locus stars at
+-0.2 px, 63 at 3 sigma) and is loose on sharp ones. k = 3 is
where widening stops adding mostly stars: against the
size-independent MU_MAX - MAG_AUTO star sequence (18-20.5 mag, 79
CCDs), objects added between 2.5 and 3 sigma are 59% (0.53 arcsec
seeing) and 71% (0.69 arcsec) stars, and between 3 and 3.5 sigma
28% and 65%. At k = 3, 98.9% and 89.1% of locus stars are kept
with 2.7% and 5.6% non-stars, against 95.6%, 80.9%, 1.7% and 3.0%
for the fixed +-0.2 px box. The [HARDCODED] 0.1 px kernel
bandwidth is close to the median locus width (0.08 px at 0.53
arcsec, 0.10 px at 0.69 arcsec) and is not tied to each CCD's
width: a wider kernel on a broad locus pulls
the peak and the width into the galaxies, and a tied bandwidth
moved box edges by up to 4.5 px when the preselection bounds
shifted slightly on 0.69 arcsec CCDs. Measured widths make the box
edges noisier than a fixed half-width (bootstrap 0.03-0.05 px,
against 0.01 px), still below the locus width. Below 20 objects the centre is the median
and the width the normalised MAD; with none both are -1, which
selects nothing. Where galaxies capture the peak (2254826p CCD
35), no box recovers the stars; the logged locus width flags it
(0.32 px, against 0.06-0.26 px elsewhere).
PSFEx's own selection is off; see psfex_candidate_vetting for what
PSFEx may still apply.
Values:
MASK:star_selection.FLAGS = "== 0";
MASK:preselect.FLAGS = "== 0";
MASK:star_selection.IMAFLAGS_ISO = "== 0";
MASK:preselect.IMAFLAGS_ISO = "== 0";
MASK:star_selection.MAG_AUTO = ["> 18.", "< 22."];
MASK:star_selection.FWHM_IMAGE = ["<= mode(FWHM_IMAGE{preselect})
+ 3 * locus_width(FWHM_IMAGE{preselect})", ">=
mode(FWHM_IMAGE{preselect}) - 3 * locus_width(FWHM_IMAGE{preselect})"];
MASK:preselect.MAG_AUTO = ["> 0", "< 21"];
MASK:preselect.FWHM_WORLD = ["> 0.3 / 3600", "< 1.5 / 3600"];
PLOT:fwhm_field.SCATTER = "FWHM_WORLD{star_selection}*3600";
LOCUS_BANDWIDTH = 0.1;
LOCUS_WIDTH_FLOOR = 0.02;
LOCUS_MIN_SIZE = 20;
SAMPLE_AUTOSELECT = N.
default: locus_scaled_box
options:
locus_scaled_box:
label: Box +-3 locus widths about the locus peak, mag 18-22
mode_centred_box:
label: Fixed box +-0.2 px (0.04 arcsec) about the FWHM mode, mag 18-22
insights: [guinot22_star_box]
size_mag_locus_fit:
label: Fitted size-magnitude stellar locus
description: Not implemented.
psfex_autoselect:
label: PSFEx SAMPLE_AUTOSELECT vetting on top
insights: [guinot22_psfex_preselection_off]
excluded: true
excluded_reason: >-
Disabled because the pipeline does its own star selection
(Guinot+22); PSFEx's other SAMPLE_* cuts still apply
(psfex_candidate_vetting).
psf_train_validation_split:
label: Seeded 80/20 star split, model fit vs held-out validation
rationale: >-
The 80% sample fits the PSFEx model and feeds the tile multi-epoch
interpolation; the 20% sample is the independent residual
diagnostic (psfex_interp VALIDATION mode). The split trades
training stars per CCD, which interacts with the acceptance gate,
against an independent residual test. The permutation is seeded
from the digits of the unit's file number, so a CCD gets the same
split on every run.
Values:
RAND_SPLIT:star_split.RATIO = 20;
PSFEX_RUNNER.FILE_PATTERN = star_split_ratio_80;
PSFEX_INTERP_RUNNER.FILE_PATTERN =
star_split_ratio_80,star_split_ratio_20,psfex_cat;
PSFEX_INTERP_RUNNER.ME_DOT_PSF_PATTERN = star_split_ratio_80.
default: split_80_20_seeded
options:
split_80_20_seeded:
label: 80% train / 20% validation, seeded from the file number
insights: [guinot22_star_split]
split_80_20_unseeded:
label: Same split from an unseeded random draw
excluded: true
excluded_reason: >-
Makes the PSF star sample, and every shape downstream of it,
irreproducible run-to-run.
no_holdout:
label: All stars in the model, no held-out diagnostic
excluded: true