Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions tract_querier/tests/test_tract_math.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,47 @@ def test_tract_math_count(script_runner):
ret = script_runner.run(["tract_math", tract_file, "count"])
assert re.search('[^0-9]6783[^0-9]', ret.stdout) is not None
assert ret.success


def test_compute_all_measures_std():
import numpy
from tract_querier.tractography import Tractography
from tract_querier.tract_math.tensor_operations import compute_all_measures

lengths = numpy.array([10., 20., 40., 70.])
values = numpy.array([.2, .4, .5, .9])
tracts = [
numpy.c_[numpy.linspace(0, length, 11), numpy.zeros((11, 2))]
for length in lengths
]
data = {'fa': [numpy.full((11, 1), value) for value in values]}
tractography = Tractography(tracts, data)

measures = compute_all_measures(
tractography,
['length mean (mm)', 'length std (mm)',
'per tract distance weighted mean %s',
'per tract distance weighted std %s'],
scalars=['fa']
)

numpy.testing.assert_allclose(measures['length std (mm)'], lengths.std())
mean = numpy.average(values, weights=lengths)
numpy.testing.assert_allclose(
measures['per tract distance weighted mean fa'], mean
)
numpy.testing.assert_allclose(
measures['per tract distance weighted std fa'],
numpy.sqrt(numpy.average((values - mean) ** 2, weights=lengths))
)

tractography = Tractography(tracts[:1] * 4, data)
measures = compute_all_measures(
tractography,
['per tract distance weighted mean %s',
'per tract distance weighted std %s'],
scalars=['fa']
)
numpy.testing.assert_allclose(
measures['per tract distance weighted std fa'], values.std()
)
4 changes: 2 additions & 2 deletions tract_querier/tract_math/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def count(optional_flags, tractographies):

@tract_math_operation(': calculates mean and std of tract length')
def length_mean_std(optional_flags, tractography):
return tensor_operations.compute_all_measures(tractography, ['length mean (mm)', 'length std (mm^2)'])
return tensor_operations.compute_all_measures(tractography, ['length mean (mm)', 'length std (mm)'])


@tract_math_operation('<volume unit>: calculates the volume of a tract based on voxel occupancy of a certain voxel volume')
Expand Down Expand Up @@ -93,7 +93,7 @@ def scalar_compute_most(optional_flags, tractographies, scalar):
['per tract distance weighted mean %s',
'per tract distance weighted std %s',
'tract volume',
'length mean (mm)', 'length std (mm^2)',
'length mean (mm)', 'length std (mm)',
'number of tracts'
],
scalars=scalars, resolution=1.)
Expand Down
8 changes: 4 additions & 4 deletions tract_querier/tract_math/tensor_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ def compute_all_measures(tractography, desired_keys_list, scalars=None, resoluti
unordered_results['number of tracts'] = tract_operations.tract_count(
tractography.tracts())

if ('length mean (mm)' in desired_keys_list) or ('length std (mm^2)' in desired_keys_list):
if ('length mean (mm)' in desired_keys_list) or ('length std (mm)' in desired_keys_list):
lengths = numpy.empty(len(tractography.tracts()))
for i, one_tract in enumerate(tractography.tracts()):
lengths[i] = tract_operations.tract_length(one_tract)
unordered_results['length mean (mm)'] = lengths.mean()
unordered_results['length std (mm^2)'] = lengths.std()
unordered_results['length std (mm)'] = lengths.std()

if ('tract volume' in desired_keys_list) and (resolution is not None):
resolution = float(resolution)
Expand Down Expand Up @@ -66,8 +66,8 @@ def compute_all_measures(tractography, desired_keys_list, scalars=None, resoluti
weighted_scalars[line_index, 1] = length
mean = numpy.average(
weighted_scalars[:, 0], weights=weighted_scalars[:, 1])
std = numpy.average(
(weighted_scalars[:, 0] - mean) ** 2, weights=weighted_scalars[:, 1])
std = numpy.sqrt(numpy.average(
(weighted_scalars[:, 0] - mean) ** 2, weights=weighted_scalars[:, 1]))
unordered_results[mean_key] = mean
unordered_results[std_key] = std
mii = desired_keys_list.index('per tract distance weighted mean %s')
Expand Down
Loading