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

Minirf Fixes #563

Merged
merged 14 commits into from
Sep 29, 2023
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
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ release.
## [Unreleased]

### Added
- Mariner10 IsisLabelNaifSpice driver, tests, and test data [#547](https://github.com/DOI-USGS/ale/pull/547)
- Mariner10 IsisLabelNaifSpice driver, tests, and test data [#547](https://github.com/DOI-USGS/ale/pull/547)

### Fixed
- Fixed LRO MiniRF drivers naif keywords focal to pixel and pixel to focal translations to be correct. [#563](https://github.com/DOI-USGS/ale/pull/563)

## [0.9.1] - 2023-06-05

Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# Specify the required version of CMake.
# cmake 3.15 required for findPython virtualenv configuration
cmake_minimum_required(VERSION 3.15)
project(ale VERSION 0.9.0 DESCRIPTION "Abstraction Library for Ephemerides ")
project(ale VERSION 0.9.1 DESCRIPTION "Abstraction Library for Ephemerides ")

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

Expand Down
26 changes: 26 additions & 0 deletions ale/base/type_distortion.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import numpy as np
import spiceypy as spice

class LegendreDistortion():
"""
Expand Down Expand Up @@ -166,4 +167,29 @@ def usgscsm_distortion_model(self):
"x_coefficients" : transx,
"y_coefficients" : transy
}
}

class LoDistortion():
@property
def usgscsm_distortion_model(self):

# From ISIS LoHighDistortionMap::SetDistortion()
# Get the perspective correction factors for x and y and the distortion
# center (point of symmetry of distortion)
perspective_key = 'INS{}_PERSPECTIVE_FACTORS'.format(self.ikid)
center_key = 'INS{}_POINT_OF_SYMMETRY'.format(self.ikid)
perspective_x = float(spice.gdpool(perspective_key, 0, 1)[0])
perspective_y = float(spice.gdpool(perspective_key, 0, 2)[1])
center_point_x = float(spice.gdpool(center_key, 0, 1)[0])
center_point_y = float(spice.gdpool(center_key, 0, 2)[1])

# Get the distortion coefficients
# CameraDistortionMap::SetDistortion(naifIkCode);
return {
"lunarorbiter":{
"perspective_x" : perspective_x,
"perspective_y" : perspective_y,
"center_point_x" : center_point_x,
"center_point_y" : center_point_y
}
}
34 changes: 31 additions & 3 deletions ale/base/type_sensor.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import math

import numpy as np
import spiceypy as spice
from scipy.spatial.transform import Rotation

from ale.transformation import FrameChain
from ale.transformation import ConstantRotation
from ale.transformation import ConstantRotation, TimeDependentRotation

class LineScanner():
"""
Expand Down Expand Up @@ -468,7 +469,7 @@ def cahvor_rotation_matrix(self):
H_prime = (self.cahvor_camera_dict['H'] - h_c * self.cahvor_camera_dict['A'])/h_s
V_prime = (self.cahvor_camera_dict['V'] - v_c * self.cahvor_camera_dict['A'])/v_s
if self._props.get("landed", False):
self._cahvor_rotation_matrix = np.array([H_prime, -V_prime, -self.cahvor_camera_dict['A']])
self._cahvor_rotation_matrix = np.array([-H_prime, -V_prime, self.cahvor_camera_dict['A']])
else:
self._cahvor_rotation_matrix = np.array([H_prime, V_prime, self.cahvor_camera_dict['A']])
return self._cahvor_rotation_matrix
Expand All @@ -485,12 +486,39 @@ def frame_chain(self):
A networkx frame chain object
"""
if not hasattr(self, '_frame_chain'):
nadir = self._props.get("nadir", False)
self._frame_chain = FrameChain.from_spice(sensor_frame=self.final_inst_frame,
target_frame=self.target_frame_id,
center_ephemeris_time=self.center_ephemeris_time,
ephemeris_times=self.ephemeris_time,
nadir=False, exact_ck_times=False)
nadir=nadir, exact_ck_times=False)
cahvor_quats = Rotation.from_matrix(self.cahvor_rotation_matrix).as_quat()

if nadir:
# Logic for nadir calculation was taken from ISIS3
# SpiceRotation::setEphemerisTimeNadir
rotation = self._frame_chain.compute_rotation(self.target_frame_id, 1)
p_vec, v_vec, times = self.sensor_position
rotated_positions = rotation.apply_at(p_vec, times)
rotated_velocities = rotation.rotate_velocity_at(p_vec, v_vec, times)

p_vec = rotated_positions
v_vec = rotated_velocities

velocity_axis = 2
# Get the default line translation with no potential flipping
# from the driver
trans_x = np.array(self.focal2pixel_lines)

if (trans_x[0] < trans_x[1]):
velocity_axis = 1

quats = [spice.m2q(spice.twovec(-p_vec[i], 3, v_vec[i], velocity_axis)) for i, time in enumerate(times)]
quats = np.array(quats)[:,[1,2,3,0]]

rotation = TimeDependentRotation(quats, times, 1, self.final_inst_frame)
self._frame_chain.add_edge(rotation)

# If we are landed we only care about the final cahvor frame relative to the target
if self._props.get("landed", False):
cahvor_rotation = ConstantRotation(cahvor_quats, self.target_frame_id, self.sensor_frame_id)
Expand Down
49 changes: 34 additions & 15 deletions ale/drivers/clementine_drivers.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
import os
import spiceypy as spice
import json
import numpy as np
import pvl

import ale
from ale.base import Driver
from ale.base.label_isis import IsisLabel
from ale.base.data_naif import NaifSpice
from ale.base.type_distortion import RadialDistortion, NoDistortion
from ale.base.type_sensor import Framer, LineScanner
from ale.util import generate_kernels_from_cube
from ale.base.type_sensor import Framer
from ale.base.type_distortion import NoDistortion

from ale import util
from ale.base.type_sensor import Framer


class ClementineUvvisIsisLabelNaifSpiceDriver(Framer, IsisLabel, NaifSpice, NoDistortion, Driver):
class ClementineIsisLabelNaifSpiceDriver(Framer, IsisLabel, NaifSpice, NoDistortion, Driver):
"""
Driver for reading Ultra-violet Invisible Spectrum ISIS3 Labels
Driver for reading UUVIS, HIRES, NIR, and LWIR ISIS3 Labels
"""

@property
Expand All @@ -37,7 +28,10 @@ def instrument_id(self):
instrument id
"""
lookup_table = {
"UVVIS": "ULTRAVIOLET/VISIBLE CAMERA"
"UVVIS": "ULTRAVIOLET/VISIBLE CAMERA",
"NIR": "Near Infrared Camera",
"HIRES": "High Resolution Camera",
"LWIR": "Long Wave Infrared Camera"
}
return lookup_table[super().instrument_id]

Expand All @@ -51,8 +45,7 @@ def sensor_name(self):
: str
instrument name
"""
filter = self.label["IsisCube"]['BandBin']['FilterName']
return "CLEM_" + super().instrument_id + "_" + filter
return super().instrument_id

@property
def spacecraft_name(self):
Expand Down Expand Up @@ -109,3 +102,29 @@ def ikid(self):
Naif ID used to for identifying the instrument in Spice kernels
"""
return self.label["IsisCube"]["Kernels"]["NaifFrameCode"]

@property
def focal_length(self):
"""
NIR manually sets focal length based on filter.

Returns
-------
: float
focal length
"""
if (self.instrument_id == "Near Infrared Camera"):
filter = self.label["IsisCube"]['BandBin']['FilterName']

lookup_table = {
"A": 2548.2642,
"B": 2530.8958,
"C": 2512.6589,
"D": 2509.0536,
"E": 2490.7378,
"F": 2487.8694
}

return lookup_table[filter.upper()] * 0.038

return super().focal_length
Loading
Loading