<commit_before># -*- coding: utf-8 -*-
# Licensed under a 3-clause BSD style license - see LICENSE.rst

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import pytest
import numpy as np
from ...tests.helper import quantity_allclose

from ... import units as u
from ... import constants
from ...time import Time
from ..builtin_frames import ICRS, AltAz, LSR, GCRS, Galactic, FK5
from ..baseframe import frame_transform_graph
from .. import (EarthLocation, TimeFrameAttribute,
                FunctionTransformWithFiniteDifference, get_sun,
                CartesianRepresentation, SphericalRepresentation,
                CartesianDifferential, SphericalDifferential,
                DynamicMatrixTransform)

J2000 = Time('J2000')

@pytest.mark.parametrize("dt, symmetric", [(1*u.second, True),
                                           (1*u.year, True),
                                           (1*u.second, False),
                                           (1*u.year, False)])
def test_faux_lsr(dt, symmetric):
    class LSR2(LSR):
        obstime = TimeFrameAttribute(default=J2000)

    @frame_transform_graph.transform(FunctionTransformWithFiniteDifference,
                                     ICRS, LSR2, finite_difference_dt=dt,
                                     symmetric_finite_difference=symmetric)
    def icrs_to_lsr(icrs_coo, lsr_frame):
        dt = lsr_frame.obstime - J2000
        offset = lsr_frame.v_bary * dt.to(u.second)
        return  lsr_frame.realize_frame(icrs_coo.data.without_differentials() + offset)

    @frame_transform_graph.transform(FunctionTransformWithFiniteDifference,
                                     LSR2, ICRS, finite_difference_dt=dt,
                                     symmetric_finite_difference=symmetric)
    def lsr_to_icrs(lsr_coo, icrs_frame):
        dt = lsr_frame.obstime - J2000
        offset = lsr_frame.v_bary * dt.to(u.second)
        return icrs_frame.realize_frame(lsr_coo.data - offset)


    ic = ICRS(ra=12.3*u.deg, dec=45.6*u.deg, distance=7.8*u.au,
              pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=0*u.marcsec/u.yr,
              radial_velocity=0*u.km/u.s)
    lsrc = ic.transform_to(LSR2())

    assert quantity_allclose(ic.cartesian.xyz, lsrc.cartesian.xyz)

    idiff = ic.cartesian.differentials['s']
    ldiff = lsrc.cartesian.differentials['s']
    change = (ldiff.d_xyz - idiff.d_xyz).to(u.km/u.s)
    totchange = np.sum(change**2)**0.5
    assert quantity_allclose(totchange, np.sum(lsrc.v_bary.d_xyz**2)**0.5)


    ic2 = ICRS(ra=120.3*u.deg, dec=45.6*u.deg, distance=7.8*u.au,
              pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=10*u.marcsec/u.yr,
              radial_velocity=1000*u.km/u.s)
    lsrc2 = ic2.transform_to(LSR2())

    tot = np.sum(lsrc2.cartesian.differentials['s'].d_xyz**2)**0.5
    assert np.abs(tot.to('km/s') - 1000*u.km/u.s) < 20*u.km/u.s


def test_faux_fk5_galactic():

    from ..builtin_frames.galactic_transforms import fk5_to_gal, _gal_to_fk5

    class Galactic2(Galactic):
        pass

    dt = 1*u.s

    @frame_transform_graph.transform(FunctionTransformWithFiniteDifference,
                                     FK5, Galactic2, finite_difference_dt=dt,
                                     symmetric_finite_difference=True,
                                     finite_difference_frameattr_name=None)
    def fk5_to_gal2(fk5_coo, gal_frame):
        trans = DynamicMatrixTransform(fk5_to_gal, FK5, Galactic2)
        return trans(fk5_coo, gal_frame)

    @frame_transform_graph.transform(FunctionTransformWithFiniteDifference,
                                     Galactic2, ICRS, finite_difference_dt=dt,
                                     symmetric_finite_difference=True,
                                     finite_difference_frameattr_name=None)
    def gal2_to_fk5(gal_coo, fk5_frame):
        trans = DynamicMatrixTransform(_gal_to_fk5, Galactic2, FK5)
        return trans(gal_coo, fk5_frame)

    c1 = FK5(ra=150*u.deg, dec=-17*u.deg, radial_velocity=83*u.km/u.s,
             pm_ra_cosdec=-41*u.mas/u.yr, pm_dec=16*u.mas/u.yr,
             distance=150*u.pc)
    c2 = c1.transform_to(Galactic2)
    c3 = c1.transform_to(Galactic)

    # compare the matrix and finite-difference calculations
    assert quantity_allclose(c2.pm_l_cosb, c3.pm_l_cosb, rtol=5e-3)
    assert quantity_allclose(c2.pm_b, c3.pm_b, rtol=5e-3)


def test_gcrs_diffs():
    time = Time('J2017')
    gf = GCRS(obstime=time)
    sung = get_sun(time)  # should have very little vhelio

    # qtr-year off sun location should be the direction of ~ maximal vhelio
    qtrsung = get_sun(time-.25*u.year)

    # now we use those essentially as directions where the velocities should
    #be either maximal or minimal - with or perpendiculat to Earh's orbit
    msungr = CartesianRepresentation(-sung.cartesian.xyz).represent_as(SphericalRepresentation)
    suni = ICRS(ra=msungr.lon, dec=msungr.lat, distance=100*u.au,
                pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=0*u.marcsec/u.yr,
                radial_velocity=0*u.km/u.s)
    qtrsuni = ICRS(ra=qtrsung.ra, dec=qtrsung.dec, distance=100*u.au,
                   pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=0*u.marcsec/u.yr,
                   radial_velocity=0*u.km/u.s)

    # Now we transform those parallel- and perpendicular-to Earth's orbit
    # directions to GCRS, which should shift the velocity to either include
    # the Earth's velocity vector, or not (for parallel and perpendicular,
    # respectively).
    sung = suni.transform_to(gf)
    qtrsung = qtrsuni.transform_to(gf)

    # should be high along the ecliptic-not-sun sun axis and
    # low along the sun axis
    assert np.abs(qtrsung.radial_velocity) > 30*u.km/u.s
    assert np.abs(qtrsung.radial_velocity) < 40*u.km/u.s
    assert np.abs(sung.radial_velocity) < 1*u.km/u.s

    suni2 = sung.transform_to(ICRS)
    assert np.all(np.abs(suni2.data.differentials['s'].d_xyz) < 3e-5*u.km/u.s)
    qtrisun2 = qtrsung.transform_to(ICRS)
    assert np.all(np.abs(qtrisun2.data.differentials['s'].d_xyz) < 3e-5*u.km/u.s)


def test_altaz_diffs():
    time = Time('J2015') + np.linspace(-1, 1, 1000)*u.day
    loc = EarthLocation.of_site('greenwich')  # built-in
    aa = AltAz(obstime=time, location=loc)

    icoo = ICRS(np.zeros_like(time)*u.deg, 10*u.deg, 100*u.au,
                pm_ra_cosdec=np.zeros_like(time)*u.marcsec/u.yr,
                pm_dec=0*u.marcsec/u.yr,
                radial_velocity=0*u.km/u.s)

    acoo = icoo.transform_to(aa)

    # Make sure the change in radial velocity over ~2 days isn't too much
    # more than the rotation speed of the Earth - some excess is expected
    # because the orbit also shifts the RV, but it should be pretty small
    # over this short a time.
    assert np.ptp(acoo.radial_velocity)/2 < (2*np.pi*constants.R_earth/u.day)*1.2  # MAGIC NUMBER

    cdiff = acoo.data.differentials['s'].represent_as(CartesianDifferential,
                                                    acoo.data)

    # The "total" velocity should be > c, because the *tangential* velocity
    # isn't a True velocity, but rather an induced velocity due to the Earth's
    # rotation at a distance of 100 AU
    assert np.all(np.sum(cdiff.d_xyz**2, axis=0)**0.5 > constants.c)


_xfail = pytest.mark.xfail
@pytest.mark.parametrize('distance', [1000*u.au,
                                      10*u.pc,
                                      pytest.param(10*u.kpc, marks=_xfail),
                                      pytest.param(100*u.kpc, marks=_xfail)])
                                      # TODO:  make these not fail when the
                                      # finite-difference numerical stability
                                      # is improved
def test_numerical_limits(distance):
    """
    Tests the numerical stability of the default settings for the finite
    difference transformation calculation.  This is *known* to fail for at<commit_msg>make compatible with older pytests<commit_after># -*- coding: utf-8 -*-
# Licensed under a 3-clause BSD style license - see LICENSE.rst

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

import pytest
import numpy as np
from ...tests.helper import quantity_allclose

from ... import units as u
from ... import constants
from ...time import Time
from ..builtin_frames import ICRS, AltAz, LSR, GCRS, Galactic, FK5
from ..baseframe import frame_transform_graph
from .. import (EarthLocation, TimeFrameAttribute,
                FunctionTransformWithFiniteDifference, get_sun,
                CartesianRepresentation, SphericalRepresentation,
                CartesianDifferential, SphericalDifferential,
                DynamicMatrixTransform)

J2000 = Time('J2000')

@pytest.mark.parametrize("dt, symmetric", [(1*u.second, True),
                                           (1*u.year, True),
                                           (1*u.second, False),
                                           (1*u.year, False)])
def test_faux_lsr(dt, symmetric):
    class LSR2(LSR):
        obstime = TimeFrameAttribute(default=J2000)

    @frame_transform_graph.transform(FunctionTransformWithFiniteDifference,
                                     ICRS, LSR2, finite_difference_dt=dt,
                                     symmetric_finite_difference=symmetric)
    def icrs_to_lsr(icrs_coo, lsr_frame):
        dt = lsr_frame.obstime - J2000
        offset = lsr_frame.v_bary * dt.to(u.second)
        return  lsr_frame.realize_frame(icrs_coo.data.without_differentials() + offset)

    @frame_transform_graph.transform(FunctionTransformWithFiniteDifference,
                                     LSR2, ICRS, finite_difference_dt=dt,
                                     symmetric_finite_difference=symmetric)
    def lsr_to_icrs(lsr_coo, icrs_frame):
        dt = lsr_frame.obstime - J2000
        offset = lsr_frame.v_bary * dt.to(u.second)
        return icrs_frame.realize_frame(lsr_coo.data - offset)


    ic = ICRS(ra=12.3*u.deg, dec=45.6*u.deg, distance=7.8*u.au,
              pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=0*u.marcsec/u.yr,
              radial_velocity=0*u.km/u.s)
    lsrc = ic.transform_to(LSR2())

    assert quantity_allclose(ic.cartesian.xyz, lsrc.cartesian.xyz)

    idiff = ic.cartesian.differentials['s']
    ldiff = lsrc.cartesian.differentials['s']
    change = (ldiff.d_xyz - idiff.d_xyz).to(u.km/u.s)
    totchange = np.sum(change**2)**0.5
    assert quantity_allclose(totchange, np.sum(lsrc.v_bary.d_xyz**2)**0.5)


    ic2 = ICRS(ra=120.3*u.deg, dec=45.6*u.deg, distance=7.8*u.au,
              pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=10*u.marcsec/u.yr,
              radial_velocity=1000*u.km/u.s)
    lsrc2 = ic2.transform_to(LSR2())

    tot = np.sum(lsrc2.cartesian.differentials['s'].d_xyz**2)**0.5
    assert np.abs(tot.to('km/s') - 1000*u.km/u.s) < 20*u.km/u.s


def test_faux_fk5_galactic():

    from ..builtin_frames.galactic_transforms import fk5_to_gal, _gal_to_fk5

    class Galactic2(Galactic):
        pass

    dt = 1*u.s

    @frame_transform_graph.transform(FunctionTransformWithFiniteDifference,
                                     FK5, Galactic2, finite_difference_dt=dt,
                                     symmetric_finite_difference=True,
                                     finite_difference_frameattr_name=None)
    def fk5_to_gal2(fk5_coo, gal_frame):
        trans = DynamicMatrixTransform(fk5_to_gal, FK5, Galactic2)
        return trans(fk5_coo, gal_frame)

    @frame_transform_graph.transform(FunctionTransformWithFiniteDifference,
                                     Galactic2, ICRS, finite_difference_dt=dt,
                                     symmetric_finite_difference=True,
                                     finite_difference_frameattr_name=None)
    def gal2_to_fk5(gal_coo, fk5_frame):
        trans = DynamicMatrixTransform(_gal_to_fk5, Galactic2, FK5)
        return trans(gal_coo, fk5_frame)

    c1 = FK5(ra=150*u.deg, dec=-17*u.deg, radial_velocity=83*u.km/u.s,
             pm_ra_cosdec=-41*u.mas/u.yr, pm_dec=16*u.mas/u.yr,
             distance=150*u.pc)
    c2 = c1.transform_to(Galactic2)
    c3 = c1.transform_to(Galactic)

    # compare the matrix and finite-difference calculations
    assert quantity_allclose(c2.pm_l_cosb, c3.pm_l_cosb, rtol=5e-3)
    assert quantity_allclose(c2.pm_b, c3.pm_b, rtol=5e-3)


def test_gcrs_diffs():
    time = Time('J2017')
    gf = GCRS(obstime=time)
    sung = get_sun(time)  # should have very little vhelio

    # qtr-year off sun location should be the direction of ~ maximal vhelio
    qtrsung = get_sun(time-.25*u.year)

    # now we use those essentially as directions where the velocities should
    #be either maximal or minimal - with or perpendiculat to Earh's orbit
    msungr = CartesianRepresentation(-sung.cartesian.xyz).represent_as(SphericalRepresentation)
    suni = ICRS(ra=msungr.lon, dec=msungr.lat, distance=100*u.au,
                pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=0*u.marcsec/u.yr,
                radial_velocity=0*u.km/u.s)
    qtrsuni = ICRS(ra=qtrsung.ra, dec=qtrsung.dec, distance=100*u.au,
                   pm_ra_cosdec=0*u.marcsec/u.yr, pm_dec=0*u.marcsec/u.yr,
                   radial_velocity=0*u.km/u.s)

    # Now we transform those parallel- and perpendicular-to Earth's orbit
    # directions to GCRS, which should shift the velocity to either include
    # the Earth's velocity vector, or not (for parallel and perpendicular,
    # respectively).
    sung = suni.transform_to(gf)
    qtrsung = qtrsuni.transform_to(gf)

    # should be high along the ecliptic-not-sun sun axis and
    # low along the sun axis
    assert np.abs(qtrsung.radial_velocity) > 30*u.km/u.s
    assert np.abs(qtrsung.radial_velocity) < 40*u.km/u.s
    assert np.abs(sung.radial_velocity) < 1*u.km/u.s

    suni2 = sung.transform_to(ICRS)
    assert np.all(np.abs(suni2.data.differentials['s'].d_xyz) < 3e-5*u.km/u.s)
    qtrisun2 = qtrsung.transform_to(ICRS)
    assert np.all(np.abs(qtrisun2.data.differentials['s'].d_xyz) < 3e-5*u.km/u.s)


def test_altaz_diffs():
    time = Time('J2015') + np.linspace(-1, 1, 1000)*u.day
    loc = EarthLocation.of_site('greenwich')  # built-in
    aa = AltAz(obstime=time, location=loc)

    icoo = ICRS(np.zeros_like(time)*u.deg, 10*u.deg, 100*u.au,
                pm_ra_cosdec=np.zeros_like(time)*u.marcsec/u.yr,
                pm_dec=0*u.marcsec/u.yr,
                radial_velocity=0*u.km/u.s)

    acoo = icoo.transform_to(aa)

    # Make sure the change in radial velocity over ~2 days isn't too much
    # more than the rotation speed of the Earth - some excess is expected
    # because the orbit also shifts the RV, but it should be pretty small
    # over this short a time.
    assert np.ptp(acoo.radial_velocity)/2 < (2*np.pi*constants.R_earth/u.day)*1.2  # MAGIC NUMBER

    cdiff = acoo.data.differentials['s'].represent_as(CartesianDifferential,
                                                    acoo.data)

    # The "total" velocity should be > c, because the *tangential* velocity
    # isn't a True velocity, but rather an induced velocity due to the Earth's
    # rotation at a distance of 100 AU
    assert np.all(np.sum(cdiff.d_xyz**2, axis=0)**0.5 > constants.c)


_xfail = pytest.mark.xfail
@pytest.mark.parametrize('distance', [1000*u.au,
                                      10*u.pc,
                                      pytest.mark.xfail(10*u.kpc),
                                      pytest.mark.xfail(100*u.kpc)])
                                      # below is xfail syntax for pytest >=3.1
                                      # TODO: change to this when the above
                                      # way of xfailing is turned off in pytest
                                      # >=4.0
                                      #pytest.param(10*u.kpc, marks=_xfail),
                                      #pytest.param(100*u.kpc, marks=_xfail)])
                                      # TODO:  make these not fail when the
                                      # finite-difference numerical stability
                                      # is improved
def test_numerical_limits(distance):
    """
    Tests the numerical stability of the default settings for the finite
    difference transformation calculation.  This is *known* to fail for at
{'fraction_non_alphanumeric': 0.10421745490004876, 'fraction_numerical': 0.024926864943929792, 'mean_word_length': 2.272636617471081, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 58, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6815027', 'n_tokens_mistral': 5885, 'n_tokens_neox': 5478, 'n_words': 1046}