So sánh trực tiếp sự thay đổi pixel phụ giữa hai phổ - và nhận được các lỗi đáng tin cậy


9

Tôi có hai quang phổ của cùng một đối tượng thiên văn. Câu hỏi thiết yếu là đây: Làm thế nào tôi có thể tính được sự dịch chuyển tương đối giữa các quang phổ này và nhận được một lỗi chính xác trên sự dịch chuyển đó?

Một số chi tiết nếu bạn vẫn còn với tôi. Mỗi phổ sẽ là một mảng có giá trị x (bước sóng), giá trị y (thông lượng) và lỗi. Sự thay đổi bước sóng sẽ là pixel phụ. Giả sử rằng các pixel thường xuyên cách nhau và sẽ chỉ có một bước sóng duy nhất được áp dụng cho toàn bộ phổ. Vì vậy, câu trả lời cuối cùng sẽ là một cái gì đó như: 0,35 +/- 0,25 pixel.

Hai quang phổ sẽ có rất nhiều liên tục không có dấu chấm câu bởi một số tính năng hấp thụ khá phức tạp (dips) không dễ dàng mô hình hóa (và không định kỳ). Tôi muốn tìm một phương pháp so sánh trực tiếp hai phổ.

Bản năng đầu tiên của mọi người là thực hiện một mối tương quan chéo, nhưng với các thay đổi subpixel, bạn sẽ phải nội suy giữa các quang phổ (bằng cách làm mịn trước?) - cũng có thể, các lỗi có vẻ khó chịu.

Cách tiếp cận hiện tại của tôi là làm mịn dữ liệu bằng cách kết hợp với hạt nhân gaussian, sau đó chia nhỏ kết quả được làm mịn và so sánh hai phổ được tách - nhưng tôi không tin tưởng nó (đặc biệt là các lỗi).

Có ai biết một cách để làm điều này đúng?

Dưới đây là một chương trình python ngắn sẽ tạo ra hai phổ đồ chơi được dịch chuyển 0,4 pixel (được viết bằng toy1.ascii và toy2.ascii) mà bạn có thể chơi cùng. Mặc dù mô hình đồ chơi này sử dụng tính năng gaussian đơn giản, giả sử rằng dữ liệu thực tế không thể phù hợp với một mô hình đơn giản.

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))

Nếu tôi hiểu chính xác thì vấn đề nghe có vẻ tương tự như đăng ký hình ảnh, ngoại trừ bạn chỉ có một thay đổi pixel phụ tuyến tính trong một trục. Có thể thử các kỹ thuật đăng ký hình ảnh tiêu chuẩn như tương quan pha?
Paul R

Nếu bạn có độ trễ thuần trong một tín hiệu (nghĩa là sự thay đổi trong tham số bước sóng mà bạn nói đến), bạn có thể khai thác thuộc tính biến đổi Fourier để biến độ trễ thời gian thành độ lệch pha tuyến tính trong miền tần số. Điều này có thể hoạt động nếu hai mẫu không bị hỏng do nhiễu hoặc nhiễu đo khác nhau.
Jason R

1
Chủ đề này có thể hữu ích- dsp.stackexchange.com/questions/2321/iêu
Jim Clay

1
Bạn có dữ liệu thực tế để kiểm tra? Giá trị nhiễu bạn đưa ra là quá nhiều để tương quan chéo là chính xác mẫu phụ. Đây là những gì nó tìm thấy với một vài lần nhiễu 2.0 và bù 0,7 (= 1000,7 trên trục x của âm mưu), ví dụ: i.stack.imgur.com/UK5JD.png
endolith

Câu trả lời:


5

Tôi nghĩ rằng sử dụng tương quan chéo và nội suy đỉnh sẽ hoạt động tốt. Như được mô tả trong Có phải việc lấy mẫu trước khi tương quan chéo là vô ích? , nội suy hoặc lấy mẫu trước khi tương quan chéo không thực sự giúp bạn có thêm thông tin. Thông tin về đỉnh mẫu phụ được chứa trong các mẫu xung quanh nó. Bạn chỉ cần giải nén nó với lỗi tối thiểu. Tôi tập hợp một số ghi chú ở đây .

Phương pháp đơn giản nhất là nội suy bậc hai / parabol, mà tôi có một ví dụ Python ở đây . Nó được cho là chính xác nếu phổ của bạn dựa trên cửa sổ Gaussian hoặc nếu cực đại xảy ra rơi chính xác vào điểm giữa giữa các mẫu, nhưng nếu không thì có một số lỗi . Vì vậy, trong trường hợp của bạn, bạn có thể muốn sử dụng một cái gì đó tốt hơn.

Dưới đây là danh sách các công cụ ước tính phức tạp hơn, nhưng chính xác hơn. "Trong số các phương pháp trên, công cụ ước tính thứ hai của Quinn có ít lỗi RMS nhất."

Tôi không biết toán học, nhưng bài báo này nói rằng phép nội suy parabol của chúng có độ chính xác về mặt lý thuyết là 5% chiều rộng của thùng FFT.

Sử dụng phép nội suy FFT trên đầu ra tương quan chéo không có bất kỳ lỗi sai lệch nào , vì vậy đó là cách tốt nhất nếu bạn muốn độ chính xác thực sự tốt. Nếu bạn cần cân bằng độ chính xác và tốc độ tính toán, bạn nên thực hiện một số phép nội suy FFT và sau đó làm theo nó với một trong các công cụ ước tính khác để có kết quả "đủ tốt".

Điều này chỉ sử dụng sự phù hợp parabol, nhưng nó đưa ra giá trị phù hợp cho phần bù nếu độ nhiễu thấp:

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

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

Tiếng ồn trong mẫu của bạn tạo ra kết quả thay đổi nhiều hơn toàn bộ mẫu, vì vậy tôi đã giảm nó. Ghép đường cong bằng cách sử dụng nhiều điểm của đỉnh giúp thắt chặt phần nào ước tính, nhưng tôi không chắc liệu điều đó có hợp lệ hay không và nó thực sự làm cho ước tính trở nên tồi tệ hơn đối với tình huống nhiễu thấp hơn.

Với độ ồn = 0,2 và 3 điểm phù hợp, nó mang lại các giá trị như 0,388 và 0,402 cho offset = 0,4.

Với độ ồn = 2.0 và 13 điểm phù hợp, nó mang lại các giá trị như 0.156 và 0.595 cho offset = 0.4.


Tôi đang cố gắng giải quyết vấn đề chính xác này để đăng ký hình ảnh. Tôi cần độ chính xác của pixel phụ (0,1 có thể là đủ tốt) nhưng quan trọng nhất là không cần sai lệch, vì vậy các phương pháp nội suy không hoạt động. Có phương pháp nào tốt (và được thực hiện trong python không?) Cho việc này? Phương pháp đệm không sẽ hoạt động, nhưng nó quá đắt để thực tế.
keflavich

@kelavich: Bạn đã thử tất cả các phương pháp nội suy và thấy sai lệch không thể chấp nhận? Cách tiếp cận được đề xuất là sự kết hợp của một số phần đệm bằng 0, theo sau là phép nội suy có lỗi thấp. Tôi không biết về bất kỳ phương pháp nào khác, nhưng tôi cá rằng điều này sẽ cung cấp cho bạn rất nhiều độ chính xác.
endolith

Có, tôi đã tìm thấy sai lệch không thể chấp nhận được trong phép nội suy tuyến tính và bậc 2. Tôi đã thử đệm không FFT, nhưng kết quả bị chi phối bởi đổ chuông tần số cao ... bất kỳ cơ hội nào bạn có thể thêm ví dụ đệm không?
keflavich
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.