У меня два спектра одного и того же астрономического объекта. Основной вопрос заключается в следующем: как я могу рассчитать относительный сдвиг между этими спектрами и получить точную ошибку в этом сдвиге?
Еще некоторые подробности, если вы все еще со мной. Каждый спектр будет массивом со значением x (длина волны), значением y (поток) и ошибкой. Сдвиг длины волны будет субпиксельным. Предположим, что пиксели расположены на регулярном расстоянии, и будет иметь место только одно смещение длины волны, примененное ко всему спектру. Таким образом, конечный ответ будет примерно таким: 0,35 +/- 0,25 пикселей.
Два спектра будут представлять собой множество безликих континуумов, перемежающихся некоторыми довольно сложными абсорбционными характеристиками (провалами), которые не моделируются легко (и не являются периодическими). Я хотел бы найти метод, который напрямую сравнивает два спектра.
Первым инстинктом каждого является взаимная корреляция, но с помощью субпиксельных сдвигов вам придется интерполировать спектры (сначала сглаживая?), А также ошибки кажутся неприятными, чтобы исправляться.
Мой текущий подход состоит в том, чтобы сгладить данные путем свертки с гауссовым ядром, затем сплайнировать сглаженный результат и сравнить два сплайновых спектра - но я не доверяю этому (особенно ошибкам).
Кто-нибудь знает способ сделать это правильно?
Вот короткая программа на python, которая создаст два игрушечных спектра, сдвинутых на 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))
источник
Ответы:
Я думаю, что использование взаимной корреляции и интерполяции пика будет работать нормально. Как описано в разделе «Бесполезно ли повышение частоты дискретизации до взаимной корреляции?». интерполяция или повышающая дискретизация до взаимной корреляции фактически не дает вам больше информации. Информация о пике подвыборки содержится в образцах вокруг него. Вам просто нужно извлечь его с минимальной ошибкой. Я собрал несколько заметок здесь .
Самый простой метод - это квадратичная / параболическая интерполяция, пример которой приведен здесь на Python . Предположительно точно, если ваш спектр основан на гауссовском окне , или если пик оказывается точно в средней точке между выборками, но в противном случае есть некоторая ошибка . Так что в вашем случае вы, вероятно, хотите использовать что-то лучшее.
Вот список более сложных, но более точных оценок. «Из приведенных выше методов вторая оценка Квинна имеет наименьшую среднеквадратичную ошибку».
Я не знаю математики, но в этой статье говорится, что их параболическая интерполяция имеет теоретическую точность 5% ширины ячейки БПФ.
Использование FFT-интерполяции на выходе кросс-корреляции не имеет ошибки смещения , так что это лучше всего, если вы хотите действительно хорошую точность. Если вам необходимо сбалансировать точность и скорость вычислений, рекомендуется выполнить некоторую FFT-интерполяцию, а затем выполнить ее с одним из других оценщиков, чтобы получить «достаточно хороший» результат.
Это просто использует параболическое соответствие, но выводит правильное значение для смещения, если шум низкий:
Шум в вашем образце дает результаты, которые варьируются более чем на целый образец, поэтому я уменьшил его. Подгонка кривой с использованием большего количества точек пика помогает несколько сузить оценку, но я не уверен, является ли она статистически достоверной, и это фактически ухудшает оценку для ситуации с низким уровнем шума.
С шумом = 0,2 и 3-точечной посадкой он дает такие значения, как 0,398 и 0,402 для смещения = 0,4.
С шумом = 2,0 и 13-точечной посадкой он дает значения, такие как 0,156 и 0,595 для смещения = 0,4.
источник