Skip to content

Mlarson/extended sources rewrite - #7

Open
mjlarson wants to merge 4 commits into
mainfrom
mlarson/extended_sources_rewrite
Open

Mlarson/extended sources rewrite#7
mjlarson wants to merge 4 commits into
mainfrom
mlarson/extended_sources_rewrite

Conversation

@mjlarson

@mjlarson mjlarson commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Bit of a rewrite to handle extended sources in the normal KingSpatialLikelihood class

Copilot AI lite review requested due to automatic review settings September 3, 2026 16:44
@mjlarson mjlarson linked an issue Sep 3, 2026 that may be closed by this pull request
@codecov-commenter

codecov-commenter commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 63.11475% with 45 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.77%. Comparing base (3a78cb4) to head (652ac0b).

Files with missing lines Patch % Lines
kingmaker/wrapper.py 9.75% 37 Missing ⚠️
kingmaker/fitting.py 87.69% 8 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main       #7      +/-   ##
==========================================
+ Coverage   53.46%   58.77%   +5.30%     
==========================================
  Files           6        6              
  Lines         937      900      -37     
==========================================
+ Hits          501      529      +28     
+ Misses        436      371      -65     
Flag Coverage Δ
test_basic 14.88% <8.19%> (+0.16%) ⬆️
test_fitting 35.66% <62.29%> (+4.28%) ⬆️
test_king_pdf 28.77% <8.19%> (+0.70%) ⬆️
test_template_smeared_king_pdf 26.44% <8.19%> (+0.61%) ⬆️
test_utils 16.33% <18.85%> (+1.60%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

There are correctness and robustness issues in the wrapper’s source-caching/validation logic (notably extension-aware cache invalidation and input validation) plus a breaking API removal that leaves in-repo examples outdated.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR refactors Kingmaker’s spatial likelihood pipeline to support extended sources by incorporating an explicit extension_grid axis into fitted PSF parameter grids and enabling per-source extension selection (nearest-snapped) during PDF evaluation.

Changes:

  • Extend KingPSFFitter outputs to shape (n_extension, n_gamma, *bins) by fitting across an extension_grid, using Rayleigh smearing of true positions.
  • Update KingSpatialLikelihood to load/store extension_grid, select per-source extension indices, and evaluate both standard and RA-marginalized PDFs with extension-aware parameter lookup.
  • Add sample_with_extension() utility + tests; expand wrapper/fitter tests for extension behavior; remove ExtendedSourceKingPDF implementation and its dedicated test module.
File summaries
File Description
tests/test_wrapper.py Updates wrapper tests for extension-aware alpha/beta grids; adds new tests for nearest extension selection and per-source extensions.
tests/test_utils.py Adds unit tests for new sample_with_extension() utility.
tests/test_fitting.py Updates fitter tests for new (n_extension, ...) parameter shapes; adds extension grid behavioral tests.
tests/test_extended_source_king_pdf.py Removes tests for ExtendedSourceKingPDF (class removed).
kingmaker/wrapper.py Adds source_extensions support, loads/validates extension_grid, and makes PDF caching/evaluation extension-aware.
kingmaker/utils.py Introduces sample_with_extension() for Rayleigh source-extension sampling.
kingmaker/pdf.py Removes ExtendedSourceKingPDF implementation and related imports.
kingmaker/fitting.py Extends fitting loop to include extension_grid and uses sample_with_extension() to smear truth positions during fitting.
docs/examples.rst Updates documentation to reflect the new extension axis in fitted results and tweaks likelihood example.
Review details

Suppressed comments (2)

docs/examples.rst:153

  • The example now documents alpha_fit as having an extension axis, but the subsequent get_interpolator()/plot_fit calls omit extension_index. This can confuse readers who provide an extension_grid with multiple entries and wonder why only the point-source slice is used.
   # Continuous evaluation between bin centers:
   alpha_interp, beta_interp = fitter.get_interpolator(gamma_index=0)
   point = np.array([[3.5, np.arcsin(0.0)]])  # [logE, dec]
   alpha_value = alpha_interp(point)

   # Inspect a single bin's fit against its histogram:
   ax = fitter.plot_fit(bin_indices=(2, 2), gamma_index=0)

kingmaker/wrapper.py:309

  • set_events accepts source_extensions but does not validate that the radii are finite and non-negative. Negative/NaN values will silently snap to the nearest extension_grid entry, masking upstream data issues and producing incorrect likelihood values.
        self.source_extensions = (
            np.zeros(len(source_ras))
            if source_extensions is None
            else np.asarray(source_extensions, dtype=np.float64)
        )
  • Files reviewed: 9/9 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread kingmaker/wrapper.py
Comment on lines +223 to +226
if source_extensions is not None and not np.array_equal(
self.source_extensions, source_extensions
):
return False
Comment thread kingmaker/pdf.py
Comment thread kingmaker/wrapper.py
Comment on lines +142 to +155
# Extension grid (bin-center-style values, nearest-snapped per source).
if "extension_grid" not in fitted_parameters:
raise ValueError(f"Cache {cache_name!r} has no extension_grid. Delete it and refit.")
self.extension_grid = np.sort(np.atleast_1d(fitted_parameters["extension_grid"]))

# And grab the fitted alpha/beta arrays, shape (n_extension, n_gamma, *bins).
self.alpha_values = fitted_parameters["alpha"]
self.beta_values = fitted_parameters["beta"]
expected_ndim = 2 + len(self.parametrization_bins)
if self.alpha_values.ndim != expected_ndim or self.beta_values.ndim != expected_ndim:
raise ValueError(
f"Cached alpha/beta have {self.alpha_values.ndim} dimensions, expected "
f"{expected_ndim} (extension, gamma, *bins). Delete {cache_name!r} and refit."
)
Comment thread kingmaker/wrapper.py
Comment on lines +262 to +265
source_extensions : ndarray, optional
Source extension radii in radians, nearest-snapped to the fitted
``extension_grid``. Defaults to zero (point source) for every
source.
Copilot AI review requested due to automatic review settings September 3, 2026 19:06
@mjlarson
mjlarson force-pushed the mlarson/extended_sources_rewrite branch from effbd81 to 652ac0b Compare September 3, 2026 19:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

There are confirmed correctness issues in the new extension-aware caching and interpolator defaults, plus an example notebook still references the removed ExtendedSourceKingPDF API.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details

Suppressed comments (3)

kingmaker/pdf.py:7

  • ExtendedSourceKingPDF has been removed from kingmaker.pdf, but the repository still contains examples/extended_source_demo.ipynb importing and documenting it. As-is, that notebook will break for users and in any documentation build/test that executes it.
from scipy.special import legendre_p_all, sph_harm_y_all

kingmaker/fitting.py:602

  • fill_value indexes fit_beta with gamma_index only, but fit_beta is now shaped (n_extension, n_gamma, *bins). This can raise IndexError when n_extension == 1 and gamma_index > 0, and it also uses the wrong slice for non-default extension_index.
            fill_value=self.fit_beta[gamma_index].mean(),

kingmaker/wrapper.py:226

  • _sources_match only compares source_extensions when the caller passes a non-None array. If a previous set_events call used explicit non-zero extensions and a later call passes source_extensions=None (meaning “default to zeros”), this method can incorrectly treat the sources as unchanged and reuse stale cached matrices.
        if source_extensions is not None and not np.array_equal(
            self.source_extensions, source_extensions
        ):
            return False
  • Files reviewed: 9/9 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread kingmaker/fitting.py
self.fit_alpha[extension_index, gamma_index],
method="linear",
bounds_error=False,
fill_value=self.fit_alpha[gamma_index].mean(),
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement extended sources

3 participants