Loading ale/drivers/co_drivers.py +212 −2 Original line number Diff line number Diff line Loading @@ -12,17 +12,27 @@ from ale.base.label_pds3 import Pds3Label from ale.base.label_isis import IsisLabel from ale.base.type_distortion import RadialDistortion, NoDistortion from ale.base.type_sensor import Framer from ale.base.type_sensor import LineScanner from ale.rotation import ConstantRotation from ale.transformation import FrameChain from scipy.spatial.transform import Rotation id_lookup = { vims_id_lookup = { "VIMS_VIS" : "CASSINI_VIMS_V", "VIMS_IR" : "CASSINI_VIMS_IR" } vims_name_lookup = { "VIMS" : "Visible and Infrared Mapping Spectrometer", } iss_id_lookup = { "ISSNA" : "CASSINI_ISS_NAC", "ISSWA" : "CASSINI_ISS_WAC" } name_lookup = { iss_name_lookup = { "ISSNA" : "Imaging Science Subsystem Narrow Angle Camera", "ISSWA" : "Imaging Science Subsystem Wide Angle Camera" } Loading Loading @@ -293,6 +303,206 @@ class CassiniIssIsisLabelNaifSpiceDriver(Framer, IsisLabel, NaifSpice, RadialDis def sensor_model_version(self): return 1 class CassiniVimsIsisLabelNaifSpiceDriver(LineScanner, IsisLabel, NaifSpice, NoDistortion, Driver): @property def vims_channel(self): if not hasattr(self, '_vims_channel'): self._vims_channel = self.label['IsisCube']["Instrument"]["Channel"] return self._vims_channel @property def instrument_id(self): """ Returns an instrument id for uniquely identifying the instrument, but often also used to be piped into Spice Kernels to acquire IKIDs. Therefore they the same ID the Spice expects in bods2c calls. Expects instrument_id to be defined in the IsisLabel mixin. This should be a string of the form 'CTX' Returns ------- : str instrument id """ return vims_id_lookup[super().instrument_id + "_" + self.vims_channel] @property def sensor_name(self): """ ISIS doesn't propergate this to the ingested cube label, so hard-code it. """ return vims_name_lookup[super().instrument_id] @property def spacecraft_name(self): """ Returns the spacecraft name used in various Spice calls to acquire ephemeris data. Expects the platform_name to be defined. This should be a string of the form 'Mars_Reconnaissance_Orbiter' Returns ------- : str spacecraft name """ return spacecraft_name_lookup[super().platform_name] @property def exposure_duration(self): """ The exposure duration of the image, in seconds Returns ------- : float Exposure duration in seconds """ if 'ExposureDuration' in self.label['IsisCube']['Instrument']: exposure_duration = self.label['IsisCube']['Instrument']['ExposureDuration'] for i in exposure_duration: if i.units == "VIS": exposure_duration = i exposure_duration = exposure_duration.value * 0.001 return exposure_duration else: return self.line_exposure_duration @property def focal_length(self): """ Hardcoded value taken from ISIS """ if not hasattr(self, '_focal_length'): if self.vims_channel == "VIS": self._focal_length = 143.0 else: self._focal_length = 426.0 return self._focal_length @property def detector_center_line(self): return 0 @property def detector_center_sample(self): return 0 def compute_vims_time(self, line, sample, number_of_samples, mode="VIS"): instrument_group = self.label["IsisCube"]["Instrument"] time = str(instrument_group["NativeStartTime"]) int_time, decimal_time = str(time).split(".") ephemeris_time = spice.scs2e(self.spacecraft_id, int_time) ephemeris_time += float(decimal_time) / 15959.0 ir_exp = float(instrument_group["ExposureDuration"][0]) * 1.01725 / 1000.0; vis_exp = float(instrument_group["ExposureDuration"][1]) / 1000.0 interline_delay = (float(instrument_group["InterlineDelayDuration"]) * 1.01725) / 1000.0 swath_width = instrument_group["SwathWidth"]; if mode == "VIS": ephemeris_time = (float(ephemeris_time) + (((ir_exp * swath_width) - vis_exp) / 2.0)) + ((line + 0.5) * vis_exp) elif mode == "IR": ephemeris_time = float(ephemeris_time) + (line * number_of_samples * ir_exp) + (line * interline_delay) + ((sample + 0.5) * ir_exp) return ephemeris_time @property def ephemeris_start_time(self): instrument_group = self.label["IsisCube"]["Instrument"] return self.compute_vims_time(0 - 0.5, 0 - 0.5, self.image_samples, mode=self.vims_channel) @property def ephemeris_stop_time(self): instrument_group = self.label["IsisCube"]["Instrument"] return self.compute_vims_time((self.image_lines - 1) + 0.5, (self.image_samples - 1) + 0.5, self.image_samples, mode=self.vims_channel) @property def sensor_model_version(self): """ Returns instrument model version Returns ------- : int ISIS sensor model version """ try: return super().sensor_model_version except: return 1 class CassiniVimsIsisLabelIsisSpiceDriver(LineScanner, IsisLabel, IsisSpice, NoDistortion, Driver): @property def instrument_id(self): """ Returns an instrument id for uniquely identifying the instrument, but often also used to be piped into Spice Kernels to acquire IKIDs. Therefore they the same ID the Spice expects in bods2c calls. Expects instrument_id to be defined in the IsisLabel mixin. This should be a string of the form 'CTX' Returns ------- : str instrument id """ image_type = self.label['IsisCube']["Instrument"]["Channel"] return vims_id_lookup[super().instrument_id + "_" + image_type] @property def sensor_name(self): """ ISIS doesn't propergate this to the ingested cube label, so hard-code it. """ return "Visible and Infrared Mapping Spectrometer" @property def spacecraft_name(self): """ Returns the spacecraft name used in various Spice calls to acquire ephemeris data. Expects the platform_name to be defined. This should be a string of the form 'Mars_Reconnaissance_Orbiter' Returns ------- : str spacecraft name """ return spacecraft_name_lookup[super().platform_name] @property def exposure_duration(self): """ The exposure duration of the image, in seconds Returns ------- : float Exposure duration in seconds """ if 'ExposureDuration' in self.label['IsisCube']['Instrument']: exposure_duration = self.label['IsisCube']['Instrument']['ExposureDuration'] for i in exposure_duration: if i.units == "VIS": exposure_duration = i exposure_duration = exposure_duration.value * 0.001 return exposure_duration else: return self.line_exposure_duration class CassiniIssPds3LabelNaifSpiceDriver(Framer, Pds3Label, NaifSpice, RadialDistortion, Driver): """ Cassini mixin class for defining Spice calls. Loading tests/pytests/test_util.py +11 −0 Original line number Diff line number Diff line Loading @@ -152,7 +152,11 @@ def test_find_kernels(cube_kernels, tmpdir): print(pvl.load(str(cube_file))) kernels = util.find_kernels(str(cube_file), str(tmpdir)) <<<<<<< HEAD assert kernels == {'Pointing': {'kernels': [str(tmpdir / 'MRO/fake')], 'types': ['Reconstructed']}, 'instrument': {'kernels': [str(tmpdir / 'fake/not/a/real/file')]}} ======= assert kernels == {'Pointing': {'kernels': ['/usgs/cpkgs/isis3/data/MRO/fake'], 'types': ['Reconstructed']}, 'instrument': {'kernels': ['/usgs/cpkgs/isis3/data/fake/not/a/real/file']}} >>>>>>> f552325 (Added cassini vims vis/ir drivers) def test_kernel_from_cube_list(cube_kernels): Loading Loading @@ -277,10 +281,17 @@ def test_get_prefrences_malformed_files(monkeypatch, tmpdir, filename): util.get_isis_preferences(tmpdir.join(filename)) <<<<<<< HEAD @pytest.mark.parametrize('string,expected,case_sensitive', [('$bar/baz', '/bar/baz', False), ('$bar/$foo/baz', '/bar//foo/baz', True), ('$BAR/$FOO/baz', '/bar//foo/baz', False)]) def test_expand_vars(string, expected, case_sensitive): user_vars = {'foo': '/foo', 'bar': '/bar'} result = util.expandvars(string, env_dict=user_vars, case_sensitive=case_sensitive) ======= @pytest.mark.parametrize('string,expected,case_sensative', [('$bar/baz', '/bar/baz', False), ('$bar/$foo/baz', '/bar//foo/baz', True), ('$BAR/$FOO/baz', '/bar//foo/baz', False)]) def test_expand_vars(string, expected, case_sensative): user_vars = {'foo': '/foo', 'bar': '/bar'} result = util.expandvars(string, env_dict=user_vars, case_sensative=case_sensative) >>>>>>> f552325 (Added cassini vims vis/ir drivers) assert result == expected Loading Loading
ale/drivers/co_drivers.py +212 −2 Original line number Diff line number Diff line Loading @@ -12,17 +12,27 @@ from ale.base.label_pds3 import Pds3Label from ale.base.label_isis import IsisLabel from ale.base.type_distortion import RadialDistortion, NoDistortion from ale.base.type_sensor import Framer from ale.base.type_sensor import LineScanner from ale.rotation import ConstantRotation from ale.transformation import FrameChain from scipy.spatial.transform import Rotation id_lookup = { vims_id_lookup = { "VIMS_VIS" : "CASSINI_VIMS_V", "VIMS_IR" : "CASSINI_VIMS_IR" } vims_name_lookup = { "VIMS" : "Visible and Infrared Mapping Spectrometer", } iss_id_lookup = { "ISSNA" : "CASSINI_ISS_NAC", "ISSWA" : "CASSINI_ISS_WAC" } name_lookup = { iss_name_lookup = { "ISSNA" : "Imaging Science Subsystem Narrow Angle Camera", "ISSWA" : "Imaging Science Subsystem Wide Angle Camera" } Loading Loading @@ -293,6 +303,206 @@ class CassiniIssIsisLabelNaifSpiceDriver(Framer, IsisLabel, NaifSpice, RadialDis def sensor_model_version(self): return 1 class CassiniVimsIsisLabelNaifSpiceDriver(LineScanner, IsisLabel, NaifSpice, NoDistortion, Driver): @property def vims_channel(self): if not hasattr(self, '_vims_channel'): self._vims_channel = self.label['IsisCube']["Instrument"]["Channel"] return self._vims_channel @property def instrument_id(self): """ Returns an instrument id for uniquely identifying the instrument, but often also used to be piped into Spice Kernels to acquire IKIDs. Therefore they the same ID the Spice expects in bods2c calls. Expects instrument_id to be defined in the IsisLabel mixin. This should be a string of the form 'CTX' Returns ------- : str instrument id """ return vims_id_lookup[super().instrument_id + "_" + self.vims_channel] @property def sensor_name(self): """ ISIS doesn't propergate this to the ingested cube label, so hard-code it. """ return vims_name_lookup[super().instrument_id] @property def spacecraft_name(self): """ Returns the spacecraft name used in various Spice calls to acquire ephemeris data. Expects the platform_name to be defined. This should be a string of the form 'Mars_Reconnaissance_Orbiter' Returns ------- : str spacecraft name """ return spacecraft_name_lookup[super().platform_name] @property def exposure_duration(self): """ The exposure duration of the image, in seconds Returns ------- : float Exposure duration in seconds """ if 'ExposureDuration' in self.label['IsisCube']['Instrument']: exposure_duration = self.label['IsisCube']['Instrument']['ExposureDuration'] for i in exposure_duration: if i.units == "VIS": exposure_duration = i exposure_duration = exposure_duration.value * 0.001 return exposure_duration else: return self.line_exposure_duration @property def focal_length(self): """ Hardcoded value taken from ISIS """ if not hasattr(self, '_focal_length'): if self.vims_channel == "VIS": self._focal_length = 143.0 else: self._focal_length = 426.0 return self._focal_length @property def detector_center_line(self): return 0 @property def detector_center_sample(self): return 0 def compute_vims_time(self, line, sample, number_of_samples, mode="VIS"): instrument_group = self.label["IsisCube"]["Instrument"] time = str(instrument_group["NativeStartTime"]) int_time, decimal_time = str(time).split(".") ephemeris_time = spice.scs2e(self.spacecraft_id, int_time) ephemeris_time += float(decimal_time) / 15959.0 ir_exp = float(instrument_group["ExposureDuration"][0]) * 1.01725 / 1000.0; vis_exp = float(instrument_group["ExposureDuration"][1]) / 1000.0 interline_delay = (float(instrument_group["InterlineDelayDuration"]) * 1.01725) / 1000.0 swath_width = instrument_group["SwathWidth"]; if mode == "VIS": ephemeris_time = (float(ephemeris_time) + (((ir_exp * swath_width) - vis_exp) / 2.0)) + ((line + 0.5) * vis_exp) elif mode == "IR": ephemeris_time = float(ephemeris_time) + (line * number_of_samples * ir_exp) + (line * interline_delay) + ((sample + 0.5) * ir_exp) return ephemeris_time @property def ephemeris_start_time(self): instrument_group = self.label["IsisCube"]["Instrument"] return self.compute_vims_time(0 - 0.5, 0 - 0.5, self.image_samples, mode=self.vims_channel) @property def ephemeris_stop_time(self): instrument_group = self.label["IsisCube"]["Instrument"] return self.compute_vims_time((self.image_lines - 1) + 0.5, (self.image_samples - 1) + 0.5, self.image_samples, mode=self.vims_channel) @property def sensor_model_version(self): """ Returns instrument model version Returns ------- : int ISIS sensor model version """ try: return super().sensor_model_version except: return 1 class CassiniVimsIsisLabelIsisSpiceDriver(LineScanner, IsisLabel, IsisSpice, NoDistortion, Driver): @property def instrument_id(self): """ Returns an instrument id for uniquely identifying the instrument, but often also used to be piped into Spice Kernels to acquire IKIDs. Therefore they the same ID the Spice expects in bods2c calls. Expects instrument_id to be defined in the IsisLabel mixin. This should be a string of the form 'CTX' Returns ------- : str instrument id """ image_type = self.label['IsisCube']["Instrument"]["Channel"] return vims_id_lookup[super().instrument_id + "_" + image_type] @property def sensor_name(self): """ ISIS doesn't propergate this to the ingested cube label, so hard-code it. """ return "Visible and Infrared Mapping Spectrometer" @property def spacecraft_name(self): """ Returns the spacecraft name used in various Spice calls to acquire ephemeris data. Expects the platform_name to be defined. This should be a string of the form 'Mars_Reconnaissance_Orbiter' Returns ------- : str spacecraft name """ return spacecraft_name_lookup[super().platform_name] @property def exposure_duration(self): """ The exposure duration of the image, in seconds Returns ------- : float Exposure duration in seconds """ if 'ExposureDuration' in self.label['IsisCube']['Instrument']: exposure_duration = self.label['IsisCube']['Instrument']['ExposureDuration'] for i in exposure_duration: if i.units == "VIS": exposure_duration = i exposure_duration = exposure_duration.value * 0.001 return exposure_duration else: return self.line_exposure_duration class CassiniIssPds3LabelNaifSpiceDriver(Framer, Pds3Label, NaifSpice, RadialDistortion, Driver): """ Cassini mixin class for defining Spice calls. Loading
tests/pytests/test_util.py +11 −0 Original line number Diff line number Diff line Loading @@ -152,7 +152,11 @@ def test_find_kernels(cube_kernels, tmpdir): print(pvl.load(str(cube_file))) kernels = util.find_kernels(str(cube_file), str(tmpdir)) <<<<<<< HEAD assert kernels == {'Pointing': {'kernels': [str(tmpdir / 'MRO/fake')], 'types': ['Reconstructed']}, 'instrument': {'kernels': [str(tmpdir / 'fake/not/a/real/file')]}} ======= assert kernels == {'Pointing': {'kernels': ['/usgs/cpkgs/isis3/data/MRO/fake'], 'types': ['Reconstructed']}, 'instrument': {'kernels': ['/usgs/cpkgs/isis3/data/fake/not/a/real/file']}} >>>>>>> f552325 (Added cassini vims vis/ir drivers) def test_kernel_from_cube_list(cube_kernels): Loading Loading @@ -277,10 +281,17 @@ def test_get_prefrences_malformed_files(monkeypatch, tmpdir, filename): util.get_isis_preferences(tmpdir.join(filename)) <<<<<<< HEAD @pytest.mark.parametrize('string,expected,case_sensitive', [('$bar/baz', '/bar/baz', False), ('$bar/$foo/baz', '/bar//foo/baz', True), ('$BAR/$FOO/baz', '/bar//foo/baz', False)]) def test_expand_vars(string, expected, case_sensitive): user_vars = {'foo': '/foo', 'bar': '/bar'} result = util.expandvars(string, env_dict=user_vars, case_sensitive=case_sensitive) ======= @pytest.mark.parametrize('string,expected,case_sensative', [('$bar/baz', '/bar/baz', False), ('$bar/$foo/baz', '/bar//foo/baz', True), ('$BAR/$FOO/baz', '/bar//foo/baz', False)]) def test_expand_vars(string, expected, case_sensative): user_vars = {'foo': '/foo', 'bar': '/bar'} result = util.expandvars(string, env_dict=user_vars, case_sensative=case_sensative) >>>>>>> f552325 (Added cassini vims vis/ir drivers) assert result == expected Loading