diff --git a/CMakeLists.txt b/CMakeLists.txt index b57d5a16..52cefb08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,8 +87,10 @@ if(SPICEQL_BUILD_LIB) ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/apollo17.json ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/base.json ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/cassini.json + ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/chandrayaan1.json ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/clem1.json ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/galileo.json + ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/hayabusa.json ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/hayabusa2.json ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/juno.json ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/kaguya.json @@ -98,6 +100,7 @@ if(SPICEQL_BUILD_LIB) ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/mer2.json ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/mess.json ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/mex.json + ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/newhorizons.json ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/mgs.json ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/mro.json ${CMAKE_CURRENT_SOURCE_DIR}/SpiceQL/db/msl.json diff --git a/SpiceQL/src/query.cpp b/SpiceQL/src/query.cpp index 2f63af41..4a0a59dd 100644 --- a/SpiceQL/src/query.cpp +++ b/SpiceQL/src/query.cpp @@ -411,7 +411,7 @@ namespace SpiceQL { refinedMissionKernels = searchEphemerisKernels(refinedMissionKernels, times, true, cachedTimes); if (refinedMissionKernels.contains("ck")) { - for (int i = (int) ckQualityEnum; (int) ckQualityEnum != 0; i--) { + for (int i = (int) ckQualityEnum; (int) i > 0; i--) { string ckQual = Kernel::translateQuality(Kernel::Quality(i)); if (refinedMissionKernels["ck"].contains(ckQual)) { if (size(refinedMissionKernels["ck"][ckQual]["kernels"]) != 0) { @@ -423,7 +423,7 @@ namespace SpiceQL { } if (refinedMissionKernels.contains("spk")) { - for (int i = (int) spkQualityEnum; (int) spkQualityEnum != 0; i--) { + for (int i = (int) spkQualityEnum; (int) i > 0; i--) { string spkQual = Kernel::translateQuality(Kernel::Quality(i)); if (refinedMissionKernels["spk"].contains(spkQual)) { if (size(refinedMissionKernels["spk"][spkQual]["kernels"]) != 0) { diff --git a/fastapi/app/main.py b/fastapi/app/main.py index 664782fd..0a66c409 100644 --- a/fastapi/app/main.py +++ b/fastapi/app/main.py @@ -28,6 +28,19 @@ class ResponseModel(BaseModel): statusCode: int body: ResultModel | ErrorModel +class TargetStatesRequestModel(BaseModel): + target: str + observer: str + frame: str + abcorr: str + mission: str + ets: Annotated[list[float], Query()] | float | str | None = None + startEts: float | None = None + exposureDuration: float | None = None + numOfExposures: int | None = None + ckQuality: str = "predicted" + spkQuality: str = "predicted" + # Create FastAPI instance app = FastAPI() @@ -56,7 +69,7 @@ async def getTargetStates( frame: str, abcorr: str, mission: str, - ets: Annotated[list[float], Query()] | str | None = None, + ets: Annotated[list[float], Query()] | float | str | None = None, startEts: float | None = None, exposureDuration: float | None = None, numOfExposures: int | None = None, @@ -66,10 +79,17 @@ async def getTargetStates( if ets is not None: if isinstance(ets, str): ets = literal_eval(ets) + else: + # getTargetStates requires an iterable ets. If not iterable, make it a list. + try: + iter(ets) + except TypeError: + ets = [ets] else: if all(v is not None for v in [startEts, exposureDuration, numOfExposures]): stopEts = (exposureDuration * numOfExposures) + startEts etsNpArray = np.arange(startEts, stopEts, exposureDuration) + # If ets is a single value, np.arange yields an empty array ets = list(etsNpArray) else: raise Exception("Verify that a startEts, exposureDuration, and numOfExposures are being passed correctly.") @@ -80,6 +100,44 @@ async def getTargetStates( body = ErrorModel(error=str(e)) return ResponseModel(statusCode=500, body=body) +@app.post("/getTargetStates/") +async def getTargetStates(params: TargetStatesRequestModel): + target = params.target + observer = params.observer + frame = params.frame + abcorr = params.abcorr + mission = params.mission + ets = params.ets + startEts = params.startEts + exposureDuration = params.exposureDuration + numOfExposures = params.numOfExposures + ckQuality = params.ckQuality + spkQuality = params.spkQuality + try: + if ets is not None: + if isinstance(ets, str): + ets = literal_eval(ets) + else: + # getTargetStates requires an iterable ets. If not iterable, make it a list. + try: + iter(ets) + except TypeError: + ets = [ets] + else: + if all(v is not None for v in [startEts, exposureDuration, numOfExposures]): + stopEts = (exposureDuration * numOfExposures) + startEts + etsNpArray = np.arange(startEts, stopEts, exposureDuration) + # If ets is a single value, np.arange yields an empty array + ets = list(etsNpArray) + else: + raise Exception("Verify that a startEts, exposureDuration, and numOfExposures are being passed correctly.") + result = pyspiceql.getTargetStates(ets, target, observer, frame, abcorr, mission, ckQuality, spkQuality, SEARCH_KERNELS_BOOL) + body = ResultModel(result=result) + return ResponseModel(statusCode=200, body=body) + except Exception as e: + body = ErrorModel(error=str(e)) + return ResponseModel(statusCode=500, body=body) + @app.get("/getTargetOrientations") async def getTargetOrientations( toFrame: int,