|
a |
|
b/MATLAB/analysis/findDuplicateSubjects.m |
|
|
1 |
%FINDDUPLICATESUBJECTS finds duplicate subjects in the database. |
|
|
2 |
% |
|
|
3 |
% AUTHOR: Maximilian C. M. Fischer |
|
|
4 |
% COPYRIGHT (C) 2023 Maximilian C. M. Fischer |
|
|
5 |
% LICENSE: EUPL v1.2 |
|
|
6 |
% |
|
|
7 |
|
|
|
8 |
clearvars; close all |
|
|
9 |
|
|
|
10 |
addpath(genpath('..\src')) |
|
|
11 |
VSD_addPathes('..\..\..\..\..\') |
|
|
12 |
|
|
|
13 |
% Load subjects & meta data |
|
|
14 |
subjectXLSX = '..\res\VSD_Subjects.xlsx'; |
|
|
15 |
Subjects = readtable(subjectXLSX); |
|
|
16 |
|
|
|
17 |
%% Import |
|
|
18 |
NoS = size(Subjects, 1); |
|
|
19 |
patchProps.FaceAlpha = 0.5; |
|
|
20 |
TFM2 = repmat(struct('APP',[]),NoS,1); |
|
|
21 |
Sacrum = repmat(struct('vertices',[],'faces',[]),NoS,1); |
|
|
22 |
for s=1:NoS |
|
|
23 |
% Import the bones |
|
|
24 |
load(['..\..\Bones\' Subjects.ID{s} '.mat'], 'B') |
|
|
25 |
% Import the transformation to the APP coordinate system |
|
|
26 |
load(['D:\Biomechanics\Hip\Code\AcetabularMorphologyAnalysis\data\' Subjects.ID{s} '.mat'], 'TFM2APP') |
|
|
27 |
TFM2(s).APP = TFM2APP; |
|
|
28 |
% Transform the sacrum to the APP coordinate system |
|
|
29 |
Sacrum(s) = transformPoint3d(splitMesh(... |
|
|
30 |
B(ismember({B.name},'Sacrum')).mesh,'maxBoundingBox'), TFM2(s).APP); |
|
|
31 |
end |
|
|
32 |
clearvars B TFM2APP |
|
|
33 |
|
|
|
34 |
% Compare the sacrum of each subject using an ICP registration |
|
|
35 |
patchProps.FaceAlpha = 0.5; |
|
|
36 |
SS = 1:NoS; |
|
|
37 |
rigidRegRMSE = nan(NoS); |
|
|
38 |
for s=1:NoS |
|
|
39 |
SS(SS==s)=[]; |
|
|
40 |
for ss=SS |
|
|
41 |
rigidReg = icp(Sacrum(s),Sacrum(ss),'Plot',false,'ChangeRate',1e-2,'Delay',0); |
|
|
42 |
rigidRegRMSE(s,ss) = rigidReg.rmse; |
|
|
43 |
end |
|
|
44 |
end |
|
|
45 |
|
|
|
46 |
save('rigidRegRMSE','rigidRegRMSE') |
|
|
47 |
|
|
|
48 |
%% Evaluate results |
|
|
49 |
load('rigidRegRMSE','rigidRegRMSE') |
|
|
50 |
|
|
|
51 |
medianRMSE = median(rigidRegRMSE(:), 'omitnan'); |
|
|
52 |
outlierCutOff = prctile(rigidRegRMSE(:),25)-1.5*iqr(rigidRegRMSE(:)); |
|
|
53 |
[row,col] = ind2sub(size(rigidRegRMSE),find(rigidRegRMSE<outlierCutOff)); |
|
|
54 |
for d=1:length(row) |
|
|
55 |
disp([... |
|
|
56 |
'Subject ' Subjects.ID{row(d)} ' and ' Subjects.ID{col(d)} ... |
|
|
57 |
' are dupes based on a comparison of the sacrum!']) |
|
|
58 |
end |
|
|
59 |
|
|
|
60 |
% [List.f, List.p] = matlab.codetools.requiredFilesAndProducts([mfilename '.m']); |
|
|
61 |
% List.f = List.f'; List.p = List.p'; |