Message Boards Message Boards

0
|
4439 Views
|
10 Replies
|
1 Total Likes
View groups...
Share
Share this post:

Eliminating peaks too close

Posted 3 years ago

Hi

I am working on a 1D (nice) data-set and trying to find its peaks. It picked 2 peaks (121th and 123th data points) due to obvious noises. I am only looking for a rough (not accurate, whichever of the two) location of the peak, but not like to get 2 peak locations. How could I: 1) Set the FindPeaks parameter so it will only find 1 peak? or 2) After get a list of peaks, how could I eliminate close ones among 5-10 peak resulted points?

Raw data and curve images are attached.

Many thanks.

Xiaxing Xiong

Attachment

POSTED BY: Xiaxing Xiong
10 Replies
Posted 3 years ago

A simple peak finder

findPeaks[list_] := (list // BlockMap[(#[[1]] < #[[2]] > #[[3]] &), #, 3, 1] & // Position[True]) + 1

On Mike's sample data

peaks = findPeaks@data;
values = Extract[data, peaks];

ListPlot[{data, Transpose[{Flatten@peaks, values}]}, 
 PlotStyle -> {Automatic, Red}]

enter image description here

POSTED BY: Rohit Namjoshi

Welcome to Wolfram Community!
Please make sure you know the rules: https://wolfr.am/READ-1ST
Your post is too vague. Please describe your subject extensively providing code.

POSTED BY: Moderation Team
Posted 3 years ago

Please post the code you used to generate the plot. There are no negative values in Example.txt but the plot in OSC-Signal.jpg has negative values.

POSTED BY: Rohit Namjoshi
Posted 3 years ago

The following in my code:

DATA1 = -DATA[[400 ;; 599, All]];
ListPlot[DATA1[[All, 3]], 
 PlotRange -> {{100, 130}, {-0.0000024, -0.0000018
    }}]
FindPeaks[DATA1[[All, 3]], 5][[All, 1]]

The data I attached before is the DATA1 I am looking for peaks of this data set. The result it gives is {121,123}. The peaks found were too close. I just need one of them, whichever one. Could I change the parameter of the FindPeaks so that it will give only one peak?

Thanks

Xiaxing

POSTED BY: Xiaxing Xiong
Posted 3 years ago

Hi Rohit

Sorry the data is positive, and I am looking for the bottom position. So I multiply it with (-1) and looking for the peaks instead

Thanks for looking into my problem.

Xiaxing

POSTED BY: Xiaxing Xiong
Posted 3 years ago
POSTED BY: Jim Baldwin
Posted 3 years ago

Without a better understanding of your requirements, I think something like this might work:

data = {100, 3, 2, 103, 102, 5, 4, 2, 105, 104, 103, 3};

findPeaks[ data_List, tolerance_List] := Module[
   {
    peaks = FindPeaks[data]
    , lastPeak = {-Infinity, -Infinity}
    , forward
    , reverse
    },
   forward = Map[
     With[
       {
        retVal = If[
          And[
           First[#1] -  First[lastPeak] <= tolerance[[1]],
           Last[#1] - Last[lastPeak] <= tolerance[[2]]
           ]
          ,
           Nothing
          ,
          #1
          ]
        }
       ,
       lastPeak = #1
       ] &
     ,
     peaks
     ];


   reverse = Map[
     With[
       {
        retVal = If[
          And[
           First[#1] -  First[lastPeak] <= tolerance[[1]],
           Last[#1] - Last[lastPeak] <= tolerance[[2]]
           ]
          ,
           Nothing
          ,
          #1
          ]
        }
       ,
       lastPeak = #1
       ] &
     ,
     Reverse[forward]
     ];

   Reverse[reverse]

   ];

findPeaks[data, {3, 3}]
POSTED BY: Mike Besso
Posted 3 years ago

The data I attached before is the DATA1

Example.txt only has 2 columns so, it cannot be DATA1 because this would not work

ListPlot[DATA1[[All, 3]], ...
POSTED BY: Rohit Namjoshi
Posted 3 years ago

Rohit:

Thanks again for teaching me a new trick. I can see how BlockMap[] can be very useful.

POSTED BY: Mike Besso
Posted 3 years ago
POSTED BY: Updating Name
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract