1

My code is based on a comment in: Finding local maxima/minima with Numpy in a 1D numpy array

It works, however it does not reproduce all the peaks for me. It always seems to miss the first peak. Is there any way to make this code a bit more robust in determining each peak?

I have tried smoothing the data, changing the order etc to no avail.

import numpy as np
from scipy.signal import argrelextrema

profile1 = "data posted below"

profile1_filtered = ndimage.filters.gaussian_filter(profile1, 1, mode='nearest')

plot(profile1_filtered[300:740])

# for local maxima
result = argrelextrema(profile1[300:740], np.greater, order =15)

print result

for i in result:
    plot([i,i],[-16380,-16300], color='k', linestyle='--', linewidth=1)

Thanks in advance for any help/advice!

As I am in work, my upload/download is very restricted. Usually I would post a link to my data, however I hope this will do: (i will amend this with a link to my data when I get home later)

array([-16368, -16366, -16365, -16369, -16366, -16369, -16368, -16362,
       -16368, -16366, -16367, -16364, -16367, -16367, -16367, -16366,
       -16363, -16366, -16369, -16370, -16365, -16364, -16362, -16363,
       -16365, -16363, -16364, -16362, -16361, -16362, -16364, -16364,
       -16365, -16361, -16363, -16363, -16366, -16361, -16360, -16363,
       -16362, -16362, -16357, -16360, -16359, -16362, -16359, -16359,
       -16358, -16358, -16355, -16356, -16355, -16349, -16350, -16349,
       -16343, -16338, -16332, -16329, -16329, -16339, -16339, -16348,
       -16351, -16351, -16354, -16355, -16355, -16356, -16357, -16355,
       -16355, -16356, -16356, -16358, -16354, -16355, -16356, -16357,
       -16356, -16355, -16355, -16352, -16357, -16353, -16353, -16352,
       -16357, -16351, -16347, -16347, -16345, -16342, -16332, -16321,
       -16315, -16311, -16315, -16320, -16327, -16335, -16341, -16346,
       -16347, -16349, -16350, -16350, -16347, -16351, -16354, -16354,
       -16352, -16353, -16352, -16354, -16356, -16354, -16358, -16354,
       -16353, -16356, -16351, -16352, -16351, -16351, -16352, -16347,
       -16344, -16344, -16340, -16335, -16326, -16315, -16305, -16299,
       -16303, -16309, -16322, -16331, -16335, -16342, -16342, -16346,
       -16349, -16353, -16352, -16350, -16350, -16350, -16354, -16353,
       -16353, -16355, -16355, -16356, -16353, -16352, -16352, -16356,
       -16354, -16354, -16354, -16353, -16354, -16352, -16355, -16349,
       -16350, -16347, -16346, -16342, -16338, -16334, -16338, -16335,
       -16341, -16344, -16345, -16349, -16349, -16349, -16353, -16353,
       -16353, -16353, -16354, -16353, -16351, -16351, -16352, -16354,
       -16353, -16353, -16353, -16355, -16354, -16352, -16353, -16356,
       -16354, -16353, -16353, -16353, -16352, -16349, -16350, -16347,
       -16345, -16340, -16337, -16331, -16332, -16329, -16337, -16339,
       -16342, -16344, -16345, -16348, -16351, -16351, -16350, -16352,
       -16351, -16346, -16353, -16349, -16350, -16352, -16353, -16349,
       -16352, -16351, -16354, -16352, -16354, -16352, -16354, -16352,
       -16354, -16349, -16348, -16347, -16347, -16343, -16343, -16338,
       -16333, -16330, -16331, -16336, -16340, -16341, -16345, -16346,
       -16347, -16346, -16348, -16352, -16350, -16349, -16351, -16351,
       -16354, -16353, -16353, -16355, -16351, -16352, -16353, -16354,
       -16351, -16353, -16351, -16352, -16349, -16351, -16350, -16351,
       -16352, -16348, -16352, -16349, -16345, -16346, -16341, -16337,
       -16338, -16339, -16342, -16346, -16344, -16348, -16352, -16350,
       -16352, -16353, -16350, -16353, -16356, -16355, -16356, -16354,
       -16352, -16357, -16355, -16356, -16353, -16352, -16354, -16356,
       -16355, -16358, -16352, -16352, -16353, -16351, -16353, -16350,
       -16350, -16349, -16351, -16346, -16344, -16340, -16339, -16338,
       -16339, -16343, -16344, -16345, -16348, -16351, -16350, -16351,
       -16353, -16354, -16353, -16350, -16353, -16354, -16352, -16355,
       -16353, -16356, -16353, -16354, -16356, -16352, -16353, -16355,
       -16353, -16353, -16351, -16352, -16354, -16349, -16349, -16349,
       -16348, -16343, -16340, -16334, -16323, -16322, -16326, -16328,
       -16334, -16343, -16347, -16349, -16348, -16350, -16353, -16353,
       -16354, -16354, -16357, -16356, -16353, -16354, -16358, -16356,
       -16354, -16357, -16357, -16358, -16356, -16357, -16356, -16354,
       -16355, -16356, -16354, -16355, -16353, -16352, -16351, -16351,
       -16346, -16342, -16336, -16333, -16334, -16336, -16342, -16345,
       -16347, -16354, -16354, -16357, -16358, -16359, -16359, -16362,
       -16361, -16360, -16361, -16360, -16363, -16362, -16362, -16364,
       -16363, -16363, -16363, -16363, -16364, -16363, -16364, -16366,
       -16365, -16363, -16362, -16365, -16366, -16364, -16368, -16367])
2
  • can you reproduce your problem with a small data set and post that instead? Commented May 6, 2015 at 9:45
  • what is your expected output? you have a print result, what does it print? Commented May 6, 2015 at 9:46

1 Answer 1

1

The problem seems to be originating in your original data. The first peak, unlike all the other ones, consists of the same value twice -16329, -16329,. Even after applying the Gauss filter this will still be a plateau rather than a peak.

When you use np.greater as a comparator it fails due to the nature of your input data. A quick solution would be to use np.greater_equal as comparator, but this will register the first 'peak' twice. Another option might be to check your input data for repeated values or apply another filter.

local_maxima = argrelextrema(profile, np.greater_equal, order = 15, mode = 'clip')

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

I see what you mean, the plateau does make things more difficult. I will have to correct my data for such repeating values so. This will get even more difficult the noisier my data gets. I will play with it a little bit to see what I can get, thanks!
You could also check the indices argrelextrema with np.greater_equal returns. If they are 1 apart you are looking at a plateau counted twice with greater_equal. This could easily be done with np.diff() and np.where().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.