def test_equatorial_round_trip_mars():
    """Round trip testing between CRS and TOD, J2000 Equatorial and Body Fixed."""

    allowable_pos_diff = 2e-6 * u.mm
    allowable_vel_diff = 2e-6 * u.mm / u.s

    # init CRS
    pvt_crs = _init_orbit_mars()

    # Convert to Body Fixed
    pvt_body_fixed = pvt_crs.transform_to(MarsBodyFixed)
    # Convert to TOD Equatorial
    pvt_tod_eq = pvt_crs.transform_to(MarsTODEquatorial)
    # Convert to J2000 Equatorial
    pvt_j2000_eq = pvt_crs.transform_to(MarsJ2000Equatorial)

    # Convert J2000 back to CRS
    assert pos_err(pvt_j2000_eq.transform_to(MarsCRS),
                   pvt_crs) < allowable_pos_diff
    assert vel_err(pvt_j2000_eq.transform_to(MarsCRS),
                   pvt_crs) < allowable_vel_diff

    # print(pos_err(pvt_body_fixed.transform_to(MarsCRS), pvt_crs))
    # print(vel_err(pvt_body_fixed.transform_to(MarsCRS), pvt_crs))

    # Convert TOD back to CRS
    assert pos_err(pvt_tod_eq.transform_to(MarsCRS),
                   pvt_crs) < allowable_pos_diff
    assert vel_err(pvt_tod_eq.transform_to(MarsCRS),
                   pvt_crs) < allowable_vel_diff

    # Convert Body Fixed back to CRS
    assert pos_err(pvt_body_fixed.transform_to(MarsCRS),
                   pvt_crs) < allowable_pos_diff
    assert vel_err(pvt_body_fixed.transform_to(MarsCRS),
                   pvt_crs) < allowable_vel_diff
def test_tirs_to_itrs():
    """Check the coordinate transform accuracy."""
    # test_frame = "ITRS"
    allowable_pos_diff = 60 * u.mm
    allowable_vel_diff = 0.05 * u.mm / u.s

    rv_itrs = rv_tirs_true.transform_to(ITRS(obstime=time))

    r_diff = pos_err(rv_itrs, rv_itrs_true)
    v_diff = vel_err(rv_itrs, rv_itrs_true)

    # print(f"r {test_frame} diff      :  {r_diff}")
    # print(f"v {test_frame} diff      :  {v_diff}")

    assert r_diff < allowable_pos_diff
    assert v_diff < allowable_vel_diff
def test_itrs_to_teme():
    """Check the coordinate transform accuracy."""
    # test_frame = "TEME"
    allowable_pos_diff = 300 * u.mm
    allowable_vel_diff = 0.23 * u.mm / u.s

    rv_teme = rv_itrs_true.transform_to(TEME(obstime=time))

    r_diff = pos_err(rv_teme, rv_teme_true)
    v_diff = vel_err(rv_teme, rv_teme_true)

    # print(f"r {rv_teme.name} diff      :  {r_diff}")
    # print(f"v {rv_teme.name} diff      :  {v_diff}")

    assert r_diff < allowable_pos_diff
    assert v_diff < allowable_vel_diff
def test_j2000_to_gcrs():
    """Check the coordinate transform accuracy."""
    # test_frame = "GCRS"
    allowable_pos_diff = 800 * u.mm
    allowable_vel_diff = 0.36 * u.mm / u.s

    rv_gcrs = rv_j2000_true.transform_to(GCRS(obstime=time))

    r_diff = pos_err(rv_gcrs, rv_gcrs_true)
    v_diff = vel_err(rv_gcrs, rv_gcrs_true)

    # print(f"r {test_frame} diff      :  {r_diff}")
    # print(f"v {test_frame} diff      :  {v_diff}")

    assert r_diff < allowable_pos_diff
    assert v_diff < allowable_vel_diff
def test_j2000_roundtrip():
    """Check whether transforming to a coord and then
    transforming back yields the same output."""
    # test_frame = "J2000"
    allowable_pos_diff = 1.5e-6 * u.mm
    allowable_vel_diff = 1.0e-9 * u.mm / u.s

    rv_gcrs = rv_j2000_true.transform_to(GCRS(obstime=time))
    rv_j2000_from_gcrs = rv_gcrs.transform_to(J2000(obstime=time))

    r_diff = pos_err(rv_j2000_from_gcrs, rv_j2000_true)
    v_diff = vel_err(rv_j2000_from_gcrs, rv_j2000_true)

    # print(f"r {test_frame} diff      :  {r_diff}")
    # print(f"v {test_frame} diff      :  {v_diff}")

    assert r_diff < allowable_pos_diff
    assert v_diff < allowable_vel_diff
def test_itrs_roundtrip():
    """Check whether transforming to a coord and then
    transforming back yields the same output."""
    # test_frame = "ITRS"
    allowable_pos_diff = 1.5e-6 * u.mm
    allowable_vel_diff = 2.8e-6 * u.mm / u.s

    rv_teme = rv_itrs_true.transform_to(TEME(obstime=time))
    rv_itrs_from_teme = rv_teme.transform_to(ITRS(obstime=time))

    r_diff = pos_err(rv_itrs_from_teme, rv_itrs_true)
    v_diff = vel_err(rv_itrs_from_teme, rv_itrs_true)

    # print(f"r {rv_itrs_true.name} diff      :  {r_diff}")
    # print(f"v {rv_itrs_true.name} diff      :  {v_diff}")

    assert r_diff < allowable_pos_diff
    assert v_diff < allowable_vel_diff
def test_cb_crs_to_icrs_earth():
    """Check the basic quasi-round-trip accuracy for the generic Central Body Celestial
    Reference System, using Earth (equal to GCRS). Converts GCRS to ICRS, then ICRS to
    Earth CRS. However there is a difference, possibly due to the difference between
    the two transformations (`FunctionTransformWithFiniteDifference` vs
    `AffineTransform`)"""
    allowable_pos_diff = 800 * u.m
    allowable_vel_diff = 0.510 * u.m / u.s

    rv_icrs = SkyCoord(rv_gcrs_true).transform_to(ICRS)

    rv_gcrs = rv_icrs.transform_to(_EarthCRS)

    r_diff = pos_err(rv_gcrs, rv_gcrs_true)
    v_diff = vel_err(rv_gcrs, rv_gcrs_true)

    # print(f"r {rv_gcrs.name} diff      :  {r_diff}")
    # print(f"v {rv_gcrs.name} diff      :  {v_diff}")

    assert r_diff < allowable_pos_diff
    assert v_diff < allowable_vel_diff
def test_cb_crs_to_icrs_sun():
    """Check the basic quasi-round-trip accuracy for the generic Central Body Celestial
    Reference System, using Sun (equal to HCRS). Converts Sun CRS to ICRS, then ICRS to
    HCRS."""
    allowable_pos_diff = 5e-4 * u.mm
    allowable_vel_diff = 0.0001 * u.mm / u.s

    rv_suncrs_true = init_pvt(_SunCRS, time,
                              r_gcrs_true.with_differentials(v_gcrs_true))

    rv_icrs = rv_suncrs_true.transform_to(ICRS)

    rv_hcrs = rv_icrs.transform_to(HCRS)

    r_diff = pos_err(rv_hcrs, rv_suncrs_true)
    v_diff = vel_err(rv_hcrs, rv_suncrs_true)

    # print(f"r {rv_hcrs.name} diff      :  {r_diff}")
    # print(f"v {rv_hcrs.name} diff      :  {v_diff}")

    assert r_diff < allowable_pos_diff
    assert v_diff < allowable_vel_diff
def test_equatorial_mars():
    """NASA HORIZONS/GMAT testing between CRS and TOD & J2000 Equatorial
    as well as Body Fixed (GMAT).

    GMAT and HORIZONS use a different model in the IAU polar rotation parameters
    (IAU 2000). Therefore test setup uses this version but not IAU 2015 versions.

    Satellite orbit is taken from Mars Reconnaissance Orbiter,
    using the NASA Horizons Web Interface (https://ssd.jpl.nasa.gov/horizons.cgi)."""

    obstime = Time("2020-01-10T11:30:00.0003", scale="tdb")

    v_eq_horz = CartesianDifferential(
        [-2.061955207079347, -2.671302888480574, 0.269551765393186],
        unit=u.km / u.s,
    )
    r_eq_horz = CartesianRepresentation(
        [322.259677663235, 120.3781499221643, 3676.074343158492], unit=u.km)
    rv_eq_horz = init_pvt(_MarsIAU2000TODEquatorial, obstime, r_eq_horz,
                          v_eq_horz)

    v_inert_horz = CartesianDifferential(
        [-2.062805178080304, -2.670750348642094, 0.2685217398016297],
        unit=u.km / u.s,
    )
    r_inert_horz = CartesianRepresentation(
        [321.472501283011, 119.500545946684, 3676.171898278387], unit=u.km)
    rv_inert_horz = init_pvt(_MarsIAU2000J2000Equatorial, obstime,
                             r_inert_horz, v_inert_horz)

    v_body_fixed_gmat = CartesianDifferential(
        [0.622659762445902, 3.329753468204519, 0.2695517652769852],
        unit=u.km / u.s,
    )
    r_body_fixed_gmat = CartesianRepresentation(
        [-233.7124768823157, -252.4295484193542, 3676.074343157078], unit=u.km)
    rv_body_fixed_gmat = init_pvt(_MarsIAU2000BodyFixed, obstime,
                                  r_body_fixed_gmat, v_body_fixed_gmat)

    allowable_pos_diff = 800 * u.mm
    allowable_vel_diff = 0.35 * u.mm / u.s

    # init CRS - modify frame name to point at test coords
    pvt_crs = _init_orbit_mars()
    pvt_crs.frame.body_name = "Mars_IAU_2000"

    # Convert to TOD Equatorial
    pvt_tod_eq = pvt_crs.transform_to(_MarsIAU2000TODEquatorial)
    # Convert to J2000 Equatorial
    pvt_j2000_eq = pvt_crs.transform_to(_MarsIAU2000J2000Equatorial)
    # Convert to Body Fixed
    pvt_body_fixed = pvt_crs.transform_to(_MarsIAU2000BodyFixed)

    print(pvt_crs)
    print(pvt_tod_eq)
    print(pvt_j2000_eq)
    print(pvt_body_fixed)

    print(pos_err(pvt_body_fixed, rv_body_fixed_gmat))
    print(vel_err(pvt_body_fixed, rv_body_fixed_gmat))

    # Diff between TOD Eq values
    assert pos_err(pvt_tod_eq, rv_eq_horz) < allowable_pos_diff
    assert vel_err(pvt_tod_eq, rv_eq_horz) < allowable_vel_diff

    # Diff between J2000 Eq (Inertial) values
    assert pos_err(pvt_j2000_eq, rv_inert_horz) < allowable_pos_diff
    assert vel_err(pvt_j2000_eq, rv_inert_horz) < allowable_vel_diff

    # Diff between Body Fixed values
    assert pos_err(pvt_body_fixed, rv_body_fixed_gmat) < allowable_pos_diff
    assert vel_err(pvt_body_fixed, rv_body_fixed_gmat) < allowable_vel_diff