Patch.select reads a bare numeric range in the coordinate's own units, while Spool.select reads it as canonical SI. For a coordinate already in SI these agree, which is why it has gone unnoticed. For any other unit they do not, and the same call returns opposite answers.
patch = ... # x coordinate in degrees, e.g. from Patch.enrich against an EPSG:4979 inventory
spool = dc.spool(directory_of_that_patch).update()
patch.select(x=(-117.0, -116.9)) # keeps all 300 channels
spool.select(x=(-117.0, -116.9)) # 0 rows
spool.get_contents()[["x_min", "x_max"]]
# -2.0420352248333655 -- the value in radians, for a patch whose x is -117.0
get_contents() therefore reports an envelope no patch it yields actually contains, and a geographic selection silently returns nothing.
The mechanism is _CanonicalRange.for_patch_coord (dascore/utils/misc.py), which treats a bare number as a canonical SI magnitude, together with _base_unit_info in dascore/io/index/ingest.py, which stores coordinate envelopes converted with to_base_units(). Passing an explicit quantity works correctly on both paths (x=(-117.0 * dc.get_quantity("degree"), ...)), so the machinery is sound; the default reading of a bare number is what diverges.
This is not specific to degrees. A distance coordinate in feet has the same problem: patch.select(distance=(0, 100)) means 100 feet and spool.select(distance=(0, 100)) means 100 metres. Degrees just make it easy to hit, because a geographic coordinate is never in its SI base.
It predates the inventory work, but that work is what makes it reachable by default: Patch.enrich stamps geometry axes with the CRS's units, and the default CRS is EPSG:4979, so x and y come out in degrees while z is in metres. The same query is then right on one axis of a coordinate triple and wrong on the other two.
Deciding which reading is correct is the substance here. Patch.select's — a bare number means the coordinate's own units — seems the more defensible, since it is what the patch itself shows you, but changing Spool.select changes indexed-query semantics for every non-SI coordinate and deserves its own change rather than riding along with something else.
Patch.selectreads a bare numeric range in the coordinate's own units, whileSpool.selectreads it as canonical SI. For a coordinate already in SI these agree, which is why it has gone unnoticed. For any other unit they do not, and the same call returns opposite answers.get_contents()therefore reports an envelope no patch it yields actually contains, and a geographic selection silently returns nothing.The mechanism is
_CanonicalRange.for_patch_coord(dascore/utils/misc.py), which treats a bare number as a canonical SI magnitude, together with_base_unit_infoindascore/io/index/ingest.py, which stores coordinate envelopes converted withto_base_units(). Passing an explicit quantity works correctly on both paths (x=(-117.0 * dc.get_quantity("degree"), ...)), so the machinery is sound; the default reading of a bare number is what diverges.This is not specific to degrees. A distance coordinate in feet has the same problem:
patch.select(distance=(0, 100))means 100 feet andspool.select(distance=(0, 100))means 100 metres. Degrees just make it easy to hit, because a geographic coordinate is never in its SI base.It predates the inventory work, but that work is what makes it reachable by default:
Patch.enrichstamps geometry axes with the CRS's units, and the default CRS is EPSG:4979, soxandycome out in degrees whilezis in metres. The same query is then right on one axis of a coordinate triple and wrong on the other two.Deciding which reading is correct is the substance here.
Patch.select's — a bare number means the coordinate's own units — seems the more defensible, since it is what the patch itself shows you, but changingSpool.selectchanges indexed-query semantics for every non-SI coordinate and deserves its own change rather than riding along with something else.