From ad97ca712d4fb4daba9324b3d2dd3fa307ad621a Mon Sep 17 00:00:00 2001 From: acpaquette <acp263@nau.edu> Date: Wed, 8 Mar 2023 19:04:51 -0700 Subject: [PATCH] Added initial ability to access SpiceQL service --- ale/base/__init__.py | 75 +++++++++++++++++++++++++++++ ale/base/data_naif.py | 89 +++++++++++++++++++++++++++++++++-- ale/drivers/viking_drivers.py | 6 ++- 3 files changed, 165 insertions(+), 5 deletions(-) diff --git a/ale/base/__init__.py b/ale/base/__init__.py index 0312f47..1f1fbd3 100644 --- a/ale/base/__init__.py +++ b/ale/base/__init__.py @@ -1 +1,76 @@ from ale.base.base import Driver + +spiceql_mission_map = { + "CHANDRAYAAN-1_M3": "", + "CASSINI_ISS_NAC": "cassini", + "CASSINI_ISS_WAC": "cassini", + "DAWN_FC2_FILTER_1": "", + "DAWN_FC2_FILTER_2": "", + "DAWN_FC2_FILTER_3": "", + "DAWN_FC2_FILTER_4": "", + "DAWN_FC2_FILTER_5": "", + "DAWN_FC2_FILTER_6": "", + "DAWN_FC2_FILTER_7": "", + "DAWN_FC2_FILTER_8": "", + "GLL_SSI_PLATFORM": "galileo", + "HAYABUSA2_ONC-W2": "", + "JUNO_JUNOCAM": "juno", + "LRO_LROCNACL": "lroc", + "LRO_LROCNACR": "lroc", + "LRO_LROCWAC_UV": "lroc", + "LRO_LROCWAC_VIS": "lroc", + "LRO_MINIRF": "", + "MSGR_MDIS_WAC": "mdis", + "MSGR_MDIS_NAC": "mdis", + "MEX_HRSC_SRC": "src", + "MEX_HRSC_IR": "hrsc", + "MGS_MOC_NA": "mgs", + "MGS_MOC_WA_RED": "mgs", + "MGS_MOC_WA_BLUE": "mgs", + "MRO_MARCI_VIS": "marci", + "MRO_MARCI_UV": "marci", + "MRO_CTX": "ctx", + "MRO_HIRISE": "hirise", + "MRO_CRISM_VNIR": "crism", + "NEAR EARTH ASTEROID RENDEZVOUS": "", + "MSL_MASTCAM_RIGHT": "", + "MSL_MASTCAM_LEFT": "", + "NH_LORRI": "", + "NH_RALPH_LEISA": "", + "NH_MVIC": "", + "ISIS_NH_RALPH_MVIC_METHANE": "", + "THEMIS_IR": "odyssey", + "THEMIS_VIS": "odyssey", + "ORX_OCAMS_MAPCAM": "", + "ORX_OCAMS_POLYCAM": "", + "ORX_OCAMS_SAMCAM": "", + "LISM_MI-VIS1": "kaguya", + "LISM_MI-VIS2": "kaguya", + "LISM_MI-VIS3": "kaguya", + "LISM_MI-VIS4": "kaguya", + "LISM_MI-VIS5": "kaguya", + "LISM_MI-NIR1": "kaguya", + "LISM_MI-NIR2": "kaguya", + "LISM_MI-NIR3": "kaguya", + "LISM_MI-NIR4": "kaguya", + "LISM_TC1_WDF": "kaguya", + "LISM_TC1_WTF": "kaguya", + "LISM_TC1_SDF": "kaguya", + "LISM_TC1_STF": "kaguya", + "LISM_TC1_WDN": "kaguya", + "LISM_TC1_WTN": "kaguya", + "LISM_TC1_SDN": "kaguya", + "LISM_TC1_STN": "kaguya", + "LISM_TC1_WDH": "kaguya", + "LISM_TC1_WTH": "kaguya", + "LISM_TC1_SDH": "kaguya", + "LISM_TC1_STH": "kaguya", + "LISM_TC1_SSH": "kaguya", + "TGO_CASSIS": "cassis", + "VIKING ORBITER 1": "viking1", + "VIKING ORBITER 2": "viking2", + "VG1_ISSNA": "", + "VG1_ISSWA": "", + "VG2_ISSNA": "", + "VG2_ISSWA": "" +} \ No newline at end of file diff --git a/ale/base/data_naif.py b/ale/base/data_naif.py index 0978680..51d96d4 100644 --- a/ale/base/data_naif.py +++ b/ale/base/data_naif.py @@ -1,10 +1,14 @@ -import spiceypy as spice -from pyspiceql import pyspiceql +import json +import requests +import warnings + import numpy as np +import pyspiceql import scipy.constants +import spiceypy as spice import ale -from ale.base.type_sensor import Framer +from ale.base import spiceql_mission_map from ale.transformation import FrameChain from ale.rotation import TimeDependentRotation from ale import util @@ -76,6 +80,29 @@ class NaifSpice(): return self._kernels + @property + def use_web(self): + """ + Reads the web property in the props dictionary to define the use_web value. + This property dictates if you are running in a web enabled driver + + Returns + ------- + : bool + Boolean defining if you are running web enabled(True) or Disabled(False) + """ + if not hasattr(self, '_use_web'): + self._use_web = False + + if "web" in self._props.keys(): + web_prop = self._props["web"] + if not isinstance(web_prop, bool): + warnings.warn(f"Web value {web_prop} not a boolean type, setting web to False") + web_prop = False + self._use_web = web_prop + + return self._use_web + @property def light_time_correction(self): """ @@ -643,3 +670,59 @@ class NaifSpice(): pass return self._naif_keywords + + @property + def spiceql_mission(self): + """ + Access the mapping between a SpiceQL "mission" and the driver. + The mapping can be found under ale.base.__init__.py + + See Also + -------- + ale.base.__init__.py + """ + return spiceql_mission_map[self.instrument_id] + + def spiceql_call(self, function_name = "", function_args = {}): + """ + Interface to SpiceQL (Spice Query Library) for both Offline and Online use + + This function will access the value passed through props defined as `web`. This + value determines the access pattern for spice data. When set to Online, you will + access the SpiceQL service provided through the USGS Astro AWS platform. This service + performs kernel and data aquisition. If set to Offline, you will access locally loaded + kernels, and SpiceQL will do no searching for you. + + Parameters + ---------- + functions_name : str + String defineing the function to call, properly exposed SpiceQL + functions should map 1-to-1 with endpoints on the service + + function_args : dict + Dictionary of arguments used by the function + + Returns : any + Any return from a SpiceQL function + """ + if not self.use_web: + func = getattr(pyspiceql, function_name) + + # Ensure that in offline mode we anticipate the user loading/passing their own kernels + # to ALE + function_args["searchKernels"] = self.use_web + return func(**function_args) + + try: + url = "http://localhost:9000/2015-03-31/functions/function/invocations" + headers = { + 'Content-Type': 'application/x-www-form-urlencoded', + } + function_args["func"] = function_name + r = requests.get(url, data=json.dumps(function_args), headers=headers, verify=False) + r.raise_for_status() + if r.json()["statusCode"] != 200: + raise requests.HTTPError(f"Recieved code {r.json()['statusCode']} from spice server, with error: {r.json()}") + return r.json()["body"]["return"] + except requests.exceptions.HTTPError as err: + raise err diff --git a/ale/drivers/viking_drivers.py b/ale/drivers/viking_drivers.py index 5577fe1..22464b5 100644 --- a/ale/drivers/viking_drivers.py +++ b/ale/drivers/viking_drivers.py @@ -1,4 +1,4 @@ -import ale +from ale.base import spiceql_mission_map from ale.base.data_naif import NaifSpice from ale.base.data_isis import IsisSpice from ale.base.label_isis import IsisLabel @@ -151,7 +151,9 @@ class VikingIsisLabelNaifSpiceDriver(Framer, IsisLabel, NaifSpice, NoDistortion, def detector_center_sample(self): return 0 - + @property + def spiceql_mission(self): + return spiceql_mission_map[self.spacecraft_name] class VikingIsisLabelIsisSpiceDriver(Framer, IsisLabel, IsisSpice, NoDistortion, Driver): -- GitLab