diff --git a/CHANGELOG-unreleased.md b/CHANGELOG-unreleased.md index 2bf17f470..cb79874b1 100644 --- a/CHANGELOG-unreleased.md +++ b/CHANGELOG-unreleased.md @@ -31,5 +31,6 @@ the released changes. - fixed docstring for `add_param_from_top` - Gridded calculations now respect logger settings - Event TOAs now have default error that is non-zero, and can set as desired +- Model conversion ICRS <-> ECL works if PM uncertainties are not set - Fix `merge_TOAs()` to allow lists of length 1 ### Removed \ No newline at end of file diff --git a/src/pint/models/astrometry.py b/src/pint/models/astrometry.py index 6f0af367e..38b5ac7c6 100644 --- a/src/pint/models/astrometry.py +++ b/src/pint/models/astrometry.py @@ -957,8 +957,12 @@ def as_ECL(self, epoch=None, ecl="IERS2010"): lat=self.ELAT.quantity, obliquity=OBL[self.ECL.value], obstime=self.POSEPOCH.quantity, - pm_lon_coslat=self.PMELONG.uncertainty, - pm_lat=self.PMELAT.uncertainty, + pm_lon_coslat=self.PMELONG.uncertainty + if self.PMELONG.uncertainty is not None + else 0 * self.PMELONG.units, + pm_lat=self.PMELAT.uncertainty + if self.PMELAT.uncertainty is not None + else 0 * self.PMELAT.units, frame=PulsarEcliptic, ) c_ECL = c.transform_to(PulsarEcliptic(ecl=ecl)) @@ -1007,8 +1011,12 @@ def as_ICRS(self, epoch=None): lat=self.ELAT.quantity, obliquity=OBL[self.ECL.value], obstime=self.POSEPOCH.quantity, - pm_lon_coslat=self.ELONG.uncertainty * np.cos(self.ELAT.quantity) / dt, - pm_lat=self.ELAT.uncertainty / dt, + pm_lon_coslat=self.ELONG.uncertainty * np.cos(self.ELAT.quantity) / dt + if self.ELONG.uncertainty is not None + else 0 * self.ELONG.units / dt, + pm_lat=self.ELAT.uncertainty / dt + if self.ELAT.uncertainty is not None + else 0 * self.ELAT.units / dt, frame=PulsarEcliptic, ) c_ICRS = c.transform_to(coords.ICRS) @@ -1021,8 +1029,12 @@ def as_ICRS(self, epoch=None): lat=self.ELAT.quantity, obliquity=OBL[self.ECL.value], obstime=self.POSEPOCH.quantity, - pm_lon_coslat=self.PMELONG.uncertainty, - pm_lat=self.PMELAT.uncertainty, + pm_lon_coslat=self.PMELONG.uncertainty + if self.PMELONG.uncertainty is not None + else 0 * self.PMELONG.units, + pm_lat=self.PMELAT.uncertainty + if self.PMELAT.uncertainty is not None + else 0 * self.PMELAT.units, frame=PulsarEcliptic, ) c_ICRS = c.transform_to(coords.ICRS) diff --git a/tests/test_modelconversions.py b/tests/test_modelconversions.py index 4cd4ad3e1..dddae8d9c 100644 --- a/tests/test_modelconversions.py +++ b/tests/test_modelconversions.py @@ -70,6 +70,37 @@ def test_ECL_to_ICRS(): assert np.allclose(r_ECL.resids, r_ICRS.resids) +def test_ICRS_to_ECL_nouncertainties(): + # start with ICRS model with no pm uncertainties, get residuals with ECL model, compare + model_ICRS = get_model(io.StringIO(modelstring_ICRS)) + for p in ["PMRA", "PMDEC"]: + getattr(model_ICRS, p).frozen = True + getattr(model_ICRS, p).uncertainties = None + + toas = pint.simulation.make_fake_toas_uniform( + MJDStart, MJDStop, NTOA, model=model_ICRS, error=1 * u.us, add_noise=True + ) + r_ICRS = pint.residuals.Residuals(toas, model_ICRS) + r_ECL = pint.residuals.Residuals(toas, model_ICRS.as_ECL()) + assert np.allclose(r_ECL.resids, r_ICRS.resids) + # assert model_ICRS.as_ECL(ecl).ECL.value == ecl + + +def test_ECL_to_ICRS_nouncertainties(): + # start with ECL model with no pm uncertainties, get residuals with ICRS model, compare + model_ECL = get_model(io.StringIO(modelstring_ECL)) + for p in ["PMELONG", "PMELAT"]: + getattr(model_ECL, p).frozen = True + getattr(model_ECL, p).uncertainties = None + + toas = pint.simulation.make_fake_toas_uniform( + MJDStart, MJDStop, NTOA, model=model_ECL, error=1 * u.us, add_noise=True + ) + r_ECL = pint.residuals.Residuals(toas, model_ECL) + r_ICRS = pint.residuals.Residuals(toas, model_ECL.as_ICRS()) + assert np.allclose(r_ECL.resids, r_ICRS.resids) + + def test_ECL_to_ECL(): # start with ECL model, get residuals with ECL model with different obliquity, compare model_ECL = get_model(io.StringIO(modelstring_ECL))