2017-12-16 5 views
1

어떻게 CWT 얻을 피크 방법 사용 예 Scipy 신호 함수로부터 위치, 피크 aarea 피크 폭 등과 같은 특성을 가진 최대 객체를 얻는다 :Scipy 신호 개체에서의 피크의 폭과 면적을 얻기

def CWT(trace): 
x = [] 
y = [] 
for i in range(len(trace)): 
    x.append(trace[i].Position) 
    y.append(trace[i].Intensity) 
x = np.asarray(x) 
y = np.asarray(y) 
return signal.find_peaks_cwt(x,y) 

이것은 단지 배열을 반환합니까?

답변

0

먼저 find_peaks_cwt를 잘못 사용하고있는 것 같습니다. 두 개의 위치 매개 변수는 데이터 포인트의 x 및 y 좌표가 아닙니다. 첫 번째 매개 변수는 y 값입니다. x 값은 전혀 가져 오지 않으며 0,1,2, ...로 가정합니다. 두 번째 매개 변수는 관심있는 피크 너비 목록입니다.

CWT 행렬을 계산하는 데 사용할 1 차원 배열입니다. 일반적으로이 범위는 예상되는 봉우리 폭을 포함해야합니다.

width 매개 변수가 데이터 배열과 같은 크기 일 수는 없습니다. 아래 예제에서 데이터에는 500 개의 값이 있지만 사용하는 너비는 30 ... 99입니다.

둘째,이 방법은 피크의 위치 만 찾습니다 (얻을 수있는 배열에는 피크의 인덱스가 있음). 폭과 면적에 대한 분석은 없습니다. 다른 곳 (블로그 게시물 Peak Detection in the Python World에는 몇 가지 대안이 나열되어 있지만 원하는 데이터를 반환하지는 않음)을 보거나 자신의 방식을 예측할 수 있습니다.

내 시도는 다음과 같습니다.

  1. 는 피크 각 조각에 대한
  2. 사이의 중간 점에 의해 상기 신호를 인하
  3. 보다 큰 모든 값을 구성하는 정점을 선언 기준으로의 값의 평균을 사용하여이 기능은 다음 수행 0.5 * (최고 값 + 기준선), 즉 중앙값과 최대 값의 중간 값.
  4. 피크가 시작되는 지점과 끝나는 지점을 찾습니다.
  5. 는 (Y - 기준선)의 합으로 피크의 면적을 선언 (폭이 단지 차이) 단계에서 발견 간격 동안 제

완료 예 :

t = np.linspace(0, 4.2, 500) 
y = np.sin(t**2) + np.random.normal(0, 0.03, size=t.shape) # simulated noisy signal 
peaks = find_peaks_cwt(y, np.arange(30, 100, 10)) 

cuts = (peaks[1:] + peaks[:-1])//2 # where to cut the signal 
cuts = np.insert(cuts, [0, cuts.size], [0, t.size]) 
peak_begins = np.zeros_like(peaks) 
peak_ends = np.zeros_like(peaks) 
areas = np.zeros(peaks.shape) 
for i in range(peaks.size): 
    peak_value = y[peaks[i]] 
    y_cut = y[cuts[i]:cuts[i+1]]   # piece of signal with 1 peak 
    baseline = np.median(y_cut) 
    large = np.where(y_cut > 0.5*(peak_value + baseline))[0] 
    peak_begins[i] = large.min() + cuts[i] 
    peak_ends[i] = large.max() + cuts[i] 
    areas[i] = np.sum(y[peak_begins[i]:peak_ends[i]] - baseline) 

배열 areas, peak_beginspeak_ends이 여기에 중요합니다. 너비는 [84 47 36]입니다. 이는 피크가 더 얇아 짐을 나타냅니다 (이 값은 인덱스 단위로 표시되며 폭은 ​​피크의 데이터 요소 수입니다). 나는 빨간색으로 피크 색상이 데이터를 사용 :

widths = peak_ends - peak_begins 
print(widths, areas) 
plt.plot(t, y) 
for i in range(peaks.size): 
    plt.plot(t[peak_begins[i]:peak_ends[i]], y[peak_begins[i]:peak_ends[i]], 'r') 
plt.show() 

picture