Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Apply black and isort #23

Merged
merged 4 commits into from
Dec 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .github/workflows/black.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: Check black formatting

on: [push]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: psf/black@stable
6 changes: 3 additions & 3 deletions .github/workflows/flake8.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.8
uses: actions/setup-python@v1
uses: actions/setup-python@v4
with:
python-version: 3.8
- name: Lint with flake8
run: |
pip install flake8
flake8 . --count --exclude=docs --ignore=E402,W503,F541 --max-line-length=100 --show-source --statistics
flake8 . --exclude=docs --count --ignore=W503,W504,F541,E203 --max-line-length=100 --show-source --statistics
12 changes: 12 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
repos:
- repo: https://github.com/psf/black
rev: 22.12.0
hooks:
- id: black
language_version: python3.11

- repo: https://github.com/pycqa/isort
rev: 5.11.4
hooks:
- id: isort
name: isort (python)
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#
import os
import sys

sys.path.insert(0, os.path.abspath('..'))
from Ska.Sun import __version__

Expand Down
11 changes: 6 additions & 5 deletions make_rolldev_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@

import numpy as np
from astropy.table import Table
dat = Table.read('pitch_roll_2022.csv')

assert np.allclose(np.abs(dat['negrolldev']), dat['rolldev'], rtol=0, atol=1e-08)
dat = Table.read("pitch_roll_2022.csv")

dat['pitch'] = dat['pitch'].astype(np.float32)
dat['rolldev'] = dat['rolldev'].astype(np.float32)
dat['pitch', 'rolldev'].write('pitch_roll.fits.gz', overwrite=True)
assert np.allclose(np.abs(dat["negrolldev"]), dat["rolldev"], rtol=0, atol=1e-08)

dat["pitch"] = dat["pitch"].astype(np.float32)
dat["rolldev"] = dat["rolldev"].astype(np.float32)
dat["pitch", "rolldev"].write("pitch_roll.fits.gz", overwrite=True)
20 changes: 20 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[tool.black]
include = '\.pyi?$'
exclude = '''
/(
\.git
| \.mypy_cache
| \.tox
| \.venv
| \.vscode
| \.eggs
| _build
| buck-out
| build
| dist
| docs
)/
'''

[tool.isort]
profile = "black"
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Licensed under a 3-clause BSD style license - see LICENSE.rst

from setuptools import setup
from testr.setup_helper import cmdclass
from ska_helpers.setup_helper import duplicate_package_info
from testr.setup_helper import cmdclass

name = "ska_sun"
namespace = "Ska.Sun"
Expand Down
8 changes: 5 additions & 3 deletions ska_sun/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# Licensed under a 3-clause BSD style license - see LICENSE.rst

import ska_helpers

from .sun import * # noqa

__version__ = ska_helpers.get_version('ska_sun')
__version__ = ska_helpers.get_version("ska_sun")


def test(*args, **kwargs):
'''
"""
Run py.test unit tests.
'''
"""
import testr

return testr.test(*args, **kwargs)
72 changes: 39 additions & 33 deletions ska_sun/sun.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,24 @@
"""
Utility for calculating sun position, pitch angle and values related to roll.
"""
from math import acos, asin, atan2, cos, degrees, pi, radians, sin
from pathlib import Path

import numpy as np
from math import cos, sin, acos, atan2, asin, pi, radians, degrees
import Ska.quatutil
from astropy.table import Table

from ska_helpers.utils import LazyVal
from Quaternion import Quat
from chandra_aca.transform import radec_to_eci
from Chandra.Time import DateTime
import Ska.quatutil
from chandra_aca.transform import radec_to_eci
from Quaternion import Quat
from ska_helpers.utils import LazyVal


def load_roll_table():
dat = Table.read(Path(__file__).parent / 'data' / 'pitch_roll.fits.gz')
dat = Table.read(Path(__file__).parent / "data" / "pitch_roll.fits.gz")

# Add a terminating row to the data such that for pitch at or greater
# than 180 the allowed roll deviation is defined as 0.
dat.add_row({'pitch': 180, 'rolldev': 0})
dat.add_row({"pitch": 180, "rolldev": 0})
return dat


Expand All @@ -31,13 +31,13 @@ def allowed_rolldev(pitch):
:param pitch: Sun pitch angle (deg)
:returns: Roll deviation (deg)
"""
idx1 = np.searchsorted(ROLL_TABLE.val['pitch'], pitch, side='right')
idx1 = np.searchsorted(ROLL_TABLE.val["pitch"], pitch, side="right")
idx0 = idx1 - 1
idx_max = len(ROLL_TABLE.val) - 1
idx0 = np.clip(idx0, 0, idx_max)
idx1 = np.clip(idx1, 0, idx_max)
val0 = ROLL_TABLE.val['rolldev'][idx0]
val1 = ROLL_TABLE.val['rolldev'][idx1]
val0 = ROLL_TABLE.val["rolldev"][idx0]
val1 = ROLL_TABLE.val["rolldev"][idx1]
out = np.minimum(val0, val1) # works even for a vector input for `pitch`
return out

Expand Down Expand Up @@ -102,25 +102,30 @@ def position(time):

# allow for the Venus perturbations using the mean anomaly of Venus MV
mv = 212.603219 + (58517.803875 * t) % 360.0
vencorr = 4.8 * cos((299.1017 + mv - me) * dtor) + \
5.5 * cos((148.3133 + 2.0 * mv - 2.0 * me) * dtor) + \
2.5 * cos((315.9433 + 2.0 * mv - 3.0 * me) * dtor) + \
1.6 * cos((345.2533 + 3.0 * mv - 4.0 * me) * dtor) + \
1.0 * cos((318.15 + 3.0 * mv - 5.0 * me) * dtor)
vencorr = (
4.8 * cos((299.1017 + mv - me) * dtor)
+ 5.5 * cos((148.3133 + 2.0 * mv - 2.0 * me) * dtor)
+ 2.5 * cos((315.9433 + 2.0 * mv - 3.0 * me) * dtor)
+ 1.6 * cos((345.2533 + 3.0 * mv - 4.0 * me) * dtor)
+ 1.0 * cos((318.15 + 3.0 * mv - 5.0 * me) * dtor)
)
lon = lon + vencorr

# Allow for the Mars perturbations using the mean anomaly of Mars MM
mm = 319.529425 + (19139.858500 * t) % 360.0
marscorr = 2.0 * cos((343.8883 - 2.0 * mm + 2.0 * me) * dtor) + \
1.8 * cos((200.4017 - 2.0 * mm + me) * dtor)
marscorr = 2.0 * cos((343.8883 - 2.0 * mm + 2.0 * me) * dtor) + 1.8 * cos(
(200.4017 - 2.0 * mm + me) * dtor
)
lon = lon + marscorr

# Allow for the Jupiter perturbations using the mean anomaly of Jupiter MJ
mj = 225.328328 + (3034.6920239 * t) % 360.0
jupcorr = 7.2 * cos((179.5317 - mj + me) * dtor) + \
2.6 * cos((263.2167 - mj) * dtor) + \
2.7 * cos((87.1450 - 2.0 * mj + 2.0 * me) * dtor) + \
1.6 * cos((109.4933 - 2.0 * mj + me) * dtor)
jupcorr = (
7.2 * cos((179.5317 - mj + me) * dtor)
+ 2.6 * cos((263.2167 - mj) * dtor)
+ 2.7 * cos((87.1450 - 2.0 * mj + 2.0 * me) * dtor)
+ 1.6 * cos((109.4933 - 2.0 * mj + me) * dtor)
)
lon = lon + jupcorr

# Allow for the Moons perturbations using the mean elongation of the Moon
Expand Down Expand Up @@ -148,11 +153,11 @@ def position(time):
lon = lon / 3600.0
ra = atan2(sin(lon * dtor) * cos(oblt * dtor), cos(lon * dtor))

while ((ra < 0) or (ra > (2 * pi))):
if (ra < 0):
ra += (2 * pi)
if (ra > (2 * pi)):
ra -= (2 * pi)
while (ra < 0) or (ra > (2 * pi)):
if ra < 0:
ra += 2 * pi
if ra > (2 * pi):
ra -= 2 * pi

dec = asin(sin(lon * dtor) * sin(oblt * dtor))

Expand Down Expand Up @@ -230,12 +235,14 @@ def nominal_roll(ra, dec, time=None, sun_ra=None, sun_dec=None):
sun_ra, sun_dec = position(time)
sun_eci = Ska.quatutil.radec2eci(sun_ra, sun_dec)
body_x = Ska.quatutil.radec2eci(ra, dec)
if np.sum((sun_eci - body_x)**2) < 1e-10:
raise ValueError('No nominal roll for ra, dec == sun_ra, sun_dec')
if np.sum((sun_eci - body_x) ** 2) < 1e-10:
raise ValueError("No nominal roll for ra, dec == sun_ra, sun_dec")
body_y = np.cross(body_x, sun_eci)
body_y = body_y / np.sqrt(np.sum(body_y**2))
body_z = np.cross(body_x, body_y)
body_z = body_z / np.sqrt(np.sum(body_z**2)) # shouldn't be needed but do it anyway
body_z = body_z / np.sqrt(
np.sum(body_z**2)
) # shouldn't be needed but do it anyway
q_att = Quat(np.array([body_x, body_y, body_z]).transpose())
return q_att.roll

Expand Down Expand Up @@ -302,7 +309,7 @@ def get_sun_pitch_yaw(ra, dec, time=None, sun_ra=None, sun_dec=None):
sun_frame_rot = sun_frame.transform.T

# Compute attitude vector in Sun frame.
att_sun = np.einsum('...jk,...k->...j', sun_frame_rot, att_eci)
att_sun = np.einsum("...jk,...k->...j", sun_frame_rot, att_eci)

# Usual for pitch and yaw. The yaw is set to match ORviewer:
# get_sun_pitch_yaw(109, 55.3, time='2021:242') ~ (60, 30)
Expand All @@ -314,8 +321,7 @@ def get_sun_pitch_yaw(ra, dec, time=None, sun_ra=None, sun_dec=None):
return np.rad2deg(pitch), np.rad2deg(yaw)


def apply_sun_pitch_yaw(att, pitch=0, yaw=0,
time=None, sun_ra=None, sun_dec=None):
def apply_sun_pitch_yaw(att, pitch=0, yaw=0, time=None, sun_ra=None, sun_dec=None):
"""Apply pitch(es) and yaw(s) about Sun line to an attitude.

:param att: Quaternion-like
Expand Down
78 changes: 45 additions & 33 deletions ska_sun/tests/test_sun.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,50 +2,60 @@

import numpy as np
from Quaternion import Quat
from ..sun import (apply_sun_pitch_yaw, get_sun_pitch_yaw, nominal_roll,
off_nominal_roll, position, allowed_rolldev,
pitch as sun_pitch)

from ..sun import (
allowed_rolldev,
apply_sun_pitch_yaw,
get_sun_pitch_yaw,
nominal_roll,
off_nominal_roll,
)
from ..sun import pitch as sun_pitch
from ..sun import position


def test_allowed_rolldev():

# Test array of pitchs and allowed roll dev
testarr = [[135, 13.979],
[138, 14.516],
[0, 0],
[40, 0],
[179.9, 18.748772],
[179.997, 0],
[180, 0],
[181, 0],
[85.49229, 13.677669],
[85.52, 18.756727],
[124.99, 18.748772],
[125, 17.0]]
testarr = [
[135, 13.979],
[138, 14.516],
[0, 0],
[40, 0],
[179.9, 18.748772],
[179.997, 0],
[180, 0],
[181, 0],
[85.49229, 13.677669],
[85.52, 18.756727],
[124.99, 18.748772],
[125, 17.0],
]
for pitch, rolldev in testarr:
assert np.isclose(allowed_rolldev(pitch), rolldev)

# Also test with pitch as vector
assert np.allclose(allowed_rolldev(np.array(testarr)[:, 0]),
np.array(testarr)[:, 1])
assert np.allclose(
allowed_rolldev(np.array(testarr)[:, 0]), np.array(testarr)[:, 1]
)


def test_position():
ra, dec = position('2008:002:00:01:02')
ra, dec = position("2008:002:00:01:02")
assert np.allclose((ra, dec), (281.903448, -22.989273))


def test_nominal_roll():
roll = nominal_roll(205.3105, -14.6925, time='2011:019:20:51:13')
roll = nominal_roll(205.3105, -14.6925, time="2011:019:20:51:13")
assert np.allclose(roll, 68.83020) # vs. 68.80 for obsid 12393 in JAN1711A


def test_off_nominal_roll_and_pitch():
att = (198.392135, 36.594359, 33.983322) # RA, Dec, Roll of obsid 16354
oroll = off_nominal_roll(att, '2015:335:00:00:00') # NOT the 16354 time
oroll = off_nominal_roll(att, "2015:335:00:00:00") # NOT the 16354 time
assert np.isclose(oroll, -12.224010)

date = '2015:077:01:07:04'
date = "2015:077:01:07:04"
pitch = sun_pitch(att[0], att[1], time=date)
assert np.isclose(pitch, 139.5651) # vs. 139.59 in SOT MP page

Expand All @@ -55,8 +65,9 @@ def test_off_nominal_roll_and_pitch():

def test_apply_get_sun_pitch_yaw():
"""Test apply and get sun_pitch_yaw with multiple components"""
att = apply_sun_pitch_yaw([0, 45, 0], pitch=[0, 10, 20], yaw=[0, 5, 10],
sun_ra=0, sun_dec=90)
att = apply_sun_pitch_yaw(
[0, 45, 0], pitch=[0, 10, 20], yaw=[0, 5, 10], sun_ra=0, sun_dec=90
)
pitch, yaw = get_sun_pitch_yaw(att.ra, att.dec, sun_ra=0, sun_dec=90)
assert np.allclose(pitch, 45 + np.array([0, 10, 20]))
assert np.allclose(yaw, 180 + np.array([0, 5, 10]))
Expand All @@ -75,15 +86,16 @@ def test_apply_sun_pitch_yaw():
def test_apply_sun_pitch_yaw_with_grid():
"""Use np.ogrid to make a grid of RA/Dec values (via dpitches and dyaws)"""
dpitches, dyaws = np.ogrid[0:-3:2j, -5:5:3j]
atts = apply_sun_pitch_yaw(att=[0, 45, 10], pitch=dpitches, yaw=dyaws, sun_ra=0, sun_dec=90)
atts = apply_sun_pitch_yaw(
att=[0, 45, 10], pitch=dpitches, yaw=dyaws, sun_ra=0, sun_dec=90
)
assert atts.shape == (2, 3)
exp = np.array(
[[[355., 45., 10.],
[360., 45., 10.],
[5., 45., 10.]],
[[355., 48., 10.],
[0., 48., 10.],
[5., 48., 10.]]])
[
[[355.0, 45.0, 10.0], [360.0, 45.0, 10.0], [5.0, 45.0, 10.0]],
[[355.0, 48.0, 10.0], [0.0, 48.0, 10.0], [5.0, 48.0, 10.0]],
]
)
assert np.allclose(atts.equatorial, exp)


Expand All @@ -92,9 +104,9 @@ def test_get_sun_pitch_yaw():

See slack discussion "ORviewer sun / anti-sun plots azimuthal Sun yaw angle"
"""
pitch, yaw = get_sun_pitch_yaw(109, 55.3, time='2021:242')
pitch, yaw = get_sun_pitch_yaw(109, 55.3, time="2021:242")
assert np.allclose((pitch, yaw), (60.453385, 29.880125))
pitch, yaw = get_sun_pitch_yaw(238.2, -58.9, time='2021:242')
pitch, yaw = get_sun_pitch_yaw(238.2, -58.9, time="2021:242")
assert np.allclose((pitch, yaw), (92.405603, 210.56582))
pitch, yaw = get_sun_pitch_yaw(338, -9.1, time='2021:242')
pitch, yaw = get_sun_pitch_yaw(338, -9.1, time="2021:242")
assert np.allclose((pitch, yaw), (179.417797, 259.703451))