diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f4566fabb486d52dafae7dc00837d865a62d1be..29acad1d6a37b4b28a050c265f05415dd73c343e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ release. ### Fixed - MexHrscIsisLabelNaifSpice and MexHrscPds3NaifSpice have had there ephemeris times changed and sampling factor updated. MexHrscIsisLabelNaifSpice has also had it's focal length, and focal plane translation updated to reflect those found in the MexHrscPds3NaifSpice driver [#541](https://github.com/DOI-USGS/ale/pull/541) +- MGS drivers now account for a time bias in the ephemeris data [#538](https://github.com/DOI-USGS/ale/pull/538) ## [0.9.0] - 2023-04-19 diff --git a/DISCLAIMER.md b/DISCLAIMER.md index 2b91b395ede81569f0d162b1873f254ea6cf545c..8515c12c73aba7a53b006a886e52b743863b8aa5 100644 --- a/DISCLAIMER.md +++ b/DISCLAIMER.md @@ -1,15 +1,9 @@ -This software is preliminary or provisional and is subject to revision. It is -being provided to meet the need for timely best science. The software has not -received final approval by the U.S. Geological Survey (USGS). No warranty, -expressed or implied, is made by the USGS or the U.S. Government as to the -functionality of the software and related material nor shall the fact of release -constitute any such warranty. The software is provided on the condition that -neither the USGS nor the U.S. Government shall be held liable for any damages -resulting from the authorized or unauthorized use of the software.This software is preliminary or provisional and is subject to revision. It is -being provided to meet the need for timely best science. The software has not -received final approval by the U.S. Geological Survey (USGS). No warranty, -expressed or implied, is made by the USGS or the U.S. Government as to the -functionality of the software and related material nor shall the fact of release -constitute any such warranty. The software is provided on the condition that -neither the USGS nor the U.S. Government shall be held liable for any damages -resulting from the authorized or unauthorized use of the software. \ No newline at end of file +This software has been approved for release by the U.S. Geological Survey +(USGS). Although the software has been subjected to rigorous review, the USGS +reserves the right to update the software as needed pursuant to further analysis +and review. No warranty, expressed or implied, is made by the USGS or the U.S. +Government as to the functionality of the software and related material nor +shall the fact of release constitute any such warranty. Furthermore, the +software is released on condition that neither the USGS nor the U.S. Government +shall be held liable for any damages resulting from its authorized or +unauthorized use. \ No newline at end of file diff --git a/ale/base/base.py b/ale/base/base.py index 6fba26669e837c768c2185f70e6ca86a36581f41..7bddcea50d50607cf5cecc31d695334085039747 100644 --- a/ale/base/base.py +++ b/ale/base/base.py @@ -359,7 +359,6 @@ class Driver(): self._projection = "" return self._projection - @property def geotransform(self): if not hasattr(self, "_geotransform"): diff --git a/ale/base/data_naif.py b/ale/base/data_naif.py index dad57ad0b27383672e8b4d6a71a261965f7338d8..985abaeadf81ea5cde0c0853369c1edf3a96134e 100644 --- a/ale/base/data_naif.py +++ b/ale/base/data_naif.py @@ -428,7 +428,8 @@ class NaifSpice(): target_frame=self.target_frame_id, center_ephemeris_time=self.center_ephemeris_time, ephemeris_times=self.ephemeris_time, - nadir=nadir, exact_ck_times=exact_ck_times) + nadir=nadir, exact_ck_times=exact_ck_times, + inst_time_bias=self.instrument_time_bias) if nadir: # Logic for nadir calculation was taken from ISIS3 @@ -589,3 +590,17 @@ class NaifSpice(): pass return self._naif_keywords + + @property + def instrument_time_bias(self): + """ + Time bias used for generating sensor orientations + + The default is 0 for not time bias + + Returns + ------- + : int + Time bias in ephemeris time + """ + return 0 \ No newline at end of file diff --git a/ale/drivers/__init__.py b/ale/drivers/__init__.py index 06343e1c6236ffdfa4174ae03243e9adf35c286d..dbb2609c2187acba56264efb50fba1e92e1499d0 100644 --- a/ale/drivers/__init__.py +++ b/ale/drivers/__init__.py @@ -27,8 +27,7 @@ __disabled_drivers__ = ["ody_drivers", "hayabusa2_drivers", "juno_drivers", "tgo_drivers", - "msi_drivers", - "mgs_drivers"] + "msi_drivers"] # dynamically load drivers __all__ = [os.path.splitext(os.path.basename(d))[0] for d in glob(os.path.join(os.path.dirname(__file__), '*_drivers.py'))] diff --git a/ale/drivers/mgs_drivers.py b/ale/drivers/mgs_drivers.py index 8469bf9f294e188d16a8d0dbe756c6557afdd051..681acd0d56d320fbd959bd9890392197df999f81 100644 --- a/ale/drivers/mgs_drivers.py +++ b/ale/drivers/mgs_drivers.py @@ -130,6 +130,20 @@ class MgsMocNarrowAngleCameraIsisLabelNaifSpiceDriver(LineScanner, IsisLabel, Na """ return [0, 0.0131240578522949, 0.0131240578522949] + @property + def instrument_time_bias(self): + """ + Defines the time bias for Mars Global Survayor instrument rotation information. + + This shifts the sensor orientation window back by 1.15 seconds in ephemeris time. + + Returns + ------- + : int + Time bias adjustment + """ + return -1.15 + class MgsMocWideAngleCameraIsisLabelNaifSpiceDriver(LineScanner, IsisLabel, NaifSpice, RadialDistortion, Driver): """ Driver for reading MGS MOC WA ISIS labels. @@ -268,3 +282,17 @@ class MgsMocWideAngleCameraIsisLabelNaifSpiceDriver(LineScanner, IsisLabel, Naif return [0, -.007, .007] else: return [0, .007, .007] + + @property + def instrument_time_bias(self): + """ + Defines the time bias for Mars Global Survayor instrument rotation information. + + This shifts the sensor orientation window back by 1.15 seconds in ephemeris time. + + Returns + ------- + : int + Time bias adjustment + """ + return -1.15 diff --git a/ale/transformation.py b/ale/transformation.py index 84ef0c415212f9a2dfc5d6f884a2b1e41b96d147..ab3ff5e6f3b8706be46f4af531e094b3a316f3ba 100644 --- a/ale/transformation.py +++ b/ale/transformation.py @@ -96,7 +96,7 @@ class FrameChain(nx.DiGraph): of frame rotations in the frame chain """ @classmethod - def from_spice(cls, sensor_frame, target_frame, center_ephemeris_time, ephemeris_times=[], nadir=False, exact_ck_times=False): + def from_spice(cls, sensor_frame, target_frame, center_ephemeris_time, ephemeris_times=[], nadir=False, exact_ck_times=False, inst_time_bias=0): frame_chain = cls() sensor_times = [] # Default assume one time @@ -106,7 +106,7 @@ class FrameChain(nx.DiGraph): if exact_ck_times and len(ephemeris_times) > 1 and not nadir: try: - sensor_times = cls.extract_exact_ck_times(ephemeris_times[0], ephemeris_times[-1], sensor_frame) + sensor_times = cls.extract_exact_ck_times(ephemeris_times[0] + inst_time_bias, ephemeris_times[-1] + inst_time_bias, sensor_frame) except Exception as e: pass @@ -123,8 +123,8 @@ class FrameChain(nx.DiGraph): constant_frames.extend(target_constant_frames) - frame_chain.compute_time_dependent_rotiations(sensor_time_dependent_frames, sensor_times) - frame_chain.compute_time_dependent_rotiations(target_time_dependent_frames, target_times) + frame_chain.compute_time_dependent_rotiations(sensor_time_dependent_frames, sensor_times, inst_time_bias) + frame_chain.compute_time_dependent_rotiations(target_time_dependent_frames, target_times, 0) for s, d in constant_frames: quats = np.zeros(4) @@ -380,7 +380,7 @@ class FrameChain(nx.DiGraph): return times - def compute_time_dependent_rotiations(self, frames, times): + def compute_time_dependent_rotiations(self, frames, times, time_bias): """ Computes the time dependent rotations based on a list of tuples that define the relationships between frames as (source, destination) and a list of times to @@ -409,5 +409,6 @@ class FrameChain(nx.DiGraph): if not avs: avs = None - rotation = TimeDependentRotation(quats, times, s, d, av=avs) + biased_times = [time - time_bias for time in times] + rotation = TimeDependentRotation(quats, biased_times, s, d, av=avs) self.add_edge(rotation=rotation) \ No newline at end of file diff --git a/tests/pytests/data/isds/mgsmocwa_isd.json b/tests/pytests/data/isds/mgsmocwa_isd.json index 864eb6d6d0b5372f5050f2ac7115c51bb46fd317..f2f07e219e5657ba836f286a4320b68bfb69c8cf 100644 --- a/tests/pytests/data/isds/mgsmocwa_isd.json +++ b/tests/pytests/data/isds/mgsmocwa_isd.json @@ -1,4 +1,4 @@ - { +{ "isis_camera_version": 1, "image_lines": 768, "image_samples": 640, @@ -70,90 +70,97 @@ -94000, 1 ], - "ck_table_start_time": -69382819.71598774, - "ck_table_end_time": -69382511.7160111, - "ck_table_original_size": 78, + "ck_table_start_time": -69382822.56598744, + "ck_table_end_time": -69382510.5660111, + "ck_table_original_size": 79, "ephemeris_times": [ - -69382819.71598774, - -69382815.71598805, - -69382811.71598835, - -69382807.71598867, - -69382803.71598896, - -69382799.71598926, - -69382795.71598957, - -69382791.71598987, - -69382787.71599017, - -69382783.71599048, - -69382779.71599078, - -69382775.7159911, - -69382771.7159914, - -69382767.71599169, - -69382763.715992, - -69382759.7159923, - -69382755.7159926, - -69382751.71599291, - -69382747.71599321, - -69382743.71599352, - -69382739.71599382, - -69382735.71599412, - -69382731.71599443, - -69382727.71599473, - -69382723.71599503, - -69382719.71599534, - -69382715.71599564, - -69382711.71599595, - -69382707.71599625, - -69382703.71599655, - -69382699.71599686, - -69382695.71599716, - -69382691.71599746, - -69382687.71599777, - -69382683.71599805, - -69382679.71599837, - -69382675.71599866, - -69382671.71599896, - -69382667.71599928, - -69382663.71599957, - -69382659.71599987, - -69382655.71600018, - -69382651.71600048, - -69382647.71600078, - -69382643.7160011, - -69382639.71600139, - -69382635.7160017, - -69382631.716002, - -69382627.7160023, - -69382623.71600261, - -69382619.71600291, - -69382615.71600321, - -69382611.71600352, - -69382607.71600382, - -69382603.71600413, - -69382599.71600443, - -69382595.71600473, - -69382591.71600504, - -69382587.71600534, - -69382583.71600564, - -69382579.71600595, - -69382575.71600625, - -69382571.71600656, - -69382567.71600686, - -69382563.71600716, - -69382559.71600747, - -69382555.71600777, - -69382551.71600807, - -69382547.71600838, - -69382543.71600868, - -69382539.71600899, - -69382535.71600929, - -69382531.71600959, - -69382527.7160099, - -69382523.7160102, - -69382519.7160105, - -69382515.71601081, - -69382511.7160111 + -69382822.56598744, + -69382818.56598774, + -69382814.56598805, + -69382810.56598835, + -69382806.56598866, + -69382802.56598896, + -69382798.56598926, + -69382794.56598957, + -69382790.56598987, + -69382786.56599016, + -69382782.56599048, + -69382778.56599078, + -69382774.56599109, + -69382770.56599139, + -69382766.56599168, + -69382762.565992, + -69382758.5659923, + -69382754.5659926, + -69382750.5659929, + -69382746.5659932, + -69382742.56599352, + -69382738.56599382, + -69382734.56599411, + -69382730.56599443, + -69382726.56599472, + -69382722.56599502, + -69382718.56599534, + -69382714.56599563, + -69382710.56599595, + -69382706.56599624, + -69382702.56599654, + -69382698.56599686, + -69382694.56599715, + -69382690.56599745, + -69382686.56599776, + -69382682.56599805, + -69382678.56599836, + -69382674.56599866, + -69382670.56599896, + -69382666.56599927, + -69382662.56599957, + -69382658.56599987, + -69382654.56600018, + -69382650.56600048, + -69382646.56600077, + -69382642.56600109, + -69382638.56600139, + -69382634.5660017, + -69382630.566002, + -69382626.5660023, + -69382622.5660026, + -69382618.5660029, + -69382614.5660032, + -69382610.56600352, + -69382606.56600381, + -69382602.56600413, + -69382598.56600443, + -69382594.56600472, + -69382590.56600504, + -69382586.56600533, + -69382582.56600563, + -69382578.56600595, + -69382574.56600624, + -69382570.56600656, + -69382566.56600685, + -69382562.56600715, + -69382558.56600747, + -69382554.56600776, + -69382550.56600806, + -69382546.56600837, + -69382542.56600867, + -69382538.56600899, + -69382534.56600928, + -69382530.56600958, + -69382526.5660099, + -69382522.56601019, + -69382518.56601049, + -69382514.5660108, + -69382510.5660111 ], "quaternions": [ + [ + -0.23708037152577427, + 0.06913949189951372, + 0.9353535261221577, + 0.2532319278209684 + ], [ -0.23957495682735272, 0.06980832265124022, @@ -624,6 +631,11 @@ ] ], "angular_velocities": [ + [ + -1.3243650720946794e-05, + -0.001147942524828248, + -0.0006765182794334033 + ], [ -1.4192050960089805e-05, -0.001149540028905371, diff --git a/tests/pytests/test_cassini_drivers.py b/tests/pytests/test_cassini_drivers.py index c2627ccab32d5a11453b194f13303c8db6dcca67..79041a7fc865c06bd73e36606b26fb965dc7a60b 100644 --- a/tests/pytests/test_cassini_drivers.py +++ b/tests/pytests/test_cassini_drivers.py @@ -140,7 +140,7 @@ class test_cassini_pds3_naif(unittest.TestCase): target_frame_id.return_value = -800 frame_chain = self.driver.frame_chain assert len(frame_chain.nodes()) == 0 - from_spice.assert_called_with(center_ephemeris_time=2.4, ephemeris_times=[2.4], nadir=False, sensor_frame=14082360, target_frame=-800, exact_ck_times=True) + from_spice.assert_called_with(center_ephemeris_time=2.4, ephemeris_times=[2.4], nadir=False, sensor_frame=14082360, target_frame=-800, exact_ck_times=True, inst_time_bias=0) # ========= Test cassini isislabel and naifspice driver ========= class test_cassini_isis_naif(unittest.TestCase): @@ -212,4 +212,4 @@ class test_cassini_isis_naif(unittest.TestCase): target_frame_id.return_value = -800 frame_chain = self.driver.frame_chain assert len(frame_chain.nodes()) == 0 - from_spice.assert_called_with(center_ephemeris_time=2.4000000000000004, ephemeris_times=[2.4000000000000004], nadir=False, sensor_frame=14082360, target_frame=-800, exact_ck_times=True) + from_spice.assert_called_with(center_ephemeris_time=2.4000000000000004, ephemeris_times=[2.4000000000000004], nadir=False, sensor_frame=14082360, target_frame=-800, exact_ck_times=True, inst_time_bias=0) diff --git a/tests/pytests/test_mgs_drivers.py b/tests/pytests/test_mgs_drivers.py index 0c5d184c66ec9328433f3cac54a1bafcfbf6a63a..5dbe6828c9f10d3a7d14608213cdf8f4e30c4666 100644 --- a/tests/pytests/test_mgs_drivers.py +++ b/tests/pytests/test_mgs_drivers.py @@ -20,7 +20,6 @@ def test_nac_kernels(): for kern in binary_kernels: os.remove(kern) -@pytest.mark.xfail def test_nac_load(test_nac_kernels): label_file = get_image_label('m0402852', 'isis') compare_dict = get_isd("mgsmocna") @@ -39,14 +38,12 @@ def test_wac_kernels(): for kern in binary_kernels: os.remove(kern) -@pytest.mark.xfail def test_wac_load(test_wac_kernels): label_file = get_image_label('ab102401', 'isis3') compare_dict = get_isd("mgsmocwa") isd_str = ale.loads(label_file, props={'kernels': test_wac_kernels}) isd_obj = json.loads(isd_str) - print(json.dumps(isd_obj, indent=2)) assert compare_dicts(isd_obj, compare_dict) == []