Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH add moment weight sums to output #219

Merged
merged 17 commits into from
Jul 21, 2022
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
## v2.1.0

### bug fixes

- Fixed 1/area normalization for all moments fields in `GaussMom` results.

beckermr marked this conversation as resolved.
Show resolved Hide resolved
### new features

- Added `fwhm_smooth` keyword to pre-PSF moments routines to allow for extra
smoothing of the profile before the moments are measured.
- Added caching of FFTs in metacal and pre-PSF moment rountines.
- Added moments weight function normalization.


## v2.0.6
Expand Down
5 changes: 4 additions & 1 deletion mdet_tests/test_mdet_regression.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,10 @@ def test_mdet_regression(fname, write=False):
else:
old_data = fitsio.read(fname)
for col in old_data.dtype.names:
if ('psf_' in col or 'ratio' in col) and '1.3.9' in fname:
if (
('psf_' in col or 'ratio' in col)
and ('1.3.9' in fname or '2.0' in fname)
):
rtol = 1.0e-4
atol = 1.0e-4
else:
Expand Down
5 changes: 5 additions & 0 deletions ngmix/gaussmom.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ def _measure_moments(self, obs):
res['flux'] *= fac
res['flux_err'] *= fac
res['pars'][5] *= fac
res["sums"] *= fac
res["sums_cov"] *= fac**2
res["sums_norm"] *= fac
res["wsum"] *= fac
res["sums_err"] *= fac
return res

def _set_mompars(self):
Expand Down
6 changes: 2 additions & 4 deletions ngmix/gmix/gmix.py
Original file line number Diff line number Diff line change
Expand Up @@ -1239,15 +1239,13 @@ def get_weighted_moments_stats(ares):

res = {}
for n in ares.dtype.names:
if n == "sums":
res[n] = ares[n].copy()
elif n == "sums_cov":
if n in ["sums", "sums_cov"]:
res[n] = ares[n].copy()
else:
res[n] = ares[n]

res.update(
moments.make_mom_result(res["sums"], res["sums_cov"])
moments.make_mom_result(res["sums"].copy(), res["sums_cov"].copy(), res["wsum"])
)

return res
Expand Down
84 changes: 44 additions & 40 deletions ngmix/moments.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,28 +349,31 @@ def g2mom(g1, g2, T):
return Irr, Irc, Icc


def make_mom_result(mom, mom_cov):
"""Make a fitting results dict from a set of moments.
def make_mom_result(sums, sums_cov, sums_norm=None):
"""Make a fitting results dict from a set of unnormalized moments.

Parameters
----------
mom : np.ndarray
The array of moments in the order [Mv, Mu, M1, M2, MT, MF].
mom_cov : np.ndarray
The array of moment covariances.
sums : np.ndarray
The array of unnormalized moments in the order [Mv, Mu, M1, M2, MT, MF].
sums_cov : np.ndarray
The array of unnormalized moment covariances.
sums_norm : float, optional
The sum of the moment weight function itself. This is added to the output data.
The default of None puts in NaN.

Returns
-------
res : dict
A dictionary of results.
"""
# for safety...
if len(mom) != 6:
if len(sums) != 6:
raise ValueError(
"You must pass exactly 6 moments in the order [Mv, Mu, M1, M2, MT, MF] "
"for ngmix.moments.make_mom_result."
"You must pass exactly 6 unnormalized moments in the order "
"[Mv, Mu, M1, M2, MT, MF] for ngmix.moments.make_mom_result."
)
if mom_cov.shape != (6, 6):
if sums_cov.shape != (6, 6):
raise ValueError(
"You must pass a 6x6 matrix for ngmix.moments.make_mom_result."
)
Expand All @@ -386,9 +389,10 @@ def make_mom_result(mom, mom_cov):
res = {}
res["flags"] = 0
res["flagstr"] = ""
res["flux"] = mom[mf_ind]
res["mom"] = mom
res["mom_cov"] = mom_cov
res["flux"] = sums[mf_ind]
res["sums"] = sums
res["sums_cov"] = sums_cov
res["sums_norm"] = sums_norm if sums_norm is not None else np.nan
res["flux_flags"] = 0
res["flux_flagstr"] = ""
res["T_flags"] = 0
Expand All @@ -404,25 +408,25 @@ def make_mom_result(mom, mom_cov):
res["e"] = np.array([np.nan, np.nan])
res["e_err"] = np.array([np.nan, np.nan])
res["e_cov"] = np.diag([np.nan, np.nan])
res["mom_err"] = np.array([np.nan, np.nan, np.nan, np.nan, np.nan, np.nan])
res["sums_err"] = np.array([np.nan, np.nan, np.nan, np.nan, np.nan, np.nan])

# handle flux-only
if mom_cov[mf_ind, mf_ind] > 0:
res["flux_err"] = np.sqrt(mom_cov[mf_ind, mf_ind])
if sums_cov[mf_ind, mf_ind] > 0:
res["flux_err"] = np.sqrt(sums_cov[mf_ind, mf_ind])
res["s2n"] = res["flux"] / res["flux_err"]
else:
res["flux_flags"] |= ngmix.flags.NONPOS_VAR

# handle flux+T only
if mom_cov[mf_ind, mf_ind] > 0 and mom_cov[mt_ind, mt_ind] > 0:
if mom[mf_ind] > 0:
res["T"] = mom[mt_ind] / mom[mf_ind]
if sums_cov[mf_ind, mf_ind] > 0 and sums_cov[mt_ind, mt_ind] > 0:
if sums[mf_ind] > 0:
res["T"] = sums[mt_ind] / sums[mf_ind]
res["T_err"] = get_ratio_error(
mom[mt_ind],
mom[mf_ind],
mom_cov[mt_ind, mt_ind],
mom_cov[mf_ind, mf_ind],
mom_cov[mt_ind, mf_ind],
sums[mt_ind],
sums[mf_ind],
sums_cov[mt_ind, mt_ind],
sums_cov[mf_ind, mf_ind],
sums_cov[mt_ind, mf_ind],
)
else:
# flux <= 0.0
Expand All @@ -431,21 +435,21 @@ def make_mom_result(mom, mom_cov):
res["T_flags"] |= ngmix.flags.NONPOS_VAR

# now handle full flags
if np.all(np.diagonal(mom_cov) > 0):
res["mom_err"] = np.sqrt(np.diagonal(mom_cov))
if np.all(np.diagonal(sums_cov) > 0):
res["sums_err"] = np.sqrt(np.diagonal(sums_cov))
else:
res["flags"] |= ngmix.flags.NONPOS_VAR

if res["flags"] == 0:
if res["flux"] > 0:
if res["T"] > 0:
res["e1"] = mom[m1_ind] / mom[mt_ind]
res["e2"] = mom[m2_ind] / mom[mt_ind]
res["e1"] = sums[m1_ind] / sums[mt_ind]
res["e2"] = sums[m2_ind] / sums[mt_ind]
res["e"] = np.array([res["e1"], res["e2"]])

res["pars"] = np.array([
mom[mv_ind],
mom[mu_ind],
sums[mv_ind],
sums[mu_ind],
res["e1"],
res["e2"],
res["T"],
Expand All @@ -454,18 +458,18 @@ def make_mom_result(mom, mom_cov):

e_err = np.zeros(2)
e_err[0] = get_ratio_error(
mom[m1_ind],
mom[mt_ind],
mom_cov[m1_ind, m1_ind],
mom_cov[mt_ind, mt_ind],
mom_cov[m1_ind, mt_ind],
sums[m1_ind],
sums[mt_ind],
sums_cov[m1_ind, m1_ind],
sums_cov[mt_ind, mt_ind],
sums_cov[m1_ind, mt_ind],
)
e_err[1] = get_ratio_error(
mom[m2_ind],
mom[mt_ind],
mom_cov[m2_ind, m2_ind],
mom_cov[mt_ind, mt_ind],
mom_cov[m2_ind, mt_ind]
sums[m2_ind],
sums[mt_ind],
sums_cov[m2_ind, m2_ind],
sums_cov[mt_ind, mt_ind],
sums_cov[m2_ind, mt_ind]
)
if np.all(np.isfinite(e_err)):
res["e_err"] = e_err
Expand Down
9 changes: 6 additions & 3 deletions ngmix/prepsfmom.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,11 @@ def _meas(self, obs, psf_obs, return_kernels):
tot_var = np.sum(1.0 / obs.weight[msk])

# run the actual measurements and return
mom, mom_cov = _measure_moments_fft(
mom, mom_cov, mom_norm = _measure_moments_fft(
kim, kpsf_im, tot_var, eff_pad_factor, kernels,
im_row - psf_im_row, im_col - psf_im_col,
)
res = make_mom_result(mom, mom_cov)
res = make_mom_result(mom, mom_cov, sums_norm=mom_norm)
if res['flags'] != 0:
logger.debug("pre-psf moments failed: %s" % res['flagstr'])

Expand Down Expand Up @@ -291,6 +291,7 @@ def _measure_moments_fft(
fkp = kernels["fkp"]
fkc = kernels["fkc"]

mom_norm = kernels["fk00"]
mf = np.sum((kim * fkf).real) * df2
mr = np.sum((kim * fkr).real) * df2
mp = np.sum((kim * fkp).real) * df2
Expand Down Expand Up @@ -324,7 +325,7 @@ def _measure_moments_fft(

mom = np.array([np.nan, np.nan, mp, mc, mr, mf])

return mom, m_cov
return mom, m_cov, mom_norm


@njit
Expand Down Expand Up @@ -580,6 +581,7 @@ def _ksigma_kernels(
fkc=fkc,
msk=msk,
nrm=nrm,
fk00=knrm,
)


Expand Down Expand Up @@ -679,6 +681,7 @@ def _gauss_kernels(
fkc=fkc,
msk=msk,
nrm=nrm,
fk00=knrm,
)


Expand Down
Loading