Skip to content

Spool.select reads a bare range as SI while Patch.select reads it in the coordinate's units #863

Description

@d-chambers

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions