ePSF Brightness Dependence
SynDiff forward ePSF/WCS · updated 2026-10-13 (§12: decision revised — effect reported, term in an appendix)

Does the ePSF change with magnitude?

Residual analysis of the newest and best ePSF/WCS fits on F1 (S24 C2K2) and F2 (S20 C3K3), fold 0, and a plan for modelling what they show.

Current answer (2026-10-13, §12): yes. Excess PSF variance grows linearly with peak charge per read, $(1.33\pm0.06)\times10^{-3}$ px² per $10^4$ e⁻ (true $\Delta\Sigma$ units; earlier sections quote estimator units, ×0.59). It is a brighter–fatter-type effect, seen in all 5 fields and 9/9 detector cells. Paper 1 reports it; the linear term we tried captures about half and goes to Appendix D, so the adopted model has no term. The text below is the 10-07 analysis.

Yes. The fits use one ePSF for every star (bright_width: none). Their residuals show that the real PSF of stars brighter than T≈10 is broader than the model, with a central-pixel deficit and an excess in the first ring at r ≈ 1.2 px. F1 and F2 show the same pattern. The bright-minus-faint width difference is $\Delta c \approx +1.0\times10^{-3}$ px² (held-out stars: 0.65–0.95).

The width rises with peak charge per read. Expressed as the existing bright_width law, the implied coefficient is $b = 1.24\pm0.18$ (F1) and $0.50\pm0.09$ (F2), in units of $10^{-3}$ px² per $10^4$ e⁻. The 09-30 measurement, $b = 0.80$, lies between them. About $0.4\times10^{-3}$ px² of the earlier "faint stars are sharper" signal was light from unmodelled Gaia neighbours, not PSF.

Fits examined

All fits come from dev_runs/training_fixes_20261005, fold 0, under the 10-04 A3 recipe run to a smoothed-stop plateau. "Best" is the arm with the lowest paired held-out core χ² on both fields.

ArmWhat it addspaired held-out χ² vs base (F1 / F2)bright gap T8–9 (F1 / F2)
v6 base10-04 recipe from the training-only start1 / 15.85 / 22.8
v8 nbr onlyomitted Gaia neighbours T ≤ 17 rendered as nuisance stars0.85 / 0.775.5 / 15.2
v8 bestneighbours + weight cap T10.5 (D) + anchors train the shape (#3)0.56 / 0.540.92 / 1.00

"Bright gap" is the held-out median χ² divided by the in-fold median χ² at T8–9. Values far above 1 mean the ePSF memorised its training stars.

What the recipe labels mean

Every star in the scene has a role. Contributors (T8–11, 1,655 stars in F1 fold 0) train the ePSF shape: the loss gradient flows into the ePSF pixels through their stamps. Anchors (T11–13, 9,822 stars) are fitted for flux and position and pin the WCS. By default, the gradient of their stamps with respect to the ePSF is stopped, so they do not shape it. Nuisance stars (blended or rejected stars, and the added neighbours) have their template held fixed and only their flux solved. The arms change these rules:

LabelFlagWhat it does
D, cap T10.5--star-weight-cap-tmag 10.5Caps each star's total weight in the loss at that of a T = 10.5 star (formula below). Without it, the few brightest stars dominate the ePSF and are memorised; the bright gap is 5.9 (F1) and 22.8 (F2).
#3, "T11–13 train shape"--anchors-train-epsfOption 3 of the training-fixes plan. Relabels every anchor as a contributor at scene load, so the 9,822 faint T11–13 stars also train the ePSF shape (about 7× more training stars). Their pixels then constrain the core and centroid, which the bright stars alone pinned poorly.
nbr17, "neighbours"augmented scene nbr/F*_fold0_T17Adds the Gaia neighbours with T ≤ 17 that the PS1 removal ledger recorded but the scene had omitted (F1: 2,969). They enter as nuisance stars, with a weak prior toward their catalogue flux, so their light is no longer attributed to the target's PSF.
$$w_s=\min\!\left(1,\;\left(\frac{f_{\rm cap}}{f_s}\right)^{2}\right),\qquad \sigma_{\rm eff}^{-2}(p)=w_s\,\sigma^{-2}(p)\ \ \text{for every pixel } p \text{ of star } s$$

$w_s$: weight factor of star $s$ (dimensionless). $f_s$: its flux, in e⁻/s. $f_{\rm cap}$: flux of a T = 10.5 star (15,000 e⁻/s × 10^{−0.2} ≈ 9,460 e⁻/s). $\sigma^{-2}(p)$: the pixel's inverse variance from the NOISE plane. A star's χ² contribution grows roughly as $f^2$, so this caps each bright star's total pull at that of a T10.5 star without changing the relative weighting of pixels inside the star. The paired held-out χ² gains in the arms table come from adding these three changes together: D alone 0.90 / 0.83, #3 alone 0.91 / 0.87, neighbours alone 0.85 / 0.77, all three 0.56 / 0.54 (F1 / F2).

Status. On 2026-10-07 the user finalised v8 nbr17_D105_E (neighbours + D + #3, on the 10-04 recipe with the smoothed stop rule) as the Paper 1 recipe (forward_model/recipes/paper1_final.yaml, main 677a6c5e). The fits on this page are therefore fold-0 fits of the adopted recipe. The bright-star residual they leave is the open modelling item.

Method

For each star, the evaluation writes the residual divided by the fitted flux on a 33×33 grid at 0.25 px (±4 px). I pool stars over the whole CCD, bin them by catalogue Tmag (0.5 mag bins) or by peak charge, and stack each bin with a 5-MAD clipped mean. I then fit the stack with the derivatives of the bin's median model image:

$$R(\mathbf r)\;\approx\;a\,P+b_x\,\partial_xP+b_y\,\partial_yP+c_{xx}\,\partial_x^2P+c_{yy}\,\partial_y^2P+c_{xy}\,\partial_x\partial_yP+d,\qquad r<3.5\ \text{px}$$

$R$: stacked (data − model)/flux, in px⁻². $P$: median model/flux image of the bin, in px⁻². $a$: flux scale. $b_x, b_y$: centroid shifts, in px. $c_{xx}, c_{yy}$: width terms, in px², with negative meaning the data are sharper than the model. A Gaussian blur of variance $\Delta\Sigma$ per axis gives $c=\Delta\Sigma/2$. $d$: constant pedestal. All quantities are fitted by least squares. I report $c=(c_{xx}+c_{yy})/2$ in $10^{-3}$ px², with ±1σ from bootstrap resampling of stars. The primary sample is mid-colour stars (BP−RP 0.75–1.25), so the change of colour mix with magnitude cannot imitate a trend. Code: diagnostics/residual_grid.width_terms, called from magdep_v8.py.

Reading the zero point. Because the ePSF is shared by all stars, it sits at a weighted compromise between bright and faint stars. The absolute level of $c$ therefore says where the training weight went. Only the change of $c$ with brightness is evidence of a magnitude-dependent PSF.

1 · Width against magnitude

Residual width vs Tmag for base, neighbours-only and best v8 fits, F1 and F2, held-out and all stars
Residual width $c$ against Tmag for mid-colour stars. Top row: held-out stars. Bottom row: all stars. Grey band: stars down-weighted by the T10.5 cap in the best arm. In the best arm (red), the faint end T10.5–13 is nearly flat and close to zero, and $c$ rises only at T < 10. In the base and neighbours-only arms, the faint end sits about 1e-3 px² lower, because there the ePSF is pulled toward the heavily weighted bright stars.
Fit (mid colour, all stars)T8–9.5T10.5–11.5T12–13Δ bright − faintheld-out Δ
F1 base+0.20−0.77−1.401.61.9
F1 nbr only+0.20−0.79−1.041.251.65
F1 best v8+0.76−0.10−0.341.10.95
F2 base+0.10−0.67−1.211.31.6
F2 nbr only+0.10−0.61−0.820.91.05
F2 best v8+0.70−0.12−0.250.950.65

Units are $10^{-3}$ px². Statistical errors are about ±0.2–0.3 for the bright bins (26–120 stars per 0.5 mag) and ±0.06–0.1 for the faint bins (600–2,600 stars). The held-out Δ compares T8.5–10 with T12–13; the held-out sample has only 10–18 stars per bright bin.

2 · The images the widths are measured on

Stacked residual images per Tmag bin, all stars
Stacked residual/flux for all mid-colour stars, pooled over the CCD, on one colour scale (±12×10⁻⁴ px⁻²). Each panel lists n and $c$. In the best rows (3rd and 6th) the faint panels are almost empty. T8–9.5 shows a deep blue core with a red ring, so the data are broader than the model. In the base rows, the faint stars show the opposite: a red core spike with a blue ring, so the data are sharper.
Stacked residual images per Tmag bin, held-out stars
The same stacks for held-out stars only, which never trained the ePSF. The bright bins are noisy (10–18 stars), but the core deficit at T8.5–10 is visible in all three F1 rows and in the F2 best row. The dotted vertical streaks in the F2 T9.5–10 and T10.5–11 panels come from a bad column crossing a few stamps, not from the PSF.
Azimuthal profiles of the stacks, all stars
Azimuthal profiles of the stacks, held-out stars
Azimuthal means of the stacks. Top: all stars. Bottom: held-out stars. In the best fits, the brightest bins have a central deficit of −15 to −30×10⁻⁴ of the flux per px² and a positive ring at r ≈ 1–1.6 px. Light is moved out of the brightest pixel into its neighbours, the brighter-fatter signature. Beyond 2 px the residual is flat.

2b · Does the width fit describe the stacks?

The width numbers come from fitting each stack with seven images: the PSF, its two first derivatives (shifts), its three second derivatives (widths) and a constant. Below, each stack appears with its fit, the fit residual (R − fit), and the width part of the fit alone, all on the same colour scale. This shows how much of the stacked residual the width term actually describes.

Stack, basis fit, stack minus fit, and width part for the best v8 fits
All mid-colour stars, best v8 fits, 1-mag bins. Rows per field: stack R, the 7-term basis fit, R − fit, and the width part only ($c_{xx}\partial_x^2P+c_{yy}\partial_y^2P+c_{xy}\partial_x\partial_yP$). Labels: χ² per pixel of the raw stack, $c$ of the fit, and χ²/dof after the fit with the fraction of stack power the fit explains (r < 3.5 px). The noise is the clipped-mean standard error, 1.4826·MAD/√n per pixel, which ignores correlations between neighbouring 0.25 px samples.
Azimuthal profiles of stack, fit, width part and residual
Azimuthal profiles of the same images. Black: stack. Red dashed: basis fit. Blue dotted: width part. Green: R − fit. Grey band: ±1σ noise of the azimuthal mean.
Bin (all stars)F1 cF1 power explainedF1 χ²/pix raw → after fitF2 cF2 power explainedF2 χ² raw → fit
T8–9+1.3346%11.9 → 17.7+1.1953%18.3 → 22.1
T9–10+0.7144%10.5 → 12.4+0.2620%12.0 → 10.4
T10–11−0.049%8.7 → 6.9−0.0330%11.3 → 10.9
T11–12−0.0834%21.7 → 10.9−0.3540%13.0 → 11.6
T12–13−0.3467%58.4 → 16.0−0.2433%27.3 → 19.7

What this shows.

  • Bright stars (T8–10): the sign and the ring are right, the core is not. The width part reproduces the broad shape: a deficit inside r ≈ 0.8 px and an excess at r ≈ 1–1.6 px. But the real central deficit is about twice as deep and much narrower: −14 to −17×10⁻⁴ in the stack against −6 to −8 in the fit. What is left over (green) is a narrow hole confined to the central pixel plus a ring at r ≈ 1 px, at 3–5σ. A blur of the PSF ($\nabla^2P$) is smooth on the scale of the PSF. Charge moving from the brightest pixel into its four neighbours, which is what the 09-30 study saw, is a pixel-scale feature. The stack prefers the second description.
  • Faint stars (T11–13): the width term catches the main part, a central excess, so the data are slightly sharper. What is left is low-level non-radial structure: small dipoles and pixel-grid speckle. That is ePSF shape error at the 1–3×10⁻⁴ level that no width term can describe.
  • T10–11 carries almost no signal, so the fit explains little there. That is expected where the curve crosses zero.
  • Unweighted fit. χ² can rise after the fit (bright bins), because the fit minimises unweighted squared residuals while χ² weights pixels by their noise. The bright core pixels are both the noisiest and the worst fitted.

Consequences. $c$ is the projection of the residual onto a smooth blur. It measures the sign, the onset and the second-moment size reliably, but it underestimates the central-pixel loss of bright stars by about 2×. The bright_width term, which is exactly such a blur, should therefore remove the ring and about half of the core deficit, but not all of it. This adds an arm to the plan (§5): a pixel-boundary brighter-fatter operator that moves charge from a pixel to its four neighbours in proportion to its charge. 09-30 found that operator degenerate with the blur in moments; the stack images above are where the two differ, so the test should be judged on these images and on the central-pixel residual, not on $c$ alone.

2c · §2b for all five Paper-1 fields on the final run-3 fits, and the dipole terms (2026-10-09)

The user saw that the width fit describes F1 very well, while on F2 the R − fit residual shows dipoles in the fainter bins. They asked for the §2b figure for every Paper-1 field and for the shift terms. The §2b panels above are the 10-07 v8 fits on fold 0 only, with no brightness-width term (bright_width: none). They remain the reference. The figures below use the run-3 final fits (the Paper-1 recipe), with held-out stars from all K = 5 folds, which is about 5× more stars per bin. Each field is shown twice. LAW OFF is the frozen fit with no brightness term. LAW ON adds the run-3 held-out-chosen charge law $\Delta\Sigma=a_0+b\,q/10^4$, post hoc (§9). The method is the same as §2b: mid-colour stars (0.75 ≤ colour < 1.25), 1-mag bins, 5-MAD-clipped stack $R$ of (data − model)/flux, least-squares fit of the 7-term basis over r < 3.5 px.

$$R \approx a\,P + b_x\,\partial_xP + b_y\,\partial_yP + c_{xx}\,\partial_x^2P + c_{yy}\,\partial_y^2P + c_{xy}\,\partial_x\partial_yP + k$$

$P$: the bin's median model/flux image. $a$: flux term. $b_x,b_y$: shift terms (px); the data − model centroid offset is $\delta=-b$, quoted in mpx (10⁻³ px). $c_{xx},c_{yy},c_{xy}$: width terms (px²); $c=(c_{xx}+c_{yy})/2$, negative means the data are sharper than the model. $k$: constant. Errors are 30 bootstrap resamples of stars. Axis frame: each stamp (residual and model) is rotated so that +x′ points from the star toward the optical axis (the fit's chroma_axis), then stacked. $\delta_{\rm rad}$ is positive toward the axis; $\delta_{\rm tan}$ is 90° counter-clockwise from it.

F1 law off vs law on
F1, run 3. Rows 1–4: LAW OFF; rows 5–8: LAW ON ($b$ = 1.0e-3, $a_0$ = −0.8e-3). Each block shows the stack $R$, the 7-term fit, $R$ − fit and the width part, on a shared ±12e-4 scale. As in §2b the width part captures the T8–10 central deficit; the law removes about half of it (width $c$ +1.26 → +0.73 at T8–9). $R$ − fit carries no coherent dipole in any bin.
F2 law off vs law on
F2, run 3. Rows 1–4 LAW OFF, rows 5–8 LAW ON ($b$ = 1.0e-3, $a_0$ = −0.8e-3). The only strong dipole is at T8–9: red above, blue below. The fit absorbs it as $\delta_y$ = +2.6 ± 1.0 mpx, which points toward F2's optical axis (+y). With 5× the stars of the 10-07 panels, the faint bins (T10–13) show no dipole in $R$ − fit; offsets are ≤ 0.5 mpx. What remains is a ring/cross pattern around the core, a core/wing shape the basis cannot express. The faint F2 dipoles in the 10-07 figure were sampling noise of fold 0 (n = 81–676).
S22 law off vs law on
S22, run 3. Rows 1–4 LAW OFF, rows 5–8 LAW ON ($b$ = 1.5e-3, $a_0$ = −1.2e-3). The width part matches the bright central deficit (c +1.37 → +0.27 at T8–9). Shift terms are ≤ 0.7 mpx in every bin, and $R$ − fit shows a faint cross pattern but no dipole.
C1 law off vs law on
C1, run 3. Rows 1–4 LAW OFF, rows 5–8 LAW ON ($b$ = 1.5e-3, $a_0$ = −1.2e-3). This field has the largest bright deficit (c +2.34 at T8–9, of which the law removes about two thirds). At T12–13 the stack is asymmetric: a blue arc on one side of the core and red on the other. The fit takes this as δ = (−0.6, −0.5) mpx; in the axis frame it is tangential (+0.86 ± 0.13 mpx).
C4 law off vs law on
C4, run 3. Rows 1–4 LAW OFF, rows 5–8 LAW ON ($b$ = 1.0e-3, $a_0$ = −1.2e-3). This is the clearest faint-bin dipole. At T10–13 the core residual is displaced toward lower right and a red arc sits upper left at r ≈ 2 px. The fit absorbs only the core part (≈ 0.4–0.5 mpx), so $R$ − fit keeps the arc (χ²/dof 31–38, the highest of the five fields). A shift cannot move the core and the wing in opposite directions, so this is a coma-like shape asymmetry, not a centroid offset. At T8–9 a separate shift of δ = (−1.2, +2.4) mpx points toward C4's axis (−x, +y).
radial profiles law off/on
Azimuthal profiles, mid colour, held out; solid = LAW OFF, dashed = LAW ON. Black: stack. Green: $R$ − fit. Blue dotted: width part (law off). The law lifts the T8–9 central deficit on every field, and the faint-star central excess (T11–13) shrinks under the law's offset.
fieldTmagnwidth $c$ [1e-3 px²] off / onpower explained off / onχ²/pix → χ²/dof after fit, off / onδx [mpx]δy [mpx]
F18–971+1.26 / +0.7339 / 26%17.1 → 23.1 / 16.7 → 16.7-1.5±0.9+0.1±0.8
F19–10196+0.90 / +0.7649 / 43%9.6 → 9.9 / 9.3 → 9.4+0.1±0.5+0.4±0.4
F110–11502-0.09 / +0.0819 / 12%8.2 → 6.1 / 7.3 → 6.1-0.4±0.3+0.1±0.2
F111–121847-0.00 / +0.3131 / 41%15.3 → 10.5 / 14.0 → 10.4-0.3±0.2+0.2±0.1
F112–134189-0.34 / +0.0353 / 28%28.8 → 16.3 / 21.4 → 15.9-0.4±0.1-0.0±0.1
F28–959+1.01 / +0.2349 / 34%19.6 → 24.2 / 21.6 → 21.1+0.3±0.6+2.6±1.0
F29–10135+0.24 / +0.0918 / 20%15.2 → 9.2 / 15.9 → 9.3+0.3±0.3+0.3±0.5
F210–11401-0.04 / +0.0931 / 27%10.4 → 9.4 / 9.9 → 9.3+0.4±0.3+0.5±0.3
F211–121476-0.39 / -0.1144 / 17%10.7 → 11.4 / 10.1 → 11.7+0.3±0.1-0.1±0.1
F212–133402-0.30 / +0.0628 / 12%18.9 → 20.5 / 21.6 → 20.3+0.2±0.1-0.2±0.1
S228–956+1.37 / +0.2749 / 15%18.9 → 17.6 / 21.2 → 15.2+0.1±0.7-0.3±0.9
S229–10164+0.70 / +0.4145 / 35%15.8 → 13.4 / 17.2 → 13.0+0.5±0.4+0.6±0.5
S2210–11456+0.09 / +0.3022 / 25%16.2 → 7.8 / 14.4 → 7.5+0.2±0.2+0.0±0.2
S2211–121558-0.41 / +0.0253 / 20%18.5 → 13.7 / 15.2 → 13.9+0.2±0.1-0.0±0.2
S2212–133304-0.39 / +0.1434 / 17%17.8 → 21.9 / 25.9 → 21.9+0.2±0.1+0.0±0.1
C18–966+2.34 / +0.8764 / 32%12.0 → 15.6 / 12.2 → 12.2+1.6±1.6-0.9±0.8
C19–10189+0.65 / +0.2527 / 20%14.3 → 14.6 / 15.3 → 12.7-1.0±0.7+0.8±0.7
C110–11456-0.29 / -0.0942 / 28%10.5 → 6.3 / 9.1 → 6.6-0.3±0.6+0.6±0.3
C111–121550-0.45 / -0.0249 / 15%18.3 → 12.6 / 13.9 → 13.0-0.4±0.2-0.2±0.2
C112–133389-0.20 / +0.3439 / 42%23.6 → 21.6 / 30.0 → 22.0-0.6±0.1-0.5±0.2
C48–956+1.16 / +0.4951 / 42%20.2 → 13.9 / 22.3 → 18.0-1.2±0.5+2.4±1.0
C49–10179+0.32 / +0.2945 / 43%13.1 → 9.3 / 13.0 → 9.2-0.4±0.4+1.1±0.4
C410–11482-0.35 / -0.0762 / 38%31.7 → 7.6 / 26.8 → 7.3+0.3±0.3-0.1±0.3
C411–122294-0.48 / -0.0268 / 35%54.1 → 15.8 / 37.2 → 16.3+0.4±0.1-0.4±0.1
C412–135617-0.28 / +0.2542 / 31%47.7 → 37.3 / 46.0 → 38.0+0.4±0.1-0.5±0.1

Table: width $c$, fraction of stack power the 7-term fit explains, and χ² per pixel of the stack and per degree of freedom after the fit (noise from the stars' MAD), for LAW OFF / LAW ON. Shift terms (LAW OFF) are data − model centroid offsets; they are the same with the law on, because the law is symmetric.

dipole summary vs Tmag
Data − model centroid offset against Tmag per field, law off, held out, ±1σ. Panels 1–2: detector-frame stack shifts. Panels 3–4: axis-frame stack shifts, with the inverse-variance pool in black squares. Panel 5: per-stamp radial offset (median per 0.5 mag; the per-stamp fit is core-weighted). Bright stars sit toward the optical axis: pooled +0.89 ± 0.50 (T8–9), +0.79 ± 0.28 (T9–10; the five fields agree, χ² 1.9/4), +0.25 ± 0.16 (T10–11), and 0.04 / −0.15 at T11–13. The per-stamp fits give +1.5–2 mpx at T8–9 on F1, F2 and C4. In the faint bins the pooled offset is near zero but the fields disagree (χ² 25–67 for 4 dof): C4 radial −0.7 ± 0.1, C1 tangential +0.86 ± 0.13, F1 radial +0.4 ± 0.2.
axis-frame stacks
axis-frame odd part
Top: law-off mid-colour stacks rotated into the optical-axis frame (the arrow points toward the axis), on a shared ±8e-4 scale. Bottom: the odd (dipole) part against radius, excluding the r = 0 pixel. $A_1=\langle R\cos\theta\rangle$ is the radial part and $B_1=\langle R\sin\theta\rangle$ the tangential part. The red dashed curve is the same quantity for the fitted shift alone. A pure shift keeps one sign. C4 T11–13 changes sign, negative at r ≈ 0.4–1.1 px and positive at 1.4–2.2 px: the core sits away from the axis and the wing toward it, which is coma-like. C1 T12–13 is mostly tangential ($B_1$). Bright bins follow the shift curve within their errors.

Conclusion. (1) The brightness-width term does not create or remove dipoles; the shift terms are the same with LAW ON and LAW OFF. (2) Bright stars (T8–10) carry a small brightness-dependent centroid offset toward the optical axis: ≈ +0.8 mpx in the stacks, +1.5–2 mpx per stamp at T8–9, fading by T10.5. It changes smoothly with brightness and is consistent across fields at T9–10, but is only about 3σ pooled, and C1 at T8–9 disagrees at 2σ. It is the sign expected from the WCS↔ePSF-centroid compromise (faint stars dominate the astrometric solution) or from radially asymmetric charge spreading; these data cannot separate the two. Confidence that it exists: moderate. Size: ≤ 0.002 px, below current astrometric needs. (3) The faint-bin dipoles are not one smooth brightness effect. They are field-specific shape asymmetries of 0.4–0.9 mpx in equivalent shift: coma-like on C4 (core and wing on opposite sides), tangential on C1. Bootstrap errors put them at 6–7σ, so they are not noise. On C1 the per-stamp clean-sample (no neighbours) curve agrees, so it is not neighbour light. On F2 they were small-sample noise of the 10-07 fold-0 panels. Confidence: high that they are real and field-specific, low on cause; the most likely is an odd-order (coma-like) ePSF shape term that the fit's spatial/colour model does not carry on C4. Next step: a held-out test of a coma generator ($r^2\,\partial_rP$-type, radial to the axis) per field, if the user wants it.

3 · Controls

Colour

The median BP−RP of the mid-colour bin drifts from 1.15 (bright) to 0.90 (faint). To rule this out I repeated the measurement in narrow colour slices. Bright (T8–9.5) minus faint (T12.5–13), in $10^{-3}$ px²:

FitBP−RP 0.6–0.850.85–1.051.05–1.35
F1 best v8+1.2+0.9+1.1
F1 nbr only+1.2+1.0+0.9
F2 nbr only+0.75+0.5+0.5
F1 v7 (no neighbours)+1.9+1.8+1.6

The trend is present in every slice. Separately, red stars sit higher overall (+0.4 to +1.0 at all magnitudes), which is a colour residual of the A3 model and a different effect.

Neighbours

Rendering the omitted Gaia neighbours (T ≤ 17) as nuisance stars moves the T12–13 width from −1.48 to −1.02 on F1 and from −1.19 to −0.80 on F2, with no change at the bright end. Without neighbours, the light of fainter companions was attributed to the target star's PSF. That made faint stars look sharper relative to bright ones, which inflated the first-pass number (F1 v7: Δ = 2.0). That number is superseded.

Held-out stars

Held-out stars show the same sign and onset, so this is not memorisation. They cannot measure the slope against peak charge, because the held-out set has no stars above $q\approx1.2\times10^4$ e⁻.

4 · What it scales with: peak charge per read

The 09-30 study (bfwidth_20260929) found that the extra width is isotropic and linear in the charge collected in the brightest pixel during one 2-s read. The same quantity organises these residuals:

$$q_s = t_{\rm read}\,f_s\,\pi_s$$

$q_s$: peak charge of star $s$, in e⁻ per read. $t_{\rm read}=2$ s, the TESS exposure that is co-added into every FFI. $f_s$: fitted flux, in e⁻/s. $\pi_s$: fraction of the star's flux in its brightest pixel, taken as the maximum of the pixel-integrated model/flux raster (about 0.2–0.3 here). T = 10 corresponds to $q\approx 1\times10^4$ e⁻, which is where the width starts to rise.

A linear fit of $c$ against $q$ (log-spaced bins at high $q$) measures the coefficient of the existing bright_width law, because $c = \tfrac12 b\,(q-q_{\rm ref})/10^4$:

Residual width vs peak charge for the best v8 fits
Residual width against peak charge for the best v8 fits (mid colour). Red: all stars. Blue: held-out stars. Solid lines: weighted linear fits. Dashed: the 09-30 law, $b=0.80$, drawn through the same intercept. The highest-$q$ bin (T≈8.3, $q$ = 3–4.4×10⁴) falls back on both fields; only 10–20 stars are in that bin.
Implied $b$ [$10^{-3}$ px² per $10^4$ e⁻]all starsheld-out
F1 best v81.24 ± 0.181.55 ± 0.56
F2 best v80.50 ± 0.090.57 ± 0.70
09-30 independent measurement (7 datasets)0.80 ± 0.10

These are post-hoc estimates from residuals of a fit without the term, so they are not fitted values. The F1–F2 difference (about 3.6σ) could be real, because the CCDs differ (F1 is cam2/CCD2, which earlier showed its own width band) or because exposure times differ. It could also come from the high-$q$ bins, which carry few stars.

5 · How to model it

The physics is already in the code. forward_model/bright_width.py (in the pinned training-fixes tree) adds a per-star isotropic blur proportional to peak charge on top of the shared ePSF and the A3 colour model:

$$P_s(\mathbf r)=P(\mathbf r;\,\mathbf x_s,\text{colour}_s)+\tfrac12\,b\,\frac{q_s-q_{\rm ref}}{10^4}\,\nabla^2P(\mathbf r;\,\mathbf x_s,\text{colour}_s)$$

$P_s$: rendered unit-flux template of star $s$. $P$: the shared spatially varying, colour-dependent ePSF at its position. $b$: one global coefficient, in px² of $\Delta\Sigma$ per $10^4$ e⁻ per read; a leaf of the fit, trained or fixed. $q_s$: static peak charge from the warm-start flux and the rendered peak, capped at $2\times10^5$ e⁻. $q_{\rm ref}$: loss-weighted mean $q$ of the trained stars, so that $P$ stays the PSF of a typical trained star. The term rides on the raw-gauge blur_raw generator (exactly calibrated: $\Delta\Sigma = 2w$, tested to 1%) and applies to every rendered star, including neighbours. CLI: --bright-width lin [--bright-width-init 0.8e-3] [--bright-width-train/--no-…].

Why it was not adopted before, and why that may now change. The 10-04 closure tested only the fixed historical $b=0.8\times10^{-3}$ on the old A3 recipe, and found +1.9% worse paired χ². On 09-30, a trained $b$ went negative (−0.7 to −1.1), because the faint anchors used the Laplacian to smooth pixel-scale ePSF structure. Three things are different in the v8 recipe. (1) Faint T11–13 stars now train the shape, so the Laplacian is no longer a free knob for anchors. (2) Neighbours are modelled, which removes a fake faint-sharper signal that pushed $b$ the wrong way. (3) The weight cap makes the shared ePSF a faint-star PSF, so the bright mismatch sits openly in the residual for $b$ to absorb.

Proposed test (one round, F1 + F2 fold 0, same scenes and held-out cores as v8; arm E needs code)

Arm A · reference

v8 best, as is

Neighbours + cap T10.5 + #3, bright_width none. Already done.

Arm B · trained b

v8 + trained global b

--bright-width lin, init 0.8e-3, trained. Primary question: does $b$ settle positive, near 0.5–1.2, and agree between fields?

Arm C · fixed b

v8 + fixed b = 0.8e-3

The 09-30 value, not trained. Separates "the term helps" from "training finds it".

Arm E · pixel operator

v8 + pixel-boundary BF operator

Charge moved from each pixel to its 4 neighbours, proportional to its charge. Tests whether the narrow central-pixel deficit left over by the blur (§2b) needs a pixel-scale term. Judge it on the stacked images, not on $c$.

Arm F · magnitude law

v8 + term linear in Tmag

The same bright_width code with $q_s\propto T_{\rm ref}-T_s$ supplied as the q file (needs a small load-q-file option), trained. A direct held-out comparison with arm B (charge) on the same stars (§6).

Arm D · relaxed cap

trained b, cap lifted to T9

With brightness in the model, bright stars may be informative again rather than harmful. This tests whether $b$ lets us drop part of the weight cap.

Gates (each judged on held-out stars, fixed eval set, same scorer)

  1. Physics gate. The width-vs-$q$ curve of held-out and all stars (this page's §4 figure, re-made per arm) is flat within errors from T8 to T13, and the stacked T8–9.5 core deficit and ring are gone on the shared colour scale.
  2. No-regression gate. Paired held-out core χ² at T10.5–13 is ≤ 1.00 vs arm A on both fields. The term must not buy bright stars at the faint stars' expense.
  3. Bright gate. Paired held-out χ² at T8–10.5 improves vs arm A, and the bright memorisation gap does not grow.
  4. Consistency gate. Trained $b$ is positive and agrees between F1 and F2 within errors, or the difference repeats on a second fold. Otherwise move to a per-CCD $b$, which is the user's standing goal from 10-01.
  5. Flux gate. A PSF-vs-aperture flux trend against Tmag (r < 3 px) shrinks. 09-30 found bright PSF fluxes about 0.3% low at T8; the core-χ² score cannot see this.

If the linear law is not enough

6 · Can a term linear in magnitude model it?

The candidate is the same machinery as bright_width, with magnitude in place of charge:

$$P_s=P+\tfrac12\,\beta\,(T_{\rm ref}-T_s)\,\nabla^2P\qquad\text{versus}\qquad P_s=P+\tfrac12\,b\,\frac{q_s-q_{\rm ref}}{10^4}\,\nabla^2P$$

$T_s$: catalogue TESS magnitude of star $s$. $\beta$: width change per magnitude, in px² of $\Delta\Sigma$ per mag. $T_{\rm ref}$: reference magnitude, which the ePSF absorbs. The other symbols are as in §5. Since $q_s\propto 10^{-0.4T_s}$, the two laws differ in shape: the magnitude law changes the width by the same amount per magnitude everywhere, while the charge law is nearly flat for faint stars and steep for bright ones ($q$ changes 100× from T13 to T8).

Test 1: which law fits the measured width curve?

Brightness laws fitted to the width curve
Width $c$ per 0.5-mag bin (mid colour, best v8) with weighted least-squares fits. Laws: linear in Tmag, linear in peak charge $q$ (bin-mean $q$, because $c$ is the stack of a mean), linear in flux, a hinge in Tmag, and a constant. Purple: the magnitude law fitted only to T > 10.5 and extrapolated to the bright end. The flat segment of the $q$ and flux curves brighter than T≈8.3 is the edge of the interpolation, not a prediction.
χ² / doflinear in Tmaglinear in qlinear in fluxhingeconstant
F1 all stars5.6/811.0/811.0/84.6/7 (T 12.4)53/9
F2 all stars20.2/89.8/89.7/87.1/7 (T 11.3)40/9
F1 held-out2.3/75.8/76.4/72.6/627/8
F2 held-out4.0/64.7/64.6/64.5/514/7

The binned curve does not decide. F1 prefers the magnitude law, because its faint end still slopes by about 0.12 per magnitude, which a straight line follows and the charge law cannot. F2 prefers the charge law, because its faint end is flat. Summed over both fields: magnitude 25.8/16 against charge 20.8/16 (all stars), and 6.3/13 against 10.5/13 (held-out).

Where a magnitude slope is learned matters. A magnitude term is constrained mostly by the 10,000 faint stars, because they dominate the count and have the same lever arm per magnitude as the bright ones. Fitted on T > 10.5 only and extrapolated, it predicts $c$ = −0.18 at T8.25 on F2, where +0.76 is observed. On F1 it predicts +0.42 against +0.80. The faint-end slope does not continue into the bright effect. It is a different thing, and the neighbour test already showed that the faint end is sensitive to contamination: modelling neighbours moved it by 0.4.

Test 2: at a fixed magnitude, does the width follow the pixel charge?

At fixed flux, the charge in the brightest pixel depends on where the star falls within its pixel. A magnitude law predicts no dependence on sub-pixel phase; a charge law, or a pixel-boundary operator, does. Below, stars in each magnitude range are split into terciles by their distance from the pixel centre (mid colour, matched median colour).

Width vs sub-pixel phase at fixed magnitude
Residual width against the median distance of the star from its pixel centre, with the corner on the left and the centre on the right. Dotted: what the charge law (§4 $b$) predicts from each tercile's measured mean peak charge. The peak-pixel fraction varies only about 10% across the terciles, because the PSF is broad compared with a pixel.

Brightest bin (T8–9.5): stars near a pixel centre are broader. On F1 the change is 0.13 → 0.88 (3.3σ), much more than the charge law's +0.13. On F2 it is 0.23 → 0.60 (about 2σ), close to the charge law. The next bin (T9.5–10.5) shows no clean trend: F1 has an outlying middle tercile and F2 is flat. Faint stars show a small decrease toward the pixel centre on both fields (−0.12 and −0.15, 3–5σ), a phase-dependent ePSF error unrelated to brightness. This is suggestive evidence for a pixel-charge effect, which a magnitude law cannot produce, but it is not decisive on these star counts.

Answer

  • Over T8–13 the data cannot rule a magnitude-linear term out. On F1 it fits the binned curve as well as anything. It would remove most of the bright-star residual in these fields.
  • It is the wrong variable, for four reasons. (1) Its slope is set by faint stars, whose small width trend is not the bright effect: it does not extrapolate, and it moved with neighbour modelling. That is the same failure mode as the 09-30 trained $b$, which faint anchors drove negative. (2) It extrapolates badly at both ends. At F1's slope it makes T19 stars 1.4e-3 px² sharper than T13 stars, which matters for the faint-target photometry. It also under-predicts brighter than T8, where charge keeps growing by 2.5× per magnitude. (3) It cannot carry the sub-pixel-phase dependence or the central-pixel shape (§2b), which both point to charge in pixels. (4) Charge per 2-s read is portable between sectors, cadences and fields; a magnitude slope is tied to the zero point and to each field's crowding.
  • Recommended: model the bright effect with charge (the existing bright_width term), plus the pixel-boundary operator (arm E) if the central-pixel and phase residual remain. Treat the F1 faint-end slope as a separate item to explain, for example remaining contamination or background level, and not as PSF.
  • Cheap to settle by experiment: the bright_width term already takes its per-star $q$ from bright_width_q.npz. scene_fit reads that file only when resuming, so it needs a small option (about 10 lines) to load a supplied file. Writing $q_s\propto T_{\rm ref}-T_s$ into it then gives the magnitude law as arm F. Arms B and F then compete on the same held-out stars, so the comparison does not rest on residual stacks.

7 · Plan: per-stamp tests on the trained Paper-1 fits (awaiting approval)

This uses the five finalised Paper-1 fits (F1, F2, S22, C1, C4) with K = 5 folds, so every star is scored by a fit that never trained on it. That gives 8,200–13,500 out-of-fold stars per field, 270–380 of them at T8–9.5. Nothing is retrained. Each star is fitted on its own stamp, its real pixels with their noise, rather than on a stack. Trends then come from a regression over stars. Full plan: dev/forward_epsf_wcs/docs/BRIGHT_WIDTH_PERSTAMP_PLAN_20261008.md.

Per-stamp model

$$d_p = m_p + f_s\big[\alpha_s T_{s,p} + \delta x_s\,\partial_xT_{s,p} + \delta y_s\,\partial_yT_{s,p} + c^{xx}_s\,\partial_x^2T_{s,p} + c^{yy}_s\,\partial_y^2T_{s,p} + c^{xy}_s\,\partial_x\partial_yT_{s,p} + \kappa_s K_{s,p}\big] + \beta_s + \epsilon_p$$

$d_p$: data in stamp pixel $p$, in e⁻/s. $m_p$: frozen scene model, including neighbours, with fluxes re-solved. $T_{s,p}$: the star's rendered pixel-integrated unit template, in px⁻². $\partial$: its derivatives with respect to the star's position, rendered by the real renderer as finite differences ($\pm$0.05 px). $f_s$: flux, in e⁻/s. $\alpha_s$: flux correction. $\delta x_s, \delta y_s$: shifts, in px. $c_s$: width terms, in px². $K_{s,p}$: pixel-boundary charge-transfer image, with dimensionless amplitude $\kappa_s$. $\beta_s$: local background. $\epsilon_p$: noise with variance $\sigma_p^2$ from the NOISE plane. The fit is weighted linear least squares in $r<3$ px. Every fit is repeated with fixed normalised weights, because noise weights that depend on S/N can fake brightness trends.

$$\bar c_s=\tfrac12(c^{xx}_s+c^{yy}_s)=c_0+\tfrac12\,b\,\frac{q_s-q_{\rm ref}}{10^4}+\gamma^\top\mathbf z_s+\eta_s$$

$q_s$: peak charge per read, which includes the sub-pixel phase. $b$: brightness-width coefficient. $\mathbf z_s$: nuisance covariates (colour, position), with coefficients $\gamma$. $\eta_s$: per-star scatter, with variance = the formal error plus a fitted intrinsic $\tau^2$.

Tests

  1. Null and injection (gate). Simulate each stamp from the frozen model plus noise, where the ePSF is exact and has no brightness effect. The fitted slope against $q$ and against $T$ must be 0 within 2σ, and any residual slope is subtracted as the method's bias. Inject $b$ = 0.8e-3 through the real bright_width render and recover it to within 10%.
  2. Law selection. Regress $\bar c_s$ on charge, magnitude and a threshold, plus the joint fit $c_0+\tfrac12 b\,q_s/10^4+\beta(T_s-11)$. At fixed magnitude, the sub-pixel phase discriminates between the laws.
  3. Spatial structure. Per-CCD $b$ (likelihood-ratio test, 4 dof), a linear gradient across each CCD (2 dof), per-axis $b^{xx}$ and $b^{yy}$, and descriptive 3×3 maps.
  4. Pixel-scale operator. Regress $\kappa_s$ on $q_s$. Check whether it removes the bright central-pixel deficit that the blur reproduces only half of (§2b).
  5. Decisive test. Render the frozen fits plus each candidate law with the real renderer, re-solve fluxes, and score with the existing held-out core-χ² scorer. Parameters are chosen on four folds' held-out stars and scored on the fifth. Gates: (G1) T8–10.5 improves on ≥4 of 5 fields; (G2) T10.5–13 does not get worse; (G3) the width trend against $q$ and against phase goes flat; (G4) the PSF−aperture flux trend shrinks. The charge and magnitude laws need only a wrapper around the existing bright_width path; the pixel operator is a post-render step.
  6. Retrain one field with the adopted law, only if test 5 passes. This needs a separate approval.

Should it be spatially variable? Power check on the OOF stacks

Fieldimplied $b$ [1e-3]bright $c_{xx}$ / $c_{yy}$ [1e-3 px²]OOF stars T<10 per 1/9 of the CCD
F1 (S24 C2K2)1.11 ± 0.191.35 / 1.3551–90
F2 (S20 C3K3)0.58 ± 0.110.78 / 1.0942–65
S22 (S22 C3K3)1.53 ± 0.201.37 / 1.3151–71
C1 (S24 C1K2)0.82 ± 0.161.13 / 1.3949–70
C4 (S23 C4K2)0.86 ± 0.101.10 / 0.6646–83

The coefficient may differ between CCDs: $b$ ranges over 0.58–1.53, which is χ² ≈ 20/4 against a single value with stack-bootstrap errors, still significant if those errors are 1.5× too small. Note that F2 and S22 are the same camera/CCD (C3K3) in different sectors, at 0.58 and 1.53. If that difference holds on the per-stamp fits, it argues against a pure CCD property and toward something that changes with the sector, such as focus or background, and per-sector rather than per-CCD fitting. Within a CCD there are only about 40–90 bright stars per ninth, so a per-cell $b$ has σ ≈ 50% of the signal. Only a linear gradient is testable, and part of any spatial variation is already carried by $q$, because a sharper local PSF puts more charge in its brightest pixel. No anisotropy is seen at ±0.3–0.45. Recommendation: test per-CCD (per-sector) $b$ first, then a gradient, and keep it isotropic unless the per-stamp fits show $b^{xx}\ne b^{yy}$.

8 · Results of the per-stamp tests (Paper 1 W3d, 2026-10-08)

The §7 plan was run on the five finalised Paper-1 fits. All 49,541 stars are out-of-fold (K = 5), and nothing was retrained. These were measured on the reference fits; the rerun on the end-to-end run-3 fits (§9, 10-09) reproduces every number within its error. The full record is the "3d brightness law" section of dev_runs/epsf_dependence_20261008/README.md.

$$\Delta\Sigma_s = a_0 + b\,q_s/10^4$$

$\Delta\Sigma_s$: extra blur covariance per axis of star $s$, in px². $a_0$: width offset applied to every star; it absorbs the frozen ePSF's zero point. $b$: brightness coefficient, in px² per $10^4$ e⁻ per 2-s read. $q_s$: peak charge per read.

Per-stamp blur amplitude vs peak charge with null and injection
Per-stamp blur amplitude ($\Delta\Sigma = 2a$) of held-out stars against peak charge, per field and pooled. Black: real data. Grey: noise null. Green: cross-fold null (another fold's ePSF plus noise). Red: injection of $b$ = 0.8e-3 through the real render. The real curve rises above about $10^4$ e⁻ on every field, the noise null is flat, and the injection is recovered to 95%.
Stacked residuals without and with the charge law
Radial profiles of the stacks
Held-out stacked residuals on a shared scale. For each field, three rows: the frozen fit, the frozen fit plus the charge law chosen on held-out stars, and their difference. At T8–9 the central deficit drops from −5…−11 to +1…−3 (×10⁻⁴ px⁻²). Non-radial structure remains, clearest on C4.
b per field and in crowding bins
Radial elongation and pixel operator vs charge
Top: $b$ per field for both weightings, with the null shown as crosses, and $b$ in contamination bins. Bottom: elongation in the frame of the direction to the optical axis (left: radial, by distance zone; middle: tangential), and the pixel-operator amplitude (right), all against charge.
QuestionAnswer
ChecksNoise null $b$ = 0.00; cross-fold null 0.10 ± 0.02 (subtracted); injected 0.80 recovered as 0.74–0.78
Charge or magnitude?Charge. ΔAIC −278 against −79 for magnitude. On held-out stars at T8–10.5, χ² improves by 0.5–1.3% on all 5 fields with charge; magnitude gives 0–0.5%; a width offset alone makes bright stars worse
Size$b$ = 1.42 / 0.68 / 1.01 / 0.94 / 0.82 ×10⁻³ (F1 / F2 / S22 / C1 / C4), pooled 0.98. The fields differ (p ≈ 0.007). F2 and S22 are the same CCD in different sectors, so $b$ should be fitted per FFI
Crowding?No. The clean sample gives the same $b$, and $b$ is flat across contamination bins
Spatial?No gradient within a CCD and no x/y anisotropy. Bright stars elongate toward the optical axis (6σ, stronger off-axis), but modelling that gives no held-out gain
Pixel operator?Its amplitude rises with charge and it absorbs 60% of the blur slope. It has not yet been scored on held-out stars

Conclusion. The bright-star broadening is a peak-charge effect of about $10^{-3}$ px² per $10^4$ e⁻ per read, varying by field. It is not a magnitude law, not crowding, and has no position dependence within a CCD. With the ePSF frozen, the existing bright_width blur plus a width offset removes most of the visible bright-star core residual but buys only about 1% in held-out χ². The next step is a retrain with the term (Test 5).

8b · Faint-end check: the width offset over-sharpens T12.5–13

The user noticed that the law seemed to make T11–13 worse. That is correct for the faintest stars. The law chosen on held-out stars applies a global width offset of $a_0\approx-1.2\times10^{-3}$ px². That offset fits T11–12, but it makes the model too sharp at T12.5–13.

Pooled stacks: frozen fit, chosen law, smaller offset
Held-out stars from all five fields, stacked on a shared scale. Rows: the frozen fit; the charge law with the chosen offset; the same $b$ with a smaller offset ($a_0=-0.4\times10^{-3}$). At T12.5–13 the chosen law turns a red core with a blue ring (model too broad, width $c=-0.30$) into a blue centre with a red ring at r ≈ 2 px (model too sharp, $c=+0.19\pm0.03$). The smaller offset gets both ends right but leaves T10.5–12.5 too sharp.
Per-stamp shape coefficients vs magnitude
Per-stamp shape coefficients against Tmag (held-out medians). Fitted alone, the blur dips at T11.5–12 and recovers toward T13. Fitted together with dilation and kurtosis, the faint stars show a steady core/wing shape change. The cross-fold null (dotted) is much smaller.
Faint check per field
Per field. Top: stack width before and after the law. Middle: held-out χ² ratio per 0.5 mag, labelled with the offset each bin prefers. Bottom: per-stamp blur amplitude before and after the law.

Conclusion. The faint-end mismatch is a core/wing shape change, not a constant width, so no single width offset fits both T11–12 and T12.5–13. It is not crowding (the clean sample is the same), not a background offset (adding a local background changes nothing), and not the estimator (the nulls are flat). Keep the charge term for the bright stars. In the retrain, let the ePSF set its own zero point and do not add a global offset. Treat the faint-end shape change as a separate, still-unexplained effect.

9 · Run-3 rerun and the charge-transport alternative (2026-10-09)

Everything in §8–8b was rerun unchanged on the final Paper-1 fits (run 3: K = 5 on the final per-band image, evaluated on its neighbour scene, run 3's own code). The per-stamp tables are the W3 lead's run-3 tables, made with the same perstamp.py. Law scoring, stacks and the faint check are new. Separately, the Codex session tested a nearest-neighbour charge-transport model (dev_runs/bf_transport_20261008/current) on the reference F1/F2 fits. I reviewed that code and replayed it, unchanged except for the paths, on all five run-3 fields.

$$T_{p\to r}=\kappa_d\,(Q_p^2-Q_r^2)/Q_0$$

$T_{p\to r}$: electrons moved from pixel $p$ to its neighbour $r$ per 2-s read. $Q_p$: predicted charge in pixel $p$ (scene model × 2 s). $Q_0=10^4$ e⁻ (fixed). $\kappa_d$: fitted dimensionless coefficient, one value for both axes ("isotropic") or separate x and y values ("x/y"). The control arm "peak-charge blur" is the model's blur generator scaled by $q_s/10^4$ with no offset, i.e. the §8 law with $a_0=0$. Both arms make the relative change scale as $Q$, so they have the same brightness law and differ only in spatial shape: smooth blur against a pixel-boundary flow. The transport model therefore tests the shape, not the law.

Reference vs run-3: b per field, law scores, Codex arms
Left: per-stamp $b$ per field, reference fits (grey) against run 3 (red). Pooled raw 1.03 → 1.07 ± 0.06 ×10⁻³, i.e. 0.98 → 1.01 after the cross-fold-null subtraction (0.11) and the 0.95 injection recovery. Every field agrees within 0.12. Middle: held-out χ² ratio against no term at T8–10.5, by nested CV (open = reference, filled = run 3). The charge law improves all 5 fields (0.987–0.994); the magnitude law gives 0.995–1.001; an offset alone gives 1.005–1.014, i.e. worse. Right: the Codex native-pixel arms (clean stars, r < 3 px, tile-held-out coefficients). Positive is better. The bars are conditional 95% intervals that hold the coefficients fixed.
run-3 per-stamp blur vs charge
Run 3, same as the §8 figure. Per-stamp blur amplitude rises with peak charge above about $10^4$ e⁻ on all five fields. The noise null (grey) is flat; the cross-fold null (green) is ≤ 0.2; injection of $b$ = 0.8e-3 (red) is recovered as 0.76.
run-3 transport vs blur stacks
run-3 transport vs blur radial
Run 3, held-out clean stars at T8–9 (123–161 per field), plain mean of phase-binned native samples, shared ±12e-4 scale. Columns: no term; the peak-charge blur; x/y transport; the model change made by the blur; transport residual minus blur residual. Both corrections remove the central deficit (core −7…−12 → −0.4…−4 ×10⁻⁴), and their radial profiles overlap. Transport and blur differ by ≤ 1×10⁻⁴ per pixel, apart from weak ±y lobes. The asymmetric structure (the F2 up/down dipole, the C1/C4 lobes) is left by both.
Run 3, T8–10.5F1F2S22C1C4
blur, χ² reduction3.4%1.5%7.7%4.0%2.6%
x/y transport2.6%1.8%6.9%1.9%1.8%
paired χ²(x/y transport)/χ²(blur), 95%1.008 [1.001, 1.015]0.997 [0.991, 1.004]1.009 [0.997, 1.021]1.022 [1.011, 1.044]1.009 [1.001, 1.019]
W3d charge law, held-out χ² ratio (all held stars)0.99450.99310.98810.98660.9941

Review of the Codex record. The record is sound. It uses the right reference; its per-star χ² and fluxes replay mine to 5×10⁻¹⁶; and its tile split is genuinely held out. It conserves charge, recovers injections (1.0/0.6 → 1.00/0.60), and its noise null is zero. I found no bug, and the run-3 replay reproduces its F1/F2 numbers to 0.1%. Four points to add. (i) Transport and the blur arm share the brightness law (both ∝ Q), so "transport works" supports the charge law but says nothing new about its scaling. (ii) The paired comparison favours the one-parameter smooth blur over two-parameter x/y transport on F1, C1 and C4, and ties on F2 and S22. The extra x/y freedom does worse than isotropic on C1 and C4. (iii) About 11% of a charge-independent width defect leaks into the transport coefficients (its own leakage gate). (iv) The intervals hold coefficients fixed, so they are slightly optimistic. Its χ² gains are 2–3× mine because it scores only clean stars within r < 3 px, where the effect lives. That is the same signal, not a contradiction.

run-3 pooled stacks four law variants
Run 3, all fields pooled, shared ±8e-4 scale. Rows: frozen fit; chosen law ($a_0$ = −0.8e-3 for F1/F2, −1.2e-3 for S22/C1/C4); same $b$ with $a_0$ = −0.4e-3; $b$ = 1.0e-3 with no offset. Width term $c$ (×10⁻³ px², negative = data sharper) at T8–9 / 11.5–12.5 / 12.5–13: +1.91 / −0.43 / −0.31 (frozen); +0.63 / 0.00 / +0.16 (chosen); +0.32 / −0.31 / −0.15 ($a_0$ = −0.4); +0.45 / −0.49 / −0.34 (no offset). The bright end is fixed by all three. Applied post hoc to a frozen ePSF, the no-offset law broadens the faint stars slightly too, because the frozen ePSF cannot move its zero point. Only a retrain can test the no-offset version.
run-3 faint check per field
run-3 shape vs mag
Run 3, per field: stack width, held-out χ² per 0.5 mag with the preferred offset, and per-stamp blur, before and after the chosen law. With $a_0$ = −0.8e-3 (F1, F2) the faint end is flat to T13. With −1.2e-3 (S22, C1, C4) T12–13 is over-sharpened by +0.2…+0.45. Bottom: the faint stars again show the steady dilation/kurtosis rise from T10 to T13 (the cross-fold null is dotted), the same core/wing shape change as in §8b.

Conclusion (run 3). The peak-charge law holds on the final Paper-1 fits: $b$ = 1.01 ± 0.06 ×10⁻³ px² per 10⁴ e⁻ per read pooled (0.8–1.4 by field, differing between fields at p ≈ 0.01), with every gate passed. It beats a magnitude law on 5/5 fields. On the frozen fits it removes most of the T8–9 core deficit and gains 0.6–1.3% held-out χ² on all held stars, or 1.5–7.7% on clean stars within r < 3 px. A pixel-boundary transport law of the same brightness scaling fits no better than the smooth blur, and worse on 3/5 fields, so keep the smooth bright_width generator. Asymmetric bright-star residuals and the faint-end core/wing change remain for both. Confidence: high for the charge law and its size, high that transport is not preferred. Adoption, and whether to add an offset, depends on a retrain (Test 5), which needs the user's approval.

10 · Retraining with the brightness term on the new colour model (Arm A, 2026-10-10)

Post hoc, the charge law needed a global width offset, and that offset over-sharpened T12–13 (§8b, §9). Two cheap checks came first. Test 1: the faint-star sharpness survives the new colour model (s1c: radial rings and coma, A3 round terms dropped), in mid-colour stars too, so it is not a colour effect. Step 3: it shows no trend with CCD row and none inside the readout blocks, and it is flat over peak charge 300–5000 e⁻, so it is neither charge-transfer trailing nor a low-signal effect. Arm A then retrained s1c with the term trained and its zero point at zero charge ($q_{\rm ref}=0$), so the ePSF is the zero-charge PSF and no offset exists. It used F1/F2/C4, folds 0–1, the same scenes, initialisation and schedule as the s1c fits, and was scored on the same held-out stars.

$$P_s = P + \tfrac12\,b\,\frac{q_s}{10^4}\,\nabla^2 P$$

$P$: the ePSF after the colour model (zero-charge PSF). $b$: brightness coefficient, extra blur covariance per axis (px²) per $10^4$ e⁻ per 2-s read, trained. $q_s$: the star's peak charge per read. For held-out stars it is computed on the evaluation scene from a solve without the term; see the bug note below.

Test 1 faint width
Test 1, no training: stack width $c$ against Tmag for held-out stars on rf5 images, A3 control (grey) vs the new colour model (red), all colours and mid colour. Faint stars stay sharper than the model by 0.3–0.4 ×10⁻³ px² under both colour models. The dashed lines are the post-hoc no-offset law, which leaves the faint end as it is.
Arm A width and chi2
Arm A (red) against the control (grey), per field and pooled. Rows: stack width $c$ (all colours; mid colour), held-out χ² ratio (median per star). The bright excess falls from +1.17 / +0.70 / +0.50 to +0.49 / +0.17 / +0.22 (T8–8.5 / 8.5–9 / 9–9.5, pooled; F1 to zero). The faint end moves toward zero (T12.5–13: −0.30 → −0.18) without crossing it. Faint χ² improves by 0.2% on every field; bright χ² improves at T8–9 (−1…−5%), is slightly worse at T9.5–10 (+0.5%), and is flat overall at T8–10.5.
Arm A stacks
Held-out stacks per 1-mag bin (control, Arm A, difference), shared ±8e-4 scale. At T8–9 the difference is a red core with a blue ring on all three fields: the term fills the bright stars' central deficit, and the T8–9 residual rms drops by 31 / 16 / 26% (F1 / F2 / C4). At T12–13 the difference is a faint blue core: the ePSF sharpened toward the faint stars, with no overshoot. The faint red-core/blue-ring pattern largely remains.
faint vs row
Step 3: per-stamp shape against CCD row, faint (top) and bright (bottom), real vs null. There is no row gradient, so no readout-transfer signature. A ~410 px periodic pattern, the same at all magnitudes, matches the 6×6 ePSF node grid. Stars look broader than the model at the nodes and sharper between them: an interpolation artefact, flagged to the ePSF lead.

Bug found and fixed before the verdict. In the first evaluation the held-out stars had $q = 0$. Their pixels are withheld from the fold scene, so their warm-start flux, and hence their q, is zero, and the scorer took q from the fit's file. The bright stars were therefore scored without the term. The scorer now computes q for those stars on the evaluation scene (branch bwidth-rf5-20261009 f6364402). The buggy evaluations are kept for reference.

Conclusion. Trained together with the ePSF, the peak-charge term removes most of the bright-star width excess (fully on F1) and does not over-sharpen T12–13. The faint end improves (width mismatch −10…−40%, held-out χ² −0.2%). Held-out χ² at T8–10.5 does not improve overall (+0.02%), and about two thirds of the faint-star sharpness remains, so that is a separate effect, not the ePSF compromise. The trained $b$ differs by field, 1.43 / 0.64 / 0.57 ×10⁻³ (F1 / F2 / C4, stable between folds), so the term needs a per-FFI coefficient. Adoption is the user's decision, together with the colour shape.

11 · Brightness-term campaign: all five fields, forms, chain, injection, fixed vs trained b (2026-10-12)

Preliminary result (10-12, 13:xx EDT). Trained with the ePSF on the run-4 final image (5 fields × 5 folds, held-out stars), the linear peak-charge term lowers the bright-star χ²: the bin-averaged T8–10.5 ratio is 0.988 ± 0.002 and T8–9.5 is 0.989 ± 0.002. It also improves the faint stars slightly (T10.5–13: −0.15%). Trained through the whole run-4 chain (boot → kernels → final image → fold fits) on F1 and C4, the gain is larger: bright 0.987 ± 0.004, faint −0.36%, and no cost at T9.5–10.5. The pre-registered gate, the pooled T8–10.5 median ≤ 0.994, still fails (0.9990 ± 0.0004), because the gain sits in the few hundred T8–9.5 stars while the median is set by the many T9.5–10.5 stars. b is recovered without bias in injection tests on F1 and C4. It varies by field (0.4–1.4 ×10⁻³) for reasons not yet found, and it is not reproducible fold to fold in S22.

$$P_s = P + \tfrac12\,\Delta\Sigma_{xx,s}\,\partial_x^2 P + \tfrac12\,\Delta\Sigma_{yy,s}\,\partial_y^2 P,\qquad u_s=\frac{q_s-q_{\rm ref}}{10^4\ e^-}$$

$P$: the ePSF after the colour model, i.e. the zero-charge PSF (fitted). $q_s$: peak charge of star $s$ per 2-s read (e⁻) $=2\,{\rm s}\times f_s\times$ peak-pixel fraction of its unit-flux template, where $f_s$ is the warm-start solved flux (e⁻/s). It is fixed during training and capped at $2\times10^5$ e⁻. For held-out stars it is computed on the evaluation scene from a solve without the term. $q_{\rm ref}=0$ (fixed). $\Delta\Sigma$: extra Gaussian covariance per axis (px²). Forms, with $b,d,c$ fitted and $q_0$ fixed: lin $\Delta\Sigma_{xx}=\Delta\Sigma_{yy}=b\,u_s$; aniso $\Delta\Sigma_{xx}=(b+d)\,u_s$, $\Delta\Sigma_{yy}=(b-d)\,u_s$; quad $\Delta\Sigma=b\,u_s+c\,u_s^2$; onset $\Delta\Sigma=b\,\max(q_s-q_0,0)/10^4$ with $q_0=3\times10^3$ (the knee of the run-3 per-star curve, §4) or $10^4$ e⁻ (≈ T10). Units: $b,d$ in px² per $10^4$ e⁻; $c$ in px² per $(10^4\ e^-)^2$. Metric: $r_s=\chi^2_{{\rm arm},s}/\chi^2_{{\rm ctrl},s}$, the held-out core χ² of the same star under the arm and under the control, summarised as medians with bootstrap errors.

Setup. Every arm uses run 4's own fold argv: same fold scene, warm start, colour file, step budget and smoothed stop rule. Only the term flags are added. The controls are run 4's folds_final fits, re-scored with this branch; re-scoring agrees with run 4's own scores to within 1.6×10⁻⁴ in χ². Run 4's C4 folds were trained on a T4, so the CPU arms use matched CPU control fits for C4, while the chain, also trained on T4, uses run 4's C4 folds. Branch bwidth-campaign-20261012 @65c2e367 (not merged).

Held-out χ² ratios (median per star, ± bootstrap)

arm (folds)scopebin-avg T8–10.5T8–9.5gate: pooled T8–10.5 (≤0.994)T9.5–10.5T10.5–13
lin (5)F10.994 ± 0.0060.992 ± 0.0061.00091.00370.9962
lin (5)F20.987 ± 0.0050.985 ± 0.0040.99911.00130.9988
lin (5)S220.995 ± 0.0030.993 ± 0.0020.99810.99950.9991
lin (5)C10.985 ± 0.0060.989 ± 0.0040.99921.00160.9993
lin (5)C40.981 ± 0.0040.985 ± 0.0040.99791.00060.9983
lin (25)pooled0.988 ± 0.0020.989 ± 0.0020.9990 ± 0.00041.0010 ± 0.00060.9985 ± 0.0001
chain (5)F10.992 ± 0.0060.991 ± 0.0060.99971.00190.9959
chain (5)C40.980 ± 0.0040.983 ± 0.0060.99680.99850.9966
chain (10)pooled0.987 ± 0.0040.988 ± 0.0040.9979 ± 0.00111.0000 ± 0.00120.9964 ± 0.0002
hyb_term: control ePSF + lin b (25)pooled0.984 ± 0.0030.986 ± 0.0030.99911.0021 ± 0.00071.0003
hyb_shape: lin ePSF, term off (25)per field1.003–1.0061.004–1.0091.000–1.0050.998–1.0010.996–0.999
lin chi2 and width, 5 fields
Test 1, lin on the run-4 final image, all 25 folds. Top: stack width $c$ against Tmag (control grey, lin red). Bottom: held-out χ² ratio lin/control. The bright excess falls on every field: pooled T8–8.5 $c$ goes from +2.2 to +1.0. T8–8.5 χ² is −2 to −8%. The ratio sits near 1.000 at T9.5–10.5, with a bump to +0.7% on F1 at T9.75. The faint end is flat or slightly below 1.
chain chi2
Test 6, the brightness term trained through the whole run-4 chain (recipe paper1_final_step1_bw: boot fit → template shift → kernels → final image → scene_final → folds_final). F1 and C4, 5 folds each, against run 4 on the same held-out stars. Bright $c$: F1 +1.3 → +0.3, C4 +1.5 → +0.8 (T8–8.5). χ²: T8–8.5 −3% (F1) and −8.5% (C4). The ratio is ≤ 1 in every bin except T10–10.5 (1.00). Both final images with the term pass G4.
chain stacks
F1 chain held-out stacks per magnitude bin (control, chain, difference; ±8e-4). The difference at T8–9 is a red core with a blue ring: the term fills the bright stars' central deficit. T8–9 rms 2.25 → 1.27, T9–10 0.86 → 0.66, T12–13 0.73 → 0.59.
decomposition hyb_term
Decomposition: the control's ePSF with the lin fit's b added (hyb_term), against the control. The term alone gives the whole bright gain (bin-avg 0.984). On the control's ePSF, which had already broadened to compromise toward the bright stars, it over-sharpens T9.5–11 ($c$ ≈ −0.5): this is the T9.5–10.5 cost (+0.2%). The lin fit's own ePSF without the term (hyb_shape, table) is worse on bright stars and better on faint ones. When the term carries the bright stars, the ePSF re-sharpens toward the faint stars.
form ranking
Test 2: the forms on F1/F2/C4 × folds 0–1, same stars. Left: stack width. Middle: χ² ratio vs control. Right: χ² ratio vs lin. All forms remove most of the bright width; quad and onset 10⁴ flatten T8–8.5 further (quad overshoots to −0.3). Pooled: lin bin-avg 0.990, T9.5–10.5 +0.15%, faint −0.18%; quad 0.996 / −0.04% / −0.04%; onset 10⁴ 0.992 / −0.10% / −0.09%; onset 3×10³ 0.989 / +0.09% / −0.16%; aniso ≈ lin. The forms that remove the T9.5–10.5 cost give back the faint gain. No form beats lin significantly. Anisotropy: d = −0.27…+0.13 ×10⁻³ with no consistent sign, so the 09-25 $k_{yy}\approx2k_{xx}$ is not reproduced.
b vs field
Test 3: trained b (lin, mean ± sd over 5 folds) against ePSF core width, faint-stamp noise (sky), median q of T8–10 stars, and the fraction with q > 10⁴. b: F1 1.39 ± 0.08, C1 0.94 ± 0.04, C4 0.61 ± 0.08, F2 0.57 ± 0.07, S22 0.42 ± 0.38 (×10⁻³). No covariate orders the fields. F2 and S22 are the same camera 3 CCD 3, with equal core width (0.510/0.509 px²), sky and q distribution. Their trained b differs mainly through S22's fold scatter.
per-quadrant slope
Model-independent check: the slope of the control's held-out stack width against $u=q/10^4$ (T8–11.5, stacks per q bin), per CCD quadrant. All quadrants of all fields are positive, 0.24–0.81 ×10⁻³ px². The all-star slopes are F1 0.70 ± 0.10, F2 0.41 ± 0.06, S22 0.66 ± 0.08, C1 0.65 ± 0.09 and C4 0.65 ± 0.06, much more uniform than the trained b. The 2.5× spread in trained b is therefore largely a training (b–ePSF trade) effect, not a detector difference. Quadrant differences reach 3σ in places (F1 y-high vs y-low) and are not yet tested by a trained per-quadrant b.

Measured b: what it is and whether it trends

The trained $b$ is one scalar per ePSF fit, i.e. per field per fold. It applies to every star on the CCD and to every ePSF node: there is no per-quadrant or per-node $b$ in the model. The only position-resolved measurement is the model-independent slope $\hat b$ of the control fits' held-out stack width against $u=q/10^4$, per CCD quadrant.

measured b
Left: every trained $b$. Red = lin on the run-4 image (digits = fold), blue = chain, green = Arm A on the run3_rf5 image, purple = the isotropic part of aniso; grey band = control slope $\hat b \pm 1\sigma$; dotted = the fixed global $b = 0.65$ arm. Values cluster by field: F1 1.25–1.49, C1 0.91–1.03, C4 0.52–0.74, F2 0.46–0.66, S22 0.10–1.15. A given fold gives the same $b$ on every image (F1/F2/C4 folds 0–1: run3_rf5, run4 and chain agree to ≤0.01), so $b$ is set by the fold's training-star set, not by image noise. Trained $b$ exceeds the control slope 2× on F1 and 1.4× on C1, matches it on C4 and lies near it on F2. Middle: control slope per CCD quadrant. In 4 of 5 fields the quadrant nearest the camera's optical axis is highest: F1 (axis top-left) 0.81 ± 0.20 top-left vs 0.24 ± 0.07 bottom-right; S22 (axis top-right) 0.81 top-right vs 0.33 bottom; C1 top 0.50 vs bottom 0.31; F2 weak. C4 is the exception (0.72 bottom-right). This is a 2–3σ hint that the charge term is stronger where the PSF is sharpest. Right: per-fold $b$ against the bright-star leverage of the fold's trained set: no trend inside a field.
b vs fold properties
Per-fold trained $b$ (lin, 25 fits) against the fold's trained contributors at T<9.5, the number with $q>2\times10^4$ e⁻, their median $q$, and the number of capped (saturated) nuisance stars. Within each field these vary by under ±10% while S22's $b$ varies 10×. None of them explains the S22 scatter, and none orders the fields.
photometry
Test 5: photometric change from the term (lin minus control, held-out stars, 5 fields). PSF flux: T8 stars become 0.6 mmag brighter and T13 stars 0.25 mmag fainter, about 5% of the +15 → −4 mmag bright-end Gaia trend (dashed, aprad_brightend_20261010). The term does not explain that trend. The model aperture flux at r ≤ 3 and r ≤ 5 px changes by at most ±0.35 ppt, inside the ±1 ppt E3 tolerance. The chain gives the same picture (−0.7 → +0.25 mmag, ±0.3 ppt).

Fixed global b vs trained b (25 folds, same stars)

Arm fixed065 uses the same recipe with $b$ frozen at $0.65\times10^{-3}$ (not trained). The χ² ratio is vs the control, median per star. "fixed/trained" is the per-star ratio of the two term arms.

fieldbin-avg T8–10.5 trained → fixedT8–9.5 trained → fixedfixed / trained T8–10.5fixed / trained T10.5–13
F10.994 → 0.9910.992 → 0.9911.0002 ± 0.00111.0015 ± 0.0002
F20.987 → 0.9870.985 → 0.9831.0007 ± 0.00040.9998 ± 0.0001
S220.995 → 0.9840.993 → 0.9850.9988 ± 0.00080.9994 ± 0.0002
C10.985 → 0.9860.989 → 0.9901.0001 ± 0.00071.0003 ± 0.0001
C40.981 → 0.9820.985 → 0.9861.0000 ± 0.00020.9999 ± 0.0000
pooled0.988 → 0.9860.989 → 0.9881.0000 ± 0.00021.0001 ± 0.0000

Overall, fixed and trained $b$ are the same fit. Trained $b$ is better only for F1's faint stars (+0.15% with fixed $b$). Fixed $b$ is better on S22, where training collapsed. Transfer: S22 with F2's trained $b$ (0.57, same camera 3 CCD 3) equals S22's own trained $b$ (per star 0.9995 ± 0.0007). F2 at its own measured slope (0.41) equals both. Held-out χ² is flat in $b$ over about 0.4–1.4 ×10⁻³: the data cannot pin $b$ per field. Production consistency: the all-star refit, i.e. the production fit through the full chain, gives F1 1.45 and C4 0.64, against fold means 1.39 ± 0.09 and 0.62 ± 0.08. The boot fits give 1.41 and 0.62.

slope with data points
The direct brightness slope with its data. Held-out stack width $c$ is plotted against $u=q/10^4$ (T8–11.5, 5 folds; the digits give stars per bin). Grey: control (no term). Red: lin (term trained). Black: line fitted to the control. Dashed blue: the field's mean trained $b$ through the same intercept. Straight-line slopes: F1 0.51 ± 0.07, F2 0.41 ± 0.06, S22 0.52 ± 0.06, C1 0.57 ± 0.06, C4 0.36 ± 0.04 (×10⁻³), similar across fields. The faint end stays at −0.3 to −0.4, the separate faint-star sharpness, which the term does not change. F1's trained $b$ (1.39) is far steeper than its points, yet lin removes F1's excess (red ≈ 0). Training also re-sharpens the ePSF, so the trained $b$ is the slope plus compensation for that change.
x and y slopes
The same control curves split into rows ($c_{xx}$) and columns ($c_{yy}$). Below $u\approx2$ both axes rise together. Above that, several fields show a larger column excess in single bins (S22, C1, C4, F2), with errors of ±0.4–0.7 per point.
law fits
Candidate laws fitted to those model-free curves; each field has an offset for the faint level, and thresholds are shared across fields. Total χ² for 80 points, free parameters, AIC: linear round 96.2 / 10 / 116.2; linear $b_x\ne b_y$ (= aniso) 87.2 / 15 / 117.2; round onset 98.2 / 11 / 120.2; onset with $b_x\ne b_y$ 86.8 / 16 / 118.8; round onset + column onset 87.4 / 17 / 121.4. The fitted onset runs to the lowest grid value (no knee is needed). The column-onset coefficient changes sign between fields (F1 −0.59, F2 +0.15, S22 −0.32, C1 +0.91, C4 −0.86). Within the errors the data are consistent with the linear round law, which is also what the trained aniso arm showed: no gain and an inconsistent x/y split. With both thresholds at zero, the two-threshold law is exactly aniso. The form is settled as linear and round at the current precision; more bright stars, from more FFIs or sectors, would be needed to test a threshold or a column effect.

Decision (user, 2026-10-12 evening). Keep the current model: the linear round peak-charge term, $\Delta\Sigma=b\,q/10^4$ with $q_{\rm ref}=0$, $b$ trained per fit with the ePSF, and the term carried through the whole chain. Production runs with this recipe (paper1_final_step1_bw) on all five fields: F1 and C4 complete; S22, F2 and C1 running. $b$ is reported as a fitted parameter, with its fold spread next to the model-free slope, not as a detector constant. Whether S22 needs a safeguard (weak prior or fallback to fixed $b$) will be decided from its production run and star diagnosis. The pre-registered pooled-median gate fails (0.9990) and stays reported.

Production run with the adopted model (status 2026-10-12 23:20)

Recipe paper1_final_step1_bw through the whole chain: boot fit → template shift → kernels → final image → all-star refit (the production fit) + 5 folds. Fits ran on Colab T4/L4 and Condor; every fit is installed with its provenance, and no session is left running.

fieldstatusboot $b$production (refit) $b$folds $b$ (mean ± sample sd)G4 (final image with term)
S24 C2K2 (F1)complete1.411.451.39 ± 0.09PASS
S23 C4K2 (C4)complete0.620.640.62 ± 0.09PASS
S20 C3K3 (F2)complete0.500.580.57 ± 0.08PASS
S22 C3K3 (S22)final image done; refit + folds running0.36pendingpendingPASS
S24 C1K2 (C1)final image done; refit + folds running0.95pendingpendingPASS

Units ×10⁻³ px² per 10⁴ e⁻. Where complete, the production $b$ agrees with the fold values within the fold spread. S22's boot value (0.36) lies at the low end of its lin-arm fold range (0.10–1.15) and below the transfer/fixed values (0.57–0.65). Whether S22 gets the fixed-$b$ safeguard will be decided from its production refit and folds. GPU note: L4 sessions were unreliable tonight (C1 boot failed 3×; one S22 run trained but its session vanished before the final sync). Both were restarted on T4, which completed.

S22: why trained $b$ is not reproducible

S22 drop refits
Stage-3 trajectory of $b$ for S22 fold-1 refits. Original fold 1: 0.29. With the 117 bright stars that only fold 0 holds out removed from training: 0.17. With 117 random bright stars from other folds removed: −0.02. Fold 0 for comparison: 1.15, the only fold where $b$ rises. No anomalous group of stars exists (fold-0 bright stars match the others in charge, position, neighbours, masking and per-star width). Removing any 117 bright stars moves $b$ by several tenths, so on S22 the loss is nearly flat along the $b$–ePSF direction and the trained $b$ depends on the training path and sample. Transfer test (5 folds, same held-out stars): S22 with F2's trained $b$ = 0.57 gives bright bin-avg 0.990 vs 0.995 for S22's own trained $b$, and 0.984 for 0.65. A fixed $b$ ≈ 0.57–0.65 is the practical choice on S22.

Correction: the model-free slope depends on the estimator

Two binnings of the same control curves give different straight-line slopes: 4 charge bins (test 3, used in the b-vs-field and quadrant figures and for the fixed value 0.65): F1 0.70, F2 0.41, S22 0.66, C1 0.65, C4 0.65; 8 finer bins (slope figure, Fig 14 draft): 0.51, 0.41, 0.52, 0.57, 0.36. They differ by up to 0.3 (C4) because the curves are not exactly straight (C4 χ² 25/6), so the model-free slope carries a systematic uncertainty of about ±0.15–0.3 ×10⁻³. The finer-bin values are now the quoted ones. The conclusions do not change: the slope's spread across fields (0.36–0.70) is smaller than trained $b$'s (0.42–1.39), F1's trained $b$ is still 2–3× its slope, and χ² is flat in $b$ over 0.4–1.4. Fold spreads are now quoted as sample sd (F1 ±0.09, F2 ±0.08).

Where the leftover bullseye comes from (diagnostics, 10-12 night)

With the term, the held-out stacks still show a bullseye: a blue core and red ring for bright stars (data less peaked than the model), and a red core with a blue ring for faint stars (data sharper). Four checks:

checkresultverdict
Trained vs held-out stars (5 fields × 5 folds)Same bullseye: control T8–9 core −8.2 vs −8.4 ×10⁻⁴; T12–13 +1.56 vs +1.65; with term −3.9 vs −3.6Not memorisation; the fit has converged to what the model can represent
3×3 CCD cellsBright core negative in all 9 cells, faint core positive in all 9Not a stacking artefact
Sub-pixel positionBright core: centred −7.8, between −3.8, corner −2.3; faint: +3.1 / +0.5 / +1.6 (with term)2–6× stronger for pixel-centred stars: a pixel-scale effect (intra-pixel response or ePSF resolution)
ePSF node phase (figure below)Faint core falls ≈6× from node to midway (T12–13 2.0 → 0.35, edges excluded); bright core more negative midwayThe faint bullseye is mostly a node-interpolation artefact
Smoothing-prior strength (figure below)A strong prior inflates the faint bullseye (×4 core, ×8 ring), but the production fits sit below even the prior-free level of that scanNot the main cause in production
Smooth blur vs pixel charge operator (figure below)Shapes collinear (cos 0.93–0.97); the charge operator is not preferred and behaves identically with and without the termThe term's smooth shape is not the limitation
node phase
Bullseye core, ring and width term against ePSF node phase (0 = at a node, 1 = midway between nodes; nodes every 409.6 px). Held-out stars, 5 fields × 5 folds, with the term; solid = all stars, dotted = stars more than 100 px from the CCD edge; black = combined phase, blue = x only, red = y only. For faint stars (T10–13) the red core falls about sixfold from node to midway, in x and y alike and with edges excluded. Bright stars show the opposite trend. Interpretation: each star's ePSF blends the four nearest node ePSFs, and the true width changes across the CCD by about 20%. A blend of two PSFs of different width is peakier with heavier wings than a single PSF of intermediate width, so training makes the node ePSFs slightly too blunt; faint stars then look sharper than the model at nodes, and bright stars less peaked midway. Fix candidates, all ePSF-model changes that need training: a denser node grid, an explicit smooth width field across the CCD, or shape-aware interpolation.
penalty scan
Bullseye core, ring and width term against the local-polynomial prior strength λ (an older "floor" recipe scan, F1/F2 fold 0, held-out; squares = λ 0; dotted/dashed = 10-04 reference arms). The faint bullseye is flat for λ ≤ 3×10⁶ and grows steeply beyond. The production fits (λ = 3×10⁸ without the floor) have faint cores of 1.2–2.2 ×10⁻⁴, below this scan's λ = 0 level, so the prior is not what limits production. There is no production-recipe λ = 0 fit; that is the remaining direct check.
shape amplitudes vs q
Per-star shape amplitudes against peak charge (held-out stars, 4 fields; grey = control, red = with term). Blur rises with charge in the control (+2.6 at 5.6×10⁴ e⁻) and is mostly removed by the term (+0.8 ± 0.6). Dilation (≈ +1) and kurtosis (≈ −0.2) are flat with charge and identical with and without the term: a magnitude-independent profile mismatch, i.e. the bullseye above. The exception is the 10 brightest stars (q > 5×10⁴ e⁻, T ≲ 8.5): dilation +6.6 ± 2.5 and kurtosis −2.4 ± 0.7, a hint that the very brightest stars need more than a linear blur (≈3σ, one bin).

Paper figure draft (Fig 14 v2)

Fig 14 v2 draft
Draft of the paper's brightness figure (generator dev/paper/paper1_single_ffi/figures/final_20261009/fig14_brightness/fig14_brightness_v2.py; text draft drafts/brightness_term_20261012.md). (a) Extra width against peak charge without (grey) and with (red) the term, five fields, with the straight-line model-free slope. (b) Held-out χ² ratio per magnitude bin. (c) T8–9 and T12–13 residual stacks without and with the term. (d) Fitted $b$ per field (folds, production value marked) next to the model-free slope. It currently uses the term trained on the final image for all five fields, and will switch to the production-chain fits once S22 and C1 finish.

Injection–recovery (test 4)

Synthetic scene $=$ data $+\,M(b_{\rm true}) - M(b_{\rm fit})$, where $M$ is the lin fit's own model with fluxes held at its solved values. The real residual, data $- M(b_{\rm fit})$, keeps real noise, background and neighbours, and also the model's own errors. Each scene is refitted with the training pipeline from $b_{\rm init}=1.0\times10^{-3}$.

base fitb_fitb_true = 00.51.21.5 (×10⁻³)
F1 fold 0 (Arm A, run3_rf5)1.49−0.0120.498—1.495
C4 fold 0 (Arm A, run3_rf5)0.60−0.0020.507—1.501
S22 fold 1 (run4 lin)0.29−0.012—1.137 (still falling)—

b is recovered without bias on F1 and C4 (|Δb| ≤ 0.012×10⁻³). The residual alone does not produce a b (b_true = 0 → 0), so the faint-end χ² is not distorted by the term. On S22 the null is also recovered (−0.012), and 1.2 comes back 5% low, still drifting when training stopped.

S22: b not reproducible fold to fold

Trained b for S22 folds 0–4: 1.15, 0.29, 0.38, 0.20, 0.10 ×10⁻³. Every fold starts at 1.0. Fold 0 settles while folds 1–4 fall slowly through stage 3; the loss plateau stops them with b nearly flat (last-quarter drift ≤ 0.006×10⁻³). The same image and recipe give F2 0.46–0.66. The capped saturated stars (all nuisance) number 41–53 per fold and do not track b. The control-stack slope for S22 is an ordinary 0.66 ± 0.08. In S22 the loss is flat along a b–ePSF direction and the trained b depends on which stars are trained. Under investigation.

Explorer: residual grids per field and arm

Held-out stars. "all folds pooled" = every available fold (5 for control, lin, chain, hybrids; 2 for Arm A and the forms; the image title states n folds). Use "folds 0–1 pooled" to compare any arm with the control on the same stars: grid-cell noise falls as √(number of stars), so a 5-fold grid looks cleaner than a 2-fold grid even at equal model quality. Single folds are available for control, lin and chain. Fixed colour scales for every arm: absolute ±30e-4, relative ±20e-4, arm − control ±10e-4 (cell titles Δcxx/Δcyy, 1e-3 px²), stacks ±8e-4. Combinations that do not exist are greyed out. The forms cover only F1/F2/C4 folds 0–1, the chain only F1/C4, Arm A (run3_rf5) only F1/F2/C4. "CPU control" = matched C4 CPU control. Injection fits have no held-out evaluation (table above).

residual grid

Bugs found and fixed in this campaign

  • A test of the new aniso form passed only when the worktree was on PYTHONPATH: the editable install imports the live checkout. Every job now pins PYTHONPATH to the branch pin, and the launcher asserts the import path.
  • My pkill -f inject_submit.sh matched the shell running it and killed that command. The watcher was stopped by pid instead.
  • Per-star width regression (test 3, first version) gave near-zero negative slopes: single-star residual rasters are noise- and NaN-dominated. It was replaced by stacks per q bin.
  • Earlier (10-10, Arm A): the scorer gave held-out stars q = 0. Fixed in bwidth-rf5 f6364402, which is in this branch.

Compute

54 + 30 + 25 + 8 Condor jobs. 12 chain fits on Colab T4: 6 sessions, never more than 2 at once, all self-stopped. `colab sessions` is empty and usage 0.00/hr; ≈ 9 CU. GPU landing: hold the Condor fold job, install the verified GPU fit, release; the job then only evaluates.

Records

/astro/armin/koji/syndiff/dev_runs/bwidth_campaign_20261012/README.md (log, all numbers), eval/*.json, figs/, explorer/; residual-grid canvas tabs bwchain_* / run4ctrl_*; Colab RUN_CATALOG entries bwcamp-*.

SUPERSEDED 10-13 by §12 (decision revised; "removes most of the excess" was wrong, it removes about half). Conclusion (PRELIMINARY, 2026-10-12). The brightness term is real, recoverable and helps. The control's own residual stacks show a positive width-vs-charge slope in every quadrant of all five fields. Trained with the ePSF it removes most of the bright-star excess, lowers bright held-out χ² by 1.2% bin-averaged (more through the full chain), and slightly improves faint stars, because the ePSF stops compromising toward the bright stars. It changes photometry by under 1 mmag and apertures by under 0.4 ppt. Open: the trained b's field-to-field spread (0.4–1.4 ×10⁻³) is not detector-driven (the control slopes are uniform), and S22 does not reproduce fold to fold. A per-field trained b is therefore partly an optimisation outcome rather than a physical constant. The pre-registered pooled-median gate fails and stays reported. Recommendation pending the final round.

12 · Decision revised (user, 2026-10-13): report the effect, the term goes to an appendix

Decision. The adopted Paper 1 model is run4 without the brightness term. The main text (§5.3, Fig. 14) reports the effect as an observation; the linear term is Appendix D (Fig. D1). Recorded in MODEL_FREEZE.md "D9 REVISED" (dev 646b527). The term chains keep running to complete the appendix record; the S22 all-star fit has finished ($b=0.38\times10^{-3}$).

Width measurement. Stacks of $R=(\text{data}-\text{model})/f$ are fitted inside $r<3.5$ px with $R\simeq a_0P+a_x\partial_xP+a_y\partial_yP+c_{xx}\partial_x^2P+c_{yy}\partial_y^2P+c_{xy}\partial_x\partial_yP+a_1$. Here $P$ is the median unit-flux model of the field's $T\ge10$ stars; $a_0$, $a_x$, $a_y$ and $a_1$ are the flux, centroid and background offsets; and $c=\tfrac12(c_{xx}+c_{yy})$. The extra Gaussian variance per axis is $\Delta\Sigma=c/0.59$. The factor 0.59 is a calibration: an exact Gaussian blur of known variance pushed through the same fit (0.586–0.592 in every field). $q$ is the peak charge per 2-s read, $q=2\,\mathrm{s}\times f\times\phi$, with $f$ the fitted flux (e⁻ s⁻¹) and $\phi$ the model's peak-pixel fraction.

Fig 14
Paper Fig. 14 (main text): the observation, adopted model only, held-out stars, 5 fields × 5 folds. (a) The excess $\Delta\Sigma$ over each field's faint stars grows linearly with $q$: pooled slope $(1.33\pm0.06)\times10^{-3}$ px² per $10^4$ e⁻ ($\chi^2$ 1.4/6), per field 1.05–1.65. (b) The $T$8–9 minus $T$12–13 difference has the profile of a pure Gaussian broadening ($\Delta\Sigma\approx2.9\times10^{-3}$). (c) Pixel phase: centred 5.2 ± 0.6, intermediate 3.3 ± 0.3, corner 2.0 ± 0.3 ($10^{-3}$ px²), the ordering expected if the charge in a pixel drives the broadening. (d) The stacks themselves on one scale: a deep bright-star core deficit with a ring, and a nearly empty faint stack with a weak central excess (the ePSF is the brightness average). (e) All 9 detector cells are positive (1.7–5.5), largest at high rows; the origin of that variation is not established.
Fig D1
Paper Fig. D1 (Appendix D): the linear term we tried, on the same held-out stars. (a) The term halves the slope (1.34 → 0.72) and removes 51 % of the excess at $q>1.2\times10^4$. (b) What remains is still a Gaussian broadening at half the amplitude (core ratio 1.03 with and without the term), so the term has the right form but too small an amplitude. (c) The trained $b$ is below the model-free slope in every field. (d) The $T$8–9 core deficit is reduced, not removed. (e) Held-out $\chi^2$: −1.2 % at $T$8–10.5, −0.15 % faint, +0.10 % at $T$9.5–10.5; the pre-registered gate fails.

Two corrections to earlier sections.

Conclusion (2026-10-13). The effect is robust: a brighter–fatter-type broadening linear in peak charge per read, seen in all fields and detector cells, stronger for pixel-centred stars, about $1.3\times10^{-3}$ px² per $10^4$ e⁻. Our model of it is not robust: the trained linear term captures half, its coefficient differs between fields, and it failed its gate. Leaving it out costs about 1 % bright-star $\chi^2$ and under 1 mmag of photometry. Paper: observation in the main text, term in the appendix. The investigation continues off the paper's critical path, starting with the amplitude question.

Conclusion

Current conclusion: §12 (2026-10-13). The paragraph below is the 10-07 conclusion, kept for the record; its "narrower than a blur" reading is superseded by §12.

The best current fits leave a brightness-dependent PSF width that is significant, repeated on two fields, present in held-out stars and in every colour slice, and shaped like charge spreading from the brightest pixel. It starts near $q\approx10^4$ e⁻ per read (T≈10). Expressed as the existing linear law, it implies $b\approx0.5$–$1.2\times10^{-3}$ px² per $10^4$ e⁻, consistent with the independent 09-30 value of 0.8. Confidence in the effect is high. The exact size, and whether one global $b$ fits both CCDs, is uncertain, because the bright end rests on tens of stars per bin and held-out stars cannot measure the slope. Modelling neighbours removed a spurious faint-end part of about 0.4e-3 px², so earlier magnitude-trend numbers that ignored neighbours overstate the effect. The width-term fit (§2b) captures the ring and the sign but only about half of the bright stars’ central-pixel deficit, which is narrower than a blur of the PSF. So the existing bright_width blur is expected to be necessary but not sufficient, and a pixel-scale charge-redistribution term should be tested alongside it. A term linear in magnitude cannot be ruled out on the binned curve, but it is the wrong variable (§6). Next step: the test in §5, arms B–F.

Limits: fold 0 only. The residual stacks use fitted fluxes as the denominator, which affects the absolute level but not the width terms. The width estimator uses the bin's median model and is linear in small perturbations; 1e-3 px² is about 0.1% of the PSF's second moment.

Records