Peak detection and feature extraction from multiple CSV files
2 views (last 30 days)
Show older comments
Hi everyone,
I am collecting accelerometer data and my purpose is to detect all peaks, then calculate/plot acceleration, velocity, displacement, power and work for each peak-to-peak interval. Data is collected at 3 different tempos - 60, 120 and 180 which correspond to a frequency of 1, 2 and 3 Hz respectively.
I have the code sorted for detecting all peaks within the CSV file, but due to different frequencies the same options specified within findpeaks() don't allow me to select the correct number of peaks for each frequency. I therefore split the dataset into 3 separate time intervals which allowed me to use the appropriate options for findpeaks() in each situation. My code works and it allows me to calculate acceleration, velocity, displacement, power and work for each interval. However, I need to do everything 3x since I have 3 different frequencies which clutters the code, adds lots of variables to the workspace and may not be ideal.
Questions:
1) Is there a way to write a loop or something similar so I only have one code section that does acceleration for all frequencies, velocity for all frequencies and so forth? I've had a look on the forums but I couldn't find anything to help me with this.
2) I will have more files when the data collection is finished; is there is a way to do all of the above only once rather than e.g. 10 times, once for each CSV file?
3) This is just one file, and if new files have the same frequencies contained in the same intervals and the same findpeaks() options identify the correct peaks, then that's fantastic. If that's not the case however, would my needs bee better served by creating a metadata file (CSV? something else?) containing the participant, filepath to accelerometer data, time points and frequencies with associated findpeaks() options? I've done some reading on timetables and datastores but I'm not sure what would be best.
Sorry in advance for asking 3 questions at once, but I felt they were linked hence it made sense to put them together. Happy to split and ask separately if that;s not the case! Code added below, data file attached.
Evelyn :)
% ---------------------------------------
% Import and clean data from CSV file
% ---------------------------------------
opts = delimitedTextImportOptions("NumVariables", 22);
% Specify range and delimiter
opts.DataLines = [2, Inf];
opts.Delimiter = ",";
opts.SelectedVariableNames = opts.SelectedVariableNames([1:22]);
% Specify column names and types
opts.VariableNames = ["Time", "LogSample_N", "locationTimestamp_since1970s", "locationLatitudeWGS84", "locationLongitudeWGS84", "locationAltitudem", "locationSpeedms", "locationCourse", "locationVerticalAccuracym", "locationHorizontalAccuracym", "locationFloorZ", "locationHeadingTimestamp_since1970s", "locationHeadingXT", "locationHeadingYT", "locationHeadingZT", "locationTrueHeading", "locationMagneticHeading", "locationHeadingAccuracy", "accelerometerTimestamp_sinceReboots", "Acceleration_XG", "Acceleration_YG", "Acceleration_ZG"];
opts.VariableTypes = ["datetime", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double", "double"];
% Specify file level properties
opts.ExtraColumnsRule = "ignore";
opts.EmptyLineRule = "read";
opts.ConsecutiveDelimitersRule = "join";
opts.LeadingDelimitersRule = "ignore";
% Specify variable properties
opts = setvaropts(opts, "Time", "Suffixes", "+0100"); % Remove +0100 at the end of datetime
opts = setvaropts(opts,'Time','InputFormat','yyyy-MM-dd HH:mm:ss.SSS', 'DatetimeFormat', 'HH:mm:ss.SSS' ); % Specify datetime format
% Import the data
Data = readtable("/Users/windsnowflake/OneDrive - University College London/1st Year/2nd Rotation/Data analysis/Trial project/Trial data/t8.csv", opts);
Data = removevars (Data, {'LogSample_N', 'locationTimestamp_since1970s', 'locationLatitudeWGS84', 'locationLongitudeWGS84', 'locationAltitudem', 'locationSpeedms', 'locationCourse', 'locationVerticalAccuracym', 'locationHorizontalAccuracym', 'locationFloorZ', 'locationHeadingTimestamp_since1970s', 'locationHeadingXT', 'locationHeadingYT', 'locationHeadingZT', 'locationTrueHeading', 'locationMagneticHeading', 'locationHeadingAccuracy', 'accelerometerTimestamp_sinceReboots'});
Data = removevars (Data, {'Acceleration_XG', 'Acceleration_YG'}); % I only need Z axis for this
% Clean temporary variables
clear opts
% Create elapsed time variable
Elapsed_Time = Data.Time - Data.Time(1);
% Add to table
Data = addvars(Data, Elapsed_Time, 'Before', 'Acceleration_ZG');
% Clean temporary variable
clear Elapsed_Time
% ---------------------------------------
% Visualise data with annotated peaks
% ---------------------------------------
% Convert table columns to arrays
Acceleration = table2array(Data(:,3));
Time = table2array(Data(:,2));
Time = seconds(Time); % Convert Elapsed_Time from duration to double
% Specify each time interval
int_1 = [0, 25];
idx1 = find((Time >= int_1(1)) & (Time <= int_1(2)));
int_2 = [25, 45];
idx2 = find((Time >= int_2(1)) & (Time <= int_2(2)));
int_3 = [45, 60];
idx3 = find((Time >= int_3(1)) & (Time <= int_3(2)));
% Determine Peaks & Indices @ each time interval using specific options
[a_pks1, a_locs1] = findpeaks(Acceleration(idx1), 'MinPeakHeight', 0.3, "MinPeakProminence", 0.1, "MinPeakDistance", 110);
[a_pks2, a_locs2] = findpeaks(Acceleration(idx2), 'MinPeakHeight', 0.5, "MinPeakProminence", 0.1, "MinPeakDistance", 70);
[a_pks3, a_locs3] = findpeaks(Acceleration(idx3), 'MinPeakHeight', 1.0, "MinPeakProminence", 0.1, "MinPeakDistance", 70);
% Adjust a_locs to correct for offset
adjlocs_1 = a_locs1 + idx1(1)-1;
adjlocs_2 = a_locs2 + idx2(1)-1;
adjlocs_3 = a_locs3 + idx3(1)-1;
% Plot the data
figure()
plot(Time, Acceleration)
hold on
% Add the peaks for each interval
plot(Time(adjlocs_1), a_pks1, 'rd')
plot(Time(adjlocs_2), a_pks2, 'gd')
plot(Time(adjlocs_3), a_pks3, 'bd')
hold off
grid
set(gca,'FontSize', 12)
title('Pilot data', 'FontSize', 18)
xlabel('Time (seconds)')
ylabel('Acceleration (G)')
% ---------------------------------------
% Visualise data as separate frames
% ---------------------------------------
% Create for loop to store frames of acceleration over time data - 1st interval
for k1 = 1 : numel(adjlocs_1)-1 % From the 1st peak (1) to the penultimate peak (a_locs-1)
a1{k1} = Acceleration(adjlocs_1(k1) : adjlocs_1(k1+1)); % Store all acceleration data from current peak to the next in a cell
t1{k1} = Time(adjlocs_1(k1) : adjlocs_1(k1+1)); % Store all time data from current peak to the next in a cell
end
% Plot all frames - 1st interval
figure()
hold all
for k1 = 1:numel(a1)
plot(t1{k1}-t1{k1}(1), a1{k1})
xlim([0,1.6])
set(gca,'FontSize', 12)
title('Acceleration over Time - 1st', 'FontSize', 18)
xlabel('Time (seconds)')
ylabel('Acceleration (G)')
end
hold off
grid
% Create for loop to store frames of acceleration over time data - 2nd interval
for k2 = 1 : numel(adjlocs_2)-1 % From the 1st peak (1) to the penultimate peak (a_locs-1)
a2{k2} = Acceleration(adjlocs_2(k2) : adjlocs_2(k2+1)); % Store all acceleration data from current peak to the next in a cell
t2{k2} = Time(adjlocs_2(k2) : adjlocs_2(k2+1)); % Store all time data from current peak to the next in a cell
end
% Plot all frames - 2nd interval
figure()
hold all
for k2 = 1:numel(a2)
plot(t2{k2}-t2{k2}(1), a2{k2})
xlim([0,1.6])
set(gca,'FontSize', 12)
title('Acceleration over Time - 2nd', 'FontSize', 18)
xlabel('Time (seconds)')
ylabel('Acceleration (G)')
end
hold off
grid
% Create for loop to store frames of acceleration over time data - 3rd interval
for k3 = 1 : numel(adjlocs_3)-1 % From the 1st peak (1) to the penultimate peak (a_locs-1)
a3{k3} = Acceleration(adjlocs_3(k3) : adjlocs_3(k3+1)); % Store all acceleration data from current peak to the next in a cell
t3{k3} = Time(adjlocs_3(k3) : adjlocs_3(k3+1)); % Store all time data from current peak to the next in a cell
end
% Plot all frames - 3rd interval
figure()
hold all
for k3 = 1:numel(a3)
plot(t3{k3}-t3{k3}(1), a3{k3})
xlim([0,1.6])
set(gca,'FontSize', 12)
title('Acceleration over Time - 3rd', 'FontSize', 18)
xlabel('Time (seconds)')
ylabel('Acceleration (G)')
end
hold off
grid
0 Comments
Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!