Skip to content

BUG: Report standard deviations, not variances, in tract_math - #145

Open
demianw wants to merge 1 commit into
masterfrom
fix-tract-math-std
Open

demianw wants to merge 1 commit into
masterfrom
fix-tract-math-std

Conversation

@demianw

@demianw demianw commented Nov 4, 2026

Copy link
Copy Markdown
Owner

What was wrong

tensor_operations.compute_all_measures stored the length-weighted variance of the per-tract scalar means under per tract distance weighted std <scalar> (the square root was missing). This is what scalar_per_tract_mean_std and scalar_compute_most report.

For the tract length, the value was already a standard deviation (lengths.std(), in mm), but the column was labelled length std (mm^2). I kept the value and fixed the label, so value and unit agree.

The change

  • per tract distance weighted std <scalar> = sqrt(average((m_i - mean)**2, weights=L_i)), where m_i is the length-weighted mean of the scalar along tract i and L_i its length.
  • length std (mm^2) → length std (mm) (in compute_all_measures, length_mean_std and scalar_compute_most).

This changes numeric output and a column name:

  • per tract distance weighted std <scalar> values change (now the square root of the old value). Example on 100 tracts of the test .trk file with a synthetic per-point scalar fa = |sin(x)|, tract_math a.trk scalar_per_tract_mean_std fa:
    • before: per tract distance weighted std fa = 0.0028079537354601916
    • after: per tract distance weighted std fa = 0.05299012866053631
  • length_mean_std and scalar_compute_most: the column length std (mm^2) is now called length std (mm); its value does not change. On the full test file, tract_math IIT3mean_left_hemisphere_small.trk length_mean_std gives 44.18812674562544 before and after. Scripts that read this column by name need updating.

Testing

  • New test_compute_all_measures_std: synthetic tracts of different lengths with a constant scalar per tract; checks the length std against numpy.std, and the weighted mean/std against numpy.average-based formulas; with equal tract lengths the weighted std equals numpy.std of the per-tract values. Fails on master, passes here.
  • python -m pytest -q -p no:cacheprovider tract_querier: 43 passed, 1 skipped (pre-existing unconditional skip).
  • Ran the two tract_math commands above on master and on this branch.

Merge order

Touches operations.py lines 43 and 96 and appends to tests/test_tract_math.py, like #143 and #144 (textual conflicts only). Independent otherwise.

Closes #102

🤖 Generated with Claude Code

compute_all_measures stored the length-weighted variance of the
per-tract scalar means under "per tract distance weighted std
<scalar>": take its square root.

The tract length standard deviation was already a standard deviation
in mm but was labelled "length std (mm^2)"; label it "length std (mm)".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

BUG: "std" measures in tract_math are variances

1 participant