Signal Analysis
%% BMES 202: Code 7_1 %% CODE function [data, emg_labels] = ca07_fun1(txt_file) %% 1. If the file name is not provided by the user, prompt the user to select a file, the program should %'remember' the previous user selection if nargin<1 if ~exist('fig1','var') fig1=figure; set(fig1,'filename','DEFAULT.txt'); end [fnm,pth]=uigetfile('*.txt','Choose a File',get(fig1,'filename')); txt_file=fullfile(pth,fnm); end %% 2. Read data into the function (data) data=load(txt_file); set(fig1,'userdata',data); %% 3. Read the header line and get the labels (emg_labels) for the EMG signals tfid=fopen(txt_file); tline=fgetl(tfid); fclose(tfid); emg_labels=regexp(tline,'\t','split'); %% 4. In figure 1, create a subplot for each muscle, and plot emg (y) versus time (x) (as ALWAYS label % your axes & ALL subplots must have the SAME y limits) figure(fig1) subplot(2,2,1) plot(data(:,1),data(:,2)) xlabel('Time (s)') ylabel('Masseter (mV)') title('Masseter Muscle') subplot(2,2,2) plot(data(:,1),data(:,3)) xlabel('Time (s)') ylabel('Biceps (mV)') title('Biceps Muscle') subplot(2,2,3) plot(data(:,1),data(:,4)) xlabel('Time (s)') ylabel('Quadriceps (mV)') title('Quadriceps Muscle') subplot(2,2,4) plot(data(:,1),data(:,5)) xlabel('Time (s)') ylabel('Abdominals (mV)') title('Abdominals Muscle') axH = findall(gcf,'type','axes'); set(axH,'ylim',[-.5 .5]); %% 5. Title the plot with the name of the file (strip the path) suptitle(fnm) end %% BMES 202: Code 7_2 %% CODE function [dtF] = ca07_fun2(data, filt_opts) %% 1. If the user does not provide filter options (filt_opts), you must prompt the user to input the low- %pass filter stop frequency (Hz) [F_stop], and the sub-sampling rate (Hz) %[F_ss]. if ~exist('filt_opts','var') if ~exist('fig2','var') fig2=figure; inp=inputdlg({'Choose the Pass Filter Stop Frequency (Hz)','Choose the sub-sampling rate (Hz)'},'Enter Information',1,{'0.5','2'}); inpn(1)=str2num(inp{1}); inpn(2)=str2num(inp{2}); set(fig2,'userdata',inpn); end filt_opts=get(fig2,'userdata'); end %% 7. Remove any 'bias' from the signal (detrend) dt=detrend(data(:,2:5)); %% 8. Create a 5th order low-pass butterworth filter (butter) using the stop-frequency from filt_opts [b,a]=butter(5,filt_opts(1)/filt_opts(2)); %% 9. Apply filter to detrended data (filter) dtf=filter(b,a,dt); %% 10. Down-sample the filtered data (downsample), based on the sub-sample frequency from filt_opts dtfd=downsample(dtf,filt_opts(2)); dtft=downsample(data(:,1),filt_opts(2)); dtF=[dtft dtfd]; %% 11. In figure 2, create a subplot of time versus each filtered/sub-sampled emg signal (be sure to label %axes with the emg labels figure(fig2) subplot(4,1,1) plot(dtF(:,1),dtF(:,2)) ylabel('Masseter (mV)') subplot(4,1,2) plot(dtF(:,1),dtF(:,3)) ylabel('Biceps (mV)') subplot(4,1,3) plot(dtF(:,1),dtF(:,4)) ylabel('Quadriceps (mV)') subplot(4,1,4) plot(dtF(:,1),dtF(:,5)) xlabel('Time (s)') ylabel('Abdominals (mV)') suptitle('Time vs Each Filtered/Sub-Sampled EMG Signal') end %% BMES 202: Code 7_3 %% CODE function [dtS, dt_sum] = ca07_fun3(dtF, sp_opts) % Based on the input data (dtF [Mx5]) and the spectral % options (sp_opts [1x2]), this function should calculate the spectral power, display the results in figure 3, % and output a summary of the key spectral parameters (dt_sum [4x5]). %% 12. If the user does not provide spectral options (sp_opts), you must prompt the user to input the ... minimum tremore frequency (Hz) [F_min], and the maximum tremor frequency (Hz) [F_max]. !!!!! ... The program MUST remember what the user input last time.!!!!! (Hint, you can store and retrieve ... information from figure 2 object). if ~exist('sp_opts','var') if exist('Hfig2','var') [F_min,F_max]=get(Hfig2,'data'); else answers=inputdlg({'F_min','F_max'},'Please select Spectral Powers',1,{'20','20'}); end end %% 13. Determine the sampling frequency (Fs) using nqist, and using a frequency resolution of 1.0 Hz (frq_res), ... determine the number of frequencies (Nfrq = 2*Fs/frq_res, must be an INTEGER) frq_res=1; Fs = 1/mean(diff(dtF(:, 1))); %Frequency is the inverse of the period Nfrq = 2*Fs/frq_res; %% 14.Loop through all EMG signals, and calculate the spectral power (yP) (periodogram(dtF(:,i), [], ... 'onesided', Nfrq, Fs)) ... 14. Loop through all EMG signals, and calculate the spectral power (yP) ... (periodogram(dtF(:,i), [], 'onesided', Nfrq, Fs)) for i=2:5 % for all of the muscle groups [yP(:,i), Frq(:,i)] = periodogram(dtF(:,i), [], 'onesided', Nfrq, Fs); % run a periodogram and store the spectral powers in yP and frequencies % in frq end %% 15. Determine max spectral power and frequency of max spectral power for ... each signal [dtS, ind] = max(yP); % the max yP for each column is stored in dtS Frq_max = Frq(ind);% the maximum frequency is found at the indices %% 16.Calculate the cumulative spectral power (cumtrapz) (cP) for i=2:5 cP(:,i)=cumtrapz(Frq(:,i),yP(:,i)); end %% 17. ...Loop through emg signals, and calculate the percentage of cumulative spectral power (cPp), and ...determine the cPp at the F_min and F_max (interp1), as well as the frequency at 50% cPp ...(interp1) s=length(cP); for I=2:5 for i=1:s(1) cPp(i,I)=(cP(i,I)./cP(s(1),I))*100; end [F_max(I),F_maxi(I)]=max(Frq(:,I)); [F_min(I),F_mini(I)]=min(Frq(:,I)); cPp_fmax(I)=interp1(Frq(:,I),cPp(:,I),F_max(I)); cPp_fmin(I)=interp1(Frq(:,I),cPp(:,I),F_min(I)); cPp50(I)=interp1(Frq(:,I),cPp(:,I),50); f50(I)=interp1(cPp(:,I),Frq(:,I),50); end %% 18. In figure 3, in subplot1, plot freq (x) versus spectral power (y) for all emg signals (add legend, and ... use '.-' for the line style). Hfig3 = findobj('tag','spectral power'); if(isempty(Hfig3)); Hfig3 = figure('tag','spectral power'); end subplot(2,1,1); plot(Frq,yP,'-'); xlim([0 100]); ylim([0 0.0004149]); title('Frequency vs Spectral Power'); xlabel('Frequency'); ylabel('Spectral Power'); legend('Frequency vs Spectral Power'); grid on; %% 19. In figure 3, subplot2, plot freq (x) versus percentage cumulative spectral power (y), subplot(2,1,2); plot(Frq,cPp,'-'); hold on %and overlay the min/max tremor frequencies plot(F_min,F_max); %needs fixing hold off xlim([0 100]); ylim([0 200]); title('Frequency vs Percentage cumulative spectral power'); xlabel('Frequency'); ylabel('Percentage cumulative spectral power'); legend('Frequency vs Percentage cumulative spectral power', 'Min tremor frequencies','Max tremor frequencies'); grid on; %% 20.Summary output should contain: % 1. Freq at Max SP % 2. Max SP % 3. freq at 50% CSP % 4. 50% CSP % 5. fmin_tremor % 6. %CSP at fmin_tremor % 7. fmax_tremor % 8. %CSP at fmax_tremor % 9. %CSP between fmax_tremor and fmin_tremor new_mat=[Frq_max;dtS;f50;cPp50;F_min;cPp_fmin;F_max;cPp_fmax;[cPp_fmax-cPp_fmin]]; dt_sum=(new_mat(:,2:end))' return; %% BMES 202: Code 7_4 %% CODE %function ca07_fun4; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% Master script, which calls functions 1-3 %% and formats the results %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %--- read EMG data clear dt1 emg_lbls [dt1, emg_lbls] = ca07_fun1; %--- filter EMG data clear dtF dtF = ca07_fun2(dt1); %-- spectral analysis clear dtP dt_sum [dtP, dt_sum] = ca07_fun3(dtF); %% Format output %-- get filename from figure 1 handle clear hfig1 txt_file t_pth t_fnm t_ext hfig1 = findobj('tag','EMG-data'); txt_file = get(hfig1,'filename'); %--- strip path [t_pth,t_fnm,t_ext]=fileparts(txt_file); %% Summarize output clear out_txt out_txt(1,1) = {sprintf('%%File:\t%s',[t_fnm,t_ext])}; out_txt(2,1) = {sprintf(['%%Muscle\t', ... 'fmx(Hz)\tPmx()\t', ... 'f50(Hz)\tCSP_50()\t', ... 'f1(Hz)\tcPf1(%%)\t', ... 'f2(Hz)\tcPf2(%%)\t', ... 'cP_rng(%%)'])}; for(i=1:length(emg_lbls)) out_txt(i+2,1) = {sprintf(['%s\t', ... '%.1f\t%.2e\t', ... '%.1f\t%.2e\t', ... '%.1f\t%.1f\t', ... '%.1f\t%.1f\t', ... '%.1f'], ... char(emg_lbls(i)), ... dt_sum(i,:))}; end %--- display to screen disp(char(out_txt)); return;
RESULTS
%% MHOMO KADIRI (c)2014











