为什么在天体中从地球坐标转换到银河系坐标不保持距离?
Why does transforming from Earth coordinates to galactocentric coordinates in astropy not preserve distances?
我正在将 GCRS
对象转换为半乳糖坐标,发现在此转换下两点之间的距离没有保留。
import astropy.units
import astropy.coordinates
import astropy.time
from numpy.linalg import norm
t = astropy.time.Time('1999-01-01T00:00:00.123456789')
def earth2galaxy(lat):
'''
Convert an Earth coordinate to a galactocentric coordinate.
'''
# get GCRS coordinates
earth = astropy.coordinates.EarthLocation(lat=lat*astropy.units.deg,
lon=0,
height=0)
pos, _ = earth.get_gcrs_posvel(obstime=t)
cartrep = astropy.coordinates.CartesianRepresentation(pos.xyz,
unit=astropy.units.m)
gcrs = astropy.coordinates.GCRS(cartrep)
# convert GCRS to galactocentric
gc = gcrs.transform_to(astropy.coordinates.Galactocentric)
return earth, gcrs, gc
earthA, gcrsA, gcA = earth2galaxy(0)
earthB, gcrsB, gcB = earth2galaxy(0.01)
print(norm(earthA-earthB))
print(norm(gcrsA.cartesian.xyz-gcrsB.cartesian.xyz))
print(norm(gcA.cartesian.xyz-gcB.cartesian.xyz))
此代码给出
1105.74275693
1105.74275232
971.796949054
我发现这对于更大的距离来说不是问题(例如,纬度偏移量为 10 度)。
我之前通过 -- 给定点 A
和 B
-- 转换点 A
和 C = A + c*AB
来解决这个问题,其中 c
是一些大的数字。然后我将通过撤消此缩放 B' = A' + A'C' / c
来恢复转换后的 B'
。但是,感觉我应该解决问题的实际根源而不是这个解决方法。
这可能只是一个浮点精度问题。如果我查看笛卡尔值,GCRS 框架的 x
、y
和 z
顺序为 1e6
、1e6
和 1e2
,但对于银河坐标系,它们的顺序分别为 1e20
、1e10
和 1e17
。
给定 8 字节浮点数 (numpy.finfo('f8').eps
) 的精度 1e-15
,这意味着银河坐标的 x
值只能精确到大约 1e5
(米)。然后采用标准(以 x
值不确定性为主),也会导致 1e5
米级的精度,远高于实际间隔。
计算值仍然彼此接近这一事实在很大程度上是运气(尽管它有一个潜在的原因,例如偏差稍微平均)。
这也与您没有发现更大偏移量的问题(或更少的问题)这一事实相符。虽然我自己测试了,但我仍然看到了差异,顺序 1e4
~1e5
)。准确地说,使用 0 和 10 纬度,我得到:
GCRS: 1104451.74511518
Galactic: 1108541.8206286128
如果我的假设是正确的,那么我的建议很简单:为您的坐标使用适当的坐标系,并考虑相关的不确定性(机器精度和所用坐标系的精度)。
我认为“0 0”主要是一针见血,但对于这种情况还有另一种解决方案:使用精度更高的 float dtype - 例如float128
dtype(您将其传递给 CartesianRepresentation
的 dtype
关键字),可能距离 会 更近。
不幸的是,有一个错误似乎迫使 dtypes 返回 float64
(我报告:https://github.com/astropy/astropy/issues/8870),但如果它已修复,则取决于您的计算机及其支持的精度,使用 higher-precision dtype 可能会做到这一点。
我正在将 GCRS
对象转换为半乳糖坐标,发现在此转换下两点之间的距离没有保留。
import astropy.units
import astropy.coordinates
import astropy.time
from numpy.linalg import norm
t = astropy.time.Time('1999-01-01T00:00:00.123456789')
def earth2galaxy(lat):
'''
Convert an Earth coordinate to a galactocentric coordinate.
'''
# get GCRS coordinates
earth = astropy.coordinates.EarthLocation(lat=lat*astropy.units.deg,
lon=0,
height=0)
pos, _ = earth.get_gcrs_posvel(obstime=t)
cartrep = astropy.coordinates.CartesianRepresentation(pos.xyz,
unit=astropy.units.m)
gcrs = astropy.coordinates.GCRS(cartrep)
# convert GCRS to galactocentric
gc = gcrs.transform_to(astropy.coordinates.Galactocentric)
return earth, gcrs, gc
earthA, gcrsA, gcA = earth2galaxy(0)
earthB, gcrsB, gcB = earth2galaxy(0.01)
print(norm(earthA-earthB))
print(norm(gcrsA.cartesian.xyz-gcrsB.cartesian.xyz))
print(norm(gcA.cartesian.xyz-gcB.cartesian.xyz))
此代码给出
1105.74275693
1105.74275232
971.796949054
我发现这对于更大的距离来说不是问题(例如,纬度偏移量为 10 度)。
我之前通过 -- 给定点 A
和 B
-- 转换点 A
和 C = A + c*AB
来解决这个问题,其中 c
是一些大的数字。然后我将通过撤消此缩放 B' = A' + A'C' / c
来恢复转换后的 B'
。但是,感觉我应该解决问题的实际根源而不是这个解决方法。
这可能只是一个浮点精度问题。如果我查看笛卡尔值,GCRS 框架的 x
、y
和 z
顺序为 1e6
、1e6
和 1e2
,但对于银河坐标系,它们的顺序分别为 1e20
、1e10
和 1e17
。
给定 8 字节浮点数 (numpy.finfo('f8').eps
) 的精度 1e-15
,这意味着银河坐标的 x
值只能精确到大约 1e5
(米)。然后采用标准(以 x
值不确定性为主),也会导致 1e5
米级的精度,远高于实际间隔。
计算值仍然彼此接近这一事实在很大程度上是运气(尽管它有一个潜在的原因,例如偏差稍微平均)。
这也与您没有发现更大偏移量的问题(或更少的问题)这一事实相符。虽然我自己测试了,但我仍然看到了差异,顺序 1e4
~1e5
)。准确地说,使用 0 和 10 纬度,我得到:
GCRS: 1104451.74511518
Galactic: 1108541.8206286128
如果我的假设是正确的,那么我的建议很简单:为您的坐标使用适当的坐标系,并考虑相关的不确定性(机器精度和所用坐标系的精度)。
我认为“0 0”主要是一针见血,但对于这种情况还有另一种解决方案:使用精度更高的 float dtype - 例如float128
dtype(您将其传递给 CartesianRepresentation
的 dtype
关键字),可能距离 会 更近。
不幸的是,有一个错误似乎迫使 dtypes 返回 float64
(我报告:https://github.com/astropy/astropy/issues/8870),但如果它已修复,则取决于您的计算机及其支持的精度,使用 higher-precision dtype 可能会做到这一点。