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

Added and updated docstrings #610

Merged
merged 7 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
166 changes: 123 additions & 43 deletions ale/base/base.py

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions ale/base/data_isis.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,14 @@ def odtk(self):

@property
def sensor_frame_id(self):
"""Returns the Naif ID code for the sensor reference frame.

Returns
-------
: int
NAIF ID associated with the sensor frame

"""
if 'ConstantFrames' in self.inst_pointing_table:
return self.inst_pointing_table['ConstantFrames'][0]
else:
Expand All @@ -610,6 +618,13 @@ def sensor_frame_id(self):

@property
def target_frame_id(self):
"""The NAIF ID associated with the target body.

Returns
-------
: int
NAIF ID associated with the target body
"""
if 'ConstantFrames' in self.body_orientation_table:
return self.body_orientation_table['ConstantFrames'][0]
else:
Expand Down
8 changes: 8 additions & 0 deletions ale/base/data_naif.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,14 @@ def sensor_position(self):

@property
def frame_chain(self):
"""Return the root node of the rotation frame tree/chain.

Returns
-------
FrameNode
The root node of the frame tree. This will always be the J2000 reference frame.
"""

if not hasattr(self, '_frame_chain'):
nadir = self._props.get('nadir', False)
exact_ck_times = self._props.get('exact_ck_times', True)
Expand Down
15 changes: 13 additions & 2 deletions ale/base/label_isis.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ class IsisLabel():

@property
def label(self):
""" Return the cube label.

Returns
-------
pvl.PVLModule
The cube label as a PVLModule object.

Raises
------
ValueError
Raised when an invalid label is provided.
"""
if not hasattr(self, "_label"):
if isinstance(self._file, pvl.PVLModule):
self._label = self._file
Expand Down Expand Up @@ -124,8 +136,7 @@ def sampling_factor(self):

@property
def sample_summing(self):
"""
Returns the number of detector samples summed to produce each image sample
""" Returns the number of detector samples summed to produce each image sample

Returns
-------
Expand Down
12 changes: 12 additions & 0 deletions ale/base/label_pds3.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ class Pds3Label():

@property
def label(self):
""" Return the PDS3 label.

Returns
-------
pvl.PVLModule
The cube label as a PVLModule object.

Raises
------
ValueError
Raised when an invalid label is provided.
"""
if not hasattr(self, "_label"):
if isinstance(self._file, pvl.PVLModule):
self._label = self._file
Expand Down
23 changes: 23 additions & 0 deletions ale/base/type_distortion.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,15 @@ def usgscsm_distortion_model(self):
class ChandrayaanMrffrDistortion():
@property
def usgscsm_distortion_model(self):
"""
Returns the specification for ChandrayaanMrffr distortion in usgscsm.
AustinSanders marked this conversation as resolved.
Show resolved Hide resolved

Returns
-------
: dict
Dictionary containing the usgscsm specification for ChandrayaanMrffr distortion.
"""

transx = [-1* self.scaled_pixel_height, self.scaled_pixel_height, 0.0]
transy = [0,0,0]
transs = [1.0, 1.0 / self.scaled_pixel_height, 0.0]
Expand All @@ -172,7 +181,14 @@ def usgscsm_distortion_model(self):
class LoDistortion():
@property
def usgscsm_distortion_model(self):
"""
Returns the specification for Lo distortion in usgscsm.

Returns
-------
: dict
Dictionary containing the usgscsm specification for Lo distortion.
"""
# From ISIS LoHighDistortionMap::SetDistortion()
# Get the perspective correction factors for x and y and the distortion
# center (point of symmetry of distortion)
Expand All @@ -197,7 +213,14 @@ def usgscsm_distortion_model(self):
class ThemisIrDistortion():
@property
def usgscsm_distortion_model(self):
"""
Returns the specification for ThemisIR distortion in usgscsm.

Returns
-------
: dict
Dictionary containing the usgscsm specification for ThemisIR distortion.
"""
return {
"themisir":{
"p_alpha1" : 0.00447623,
Expand Down
29 changes: 29 additions & 0 deletions ale/base/type_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,21 +120,50 @@ def ephemeris_time(self):

@property
def framelet_height(self):
""" Return the number of lines in a framelet.

Returns
-------
int
The number of lines in each framelet.
"""
return 1


@property
def framelet_order_reversed(self):
""" Return a boolean indicating if the framelets are reversed.

Returns
-------
Bool
A boolean indicating if the framelets are reversed.
"""
return False


@property
def framelets_flipped(self):
""" Return a boolean indicating if the framelets are flipped.

Returns
-------
Bool
A boolean indicating if the framelets are flipped.
"""

return False


@property
def num_frames(self):
""" Return the number of frames in the image.

Returns
-------
int
The number of frames in the image.
"""
return int(self.image_lines // self.framelet_height)

@property
Expand Down
131 changes: 126 additions & 5 deletions ale/driver_verification.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,19 @@ class ReadIsis(IsisSpice, IsisLabel, Driver):
def sensor_model_version(self):
return 0

# Define the function to run spiceinit with ISIS
def run_spiceinit_isis(image_path):
""" Run spiceinit on an image using ISIS.

Parameters
----------
image_path : str
String path to the image on which spiceinit will be run

Returns
-------
None

"""
if ale_root is None:
raise EnvironmentError("The environment variable 'ALEROOT' is not set.")
# Move ALE drivers to a temporary subfolder
Expand All @@ -45,12 +56,39 @@ def run_spiceinit_isis(image_path):
shutil.move(str(driver), str(ale_drivers_path))
temp_folder.rmdir()

# Define the function to run spiceinit with ALE
def run_spiceinit_ale(image_path):
""" Run spiceinit on an image using ALE drivers.

Parameters
----------
image_path : str
String path to the image on which spiceinit will be run

Returns
-------
None

"""
# Run spiceinit with ALE
subprocess.run(['spiceinit', f'from={image_path}'])


def generate_body_rotation(driver, target_frame_id):
""" Generate body rotation information from a driver.

Parameters
----------
driver : :class:`ale.base.Driver`
The driver from which body rotation information will be generated.
target_frame_id :
The NAIF ID associated with the target body for which rotation information will be generated.

Returns
-------
dict
A dictionary containing body rotation information for the target body.

"""
frame_chain = driver.frame_chain
target_frame = target_frame_id

Expand Down Expand Up @@ -81,6 +119,20 @@ def generate_body_rotation(driver, target_frame_id):
return body_rotation

def generate_instrument_rotation(driver, sensor_frame_id):
""" Generate instrument rotation information from a driver.

Parameters
----------
driver : :class:`ale.base.Driver`
The driver from which to generate instrument rotation information.
sensor_frame_id : dict
The NAIF ID of the sensor frame for which to generate rotation information.

Returns
-------
dict
A dictionary containing instrument rotation information.
"""
# sensor orientation
frame_chain = driver.frame_chain
sensor_frame = sensor_frame_id
Expand Down Expand Up @@ -112,6 +164,18 @@ def generate_instrument_rotation(driver, sensor_frame_id):
return instrument_pointing

def generate_instrument_position(driver):
""" Generate instrument position information from a driver.

Parameters
----------
driver : :class:`ale.base.Driver`
The driver from which to generate instrument position information.

Returns
-------
dict
A dictionary containing instrument position information.
"""
instrument_position = {}
positions, velocities, times = driver.sensor_position
instrument_position['spk_table_start_time'] = times[0]
Expand All @@ -126,6 +190,18 @@ def generate_instrument_position(driver):
return instrument_position

def generate_sun_position(driver):
""" Generate sun position information from a driver.

Parameters
----------
driver : :class:`ale.base.Driver`
The driver from which to generate sun position information.

Returns
-------
dict
A dictionary containing sun position information.
"""
sun_position = {}
positions, velocities, times = driver.sun_position
sun_position['spk_table_start_time'] = times[0]
Expand All @@ -141,6 +217,22 @@ def generate_sun_position(driver):
return sun_position

def create_json_dump(driver, sensor_frame_id, target_frame_id):
""" Convenience function for generating and merging instrument rotation, body rotation, instrument position, and sun position.

Parameters
----------
driver : :class:`ale.base.Driver`
The driver from which to generate rotation and position information.
sensor_frame_id : dict
The NAIF ID of the sensor frame for which to generate rotation information.
target_frame_id : dict
The NAIF ID associated with the target body for which rotation information will be generated.

Returns
-------
dict
A dictionary containing instrument_rotation, body_rotation, instrument_position, and sun_position.
"""
json_dump = {}
json_dump["instrument_rotation"] = generate_instrument_rotation(driver, sensor_frame_id)
json_dump["body_rotation"] = generate_body_rotation(driver, target_frame_id)
Expand All @@ -149,14 +241,38 @@ def create_json_dump(driver, sensor_frame_id, target_frame_id):
return json_dump

def diff_and_describe(json1, json2, key_array):
""" Compare two dictionaries and output differences.

Parameters
----------
json1 : dict
The first dictionary for comparison.
json2 : dict
The second dictionary for comparison.
key_array : str
The key to be compared.
"""
for key in key_array:
json1 = json1[key]
json2 = json2[key]
diff = json1 - json2
print(" ".join(key_array) + "\nNum records:", len(diff), "\nMean:", np.mean(diff, axis=(0)), "\nMedian:", np.median(diff, axis=(0)), "\n")

# Define the function to compare ISDs
def compare_isds(json1, json2):
""" Compare two isds using :func:`driver_verification.diff_and_describe`

Parameters
----------
json1 : dict
A dictionary containing a json-formatted ISD for comparison
json2 : dict
A dictionary containing a json-formatted ISD for comparison

Returns
-------
None

"""
diff_and_describe(json1, json2, ["instrument_position", "positions"])
diff_and_describe(json1, json2, ["instrument_position", "velocities"])
diff_and_describe(json1, json2, ["sun_position", "positions"])
Expand All @@ -166,9 +282,14 @@ def compare_isds(json1, json2):
diff_and_describe(json1, json2, ["body_rotation", "quaternions"])
diff_and_describe(json1, json2, ["body_rotation", "angular_velocities"])

# Define the main function
def main(image):

""" Generate and compare an ALE ISD and an ISIS ISD.

Parameters
----------
image : str
The name of the file for which to generate and compare ISDs.
"""
# Duplicate the image for ALE and ISIS processing
image_ale_path = Path(f"{image}_ALE.cub")
image_isis_path = Path(f"{image}_ISIS.cub")
Expand Down
Loading
Loading