(Answers Dev) Restored edit
Info
This question is locked. Reopen it to edit or answer.
Finding length of time in between peaks.
    10 views (last 30 days)
  
       Show older comments
    
I am currently working on a project involving signal processing of ECG and PPG data to calculate Pulse Transit Time (PTT). I need to determine the time between corresponding peaks in ECG and PPG signals with precision down to fractions of a millisecond. However, I'm concerned that my current method might not be providing accurate results. I would appreciate any guidance or suggestions on how to improve my calculations.
This is my code at the minute: 
clc;
clear;
close all;
All_Data = {};  % set up cell array for all workbook data
Plotted_Data_ECG_PPG = {}; % set up cell array for ECG and PPG plotted data
PTT_Data = {}; % set up cell array for PTT data
BP_Calculation = {}; % set up cell array for BP calculation
SYS_Data_single = {}; % Initialize the cell array for storing single systolic data values
DIA_Data_single = {}; % Initialize the cell array for storing single diastolic data values
collected_BP_Data = [];  
windowSize = 2;  % window size for filtering data
ecgThreshold = 0.375; % Threshold for ECG peaks
ppgThreshold = 0.1; % Threshold for PPG peaks
for i = 1:11  % set up loop to run for 11 iterations (number of workbooks)
    filename = sprintf('%03d.xlsx', i); % set up each filename (001-011) to be read on each iteration
    opt = detectImportOptions(filename); % import data from filename
    sheets = sheetnames(filename);  % retrieve names of sheets
    for j = 1:numel(sheets)  % iterate over each sheet within a workbook 
        tBC = readtable(filename, opt, 'Sheet', sheets{j});  % extract sheets from workbooks
        Time_Data = tBC{:, 'Var4'};  % extract time data from column 4
        % Remove invalid cells from time data column
        rows2delete = isnan(Time_Data);
        tBC(rows2delete,:) = [];
        Time_Data = tBC{:, 'Var4'};
        % Fit polynomial line to smooth out time data
        xx = (1:numel(Time_Data))';
        p = polyfit(xx, Time_Data, 1);
        Time_Data_new = polyval(p, xx);
        ECG_Data = tBC{:, 'Var6'};  % extract ECG data from column 6
        PPG_Data = tBC{:, 'Var8'};  % extract PPG data from column 8
        SYS_Data = tBC{:, 'Var10'};  % extract systolic pressure data from column 10
        DIA_Data = tBC{:, 'Var12'};  % extract diastolic pressure data from column 12
        % Select the first value as the single data value for SYS and DIA
        SYS_Data_single_value = SYS_Data(1);
        DIA_Data_single_value = DIA_Data(1);
        % Apply filter to ECG and PPG data
        ECG_Data_smoothed = movmean(ECG_Data, windowSize);
        PPG_Data_smoothed = movmean(PPG_Data, windowSize);
        % Normalize ECG and PPG data around 0 for accurate calculations
        ECG_Data_normalized = ECG_Data_smoothed - mean(ECG_Data_smoothed);
        PPG_Data_normalized = PPG_Data_smoothed - mean(PPG_Data_smoothed);
        % Find peaks for ECG and PPG data above thresholds
        [ecgPeaks, ecgPeakIdx] = findpeaks(ECG_Data_normalized, 'MinPeakHeight', ecgThreshold);
        [ppgPeaks, ppgPeakIdx] = findpeaks(PPG_Data_normalized, 'MinPeakHeight', ppgThreshold);
        % Calculate PTT for each pair of corresponding peaks
        numPeaks = min(length(ecgPeaks), length(ppgPeaks));
        PTT = zeros(numPeaks, 1);
        for k = 1:numPeaks
            PTT(k) = (Time_Data_new(ppgPeakIdx(k)) - Time_Data_new(ecgPeakIdx(k))) * 1000; % Convert measurement to milliseconds
        end
        % Make PTT values positive
        PTT = abs(PTT);
        % Place the PTT data in PTT_Data cell array
        PTT_Data{i, j} = PTT;
   end
end   
I would greatly appreciate any help. I have included one of the files that is being used.
1 Comment
Accepted Answer
  Star Strider
      
      
 on 12 Apr 2024
        
      Edited: Star Strider
      
      
 on 12 Apr 2024
  
      If you are having problems with it, address it there rather than opening another question.  
My problem with your file is that the ‘TIME:’ values make no sense.  I originally thought that they were fractions of a day,  and so converted them to something useful using 'ConvertFrom','datenum' however those values do not make sense.  I had to construct a millisecond vector to make the times come out even remotely realistic, however it is obvious that those are not correct.  Your code does not at all address the ‘TIME:’ vector.  
You need to provide information on the ‘TIME:’ column that permits the values to be useful.  There is no current information on how to interpret those values.  
EDIT — (12 Mar 2024 at 14:56)
I took another look at the times that I created (calculated from the ‘TIME:’ variable), and I believe they are correct, based on the calculated heart rate (that I just now added).  So my interpreting them as fractions-of-a-day and converting them as ‘datenum’ representations appears to be correct.  
.
0 Comments
More Answers (0)
This question is locked.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

