Kernel-quality fallback in search_for_kernelset stops before checking time-window coverage
- 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
Assessment
This issue has not been assessed yet.