0

I have a question regarding findpeaks. I want to use it to detect peaks in my signal time series (Signal 1). This works fine, but I also have surrogate data, serving as a threshold of significance, of equal length (Signal 2). I now want to use findpeaks on Signal 1, but only if Signal 1 is greater then Signal 2 at that timepoint. I tried to use the regular properties of findpeaks but nothing worked so far...Here is what I have right now:

GPDC is a 9x9x512 double. Dim 1 contains partial directed coherence values estimated through a multi-variate autoregressive model in direction xi - xj, Dim 2 contains the same for xj -xi and Dim 3 represents the number of frequency bins. eEPDCsth is a 9x9x512 double containing the corresponding surrogate data. f is a 1x512 double containing the frequency values. I think right now, the >= reference isn't working, because it is not time-specific, i.e. it does not compare the signal point by point but rather in total. This is my main problem I think...

Sz=9;
for i=1:Sz
    for j=1:Sz
    if squeeze(GPDC(i,j,:)) >= squeeze(eEPDCsth(i,j,:))
       [pks_1{i,j},locs_1{i,j}] = findpeaks(squeeze(GPDC(i,j,:)),f,'npeaks',5,'MinPeakHeight', .1);
    end
    end
end
Tydur
  • 3
  • 5

2 Answers2

1

Not sure if I have understood the question correctly. From your code it is clear that you have data for peaks and the co-ordinates at which these peaks occur.

If you want only the peaks where your second time series has lower value, "just loop through all the peaks - check if the peak(i) value is lower than value of second series at locs(i) - remove the peaks that are lower than value of second series at same locs".

Hope this helps.

Mayank Kumar Chaudhari
  • 16,027
  • 10
  • 55
  • 122
1

Here is an example that should accomplish what you have described. You didn't specify the actual contents of the 'f' vector, so I've set it to 1:512 for this example

% data for testing
GPDC = rand(9,9,512);
eEPDCsth = rand(9,9,512);
f = 1:512; % the value of the 'f' vector wasn't specified in question

Sz=9;
for i=1:Sz
    for j=1:Sz
        % find the 'raw' peaks below thresholding
        [peak_val_raw, peak_indices_raw] = findpeaks(squeeze(GPDC(i,j,:)),'npeaks',5,'MinPeakHeight', .1);

        % only keep peaks that are above the corresponding threshold value
        peaks_above_threshold = squeeze(GPDC(i,j,peak_indices_raw)) > squeeze(eEPDCsth(i,j,peak_indices_raw));
        peak_values_thresholded = peak_val_raw(peaks_above_threshold);
        peak_indices_thresholded = peak_indices_raw(peaks_above_threshold);

        pks_1{i,j} = peak_values_thresholded;
        % index into 'f' vector to match code in original question
        locs_1{i,j} = f(peak_indices_thresholded); 

    end
end
DMR
  • 1,479
  • 1
  • 8
  • 11
  • Hey, thanks a lot. I tried it out, but isn't the ‘f‘ vector missing in the findpeaks function? Since I want to also specify frequency ranges in findpeaks... – Tydur Oct 14 '18 at 17:38
  • If the 'f' vector (what the MATLAB docs for findpeaks calls the 'location vector') is specific to findpeaks, then the locations returned will be in terms of f, rather than their original indices. But here, we need to know the original indices so that we can index into both the signal and comparison datasets for the threshold comparison. The last line of the loop then indexes the positions of the values that exceeded the threshold back into the 'f' vector. – DMR Oct 15 '18 at 13:03