Skip to content

Commit 0ef89ce

Browse files
committed
working static types for geometry.py, move optplot constant to constant.py
1 parent f8af45a commit 0ef89ce

File tree

4 files changed

+40
-26
lines changed

4 files changed

+40
-26
lines changed

tracepy/constants.py

+3
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@
77
MAX_REFRACTION_ITERATIONS = 1e5 # Max iter before failed refraction.
88
INTERSECTION_CONVERGENCE_TOLERANCE = 1e-6 # Tolerance for intersection search.
99
REFRACTION_CONVERGENCE_TOLERANCE = 1e-15 # Tolerance for refraction.
10+
11+
# Constants used for plotting
12+
PLOT_ROUNDING_ACC = 14 # Rounding accuracy for spot diagrams and plots.

tracepy/exceptions.py

+3
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,6 @@ class NotOnSurfaceError(Exception):
66

77
class TraceError(Exception):
88
""" Custom error for lens systems where no rays survive being traced. """
9+
10+
class InvalidGeometry(Exception):
11+
""" Invalid parameters were given to define a geometry object. """

tracepy/geometry.py

+32-25
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import numpy as np
22

33
from .utils import gen_rot
4-
from .exceptions import NotOnSurfaceError
4+
from .exceptions import NotOnSurfaceError, InvalidGeometry
55
from .index import glass_index
66

7-
from typing import Dict, List, Tuple
7+
from typing import Dict, List, Tuple, Union, Optional
88

99
class geometry:
1010
"""Class for the different surfaces in an optical system.
@@ -47,16 +47,24 @@ class geometry:
4747
"""
4848

4949
def __init__(self, params: Dict):
50-
self.P = params['P']
51-
self.D = np.array(params.get('D', [0., 0., 0.]))
52-
self.action = params['action']
53-
self.Diam = params['Diam']
54-
self.N = params.get('N', 1.)
55-
self.kappa = params.get('kappa', None)
56-
self.diam = params.get('diam', 0.)
57-
self.c = params.get('c', 0.)
58-
self.name = params.get('name', None)
59-
self.R = gen_rot(self.D)
50+
P = params.get('P')
51+
# Allow on axis integer for P.
52+
if isinstance(P, float) or isinstance(P, int):
53+
P = np.array([0., 0., P])
54+
elif isinstance(P, List):
55+
P = np.array(P)
56+
else:
57+
raise InvalidGeometry()
58+
self.P: np.ndarray = np.array(P)
59+
self.D: np.ndarray = np.array(params.get('D', [0., 0., 0.]))
60+
self.action: str = params['action']
61+
self.Diam: Union[float, int] = params['Diam']
62+
self.N: Union[float, int] = params.get('N', 1.)
63+
self.kappa: Optional[Union[float, int]] = params.get('kappa')
64+
self.diam: Union[float, int] = params.get('diam', 0.)
65+
self.c: Union[float, int] = params.get('c', 0.)
66+
self.name: str = params.get('name', None)
67+
self.R: np.ndarray = gen_rot(self.D)
6068
if params.get('glass'):
6169
self.glass = glass_index(params.get('glass'))
6270
self.check_params()
@@ -66,22 +74,15 @@ def check_params(self) -> None:
6674
6775
Summary
6876
-------
69-
If P is given as a float/int then it is converted to a np array
70-
with that float/int in the Z direction. If c != 0 (in the case
71-
of a conic) then kappa must be specified, and if kappa is greater
72-
than 0 then the value of c is redundant by boundary conditions of
73-
the conic equation. Lastly, if c == 0 in the case of a planar
74-
surface the None value of kappa needs to be set to a dummy value
75-
to avoid exceptions in calculating the conic equation. Note that
76-
this does not affect the calculation since c is 0.
77+
If c != 0 (in the case of a conic) then kappa must be specified,
78+
and if kappa is greater than 0 then the value of c is redundant
79+
by boundary conditions of the conic equation. Lastly, if c == 0 in
80+
the case of a planar surface the None value of kappa needs to be set
81+
to a dummy value to avoid exceptions in calculating the conic equation.
82+
Note that this does not affect the calculation since c is 0.
7783
7884
"""
7985

80-
if isinstance(self.P, float) or isinstance(self.P, int):
81-
#Allow on axis integer for P.
82-
self.P = np.array([0., 0., self.P])
83-
else:
84-
self.P = np.array(self.P)
8586
if self.c != 0:
8687
if self.kappa is None:
8788
raise Exception("Specify a kappa for this conic.")
@@ -131,6 +132,9 @@ def conics(self, point: np.ndarray) -> Tuple[float, List[float]]:
131132
rho = np.sqrt(pow(X,2) + pow(Y, 2))
132133
if rho > self.Diam/2. or rho < self.diam/2.:
133134
raise NotOnSurfaceError()
135+
# Ensure kappa is not None before using it in calculations
136+
if self.kappa is None:
137+
raise ValueError("kappa must not be None for conic calculations")
134138
#Conic equation.
135139
function = Z - self.c*pow(rho, 2)/(1 + pow((1-self.kappa*pow(self.c, 2)*pow(rho,2)), 0.5))
136140
#See Spencer, Murty section on rotational surfaces for definition of E.
@@ -160,5 +164,8 @@ def conics_plot(self, point: np.ndarray) -> np.ndarray:
160164
nan_idx = (rho > self.Diam/2.) + (rho < self.diam/2.)
161165
rho = np.sqrt(pow(X[~nan_idx],2) + pow(Y[~nan_idx], 2))
162166
function[nan_idx] = np.nan
167+
# Ensure kappa is not None before using it in calculations
168+
if self.kappa is None:
169+
raise ValueError("kappa must not be None for conic plot calculations")
163170
function[~nan_idx] = self.c*pow(rho, 2)/(1 + pow((1-self.kappa*pow(self.c, 2)*pow(rho,2)), 0.5))
164171
return function

tracepy/optplot.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import matplotlib.pyplot as plt
33

44
from .ray import ray
5+
from .constants import PLOT_ROUNDING_ACC
56
from .geometry import geometry
67
from .transforms import transform_points
78
from .exceptions import TraceError
@@ -40,7 +41,7 @@ def _gen_object_points(surface: geometry,
4041
points_obj = transform_points(surface.R, surface, points)
4142

4243
# Round arrays to upper bound on accuracy.
43-
return np.around(points_obj, 14)
44+
return np.around(points_obj, PLOT_ROUNDING_ACC)
4445

4546
def calculate_rms(points: np.ndarray) -> float:
4647
"""Calculates the RMS of the given points.

0 commit comments

Comments
 (0)