def test_eloc_attributes(): from astropy.coordinates import AltAz, ITRS, GCRS, EarthLocation el = EarthLocation(lon=12.3*u.deg, lat=45.6*u.deg, height=1*u.km) it = ITRS(r.SphericalRepresentation(lon=12.3*u.deg, lat=45.6*u.deg, distance=1*u.km)) gc = GCRS(ra=12.3*u.deg, dec=45.6*u.deg, distance=6375*u.km) el1 = AltAz(location=el).location assert isinstance(el1, EarthLocation) # these should match *exactly* because the EarthLocation assert el1.lat == el.lat assert el1.lon == el.lon assert el1.height == el.height el2 = AltAz(location=it).location assert isinstance(el2, EarthLocation) # these should *not* match because giving something in Spherical ITRS is # *not* the same as giving it as an EarthLocation: EarthLocation is on an # elliptical geoid. So the longitude should match (because flattening is # only along the z-axis), but latitude should not. Also, height is relative # to the *surface* in EarthLocation, but the ITRS distance is relative to # the center of the Earth assert not allclose(el2.lat, it.spherical.lat) assert allclose(el2.lon, it.spherical.lon) assert el2.height < -6000*u.km el3 = AltAz(location=gc).location # GCRS inputs implicitly get transformed to ITRS and then onto # EarthLocation's elliptical geoid. So both lat and lon shouldn't match assert isinstance(el3, EarthLocation) assert not allclose(el3.lat, gc.dec) assert not allclose(el3.lon, gc.ra) assert np.abs(el3.height) < 500*u.km
def test_equivalent_frames(): from astropy.coordinates import SkyCoord from astropy.coordinates.builtin_frames import ICRS, FK4, FK5, AltAz i = ICRS() i2 = ICRS(1*u.deg, 2*u.deg) assert i.is_equivalent_frame(i) assert i.is_equivalent_frame(i2) with pytest.raises(TypeError): assert i.is_equivalent_frame(10) with pytest.raises(TypeError): assert i2.is_equivalent_frame(SkyCoord(i2)) f0 = FK5() # this J2000 is TT f1 = FK5(equinox='J2000') f2 = FK5(1*u.deg, 2*u.deg, equinox='J2000') f3 = FK5(equinox='J2010') f4 = FK4(equinox='J2010') assert f1.is_equivalent_frame(f1) assert not i.is_equivalent_frame(f1) assert f0.is_equivalent_frame(f1) assert f1.is_equivalent_frame(f2) assert not f1.is_equivalent_frame(f3) assert not f3.is_equivalent_frame(f4) aa1 = AltAz() aa2 = AltAz(obstime='J2010') assert aa2.is_equivalent_frame(aa2) assert not aa1.is_equivalent_frame(i) assert not aa1.is_equivalent_frame(aa2)
def test_altaz_attribute_transforms(): """Test transforms between AltAz frames with different attributes.""" el1 = EarthLocation(0 * u.deg, 0 * u.deg, 0 * u.m) origin1 = AltAz(0 * u.deg, 0 * u.deg, obstime=Time("2000-01-01T12:00:00"), location=el1) frame1 = SkyOffsetFrame(origin=origin1) coo1 = SkyCoord(1 * u.deg, 1 * u.deg, frame=frame1) el2 = EarthLocation(0 * u.deg, 0 * u.deg, 0 * u.m) origin2 = AltAz(0 * u.deg, 0 * u.deg, obstime=Time("2000-01-01T11:00:00"), location=el2) frame2 = SkyOffsetFrame(origin=origin2) coo2 = coo1.transform_to(frame2) coo2_expected = [1.22522446, 0.70624298] * u.deg assert_allclose([coo2.lon.wrap_at(180 * u.deg), coo2.lat], coo2_expected, atol=convert_precision) el3 = EarthLocation(0 * u.deg, 90 * u.deg, 0 * u.m) origin3 = AltAz(0 * u.deg, 90 * u.deg, obstime=Time("2000-01-01T12:00:00"), location=el3) frame3 = SkyOffsetFrame(origin=origin3) coo3 = coo2.transform_to(frame3) assert_allclose([coo3.lon.wrap_at(180 * u.deg), coo3.lat], [1 * u.deg, 1 * u.deg], atol=convert_precision)
def test_vel_transformation_obstime_err(): # TODO: replace after a final decision on PR #6280 from astropy.coordinates.sites import get_builtin_sites diff = r.CartesianDifferential([.1, .2, .3]*u.km/u.s) rep = r.CartesianRepresentation([1, 2, 3]*u.au, differentials=diff) loc = get_builtin_sites()['example_site'] aaf = AltAz(obstime='J2010', location=loc) aaf2 = AltAz(obstime=aaf.obstime + 3*u.day, location=loc) aaf3 = AltAz(obstime=aaf.obstime + np.arange(3)*u.day, location=loc) aaf4 = AltAz(obstime=aaf.obstime, location=loc) aa = aaf.realize_frame(rep) with pytest.raises(NotImplementedError) as exc: aa.transform_to(aaf2) assert 'cannot transform' in exc.value.args[0] with pytest.raises(NotImplementedError) as exc: aa.transform_to(aaf3) assert 'cannot transform' in exc.value.args[0] aa.transform_to(aaf4) aa.transform_to(ICRS())
def test_no_data_nonscalar_frames(): from astropy.coordinates.builtin_frames import AltAz from astropy.time import Time a1 = AltAz(obstime=Time('2012-01-01') + np.arange(10.) * u.day, temperature=np.ones((3, 1)) * u.deg_C) assert a1.obstime.shape == (3, 10) assert a1.temperature.shape == (3, 10) assert a1.shape == (3, 10) with pytest.raises(ValueError) as exc: AltAz(obstime=Time('2012-01-01') + np.arange(10.) * u.day, temperature=np.ones((3, )) * u.deg_C) assert 'inconsistent shapes' in str(exc.value)
def test_altaz_attributes(): from astropy.time import Time from astropy.coordinates import EarthLocation, AltAz aa = AltAz(1*u.deg, 2*u.deg) assert aa.obstime is None assert aa.location is None aa2 = AltAz(1*u.deg, 2*u.deg, obstime='J2000') assert aa2.obstime == Time('J2000') aa3 = AltAz(1*u.deg, 2*u.deg, location=EarthLocation(0*u.deg, 0*u.deg, 0*u.m)) assert isinstance(aa3.location, EarthLocation)
def test_against_jpl_horizons(): """Check that Astropy gives consistent results with the JPL Horizons example. The input parameters and reference results are taken from this page: (from the first row of the Results table at the bottom of that page) http://ssd.jpl.nasa.gov/?horizons_tutorial """ print('NASA JPL') obstime = Time('1998-07-28 03:00') location = EarthLocation(lon=Angle('248.405300d'), lat=Angle('31.9585d'), height=2.06 * u.km) # No atmosphere altaz_frame = AltAz(obstime=obstime, location=location) altaz = SkyCoord('143.2970d 2.6223d', frame=altaz_frame) radec_actual = altaz.transform_to('icrs') print('Astropy: ', radec_actual) radec_expected = SkyCoord('19h24m55.01s -40d56m28.9s', frame='icrs') print('Source: ', radec_expected) distance = radec_actual.separation(radec_expected).to('arcsec') #assert distance < 1 * u.arcsec # SAPPHiRE longitude = 248.405300 latitude = 31.9585 utc = datetime.datetime(1998, 7, 28, 3, 0) elevation = np.radians(2.6223) azi = np.radians(143.2970) gps = clock.utc_to_gps(calendar.timegm(utc.utctimetuple())) zenith, azimuth = celestial.horizontal_to_zenithazimuth(elevation, azi) ra, dec = celestial.zenithazimuth_to_equatorial(longitude, latitude, gps, zenith, azimuth) print('SAPPHiRE: ra=%f, dec=%f' % (np.degrees(ra), np.degrees(dec)))
def test_altaz_diffs(): time = Time('J2015') + np.linspace(-1, 1, 1000) * u.day loc = get_builtin_sites()['greenwich'] 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)
def test_future_altaz(): """ While this does test the full stack, it is mostly meant to check that a warning is raised when attempting to get to AltAz in the future (beyond IERS tables) """ from astropy.utils.exceptions import AstropyWarning # this is an ugly hack to get the warning to show up even if it has already # appeared from astropy.coordinates.builtin_frames import utils if hasattr(utils, '__warningregistry__'): utils.__warningregistry__.clear() location = EarthLocation(lat=0 * u.deg, lon=0 * u.deg) t = Time('J2161') # check that these message(s) appear among any other warnings. If tests are run with # --remote-data then the IERS table will be an instance of IERS_Auto which is # assured of being "fresh". In this case getting times outside the range of the # table does not raise an exception. Only if using IERS_B (which happens without # --remote-data, i.e. for all CI testing) do we expect another warning. with pytest.warns(AstropyWarning, match=r"Tried to get polar motions for " "times after IERS data is valid.*") as found_warnings: SkyCoord(1 * u.deg, 2 * u.deg).transform_to(AltAz(location=location, obstime=t)) if isinstance(iers.earth_orientation_table.get(), iers.IERS_B): messages_found = [ "(some) times are outside of range covered by IERS " "table." in str(w.message) for w in found_warnings ] assert any(messages_found)
def test_against_pyephem(): """Check that Astropy gives consistent results with one PyEphem example. PyEphem: http://rhodesmill.org/pyephem/ See example input and output here: https://gist.github.com/zonca/1672906 https://github.com/phn/pytpm/issues/2#issuecomment-3698679 """ obstime = Time('2011-09-18 08:50:00') location = EarthLocation(lon=Angle('-109d24m53.1s'), lat=Angle('33d41m46.0s'), height=30000. * u.m) # We are using the default pressure and temperature in PyEphem # relative_humidity = ? # obswl = ? altaz_frame = AltAz(obstime=obstime, location=location, temperature=15 * u.deg_C, pressure=1.010 * u.bar) altaz = SkyCoord('6.8927d -60.7665d', frame=altaz_frame) radec_actual = altaz.transform_to('icrs') radec_expected = SkyCoord('196.497518d -4.569323d', frame='icrs') # EPHEM # radec_expected = SkyCoord('196.496220d -4.569390d', frame='icrs') # HORIZON distance = radec_actual.separation(radec_expected).to('arcsec') # TODO: why is this difference so large? # It currently is: 31.45187984720655 arcsec assert distance < 1e3 * u.arcsec # Add assert on current Astropy result so that we notice if something changes radec_expected = SkyCoord('196.495372d -4.560694d', frame='icrs') distance = radec_actual.separation(radec_expected).to('arcsec') # Current value: 0.0031402822944751997 arcsec assert distance < 1 * u.arcsec
def fullstack_fiducial_altaz(fullstack_icrs): altazframe = AltAz(location=EarthLocation(lat=0*u.deg, lon=0*u.deg, height=0*u.m), obstime=Time('J2000')) with warnings.catch_warnings(): # Ignore remote_data warning warnings.simplefilter('ignore') result = fullstack_icrs.transform_to(altazframe) return result
def test_fk5_equinox_and_epoch_j2000_0_to_topocentric_observed(): """ http://phn.github.io/pytpm/conversions.html#fk5-equinox-and-epoch-j2000-0-to-topocentric-observed """ # Observatory position for `kpno` from here: # http://idlastro.gsfc.nasa.gov/ftp/pro/astro/observatory.pro location = EarthLocation(lon=Angle('-111.598333d'), lat=Angle('31.956389d'), height=2093.093 * u.m) # TODO: height correct? obstime = Time('2010-01-01 12:00:00') # relative_humidity = ? # obswl = ? altaz_frame = AltAz(obstime=obstime, location=location, temperature=0 * u.deg_C, pressure=0.781 * u.bar) radec = SkyCoord('12h22m54.899s 15d49m20.57s', frame='fk5') altaz_actual = radec.transform_to(altaz_frame) altaz_expected = SkyCoord('264d55m06s 37d54m41s', frame='altaz') # altaz_expected = SkyCoord('343.586827647d 15.7683070508d', frame='altaz') # altaz_expected = SkyCoord('133.498195532d 22.0162383595d', frame='altaz') distance = altaz_actual.separation(altaz_expected) # print(altaz_actual) # print(altaz_expected) # print(distance) """TODO: Current output is completely incorrect ... xfailing this test for now. <SkyCoord (AltAz: obstime=2010-01-01 12:00:00.000, location=(-1994497.7199061865, -5037954.447348028, 3357437.2294832403) m, pressure=781.0 hPa, temperature=0.0 deg_C, relative_humidity=0, obswl=1.0 micron):00:00.000, location=(-1994497.7199061865, -5037954.447348028, 3357437.2294832403) m, pressure=781.0 hPa, temperature=0.0 deg_C, relative_humidity=0, obswl=1.0 micron): az=133.4869896371561 deg, alt=67.97857990957701 deg> <SkyCoord (AltAz: obstime=None, location=None, pressure=0.0 hPa, temperature=0.0 deg_C, relative_humidity=0, obswl=1.0 micron): az=264.91833333333335 deg, alt=37.91138888888889 deg> 68d02m45.732s """ assert distance < 1 * u.arcsec
def test_against_pyephem(): """Check that Astropy gives consistent results with one PyEphem example. PyEphem: https://rhodesmill.org/pyephem/ See example input and output here: https://gist.github.com/zonca/1672906 https://github.com/phn/pytpm/issues/2#issuecomment-3698679 """ obstime = Time('2011-09-18 08:50:00') location = EarthLocation(lon=Angle('-109d24m53.1s'), lat=Angle('33d41m46.0s'), height=300. * u.m) # We are using the default pressure and temperature in PyEphem # relative_humidity = ? # obswl = ? altaz_frame = AltAz(obstime=obstime, location=location, temperature=15 * u.deg_C, pressure=1.010 * u.bar) altaz = SkyCoord('6.8927d +60.7665d', frame=altaz_frame) radec_actual = altaz.transform_to('icrs') radec_expected = SkyCoord('27.107480889479397d +62.512687777362046d', frame='icrs') distance_ephem = radec_actual.separation(radec_expected).to('arcsec') # 2021-04-06: 2.42 arcsec assert distance_ephem < 3 * u.arcsec # Add assert on current Astropy result so that we notice if something changes radec_expected = SkyCoord('27.10602683d +62.51275391d', frame='icrs') distance_astropy = radec_actual.separation(radec_expected).to('arcsec') # 2021-04-06: 5e-6 arcsec (erfa 1.7.2 vs erfa 1.7.1). assert distance_astropy < 0.1 * u.arcsec
def test_equivalent_frames(): from astropy.coordinates import SkyCoord from astropy.coordinates.builtin_frames import ICRS, FK4, FK5, AltAz i = ICRS() i2 = ICRS(1 * u.deg, 2 * u.deg) assert i.is_equivalent_frame(i) assert i.is_equivalent_frame(i2) with pytest.raises(TypeError): assert i.is_equivalent_frame(10) with pytest.raises(TypeError): assert i2.is_equivalent_frame(SkyCoord(i2)) f0 = FK5() # this J2000 is TT f1 = FK5(equinox='J2000') f2 = FK5(1 * u.deg, 2 * u.deg, equinox='J2000') f3 = FK5(equinox='J2010') f4 = FK4(equinox='J2010') assert f1.is_equivalent_frame(f1) assert not i.is_equivalent_frame(f1) assert f0.is_equivalent_frame(f1) assert f1.is_equivalent_frame(f2) assert not f1.is_equivalent_frame(f3) assert not f3.is_equivalent_frame(f4) aa1 = AltAz() aa2 = AltAz(obstime='J2010') assert aa2.is_equivalent_frame(aa2) assert not aa1.is_equivalent_frame(i) assert not aa1.is_equivalent_frame(aa2)
def test_against_hor2eq(): """Check that Astropy gives consistent results with an IDL hor2eq example. See EXAMPLE input and output here: http://idlastro.gsfc.nasa.gov/ftp/pro/astro/hor2eq.pro """ print('IDL hor2eq') # Observatory position for `kpno` from here: # http://idlastro.gsfc.nasa.gov/ftp/pro/astro/observatory.pro location = EarthLocation(lon=Angle('-111d36.0m'), lat=Angle('31d57.8m'), height=2120. * u.m) # obstime = Time('2041-12-26 05:00:00') obstime = Time(2466879.7083333, format='jd') # obstime += TimeDelta(-2, format='sec') altaz_frame = AltAz(obstime=obstime, location=location) altaz = SkyCoord('264d55m06s 37d54m41s', frame=altaz_frame) radec_frame = 'icrs' # The following transformation throws a warning about precision problems # because the observation date is in the future with catch_warnings() as _: radec_actual = altaz.transform_to(radec_frame) print('Astropy: ', radec_actual) radec_expected = SkyCoord('00h13m14.1s +15d11m0.3s', frame=radec_frame) print('Source: ', radec_expected) distance = radec_actual.separation(radec_expected).to('arcsec') # print(distance) # TODO: why is there a difference of 2.6 arcsec currently? # radec_expected = ra=3.30875 deg, dec=15.183416666666666 deg # radec_actual = ra=3.3094193224314625 deg, dec=15.183757021354532 deg # distance = 2.6285 arcsec # assert distance < 5 * u.arcsec # SAPPHiRE longitude = -111.6 latitude = 31.9633 jd = 2466879.7083333 elevation = (37, 54, 41) azi = (264, 55, 6) # lst = clock.gmst_to_lst(clock.juliandate_to_gmst(jd), longitude) # Matches LAST = +03 53 53.6 in the hor2eq.pro gps = clock.utc_to_gps( calendar.timegm(clock.juliandate_to_utc(jd).utctimetuple())) zenith, azimuth = celestial.horizontal_to_zenithazimuth( np.radians(base.sexagesimal_to_decimal(*elevation)), np.radians(base.sexagesimal_to_decimal(*azi))) ra, dec = celestial.zenithazimuth_to_equatorial(longitude, latitude, gps, zenith, azimuth) print('SAPPHiRE: ra=%f, dec=%f' % (np.degrees(ra), np.degrees(dec)))
def test_vel_transformation_obstime_err(): # TODO: replace after a final decision on PR #6280 from astropy.coordinates.sites import get_builtin_sites diff = r.CartesianDifferential([.1, .2, .3]*u.km/u.s) rep = r.CartesianRepresentation([1, 2, 3]*u.au, differentials=diff) loc = get_builtin_sites()['example_site'] aaf = AltAz(obstime='J2010', location=loc) aaf2 = AltAz(obstime=aaf.obstime + 3*u.day, location=loc) aaf3 = AltAz(obstime=aaf.obstime + np.arange(3)*u.day, location=loc) aaf4 = AltAz(obstime=aaf.obstime, location=loc) aa = aaf.realize_frame(rep) with pytest.raises(NotImplementedError) as exc: aa.transform_to(aaf2) assert 'cannot transform' in exc.value.args[0] with pytest.raises(NotImplementedError) as exc: aa.transform_to(aaf3) assert 'cannot transform' in exc.value.args[0] aa.transform_to(aaf4) aa.transform_to(ICRS())
def setup(self): # For these tests, we set up frames and coordinates using copy=False, # so we can check that broadcasting is handled correctly. lon = Longitude(np.arange(0, 24, 4), u.hourangle) lat = Latitude(np.arange(-90, 91, 30), u.deg) # With same-sized arrays, no attributes. self.s0 = ICRS(lon[:, np.newaxis] * np.ones(lat.shape), lat * np.ones(lon.shape)[:, np.newaxis], copy=False) # Make an AltAz frame since that has many types of attributes. # Match one axis with times. self.obstime = (Time('2012-01-01') + np.arange(len(lon))[:, np.newaxis] * u.s) # And another with location. self.location = EarthLocation(20.*u.deg, lat, 100*u.m) # Ensure we have a quantity scalar. self.pressure = 1000 * u.hPa # As well as an array. self.temperature = np.random.uniform( 0., 20., size=(lon.size, lat.size)) * u.deg_C self.s1 = AltAz(az=lon[:, np.newaxis], alt=lat, obstime=self.obstime, location=self.location, pressure=self.pressure, temperature=self.temperature, copy=False) # For some tests, also try a GCRS, since that has representation # attributes. We match the second dimension (via the location) self.obsgeoloc, self.obsgeovel = self.location.get_gcrs_posvel( self.obstime[0, 0]) self.s2 = GCRS(ra=lon[:, np.newaxis], dec=lat, obstime=self.obstime, obsgeoloc=self.obsgeoloc, obsgeovel=self.obsgeovel, copy=False) # For completeness, also some tests on an empty frame. self.s3 = GCRS(obstime=self.obstime, obsgeoloc=self.obsgeoloc, obsgeovel=self.obsgeovel, copy=False) # And make a SkyCoord self.sc = SkyCoord(ra=lon[:, np.newaxis], dec=lat, frame=self.s3, copy=False)
def test_replicating(): from astropy.coordinates.builtin_frames import ICRS, AltAz from astropy.time import Time i = ICRS(ra=[1] * u.deg, dec=[2] * u.deg) icopy = i.replicate(copy=True) irepl = i.replicate(copy=False) i.data._lat[:] = 0 * u.deg assert np.all(i.data.lat == irepl.data.lat) assert np.all(i.data.lat != icopy.data.lat) iclone = i.replicate_without_data() assert i.has_data assert not iclone.has_data aa = AltAz(alt=1 * u.deg, az=2 * u.deg, obstime=Time('J2000')) aaclone = aa.replicate_without_data(obstime=Time('J2001')) assert not aaclone.has_data assert aa.obstime != aaclone.obstime assert aa.pressure == aaclone.pressure assert aa.obswl == aaclone.obswl
def test_replicating(): from astropy.coordinates.builtin_frames import ICRS, AltAz from astropy.time import Time i = ICRS(ra=[1]*u.deg, dec=[2]*u.deg) icopy = i.replicate(copy=True) irepl = i.replicate(copy=False) i.data._lat[:] = 0*u.deg assert np.all(i.data.lat == irepl.data.lat) assert np.all(i.data.lat != icopy.data.lat) iclone = i.replicate_without_data() assert i.has_data assert not iclone.has_data aa = AltAz(alt=1*u.deg, az=2*u.deg, obstime=Time('J2000')) aaclone = aa.replicate_without_data(obstime=Time('J2001')) assert not aaclone.has_data assert aa.obstime != aaclone.obstime assert aa.pressure == aaclone.pressure assert aa.obswl == aaclone.obswl
def test_against_pyephem(): """Check that Astropy gives consistent results with one PyEphem example. PyEphem: http://rhodesmill.org/pyephem/ See example input and output here: https://gist.github.com/zonca/1672906 https://github.com/phn/pytpm/issues/2#issuecomment-3698679 """ print('PyEphem') obstime = Time('2011-09-18 08:50:00') location = EarthLocation(lon=Angle('-109d24m53.1s'), lat=Angle('33d41m46.0s'), height=0. * u.m) # We are using the default pressure and temperature in PyEphem altaz_frame = AltAz(obstime=obstime, location=location) altaz = SkyCoord('6.8927d -60.7665d', frame=altaz_frame) radec_actual = altaz.transform_to('icrs') print('Astropy: ', radec_actual) radec_expected = SkyCoord('196.497518d -4.569323d', frame='icrs') # EPHEM print('Source: ', radec_expected) # radec_expected = SkyCoord('196.496220d -4.569390d', frame='icrs') # HORIZON distance = radec_actual.separation(radec_expected).to('arcsec') # TODO: why is this difference so large? # It currently is: 31.45187984720655 arcsec assert distance < 1e3 * u.arcsec # Add assert on current Astropy result so that we notice if something changes radec_expected = SkyCoord('196.495372d -4.560694d', frame='icrs') distance = radec_actual.separation(radec_expected).to('arcsec') # Current value: 0.0031402822944751997 arcsec #assert distance < 1 * u.arcsec # SAPPHiRE longitude = base.sexagesimal_to_decimal(-109, -24, -53.1) latitude = base.sexagesimal_to_decimal(33, 41, 46.0) utc = datetime.datetime(2011, 9, 18, 8, 50, 00) elevation = np.radians(-60.7665) azi = np.radians(6.8927) gps = clock.utc_to_gps(calendar.timegm(utc.utctimetuple())) zenith, azimuth = celestial.horizontal_to_zenithazimuth(elevation, azi) ra, dec = celestial.zenithazimuth_to_equatorial(longitude, latitude, gps, zenith, azimuth) print('SAPPHiRE: ra=%f, dec=%f' % (np.degrees(ra), np.degrees(dec)))
def calc_astropy(): """Caclulate coordinates using AstroPy Code from the test code for AzAlt in AstroPy """ obstime = Time(UTC, format='unix') location = EarthLocation(lon=Angle('%fd' % LONGITUDE), lat=Angle('%fd' % LATITUDE), height=ALTITUDE * u.m) altaz_frame = AltAz(obstime=obstime, location=location) altaz = SkyCoord('%fd %fd' % (np.degrees(H_AZIMUTH), np.degrees(H_ALTITUDE)), frame=altaz_frame) radec = altaz.transform_to('icrs') print 'Astropy: %10.6f %10.6f' % (radec.frame.ra.deg, radec.frame.dec.deg)
def test_against_jpl_horizons(): """Check that Astropy gives consistent results with the JPL Horizons example. The input parameters and reference results are taken from this page: (from the first row of the Results table at the bottom of that page) http://ssd.jpl.nasa.gov/?horizons_tutorial """ obstime = Time('1998-07-28 03:00') location = EarthLocation(lon=Angle('248.405300d'), lat=Angle('31.9585d'), height=2.06 * u.km) # No atmosphere altaz_frame = AltAz(obstime=obstime, location=location) altaz = SkyCoord('143.2970d 2.6223d', frame=altaz_frame) radec_actual = altaz.transform_to('icrs') radec_expected = SkyCoord('19h24m55.01s -40d56m28.9s', frame='icrs') distance = radec_actual.separation(radec_expected).to('arcsec') # Current value: 0.238111 arcsec assert distance < 1 * u.arcsec
def test_future_altaz(): """ While this does test the full stack, it is mostly meant to check that a warning is raised when attempting to get to AltAz in the future (beyond IERS tables) """ from astropy.utils.exceptions import AstropyWarning # this is an ugly hack to get the warning to show up even if it has already # appeared from astropy.coordinates.builtin_frames import utils if hasattr(utils, '__warningregistry__'): utils.__warningregistry__.clear() with catch_warnings() as found_warnings: location = EarthLocation(lat=0 * u.deg, lon=0 * u.deg) t = Time('J2161') SkyCoord(1 * u.deg, 2 * u.deg).transform_to(AltAz(location=location, obstime=t)) # check that these message(s) appear among any other warnings. If tests are run with # --remote-data then the IERS table will be an instance of IERS_Auto which is # assured of being "fresh". In this case getting times outside the range of the # table does not raise an exception. Only if using IERS_B (which happens without # --remote-data, i.e. for all CI testing) do we expect another warning. messages_to_find = [ "Tried to get polar motions for times after IERS data is valid." ] if isinstance(iers.IERS_Auto.iers_table, iers.IERS_B): messages_to_find.append( "(some) times are outside of range covered by IERS table.") messages_found = [False for _ in messages_to_find] for w in found_warnings: if issubclass(w.category, AstropyWarning): for i, message_to_find in enumerate(messages_to_find): if message_to_find in str(w.message): messages_found[i] = True assert all(messages_found)
def test_skyoffset_two_frames_interfering(): """Regression test for gh-11277, where it turned out that the origin argument validation from one SkyOffsetFrame could interfere with that of another. Note that this example brought out a different bug than that at the top of gh-11277, viz., that an attempt was made to set origin on a SkyCoord when it should just be stay as part of the SkyOffsetFrame. """ # Example adapted from @bmerry's minimal example at # https://github.com/astropy/astropy/issues/11277#issuecomment-825492335 altaz_frame = AltAz(obstime=Time('2020-04-22T13:00:00Z'), location=EarthLocation(18, -30)) target = SkyCoord(alt=70*u.deg, az=150*u.deg, frame=altaz_frame) dirs_altaz_offset = SkyCoord(lon=[-0.02, 0.01, 0.0, 0.0, 0.0] * u.rad, lat=[0.0, 0.2, 0.0, -0.3, 0.1] * u.rad, frame=target.skyoffset_frame()) dirs_altaz = dirs_altaz_offset.transform_to(altaz_frame) dirs_icrs = dirs_altaz.transform_to(ICRS()) target_icrs = target.transform_to(ICRS()) # The line below was almost guaranteed to fail. dirs_icrs.transform_to(target_icrs.skyoffset_frame())
def test_create_orderered_data(): from astropy.coordinates.builtin_frames import ICRS, Galactic, AltAz TOL = 1e-10 * u.deg i = ICRS(1 * u.deg, 2 * u.deg) assert (i.ra - 1 * u.deg) < TOL assert (i.dec - 2 * u.deg) < TOL g = Galactic(1 * u.deg, 2 * u.deg) assert (g.l - 1 * u.deg) < TOL assert (g.b - 2 * u.deg) < TOL a = AltAz(1 * u.deg, 2 * u.deg) assert (a.az - 1 * u.deg) < TOL assert (a.alt - 2 * u.deg) < TOL with pytest.raises(TypeError): ICRS(1 * u.deg, 2 * u.deg, 1 * u.deg, 2 * u.deg) with pytest.raises(TypeError): sph = r.SphericalRepresentation(1 * u.deg, 2 * u.deg, 3 * u.kpc) ICRS(sph, 1 * u.deg, 2 * u.deg)
def setup(self): lon = Longitude(np.arange(0, 24, 4), u.hourangle) lat = Latitude(np.arange(-90, 91, 30), u.deg) # With same-sized arrays, no attributes self.s0 = ICRS(lon[:, np.newaxis] * np.ones(lat.shape), lat * np.ones(lon.shape)[:, np.newaxis]) # Make an AltAz frame since that has many types of attributes. # Match one axis with times. self.obstime = (Time('2012-01-01') + np.arange(len(lon))[:, np.newaxis] * u.s) # And another with location. self.location = EarthLocation(20.*u.deg, lat, 100*u.m) # Ensure we have a quantity scalar. self.pressure = 1000 * u.hPa # As well as an array. self.temperature = np.random.uniform( 0., 20., size=(lon.size, lat.size)) * u.deg_C self.s1 = AltAz(az=lon[:, np.newaxis], alt=lat, obstime=self.obstime, location=self.location, pressure=self.pressure, temperature=self.temperature) # For some tests, also try a GCRS, since that has representation # attributes. We match the second dimension (via the location) self.obsgeoloc, self.obsgeovel = self.location.get_gcrs_posvel( self.obstime[0, 0]) self.s2 = GCRS(ra=lon[:, np.newaxis], dec=lat, obstime=self.obstime, obsgeoloc=self.obsgeoloc, obsgeovel=self.obsgeovel) # For completeness, also some tests on an empty frame. self.s3 = GCRS(obstime=self.obstime, obsgeoloc=self.obsgeoloc, obsgeovel=self.obsgeovel) # And make a SkyCoord self.sc = SkyCoord(ra=lon[:, np.newaxis], dec=lat, frame=self.s3)
def test_iau_fullstack(fullstack_icrs, fullstack_fiducial_altaz, fullstack_times, fullstack_locations, fullstack_obsconditions): """ Test the full transform from ICRS <-> AltAz """ # create the altaz frame altazframe = AltAz(obstime=fullstack_times, location=fullstack_locations, pressure=fullstack_obsconditions[0], temperature=fullstack_obsconditions[1], relative_humidity=fullstack_obsconditions[2], obswl=fullstack_obsconditions[3]) aacoo = fullstack_icrs.transform_to(altazframe) # compare aacoo to the fiducial AltAz - should always be different assert np.all( np.abs(aacoo.alt - fullstack_fiducial_altaz.alt) > 50 * u.milliarcsecond) assert np.all( np.abs(aacoo.az - fullstack_fiducial_altaz.az) > 50 * u.milliarcsecond) # if the refraction correction is included, we *only* do the comparisons # where altitude >5 degrees. The SOFA guides imply that below 5 is where # where accuracy gets more problematic, and testing reveals that alt<~0 # gives garbage round-tripping, and <10 can give ~1 arcsec uncertainty if fullstack_obsconditions[0].value == 0: # but if there is no refraction correction, check everything msk = slice(None) tol = 5 * u.microarcsecond else: msk = aacoo.alt > 5 * u.deg # most of them aren't this bad, but some of those at low alt are offset # this much. For alt > 10, this is always better than 100 masec tol = 750 * u.milliarcsecond # now make sure the full stack round-tripping works icrs2 = aacoo.transform_to(ICRS) adras = np.abs(fullstack_icrs.ra - icrs2.ra)[msk] addecs = np.abs(fullstack_icrs.dec - icrs2.dec)[msk] assert np.all(adras < tol), 'largest RA change is {} mas, > {}'.format( np.max(adras.arcsec * 1000), tol) assert np.all(addecs < tol), 'largest Dec change is {} mas, > {}'.format( np.max(addecs.arcsec * 1000), tol) # check that we're consistent with the ERFA alt/az result iers_tab = iers.earth_orientation_table.get() xp, yp = u.Quantity(iers_tab.pm_xy(fullstack_times)).to_value(u.radian) lon = fullstack_locations.geodetic[0].to_value(u.radian) lat = fullstack_locations.geodetic[1].to_value(u.radian) height = fullstack_locations.geodetic[2].to_value(u.m) jd1, jd2 = get_jd12(fullstack_times, 'utc') pressure = fullstack_obsconditions[0].to_value(u.hPa) temperature = fullstack_obsconditions[1].to_value(u.deg_C) # Relative humidity can be a quantity or a number. relative_humidity = u.Quantity(fullstack_obsconditions[2], u.one).value obswl = fullstack_obsconditions[3].to_value(u.micron) astrom, eo = erfa.apco13(jd1, jd2, fullstack_times.delta_ut1_utc, lon, lat, height, xp, yp, pressure, temperature, relative_humidity, obswl) erfadct = _erfa_check(fullstack_icrs.ra.rad, fullstack_icrs.dec.rad, astrom) npt.assert_allclose(erfadct['alt'], aacoo.alt.radian, atol=1e-7) npt.assert_allclose(erfadct['az'], aacoo.az.radian, atol=1e-7)
def fullstack_fiducial_altaz(fullstack_icrs): altazframe = AltAz(location=EarthLocation(lat=0 * u.deg, lon=0 * u.deg, height=0 * u.m), obstime=Time('J2000')) return fullstack_icrs.transform_to(altazframe)
class TestManipulation(): """Manipulation of Frame shapes. Checking that attributes are manipulated correctly. Even more exhaustive tests are done in time.tests.test_methods """ def setup(self): lon = Longitude(np.arange(0, 24, 4), u.hourangle) lat = Latitude(np.arange(-90, 91, 30), u.deg) # With same-sized arrays, no attributes self.s0 = ICRS(lon[:, np.newaxis] * np.ones(lat.shape), lat * np.ones(lon.shape)[:, np.newaxis]) # Make an AltAz frame since that has many types of attributes. # Match one axis with times. self.obstime = (Time('2012-01-01') + np.arange(len(lon))[:, np.newaxis] * u.s) # And another with location. self.location = EarthLocation(20.*u.deg, lat, 100*u.m) # Ensure we have a quantity scalar. self.pressure = 1000 * u.hPa # As well as an array. self.temperature = np.random.uniform( 0., 20., size=(lon.size, lat.size)) * u.deg_C self.s1 = AltAz(az=lon[:, np.newaxis], alt=lat, obstime=self.obstime, location=self.location, pressure=self.pressure, temperature=self.temperature) # For some tests, also try a GCRS, since that has representation # attributes. We match the second dimension (via the location) self.obsgeoloc, self.obsgeovel = self.location.get_gcrs_posvel( self.obstime[0, 0]) self.s2 = GCRS(ra=lon[:, np.newaxis], dec=lat, obstime=self.obstime, obsgeoloc=self.obsgeoloc, obsgeovel=self.obsgeovel) # For completeness, also some tests on an empty frame. self.s3 = GCRS(obstime=self.obstime, obsgeoloc=self.obsgeoloc, obsgeovel=self.obsgeovel) # And make a SkyCoord self.sc = SkyCoord(ra=lon[:, np.newaxis], dec=lat, frame=self.s3) def test_ravel(self): s0_ravel = self.s0.ravel() assert s0_ravel.shape == (self.s0.size,) assert np.all(s0_ravel.data.lon == self.s0.data.lon.ravel()) assert np.may_share_memory(s0_ravel.data.lon, self.s0.data.lon) assert np.may_share_memory(s0_ravel.data.lat, self.s0.data.lat) # Since s1 lon, lat were broadcast, ravel needs to make a copy. s1_ravel = self.s1.ravel() assert s1_ravel.shape == (self.s1.size,) assert np.all(s1_ravel.data.lon == self.s1.data.lon.ravel()) assert not np.may_share_memory(s1_ravel.data.lat, self.s1.data.lat) assert np.all(s1_ravel.obstime == self.s1.obstime.ravel()) assert not np.may_share_memory(s1_ravel.obstime.jd1, self.s1.obstime.jd1) assert np.all(s1_ravel.location == self.s1.location.ravel()) assert not np.may_share_memory(s1_ravel.location, self.s1.location) assert np.all(s1_ravel.temperature == self.s1.temperature.ravel()) assert np.may_share_memory(s1_ravel.temperature, self.s1.temperature) assert s1_ravel.pressure == self.s1.pressure s2_ravel = self.s2.ravel() assert s2_ravel.shape == (self.s2.size,) assert np.all(s2_ravel.data.lon == self.s2.data.lon.ravel()) assert not np.may_share_memory(s2_ravel.data.lat, self.s2.data.lat) assert np.all(s2_ravel.obstime == self.s2.obstime.ravel()) assert not np.may_share_memory(s2_ravel.obstime.jd1, self.s2.obstime.jd1) # CartesianRepresentation do not allow direct comparisons, as this is # too tricky to get right in the face of rounding issues. Here, though, # it cannot be an issue, so we compare the xyz quantities. assert np.all(s2_ravel.obsgeoloc.xyz == self.s2.obsgeoloc.ravel().xyz) assert not np.may_share_memory(s2_ravel.obsgeoloc.x, self.s2.obsgeoloc.x) s3_ravel = self.s3.ravel() assert s3_ravel.shape == (42,) # cannot use .size on frame w/o data. assert np.all(s3_ravel.obstime == self.s3.obstime.ravel()) assert not np.may_share_memory(s3_ravel.obstime.jd1, self.s3.obstime.jd1) assert np.all(s3_ravel.obsgeoloc.xyz == self.s3.obsgeoloc.ravel().xyz) assert not np.may_share_memory(s3_ravel.obsgeoloc.x, self.s3.obsgeoloc.x) sc_ravel = self.sc.ravel() assert sc_ravel.shape == (self.sc.size,) assert np.all(sc_ravel.data.lon == self.sc.data.lon.ravel()) assert not np.may_share_memory(sc_ravel.data.lat, self.sc.data.lat) assert np.all(sc_ravel.obstime == self.sc.obstime.ravel()) assert not np.may_share_memory(sc_ravel.obstime.jd1, self.sc.obstime.jd1) assert np.all(sc_ravel.obsgeoloc.xyz == self.sc.obsgeoloc.ravel().xyz) assert not np.may_share_memory(sc_ravel.obsgeoloc.x, self.sc.obsgeoloc.x) def test_flatten(self): s0_flatten = self.s0.flatten() assert s0_flatten.shape == (self.s0.size,) assert np.all(s0_flatten.data.lon == self.s0.data.lon.flatten()) # Flatten always copies. assert not np.may_share_memory(s0_flatten.data.lat, self.s0.data.lat) s1_flatten = self.s1.flatten() assert s1_flatten.shape == (self.s1.size,) assert np.all(s1_flatten.data.lat == self.s1.data.lat.flatten()) assert not np.may_share_memory(s1_flatten.data.lon, self.s1.data.lat) assert np.all(s1_flatten.obstime == self.s1.obstime.flatten()) assert not np.may_share_memory(s1_flatten.obstime.jd1, self.s1.obstime.jd1) assert np.all(s1_flatten.location == self.s1.location.flatten()) assert not np.may_share_memory(s1_flatten.location, self.s1.location) assert np.all(s1_flatten.temperature == self.s1.temperature.flatten()) assert not np.may_share_memory(s1_flatten.temperature, self.s1.temperature) assert s1_flatten.pressure == self.s1.pressure def test_transpose(self): s0_transpose = self.s0.transpose() assert s0_transpose.shape == (7, 6) assert np.all(s0_transpose.data.lon == self.s0.data.lon.transpose()) assert np.may_share_memory(s0_transpose.data.lat, self.s0.data.lat) s1_transpose = self.s1.transpose() assert s1_transpose.shape == (7, 6) assert np.all(s1_transpose.data.lat == self.s1.data.lat.transpose()) assert np.may_share_memory(s1_transpose.data.lon, self.s1.data.lon) assert np.all(s1_transpose.obstime == self.s1.obstime.transpose()) assert np.may_share_memory(s1_transpose.obstime.jd1, self.s1.obstime.jd1) assert np.all(s1_transpose.location == self.s1.location.transpose()) assert np.may_share_memory(s1_transpose.location, self.s1.location) assert np.all(s1_transpose.temperature == self.s1.temperature.transpose()) assert np.may_share_memory(s1_transpose.temperature, self.s1.temperature) assert s1_transpose.pressure == self.s1.pressure # Only one check on T, since it just calls transpose anyway. s1_T = self.s1.T assert s1_T.shape == (7, 6) assert np.all(s1_T.temperature == self.s1.temperature.T) assert np.may_share_memory(s1_T.location, self.s1.location) def test_diagonal(self): s0_diagonal = self.s0.diagonal() assert s0_diagonal.shape == (6,) assert np.all(s0_diagonal.data.lat == self.s0.data.lat.diagonal()) assert np.may_share_memory(s0_diagonal.data.lat, self.s0.data.lat) def test_swapaxes(self): s1_swapaxes = self.s1.swapaxes(0, 1) assert s1_swapaxes.shape == (7, 6) assert np.all(s1_swapaxes.data.lat == self.s1.data.lat.swapaxes(0, 1)) assert np.may_share_memory(s1_swapaxes.data.lat, self.s1.data.lat) assert np.all(s1_swapaxes.obstime == self.s1.obstime.swapaxes(0, 1)) assert np.may_share_memory(s1_swapaxes.obstime.jd1, self.s1.obstime.jd1) assert np.all(s1_swapaxes.location == self.s1.location.swapaxes(0, 1)) assert s1_swapaxes.location.shape == (7, 6) assert np.may_share_memory(s1_swapaxes.location, self.s1.location) assert np.all(s1_swapaxes.temperature == self.s1.temperature.swapaxes(0, 1)) assert np.may_share_memory(s1_swapaxes.temperature, self.s1.temperature) assert s1_swapaxes.pressure == self.s1.pressure def test_reshape(self): s0_reshape = self.s0.reshape(2, 3, 7) assert s0_reshape.shape == (2, 3, 7) assert np.all(s0_reshape.data.lon == self.s0.data.lon.reshape(2, 3, 7)) assert np.all(s0_reshape.data.lat == self.s0.data.lat.reshape(2, 3, 7)) assert np.may_share_memory(s0_reshape.data.lon, self.s0.data.lon) assert np.may_share_memory(s0_reshape.data.lat, self.s0.data.lat) s1_reshape = self.s1.reshape(3, 2, 7) assert s1_reshape.shape == (3, 2, 7) assert np.all(s1_reshape.data.lat == self.s1.data.lat.reshape(3, 2, 7)) assert np.may_share_memory(s1_reshape.data.lat, self.s1.data.lat) assert np.all(s1_reshape.obstime == self.s1.obstime.reshape(3, 2, 7)) assert np.may_share_memory(s1_reshape.obstime.jd1, self.s1.obstime.jd1) assert np.all(s1_reshape.location == self.s1.location.reshape(3, 2, 7)) assert np.may_share_memory(s1_reshape.location, self.s1.location) assert np.all(s1_reshape.temperature == self.s1.temperature.reshape(3, 2, 7)) assert np.may_share_memory(s1_reshape.temperature, self.s1.temperature) assert s1_reshape.pressure == self.s1.pressure # For reshape(3, 14), copying is necessary for lon, lat, location, time s1_reshape2 = self.s1.reshape(3, 14) assert s1_reshape2.shape == (3, 14) assert np.all(s1_reshape2.data.lon == self.s1.data.lon.reshape(3, 14)) assert not np.may_share_memory(s1_reshape2.data.lon, self.s1.data.lon) assert np.all(s1_reshape2.obstime == self.s1.obstime.reshape(3, 14)) assert not np.may_share_memory(s1_reshape2.obstime.jd1, self.s1.obstime.jd1) assert np.all(s1_reshape2.location == self.s1.location.reshape(3, 14)) assert not np.may_share_memory(s1_reshape2.location, self.s1.location) assert np.all(s1_reshape2.temperature == self.s1.temperature.reshape(3, 14)) assert np.may_share_memory(s1_reshape2.temperature, self.s1.temperature) assert s1_reshape2.pressure == self.s1.pressure s2_reshape = self.s2.reshape(3, 2, 7) assert s2_reshape.shape == (3, 2, 7) assert np.all(s2_reshape.data.lon == self.s2.data.lon.reshape(3, 2, 7)) assert np.may_share_memory(s2_reshape.data.lat, self.s2.data.lat) assert np.all(s2_reshape.obstime == self.s2.obstime.reshape(3, 2, 7)) assert np.may_share_memory(s2_reshape.obstime.jd1, self.s2.obstime.jd1) assert np.all(s2_reshape.obsgeoloc.xyz == self.s2.obsgeoloc.reshape(3, 2, 7).xyz) assert np.may_share_memory(s2_reshape.obsgeoloc.x, self.s2.obsgeoloc.x) s3_reshape = self.s3.reshape(3, 2, 7) assert s3_reshape.shape == (3, 2, 7) assert np.all(s3_reshape.obstime == self.s3.obstime.reshape(3, 2, 7)) assert np.may_share_memory(s3_reshape.obstime.jd1, self.s3.obstime.jd1) assert np.all(s3_reshape.obsgeoloc.xyz == self.s3.obsgeoloc.reshape(3, 2, 7).xyz) assert np.may_share_memory(s3_reshape.obsgeoloc.x, self.s3.obsgeoloc.x) sc_reshape = self.sc.reshape(3, 2, 7) assert sc_reshape.shape == (3, 2, 7) assert np.all(sc_reshape.data.lon == self.sc.data.lon.reshape(3, 2, 7)) assert np.may_share_memory(sc_reshape.data.lat, self.sc.data.lat) assert np.all(sc_reshape.obstime == self.sc.obstime.reshape(3, 2, 7)) assert np.may_share_memory(sc_reshape.obstime.jd1, self.sc.obstime.jd1) assert np.all(sc_reshape.obsgeoloc.xyz == self.sc.obsgeoloc.reshape(3, 2, 7).xyz) assert np.may_share_memory(sc_reshape.obsgeoloc.x, self.sc.obsgeoloc.x) # For reshape(3, 14), the arrays all need to be copied. sc_reshape2 = self.sc.reshape(3, 14) assert sc_reshape2.shape == (3, 14) assert np.all(sc_reshape2.data.lon == self.sc.data.lon.reshape(3, 14)) assert not np.may_share_memory(sc_reshape2.data.lat, self.sc.data.lat) assert np.all(sc_reshape2.obstime == self.sc.obstime.reshape(3, 14)) assert not np.may_share_memory(sc_reshape2.obstime.jd1, self.sc.obstime.jd1) assert np.all(sc_reshape2.obsgeoloc.xyz == self.sc.obsgeoloc.reshape(3, 14).xyz) assert not np.may_share_memory(sc_reshape2.obsgeoloc.x, self.sc.obsgeoloc.x) def test_squeeze(self): s0_squeeze = self.s0.reshape(3, 1, 2, 1, 7).squeeze() assert s0_squeeze.shape == (3, 2, 7) assert np.all(s0_squeeze.data.lat == self.s0.data.lat.reshape(3, 2, 7)) assert np.may_share_memory(s0_squeeze.data.lat, self.s0.data.lat) def test_add_dimension(self): s0_adddim = self.s0[:, np.newaxis, :] assert s0_adddim.shape == (6, 1, 7) assert np.all(s0_adddim.data.lon == self.s0.data.lon[:, np.newaxis, :]) assert np.may_share_memory(s0_adddim.data.lat, self.s0.data.lat) def test_take(self): s0_take = self.s0.take((5, 2)) assert s0_take.shape == (2,) assert np.all(s0_take.data.lon == self.s0.data.lon.take((5, 2)))
class TestManipulation(): """Manipulation of Frame shapes. Checking that attributes are manipulated correctly. Even more exhaustive tests are done in time.tests.test_methods """ def setup(self): # For these tests, we set up frames and coordinates using copy=False, # so we can check that broadcasting is handled correctly. lon = Longitude(np.arange(0, 24, 4), u.hourangle) lat = Latitude(np.arange(-90, 91, 30), u.deg) # With same-sized arrays, no attributes. self.s0 = ICRS(lon[:, np.newaxis] * np.ones(lat.shape), lat * np.ones(lon.shape)[:, np.newaxis], copy=False) # Make an AltAz frame since that has many types of attributes. # Match one axis with times. self.obstime = (Time('2012-01-01') + np.arange(len(lon))[:, np.newaxis] * u.s) # And another with location. self.location = EarthLocation(20.*u.deg, lat, 100*u.m) # Ensure we have a quantity scalar. self.pressure = 1000 * u.hPa # As well as an array. self.temperature = np.random.uniform( 0., 20., size=(lon.size, lat.size)) * u.deg_C self.s1 = AltAz(az=lon[:, np.newaxis], alt=lat, obstime=self.obstime, location=self.location, pressure=self.pressure, temperature=self.temperature, copy=False) # For some tests, also try a GCRS, since that has representation # attributes. We match the second dimension (via the location) self.obsgeoloc, self.obsgeovel = self.location.get_gcrs_posvel( self.obstime[0, 0]) self.s2 = GCRS(ra=lon[:, np.newaxis], dec=lat, obstime=self.obstime, obsgeoloc=self.obsgeoloc, obsgeovel=self.obsgeovel, copy=False) # For completeness, also some tests on an empty frame. self.s3 = GCRS(obstime=self.obstime, obsgeoloc=self.obsgeoloc, obsgeovel=self.obsgeovel, copy=False) # And make a SkyCoord self.sc = SkyCoord(ra=lon[:, np.newaxis], dec=lat, frame=self.s3, copy=False) def test_getitem0101(self): # We on purpose take a slice with only one element, as for the # general tests it doesn't matter, but it allows us to check # for a few cases that shapes correctly become scalar if we # index our size-1 array down to a scalar. See gh-10113. item = (slice(0, 1), slice(0, 1)) s0_0101 = self.s0[item] assert s0_0101.shape == (1, 1) assert_array_equal(s0_0101.data.lon, self.s0.data.lon[item]) assert np.may_share_memory(s0_0101.data.lon, self.s0.data.lon) assert np.may_share_memory(s0_0101.data.lat, self.s0.data.lat) s0_0101_00 = s0_0101[0, 0] assert s0_0101_00.shape == () assert s0_0101_00.data.lon.shape == () assert_array_equal(s0_0101_00.data.lon, self.s0.data.lon[0, 0]) s1_0101 = self.s1[item] assert s1_0101.shape == (1, 1) assert_array_equal(s1_0101.data.lon, self.s1.data.lon[item]) assert np.may_share_memory(s1_0101.data.lat, self.s1.data.lat) assert np.all(s1_0101.obstime == self.s1.obstime[item]) assert np.may_share_memory(s1_0101.obstime.jd1, self.s1.obstime.jd1) assert_array_equal(s1_0101.location, self.s1.location[0, 0]) assert np.may_share_memory(s1_0101.location, self.s1.location) assert_array_equal(s1_0101.temperature, self.s1.temperature[item]) assert np.may_share_memory(s1_0101.temperature, self.s1.temperature) # scalar should just be transferred. assert s1_0101.pressure is self.s1.pressure s1_0101_00 = s1_0101[0, 0] assert s1_0101_00.shape == () assert s1_0101_00.obstime.shape == () assert s1_0101_00.obstime == self.s1.obstime[0, 0] s2_0101 = self.s2[item] assert s2_0101.shape == (1, 1) assert np.all(s2_0101.data.lon == self.s2.data.lon[item]) assert np.may_share_memory(s2_0101.data.lat, self.s2.data.lat) assert np.all(s2_0101.obstime == self.s2.obstime[item]) assert np.may_share_memory(s2_0101.obstime.jd1, self.s2.obstime.jd1) assert_array_equal(s2_0101.obsgeoloc.xyz, self.s2.obsgeoloc[item].xyz) s3_0101 = self.s3[item] assert s3_0101.shape == (1, 1) assert s3_0101.obstime.shape == (1, 1) assert np.all(s3_0101.obstime == self.s3.obstime[item]) assert np.may_share_memory(s3_0101.obstime.jd1, self.s3.obstime.jd1) assert_array_equal(s3_0101.obsgeoloc.xyz, self.s3.obsgeoloc[item].xyz) sc_0101 = self.sc[item] assert sc_0101.shape == (1, 1) assert_array_equal(sc_0101.data.lon, self.sc.data.lon[item]) assert np.may_share_memory(sc_0101.data.lat, self.sc.data.lat) assert np.all(sc_0101.obstime == self.sc.obstime[item]) assert np.may_share_memory(sc_0101.obstime.jd1, self.sc.obstime.jd1) assert_array_equal(sc_0101.obsgeoloc.xyz, self.sc.obsgeoloc[item].xyz) def test_ravel(self): s0_ravel = self.s0.ravel() assert s0_ravel.shape == (self.s0.size,) assert np.all(s0_ravel.data.lon == self.s0.data.lon.ravel()) assert np.may_share_memory(s0_ravel.data.lon, self.s0.data.lon) assert np.may_share_memory(s0_ravel.data.lat, self.s0.data.lat) # Since s1 lon, lat were broadcast, ravel needs to make a copy. s1_ravel = self.s1.ravel() assert s1_ravel.shape == (self.s1.size,) assert np.all(s1_ravel.data.lon == self.s1.data.lon.ravel()) assert not np.may_share_memory(s1_ravel.data.lat, self.s1.data.lat) assert np.all(s1_ravel.obstime == self.s1.obstime.ravel()) assert not np.may_share_memory(s1_ravel.obstime.jd1, self.s1.obstime.jd1) assert np.all(s1_ravel.location == self.s1.location.ravel()) assert not np.may_share_memory(s1_ravel.location, self.s1.location) assert np.all(s1_ravel.temperature == self.s1.temperature.ravel()) assert np.may_share_memory(s1_ravel.temperature, self.s1.temperature) assert s1_ravel.pressure == self.s1.pressure s2_ravel = self.s2.ravel() assert s2_ravel.shape == (self.s2.size,) assert np.all(s2_ravel.data.lon == self.s2.data.lon.ravel()) assert not np.may_share_memory(s2_ravel.data.lat, self.s2.data.lat) assert np.all(s2_ravel.obstime == self.s2.obstime.ravel()) assert not np.may_share_memory(s2_ravel.obstime.jd1, self.s2.obstime.jd1) # CartesianRepresentation do not allow direct comparisons, as this is # too tricky to get right in the face of rounding issues. Here, though, # it cannot be an issue, so we compare the xyz quantities. assert np.all(s2_ravel.obsgeoloc.xyz == self.s2.obsgeoloc.ravel().xyz) assert not np.may_share_memory(s2_ravel.obsgeoloc.x, self.s2.obsgeoloc.x) s3_ravel = self.s3.ravel() assert s3_ravel.shape == (42,) # cannot use .size on frame w/o data. assert np.all(s3_ravel.obstime == self.s3.obstime.ravel()) assert not np.may_share_memory(s3_ravel.obstime.jd1, self.s3.obstime.jd1) assert np.all(s3_ravel.obsgeoloc.xyz == self.s3.obsgeoloc.ravel().xyz) assert not np.may_share_memory(s3_ravel.obsgeoloc.x, self.s3.obsgeoloc.x) sc_ravel = self.sc.ravel() assert sc_ravel.shape == (self.sc.size,) assert np.all(sc_ravel.data.lon == self.sc.data.lon.ravel()) assert not np.may_share_memory(sc_ravel.data.lat, self.sc.data.lat) assert np.all(sc_ravel.obstime == self.sc.obstime.ravel()) assert not np.may_share_memory(sc_ravel.obstime.jd1, self.sc.obstime.jd1) assert np.all(sc_ravel.obsgeoloc.xyz == self.sc.obsgeoloc.ravel().xyz) assert not np.may_share_memory(sc_ravel.obsgeoloc.x, self.sc.obsgeoloc.x) def test_flatten(self): s0_flatten = self.s0.flatten() assert s0_flatten.shape == (self.s0.size,) assert np.all(s0_flatten.data.lon == self.s0.data.lon.flatten()) # Flatten always copies. assert not np.may_share_memory(s0_flatten.data.lat, self.s0.data.lat) s1_flatten = self.s1.flatten() assert s1_flatten.shape == (self.s1.size,) assert np.all(s1_flatten.data.lat == self.s1.data.lat.flatten()) assert not np.may_share_memory(s1_flatten.data.lon, self.s1.data.lat) assert np.all(s1_flatten.obstime == self.s1.obstime.flatten()) assert not np.may_share_memory(s1_flatten.obstime.jd1, self.s1.obstime.jd1) assert np.all(s1_flatten.location == self.s1.location.flatten()) assert not np.may_share_memory(s1_flatten.location, self.s1.location) assert np.all(s1_flatten.temperature == self.s1.temperature.flatten()) assert not np.may_share_memory(s1_flatten.temperature, self.s1.temperature) assert s1_flatten.pressure == self.s1.pressure def test_transpose(self): s0_transpose = self.s0.transpose() assert s0_transpose.shape == (7, 6) assert np.all(s0_transpose.data.lon == self.s0.data.lon.transpose()) assert np.may_share_memory(s0_transpose.data.lat, self.s0.data.lat) s1_transpose = self.s1.transpose() assert s1_transpose.shape == (7, 6) assert np.all(s1_transpose.data.lat == self.s1.data.lat.transpose()) assert np.may_share_memory(s1_transpose.data.lon, self.s1.data.lon) assert np.all(s1_transpose.obstime == self.s1.obstime.transpose()) assert np.may_share_memory(s1_transpose.obstime.jd1, self.s1.obstime.jd1) assert np.all(s1_transpose.location == self.s1.location.transpose()) assert np.may_share_memory(s1_transpose.location, self.s1.location) assert np.all(s1_transpose.temperature == self.s1.temperature.transpose()) assert np.may_share_memory(s1_transpose.temperature, self.s1.temperature) assert s1_transpose.pressure == self.s1.pressure # Only one check on T, since it just calls transpose anyway. s1_T = self.s1.T assert s1_T.shape == (7, 6) assert np.all(s1_T.temperature == self.s1.temperature.T) assert np.may_share_memory(s1_T.location, self.s1.location) def test_diagonal(self): s0_diagonal = self.s0.diagonal() assert s0_diagonal.shape == (6,) assert np.all(s0_diagonal.data.lat == self.s0.data.lat.diagonal()) assert np.may_share_memory(s0_diagonal.data.lat, self.s0.data.lat) def test_swapaxes(self): s1_swapaxes = self.s1.swapaxes(0, 1) assert s1_swapaxes.shape == (7, 6) assert np.all(s1_swapaxes.data.lat == self.s1.data.lat.swapaxes(0, 1)) assert np.may_share_memory(s1_swapaxes.data.lat, self.s1.data.lat) assert np.all(s1_swapaxes.obstime == self.s1.obstime.swapaxes(0, 1)) assert np.may_share_memory(s1_swapaxes.obstime.jd1, self.s1.obstime.jd1) assert np.all(s1_swapaxes.location == self.s1.location.swapaxes(0, 1)) assert s1_swapaxes.location.shape == (7, 6) assert np.may_share_memory(s1_swapaxes.location, self.s1.location) assert np.all(s1_swapaxes.temperature == self.s1.temperature.swapaxes(0, 1)) assert np.may_share_memory(s1_swapaxes.temperature, self.s1.temperature) assert s1_swapaxes.pressure == self.s1.pressure def test_reshape(self): s0_reshape = self.s0.reshape(2, 3, 7) assert s0_reshape.shape == (2, 3, 7) assert np.all(s0_reshape.data.lon == self.s0.data.lon.reshape(2, 3, 7)) assert np.all(s0_reshape.data.lat == self.s0.data.lat.reshape(2, 3, 7)) assert np.may_share_memory(s0_reshape.data.lon, self.s0.data.lon) assert np.may_share_memory(s0_reshape.data.lat, self.s0.data.lat) s1_reshape = self.s1.reshape(3, 2, 7) assert s1_reshape.shape == (3, 2, 7) assert np.all(s1_reshape.data.lat == self.s1.data.lat.reshape(3, 2, 7)) assert np.may_share_memory(s1_reshape.data.lat, self.s1.data.lat) assert np.all(s1_reshape.obstime == self.s1.obstime.reshape(3, 2, 7)) assert np.may_share_memory(s1_reshape.obstime.jd1, self.s1.obstime.jd1) assert np.all(s1_reshape.location == self.s1.location.reshape(3, 2, 7)) assert np.may_share_memory(s1_reshape.location, self.s1.location) assert np.all(s1_reshape.temperature == self.s1.temperature.reshape(3, 2, 7)) assert np.may_share_memory(s1_reshape.temperature, self.s1.temperature) assert s1_reshape.pressure == self.s1.pressure # For reshape(3, 14), copying is necessary for lon, lat, location, time s1_reshape2 = self.s1.reshape(3, 14) assert s1_reshape2.shape == (3, 14) assert np.all(s1_reshape2.data.lon == self.s1.data.lon.reshape(3, 14)) assert not np.may_share_memory(s1_reshape2.data.lon, self.s1.data.lon) assert np.all(s1_reshape2.obstime == self.s1.obstime.reshape(3, 14)) assert not np.may_share_memory(s1_reshape2.obstime.jd1, self.s1.obstime.jd1) assert np.all(s1_reshape2.location == self.s1.location.reshape(3, 14)) assert not np.may_share_memory(s1_reshape2.location, self.s1.location) assert np.all(s1_reshape2.temperature == self.s1.temperature.reshape(3, 14)) assert np.may_share_memory(s1_reshape2.temperature, self.s1.temperature) assert s1_reshape2.pressure == self.s1.pressure s2_reshape = self.s2.reshape(3, 2, 7) assert s2_reshape.shape == (3, 2, 7) assert np.all(s2_reshape.data.lon == self.s2.data.lon.reshape(3, 2, 7)) assert np.may_share_memory(s2_reshape.data.lat, self.s2.data.lat) assert np.all(s2_reshape.obstime == self.s2.obstime.reshape(3, 2, 7)) assert np.may_share_memory(s2_reshape.obstime.jd1, self.s2.obstime.jd1) assert np.all(s2_reshape.obsgeoloc.xyz == self.s2.obsgeoloc.reshape(3, 2, 7).xyz) assert np.may_share_memory(s2_reshape.obsgeoloc.x, self.s2.obsgeoloc.x) s3_reshape = self.s3.reshape(3, 2, 7) assert s3_reshape.shape == (3, 2, 7) assert np.all(s3_reshape.obstime == self.s3.obstime.reshape(3, 2, 7)) assert np.may_share_memory(s3_reshape.obstime.jd1, self.s3.obstime.jd1) assert np.all(s3_reshape.obsgeoloc.xyz == self.s3.obsgeoloc.reshape(3, 2, 7).xyz) assert np.may_share_memory(s3_reshape.obsgeoloc.x, self.s3.obsgeoloc.x) sc_reshape = self.sc.reshape(3, 2, 7) assert sc_reshape.shape == (3, 2, 7) assert np.all(sc_reshape.data.lon == self.sc.data.lon.reshape(3, 2, 7)) assert np.may_share_memory(sc_reshape.data.lat, self.sc.data.lat) assert np.all(sc_reshape.obstime == self.sc.obstime.reshape(3, 2, 7)) assert np.may_share_memory(sc_reshape.obstime.jd1, self.sc.obstime.jd1) assert np.all(sc_reshape.obsgeoloc.xyz == self.sc.obsgeoloc.reshape(3, 2, 7).xyz) assert np.may_share_memory(sc_reshape.obsgeoloc.x, self.sc.obsgeoloc.x) # For reshape(3, 14), the arrays all need to be copied. sc_reshape2 = self.sc.reshape(3, 14) assert sc_reshape2.shape == (3, 14) assert np.all(sc_reshape2.data.lon == self.sc.data.lon.reshape(3, 14)) assert not np.may_share_memory(sc_reshape2.data.lat, self.sc.data.lat) assert np.all(sc_reshape2.obstime == self.sc.obstime.reshape(3, 14)) assert not np.may_share_memory(sc_reshape2.obstime.jd1, self.sc.obstime.jd1) assert np.all(sc_reshape2.obsgeoloc.xyz == self.sc.obsgeoloc.reshape(3, 14).xyz) assert not np.may_share_memory(sc_reshape2.obsgeoloc.x, self.sc.obsgeoloc.x) def test_squeeze(self): s0_squeeze = self.s0.reshape(3, 1, 2, 1, 7).squeeze() assert s0_squeeze.shape == (3, 2, 7) assert np.all(s0_squeeze.data.lat == self.s0.data.lat.reshape(3, 2, 7)) assert np.may_share_memory(s0_squeeze.data.lat, self.s0.data.lat) def test_add_dimension(self): s0_adddim = self.s0[:, np.newaxis, :] assert s0_adddim.shape == (6, 1, 7) assert np.all(s0_adddim.data.lon == self.s0.data.lon[:, np.newaxis, :]) assert np.may_share_memory(s0_adddim.data.lat, self.s0.data.lat) def test_take(self): s0_take = self.s0.take((5, 2)) assert s0_take.shape == (2,) assert np.all(s0_take.data.lon == self.s0.data.lon.take((5, 2)))
def test_against_hor2eq(): """Check that Astropy gives consistent results with an IDL hor2eq example. See : http://idlastro.gsfc.nasa.gov/ftp/pro/astro/hor2eq.pro Test is against these run outputs, run at 2000-01-01T12:00:00:: # NORMAL ATMOSPHERE CASE IDL> hor2eq, ten(37,54,41), ten(264,55,06), 2451545.0d, ra, dec, /verb, obs='kpno', pres=781.0, temp=273.0 Latitude = +31 57 48.0 Longitude = *** 36 00.0 Julian Date = 2451545.000000 Az, El = 17 39 40.4 +37 54 41 (Observer Coords) Az, El = 17 39 40.4 +37 53 40 (Apparent Coords) LMST = +11 15 26.5 LAST = +11 15 25.7 Hour Angle = +03 38 30.1 (hh:mm:ss) Ra, Dec: 07 36 55.6 +15 25 02 (Apparent Coords) Ra, Dec: 07 36 55.2 +15 25 08 (J2000.0000) Ra, Dec: 07 36 55.2 +15 25 08 (J2000) IDL> print, ra, dec 114.23004 15.418818 # NO PRESSURE CASE IDL> hor2eq, ten(37,54,41), ten(264,55,06), 2451545.0d, ra, dec, /verb, obs='kpno', pres=0.0, temp=273.0 Latitude = +31 57 48.0 Longitude = *** 36 00.0 Julian Date = 2451545.000000 Az, El = 17 39 40.4 +37 54 41 (Observer Coords) Az, El = 17 39 40.4 +37 54 41 (Apparent Coords) LMST = +11 15 26.5 LAST = +11 15 25.7 Hour Angle = +03 38 26.4 (hh:mm:ss) Ra, Dec: 07 36 59.3 +15 25 31 (Apparent Coords) Ra, Dec: 07 36 58.9 +15 25 37 (J2000.0000) Ra, Dec: 07 36 58.9 +15 25 37 (J2000) IDL> print, ra, dec 114.24554 15.427022 """ # Observatory position for `kpno` from here: # http://idlastro.gsfc.nasa.gov/ftp/pro/astro/observatory.pro location = EarthLocation(lon=Angle('-111d36.0m'), lat=Angle('31d57.8m'), height=2120. * u.m) obstime = Time(2451545.0, format='jd', scale='ut1') altaz_frame = AltAz(obstime=obstime, location=location, temperature=0 * u.deg_C, pressure=0.781 * u.bar) altaz_frame_noatm = AltAz(obstime=obstime, location=location, temperature=0 * u.deg_C, pressure=0.0 * u.bar) altaz = SkyCoord('264d55m06s 37d54m41s', frame=altaz_frame) altaz_noatm = SkyCoord('264d55m06s 37d54m41s', frame=altaz_frame_noatm) radec_frame = 'icrs' radec_actual = altaz.transform_to(radec_frame) radec_actual_noatm = altaz_noatm.transform_to(radec_frame) radec_expected = SkyCoord('07h36m55.2s +15d25m08s', frame=radec_frame) distance = radec_actual.separation(radec_expected).to('arcsec') # this comes from running the example hor2eq but with the pressure set to 0 radec_expected_noatm = SkyCoord('07h36m58.9s +15d25m37s', frame=radec_frame) distance_noatm = radec_actual_noatm.separation(radec_expected_noatm).to( 'arcsec') # The baseline difference is ~2.3 arcsec with one atm of pressure. The # difference is mainly due to the somewhat different atmospheric model that # hor2eq assumes. This is confirmed by the second test which has the # atmosphere "off" - the residual difference is small enough to be embedded # in the assumptions about "J2000" or rounding errors. assert distance < 5 * u.arcsec assert distance_noatm < 0.4 * u.arcsec