def test_metric_minimum_average_direct_flip(): metric = dipymetric.MinimumAverageDirectFlipMetric() assert_equal(metric.feature.infer_shape(s1), s1.shape) features = metric.feature.extract(s1) assert_equal(features.shape, s1.shape) assert_array_equal(features, s1) # Test dist() features1 = metric.feature.extract(s1) assert_true(metric.are_compatible(features1.shape, features1.shape)) dist = metric.dist(features1, features1) assert_equal(dist, 0.0) assert_equal(dipymetric.mdf(s1, s1), 0.0) # Features 1 and 2 do have the same number of points and dimensions features2 = metric.feature.extract(s2) assert_true(metric.are_compatible(features1.shape, features2.shape)) dist = metric.dist(features1, features2) ground_truth = mdf_distance(s1, s2) assert_almost_equal(dist, ground_truth) assert_almost_equal(dipymetric.mdf(s1, s2), ground_truth) # Features 1 and 3 do not have the same number of dimensions features3 = metric.feature.extract(s3) assert_false(metric.are_compatible(features1.shape, features3.shape)) assert_raises(ValueError, metric.dist, features1, features3) assert_raises(ValueError, dipymetric.mdf, s1, s3) # Features 1 and 4 do not have the same number of points features4 = metric.feature.extract(s4) assert_false(metric.are_compatible(features1.shape, features4.shape)) assert_raises(ValueError, metric.dist, features1, features4) assert_raises(ValueError, dipymetric.dist, metric, s1, s4)
def test_subclassing_metric(): class EmptyMetric(dipymetric.Metric): pass metric = EmptyMetric() assert_raises(NotImplementedError, metric.are_compatible, None, None) assert_raises(NotImplementedError, metric.dist, None, None) class MDF(dipymetric.Metric): def are_compatible(self, shape1, shape2): return shape1 == shape2 def dist(self, features1, features2): return mdf_distance(features1, features2) metric = MDF() d1 = dipymetric.dist(metric, s1, s2) d2 = dipymetric.mdf(s1, s2) assert_almost_equal(d1, d2) features1 = metric.feature.extract(s1) features2 = metric.feature.extract(s2) d3 = metric.dist(features1, features2) assert_almost_equal(d1, d3)
def test_metric_minimum_average_direct_flip(): feature = dipymetric.IdentityFeature() class MinimumAverageDirectFlipMetric(dipymetric.Metric): def __init__(self, feature): super(MinimumAverageDirectFlipMetric, self).__init__(feature=feature) @property def is_order_invariant(self): return True # Ordering is handled in the distance computation def are_compatible(self, shape1, shape2): return shape1[0] == shape2[0] def dist(self, v1, v2): average_euclidean = lambda x, y: np.mean(norm(x-y, axis=1)) dist_direct = average_euclidean(v1, v2) dist_flipped = average_euclidean(v1, v2[::-1]) return min(dist_direct, dist_flipped) for metric in [MinimumAverageDirectFlipMetric(feature), dipymetric.MinimumAverageDirectFlipMetric(feature)]: # Test special cases of the MDF distance. assert_equal(metric.dist(s, s), 0.) assert_equal(metric.dist(s, s[::-1]), 0.) # Translation offset = np.array([0.8, 1.3, 5], dtype=dtype) assert_almost_equal(metric.dist(s, s+offset), norm(offset), 5) # Scaling M_scaling = np.diag([1.2, 2.8, 3]).astype(dtype) s_mean = np.mean(s, axis=0) s_zero_mean = s - s_mean s_scaled = np.dot(M_scaling, s_zero_mean.T).T + s_mean d = np.mean(norm((np.diag(M_scaling)-1)*s_zero_mean, axis=1)) assert_almost_equal(metric.dist(s, s_scaled), d, 5) # Rotation from dipy.core.geometry import rodrigues_axis_rotation rot_axis = np.array([1, 2, 3], dtype=dtype) M_rotation = rodrigues_axis_rotation(rot_axis, 60.).astype(dtype) s_mean = np.mean(s, axis=0) s_zero_mean = s - s_mean s_rotated = np.dot(M_rotation, s_zero_mean.T).T + s_mean opposite = norm(np.cross(rot_axis, s_zero_mean), axis=1) / norm(rot_axis) distances = np.sqrt(2*opposite**2 * (1 - np.cos(60.*np.pi/180.))).astype(dtype) d = np.mean(distances) assert_almost_equal(metric.dist(s, s_rotated), d, 5) for s1, s2 in itertools.product(*[streamlines]*2): # All possible pairs # Extract features since metric doesn't work directly on streamlines f1 = metric.feature.extract(s1) f2 = metric.feature.extract(s2) # Test method are_compatible same_nb_points = f1.shape[0] == f2.shape[0] assert_equal(metric.are_compatible(f1.shape, f2.shape), same_nb_points) # Test method dist if features are compatible if metric.are_compatible(f1.shape, f2.shape): distance = metric.dist(f1, f2) if np.all(f1 == f2): assert_equal(distance, 0.) assert_almost_equal(distance, dipymetric.dist(metric, s1, s2)) assert_almost_equal(distance, dipymetric.mdf(s1, s2)) assert_true(distance >= 0.) # This metric type is order invariant assert_true(metric.is_order_invariant) for s1, s2 in itertools.product(*[streamlines]*2): # All possible pairs f1 = metric.feature.extract(s1) f2 = metric.feature.extract(s2) if not metric.are_compatible(f1.shape, f2.shape): continue f1_flip = metric.feature.extract(s1[::-1]) f2_flip = metric.feature.extract(s2[::-1]) distance = metric.dist(f1, f2) assert_almost_equal(metric.dist(f1_flip, f2_flip), distance) if not np.all(f1_flip == f2_flip): assert_true(np.allclose(metric.dist(f1, f2_flip), distance)) assert_true(np.allclose(metric.dist(f1_flip, f2), distance))
def test_metric_minimum_average_direct_flip(): feature = dipymetric.IdentityFeature() class MinimumAverageDirectFlipMetric(dipymetric.Metric): def __init__(self, feature): super(MinimumAverageDirectFlipMetric, self).__init__(feature=feature) @property def is_order_invariant(self): return True # Ordering is handled in the distance computation def are_compatible(self, shape1, shape2): return shape1[0] == shape2[0] def dist(self, v1, v2): def average_euclidean(x, y): return np.mean(norm(x - y, axis=1)) dist_direct = average_euclidean(v1, v2) dist_flipped = average_euclidean(v1, v2[::-1]) return min(dist_direct, dist_flipped) for metric in [ MinimumAverageDirectFlipMetric(feature), dipymetric.MinimumAverageDirectFlipMetric(feature) ]: # Test special cases of the MDF distance. assert_equal(metric.dist(s, s), 0.) assert_equal(metric.dist(s, s[::-1]), 0.) # Translation offset = np.array([0.8, 1.3, 5], dtype=dtype) assert_almost_equal(metric.dist(s, s + offset), norm(offset), 5) # Scaling M_scaling = np.diag([1.2, 2.8, 3]).astype(dtype) s_mean = np.mean(s, axis=0) s_zero_mean = s - s_mean s_scaled = np.dot(M_scaling, s_zero_mean.T).T + s_mean d = np.mean(norm((np.diag(M_scaling) - 1) * s_zero_mean, axis=1)) assert_almost_equal(metric.dist(s, s_scaled), d, 5) # Rotation from dipy.core.geometry import rodrigues_axis_rotation rot_axis = np.array([1, 2, 3], dtype=dtype) M_rotation = rodrigues_axis_rotation(rot_axis, 60.).astype(dtype) s_mean = np.mean(s, axis=0) s_zero_mean = s - s_mean s_rotated = np.dot(M_rotation, s_zero_mean.T).T + s_mean opposite = norm(np.cross(rot_axis, s_zero_mean), axis=1) / norm(rot_axis) distances = np.sqrt(2 * opposite**2 * (1 - np.cos(60. * np.pi / 180.))).astype(dtype) d = np.mean(distances) assert_almost_equal(metric.dist(s, s_rotated), d, 5) # All possible pairs for s1, s2 in itertools.product(*[streamlines] * 2): # Extract features since metric doesn't work # directly on streamlines f1 = metric.feature.extract(s1) f2 = metric.feature.extract(s2) # Test method are_compatible same_nb_points = f1.shape[0] == f2.shape[0] assert_equal(metric.are_compatible(f1.shape, f2.shape), same_nb_points) # Test method dist if features are compatible if metric.are_compatible(f1.shape, f2.shape): distance = metric.dist(f1, f2) if np.all(f1 == f2): assert_equal(distance, 0.) assert_almost_equal(distance, dipymetric.dist(metric, s1, s2)) assert_almost_equal(distance, dipymetric.mdf(s1, s2)) assert_true(distance >= 0.) # This metric type is order invariant assert_true(metric.is_order_invariant) # All possible pairs for s1, s2 in itertools.product(*[streamlines] * 2): f1 = metric.feature.extract(s1) f2 = metric.feature.extract(s2) if not metric.are_compatible(f1.shape, f2.shape): continue f1_flip = metric.feature.extract(s1[::-1]) f2_flip = metric.feature.extract(s2[::-1]) distance = metric.dist(f1, f2) assert_almost_equal(metric.dist(f1_flip, f2_flip), distance) if not np.all(f1_flip == f2_flip): assert_true(np.allclose(metric.dist(f1, f2_flip), distance)) assert_true(np.allclose(metric.dist(f1_flip, f2), distance))
key=lambda i: group2_clusters.clusters_sizes()[i], reverse=True)[:num_of_bundles] # %% bundle_group1 = [group1_clusters.centroids[idx] for idx in top_idx_group1] bundle_group2 = [group2_clusters.centroids[idx] for idx in top_idx_group2] # %% from dipy.segment.metric import ResampleFeature, AveragePointwiseEuclideanMetric, mdf dist_all = np.zeros((num_of_bundles, num_of_bundles)) for g1 in range(len(bundle_group1)): for g2 in range(len(bundle_group2)): id1 = top_idx_group1[g1] id2 = top_idx_group2[g2] dist_all[g1, g2] = (mdf(group1_clusters.centroids[id1], group2_clusters.centroids[id2])) # %% import copy dist_all_fix = copy.copy(dist_all) dist_all_idx = [] for i in range(len(bundle_group1)): idx = np.argmin(dist_all_fix[i, :]) dist_all_idx.append([i, idx]) dist_all_fix[:, idx] = 100000 #dist_all_idx dist_group1_idx = [dist_all_idx[iii][0] for iii in range(num_of_bundles)] #size id dist_group2_idx = [dist_all_idx[iii][1]
""" top_idx_group_control = sorted(range(len(selected_sizes[control])), key=lambda i: selected_sizes[group][i], reverse=True)[:num_bundles] top_idx_group_noncontrol = sorted(range(len(selected_sizes[non_control])), key=lambda i: selected_sizes[group][i], reverse=True)[:num_bundles] if not np.all(top_idx_group_control == np.arange(num_bundles)) or not np.all(top_idx_group_noncontrol == np.arange(num_bundles)): warnings.warn('There is indeed a difference between the two') else: print('no difference between the two') """ for g3 in np.arange(num_bundles): for g4 in np.arange(num_bundles): dist_all[g3, g4] = (mdf(selected_centroids[control][g3], selected_centroids[non_control][g4])) dist_all_fix = copy.copy(dist_all) dist_all_idx = [] #for i in range(len(selected_centroids[group])): for i in np.arange(num_bundles): idx = np.argmin(dist_all_fix[i, :]) dist_all_idx.append([i, idx]) dist_all_fix[:, idx] = 100000 dist_group3_idx = [dist_all_idx[iii][0] for iii in range(num_bundles)] # size id dist_group4_idx = [dist_all_idx[iii][1] for iii in range(num_bundles)] # size id group_list = {} dist_idx = {} for j,group in enumerate(groups):