두 스펙트럼 사이의 서브 픽셀 이동을 직접 비교하여 믿을 수있는 오류를 얻습니다.


9

같은 천체의 두 가지 스펙트럼이 있습니다. 중요한 질문은 이것입니다. 어떻게 이러한 스펙트럼들 사이의 상대적인 이동을 계산하고 그 이동에서 정확한 에러를 얻을 수 있습니까?

당신이 여전히 나와 함께 있다면 더 많은 세부 사항. 각 스펙트럼은 x 값 (파장), y 값 (플럭스) 및 오류가있는 배열입니다. 파장 이동은 서브 픽셀이 될 것입니다. 픽셀들이 규칙적으로 이격되고 전체 스펙트럼에 단일 파장 시프트 만이 적용될 것이라고 가정하자. 따라서 최종 답변은 0.35 +/- 0.25 픽셀입니다.

두 스펙트럼은 쉽게 모델링되지 않고 주기적이 아닌 다소 복잡한 흡수 특징 (딥)에 의해 특징이없는 연속체가 될 것입니다. 두 스펙트럼을 직접 비교하는 방법을 찾고 싶습니다.

모든 사람의 첫 번째 본능은 상호 상관을 수행하는 것이지만, 서브 픽셀 이동을 사용하면 스펙트럼을 먼저 보간해야합니다 (먼저 스무딩합니까?).

내 현재 접근 방식은 가우스 커널과 함께 데이터를 부드럽게 한 다음 부드러운 결과를 스플라인하고 두 개의 스플라인 스펙트럼을 비교하는 것입니다. 그러나 나는 그것을 믿지 않습니다 (특히 오류).

누구든지 이것을 올바르게하는 방법을 알고 있습니까?

여기에 당신이 가지고 놀 수있는 0.4 픽셀 (toy1.ascii 및 toy2.ascii로 작성)만큼 이동되는 두 개의 장난감 스펙트럼을 생성하는 짧은 파이썬 프로그램이 있습니다. 이 장난감 모델이 간단한 가우스 특징을 사용하더라도 실제 데이터를 간단한 모델에 맞출 수 없다고 가정하십시오.

import numpy as np
import random as ra
import scipy.signal as ss
arraysize = 1000
fluxlevel = 100.0
noise = 2.0
signal_std = 15.0
signal_depth = 40.0
gaussian = lambda x: np.exp(-(mu-x)**2/ (2 * signal_std))
mu = 500.1
np.savetxt('toy1.ascii', zip(np.arange(arraysize), np.array([ra.normalvariate(fluxlevel, noise) for x in range(arraysize)] - gaussian(np.arange(arraysize)) * signal_depth), np.ones(arraysize) * noise))
mu = 500.5
np.savetxt('toy2.ascii', zip(np.arange(arraysize), np.array([ra.normalvariate(fluxlevel, noise) for x in range(arraysize)] - gaussian(np.arange(arraysize)) * signal_depth), np.ones(arraysize) * noise))

올바르게 이해하면 한 축에 선형 하위 픽셀 이동이 있다는 점을 제외하고 이미지 등록과 비슷한 문제가 발생합니다. 위상 상관과 같은 표준 이미지 등록 기술을 사용해보십시오.
Paul R

하나의 신호에 순수한 지연이있는 경우 (즉, 말한 파장 매개 변수의 이동) 시간 지연을 주파수 영역에서 선형 위상 오프셋으로 바꾸는 푸리에 변환 특성을 활용할 수 있습니다. 서로 다른 측정 노이즈 나 간섭으로 두 샘플이 손상되지 않은 경우 작동 할 수 있습니다.
Jason R

1
이 글타래는 유용 할 것입니다. dsp.stackexchange.com/questions/2321/…
Jim Clay

1
테스트 할 실제 데이터가 있습니까? 제공 한 노이즈 값이 너무 커서 교차 상관이 서브 샘플 정확도가되지 않습니다. : 이것은 노이즈 2.0의 여러 실행에 발견하고, 예를 들어, (플롯의 x 축에 = 1000.7) 0.7을 상쇄 무엇 i.stack.imgur.com/UK5JD.png
endolith

답변:


5

상호 상관을 사용하고 피크를 보간하는 것이 좋습니다. 상호 상관 이전의 업 샘플링이 쓸모 없는가?에 설명 된대로 , 상호 상관 이전의 보간 또는 업 샘플링은 실제로 더 이상 정보를 얻지 못합니다. 서브 샘플 피크에 대한 정보는 주변 샘플에 포함됩니다. 최소한의 오류로 추출하면됩니다. 나는 여기에 몇 가지 메모를 모았다 .

가장 간단한 방법은 2 차 / 포물선 보간법인데, 여기에 파이썬 예제가 있습니다 . 그것은 정확한 가정의 당신의 스펙트럼 가우스 윈도우를 기반으로하는 경우 , 또는 피크 샘플 사이의 중간 지점에 정확히 떨어 발생하지만, 경우에 그렇지 않으면 일부 오류가 있습니다 . 따라서 귀하의 경우에는 아마도 더 나은 것을 사용하고 싶을 것입니다.

보다 복잡하지만 정확한 추정값 목록다음과 같습니다 . "위의 방법 중에서 Quinn의 두 번째 추정기는 RMS 오류가 가장 적습니다."

나는 수학을 모른다. 그러나이 논문 은 그들의 포물선 보간이 이론적으로 FFT 빈 너비의 5 %의 정확도를 가지고 있다고 말한다.

교차 상관 출력에서 ​​FFT 보간을 사용하면 바이어스 오류 가 없으므로 정확도를 높이려면 이것이 가장 좋습니다. 정확도와 계산 속도의 균형이 필요한 경우 FFT 보간을 수행 한 다음 다른 추정기 중 하나를 따라 "충분히 좋은"결과를 얻는 것이 좋습니다.

이것은 포물선 맞춤을 사용하지만 노이즈가 낮 으면 오프셋에 올바른 값을 출력합니다.

def parabolic_polyfit(f, x, n):
    a, b, c = polyfit(arange(x-n//2, x+n//2+1), f[x-n//2:x+n//2+1], 2)
    xv = -0.5 * b/a
    yv = a * xv**2 + b * xv + c

    return (xv, yv)

arraysize = 1001
fluxlevel = 100.0
noise = 0.3 # 2.0 is too noisy for sub-sample accuracy
signal_std = 15.0
signal_depth = 40.0
gaussian = lambda x: np.exp(-(mu-x)**2/ (2 * signal_std))
mu = 500.1
a_flux = np.array([ra.normalvariate(fluxlevel, noise) for x in range(arraysize)] - gaussian(np.arange(arraysize)) * signal_depth)
mu = 500.8
b_flux = np.array([ra.normalvariate(fluxlevel, noise) for x in range(arraysize)] - gaussian(np.arange(arraysize)) * signal_depth)

a_flux -= np.mean(a_flux)
b_flux -= np.mean(b_flux)

corr = ss.fftconvolve(b_flux, a_flux[::-1])

peak = np.argmax(corr)
px, py = parabolic_polyfit(corr, peak, 13)

px = px - (len(a_flux) - 1)
print px

여기에 이미지 설명을 입력하십시오 여기에 이미지 설명을 입력하십시오

샘플의 노이즈는 전체 샘플보다 다양한 결과를 생성하므로 줄였습니다. 더 많은 피크 점을 사용하여 곡선을 피팅하면 추정치를 다소 강화하는 데 도움이되지만 통계적으로 유효한지 확실하지 않으며 실제로 노이즈가 적은 상황에서는 추정치를 악화시킵니다.

노이즈 = 0.2 및 3 점 맞춤으로 오프셋 = 0.4에 대해 0.398 및 0.402와 같은 값을 제공합니다.

노이즈 = 2.0 및 13 포인트 맞춤으로 오프셋 = 0.4에 대해 0.156 및 0.595와 같은 값을 제공합니다.


이미지 등록에 대한이 정확한 문제를 해결하려고합니다. 서브 픽셀 정확도 (0.1로 충분할 것입니다)가 필요하지만 가장 중요한 것은 바이어스가 필요하지 않으므로 보간 방법이 작동하지 않는 것입니다. 이것에 대한 좋은 (그리고 파이썬으로 구현 되었습니까?) 방법이 있습니까? 제로 패딩 방법은 작동하지만 실용적이지 않습니다.
keflavich

@kelavich : 모든 보간법을 테스트 한 결과 허용 할 수없는 치우침을 찾았습니까? 권장되는 접근 방식은 일부 제로 패딩과 낮은 오류 보간 의 조합입니다 . 나는 다른 방법을 모른다. 그러나 이것은 당신에게 많은 정확성을 제공 할 것이라고 확신합니다.
endolith

예, 선형 및 2 차 보간에서 허용 할 수없는 바이어스를 발견했습니다. FFT 제로 패딩을 시도했지만 그 결과 고주파 링잉이 지배적입니다. 제로 패딩 예제를 추가 할 수 있습니까?
keflavich
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.