@@ -380,16 +380,13 @@ def compile_results(self, results):
380380 Compiled results ready to be written to a file.
381381
382382 Two PSF column families — each carrying ellipticity *and* size,
383- for *different* PSFs (shapepipe#749):
383+ for *different* PSFs (shapepipe#749). See the function docstrings
384+ for what each family IS:
384385
385- * ``*_psf_orig`` (``g1``/``g2`` + ``*_err``, ``T``) — the
386- ORIGINAL image PSF (the psfex/mccd model stamp), fit before
387- metacal reconvolution by :func:`average_original_psf`. This is
388- the PSF whose true ellipticity and size enter object-wise
389- PSF-leakage diagnostics.
390- * ``*_psf_reconv`` — the metacal RECONVOLUTION kernel (round and
391- enlarged by construction, used for the Tgal/Tpsf size cut and a
392- g~0 sanity check), fit by :func:`average_multiepoch_psf`.
386+ * ``*_psf_orig`` (``g1``/``g2`` + ``*_err``, ``T``) — the original
387+ image PSF, fit by :func:`average_original_psf`.
388+ * ``*_psf_reconv`` — the metacal reconvolution kernel, fit by
389+ :func:`average_multiepoch_psf`.
393390
394391 Raises
395392 ------
@@ -1232,23 +1229,18 @@ def average_original_psf(gal_obs_list, psf_runner):
12321229 """Fit and average the *original* image PSF over epochs.
12331230
12341231 The original PSF is the psfex/mccd model stamp handed to ngmix
1235- (``gal_obs.psf``), fit here with the same ``psf_runner`` machinery — and
1236- so the same ``psf_fit_prior`` — used inside metacal, but on the PSF
1237- *before* metacal's reconvolution. Exported to the original-PSF columns
1232+ (``gal_obs.psf``), fit here with the same ``psf_runner`` (hence the same
1233+ fit prior and guesser) used inside metacal, but on the PSF *before*
1234+ metacal's reconvolution. Exported to the original-PSF columns
12381235 (``NGMIX_G1/G2_PSF_ORIG``, ``NGMIX_T_PSF_ORIG``). Distinct from the
12391236 reconvolution-kernel fit (:func:`average_multiepoch_psf`): the original
12401237 PSF retains its true ellipticity and size, whereas the reconvolution
12411238 kernel is round and enlarged by construction. This is the PSF whose true
12421239 shape and size enter object-wise PSF-leakage diagnostics.
12431240
1244- Epochs are weighted by the *galaxy* inverse-variance weight
1245- (``gal_obs.weight.sum()``). This is the same *form* as
1246- :func:`average_multiepoch_psf` (``weight.sum()`` per epoch, skipping
1247- ``flags != 0`` fits) but not the identical weight: the reconvolution path
1248- weights by the fixnoise-combined inverse variance of the noshear metacal
1249- image, whereas this path uses the raw galaxy inverse variance. So the two
1250- PSF families share an averaging *scheme* and differ in which PSF is fit
1251- and in the precise per-epoch weighting factor.
1241+ Weighted by the raw galaxy inverse variance (``gal_obs.weight.sum()`` per
1242+ epoch); :func:`average_multiepoch_psf` uses the same scheme but the
1243+ fixnoise-combined metacal-image weight instead.
12521244
12531245 The fit runs on a *copy* of each PSF observation so ``gal_obs.psf`` —
12541246 the object metacal later deep-copies and consumes via
@@ -1258,8 +1250,11 @@ def average_original_psf(gal_obs_list, psf_runner):
12581250 would survive metacal's deep copy and be reused as the
12591251 ``MetacalFitGaussPSF`` fallback when its own admom+ML PSF fits both fail,
12601252 silently rescuing objects the base branch dropped (``BootPSFFailure``) and
1261- changing the galaxy/shear result set. Fitting a copy keeps this add-column
1262- refactor bit-identical on the galaxy results.
1253+ changing the galaxy/shear result set. Fitting a copy closes this
1254+ PSF-aliasing channel; combined with :func:`do_ngmix_metacal` seeding this
1255+ pre-fit from a *snapshot* of the metacal RNG (so the pre-fit does not
1256+ advance it), the add-column refactor stays bit-identical on the galaxy
1257+ results.
12631258
12641259 Parameters
12651260 ----------
@@ -1268,19 +1263,17 @@ def average_original_psf(gal_obs_list, psf_runner):
12681263 (pre-metacal) PSF observation to fit, with no further ``.psf`` of
12691264 its own so the runner fits the stamp itself. Left pristine.
12701265 psf_runner : ngmix.runners.PSFRunner
1271- The module's PSF runner, carrying the resolved ``psf_fit_prior``.
1266+ The module's PSF runner (built by :func:`make_runners` from the
1267+ shared ``prior``).
12721268
12731269 Returns
12741270 -------
12751271 dict
12761272 Same keys as :func:`average_multiepoch_psf`.
12771273 """
12781274 def fit (gal_obs ):
1279- # Fit a COPY of the PSF observation: PSFRunner.go fits the PSF stamp
1280- # and sets its .meta['result'] (and .gmix on success). Reading from
1281- # the copy leaves gal_obs.psf pristine — no gmix to leak through
1282- # metacal's deep copy into the MetacalFitGaussPSF fallback. Failed
1283- # fits keep flags != 0 and are dropped by _average_psf_fits.
1275+ # Fit a COPY so gal_obs.psf stays pristine for metacal — see docstring.
1276+ # Failed fits keep flags != 0 and are dropped by _average_psf_fits.
12841277 psf_obs = gal_obs .psf .copy ()
12851278 psf_runner .go (psf_obs )
12861279 return psf_obs .meta ['result' ], gal_obs .weight .sum ()
@@ -1379,14 +1372,15 @@ def do_ngmix_metacal(stamp, prior, flux_guess, rng, centroid_source="hsm"):
13791372
13801373 runner , psf_runner = make_runners (prior , flux_guess , rng )
13811374
1382- # Fit the ORIGINAL (psfex/mccd) PSF before metacal reconvolves it, using
1383- # the same psf_runner (so the same psf_fit_prior and centroid). This is
1384- # the PSF_ORIG family; metacal below produces the PSF_RECONV family. Run
1385- # first so the original PSF is fit on its own stamp, distinct from the
1386- # round, enlarged kernel metacal convolves back in. average_original_psf
1387- # fits a COPY of each gal_obs.psf, so gal_obs_list reaches boot.go below
1388- # pristine — no stray gmix to leak into MetacalFitGaussPSF's fallback.
1389- psf_orig_res = average_original_psf (gal_obs_list , psf_runner )
1375+ # Fit the ORIGINAL (psfex/mccd) PSF before metacal reconvolves it. Use a
1376+ # psf_runner seeded from a snapshot of rng's state so this prefit does NOT
1377+ # advance the rng that boot.go consumes below — keeping the galaxy/shear
1378+ # results bit-identical to the no-prefit branch. average_original_psf fits a
1379+ # COPY of each gal_obs.psf, so gal_obs_list also reaches boot.go pristine.
1380+ prefit_rng = np .random .RandomState ()
1381+ prefit_rng .set_state (rng .get_state ())
1382+ _ , prefit_psf_runner = make_runners (prior , flux_guess , prefit_rng )
1383+ psf_orig_res = average_original_psf (gal_obs_list , prefit_psf_runner )
13901384
13911385 metacal_pars = {
13921386 'types' : ['noshear' , '1p' , '1m' , '2p' , '2m' ],
0 commit comments