Skip to content
Snippets Groups Projects
Commit e5b0dec1 authored by Amy Stamile's avatar Amy Stamile
Browse files

Added docs and classes

parent 3bd1bd5b
No related branches found
No related tags found
No related merge requests found
import pyproj
import numpy as np
from collections import namedtuple
# from collections import namedtuple
from typing import NamedTuple
def sep_angle(a_pt, b_pt, c_pt):
return sep_angle(a_pt - b_pt, c_pt - b_pt)
class Point(NamedTuple):
x: float
y: float
z: float
class LatLon(NamedTuple):
lat: float
lon: float
class Sphere(NamedTuple):
lat: float
lon: float
radius: float
class Matrix(NamedTuple):
vec_a: Point
vec_b: Point
vec_c: Point
def sep_angle(a_vec, b_vec):
"""
Parameters
----------
a_vec : Point object (x, y, z)
b_vec : Point object (x, y, z)
Returns
-------
: float
"""
dot_prod = a_vec.x * b_vec.x + a_vec.y * b_vec.y + a_vec.z * b_vec.z
dot_prod /= magnitude(a_vec) * magnitude(b_vec)
......@@ -15,17 +43,43 @@ def sep_angle(a_vec, b_vec):
return np.arccos(dot_prod)
def magnitude(vec):
"""
Parameters
----------
vec : Point object (x, y, z)
Returns
-------
: float
"""
return np.sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z)
def distance(start, stop):
Point = namedtuple("Point", 'x, y, z')
"""
Parameters
----------
start : Point object (x, y, z)
stop : Point object (x, y, z)
Returns
-------
: float
"""
diff = Point(stop.x - start.x, stop.y - start.y, stop.z - start.z)
return magnitude(diff)
def radiansToDegrees(radian_lat_lon):
LatLon = namedtuple("LatLon", 'lat lon')
"""
Parameters
----------
radian_lat_lon : LatLon object (lat, lon) in radians
Returns
-------
: LatLon object (lat, lon) in degrees
"""
degree_lon = radian_lat_lon.lon
if (degree_lon < 0):
degree_lon += 2 * np.pi
......@@ -35,8 +89,15 @@ def radiansToDegrees(radian_lat_lon):
return LatLon(degreeLat, degree_lon)
def spherical_to_rect(spherical):
Point = namedtuple("Point", 'x, y, z')
"""
Parameters
----------
spherical : Sphere object (lat, lon, radius)
Returns
-------
: Point object (x, y, z)
"""
x = spherical.radius * np.cos(spherical.lat) * np.cos(spherical.lon)
y = spherical.radius * np.cos(spherical.lat) * np.sin(spherical.lon)
z = spherical.radius * np.sin(spherical.lat)
......@@ -44,8 +105,15 @@ def spherical_to_rect(spherical):
return Point(x, y, z)
def rect_to_spherical(rectangular):
Sphere = namedtuple("Sphere", 'lat, lon, radius')
"""
Parameters
----------
rectangular : Point object (x, y, z)
Returns
-------
: Sphere object (lat, lon, radius)
"""
rad = magnitude(rectangular)
if (rad < 1e-15):
return Sphere(0.0, 0.0, 0.0)
......@@ -57,8 +125,17 @@ def rect_to_spherical(rectangular):
)
def ground_azimuth(ground_pt, sub_pt):
LatLon = namedtuple("LatLon", 'lat lon')
"""
Parameters
----------
ground_pt : LatLon object (lat, lon)
sub_pt : LatLon object (lat, lon)
Returns
-------
: float
"""
if (ground_pt.lat >= 0.0):
a = (90.0 - sub_pt.lat) * np.pi / 180.0
b = (90.0 - ground_pt.lat) * np.pi / 180.0
......@@ -128,19 +205,47 @@ def ground_azimuth(ground_pt, sub_pt):
return azimuth
def crossProduct(a_vec, b_vec):
Point = namedtuple("Point", 'x, y, z')
"""
Parameters
----------
a_vec : Point object (x, y, z)
b_vec : Point object (x, y, z)
Returns
-------
: Point object (x, y, z)
"""
x = a_vec.y * b_vec.z - a_vec.z * b_vec.y
y = a_vec.z * b_vec.x - a_vec.x * b_vec.z
z = a_vec.x * b_vec.y - a_vec.y * b_vec.x
return Point(x, y, z)
def unit_vector(vec):
"""
Parameters
----------
vec : Point object (x, y, z)
Returns
-------
: Point object (x, y, z)
"""
mag = magnitude(vec)
return vec / mag
def perpendicular_vector(a_vec, b_vec):
"""
Parameters
----------
a_vec : Point object (x, y, z)
b_vec : Point object (x, y, z)
Returns
-------
: Point object (x, y, z)
"""
if (magnitude(a_vec) == 0):
return b_vec
......@@ -157,16 +262,34 @@ def perpendicular_vector(a_vec, b_vec):
return q
def scale_vector(vec, scalar):
Point = namedtuple("Point", 'x, y, z')
"""
Parameters
----------
vec : Point object (x, y, z)
scalar : float
Returns
-------
: Point object (x, y, z)
"""
return Point(vec.x * scalar, vec.y * scalar, vec.z * scalar)
def matrixVecProduct(mat, vec):
Point = namedtuple("Point", 'x, y, z')
def matrix_vec_product(mat, vec):
"""
Parameters
----------
mat : Matrix object (vec_a, vec_b, vec_c)
vec : Point object (x, y, z)
x = mat.a.x * vec.x + mat.a.y * vec.y + mat.a.z * vec.z
y = mat.b.x * vec.x + mat.b.y * vec.y + mat.b.z * vec.z
z = mat.c.x * vec.x + mat.c.y * vec.y + mat.c.z * vec.z
Returns
-------
: Point object (x, y, z)
"""
x = mat.vec_a.x * vec.x + mat.vec_a.y * vec.y + mat.vec_a.z * vec.z
y = mat.vec_b.x * vec.x + mat.vec_b.y * vec.y + mat.vec_b.z * vec.z
z = mat.vec_c.x * vec.x + mat.vec_c.y * vec.y + mat.vec_c.z * vec.z
return Point(x, y, z)
......
import numpy as np
from knoten import utils
from collections import namedtuple
Point = namedtuple("Point", 'x, y, z')
Sphere = namedtuple("Sphere", 'lat, lon, radius')
def test_sep_angle_right():
pt1 = Point(1, 0, 0)
pt2 = Point(0, 1, 0)
pt1 = utils.Point(1, 0, 0)
pt2 = utils.Point(0, 1, 0)
np.testing.assert_array_equal(utils.sep_angle(pt1, pt2), np.pi / 2.0)
def test_sep_angle_acute():
pt1 = Point(1, 0, 0)
pt2 = Point(1, 1, 0)
pt1 = utils.Point(1, 0, 0)
pt2 = utils.Point(1, 1, 0)
np.testing.assert_allclose(utils.sep_angle(pt1, pt2), np.pi / 4.0, atol=1e-12)
def test_sep_angle_obtuse():
pt1 = Point(1, 0, 0)
pt2 = Point(-1, 1, 0)
pt1 = utils.Point(1, 0, 0)
pt2 = utils.Point(-1, 1, 0)
np.testing.assert_array_equal(utils.sep_angle(pt1, pt2), 3.0 * np.pi / 4.0)
def test_sep_angle_normalization():
pt1 = Point(1, 0, 0)
pt2 = Point(1, 1, 0)
pt3 = Point(100, 0, 0)
pt4 = Point(100, 100, 0)
pt1 = utils.Point(1, 0, 0)
pt2 = utils.Point(1, 1, 0)
pt3 = utils.Point(100, 0, 0)
pt4 = utils.Point(100, 100, 0)
np.testing.assert_array_equal(utils.sep_angle(pt1, pt2), utils.sep_angle(pt3, pt4))
def test_magnitude_unit():
assert utils.magnitude(Point(1.0, 0.0, 0.0)) == 1.0
assert utils.magnitude(Point(0.0, 1.0, 0.0)) == 1.0
assert utils.magnitude(Point(0.0, 0.0, 1.0)) == 1.0
assert utils.magnitude(utils.Point(1.0, 0.0, 0.0)) == 1.0
assert utils.magnitude(utils.Point(0.0, 1.0, 0.0)) == 1.0
assert utils.magnitude(utils.Point(0.0, 0.0, 1.0)) == 1.0
def test_magnitude_nonunit():
assert utils.magnitude(Point(0.0, 0.0, 0.0)) == 0.0
assert utils.magnitude(Point(2.0, 1.0, 4.0)) == np.sqrt(21.0)
np.testing.assert_allclose(utils.magnitude(Point(0.2, 0.1, 0.4)), np.sqrt(0.21), atol=1e-12)
assert utils.magnitude(utils.Point(0.0, 0.0, 0.0)) == 0.0
assert utils.magnitude(utils.Point(2.0, 1.0, 4.0)) == np.sqrt(21.0)
np.testing.assert_allclose(utils.magnitude(utils.Point(0.2, 0.1, 0.4)), np.sqrt(0.21), atol=1e-12)
def test_distance():
assert utils.distance(Point(1.0, 2.0, 3.0), Point(6.0, 5.0, 4.0)) == np.sqrt(35)
assert utils.distance(utils.Point(1.0, 2.0, 3.0), utils.Point(6.0, 5.0, 4.0)) == np.sqrt(35)
def test_spherical_to_rect():
result = utils.spherical_to_rect(Sphere(0.0, 0.0, 1000.0))
result = utils.spherical_to_rect(utils.Sphere(0.0, 0.0, 1000.0))
np.testing.assert_allclose(result.x, 1000.0, atol=1e-12)
np.testing.assert_allclose(result.y, 0.0, atol=1e-12)
np.testing.assert_allclose(result.z, 0.0, atol=1e-12)
result = utils.spherical_to_rect(Sphere(0.0, np.pi, 1000.0))
result = utils.spherical_to_rect(utils.Sphere(0.0, np.pi, 1000.0))
np.testing.assert_allclose( result.x, -1000.0, atol=1e-12)
np.testing.assert_allclose( result.y, 0.0, atol=1e-12)
np.testing.assert_allclose( result.z, 0.0, atol=1e-12)
result = utils.spherical_to_rect(Sphere(np.pi / 2.0, 0.0, 1000.0))
result = utils.spherical_to_rect(utils.Sphere(np.pi / 2.0, 0.0, 1000.0))
np.testing.assert_allclose( result.x, 0.0, atol=1e-12)
np.testing.assert_allclose( result.y, 0.0, atol=1e-12)
np.testing.assert_allclose( result.z, 1000.0, atol=1e-12)
result = utils.spherical_to_rect(Sphere(np.pi / -2.0, 0.0, 1000.0))
result = utils.spherical_to_rect(utils.Sphere(np.pi / -2.0, 0.0, 1000.0))
np.testing.assert_allclose( result.x, 0.0, atol=1e-12)
np.testing.assert_allclose( result.y, 0.0, atol=1e-12)
np.testing.assert_allclose( result.z, -1000.0, atol=1e-12)
def test_rect_to_spherical():
result = utils.rect_to_spherical(Point(1000.0, 0.0, 0.0))
np.testing.assert_array_equal(result, Sphere(0.0, 0.0, 1000.0))
result = utils.rect_to_spherical(utils.Point(1000.0, 0.0, 0.0))
np.testing.assert_array_equal(result, utils.Sphere(0.0, 0.0, 1000.0))
result = utils.rect_to_spherical(Point(-1000.0, 0.0, 0.0))
np.testing.assert_array_equal(result, Sphere(0.0, np.pi, 1000.0))
result = utils.rect_to_spherical(utils.Point(-1000.0, 0.0, 0.0))
np.testing.assert_array_equal(result, utils.Sphere(0.0, np.pi, 1000.0))
result = utils.rect_to_spherical(Point(0.0, 0.0, 1000.0))
np.testing.assert_array_equal(result, Sphere(np.pi / 2.0, 0.0, 1000.0))
result = utils.rect_to_spherical(utils.Point(0.0, 0.0, 1000.0))
np.testing.assert_array_equal(result, utils.Sphere(np.pi / 2.0, 0.0, 1000.0))
result = utils.rect_to_spherical(Point(0.0, 0.0, -1000.0))
np.testing.assert_array_equal(result, Sphere(np.pi / -2.0, 0.0, 1000.0))
result = utils.rect_to_spherical(utils.Point(0.0, 0.0, -1000.0))
np.testing.assert_array_equal(result, utils.Sphere(np.pi / -2.0, 0.0, 1000.0))
def test_ground_azimuth():
LatLon = namedtuple("LatLon", "lat lon")
ground_pt = LatLon(0, -180)
subsolar_pt = LatLon(0, 90)
ground_pt = utils.LatLon(0, -180)
subsolar_pt = utils.LatLon(0, 90)
np.testing.assert_array_equal(270.0, utils.ground_azimuth(ground_pt, subsolar_pt))
def test_perpendicular_vector():
vec_a = Point(6.0, 6.0, 6.0)
vec_b = Point(2.0, 0.0, 0.0)
result = Point(0.0, 6.0, 6.0)
vec_a = utils.Point(6.0, 6.0, 6.0)
vec_b = utils.Point(2.0, 0.0, 0.0)
result = utils.Point(0.0, 6.0, 6.0)
np.testing.assert_array_equal(utils.perpendicular_vector(vec_a, vec_b), result)
def test_unit_vector():
result = utils.unit_vector(Point(5.0, 12.0, 0.0))
result = utils.unit_vector(utils.Point(5.0, 12.0, 0.0))
np.testing.assert_allclose(result[0], 0.384615, atol=1e-6)
np.testing.assert_allclose(result[1], 0.923077, atol=1e-6)
np.testing.assert_array_equal(result[2], 0.0)
def test_scale_vector():
vec = Point(1.0, 2.0, -3.0)
vec = utils.Point(1.0, 2.0, -3.0)
scalar = 3.0
result = Point(3.0, 6.0, -9.0)
result = utils.Point(3.0, 6.0, -9.0)
np.testing.assert_array_equal(utils.scale_vector(vec, scalar), result)
def test_matrix_vec_product():
vec_a = utils.Point(0.0, 1.0, 0.0)
vec_b = utils.Point(-1.0, 0.0, 0.0)
vec_c = utils.Point(0.0, 0.0, 1.0)
mat = utils.Matrix(vec_a, vec_b, vec_c)
vec = utils.Point(1.0, 2.0, 3.0)
result = utils.Point(2.0, -1.0, 3.0)
np.testing.assert_array_equal(result, utils.matrix_vec_product(mat, vec))
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment