Skip to content

Polynomial pointing model#28

Open
axf295 wants to merge 18 commits intomainfrom
poly_model
Open

Polynomial pointing model#28
axf295 wants to merge 18 commits intomainfrom
poly_model

Conversation

@axf295
Copy link
Copy Markdown
Contributor

@axf295 axf295 commented Apr 29, 2026

add the polynomial pointing model to mapcat

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new polynomial-based pointing residual model to Mapcat and updates persistence/tests to support storing/retrieving this new model type alongside the existing constant model.

Changes:

  • Introduces PolynomialPointingModel with coefficient fitting, prediction, and basic statistics helpers.
  • Updates PointingResidualTable.residual_model to store either a constant or polynomial model via JSON (TypeAdapter-backed deserialization).
  • Expands pointing tests to cover constant-model behavior and basic polynomial fitting/prediction.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
tests/test_pointing.py Updates unit imports and adds tests for constant and polynomial pointing models.
mapcat/pointing/poly.py New polynomial pointing model implementation (fit + predict + stats).
mapcat/pointing/const.py Adjusts ConstantPointingModel.predict to subtract offsets.
mapcat/database/pointing_residual.py Allows storing either constant or polynomial pointing model in residual_model.
mapcat/database/json.py Switches JSON deserialization to Pydantic TypeAdapter (enables unions).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread mapcat/database/pointing_residual.py
Comment thread mapcat/pointing/poly.py Outdated
Comment thread mapcat/pointing/poly.py
Comment thread mapcat/pointing/poly.py
Comment thread mapcat/pointing/poly.py
Comment thread mapcat/pointing/poly.py Outdated
Comment thread mapcat/pointing/poly.py
Comment on lines +162 to +166
def predict(self, pos: SkyCoord) -> SkyCoord:
racoeffs,deccoeffs = self.extract_coefficients()
ra_offset = self.model_fn(pos.ra, pos.dec, racoeffs)[0]
dec_offset = self.model_fn(pos.ra, pos.dec, deccoeffs)[0]
ra = pos.ra - ra_offset
Copy link
Copy Markdown
Member

@JBorrow JBorrow left a comment

Choose a reason for hiding this comment

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

Some minor comments. It seems kinda overcomplicated for a polynomial model but that's ok. Is there a reason we can't just use https://numpy.org/doc/stable/reference/generated/numpy.polyfit.html

Comment on lines 14 to 15
from .depth_one_map import DepthOneMapTable
from .json import JSONEncodedPydantic
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks like you need to run ruff check

Comment thread mapcat/database/pointing_residual.py Outdated
from .depth_one_map import DepthOneMapTable
from .json import JSONEncodedPydantic

PointingModel = Union[ConstantPointingModel, PolynomialPointingModel]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

PointingModel = ConstantPointingModel | PolynomialPointingModel is apparently the way to go

Comment thread mapcat/pointing/poly.py Outdated
Comment on lines +56 to +61
def calculate_model(self,
measured_positions: SkyCoord,
expected_positions: SkyCoord,
position_uncertainty: tuple[u.Quantity, u.Quantity] | u.Quantity | None = None,
weights: tuple[list[float], list[float]] | list[float] | None = None
) -> SkyCoord:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks like it needs to be formatted lmao

Comment thread mapcat/pointing/poly.py
Comment on lines +95 to +112
# Lots of logic to check if weights exist, etc.
# Resolve weights from uncertainties if not provided
if ra_weights is None and dec_weights is None:
if ra_uncerts is not None and dec_uncerts is not None:
ra_weights = dec_weights = 1 / np.sqrt(ra_uncerts**2 + dec_uncerts**2)
elif ra_uncerts is not None:
dec_uncerts = np.ones(n) * np.mean(ra_uncerts)
ra_weights = dec_weights = 1 / np.sqrt(ra_uncerts**2 + dec_uncerts**2)
elif dec_uncerts is not None:
ra_uncerts = np.ones(n) * np.mean(dec_uncerts)
ra_weights = dec_weights = 1 / np.sqrt(ra_uncerts**2 + dec_uncerts**2)
else:
# No uncertainty or weights provided — uniform
ra_weights = dec_weights = np.ones(n)
elif ra_weights is None:
ra_weights = dec_weights
elif dec_weights is None:
dec_weights = ra_weights
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This seems... Overcomplicated

Comment thread mapcat/pointing/poly.py
keys.append(f"x^{i}y^{j}")
return keys

def calculate_model(self,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is calculate model here more of a... build model? Calculate is kinda ambiguous in train/apply. I'd prefer train_model or build_model or something.

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.

3 participants