DOI-USGS / DOI-USGS/SpiceQL

Kernel-quality fallback in search_for_kernelset stops before checking time-window coverage

Open
#154 1 comment 0 reactions 1 assignee Claimed by @Kelvinrr View on GitHub
Dominant language
C++
Stars
4
Forks
10
Avg merge
1d 12h
Merged PRs (30d)
2

Description

## Summary

`InventoryImpl::search_for_kernelset` (`SpiceQL/src/inventoryimpl.cpp`) does not correctly fall back from a higher-priority kernel quality (e.g. `smithed`) to a lower one (e.g. `reconstructed`) when the higher-priority quality exists for the mission/instrument in general but has no kernel covering the requested time window. The query fails outright with `SPICE(NOFRAMECONNECT)`/`SPICE(SPKINSUFFDATA)` instead of falling through to the next quality in the list, even though a covering kernel of that lower quality does exist.

## Root cause

In the CK/SPK branch of `search_for_kernelset` (around inventoryimpl.cpp:451-461), qualities are iterated in descending order and the loop condition is `!found`:

```cpp
for(auto quality = qualities.begin(); quality != qualities.end() && !found; ++quality) {
string key = spiceql_name+"/"+...+"/"+Kernel::translateQuality(*quality)+"/";
if (m_timedep_kerns.contains(key)) {
time_indices = m_timedep_kerns[key];
found = true; // <-- set here, before any time-window check
}
...
if (final_time_kernels.size()) {
found = true; // <-- the real success condition, checked later
}
}
```

`found` is set to `true` as soon as the database contains *any* entry for `mission/type/quality` — i.e. as soon as a smithed kernel exists for that instrument at all — not once a kernel is confirmed to cover `[start_time, stop_time]`. If the subsequent time-window search (further down in the same iteration) then finds zero kernels covering the requested interval for that quality, `found` is already `true`, so the loop exits without ever trying the next-lower quality in `qualities`.

## Reproduction (live server)

LRO WAC VIS filter 3 (frame `-85633`) orientation query for 2012-03-15, default `ckQualities` (smithed preferred over reconstructed):

```bash
curl -s -A "repro/0.1" 'https://astrogeology.usgs.gov/apis/spiceql/latest/getTargetOrientations?ets=%5B385041666.1855644%5D&toFrame=-85633&refFrame=10020&mission=lroc&searchKernels=true&limitCk=-1'
```

Response:

```json
{"statusCode":500,"body":{"error":"std::exception: Error Occured:SPICE(NOFRAMECONNECT) At epoch 3.8504166618556E+08 TDB (2012 MAR 15 00:01:06.185 TDB), there is insufficient information available to transform from reference frame 10020 (IAU_MOON) to reference frame -85633 (LRO_LROCWAC_VIS_FILTER_3). ..."}}
```

The identical query restricted to `reconstructed` only succeeds immediately and returns real, correct kernels:

```bash
curl -s -A "repro/0.1" 'https://astrogeology.usgs.gov/apis/spiceql/latest/getTargetOrientations?ets=%5B385041666.1855644%5D&toFrame=-85633&refFrame=10020&mission=lroc&searchKernels=true&limitCk=-1&ckQualities=%5B%22reconstructed%22%5D'
```

Response:

```json
{"statusCode":200,"body":{"return":[[0.38132597705344673,-0.5480359141741926,-0.6618101635092584,0.340961058590772,-0.0008394982190406667,-0.0001492702824311263,3.181341336238551e-05]],"kernels":{"ck":["lro/kernels/ck/moc42r_2012060_2012091_v01.bc","lro/kernels/ck/moc42r_2012060_2012092_v09.bc","lro/kernels/ck/lrolc_2012060_2012092_v06.bc"],...,"lroc_ck_quality":"reconstructed",...}}}
```

So `moc42r_2012060_2012092_v09.bc` / `lrolc_2012060_2012092_v06.bc` genuinely cover this date and are exactly what real ISIS `spiceinit web=true` also resolves to for this same date/frame — this isn't a real archive gap, it's the default-quality search failing to fall through to a quality that does have coverage.

## Expected behaviour

When the default (or any explicit) multi-quality `ckQualities`/`spkQualities` list is given, the search should fall through to the next quality in the list whenever the current quality's kernels don't actually cover the requested time window — not merely whenever the current quality has zero kernels registered for the mission/instrument at all.

## Workaround

Client-side: try the default quality list first, and only retry with `["reconstructed"]` explicitly if the first call raises an error. This avoids permanently discarding `smithed` accuracy for dates that are actually covered by it, while still working around this bug for dates that aren't.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.