ska_sun

Utility for calculating sun position, pitch angle and values related to roll.

ska_sun.sun.allowed_rolldev(pitch, roll_table=None)[source]

Get allowed roll deviation (off-nominal roll) for the given pitch.

This performs a linear interpolation of the values in the pitch/roll table in the chandra_models repo in chandra_models/pitch_roll/pitch_roll_constraint.csv.

For pitch values outside the range of the table the returned rolldev is -1.0, corresonding to a pitch angle outside of the planning limits.

Parameters:
  • pitch – float, ndarray Sun pitch angle (deg)

  • roll_table – astropy.table.Table Table of pitch/roll values (optional)

Returns:

float, ndarray Roll deviation (deg)

ska_sun.sun.apply_sun_pitch_yaw(att, pitch=0, yaw=0, time=None, sun_ra=None, sun_dec=None, coord_system='spacecraft')[source]

Apply pitch(es) and yaw(s) about Sun line to an attitude.

If time is provided then that is used to compute the sun position. Otherwise sun_ra and sun_dec must be provided.

The yaw coordinate system can be “spacecraft” (default) or “ORviewer”. The “spacecraft” system matches the engineering definition of yaw about the Sun at a sun pitch of 90 degrees: zero yaw is defined as the ECI z-axis if the Sun is at exactly RA = Dec = 0.

The example below uses real telemetry from the 2024:036 NSM recovery activity. At around 2024:036:01:32:00.000, a “positive yaw bias of 0.025 deg/s for 30 minutes” was applied. The yaw maneuver converged to a stable attitude around 0210z. The expectation that the computed attitude matches the 0210z attitude from telemetry to within about a degree.

>>> from ska_sun import apply_sun_pitch_yaw

>>> # From telemetry at 2024:036 0130z and 0210z
>>> att0 = Quat([60.35823393, -34.92322161, 291.13817936])
>>> att1 = Quat([111.94789334, -71.01495527, 335.27170577])

# Apply yaw bias to the 0130z attitude using sun position midway.
>>> att1_apply = apply_sun_pitch_yaw(att0, pitch=0, yaw=45, time="2024:036:01:47:00")
>>> att1_apply.equatorial
array([111.44329433, -71.34681456, 335.48326522])
Parameters:
  • att – Quaternion-like Attitude(s) to be rotated.

  • pitch – float, ndarray Sun pitch offsets (deg)

  • yaw – float, ndarray Sun yaw offsets (deg)

  • sun_ra – float, optional RA of sun. If not given, use estimated sun RA at time.

  • sun_dec – float, optional Dec of sun. If not given, use estimated sun dec at time.

  • coord_system – str, optional Coordinate system for yaw (“spacecraft” | “ORviewer”, default=”spacecraft”).

Returns:

Quat Modified attitude(s)

ska_sun.sun.get_sun_pitch_yaw(ra, dec, time=None, sun_ra=None, sun_dec=None, coord_system='spacecraft')[source]

Get Sun pitch and yaw angles of Sky coordinate(s).

If time is provided then that is used to compute the sun position. Otherwise sun_ra and sun_dec must be provided.

The yaw coordinate system can be “spacecraft” (default) or “ORviewer”. The “spacecraft” system matches the engineering definition of yaw about the Sun at a sun pitch of 90 degrees: zero yaw is defined as the ECI z-axis if the Sun is at exactly RA = Dec = 0.

The example below uses real telemetry from the 2024:036 NSM recovery activity. At around 2024:036:01:32:00.000, a “positive yaw bias of 0.025 deg/s for 30 minutes” was applied. The yaw maneuver converged to a stable attitude around 0210z. The expectation is that pitch is 90.0 and yaw increases by 45 degrees of the maneuver.

>>> from ska_sun import get_sun_pitch_yaw
>>> from Quaternion import Quat

# From telemetry at 2024:036 0130z and 0210z
>>> att0 = Quat([60.35823393, -34.92322161, 291.13817936])
>>> att1 = Quat([111.94789334, -71.01495527, 335.27170577])

>>> get_sun_pitch_yaw(att0.ra, att0.dec, time="2024:036:01:30:00")
(90.60565371045911, 126.82092681074306)
>>> get_sun_pitch_yaw(att1.ra, att1.dec, time="2024:036:02:10:00")
(90.97070080025568, 171.81963428481384)
Parameters:
  • ra – float, ndarray RA(s)

  • dec – float, ndarray Dec(s)

  • time – date-like, optional Date of observation. If not given, use sun_ra and sun_dec if provided or else use current date.

  • sun_ra – float, optional RA of sun. If not given, use estimated sun RA at date.

  • sun_dec – float, optional Dec of sun. If not given, use estimated sun dec at date.

  • coord_system – str, optional Coordinate system for yaw (“spacecraft” | “ORviewer”, default=”spacecraft”).

Returns:

2-tuple (pitch, yaw) in degrees.

ska_sun.sun.load_roll_table()[source]

Load the pitch/roll table from the chandra_models repo.

The result depends on environment variables:

  • CHANDRA_MODELS_REPO_DIR: root directory of chandra_models repo

  • CHANDRA_MODELS_DEFAULT_VERSION: default version of chandra_models to use

Returns:

astropy.table.Table Table with “pitch” and “off_nom_roll” columns. Detailed provenance information is available in the table meta attribute.

ska_sun.sun.nominal_roll(ra, dec, time=None, sun_ra=None, sun_dec=None, method=None)[source]

Calculate the nominal roll angle for the given spacecraft attitude.

If time is provided then that is used to compute the sun position. Otherwise sun_ra and sun_dec must be provided.

Parameters:
rafloat

Right ascension.

decfloat

Declination.

timeCxoTimeLike, optional

Time in any Chandra.Time format.

sun_rafloat, optional

Sun right ascension (instead of using time).

sun_decfloat, optional

Sun declination (instead of using time).

methodstr, optional.

Method for calculating sun position. Valid options are “accurate”, “fast”.

Returns:
float

Nominal roll angle in the range of 0-360 degrees.

Examples

>>> nominal_roll(205.3105, -14.6925, time='2011:019:20:51:13')
68.830209134280665    # vs. 68.80 for obsid 12393 in JAN1711A
ska_sun.sun.off_nominal_roll(att, time=None, sun_ra=None, sun_dec=None, method=None)[source]

Calculate off-nominal roll angle for spacecraft attitude att.

If time is provided then that is used to compute the sun position. Otherwise sun_ra and sun_dec must be provided.

method sets the method for computing the sun position. See position() for details.

Off-nominal roll is defined as roll - nominal roll.

Parameters:
attQuatLike

Chandra attitude.

timeCxoTimeLike (optional)

Time of observation. If not given, use sun_ra and sun_dec.

sun_ra: float, optional

Sun RA (deg) instead of time.

sun_decfloat, optional

Sun Dec (deg) instead of time.

methodstr, optional

Method for calculating sun position. Valid options are “accurate”, “fast”.

Returns:
float

Off-nominal roll angle in the range of -180 to 180 degrees.

Examples

>>> att = (198.392135, 36.594359, 33.983322)  # RA, Dec, Roll of obsid 16354
>>> ska_sun.off_nominal_roll(att, '2015:335:00:00:00')
-12.22401097980562
ska_sun.sun.pitch(ra, dec, time=None, sun_ra=None, sun_dec=None, method=None)[source]

Calculate sun pitch angle for spacecraft attitude.

If time is provided then that is used to compute the sun position. Otherwise sun_ra and sun_dec must be provided.

method sets the method for computing the sun position which is used for pitch. See position() for details.

Parameters:
rafloat

Target right ascension (deg).

decfloat

Target declination (deg).

timeCxoTimeLike, optional

Time for sun position.

sun_rafloat, optional

Sun RA (deg) instead of time.

sun_decfloat, optional

Sun Dec (deg) instead of time.

methodstr, optional.

Method for calculating sun position. Valid options are “accurate”, “fast”.

Returns:
float

Sun pitch angle (deg).

Examples

>>> ska_sun.pitch(10., 20., '2009:001:00:01:02')
96.256434327840864
ska_sun.sun.position(time, method=None, **kwargs)[source]

Calculate the sun RA, Dec at the given time from Earth geocenter or Chandra.

method sets the method for computing the sun position which is used for pitch. The default is set by ska_sun.conf.sun_pitch_roll_method_default, which defaults to accurate. The available options are:

  • accurate: Use the accurate method (see position_accurate()).

  • fast: Use the fast method (see position_fast()).

Parameters:
timeCxoTimeLike (scalar)

Input time.

methodstr, optional

Method to use for computing the sun position (see above).

**kwargsdict, optional

Additional keyword arguments passed to the position method.

Returns:
sun_rafloat

Right Ascension in decimal degrees (J2000).

sun_decfloat

Declination in decimal degrees (J2000).

Examples

>>> import ska_sun
>>> ska_sun.position('2008:002:00:01:02')
(281.90344855695275, -22.9892737322084)
>>> ska_sun.position('2008:002:00:01:02', method='accurate')
(281.7865848220755, -22.99607130644057)
>>> with ska_sun.conf.set_temp('sun_position_method_default', 'accurate'):
...    ska_sun.position('2008:002:00:01:02')
(281.7865848220755, -22.99607130644057
>>> ska_sun.position('2008:002:00:01:02', method='accurate', from_chandra=True)
(281.80963749492935, -23.033877980418676)
ska_sun.sun.position_accurate(time, from_chandra=False)[source]

Calculate the sun RA, Dec at the given time from Earth geocenter or Chandra.

If from_chandra=False (default) the position is calculated from Earth geocenter. If from_chandra=True the position is calculated from Chandra using the Chandra predictive ephemeris via the cheta telemetry archive.

These methods rely on the DE432 ephemeris and functions in chandra_aca.planets. With from_chandra=True the position should be accurate to within a few arcsec. With from_chandra=False the position is accurate to within about 0.05 deg.

Parameters:
timeCxoTimeLike (scalar)

Input time.

from_chandrabool, optional

If True compute position from Chandra using ephemeris in cheta.

Returns:
sun_rafloat

Right Ascension in decimal degrees (J2000).

sun_decfloat

Declination in decimal degrees (J2000).

Examples

>>> import ska_sun
>>> ska_sun.position_accurate('2008:002:00:01:02')
(281.7865848220755, -22.99607130644057)
ska_sun.sun.position_fast(time)[source]

Calculate the sun position at the given time using a fast approximation.

Code modified from http://idlastro.gsfc.nasa.gov/ftp/pro/astro/sunpos.pro

This implementation is returns coordinates that are in error by as much as 0.3 deg. Use the position_accurate() function or position(.., method='accurate') unless speed is critical.

This function is about 40x faster than the position_accurate() function (30 us for a single time vs 1.2 ms). However, the position_accurate() function can be vectorized and the speed difference is reduced.

Parameters:
timeCxoTimeLike (scalar)

Input time.

Returns:
sun_rafloat

Right Ascension in decimal degrees (J2000).

sun_decfloat

Declination in decimal degrees (J2000).

Examples

>>> import ska_sun
>>> ska_sun.position_fast('2008:002:00:01:02')
(281.90344855695275, -22.9892737322084)
ska_sun.sun.position_fast_at_jd(jd)[source]

Calculate the sun position at the given time (JD) using a fast approximation.

See position_fast() for details.

Parameters:
jdfloat

Input time in JD.

Returns:
sun_rafloat

Right Ascension in decimal degrees (J2000).

sun_decfloat

Declination in decimal degrees (J2000).

ska_sun.sun.sph_dist(a1, d1, a2, d2)[source]

Calculate spherical distance between two sky positions.

Not highly accurate for very small angles, but this function is very fast for scalars (about 300 ns on modern hardware).

Parameters:
a1float

RA position 1 (deg)

d1float

Dec position 1 (deg)

a2float

RA position 2 (deg)

d2float

Dec position 2 (deg)

Returns:
float

Spherical distance (deg)