/
test_regression.py
745 lines (602 loc) · 26.2 KB
/
test_regression.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""
Regression tests for coordinates-related bugs that don't have an obvious other
place to live
"""
import copy
import io
from contextlib import nullcontext
import numpy as np
import pytest
from erfa import ErfaWarning
from astropy import units as u
from astropy.coordinates import (
CIRS,
FK4,
GCRS,
HCRS,
ICRS,
ITRS,
AltAz,
BaseCoordinateFrame,
CartesianDifferential,
CartesianRepresentation,
CylindricalDifferential,
CylindricalRepresentation,
EarthLocation,
FK4NoETerms,
FunctionTransform,
GeocentricMeanEcliptic,
Latitude,
Longitude,
QuantityAttribute,
SkyCoord,
SphericalRepresentation,
UnitSphericalRepresentation,
get_body,
get_sun,
)
from astropy.coordinates.sites import get_builtin_sites
from astropy.table import Table
from astropy.tests.helper import assert_quantity_allclose
from astropy.time import Time
from astropy.units import allclose as quantity_allclose
from astropy.utils import iers
from astropy.utils.compat.optional_deps import HAS_SCIPY
def test_regression_5085():
"""
PR #5085 was put in place to fix the following issue.
Issue: https://github.com/astropy/astropy/issues/5069
At root was the transformation of Ecliptic coordinates with
non-scalar times.
"""
# Note: for regression test, we need to be sure that we use UTC for the
# epoch, even though more properly that should be TT; but the "expected"
# values were calculated using that.
j2000 = Time("J2000", scale="utc")
times = Time(["2015-08-28 03:30", "2015-09-05 10:30", "2015-09-15 18:35"])
latitudes = Latitude([3.9807075, -5.00733806, 1.69539491] * u.deg)
longitudes = Longitude([311.79678613, 72.86626741, 199.58698226] * u.deg)
distances = u.Quantity([0.00243266, 0.0025424, 0.00271296] * u.au)
coo = GeocentricMeanEcliptic(
lat=latitudes, lon=longitudes, distance=distances, obstime=times, equinox=times
)
# expected result
ras = Longitude([310.50095400, 314.67109920, 319.56507428] * u.deg)
decs = Latitude([-18.25190443, -17.1556676, -15.71616522] * u.deg)
distances = u.Quantity([1.78309901, 1.710874, 1.61326649] * u.au)
expected_result = GCRS(
ra=ras, dec=decs, distance=distances, obstime=j2000
).cartesian.xyz
actual_result = coo.transform_to(GCRS(obstime=j2000)).cartesian.xyz
assert_quantity_allclose(expected_result, actual_result)
def test_regression_3920():
"""
Issue: https://github.com/astropy/astropy/issues/3920
"""
loc = EarthLocation.from_geodetic(0 * u.deg, 0 * u.deg, 0)
time = Time("2010-1-1")
aa = AltAz(location=loc, obstime=time)
sc = SkyCoord(10 * u.deg, 3 * u.deg)
assert sc.transform_to(aa).shape == tuple()
# That part makes sense: the input is a scalar so the output is too
sc2 = SkyCoord(10 * u.deg, 3 * u.deg, 1 * u.AU)
assert sc2.transform_to(aa).shape == tuple()
# in 3920 that assert fails, because the shape is (1,)
# check that the same behavior occurs even if transform is from low-level classes
icoo = ICRS(sc.data)
icoo2 = ICRS(sc2.data)
assert icoo.transform_to(aa).shape == tuple()
assert icoo2.transform_to(aa).shape == tuple()
def test_regression_3938():
"""
Issue: https://github.com/astropy/astropy/issues/3938
"""
# Set up list of targets - we don't use `from_name` here to avoid
# remote_data requirements, but it does the same thing
# vega = SkyCoord.from_name('Vega')
vega = SkyCoord(279.23473479 * u.deg, 38.78368896 * u.deg)
# capella = SkyCoord.from_name('Capella')
capella = SkyCoord(79.17232794 * u.deg, 45.99799147 * u.deg)
# sirius = SkyCoord.from_name('Sirius')
sirius = SkyCoord(101.28715533 * u.deg, -16.71611586 * u.deg)
targets = [vega, capella, sirius]
# Feed list of targets into SkyCoord
combined_coords = SkyCoord(targets)
# Set up AltAz frame
time = Time("2012-01-01 00:00:00")
location = EarthLocation("10d", "45d", 0)
aa = AltAz(location=location, obstime=time)
combined_coords.transform_to(aa)
# in 3938 the above yields ``UnitConversionError: '' (dimensionless) and 'pc' (length) are not convertible``
def test_regression_3998():
"""
Issue: https://github.com/astropy/astropy/issues/3998
"""
time = Time("2012-01-01 00:00:00")
assert time.isscalar
sun = get_sun(time)
assert sun.isscalar
# in 3998, the above yields False - `sun` is a length-1 vector
assert sun.obstime is time
def test_regression_4033():
"""
Issue: https://github.com/astropy/astropy/issues/4033
"""
# alb = SkyCoord.from_name('Albireo')
alb = SkyCoord(292.68033548 * u.deg, 27.95968007 * u.deg)
alb_wdist = SkyCoord(alb, distance=133 * u.pc)
# de = SkyCoord.from_name('Deneb')
de = SkyCoord(310.35797975 * u.deg, 45.28033881 * u.deg)
de_wdist = SkyCoord(de, distance=802 * u.pc)
aa = AltAz(
location=EarthLocation(lat=45 * u.deg, lon=0 * u.deg), obstime="2010-1-1"
)
deaa = de.transform_to(aa)
albaa = alb.transform_to(aa)
alb_wdistaa = alb_wdist.transform_to(aa)
de_wdistaa = de_wdist.transform_to(aa)
# these work fine
sepnod = deaa.separation(albaa)
sepwd = deaa.separation(alb_wdistaa)
assert_quantity_allclose(sepnod, 22.2862 * u.deg, rtol=1e-6)
assert_quantity_allclose(sepwd, 22.2862 * u.deg, rtol=1e-6)
# parallax should be present when distance added
assert np.abs(sepnod - sepwd) > 1 * u.marcsec
# in 4033, the following fail with a recursion error
assert_quantity_allclose(
de_wdistaa.separation(alb_wdistaa), 22.2862 * u.deg, rtol=1e-3
)
assert_quantity_allclose(alb_wdistaa.separation(deaa), 22.2862 * u.deg, rtol=1e-3)
@pytest.mark.skipif(not HAS_SCIPY, reason="No Scipy")
def test_regression_4082():
"""
Issue: https://github.com/astropy/astropy/issues/4082
"""
from astropy.coordinates import search_around_3d, search_around_sky
cat = SkyCoord([10.076, 10.00455], [18.54746, 18.54896], unit="deg")
search_around_sky(cat[0:1], cat, seplimit=u.arcsec * 60, storekdtree=False)
# in the issue, this raises a TypeError
# also check 3d for good measure, although it's not really affected by this bug directly
cat3d = SkyCoord(
[10.076, 10.00455] * u.deg,
[18.54746, 18.54896] * u.deg,
distance=[0.1, 1.5] * u.kpc,
)
search_around_3d(cat3d[0:1], cat3d, 1 * u.kpc, storekdtree=False)
def test_regression_4210():
"""
Issue: https://github.com/astropy/astropy/issues/4210
Related PR with actual change: https://github.com/astropy/astropy/pull/4211
"""
crd = SkyCoord(0 * u.deg, 0 * u.deg, distance=1 * u.AU)
ecl = crd.geocentricmeanecliptic
# bug was that "lambda", which at the time was the name of the geocentric
# ecliptic longitude, is a reserved keyword. So this just makes sure the
# new name is are all valid
ecl.lon
# and for good measure, check the other ecliptic systems are all the same
# names for their attributes
from astropy.coordinates.builtin_frames import ecliptic
for frame_name in ecliptic.__all__:
eclcls = getattr(ecliptic, frame_name)
eclobj = eclcls(1 * u.deg, 2 * u.deg, 3 * u.AU)
eclobj.lat
eclobj.lon
eclobj.distance
def test_regression_futuretimes_4302():
"""
Checks that an error is not raised for future times not covered by IERS
tables (at least in a simple transform like CIRS->ITRS that simply requires
the UTC<->UT1 conversion).
Relevant comment: https://github.com/astropy/astropy/pull/4302#discussion_r44836531
"""
# 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
from astropy.utils.exceptions import AstropyWarning
if hasattr(utils, "__warningregistry__"):
utils.__warningregistry__.clear()
# check that out-of-range warning appears 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.
if isinstance(iers.earth_orientation_table.get(), iers.IERS_B):
ctx = pytest.warns(
AstropyWarning,
match=r"\(some\) times are outside of range covered by IERS table.*",
)
else:
ctx = nullcontext()
with ctx:
future_time = Time("2511-5-1")
c = CIRS(1 * u.deg, 2 * u.deg, obstime=future_time)
c.transform_to(ITRS(obstime=future_time))
def test_regression_4996():
# this part is the actual regression test
deltat = np.linspace(-12, 12, 1000) * u.hour
times = Time("2012-7-13 00:00:00") + deltat
suncoo = get_sun(times)
assert suncoo.shape == (len(times),)
# and this is an additional test to make sure more complex arrays work
times2 = Time("2012-7-13 00:00:00") + deltat.reshape(10, 20, 5)
suncoo2 = get_sun(times2)
assert suncoo2.shape == times2.shape
# this is intentionally not allclose - they should be *exactly* the same
assert np.all(suncoo.ra.ravel() == suncoo2.ra.ravel())
def test_regression_4293():
"""Really just an extra test on FK4 no e, after finding that the units
were not always taken correctly. This test is against explicitly doing
the transformations on pp170 of Explanatory Supplement to the Astronomical
Almanac (Seidelmann, 2005).
See https://github.com/astropy/astropy/pull/4293#issuecomment-234973086
"""
# Check all over sky, but avoiding poles (note that FK4 did not ignore
# e terms within 10∘ of the poles... see p170 of explan.supp.).
ra, dec = np.meshgrid(np.arange(0, 359, 45), np.arange(-80, 81, 40))
fk4 = FK4(ra.ravel() * u.deg, dec.ravel() * u.deg)
Dc = -0.065838 * u.arcsec
Dd = +0.335299 * u.arcsec
# Dc * tan(obliquity), as given on p.170
Dctano = -0.028553 * u.arcsec
fk4noe_dec = (
fk4.dec
- (Dd * np.cos(fk4.ra) - Dc * np.sin(fk4.ra)) * np.sin(fk4.dec)
- Dctano * np.cos(fk4.dec)
)
fk4noe_ra = fk4.ra - (Dc * np.cos(fk4.ra) + Dd * np.sin(fk4.ra)) / np.cos(fk4.dec)
fk4noe = fk4.transform_to(FK4NoETerms())
# Tolerance here just set to how well the coordinates match, which is much
# better than the claimed accuracy of <1 mas for this first-order in
# v_earth/c approximation.
# Interestingly, if one divides by np.cos(fk4noe_dec) in the ra correction,
# the match becomes good to 2 μas.
assert_quantity_allclose(fk4noe.ra, fk4noe_ra, atol=11.0 * u.uas, rtol=0)
assert_quantity_allclose(fk4noe.dec, fk4noe_dec, atol=3.0 * u.uas, rtol=0)
def test_regression_4926():
times = Time("2010-01-1") + np.arange(20) * u.day
green = get_builtin_sites()["greenwich"]
# this is the regression test
moon = get_body("moon", times, green)
# this is an additional test to make sure the GCRS->ICRS transform works for complex shapes
moon.transform_to(ICRS())
# and some others to increase coverage of transforms
moon.transform_to(HCRS(obstime="J2000"))
moon.transform_to(HCRS(obstime=times))
def test_regression_5209():
"check that distances are not lost on SkyCoord init"
time = Time("2015-01-01")
moon = get_body("moon", time)
new_coord = SkyCoord([moon])
assert_quantity_allclose(new_coord[0].distance, moon.distance)
def test_regression_5133():
N = 1000
np.random.seed(12345)
lon = np.random.uniform(-10, 10, N) * u.deg
lat = np.random.uniform(50, 52, N) * u.deg
alt = np.random.uniform(0, 10.0, N) * u.km
time = Time("2010-1-1")
objects = EarthLocation.from_geodetic(lon, lat, height=alt)
itrs_coo = objects.get_itrs(time)
homes = [
EarthLocation.from_geodetic(lon=-1 * u.deg, lat=52 * u.deg, height=h)
for h in (0, 1000, 10000) * u.km
]
altaz_frames = [AltAz(obstime=time, location=h) for h in homes]
altaz_coos = [itrs_coo.transform_to(f) for f in altaz_frames]
# they should all be different
for coo in altaz_coos[1:]:
assert not quantity_allclose(coo.az, coo.az[0])
assert not quantity_allclose(coo.alt, coo.alt[0])
def test_itrs_vals_5133():
"""
Test to check if alt-az calculations respect height of observer
Because ITRS is geocentric and includes aberration, an object that
appears 'straight up' to a geocentric observer (ITRS) won't be
straight up to a topocentric observer - see
https://github.com/astropy/astropy/issues/10983
This is worse for small height above the Earth, which is why this test
uses large distances.
"""
time = Time("2010-1-1")
height = 500000.0 * u.km
el = EarthLocation.from_geodetic(lon=20 * u.deg, lat=45 * u.deg, height=height)
lons = [20, 30, 20] * u.deg
lats = [44, 45, 45] * u.deg
alts = u.Quantity([height, height, 10 * height])
coos = [
EarthLocation.from_geodetic(lon, lat, height=alt).get_itrs(time)
for lon, lat, alt in zip(lons, lats, alts)
]
aaf = AltAz(obstime=time, location=el)
aacs = [coo.transform_to(aaf) for coo in coos]
assert all([coo.isscalar for coo in aacs])
# the ~1 degree tolerance is b/c aberration makes it not exact
assert_quantity_allclose(aacs[0].az, 180 * u.deg, atol=1 * u.deg)
assert aacs[0].alt < 0 * u.deg
assert aacs[0].distance > 5000 * u.km
# it should *not* actually be 90 degrees, b/c constant latitude is not
# straight east anywhere except the equator... but should be close-ish
assert_quantity_allclose(aacs[1].az, 90 * u.deg, atol=5 * u.deg)
assert aacs[1].alt < 0 * u.deg
assert aacs[1].distance > 5000 * u.km
assert_quantity_allclose(aacs[2].alt, 90 * u.deg, atol=1 * u.arcminute)
assert_quantity_allclose(aacs[2].distance, 9 * height)
def test_regression_simple_5133():
"""
Simple test to check if alt-az calculations respect height of observer
Because ITRS is geocentric and includes aberration, an object that
appears 'straight up' to a geocentric observer (ITRS) won't be
straight up to a topocentric observer - see
https://github.com/astropy/astropy/issues/10983
This is why we construct a topocentric GCRS SkyCoord before calculating AltAz
"""
t = Time("J2010")
obj = EarthLocation(-1 * u.deg, 52 * u.deg, height=[10.0, 0.0] * u.km)
home = EarthLocation(-1 * u.deg, 52 * u.deg, height=5.0 * u.km)
obsloc_gcrs, obsvel_gcrs = home.get_gcrs_posvel(t)
gcrs_geo = obj.get_itrs(t).transform_to(GCRS(obstime=t))
obsrepr = home.get_itrs(t).transform_to(GCRS(obstime=t)).cartesian
topo_gcrs_repr = gcrs_geo.cartesian - obsrepr
topocentric_gcrs_frame = GCRS(
obstime=t, obsgeoloc=obsloc_gcrs, obsgeovel=obsvel_gcrs
)
gcrs_topo = topocentric_gcrs_frame.realize_frame(topo_gcrs_repr)
aa = gcrs_topo.transform_to(AltAz(obstime=t, location=home))
# az is more-or-less undefined for straight up or down
assert_quantity_allclose(aa.alt, [90, -90] * u.deg, rtol=1e-7)
assert_quantity_allclose(aa.distance, 5 * u.km)
def test_regression_5743():
sc = SkyCoord(
[5, 10], [20, 30], unit=u.deg, obstime=["2017-01-01T00:00", "2017-01-01T00:10"]
)
assert sc[0].obstime.shape == tuple()
def test_regression_5889_5890():
# ensure we can represent all Representations and transform to ND frames
greenwich = EarthLocation(
*u.Quantity([3980608.90246817, -102.47522911, 4966861.27310067], unit=u.m)
)
times = Time("2017-03-20T12:00:00") + np.linspace(-2, 2, 3) * u.hour
moon = get_body("moon", times, location=greenwich)
targets = SkyCoord([350.7 * u.deg, 260.7 * u.deg], [18.4 * u.deg, 22.4 * u.deg])
targs2d = targets[:, np.newaxis]
targs2d.transform_to(moon)
def test_regression_6236():
# sunpy changes its representation upon initialisation of a frame,
# including via `realize_frame`. Ensure this works.
class MyFrame(BaseCoordinateFrame):
default_representation = CartesianRepresentation
my_attr = QuantityAttribute(default=0, unit=u.m)
class MySpecialFrame(MyFrame):
def __init__(self, *args, **kwargs):
_rep_kwarg = kwargs.get("representation_type", None)
super().__init__(*args, **kwargs)
if not _rep_kwarg:
self.representation_type = self.default_representation
self._data = self.data.represent_as(self.representation_type)
rep1 = UnitSphericalRepresentation([0.0, 1] * u.deg, [2.0, 3.0] * u.deg)
rep2 = SphericalRepresentation(
[10.0, 11] * u.deg, [12.0, 13.0] * u.deg, [14.0, 15.0] * u.kpc
)
mf1 = MyFrame(rep1, my_attr=1.0 * u.km)
mf2 = mf1.realize_frame(rep2)
# Normally, data is stored as is, but the representation gets set to a
# default, even if a different representation instance was passed in.
# realize_frame should do the same. Just in case, check attrs are passed.
assert mf1.data is rep1
assert mf2.data is rep2
assert mf1.representation_type is CartesianRepresentation
assert mf2.representation_type is CartesianRepresentation
assert mf2.my_attr == mf1.my_attr
# It should be independent of whether I set the representation explicitly
mf3 = MyFrame(rep1, my_attr=1.0 * u.km, representation_type="unitspherical")
mf4 = mf3.realize_frame(rep2)
assert mf3.data is rep1
assert mf4.data is rep2
assert mf3.representation_type is UnitSphericalRepresentation
assert mf4.representation_type is CartesianRepresentation
assert mf4.my_attr == mf3.my_attr
# This should be enough to help sunpy, but just to be sure, a test
# even closer to what is done there, i.e., transform the representation.
msf1 = MySpecialFrame(rep1, my_attr=1.0 * u.km)
msf2 = msf1.realize_frame(rep2)
assert msf1.data is not rep1 # Gets transformed to Cartesian.
assert msf2.data is not rep2
assert type(msf1.data) is CartesianRepresentation
assert type(msf2.data) is CartesianRepresentation
assert msf1.representation_type is CartesianRepresentation
assert msf2.representation_type is CartesianRepresentation
assert msf2.my_attr == msf1.my_attr
# And finally a test where the input is not transformed.
msf3 = MySpecialFrame(rep1, my_attr=1.0 * u.km, representation_type="unitspherical")
msf4 = msf3.realize_frame(rep2)
assert msf3.data is rep1
assert msf4.data is not rep2
assert msf3.representation_type is UnitSphericalRepresentation
assert msf4.representation_type is CartesianRepresentation
assert msf4.my_attr == msf3.my_attr
@pytest.mark.skipif(not HAS_SCIPY, reason="No Scipy")
def test_regression_6347():
sc1 = SkyCoord([1, 2] * u.deg, [3, 4] * u.deg)
sc2 = SkyCoord([1.1, 2.1] * u.deg, [3.1, 4.1] * u.deg)
sc0 = sc1[:0]
idx1_10, idx2_10, d2d_10, d3d_10 = sc1.search_around_sky(sc2, 10 * u.arcmin)
idx1_1, idx2_1, d2d_1, d3d_1 = sc1.search_around_sky(sc2, 1 * u.arcmin)
idx1_0, idx2_0, d2d_0, d3d_0 = sc0.search_around_sky(sc2, 10 * u.arcmin)
assert len(d2d_10) == 2
assert len(d2d_0) == 0
assert type(d2d_0) is type(d2d_10)
assert len(d2d_1) == 0
assert type(d2d_1) is type(d2d_10)
@pytest.mark.skipif(not HAS_SCIPY, reason="No Scipy")
def test_regression_6347_3d():
sc1 = SkyCoord([1, 2] * u.deg, [3, 4] * u.deg, [5, 6] * u.kpc)
sc2 = SkyCoord([1, 2] * u.deg, [3, 4] * u.deg, [5.1, 6.1] * u.kpc)
sc0 = sc1[:0]
idx1_10, idx2_10, d2d_10, d3d_10 = sc1.search_around_3d(sc2, 500 * u.pc)
idx1_1, idx2_1, d2d_1, d3d_1 = sc1.search_around_3d(sc2, 50 * u.pc)
idx1_0, idx2_0, d2d_0, d3d_0 = sc0.search_around_3d(sc2, 500 * u.pc)
assert len(d2d_10) > 0
assert len(d2d_0) == 0
assert type(d2d_0) is type(d2d_10)
assert len(d2d_1) == 0
assert type(d2d_1) is type(d2d_10)
def test_gcrs_itrs_cartesian_repr():
# issue 6436: transformation failed if coordinate representation was
# Cartesian
gcrs = GCRS(
CartesianRepresentation((859.07256, -4137.20368, 5295.56871), unit="km"),
representation_type="cartesian",
)
gcrs.transform_to(ITRS())
def test_regression_6446():
# this succeeds even before 6446:
sc1 = SkyCoord([1, 2], [3, 4], unit="deg")
t1 = Table([sc1])
sio1 = io.StringIO()
t1.write(sio1, format="ascii.ecsv")
# but this fails due to the 6446 bug
c1 = SkyCoord(1, 3, unit="deg")
c2 = SkyCoord(2, 4, unit="deg")
sc2 = SkyCoord([c1, c2])
t2 = Table([sc2])
sio2 = io.StringIO()
t2.write(sio2, format="ascii.ecsv")
assert sio1.getvalue() == sio2.getvalue()
def test_regression_6597():
frame_name = "galactic"
c1 = SkyCoord(1, 3, unit="deg", frame=frame_name)
c2 = SkyCoord(2, 4, unit="deg", frame=frame_name)
sc1 = SkyCoord([c1, c2])
assert sc1.frame.name == frame_name
def test_regression_6597_2():
"""
This tests the more subtle flaw that #6597 indirectly uncovered: that even
in the case that the frames are ra/dec, they still might be the wrong *kind*
"""
frame = FK4(equinox="J1949")
c1 = SkyCoord(1, 3, unit="deg", frame=frame)
c2 = SkyCoord(2, 4, unit="deg", frame=frame)
sc1 = SkyCoord([c1, c2])
assert sc1.frame.name == frame.name
def test_regression_6697():
"""
Test for regression of a bug in get_gcrs_posvel that introduced errors at the 1m/s level.
Comparison data is derived from calculation in PINT
https://github.com/nanograv/PINT/blob/master/pint/erfautils.py
"""
pint_vels = CartesianRepresentation(
348.63632871, -212.31704928, -0.60154936, unit=u.m / u.s
)
location = EarthLocation(
5327448.9957829, -1718665.73869569, 3051566.90295403, unit=u.m
)
t = Time(2458036.161966612, format="jd")
obsgeopos, obsgeovel = location.get_gcrs_posvel(t)
delta = (obsgeovel - pint_vels).norm()
assert delta < 1 * u.cm / u.s
def test_regression_8138():
sc = SkyCoord(1 * u.deg, 2 * u.deg)
newframe = GCRS()
sc2 = sc.transform_to(newframe)
assert newframe.is_equivalent_frame(sc2.frame)
def test_regression_8276():
from astropy.coordinates import baseframe
class MyFrame(BaseCoordinateFrame):
a = QuantityAttribute(unit=u.m)
# we save the transform graph so that it doesn't accidentally mess with other tests
old_transform_graph = baseframe.frame_transform_graph
try:
baseframe.frame_transform_graph = copy.copy(baseframe.frame_transform_graph)
# as reported in 8276, this previously failed right here because
# registering the transform tries to create a frame attribute
@baseframe.frame_transform_graph.transform(FunctionTransform, MyFrame, AltAz)
def trans(my_frame_coord, altaz_frame):
pass
# should also be able to *create* the Frame at this point
MyFrame()
finally:
baseframe.frame_transform_graph = old_transform_graph
def test_regression_8615():
# note this is a "higher-level" symptom of the problem that a test now moved
# to pyerfa (erfa/tests/test_erfa:test_float32_input) is testing for, but we keep
# it here as well due to being a more practical version of the issue.
crf = CartesianRepresentation(np.array([3, 0, 4], dtype=float) * u.pc)
srf = SphericalRepresentation.from_cartesian(crf) # does not error in 8615
cr = CartesianRepresentation(np.array([3, 0, 4], dtype="f4") * u.pc)
sr = SphericalRepresentation.from_cartesian(cr) # errors in 8615
assert_quantity_allclose(sr.distance, 5 * u.pc)
assert_quantity_allclose(srf.distance, 5 * u.pc)
def test_regression_8924():
"""This checks that the ValueError in
BaseRepresentation._re_represent_differentials is raised properly
"""
# A case where the representation has a 's' differential, but we try to
# re-represent only with an 's2' differential
rep = CartesianRepresentation(1, 2, 3, unit=u.kpc)
dif = CartesianDifferential(4, 5, 6, u.km / u.s)
rep = rep.with_differentials(dif)
with pytest.raises(ValueError):
rep._re_represent_differentials(
CylindricalRepresentation, {"s2": CylindricalDifferential}
)
def test_regression_10092():
"""
Check that we still get a proper motion even for SkyCoords without distance
"""
c = SkyCoord(
l=10 * u.degree,
b=45 * u.degree,
pm_l_cosb=34 * u.mas / u.yr,
pm_b=-117 * u.mas / u.yr,
frame="galactic",
obstime=Time("1988-12-18 05:11:23.5"),
)
with pytest.warns(ErfaWarning, match='ERFA function "pmsafe" yielded .*'):
newc = c.apply_space_motion(dt=10 * u.year)
assert_quantity_allclose(
newc.pm_l_cosb, 33.99980714 * u.mas / u.yr, atol=1.0e-5 * u.mas / u.yr
)
def test_regression_10226():
# Dictionary representation of SkyCoord should contain differentials.
sc = SkyCoord(
[270, 280] * u.deg,
[30, 35] * u.deg,
[10, 11] * u.pc,
radial_velocity=[20, -20] * u.km / u.s,
)
sc_as_dict = sc.info._represent_as_dict()
assert "radial_velocity" in sc_as_dict
# But only the components that have been specified.
assert "pm_dec" not in sc_as_dict
@pytest.mark.parametrize(
"mjd", (52000, [52000], [[52000]], [52001, 52002], [[52001], [52002]])
)
def test_regression_10422(mjd):
"""
Check that we can get a GCRS for a scalar EarthLocation and a
size=1 non-scalar Time.
"""
# Avoid trying to download new IERS data.
with iers.earth_orientation_table.set(iers.IERS_B.open(iers.IERS_B_FILE)):
t = Time(mjd, format="mjd", scale="tai")
loc = EarthLocation(88258.0 * u.m, -4924882.2 * u.m, 3943729.0 * u.m)
p, v = loc.get_gcrs_posvel(obstime=t)
assert p.shape == v.shape == t.shape
@pytest.mark.remote_data
def test_regression_10291():
"""
According to https://eclipse.gsfc.nasa.gov/OH/transit12.html,
the minimum separation between Venus and the Sun during the 2012
transit is 554 arcseconds for an observer at the Geocenter.
If light deflection from the Sun is incorrectly applied, this increases
to 557 arcseconds.
"""
t = Time("2012-06-06 01:29:36")
sun = get_body("sun", t)
venus = get_body("venus", t)
assert_quantity_allclose(
venus.separation(sun), 554.427 * u.arcsecond, atol=0.001 * u.arcsecond
)