Skip to content

Commit 687bdac

Browse files
authored
Merge pull request #2524 from SCIInstitute/amorris/2523-group-pvalues
Fix multi-domain group p-value display cross-domain bleed
2 parents a7c1202 + 9e1c96c commit 687bdac

2 files changed

Lines changed: 27 additions & 9 deletions

File tree

Libs/Analyze/Shape.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -819,8 +819,24 @@ void Shape::set_point_features(std::string feature, Eigen::VectorXd values) {
819819
auto group = get_meshes(DisplayMode::Reconstructed);
820820

821821
if (group.valid()) {
822-
for (auto mesh : group.meshes()) {
823-
mesh->interpolate_scalars_to_mesh(feature, get_local_correspondence_points(), values);
822+
auto local_particles = particles_.get_local_particles();
823+
int num_domains = local_particles.size();
824+
825+
if (num_domains > 1) {
826+
// Split particles and values per domain so that each mesh only interpolates
827+
// from its own domain's particles, preventing cross-domain bleed in the KD-tree
828+
// lookup (e.g. pelvis p-values bleeding into femur mesh near the hip joint).
829+
int value_offset = 0;
830+
for (int d = 0; d < num_domains && d < group.meshes().size(); d++) {
831+
int num_domain_particles = local_particles[d].size() / 3;
832+
Eigen::VectorXd domain_values = values.segment(value_offset, num_domain_particles);
833+
group.meshes()[d]->interpolate_scalars_to_mesh(feature, local_particles[d], domain_values);
834+
value_offset += num_domain_particles;
835+
}
836+
} else {
837+
for (auto mesh : group.meshes()) {
838+
mesh->interpolate_scalars_to_mesh(feature, get_local_correspondence_points(), values);
839+
}
824840
}
825841
}
826842
}

Python/shapeworks/shapeworks/stats.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
'''
1717

1818

19-
def compute_pvalues_for_group_difference(data, number_of_particles, permutations=100):
19+
def compute_pvalues_for_group_difference(data, number_of_particles, permutations=100, seed=42):
2020
group_id = data["group_ids"].unique()
2121
group_0_filenames = list(data[data["group_ids"] == group_id[0]]["filename"])
2222
group_1_filenames = list(data[data["group_ids"] == group_id[1]]["filename"])
@@ -26,22 +26,24 @@ def compute_pvalues_for_group_difference(data, number_of_particles, permutations
2626
group_1_data = sw.ParticleSystem(group_1_filenames).Particles()
2727
group_1_data = np.reshape(group_1_data, (number_of_particles, 3, -1))
2828

29-
return compute_pvalues_for_group_difference_data(group_0_data, group_1_data, permutations)
29+
return compute_pvalues_for_group_difference_data(group_0_data, group_1_data, permutations, seed)
3030

3131

32-
def compute_pvalues_for_group_difference_studio(group_0_data, group_1_data, permutations=100):
32+
def compute_pvalues_for_group_difference_studio(group_0_data, group_1_data, permutations=100, seed=42):
3333
number_of_particles = int(group_0_data.shape[0] / 3)
3434
group_0 = np.reshape(group_0_data, (number_of_particles, 3, -1))
3535
group_1 = np.reshape(group_1_data, (number_of_particles, 3, -1))
36-
return compute_pvalues_for_group_difference_data(group_0, group_1, permutations)
36+
return compute_pvalues_for_group_difference_data(group_0, group_1, permutations, seed)
3737

3838

39-
def compute_pvalues_for_group_difference_data(group_0_data, group_1_data, permutations=100):
39+
def compute_pvalues_for_group_difference_data(group_0_data, group_1_data, permutations=100, seed=42):
4040
number_of_particles = group_0_data.shape[0]
4141
group_0_size = group_0_data.shape[-1]
4242
group_1_size = group_1_data.shape[-1]
4343
subset_size = min(group_0_size, group_1_size)
4444

45+
rng = np.random.RandomState(seed)
46+
4547
pvalues_matrix = np.zeros((number_of_particles, permutations))
4648
idx = 0
4749
for p in range(permutations):
@@ -51,8 +53,8 @@ def compute_pvalues_for_group_difference_data(group_0_data, group_1_data, permut
5153
sw_message("Aborted")
5254
return
5355

54-
group_0_index = np.random.choice(group_0_size, subset_size, replace=False)
55-
group_1_index = np.random.choice(group_1_size, subset_size, replace=False)
56+
group_0_index = rng.choice(group_0_size, subset_size, replace=False)
57+
group_1_index = rng.choice(group_1_size, subset_size, replace=False)
5658

5759
group_0_subset = group_0_data[:, :, group_0_index]
5860
group_1_subset = group_1_data[:, :, group_1_index]

0 commit comments

Comments
 (0)