From 10d42f5b22f593d2556e51ebc4f95b6921192f59 Mon Sep 17 00:00:00 2001 From: acpaquette <acpaquette@usgs.gov> Date: Mon, 5 Jun 2023 11:58:02 -0700 Subject: [PATCH] Mgs time bias (#538) * Updated disclaimer for release * Handle MGS time bias for NAC and WAC * Re-enabled MGS drivers * Updated changelog --- CHANGELOG.md | 4 + ale/base/base.py | 1 - ale/base/data_naif.py | 17 ++- ale/drivers/mgs_drivers.py | 28 ++++ ale/transformation.py | 13 +- tests/pytests/data/isds/mgsmocwa_isd.json | 176 ++++++++++++---------- tests/pytests/test_cassini_drivers.py | 4 +- tests/pytests/test_mgs_drivers.py | 1 - 8 files changed, 151 insertions(+), 93 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 595f0ff..745b8e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,10 @@ release. ## [Unreleased] +### 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 ### Fixed diff --git a/ale/base/base.py b/ale/base/base.py index 6fba266..7bddcea 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 dad57ad..985abae 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/mgs_drivers.py b/ale/drivers/mgs_drivers.py index 8469bf9..681acd0 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 84ef0c4..ab3ff5e 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 864eb6d..f2f07e2 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 c2627cc..79041a7 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 a62690b..5dbe682 100644 --- a/tests/pytests/test_mgs_drivers.py +++ b/tests/pytests/test_mgs_drivers.py @@ -44,7 +44,6 @@ def test_wac_load(test_wac_kernels): 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) == [] -- GitLab