From 8df36738bbbe3645e85c6946f0ddc3819fd166cf Mon Sep 17 00:00:00 2001 From: Kelvin Rodriguez Date: Thu, 22 Aug 2019 14:56:42 -0700 Subject: [PATCH] kernel list support added (#250) * kernel list support added * simple spice as fixture * removed abstractmethod tags * added property tags * addressed comments * Update base.py --- ale/base/base.py | 106 ++++++++++++++++---------------- ale/base/data_naif.py | 22 +++++-- tests/pytests/conftest.py | 4 ++ tests/pytests/test_data_naif.py | 21 ++++++- 4 files changed, 92 insertions(+), 61 deletions(-) diff --git a/ale/base/base.py b/ale/base/base.py index bf8e37b..896a25a 100644 --- a/ale/base/base.py +++ b/ale/base/base.py @@ -1,8 +1,6 @@ import pvl -import abc -from abc import ABC -class Driver(ABC): +class Driver(): """ Base class for all Drivers. @@ -12,18 +10,20 @@ class Driver(ABC): Reference to file path to be used by mixins for opening. """ - def __init__(self, file, num_ephem=909, num_quats=909): + def __init__(self, file, num_ephem=909, num_quats=909, props={}): """ Parameters ---------- file : str path to file to be parsed """ + + self._props = props self._num_quaternions = num_quats self._num_ephem = num_ephem self._file = file - @abc.abstractproperty + @property def image_lines(self): """ Returns @@ -31,9 +31,9 @@ class Driver(ABC): : int Number of lines in image """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def image_samples(self): """ Returns @@ -41,9 +41,9 @@ class Driver(ABC): : int Number of samples in image """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def usgscsm_distortion_model(self): """ Returns @@ -51,7 +51,7 @@ class Driver(ABC): : dict A dict containing the information about the distortion model for the usgscsm """ - pass + raise NotImplementedError @property def detector_start_line(self): @@ -73,7 +73,7 @@ class Driver(ABC): """ return 0 - @abc.abstractproperty + @property def sample_summing(self): """ Returns @@ -81,9 +81,9 @@ class Driver(ABC): : int Sample summing """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def line_summing(self): """ Returns @@ -91,9 +91,9 @@ class Driver(ABC): : int Line summing """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def platform_name(self): """ Returns @@ -101,9 +101,9 @@ class Driver(ABC): : str Name of the platform that the sensor is on """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def sensor_name(self): """ Returns @@ -111,9 +111,9 @@ class Driver(ABC): : str Name of the sensor """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def target_body_radii(self): """ Returns @@ -121,9 +121,9 @@ class Driver(ABC): : list target body radii, first list element is semimajor axis, second is semiminor axis. """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def focal_length(self): """ Returns @@ -131,9 +131,9 @@ class Driver(ABC): : float focal length """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def detector_center_line(self): """ Returns @@ -141,9 +141,9 @@ class Driver(ABC): : int The detector line of the principle point """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def detector_center_sample(self): """ Returns @@ -151,9 +151,9 @@ class Driver(ABC): : int The detector sample of the principle point """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def sensor_position(self): """ Returns @@ -161,9 +161,9 @@ class Driver(ABC): : (positions, velocities, times) a tuple containing a list of positions, a list of velocities, and a list of times """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def frame_chain(self): """ Returns @@ -171,9 +171,9 @@ class Driver(ABC): FrameNode The root node of the frame tree. This will always be the J2000 reference frame. """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def sun_position(self): """ Returns @@ -182,7 +182,7 @@ class Driver(ABC): a tuple containing a list of sun positions, a list of sun velocities """ - @abc.abstractproperty + @property def target_name(self): """ Returns @@ -190,10 +190,10 @@ class Driver(ABC): : int NAIF ID associated with the target body """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def target_frame_id(self): """ Returns @@ -201,9 +201,9 @@ class Driver(ABC): : int NAIF ID associated with the target body """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def sensor_frame_id(self): """ Returns @@ -211,9 +211,9 @@ class Driver(ABC): : int NAIF ID associated with the sensor frame """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def isis_naif_keywords(self): """ Returns @@ -221,9 +221,9 @@ class Driver(ABC): : dict dictionary containing the keys : values needed by Isis for the NaifKeywords group """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def sensor_model_version(self): """ Returns @@ -231,9 +231,9 @@ class Driver(ABC): : int version of the sensor model """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def focal2pixel_lines(self): """ Returns @@ -242,9 +242,9 @@ class Driver(ABC): 3 element list containing affine transformation coefficient. The elements are as follows: constant, x coefficent, y coeffecient """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def focal2pixel_samples(self): """ Returns @@ -253,9 +253,9 @@ class Driver(ABC): 3 element list containing affine transformation coefficients. The elements are as follows: constant, x coefficent, y coeffecient """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def pixel2focal_x(self): """ Returns @@ -264,9 +264,9 @@ class Driver(ABC): 3 element list containing coefficience for the pixels to focal plane transformation. The elements are as follows: constant, sample, line """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def pixel2focal_y(self): """ Returns @@ -275,9 +275,9 @@ class Driver(ABC): 3 element list containing coefficience for the pixels to focal plane transformation. The elements are as follows: constant, sample, line """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def ephemeris_start_time(self): """ Returns @@ -285,9 +285,9 @@ class Driver(ABC): : double The start time of the image in ephemeris seconds past the J2000 epoch. """ - pass + raise NotImplementedError - @abc.abstractproperty + @property def ephemeris_stop_time(self): """ Returns @@ -295,7 +295,7 @@ class Driver(ABC): : double The stop time of the image in ephemeris seconds past the J2000 epoch. """ - pass + raise NotImplementedError @property def center_ephemeris_time(self): diff --git a/ale/base/data_naif.py b/ale/base/data_naif.py index 3c2136a..36af7b5 100644 --- a/ale/base/data_naif.py +++ b/ale/base/data_naif.py @@ -11,7 +11,9 @@ class NaifSpice(): Called when the context is created. This is used to get the kernels furnished. """ - if self.metakernel: + if self.kernels: + [spice.furnsh(k) for k in self.kernels] + elif self.metakernel: spice.furnsh(self.metakernel) return self @@ -21,9 +23,17 @@ class NaifSpice(): this is done, the object is out of scope and the kernels can be unloaded. """ - spice.unload(self.metakernel) + if self.kernels: + [spice.unload(k) for k in self.kernels] + else: + spice.unload(self.metakernel) @property + def kernels(self): + if not hasattr(self, '_kernels'): + self._kernels = self._props.get('kernels', None) + return self._kernels + def metakernel(self): pass @@ -299,10 +309,10 @@ class NaifSpice(): ephem = self.ephemeris_time pos = [] vel = [] - + for time in ephem: # spkezr returns a vector from the observer's location to the aberration-corrected - # location of the target. For more information, see: + # location of the target. For more information, see: # https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/FORTRAN/spicelib/spkezr.html state, _ = spice.spkezr(self.target_name, time, @@ -312,9 +322,9 @@ class NaifSpice(): pos.append(state[:3]) vel.append(state[3:]) # By default, spice works in km, and the vector returned by spkezr points the opposite - # direction to what ALE needs, so it must be multiplied by (-1) + # direction to what ALE needs, so it must be multiplied by (-1) self._position = [p * -1000 for p in pos] - self._velocity = [v * -1000 for v in vel] + self._velocity = [v * -1000 for v in vel] return self._position, self._velocity, self.ephemeris_time @property diff --git a/tests/pytests/conftest.py b/tests/pytests/conftest.py index 2ba8317..677e6fa 100644 --- a/tests/pytests/conftest.py +++ b/tests/pytests/conftest.py @@ -31,6 +31,10 @@ class SimpleSpice(): return 0.1 def cidfrm(self, *args): return (2000, "Test_Body_Frame", True) + def furnsh(self, *args): + if not hasattr(self, '_loaded_kernels'): + self._loaded_kernels = [] + self._loaded_kernels.append(args) def get_mockkernels(self, *args): return "some_metakernel" diff --git a/tests/pytests/test_data_naif.py b/tests/pytests/test_data_naif.py index 94169ee..f3d1b12 100644 --- a/tests/pytests/test_data_naif.py +++ b/tests/pytests/test_data_naif.py @@ -3,12 +3,17 @@ import pytest import numpy as np from ale.base import data_naif +from ale.base import base # 'Mock' the spice module where it is imported from conftest import SimpleSpice -simplespice = SimpleSpice() -data_naif.spice = simplespice +@pytest.fixture +def simple_spice(): + simplespice = SimpleSpice() + data_naif.spice = simplespice + base.spice = simplespice + return simplespice @pytest.fixture def test_naif_data(): @@ -19,6 +24,13 @@ def test_naif_data(): return naif_data +@pytest.fixture +def test_naif_data_with_kernels(): + kernels = ['one', 'two', 'three','four'] + FakeNaifDriver = type("FakeNaifDriver", (base.Driver, data_naif.NaifSpice), {}) + return FakeNaifDriver("", props={'kernels': kernels}) + + def test_target_id(test_naif_data): assert test_naif_data.target_id == -12345 @@ -40,3 +52,8 @@ def test_naif_keywords(test_naif_data): def test_target_frame_id(test_naif_data): assert test_naif_data.target_frame_id == 2000 + + +def test_spice_kernel_list(test_naif_data_with_kernels, simple_spice): + with test_naif_data_with_kernels as t: + assert simple_spice._loaded_kernels == [('one',), ('two',), ('three',), ('four',)] -- GitLab