Loading ale/config.yml +2 −2 Original line number Diff line number Diff line spice_root: '/data/spice/' cassini: '/usgs/cpkgs/isis3/data/cassini/kernels/mk/' # Cassini ISS spice_root: "/data/spice/" cassini: '/scratch/jlaura/spice/co-s_j_e_v-spice-6-v1.0/cosp_1000/extras/mk/' # Cassini ISS mdis: '/scratch/jlaura/spice/mess-e_v_h-spice-6-v1.0/messsp_1000/extras/mk' # Messenger mex: '/scratch/jlaura/spice/mex-e_m-spice-6-v1.0/mexsp_1000/EXTRAS/MK' # Mars Explorer mro: '/data/spice/mro-m-spice-6-v1.0/mrosp_1000/extras/mk' # Mars Reconnaissance Orbiter Loading ale/drivers/cassini_drivers.py +126 −4 Original line number Diff line number Diff line Loading @@ -12,6 +12,12 @@ from ale.base.label_pds3 import Pds3Label from ale.base.type_distortion import RadialDistortion from ale.base.type_sensor import Framer from ale.util import find_latest_metakernel from ale.rotation import ConstantRotation from ale.transformation import FrameChain from scipy.spatial.transform import Rotation class CassiniIssPds3LabelNaifSpiceDriver(Pds3Label, NaifSpice, Framer, RadialDistortion, Driver): """ Loading @@ -22,6 +28,59 @@ class CassiniIssPds3LabelNaifSpiceDriver(Pds3Label, NaifSpice, Framer, RadialDis "ISSWA" : "CASSINI_ISS_WAC" } nac_filter_to_focal_length = { ("P0","BL2"):2002.19, ("P0","CB1"):2002.30, ("P0","GRN"):2002.38, ("P0","IR1"):2002.35, ("P0","MT1"):2002.40, ("P0","UV3"):2002.71, ("P60","BL2"):2002.13, ("P60","CB1"):2002.18, ("P60","GRN"):2002.28, ("P60","IR1"):2002.36, ("P60","MT1"):2002.34, ("P60","UV3"):2002.51, ("RED","GRN"):2002.61, ("RED","IR1"):2002.48, ("UV1","CL2"):2003.03, ("UV2","CL2"):2002.91, ("UV2","UV3"):2002.90, ("RED","CL2"):2002.69, ("CL1","IR3"):2002.65, ("CL1","BL2"):2002.37, ("CL1","CB1"):2002.66, ("CL1","CB2"):2002.66, ("CL1","CB3"):2002.68, ("CL1","MT1"):2002.88, ("CL1","MT2"):2002.91, ("CL1","MT3"):2002.87, ("CL1","UV3"):2003.09, ("HAL","CL2"):2002.94, ("IR2","CL2"):2002.71, ("IR2","IR1"):2002.56, ("IR2","IR3"):2002.55, ("IR4","CL2"):2002.89, ("IR4","IR3"):2002.81, ("BL1","CL2"):2002.79, ("CL1","CL2"):2002.88, ("CL1","GRN"):2002.75, ("CL1","IR1"):2002.74, ("IRP0","CB2"):2002.48, ("IRP0","CB3"):2002.74, ("IRP0","IR1"):2002.60, ("IRP0","IR3"):2002.48, ("IRP0","MT2"):2002.72, ("IRP0","MT3"):2002.72, ("P120","BL2"):2002.11, ("P120","CB1"):002.28, ("P120","GRN"):2002.38, ("P120","IR1"):2002.39, ("P120","MT1"):2002.54, ("P120","UV3"):2002.71 } @property def metakernel(self): """ Loading @@ -33,12 +92,10 @@ class CassiniIssPds3LabelNaifSpiceDriver(Pds3Label, NaifSpice, Framer, RadialDis Path to latest metakernel file """ metakernel_dir = config.cassini year = self.utc_start_time.year mks = sorted(glob(os.path.join(metakernel_dir,'*.tm'))) if not hasattr(self, '_metakernel'): for mk in mks: if str(self.utc_start_time.year) in os.path.basename(mk): self._metakernel = mk self._metakernel = find_latest_metakernel(metakernel_dir, year) return self._metakernel @property Loading Loading @@ -175,3 +232,68 @@ class CassiniIssPds3LabelNaifSpiceDriver(Pds3Label, NaifSpice, Framer, RadialDis ISIS sensor model version """ return 1 @property def frame_chain(self): if not hasattr(self, '_frame_chain'): if self.instrument_id == 'CASSINI_ISS_NAC': self._frame_chain = FrameChain.from_spice(frame_changes = [(1, self._original_naif_sensor_frame_id), (1, self.target_frame_id)], ephemeris_time=self.ephemeris_time) rot_180 = Rotation.from_euler('z', 180, degrees=True) self._frame_chain.add_edge(self._original_naif_sensor_frame_id, self.sensor_frame_id, ConstantRotation(rot_180.as_quat(), self._original_naif_sensor_frame_id, self.sensor_frame_id)) elif self.instrument_id == "CASSINI_ISS_WAC": self._frame_chain = super(CassiniIssPds3LabelNaifSpiceDriver, self).frame_chain return self._frame_chain @property def focal_length(self): """ NAC uses multiple filter pairs, each filter combination has a different focal length. NAIF's Cassini kernels do not contain focal lengths for NAC filters and so we aquired updated NAC filter data from ISIS's IAK kernel. """ # default focal defined by IK kernel default_focal_len = super(CassiniIssPds3LabelNaifSpiceDriver, self).focal_length if self.instrument_id == "CASSINI_ISS_NAC": filters = tuple(self.label['FILTER_NAME']) return self.nac_filter_to_focal_length.get(filters, default_focal_len) elif self.instrument_id == "CASSINI_ISS_WAC": return default_focal_len @property def _original_naif_sensor_frame_id(self): """ Original sensor frame ID as defined in Cassini's IK kernel. This is the frame ID you want to default to for WAC. For NAC, this Frame ID sits between J2000 and an extra 180 rotation since NAC was mounted upside down. Returns ------- : int sensor frame code from NAIF's IK kernel """ return self.ikid @property def sensor_frame_id(self): """ Overwrite sensor frame id to return fake frame ID for NAC representing a mounting point with a 180 degree rotation. ID was taken from ISIS's IAK kernel for Cassini. This is because NAC requires an extra rotation not in NAIF's Cassini kernels. Wac does not require an extra rotation so se simply return original sensor frame id for Wac. Returns ------- : int NAIF's Wac sensor frame ID, or ALE's Nac sensor frame ID """ if self.instrument_id == "CASSINI_ISS_NAC": return 14082360 elif self.instrument_id == "CASSINI_ISS_WAC": return self._original_naif_sensor_frame_id Loading
ale/config.yml +2 −2 Original line number Diff line number Diff line spice_root: '/data/spice/' cassini: '/usgs/cpkgs/isis3/data/cassini/kernels/mk/' # Cassini ISS spice_root: "/data/spice/" cassini: '/scratch/jlaura/spice/co-s_j_e_v-spice-6-v1.0/cosp_1000/extras/mk/' # Cassini ISS mdis: '/scratch/jlaura/spice/mess-e_v_h-spice-6-v1.0/messsp_1000/extras/mk' # Messenger mex: '/scratch/jlaura/spice/mex-e_m-spice-6-v1.0/mexsp_1000/EXTRAS/MK' # Mars Explorer mro: '/data/spice/mro-m-spice-6-v1.0/mrosp_1000/extras/mk' # Mars Reconnaissance Orbiter Loading
ale/drivers/cassini_drivers.py +126 −4 Original line number Diff line number Diff line Loading @@ -12,6 +12,12 @@ from ale.base.label_pds3 import Pds3Label from ale.base.type_distortion import RadialDistortion from ale.base.type_sensor import Framer from ale.util import find_latest_metakernel from ale.rotation import ConstantRotation from ale.transformation import FrameChain from scipy.spatial.transform import Rotation class CassiniIssPds3LabelNaifSpiceDriver(Pds3Label, NaifSpice, Framer, RadialDistortion, Driver): """ Loading @@ -22,6 +28,59 @@ class CassiniIssPds3LabelNaifSpiceDriver(Pds3Label, NaifSpice, Framer, RadialDis "ISSWA" : "CASSINI_ISS_WAC" } nac_filter_to_focal_length = { ("P0","BL2"):2002.19, ("P0","CB1"):2002.30, ("P0","GRN"):2002.38, ("P0","IR1"):2002.35, ("P0","MT1"):2002.40, ("P0","UV3"):2002.71, ("P60","BL2"):2002.13, ("P60","CB1"):2002.18, ("P60","GRN"):2002.28, ("P60","IR1"):2002.36, ("P60","MT1"):2002.34, ("P60","UV3"):2002.51, ("RED","GRN"):2002.61, ("RED","IR1"):2002.48, ("UV1","CL2"):2003.03, ("UV2","CL2"):2002.91, ("UV2","UV3"):2002.90, ("RED","CL2"):2002.69, ("CL1","IR3"):2002.65, ("CL1","BL2"):2002.37, ("CL1","CB1"):2002.66, ("CL1","CB2"):2002.66, ("CL1","CB3"):2002.68, ("CL1","MT1"):2002.88, ("CL1","MT2"):2002.91, ("CL1","MT3"):2002.87, ("CL1","UV3"):2003.09, ("HAL","CL2"):2002.94, ("IR2","CL2"):2002.71, ("IR2","IR1"):2002.56, ("IR2","IR3"):2002.55, ("IR4","CL2"):2002.89, ("IR4","IR3"):2002.81, ("BL1","CL2"):2002.79, ("CL1","CL2"):2002.88, ("CL1","GRN"):2002.75, ("CL1","IR1"):2002.74, ("IRP0","CB2"):2002.48, ("IRP0","CB3"):2002.74, ("IRP0","IR1"):2002.60, ("IRP0","IR3"):2002.48, ("IRP0","MT2"):2002.72, ("IRP0","MT3"):2002.72, ("P120","BL2"):2002.11, ("P120","CB1"):002.28, ("P120","GRN"):2002.38, ("P120","IR1"):2002.39, ("P120","MT1"):2002.54, ("P120","UV3"):2002.71 } @property def metakernel(self): """ Loading @@ -33,12 +92,10 @@ class CassiniIssPds3LabelNaifSpiceDriver(Pds3Label, NaifSpice, Framer, RadialDis Path to latest metakernel file """ metakernel_dir = config.cassini year = self.utc_start_time.year mks = sorted(glob(os.path.join(metakernel_dir,'*.tm'))) if not hasattr(self, '_metakernel'): for mk in mks: if str(self.utc_start_time.year) in os.path.basename(mk): self._metakernel = mk self._metakernel = find_latest_metakernel(metakernel_dir, year) return self._metakernel @property Loading Loading @@ -175,3 +232,68 @@ class CassiniIssPds3LabelNaifSpiceDriver(Pds3Label, NaifSpice, Framer, RadialDis ISIS sensor model version """ return 1 @property def frame_chain(self): if not hasattr(self, '_frame_chain'): if self.instrument_id == 'CASSINI_ISS_NAC': self._frame_chain = FrameChain.from_spice(frame_changes = [(1, self._original_naif_sensor_frame_id), (1, self.target_frame_id)], ephemeris_time=self.ephemeris_time) rot_180 = Rotation.from_euler('z', 180, degrees=True) self._frame_chain.add_edge(self._original_naif_sensor_frame_id, self.sensor_frame_id, ConstantRotation(rot_180.as_quat(), self._original_naif_sensor_frame_id, self.sensor_frame_id)) elif self.instrument_id == "CASSINI_ISS_WAC": self._frame_chain = super(CassiniIssPds3LabelNaifSpiceDriver, self).frame_chain return self._frame_chain @property def focal_length(self): """ NAC uses multiple filter pairs, each filter combination has a different focal length. NAIF's Cassini kernels do not contain focal lengths for NAC filters and so we aquired updated NAC filter data from ISIS's IAK kernel. """ # default focal defined by IK kernel default_focal_len = super(CassiniIssPds3LabelNaifSpiceDriver, self).focal_length if self.instrument_id == "CASSINI_ISS_NAC": filters = tuple(self.label['FILTER_NAME']) return self.nac_filter_to_focal_length.get(filters, default_focal_len) elif self.instrument_id == "CASSINI_ISS_WAC": return default_focal_len @property def _original_naif_sensor_frame_id(self): """ Original sensor frame ID as defined in Cassini's IK kernel. This is the frame ID you want to default to for WAC. For NAC, this Frame ID sits between J2000 and an extra 180 rotation since NAC was mounted upside down. Returns ------- : int sensor frame code from NAIF's IK kernel """ return self.ikid @property def sensor_frame_id(self): """ Overwrite sensor frame id to return fake frame ID for NAC representing a mounting point with a 180 degree rotation. ID was taken from ISIS's IAK kernel for Cassini. This is because NAC requires an extra rotation not in NAIF's Cassini kernels. Wac does not require an extra rotation so se simply return original sensor frame id for Wac. Returns ------- : int NAIF's Wac sensor frame ID, or ALE's Nac sensor frame ID """ if self.instrument_id == "CASSINI_ISS_NAC": return 14082360 elif self.instrument_id == "CASSINI_ISS_WAC": return self._original_naif_sensor_frame_id