Skip to content

Fixed #1151 Forward query_idx from aamp_match to core.mass_absolute#1152

Merged
seanlaw merged 1 commit into
stumpy-dev:mainfrom
cagataykenter:fix-aamp-match-query-idx
Jul 10, 2026
Merged

Fixed #1151 Forward query_idx from aamp_match to core.mass_absolute#1152
seanlaw merged 1 commit into
stumpy-dev:mainfrom
cagataykenter:fix-aamp-match-query-idx

Conversation

@cagataykenter

Copy link
Copy Markdown
Contributor

Fixes #1151.

aamp_match accepts query_idx and forwards it to core._find_matches, but never forwards it to core.mass_absolute. The normalized twin, motifs.match, forwards it to both core.mass and core._find_matches.

core._find_matches seeds candidate_idx = query_idx and then breaks when D[candidate_idx] > atol + max_distance, so it depends on D[query_idx] == 0 — which is what core.mass_absolute's query_idx parameter exists to establish.

query_idx was added to core.mass and core.mass_absolute in #860; #856 wired it into core.mass from motifs.match the next day, but aamp_motifs.py was not updated. core.mass_absolute's query_idx branches have been unreachable ever since — which is why they carry # pragma: no cover. They are now covered, so the pragmas are removed.

Changes

  • stumpy/aamp_motifs.py — forward query_idx to core.mass_absolute.
  • stumpy/core.py — drop the two # pragma: no cover markers on mass_absolute's now-reachable query_idx branches.
  • tests/test_aamp_motifs.py — add test_aamp_match_query_idx. There was previously no query_idx test in either tests/test_motifs.py or tests/test_aamp_motifs.py.

Behaviour

For a correct self-join this is a no-op: _mass_absolute uses scipy.spatial.distance.cdist, which returns exactly 0.0 for the identical row, so D[query_idx] was already the minimum and the self-match was already returned first.

What it restores is the behaviour when query_idx does not describe Q — the case mass_absolute's warning exists to catch:

match aamp_match before aamp_match after
rows returned (1, 2) (0,) (1, 2)
self-match first yes no yes
warns yes no yes

Verification

  • Correct usage: output byte-identical to main (np.array_equalTrue), single- and multi-dimensional.
  • aamp_motifs (the internal caller, which always passes query_idx=candidate_idx with the real subsequence): identical motif_distances and motif_indices across 30 seeds.
  • tests/test_aamp_motifs.py, tests/test_motifs.py, tests/test_precision.py: all pass under NUMBA_DISABLE_JIT=1.
  • The new test alone covers core.py:1375, :1376, :1410, :1411 with no partial branches, so coverage report --fail-under=100 still passes with the pragmas gone.
  • black --check, isort --profile black --check-only, flake8: clean.

…absolute

core._find_matches seeds candidate_idx = query_idx and then breaks when
D[candidate_idx] > atol + max_distance, so it relies on D[query_idx] == 0.
core.mass_absolute establishes that, but aamp_match never passed query_idx to
it, unlike motifs.match which passes it to core.mass.

query_idx was added to core.mass and core.mass_absolute in stumpy-dev#860; stumpy-dev#856 wired it
into core.mass from motifs.match the next day, but aamp_motifs.py was not
updated. core.mass_absolute's query_idx branches have been unreachable since,
which is why they carry `# pragma: no cover`. They are now covered, so the
pragmas are removed.

For a correct self-join the fix is a no-op: cdist returns exactly 0.0 for the
identical row, so D[query_idx] was already the minimum. What it restores is the
"self-match is returned first" guarantee and the "Subsequences `Q` and
`T[query_idx:query_idx+m]` are different" warning when query_idx does not
describe Q -- neither of which could happen on the non-normalized path.
@cagataykenter cagataykenter requested a review from seanlaw as a code owner July 10, 2026 08:49
@gitnotebooks

gitnotebooks Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review these changes at https://app.gitnotebooks.com/stumpy-dev/stumpy/pull/1152

@seanlaw

seanlaw commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

@cagataykenter Thank you for the thorough explanation and for discovering this issue. It is greatly appreciated! Please allow me some time to review

@seanlaw seanlaw merged commit 832b2dd into stumpy-dev:main Jul 10, 2026
31 checks passed
@seanlaw

seanlaw commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

@cagataykenter Thank you again for this excellent contribution! I am curious how you discovered this issue and what you use STUMPY for?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

aamp_match does not forward query_idx to core.mass_absolute, so the self-match is never zeroed

2 participants