Trying to extract data trail by trail, but my data is sampled at different sampling rate.
Mostra commenti meno recenti
Velocity, position and torque data has sampling frequency of 1000 and EMG's channels at 2000. So I am not getting the right region of intrest. I think I might need two different time vector or is there any other way to solve this problem ?
%% Intialization
fs=960; % sampling frequency of velocity,position and torque
Fs=1960; % sampling frequency of EMG channels
fc=10;
% Low pass Filter of 10 Hz
[b,a]= butter(1,fc/(fs/2),"low");
prewindow=-1000;
postwindow=5000;
% Caliberation
%torque=12.80409731*Torque;
%tosition=34.2465753*position;
%velocity=
%% Assigning all variables
%Position
position=V300degpersec_Ch2.values;
%position=-position;
positionoffset=min(position);
Position=position+abs(positionoffset);%% remove offset
Position=filtfilt(b,a,position);
% Torque
torque=V300degpersec_Ch4.values;
Torque=filtfilt(b,a,torque);
%Velocity
velocity=V300degpersec_Ch3.values;
velocity=-velocity;
Velocity=filtfilt(b,a,velocity);
Time=1/fs:1/fs:length(Velocity)/fs;
% Raw EMG
RFp=V300degpersec_Ch5.values;% Proximal Rectus Femoris
%RFp=downsample(RFp,2);
RFd=V300degpersec_Ch6.values;% Distal Rectus Femoris
%RFd=downsample(RFd,2);
VM=V300degpersec_Ch7.values;% Vastus Medialis
%VM=downsample(VM,2);
BiFem=V300degpersec_Ch8.values;% Biceps Femoris
%BiFem=downsample(BiFem,2);
SM=V300degpersec_Ch9.values;% Semitendinosus
%SM=downsample(SM,2);
time=1/Fs:1/Fs:(length(SM))/Fs;% Time vector for EMG channels
%% Croping ROI
moving=(Velocity>1.5);
%plot(Time,Velocity);
%hold on
%plot(Time, moving*150);
x=diff(moving);
figure(1)
plot(x);
start=find(x>0);
finish=find(x<0);
figure(2)
plot(Velocity);
hold on
plot(Time, moving*150);
%tr=2;
trln=max(finish-start);
trln=trln-10;
ntr=length(start);
%Preloacation of variables
%
% vel=nan(trln,ntr);
% pos=nan(trln,ntr);
% tor=nan(trln,ntr);
% EMG1=nan(trln,ntr);
% EMG2=nan(trln,ntr);
% EMG3=nan(trln,ntr);
% EMG4=nan(trln,ntr);
% EMG5=nan(trln,ntr);
vel={};
pos={};
tor={};
EMG1={};
EMG2={};
EMG3={};
EMG4={};
EMG5={};
for tr=1:ntr
vel{tr}=Velocity(start(tr):finish(tr));
pos{tr}=Position(start(tr):finish(tr));
tor{tr}=Torque(start(tr):finish(tr));
EMG1{tr}=RFd(start(tr):finish(tr));
EMG2{tr}=RFp(start(tr):finish(tr));
EMG3{tr}=VM(start(tr):finish(tr));
EMG4{tr}=BiFem(start(tr):finish(tr));
EMG5{tr}=SM(start(tr):finish(tr));
end
for tr=1:ntr-1
bounds=[start(tr)-prewindow:finish(tr)+postwindow];
pos{tr}=Position(bounds);
vel{tr}=Velocity(bounds);
tor{tr}=Torque(bounds);
EMG1{tr}=RFd(bounds);
EMG2{tr}=RFp(bounds);
EMG3{tr}=VM(bounds);
EMG4{tr}=BiFem(bounds);
EMG5{tr}=SM(bounds);
end
%Time vector position,velocity and torque
for tr=1:ntr-1
lengthtr=finish(tr)-start(tr);
t{tr}=-prewindow:1:lengthtr+postwindow;
end
Risposte (2)
If one signal is measured with 1000 Hz and another with 2000 Hz, it is trivial to determine timepoints of the first one in the time frame of the second one:
time_2000Hz = (time_1000Hz - 1) * 2 + 1
This should allow you to convert the intervals of interest.
3 Commenti
Kiran Isapure
il 18 Gen 2023
Jan
il 20 Gen 2023
@Kiran Isapure: I do not see, that you have considered my advice to scale the time for the EMG data anywhere in the code.
Your code looks strange:
for tr=1:ntr
vel{tr}=Velocity(start(tr):finish(tr));
pos{tr}=Position(start(tr):finish(tr));
...
end
for tr=1:ntr-1
bounds=[start(tr)-prewindow:finish(tr)+postwindow];
pos{tr}=Position(bounds);
vel{tr}=Velocity(bounds);
...
end
Why do you overwrite vel and pos for the elements 1:ntr-1 ?
By the way, [a:b] is exactly the same as a:b, but the latter is slightly faster. [ and ] is Matlab's operator for concatenation. [a:b] concates the vector a:b with nothing.
Note that
bounds=[start(tr)-prewindow:finish(tr)+postwindow];
pos{tr}=Position(bounds);
is slower than:
a = start(tr)-prewindow;
b = finish(tr)+postwindow;
pos{tr}=Position(a:b);
In this code the index vector a:b is not created explicitly, but Matlab copies the block of memory directly. Aftzer creating the index vector at first, Matlab has to check each element, if it is inside the bounds of the array. This take a lot of processing time.
Kiran Isapure
il 20 Gen 2023
Star Strider
il 18 Gen 2023
0 voti
Retain the original signal of course, since the 2kHz sampling frequency has data you do not want to discard.
I would not upsample the 1kHz data, because that creates interpolated data where none previously existed.
14 Commenti
Kiran Isapure
il 18 Gen 2023
Star Strider
il 18 Gen 2023
I would downsample the EMG data however only for the purpos of comparing it with the instrumentation signal. I would not discard the EMG signal if that is part of the experimental design.
‘How would I retain and index position where the relflex starts.’
I am not certain because I do not have your data and I have no idea what your experimental design is. If there are timestamps on both signals, you could use the timestamps. The best (and in my opinion most robust) option would be to use the timestamps and data to create timetable arrays for each (instrumentation and EMG) signal, and then use synchronize or retime (or both) to work with the data. You would likely need to use interpolation of some sort to define the appropriate times for each signal..
.
Kiran Isapure
il 18 Gen 2023
Spostato: Star Strider
il 18 Gen 2023
Star Strider
il 18 Gen 2023
Spostato: Star Strider
il 18 Gen 2023
I cannot help without your data (and I am not certain I could help if I had it if I do not understand what you want to do and your experimental design).
Kiran Isapure
il 18 Gen 2023
Star Strider
il 18 Gen 2023
I have no way of determining how well that works (or if it works) without the data it is used with.
Kiran Isapure
il 19 Gen 2023
Kiran Isapure
il 19 Gen 2023
Before I go any farther just now, I note that the the row size of the Position vector is not the same as the row size of the Velocity vector. I assume they should be the same.
How were they calculated?
What should I do with the size information?
I assume that the instrumentation signals were sampled at 1kHz and the EMG at 2kHz, so I’m using those to construct the time vectors for each.
What else do I need to know about these signals?
LD1 = load(websave('Position','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1268180/Position.mat'))
Pos = LD1.Pos;
LD2 = load(websave('Velocity','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1268185/Velocity.mat'))
vel = LD2.vel;
LD3 = load(websave('EMG','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1268190/EMG.mat'))
ALLEMG = LD3.ALLEMG;
return
FsInst = 1E+3;
LInst = 1;
FsEMG = 2E+3;
LEMG = size(EMG,1);
t1 = linspace(0, LInst-1, Linst)/FsInst; % Instrumentation Time Vector
t2 = linspace(0, LEMG-1, LEMG)/FsEMG; % Instrumentation Time Vector
return
%% postprocessEMG
%% Find Region of Intrest(ROI) limits and shift position to start at 0 when ROI starts
%find index where time = 0 (ROI starts)
time_0 = cellfun(@(time_2000Hz) find(time_2000Hz == 0), time_2000Hz, 'UniformOutput',false);
%position when ROI starts
for tr=1:ntr-1
position_0(:,tr) = pos{tr}(1:time_0{tr});
end
%% cell to martix for pos
maxRows = 1;
for xx = 1:length(pos)
if length(pos{xx}) > maxRows
maxRows = length(pos{xx});
end
end
Pos= nan(maxRows,length(pos)); %make NaN array
%loop through your cell array and paste data into NaN array
for yy = 1:length(pos)
Pos(1:length(pos{yy}),yy) = pos{yy};
end
%% shift position to start at 0 when ROI starts
for tr=1:ntr-1
b1(:,tr)= Pos(tr) - position_0(:,tr);
end
%% EMG activation threshold
%create vector of logicals flagging baseline window based on time column
baselineROI=cellfun(@(time_2000Hz) time_2000Hz>=-1000 & time_2000Hz<0, time_2000Hz, 'UniformOutput', false);
%create array with baseline window from EMG stretched column
for tr=1:ntr-1
ebaseline(:,tr) = Rec_filtered_data{tr}(baselineROI{tr});
end
%find mean baseline EMG
for tr=1:ntr-1
ebaseline_mean(:,tr) = mean(ebaseline(tr));
end
%calculate baseline EMG threshold value (mean baseline EMG + 2.5 SD)
STD=std(ebaseline);% STD
for tr=1:ntr-1
ethreshold(:,tr) = (ebaseline_mean(:,tr) + 2 * STD(:,tr));
end
%% Cell to matrix
%loop through to find the largest data set in your cell array
maxRows = 1;
for xx = 1:length(Movav_data)
if length(Movav_data{xx}) > maxRows
maxRows = length(Movav_data{xx});
end
end
Movav= nan(maxRows,length(Movav_data)); %make NaN array
%loop through your cell array and paste data into NaN array
for yy = 1:length(Movav_data)
Movav(1:length(Movav_data{yy}),yy) = Movav_data{yy};
end
%% EMG onset and Offset
for tr=1:10
activation(:,tr)= find(Movav(:,tr) >= ethreshold(:,tr),1,"First");
deactivation(:,tr)= find(Movav(:,tr) >= ethreshold(:,tr),1,"Last");
end
%time index where EMG moving average first increases and decreases over threshold
for tr=1:10
activation_time(:,tr) = time_2000Hz{tr}(activation(:,tr));
end
for tr=1:10
deactivation_time(:,tr)=time_2000Hz{tr}(deactivation(:,tr));
end
% EMG Burst duration
burst_time = deactivation_time - activation_time;
figure(11)
bar(burst_time);
%find EMG activation index
for i=1:10
activation_time_index(i) = find(Rec_filtered_data{i} >= activation_time(:,tr),1,'first');
end
%%position where EMG first increases over threshold
for i=1:10
activation_position(i) = b1(activation_time_index(:,i),1);
end
Kiran Isapure
il 20 Gen 2023
Modificato: Jan
il 20 Gen 2023
@Kiran Isapure: Please use the tools above the section for typing comments to format code as code. This improves the readability.
Explain "not working" with any details. It is easier to fix a problem than to guess, what the problem is.
I atill cannot run the posted code.
See the error message —
LD1 = load(websave('Position','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1268180/Position.mat'))
Pos = LD1.Pos;
LD2 = load(websave('Velocity','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1268185/Velocity.mat'))
vel = LD2.vel;
LD3 = load(websave('EMG','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1268190/EMG.mat'))
ALLEMG = LD3.ALLEMG;
% return
FsInst = 1E+3;
LInst = 1;
FsEMG = 2E+3;
LEMG = size(ALLEMG,1);
t1 = linspace(0, LInst-1, LInst)/FsInst; % Instrumentation Time Vector
t2 = linspace(0, LEMG-1, LEMG)/FsEMG; % Instrumentation Time Vector
% return
%% postprocessEMG
%% Find Region of Intrest(ROI) limits and shift position to start at 0 when ROI starts
%find index where time = 0 (ROI starts)
time_0 = cellfun(@(time_2000Hz) find(time_2000Hz == 0), time_2000Hz, 'UniformOutput',false);
%position when ROI starts
for tr=1:ntr-1
position_0(:,tr) = pos{tr}(1:time_0{tr});
end
%% cell to martix for pos
maxRows = 1;
for xx = 1:length(pos)
if length(pos{xx}) > maxRows
maxRows = length(pos{xx});
end
end
Pos= nan(maxRows,length(pos)); %make NaN array
%loop through your cell array and paste data into NaN array
for yy = 1:length(pos)
Pos(1:length(pos{yy}),yy) = pos{yy};
end
%% shift position to start at 0 when ROI starts
for tr=1:ntr-1
b1(:,tr)= Pos(tr) - position_0(:,tr);
end
%% EMG activation threshold
%create vector of logicals flagging baseline window based on time column
baselineROI=cellfun(@(time_2000Hz) time_2000Hz>=-1000 & time_2000Hz<0, time_2000Hz, 'UniformOutput', false);
%create array with baseline window from EMG stretched column
for tr=1:ntr-1
ebaseline(:,tr) = Rec_filtered_data{tr}(baselineROI{tr});
end
%find mean baseline EMG
for tr=1:ntr-1
ebaseline_mean(:,tr) = mean(ebaseline(tr));
end
%calculate baseline EMG threshold value (mean baseline EMG + 2.5 SD)
STD=std(ebaseline);% STD
for tr=1:ntr-1
ethreshold(:,tr) = (ebaseline_mean(:,tr) + 2 * STD(:,tr));
end
%% Cell to matrix
%loop through to find the largest data set in your cell array
maxRows = 1;
for xx = 1:length(Movav_data)
if length(Movav_data{xx}) > maxRows
maxRows = length(Movav_data{xx});
end
end
Movav= nan(maxRows,length(Movav_data)); %make NaN array
%loop through your cell array and paste data into NaN array
for yy = 1:length(Movav_data)
Movav(1:length(Movav_data{yy}),yy) = Movav_data{yy};
end
%% EMG onset and Offset
for tr=1:10
activation(:,tr)= find(Movav(:,tr) >= ethreshold(:,tr),1,"First");
deactivation(:,tr)= find(Movav(:,tr) >= ethreshold(:,tr),1,"Last");
end
%time index where EMG moving average first increases and decreases over threshold
for tr=1:10
activation_time(:,tr) = time_2000Hz{tr}(activation(:,tr));
end
for tr=1:10
deactivation_time(:,tr)=time_2000Hz{tr}(deactivation(:,tr));
end
% EMG Burst duration
burst_time = deactivation_time - activation_time;
figure(11)
bar(burst_time);
%find EMG activation index
for i=1:10
activation_time_index(i) = find(Rec_filtered_data{i} >= activation_time(:,tr),1,'first')
end
%%position where EMG first increases over threshold
for i=1:10
activation_position(i) = b1(activation_time_index(:,i),1)
end
.
Kiran Isapure
il 20 Gen 2023
Star Strider
il 20 Gen 2023
The error:
Unrecognized function or variable 'time_2000Hz'.
is still unresolved, so I can’t run the code!
Categorie
Scopri di più su Data Import and Analysis in Centro assistenza e File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!