Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
Given an object's GCRS `position_au` [x,y,z] vector and the position
of an `observer_au` as a vector in the same coordinate system,
return a tuple that provides `(limb_ang, nadir_ang)`:
limb_angle
Angle of observed object above (+) or below (-) limb in degrees.
nadir_angle
Nadir angle of observed object as a fraction of apparent radius
of limb: <1.0 means below the limb, =1.0 means on the limb, and
>1.0 means above the limb.
"""
# Compute the distance to the object and the distance to the observer.
disobj = sqrt(dots(position_au, position_au))
disobs = sqrt(dots(observer_au, observer_au))
# Compute apparent angular radius of Earth's limb.
aprad = arcsin(minimum(earth_radius_au / disobs, 1.0))
# Compute zenith distance of Earth's limb.
zdlim = pi - aprad
# Compute zenith distance of observed object.
coszd = dots(position_au, observer_au) / (disobj * disobs)
coszd = clip(coszd, -1.0, 1.0)
zdobj = arccos(coszd)
# Angle of object wrt limb is difference in zenith distances.
pe = observer - deflector
# Compute vector magnitudes and unit vectors.
pmag = length_of(position)
qmag = length_of(pq)
emag = length_of(pe)
phat = position / where(pmag, pmag, 1.0) # where() avoids divide-by-zero
qhat = pq / where(qmag, qmag, 1.0)
ehat = pe / where(emag, emag, 1.0)
# Compute dot products of vectors.
pdotq = dots(phat, qhat)
qdote = dots(qhat, ehat)
edotp = dots(ehat, phat)
# If gravitating body is observed object, or is on a straight line
# toward or away from observed object to within 1 arcsec, deflection
# is set to zero set 'pos2' equal to 'pos1'.
make_no_correction = abs(edotp) > 0.99999999999
# Compute scalar factors.
fac1 = 2.0 * GS / (C * C * emag * AU_M * rmass)
fac2 = 1.0 + qdote
# Correct position vector.
position += where(make_no_correction, 0.0,
angle = arccos(pos_vec[0]/length_of(pos_vec))
v = angle if vel_vec[0] < 0 else -angle%tau
else: # circular and not equatorial
angle = angle_between(n_vec, pos_vec)
v = angle if pos_vec[2] >= 0 else -angle%tau
return v if length_of(e_vec)<(1-1e-15) else normpi(v)
else:
v = zeros_like(pos_vec[0])
circular = (length_of(e_vec)<1e-15)
equatorial = (length_of(n_vec)<1e-15)
inds = ~circular
angle = angle_between(e_vec[:, inds], pos_vec[:, inds])
condition = (dots(pos_vec[:, inds], vel_vec[:, inds]) > 0)
v[inds] = where(condition, angle, -angle%tau)
inds = circular*equatorial
angle = arccos(pos_vec[0][inds]/length_of(pos_vec)[inds])
condition = vel_vec[0][inds] < 0
v[inds] = where(condition, angle, -angle%tau)
inds = circular*~equatorial
angle = angle_between(n_vec[:, inds], pos_vec[:, inds])
condition = pos_vec[2][inds] >= 0
v[inds] = where(condition, angle, -angle%tau)
inds = length_of(e_vec)>(1-1e-15)
v[inds] = normpi(v[inds])
return v
Given an object's GCRS `position_au` [x,y,z] vector and the position
of an `observer_au` as a vector in the same coordinate system,
return a tuple that provides `(limb_ang, nadir_ang)`:
limb_angle
Angle of observed object above (+) or below (-) limb in degrees.
nadir_angle
Nadir angle of observed object as a fraction of apparent radius
of limb: <1.0 means below the limb, =1.0 means on the limb, and
>1.0 means above the limb.
"""
# Compute the distance to the object and the distance to the observer.
disobj = sqrt(dots(position_au, position_au))
disobs = sqrt(dots(observer_au, observer_au))
# Compute apparent angular radius of Earth's limb.
aprad = arcsin(minimum(earth_radius_au / disobs, 1.0))
# Compute zenith distance of Earth's limb.
zdlim = pi - aprad
# Compute zenith distance of observed object.
coszd = dots(position_au, observer_au) / (disobj * disobs)
coszd = clip(coszd, -1.0, 1.0)
zdobj = arccos(coszd)
t0 : float
Time corresponding to `position` and `velocity`
t1 : float or ndarray
Time or times to propagate to
gm : float
Gravitational parameter in units that match the other arguments
"""
if gm <= 0:
raise ValueError("'gm' should be positive")
if length_of(velocity) == 0:
raise ValueError('Velocity vector has zero magnitude')
if length_of(position) == 0:
raise ValueError('Position vector has zero magnitude')
r0 = length_of(position)
rv = dots(position, velocity)
hvec = cross(position, velocity)
h2 = dots(hvec, hvec)
if h2 == 0:
raise ValueError('Motion is not conical')
eqvec = cross(velocity, hvec)/gm + -position/r0
e = length_of(eqvec)
q = h2 / (gm * (1+e))
f = 1 - e
b = sqrt(q/gm)
br0 = b * r0
b2rv = b**2 * rv
pq = observer + position - deflector
pe = observer - deflector
# Compute vector magnitudes and unit vectors.
pmag = length_of(position)
qmag = length_of(pq)
emag = length_of(pe)
phat = position / where(pmag, pmag, 1.0) # where() avoids divide-by-zero
qhat = pq / where(qmag, qmag, 1.0)
ehat = pe / where(emag, emag, 1.0)
# Compute dot products of vectors.
pdotq = dots(phat, qhat)
qdote = dots(qhat, ehat)
edotp = dots(ehat, phat)
# If gravitating body is observed object, or is on a straight line
# toward or away from observed object to within 1 arcsec, deflection
# is set to zero set 'pos2' equal to 'pos1'.
make_no_correction = abs(edotp) > 0.99999999999
# Compute scalar factors.
fac1 = 2.0 * GS / (C * C * emag * AU_M * rmass)
fac2 = 1.0 + qdote
# Correct position vector.
def add_aberration(position, velocity, light_time):
"""Correct a relative position vector for aberration of light.
Given the relative `position` [x,y,z] of an object (AU) from a
particular observer, the `velocity` [dx,dy,dz] at which the observer
is traveling (AU/day), and the light propagation delay `light_time`
to the object (days), this function updates `position` in-place to
give the object's apparent position due to the aberration of light.
"""
p1mag = light_time * C_AUDAY
vemag = length_of(velocity)
beta = vemag / C_AUDAY
dot = dots(position, velocity)
cosd = dot / (p1mag * vemag)
gammai = sqrt(1.0 - beta * beta)
p = beta * cosd
q = (1.0 + p / (1.0 + gammai)) * light_time
r = 1.0 + p
position *= gammai
position += q * velocity
position /= r
# Compute vector magnitudes and unit vectors.
pmag = length_of(position)
qmag = length_of(pq)
emag = length_of(pe)
phat = position / where(pmag, pmag, 1.0) # where() avoids divide-by-zero
qhat = pq / where(qmag, qmag, 1.0)
ehat = pe / where(emag, emag, 1.0)
# Compute dot products of vectors.
pdotq = dots(phat, qhat)
qdote = dots(qhat, ehat)
edotp = dots(ehat, phat)
# If gravitating body is observed object, or is on a straight line
# toward or away from observed object to within 1 arcsec, deflection
# is set to zero set 'pos2' equal to 'pos1'.
make_no_correction = abs(edotp) > 0.99999999999
# Compute scalar factors.
fac1 = 2.0 * GS / (C * C * emag * AU_M * rmass)
fac2 = 1.0 + qdote
# Correct position vector.
position += where(make_no_correction, 0.0,
fac1 * (pdotq * ehat - edotp * qhat) / fac2 * pmag)