epsf_atlas_20261001 · first results · 2026-10-01 16:20 EDT
TESS ePSF Atlas
How the effective PSF of a single raw TESS FFI depends on detector position, star colour and brightness, measured without a trained model, and what that implies for the ePSF/WCS fit.
Fields: F1 S24 C2K2 · F2 S20 C3K3 · C4 S23 C4K2 (paper-dataset frames) · raw calibrated SPOC FFI, one frame each · hp_d = final method-A bootstrap (F2, C4)
Where things stand
Spatial shape validated
The PSF changes strongly and smoothly across the CCD: sharpest next to the optical axis (peak pixel fraction 0.36) and broadest at the far corner (0.18). It is elongated radially everywhere, plus a detector-frame anisotropy that rotates across the CCD.
Colour slopes validated
Red light lands radially outward of blue light (lateral colour), and red stars are sharper. Both are close to linear in colour. No colour-dependent elongation, and the colour effect is the same for bright and faint stars.
Brightness not measured yet
Single-frame stacks are too noisy at the bright end and their brightness slope fails the synthetic null. The main estimator (cross-fitted AK ePSF) will measure it once its validation gate passes.
hp_d vs raw footprint deficit
Shape, elongation and colour slopes agree between raw and hp_d. hp_d has extra light locked to the star positions. The real part is a deficit in the template inside each removed T<13 star's PS1 footprint (≲ 1–2 px). Everything under the footprint is zeroed, so hp_d gets back 0.3–3 % of the star's flux. The rest of the published feature (2–5 px) was a selection effect of my isolation cut. ks_b and the kernel are not responsible.
Method
Stars are stacked into a finely sampled empirical PSF per bin, aligned on their Gaia positions through a per-frame WCS refit (no per-star centre fit, so alignment noise does not depend on brightness). Each star is normalised by its flux inside 3.5 px, background is a plane fitted beyond 5.5 px, every star has equal weight, and the stack uses a 0.25 px grid with 10 % trimmed means and star-bootstrap errors. Colour and brightness are compared inside 3×3 detector cells and then combined, so spatial variation cannot leak into them. About 3,000 stars per field (8 ≤ T ≤ 13, unsaturated, neighbour light within 4 px < 10 %).
Shape is read from Gaussian-windowed moments of each stacked PSF:
$v_p$: stacked, flux-normalised pixel value on the 0.25 px grid · $\mathbf x_p$: offset of that grid cell from the catalogue position (px) · $\bar{\mathbf x}$: windowed centroid (iterated) · $\sigma_w=1.5$ px: fixed window width · round $=(M_{xx}+M_{yy})/2$, aniso $=(M_{xx}-M_{yy})/2$, xy $=M_{xy}$, rt_el $=(M_{rr}-M_{tt})/2$ in the axis frame (r = away from the optical axis) · all in $10^{-3}$ px². Windowed moments are not the blur covariance $\Delta\Sigma$: an injected $\Delta\Sigma$ reads at ≈ 0.74× here.
Validation colour + shape passround level fails
The same pipeline was run on synthetic stamps with a realistically sharp truth PSF (central-pixel fraction 0.42 → 0.19 across the field), real positions, fluxes, neighbours and noise, and compared against stacks of the noise-free truth.
F1 synthetic null, bias per bin (noisy − truth stack). Elongation and xy moments sit on zero (green band ±0.3e-3). The round moment is biased positive by +2 to +8e-3 in every bin: unmasked faint-neighbour light (noise alone contributes 0). That bias is a level offset: the null colour slope of round is +1.3 ± 2.9e-3 per unit u and an injected colour law is recovered with gain 1.00 ± 0.02, so colour slopes are trustworthy. Brightness slopes binned in peak charge fail.
Spatial dependence
F1, 3×3 detector cells (x right, y up; optical axis just outside the top-left corner at (−56, 2099)). Left: stacked ePSF (log). Right: cell − global on one shared scale. Bottom: moment maps. Round rises from 492 (top-left) to 724 (bottom-right); peak 0.36 → 0.18, which independently reproduces the 0.39 → 0.17 node values from the bullseye study. The near-axis cells show a concentrated core; far cells are broader with diagonal elongated structure.
F1 moments vs distance from the optical axis. Round 480 → 724 monotonic; radial elongation rt_el peaks near 1,500 px (+30); detector anisotropy and xy grow outward. The absolute centroid offsets (cx, cy, cr) are window-convention offsets relative to the refit WCS, not position errors.C4, 3×3 cells (axis just outside the top-left corner). Width varies less than on F1 (458 → 519), but the cell − global images show a strong quadrupole whose orientation rotates across the CCD: aniso −52 … +30, xy −11 … −53, rt_el 25 … 65.
Colour dependence at fixed position
F1. Top rows: Δmoment vs Gaia-XP colour u, combined over cells (blue T10–13, red T8–10). Bottom rows: bluest and reddest quartile minus the group stack, rotated into the axis frame (x = away from the axis), for three distance groups. Every group shows the same radial dipole: blue light toward the axis, red light away from it. Round falls with u (red sharper).
F2. Same pattern. Detector-frame cx/cy signs differ from F1 because F2's axis lies up-right of its CCD (F1: up-left); in the axis frame both say red is outward.C4. Same radial dipole; round vs u is smooth and nearly linear over u 0.5 → 1.65.
Slope per unit u
F1
F2
C4
Unit
Δround, T10–13
−22.3 ± 3.8
−25.4 ± 2.8
−29.1 ± 3.4
1e-3 px²
Δround, T8–10
−24 ± 7
−33 ± 7
−29.3 ± 3.0
1e-3 px²
Δcr (radial centroid), T10–13
+127 ± 22
+82 ± 18
+41 ± 22
1e-3 px
Δrt_el (radial − tangential)
−14 ± 7
−4.5 ± 7.5
+0.2 ± 7.9
1e-3 px²
Δaniso / Δxy
−1.5 / +5.0 (±2)
−5.6 / −6.2 (±1.7)
+0.9 / −1.3 (±1.9)
1e-3 px²
The bluest-to-reddest span of u in these samples is about 0.6, so the radial colour shift between blue and red stars is ≈ 25–75 mpx and the width change is ≈ 15–20e-3 windowed px².
Brightness dependence inconclusive
F1, Δmoment vs T for the blue and red halves, and brightest/faintest bin − half stack images. The bright bins hold 17–76 stars and are noise-dominated; the brightness slope binned in peak charge fails the synthetic null. No brightness law is claimed from stacks.
Raw FFI vs hp_d (paired, same stars and masks)
C4. Absolute moments vs axis distance and colour slopes overlap. Bottom row: hp_d − raw stacked images show a core deficit with a positive ring in every distance group (round +4.2 ± 0.35, E1 −0.0031). Its T-slope is +4.6 ± 0.55 per mag (8σ): larger for faint stars, as an additive dip would be.F2 (glint corner x<640, y<448 excluded on both). Same core dip, larger errors. Removing faint neighbours alone would make hp_d sharper, so the dip is something added in hp_d. Cause: see the decomposition below. The "core deficit" seen here is partly produced by how the estimator normalises the stacks.
Where the hp_d − raw feature comes from
The difference image is built exactly as
$$d = S - b_{ks} - c,$$
where $d$ is hp_d (e-/s), $S$ is the raw calibrated FFI (e-/s), $b_{ks}$ is the method-A background ks_b (e-/s), and $c$ is hp_c, the template convolved with the Hotpants kernel (e-/s). Hotpants also fits a constant offset (0.16 e-/s on C4, 0.10 on F2), which the plane fit removes. On the full 2048² images the residual of this identity has rms 5e-5 e-/s. Therefore $d - S = -b_{ks} - c$ exactly, with no third term.
Each term is stacked on the same stars with a common mask and normalised by the raw flux. A control stack at star-free positions 20–30 px away is subtracted, which removes the bias of the plane fit. All errors come from 200 paired bootstrap resamples.
C4
F2
Total Δround, control-corrected (1e-3 px²)
+9.14 ± 0.55
+13.85 ± 0.91
from the template term −hp_c
+8.08 ± 0.45 (88 %)
+13.84 ± 0.86 (100 %)
from the background term −ks_b
−0.37 ± 0.02 (−4 %)
−0.73 ± 0.05 (−5 %)
T-slope of total (hp_c alone), per mag
+11.0 ± 0.7 (+9.6 ± 0.7)
+14.0 ± 1.4 (+13.2 ± 1.2)
hp_c hole at the core (e-/s)
−3.55 ± 0.21
−1.87 ± 0.16
C4 decomposition, with all images on one colour scale.
Row 1: the published hp_d − raw splits into four pieces. Two large pieces (plane-fit pixel set and content) cancel. The flux-normalisation piece produces the whole central "deficit".
Row 2: the content equals −hp_c. The −ks_b image is blank, and both closure images are near zero.
Row 3: the control-corrected total is a broad positive bump, carried by −hp_c.
Bottom row, second panel: the absolute hp_c profile is a hole of about −3.5 e-/s that fills in by r ≈ 5–6 px and is roughly the same for every T bin. The fourth panel shows the plane-fit bias at star-free positions: +0.8 to +1.0 e-/s on raw.F2 decomposition. Same pattern: −hp_c carries 100 % of the control-corrected feature, and ks_b contributes nothing. The hp_c hole is shallower (−1.9 e-/s) and also reaches about 5–6 px. In both fields the method-A and pad-2 ks_b give the same result (last panel).
Conclusion (revised 10-01 evening after the PS1 check below). The hp_d − raw feature has two parts. (1) A real template deficit inside each removed star's PS1 footprint, r ≲ 1.2 TESS px for T 11–13 and ≲ 2 px for T<11: everything under the footprint is zeroed, including the faint-source light that the template keeps everywhere else. (2) A selection effect of my own isolation cut (cont4 < 0.1) at r ≈ 2–5 px. That part is not a pipeline problem. My earlier statements, that the hole reaches 6–7 px and scales with the local template level, came from mixing the two and are withdrawn.
Back to the PS1 skycells (8 C4 cells, recipe e17a198a)
Method. I0: each cell rebuilt from the streamed raw PS1 r, i, z, y bands with the pinned code (648c0bc) and D13 weights.
Ibk: I0 with every non-segment pixel set to 0, using the identical SEP call.
I1: the published cell from which the template is built.
Wherever I1 ≠ 0 it equals Ibk exactly (max difference 0 in all 8 cells), so the rebuild is exact.
All 296 T<13 Gaia stars in the cells were removed.
Comparison positions: 159 kept stars with 13 ≤ T < 14 that are more than 400 PS1 px from any T<13 star, and 1600 control positions more than 300 PS1 px from any T<13 star.
PS1 cells around removed stars at T = 7.5, 11.5, 12.3 and 12.9 (symlog scale). Columns: PS1 stack before zeroing, segments, published cell, and what the star removal deleted. Each star's connected footprint is deleted in full: the closed bright mask plus its halo segment, about 2.5 TESS px across at T = 7.5 and about 0.7 px at T ≈ 12.5. Faint sources inside that footprint go with it. At T = 11.5, two neighbours about 3–4.5 px away merged into the footprint and are deleted. The star's light below the detection threshold, outside the footprint, is removed by the background zeroing. Nothing is deleted beyond the footprint, so the 480-px disc is only an upper bound.Ring statistics over the 8 cells, with bootstrap errors over positions. (a) Published cell minus control. Around removed stars the cell is −0.08 to −0.09 inside about 1.2 px (T 11–13) or 2 px (T<11); the control level is 0.075–0.08 PS1 units per pixel, so 100 % of the local light is missing there. From 2 px out the cell equals the control (±0.01). Kept stars show no deficit.
(f) The star's own light (I0 excess) is all deleted, and none is left in the template.
(c) The PS1 stack itself has an over-subtracted sky ring around bright stars: −0.009 at about 5 px for T<11 and −0.0035 for T 11–13. Those are non-segment pixels, which the template sets to 0, so this ring does not reach the template.Unconvolved F=4 template (mean stack): the 2–5 px "moat" is my isolation cut. Kept T 13–14 stars, which are in the template, show a −19.7 moat at 2–4 px when the atlas cut cont4 < 0.1 is applied, and none without it (−0.08 ± 0.62).
For removed stars without the cut, the deficit is −24.9 at the core and −11.0 at 1.25 px, i.e. the template is empty there. It is down to −1.1 at 2.25 px and ≈0 beyond, the same as in PS1.
Size of the real deficit in hp_c, mean stack of all removed stars minus control, with no isolation cut:
T 8–10
T 10–11
T 11–12
T 12–13
C4 core (e-/s)
−7.9
−7.7
−7.2
−6.1
C4 missing flux, r<3 px (e-/s)
−110 ± 7 (0.42 %)
−72 ± 6 (0.84 %)
−66 ± 6 (1.9 %)
−44 ± 6 (3.2 %)
F2 missing flux, r<3 px (e-/s)
−71 ± 8 (0.27 %)
−65 ± 11 (0.74 %)
−30 ± 7 (0.85 %)
−17 ± 6 (1.2 %)
Percentages are of the median star flux, taking T = 10 as 15000 e-/s. The deficit is gone by 2–3 px. In e-/s it is larger for brighter stars, which have bigger footprints, but smaller as a fraction of their flux.
Consequences.
For hp_d: each removed star gets back the faint-source light that lay under its own footprint, +0.3 to +3 % of its flux. The percentage grows for fainter stars.
For my atlas (bug, found 10-01): the relative isolation cut cont4 < 0.1 depletes neighbour light within about 4 px, in the FFI as well as the template. Because the cut is relative to the target's flux, it is stricter for faint targets. That imprints a magnitude-dependent moat on raw-FFI stacks, which biases brightness trends. It also explains the steeper-than-1/f T-slope and the 2–5 px part of the published hp_d − raw bump. The fix is a magnitude-independent, absolute neighbour-light cut, or a correction measured from the template. Brightness results are on hold until this is done.
$E$: effective PSF at pixel offset $\delta\mathbf x$ (px) from the star's catalogue position · $\mathbf r$: detector position · $u$: Gaia-XP colour, $u_{\rm ref}=0.957$ (the scene-fit colour reference) · $P_0$: ePSF at the reference colour, position dependent (needs strong, smooth spatial freedom incl. a rotating anisotropy) · $\rho$: distance from the optical axis (px), $\hat{\boldsymbol\rho}$: unit vector away from it · $a(\rho)$: lateral-colour shift, measured +0.04 to +0.13 px per unit u (windowed centroid) · $G(\Sigma)$: Gaussian of covariance $\Sigma$; $w(\rho)$: colour width coefficient, negative (red sharper), ≈ −0.03 to −0.04 px² per unit u as $\Delta\Sigma$.
Needed: a radial colour shift linear in u, and a round colour-width term linear in u.
Not needed at this precision: colour-dependent elongation, a colour × brightness term.
Still open: the brightness width term; how $a$ and $w$ depend on $\rho$; how much of this the A3 model already contains (next: subtract A3's own colour response star by star).
Main estimator gate (V1) running on Condor
The cross-fitted Anderson–King estimator (adapted from bfwidth_20260929) measures blur covariance directly and can reach the brightness law, but its first small test runs showed two spurious trends: bright stars appearing broader (−2.0 ± 0.4e-3 px² per 1e4 e⁻, larger than the effect sought) and a width error that follows distance from the axis.
Smoke null (528 stars, K=2; not a gate result). Round error rises from −24 to +13e-3 px² with axis distance while rt_el stays flat: the position-only reference does not follow the large spatial change of the PSF. Eight full F1 runs (neighbours all/modelled/none, noise-free, bfwidth soft-PSF regression, two weaker smoothing settings, all-law injection) are on Condor; ETA about 21:00–22:00 EDT.
Astrometry: C1 header WCS
Before: raw-FFI centroids − SPOC header SIP for 2,187 Gaia stars. A coherent wedge near the optical-axis corner reaches 8.2 px in 128-px cells (up to 11.9 px at the corner).After a per-frame refit (linear TAN + degree-5 Chebyshev, Gaia propagated to the frame epoch): every cell ≤ 0.1 px, held-out rms 0.023 px. Confirmed by the paper-dataset session; C1 is being rebuilt on this WCS.
Bugs found and fixed
C1 header WCS wrong by up to 12 px near the optical-axis corner (SPOC SIP solution). Fixed with the per-frame refit above.
Isolation cut kept only 2–10 % of stars (counting any neighbour brighter than T+5 penalises faint targets). Replaced by neighbour light within 4 px < 10 %.
hp_d mask rule would have masked 74 % of pixels (bit 32 is hotpants' input mask, including the bright-star disks). Only bit 0x8000 is masked now.
Synthetic-PSF pixel integration 1 % wrong with the midpoint rule. Switched to Gauss–Legendre (3e-14).
One near-zero-flux star destabilised the stack bootstrap. Added a 0.3-mag flux-outlier cut.
The raw-vs-hp_d stack was not paired. Three problems:
The raw stack did not get the hp_d 0x8000 mask. This contributed 14–24 % of the published Δround.
hp_d was normalised by its own flux, which the template hole inflates. That normalisation alone made the core "deficit".
Each image had its own plane-fit pixel set. That choice moves Δround by −19e-3 px².
Fixed in the decomposition code: common mask, raw-flux normalisation, common pixel set, and control-position subtraction. The original stack/ comparison still needs re-running.
Open: (1) The V1 gate is being scored. (2) The template removes the faint-source light under each removed star's footprint; this is for the paper pipeline. (3) The atlas isolation cut is relative to the target's flux and so depends on magnitude; it must be replaced before any brightness result.
Records
Run record and log: /astro/armin/koji/syndiff/dev_runs/epsf_atlas_20261001/README.md (Results R1) · tables: stack/RESULTS_{F1,F2,C4}.md, stack/VALIDATION_{F1,F2}.md, stack/HPD_vs_RAW_{F2,C4}.md · astrometry: astrom/ · code: code/