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

Make all artifact arguments optional & Add assert statements to catch undefined components in system functions #98

Merged
merged 17 commits into from
Jun 25, 2022
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
c13de02
Add assert statements to catch undefined components in system functio…
abeerfatima Jun 11, 2022
d170991
Add assert statements to catch undefined components in system functio…
abeerfatima Jun 11, 2022
a14c92d
Add assert statements to catch undefined components in system functio…
abeerfatima Jun 11, 2022
0688a6d
Add assert statements to catch undefined components in system functio…
abeerfatima Jun 11, 2022
fd67b33
Add assert statements to catch undefined components in system functio…
abeerfatima Jun 11, 2022
1f2c3e1
Add assert statements to catch undefined components in system functio…
abeerfatima Jun 11, 2022
2ad3e05
Add assert statements to catch undefined components in system functio…
abeerfatima Jun 11, 2022
852976b
Add assert statements to catch undefined components in system functio…
abeerfatima Jun 11, 2022
b9fbb54
Add assert statements to catch undefined components in system functio…
abeerfatima Jun 11, 2022
38b1def
Update payload_designer/components/component.py
abeerfatima Jun 25, 2022
6282aee
Update payload_designer/systems/satellites.py
abeerfatima Jun 25, 2022
43df45b
Update payload_designer/systems/satellites.py
abeerfatima Jun 25, 2022
943b890
Update payload_designer/luts/functions.py
abeerfatima Jun 25, 2022
01a8bac
Update payload_designer/luts/functions.py
abeerfatima Jun 25, 2022
ad1db0a
Update payload_designer/luts/functions.py
abeerfatima Jun 25, 2022
c4a7f22
Update payload_designer/components/filters.py
abeerfatima Jun 25, 2022
11dc406
Update payload_designer/luts/functions.py
abeerfatima Jun 25, 2022
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
3 changes: 2 additions & 1 deletion payload_designer/components/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ def __init__(self, dimensions: tuple = None, mass=None):

def get_volume(self):
"""Get the volume of the component from its bounding box."""

assert self.dimensions is not None, "A dimensions component must be specified."

volume = self.dimensions[0] * self.dimensions[1] * self.dimensions[2]

return volume
26 changes: 23 additions & 3 deletions payload_designer/components/diffractors.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ def get_emergent_angle(self, incident_angle, wavelength, order=1):
order: Diffraction order.

"""

assert self.fringe_frequency is not None, "Fringe frequency must be specified."

emergent_angle = np.arcsin(
np.sin(incident_angle) - order * self.fringe_frequency * wavelength
)
Expand Down Expand Up @@ -149,7 +150,10 @@ def __init__(
def get_emergent_angle(
self, incident_angle, wavelength, n_initial=1, n_final=1, order=1
):

assert self.index_seal is not None, "Index Seal must be specified."
assert self.fringe_frequency is not None, "Fringe frequency must be specified."
assert self.index_dcg is not None, "Index DCG must be specified."

angle_1 = snell(angle=incident_angle, n_1=n_initial, n_2=self.index_seal)
angle_2 = np.arscin(
(order * wavelength * self.fringe_frequency / self.index_dcg)
Expand All @@ -161,7 +165,10 @@ def get_emergent_angle(

def get_transmittance_theoretical(self, wavelength, order=1):
"""Calculates the Kogelnik efficiency for unpolarized light."""

assert self.index_dcg is not None, "Index DCG must be specified."
assert self.index_dcg_amplitude is not None, "Index DCG amplitude must be specified."
assert self.dcg_thickness is not None, "DCG thickness must be specified."

a_2b = np.arcsin((order * wavelength) / (2 * self.index_dcg * wavelength))
mu_s = (
np.sin(
Expand All @@ -185,6 +192,9 @@ def get_transmittance_theoretical(self, wavelength, order=1):
return mu_s

def get_efficiency_bandwidth(self, wavelength, order=1):
assert self.index_dcg is not None, "Index DCG must be specified."
assert self.dcg_thickness is not None, "DCG thickness must be specified."

a_2b = np.arcsin((order * wavelength) / (2 * self.index_dcg * wavelength))
lmda_eff = (wavelength * wavelength) / (self.dcg_thickness * np.tan(a_2b))

Expand Down Expand Up @@ -227,6 +237,11 @@ def __init__(
def get_emergent_angle(
self, angle_in, wavelength, index_in=1, index_out=1, order=1
):
assert self.apex_angle is not None, "Apex angle must be specified."
assert self.index_prism is not None, "Index prism amplitude must be specified."
assert self.fringe_frequency is not None, "Fringe frequency must be specified."
assert self.index_seal is not None, "Index seal must be specified."

angle_1 = angle_in + self.apex_angle
angle_2 = snell(angle=angle_1, n_1=index_in, n_2=self.index_prism)
angle_3 = self.apex_angle - angle_2
Expand All @@ -244,6 +259,11 @@ def get_emergent_angle(
return angle_out

def get_undeviated_wavelength(self, angle_in, order=1, index_in=1, index_out=1):
assert self.apex_angle is not None, "Apex angle must be specified."
assert self.index_prism is not None, "Index prism amplitude must be specified."
assert self.fringe_frequency is not None, "Fringe frequency must be specified."
assert self.index_seal is not None, "Index seal must be specified."

angle_1 = angle_in + self.apex_angle
angle_2 = snell(angle=angle_1, n_1=index_in, n_2=self.index_prism)
angle_3 = self.apex_angle - angle_2
Expand Down
12 changes: 7 additions & 5 deletions payload_designer/components/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,16 @@ def __init__(
super().__init__(
diameter=diameter,
focal_length=None,
index=index,
mass=mass,
thickness=thickness,
transmittance=transmittance,
index=None,
mass=None,
thickness=None,
transmittance=None,
),

def get_phase_shift(self, wavelength, angle_in, index_in=1):
"""Get the phase shift of the filter."""

assert self.index is not None, "Index must be specified."

wavelength_shifted = wavelength * np.sqrt(
1 - ((index_in, self.index) * np.sin(angle_in) ** 2)
)
Expand All @@ -44,6 +45,7 @@ def get_phase_shift(self, wavelength, angle_in, index_in=1):

def get_reflectance(self, index_in=1):
"""Get the reflectance of the filter."""
assert self.index is not None, "Index must be specified."

reflectance = ((self.index - index_in) / (self.index + index_in)) ** 2

Expand Down
6 changes: 4 additions & 2 deletions payload_designer/components/lenses.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,16 @@ def __init__(
def get_image_height(self, incident_angle):
"""Get the height of the image formed above or below the optical axis of
the lens for an incoming beam of collimated light."""

assert self.focal_length is not None, "Focal length must be specified."

image_height = self.focal_length * np.tan(incident_angle)

return image_height

def get_volume(self):
"""Get the volume of the lens."""

assert self.diameter is not None, "Diameter must be specified."

volume = const.pi * (self.diameter / 2) ** 2 * self.thickness

return volume
3 changes: 2 additions & 1 deletion payload_designer/components/masks.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ def __init__(self, mass=None, diameter=None, thickness=None, size: tuple = None)

def get_area(self):
"""Get the clear aperture slit area."""

assert self.size is not None, "Size must be specified."

area = self.size[0] * self.size[1]

return area
17 changes: 13 additions & 4 deletions payload_designer/components/sensors.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ def __init__(
def get_size(self) -> tuple:
"""Get the size of the sensor face in the (x, y) dimensions of the
cubesat frame."""

assert self.n_px is not None, "n_px must be specified."
assert self.pitch is not None, "Pitch must be specified."

size = (self.n_px * self.pitch, self.n_px * self.pitch)

return size
Expand All @@ -83,28 +85,35 @@ def get_pixel_area(self):
Assumes square pixels.

"""
assert self.pitch is not None, "Pitch must be specified."

pixel_area = self.pitch**2

return pixel_area

def get_dark_noise(self):
"""Get the dark noise of the sensor."""

assert self.i_dark is not None, "i_dark must be specified."
assert self.dt is not None, "dt amplitude must be specified."

dark_noise = self.i_dark * self.dt

return dark_noise

def get_quantization_noise(self):
"""Get the quantization noise of the sensor."""

assert self.n_well is not None, "n_well must be specified."
assert self.n_bit is not None, "n_bit must be specified."

quant_noise = (1 / math.sqrt(12)) * self.n_well / 2**self.n_bit

return quant_noise

def get_noise(self, signal):
"""Get the net noise of the sensor."""

assert self.n_bin is not None, "n_bin must be specified."
assert self.noise_read is not None, "noise_read must be specified."

noise = np.sqrt(
signal
+ self.n_bin * self.get_dark_noise() ** 2
Expand Down
7 changes: 7 additions & 0 deletions payload_designer/luts/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,22 @@ def __init__(self, path: Path, name: str = None):
self.name = name

def get_table(self):
assert self.x is not None, "x must be specified."
assert self.y is not None, "y must be specified."

data = {f"X [{self.x.unit}]": self.x.value, f"Y [{self.y.unit}]": self.y.value}

df = pd.DataFrame.from_dict(data)

return df

def __str__(self):
assert self.name is not None, "Name must be specified."
df = self.get_table()
return f"LUT ({self.name})\n{df.to_string(index=False)}"

def _repr_html_(self):
assert self.name is not None, "Name must be specified."
df = self.get_table()
return f"LUT ({self.name})\n{df.to_html(index=False)}"

Expand All @@ -59,6 +64,8 @@ def __call__(self, x):
array-like: The interpolated y values.

"""
assert self.x is not None, "x must be specified."
assert self.y is not None, "y must be specified."
return np.interp(x=x, xp=self.x, fp=self.y)


Expand Down
9 changes: 7 additions & 2 deletions payload_designer/systems/payloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ def get_signal_to_noise(self, radiance: LUT, wavelength):
wavelength: Wavelength(s) at which to evaluate SNR.

"""
assert self.sensor is not None, "A sensor component must be specified."
assert self.foreoptic is not None, "A foreoptic component must be specified."
assert self.slit is not None, "A slit component must be specified."

signal = (
(const.pi / 4)
Expand All @@ -97,12 +100,14 @@ def get_signal_to_noise(self, radiance: LUT, wavelength):

def get_FOV(self) -> np.ndarray[float, float]:
"""Get the field of view vector.

A vector that defines the angular extent that can be imaged by the payload in
the along-track and the across-track directions.

"""

assert self.slit is not None, "A slit component must be specified."
assert self.foreoptic is not None, "A foreoptic component must be specified."

fov = 2 * np.arctan(self.slit.size / (2 * self.foreoptic.focal_length))

return fov
Expand Down
6 changes: 4 additions & 2 deletions payload_designer/systems/satellites.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ def __init__(self, altitude):

def get_attrs_table(self):
"""Get a table of satellite parameters."""

assert self.altitude is not None, "An altitude component must be specified."

orbit_radius = self.get_orbit_radius()
orbit_velocity = self.get_orbit_velocity()
orbit_angular_velocity = self.get_orbit_angular_velocity()
Expand Down Expand Up @@ -43,7 +44,8 @@ def get_attrs_table(self):

def get_orbit_radius(self):
"""Get the orbital radius."""

assert self.altitude is not None, "An altitude component must be specified."

R_orbit = const.R_earth + self.altitude

return R_orbit
Expand Down