How to write a double variable to a structure array
6 次查看(过去 30 天)
显示 更早的评论
Good morning.
I have two ''sensors'' that collected gait data, the one method is Vicon and the other method is called MS. I have captured 10 gait cycles that are analysed from heel strike to heel strike.
I have a structure T that holds all the gait cycle marker, angle and error data for each gait cycle.
Because the data is collected from two different sensors there is a delay between the signals and so align signals is used to account for this delay. I then find which signal has been padded with zeros and adjust the size of the array so that the padded zeros are not apart of the signal, this gives the time aligned signal kgc which is knee gait cycle for both vicon which is column 1 and MS which is column 2.
I then do a few error measurements to compare the signals against one another.
The part I am struggling with is I then have this line of code
GC(:,:,k) = resample((T(k).kgc),101,length(T(k).kgc),'Dimension',1);
NGC(:,:,k) = resample((T(k).norm_gc),101,length(T(k).norm_gc),'Dimension',1);
Which is the time aligned gait cycle that is no resampled so that I can compare 100% of the gait cycle. However GC(:,:,k) and NGC(:,:,k) are doubles with the first column for Vicon and the second column for MS. Both variables are in the dimension 101X2X10 for the 10 gait cycles of length 101.
I would like to find a way of now writing GC(:,:,k) and NGC(:,:,k) to the structure T where all the other infomation is stored. How do I go about assigning these doubles to the structure T?
Also if anyone has any experience in gait analysis, is there a simple way to calculate walking speed, stride length and step from the marker data I have available? I have managed to calculate a few parameters but struggling a little with the three mentioned above.
I have attach the data If you need any further info or if anything is unclear please let me know and I will try to explain it better.
The full script is below
Thanks in advance and Merry Christmas!
%% IF loading data manually ignore the load lines- where the data needs to be in the same folder as the matlab scripts
% load('H05_T05_HS_INDEX.mat')
% load('trim_data.mat')
load('TEST.mat');
load('TEST_HS_INDEX.mat');
S = trim{1}; % extract struct from cell
FN = fieldnames(S); % get field names from S
N = numel(hs_index)-1;
for ci = 1:N
T(ci).count = ci; % just to create a new structure T with new field "count" = block data index (for fun)
start_index = round(hs_index(ci));
stop_index = round(hs_index(ci+1));
for ck = 1:numel(FN)
fn = FN{ck};
% get data related to that fieldname
data = S.(fn);
T(ci).(fn) = data((start_index:stop_index),:); % store data within start / stop indexes
end
end
% store structure T in one cell Gait_cycles
Gait_cycles{1} = T;
%%Error calculations- store in structure how???? At the moment it just calculated the final
%gait cycles error value
for k = 1:N
%Align curves again- once HS HS selection is made make sure each GC is
%perfectly aligned
T(k).max_rows = min(T(k).Vic(:,1),T(k).MS(:,1));
[tempgc(:,1), tempgc(:,2), T(k).D]=alignsignals(T(k).Vic(:,1),T(k).MS(:,1),10,'truncate');
temp1 = find(tempgc(:,1)==0);
temp2 = find(tempgc(:,2)==0);
if ~isempty(temp1) && isempty(temp2)
good_rows = find(tempgc(:,1));
T(k).kgc(:,1:2) = tempgc(good_rows,1:2);
elseif isempty(temp1) && ~isempty(temp2)
good_rows = find(tempgc(:,2));
T(k).kgc(:,1:2) = tempgc(good_rows,1:2);
elseif isempty(temp1) && isempty(temp2)
T(k).kgc = tempgc;
elseif ~isempty(temp1) && ~isempty(temp2)
error('This shouldn''t happen!');
end
% error # 1 computation
err = T(k).kgc(:,1)-T(k).kgc(:,2);
T(k).mRMSE = sqrt(mean(err.^2)); % average RMS error of one gait cycle
% error # 2 computation
T(k).norm_gc(:,1) = T(k).kgc(:,1) - mean(T(k).kgc(:,1)); % double check this with phil 15/12/2023 -all or no all
T(k).norm_gc(:,2) = T(k).kgc(:,2) - mean(T(k).kgc(:,2));
err2 = T(k).norm_gc(:,1)-T(k).norm_gc(:,2);
T(k).mNRMSE = sqrt(mean(err2.^2));
clear good_rows temp1 temp2 tempgc err err2
end
% RMS averaged errors for the entire experiment
mRMSE_entire = sqrt(mean([T.mRMSE].^2)); % average RMS error for the entire experiment
mNRMSE_entire = sqrt(mean([T.mNRMSE].^2)); % average RMS error for the entire experiment
for k = 1:N
% add to existing T structure the RMS averaged errors for the entire experiment
% T(k).mRMSE_entire = mRMSE_entire;
% T(k).norm_mmse_entire = norm_mmse_entire;
%Gait parameters
%cadence: num steps per min
% T(k).StrideTime = (T(k).time(end,1)-T(k).time(1,1));
% T(k).cadence = (60/(T(k).StrideTime))*2; %Consecutive steps so double
% % T(k).stridelength = (T(k).RHeel(end,2)-T(k).RHeel(1,2)); %double check this calculation because of treadmil
% T(k).StanceTime = 0.6*(T(k).StrideTime);
% T(k).SwingTime = 0.4*(T(k).StrideTime);
% T(k).ROM = max(T(k).Vic(:,1)) - min(T(k).Vic(:,1));
%Resample all HS to same length 0-100
GC(:,:,k) = resample((T(k).kgc),101,length(T(k).kgc),'Dimension',1);
NGC(:,:,k) = resample((T(k).norm_gc),101,length(T(k).norm_gc),'Dimension',1);
%%Asigne GC(:,:,k) and NGC(:,:,k) double to the structure T so that it
%%can be accessed in the structure form later on.
end
% Average GC
GC1(:,:) = mean(GC,3);
std_GC1 = std(GC,[],3);
GC2(:,:) = mean(NGC,3);
std_GC2 = std(NGC,[],3);
GC_time = 0:1:100;
figure
plot(GC_time,GC1,GC_time,GC1+std_GC1,GC_time,GC1-std_GC1);
figure
plot(GC_time,GC2,GC_time,GC2+std_GC2,GC_time,GC2-std_GC2);
%Plot Gait phase
% Assuming you have a vector representing the gait cycle data (e.g., yData)
% and a vector representing the corresponding time points (e.g., xData).
% Define the stance and swing phases (you may need to adjust these indices)
time = 1:100;
stanceStart = 1; % Replace with the index where stance phase begins
stanceEnd = 60; % Replace with the index where stance phase ends
% Create the plot
figure;
plot(time, GCnorm_Vic , 'b -', 'LineWidth', 2); % Blue line for the gait cycle data
hold on;
%plot(time, GCnorm_MS , 'y -', 'LineWidth', 2); % Blue line for the gait cycle data
% Shade the stance phase
area(time(stanceStart:stanceEnd), GCnorm_Vic(stanceStart:stanceEnd), 'FaceColor', [0.8, 0.8, 0.8]);
% Highlight the swing phase
plot((stanceEnd+1:100), GCnorm_Vic(stanceEnd+1:100),'r --', 'LineWidth', 2); % Red line for the swing phase
% Customize the plot
xlabel('Time');
ylabel('Gait Cycle Data');
title('Gait Cycle with Stance and Swing Phases');
% Add a legend
legend('Gait Cycle', 'Stance Phase', 'Swing Phase');
% Adjust the axis limits if needed
axis tight;
% Display the grid
grid on;
% Hold off to end the plot customization
hold off;
0 个评论
采纳的回答
Mathieu NOE
2023-12-19
hello Alexandra (and welcome back ! )
I am unfortunately no xpert at all in gait so I am not sure to be able to answer the second part of your question
but for the first topic (I would like to find a way of now writing GC(:,:,k) and NGC(:,:,k) to the structure T) , it's quite easy - do this in your for loop
%%Asigne GC(:,:,k) and NGC(:,:,k) double to the structure T so that it
%%can be accessed in the structure form later on.
T(k).GC = GC(:,:,k);
T(k).NGC = NGC(:,:,k);
full code :
%% IF loading data manually ignore the load lines- where the data needs to be in the same folder as the matlab scripts
% load('H05_T05_HS_INDEX.mat')
% load('trim_data.mat')
load('TEST.mat');
load('TEST_HS_INDEX.mat');
S = trim{1}; % extract struct from cell
FN = fieldnames(S); % get field names from S
N = numel(hs_index)-1;
for ci = 1:N
T(ci).count = ci; % just to create a new structure T with new field "count" = block data index (for fun)
start_index = round(hs_index(ci));
stop_index = round(hs_index(ci+1));
for ck = 1:numel(FN)
fn = FN{ck};
% get data related to that fieldname
data = S.(fn);
T(ci).(fn) = data((start_index:stop_index),:); % store data within start / stop indexes
end
end
% store structure T in one cell Gait_cycles
Gait_cycles{1} = T;
%%Error calculations- store in structure how???? At the moment it just calculated the final
%gait cycles error value
for k = 1:N
%Align curves again- once HS HS selection is made make sure each GC is
%perfectly aligned
T(k).max_rows = min(T(k).Vic(:,1),T(k).MS(:,1));
[tempgc(:,1), tempgc(:,2), T(k).D]=alignsignals(T(k).Vic(:,1),T(k).MS(:,1),10,'truncate');
temp1 = find(tempgc(:,1)==0);
temp2 = find(tempgc(:,2)==0);
if ~isempty(temp1) && isempty(temp2)
good_rows = find(tempgc(:,1));
T(k).kgc(:,1:2) = tempgc(good_rows,1:2);
elseif isempty(temp1) && ~isempty(temp2)
good_rows = find(tempgc(:,2));
T(k).kgc(:,1:2) = tempgc(good_rows,1:2);
elseif isempty(temp1) && isempty(temp2)
T(k).kgc = tempgc;
elseif ~isempty(temp1) && ~isempty(temp2)
error('This shouldn''t happen!');
end
% error # 1 computation
err = T(k).kgc(:,1)-T(k).kgc(:,2);
T(k).mRMSE = sqrt(mean(err.^2)); % average RMS error of one gait cycle
% error # 2 computation
T(k).norm_gc(:,1) = T(k).kgc(:,1) - mean(T(k).kgc(:,1)); % double check this with phil 15/12/2023 -all or no all
T(k).norm_gc(:,2) = T(k).kgc(:,2) - mean(T(k).kgc(:,2));
err2 = T(k).norm_gc(:,1)-T(k).norm_gc(:,2);
T(k).mNRMSE = sqrt(mean(err2.^2));
clear good_rows temp1 temp2 tempgc err err2
end
% RMS averaged errors for the entire experiment
mRMSE_entire = sqrt(mean([T.mRMSE].^2)); % average RMS error for the entire experiment
mNRMSE_entire = sqrt(mean([T.mNRMSE].^2)); % average RMS error for the entire experiment
for k = 1:N
% add to existing T structure the RMS averaged errors for the entire experiment
% T(k).mRMSE_entire = mRMSE_entire;
% T(k).norm_mmse_entire = norm_mmse_entire;
%Gait parameters
%cadence: num steps per min
% T(k).StrideTime = (T(k).time(end,1)-T(k).time(1,1));
% T(k).cadence = (60/(T(k).StrideTime))*2; %Consecutive steps so double
% % T(k).stridelength = (T(k).RHeel(end,2)-T(k).RHeel(1,2)); %double check this calculation because of treadmil
% T(k).StanceTime = 0.6*(T(k).StrideTime);
% T(k).SwingTime = 0.4*(T(k).StrideTime);
% T(k).ROM = max(T(k).Vic(:,1)) - min(T(k).Vic(:,1));
%Resample all HS to same length 0-100
GC(:,:,k) = resample((T(k).kgc),101,length(T(k).kgc),'Dimension',1);
NGC(:,:,k) = resample((T(k).norm_gc),101,length(T(k).norm_gc),'Dimension',1);
%%Asigne GC(:,:,k) and NGC(:,:,k) double to the structure T so that it
%%can be accessed in the structure form later on.
T(k).GC = GC(:,:,k);
T(k).NGC = NGC(:,:,k);
end
% Average GC
GC1 = mean(GC,3);
std_GC1 = std(GC,[],3);
GC2 = mean(NGC,3);
std_GC2 = std(NGC,[],3);
GC_time = 0:1:100;
figure
plot(GC_time,GC1,GC_time,GC1+std_GC1,GC_time,GC1-std_GC1);
figure
plot(GC_time,GC2,GC_time,GC2+std_GC2,GC_time,GC2-std_GC2);
%Plot Gait phase
% Assuming you have a vector representing the gait cycle data (e.g., yData)
% and a vector representing the corresponding time points (e.g., xData).
% Define the stance and swing phases (you may need to adjust these indices)
time = 1:100;
stanceStart = 1; % Replace with the index where stance phase begins
stanceEnd = 60; % Replace with the index where stance phase ends
% Create the plot
figure;
plot(time, GCnorm_Vic , 'b -', 'LineWidth', 2); % Blue line for the gait cycle data
hold on;
%plot(time, GCnorm_MS , 'y -', 'LineWidth', 2); % Blue line for the gait cycle data
% Shade the stance phase
area(time(stanceStart:stanceEnd), GCnorm_Vic(stanceStart:stanceEnd), 'FaceColor', [0.8, 0.8, 0.8]);
% Highlight the swing phase
plot((stanceEnd+1:100), GCnorm_Vic(stanceEnd+1:100),'r --', 'LineWidth', 2); % Red line for the swing phase
% Customize the plot
xlabel('Time');
ylabel('Gait Cycle Data');
title('Gait Cycle with Stance and Swing Phases');
% Add a legend
legend('Gait Cycle', 'Stance Phase', 'Swing Phase');
% Adjust the axis limits if needed
axis tight;
% Display the grid
grid on;
% Hold off to end the plot customization
hold off;
4 个评论
Stephen23
2023-12-19
@alexandra ligeti: if this answer resolved your original question then please consider accepting the answer, which shows others that your question is resolved, gives reputation points to its author, and is an easy way to say thanks!
更多回答(0 个)
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Introduction to Installation and Licensing 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!