Eu tenho dois espectros do mesmo objeto astronômico. A questão essencial é a seguinte: como posso calcular a mudança relativa entre esses espectros e obter um erro preciso nessa mudança?
Mais alguns detalhes se você ainda estiver comigo. Cada espectro será uma matriz com um valor x (comprimento de onda), valor y (fluxo) e erro. O deslocamento do comprimento de onda será sub-pixel. Suponha que os pixels sejam espaçados regularmente e que haverá apenas uma única mudança de comprimento de onda aplicada a todo o espectro. Portanto, a resposta final será algo como: 0,35 +/- 0,25 pixels.
Os dois espectros terão um continuum sem característica pontuado por alguns recursos de absorção bastante complicados (quedas) que não modelam facilmente (e não são periódicos). Eu gostaria de encontrar um método que compare diretamente os dois espectros.
O primeiro instinto de todo mundo é fazer uma correlação cruzada, mas com as mudanças de subpixel, você terá que interpolar entre os espectros (suavizando primeiro?) - além disso, os erros parecem desagradáveis para acertar.
Minha abordagem atual é suavizar os dados convolvendo com um kernel gaussiano, depois estragar o resultado suavizado e comparar os dois espectros estriados - mas não confio neles (especialmente nos erros).
Alguém sabe uma maneira de fazer isso corretamente?
Aqui está um pequeno programa python que produzirá dois espectros de brinquedos com deslocamento de 0,4 pixels (gravados em toy1.ascii e toy2.ascii) com os quais você pode brincar. Mesmo que esse modelo de brinquedo use um recurso gaussiano simples, suponha que os dados reais não possam ser ajustados a um modelo simples.
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))
fonte
Respostas:
Eu acho que usar correlação cruzada e interpolar o pico funcionaria bem. Conforme descrito em A amostragem prévia antes da correlação cruzada é inútil? , interpolar ou aumentar a amostragem antes da correlação cruzada não fornecer mais informações. As informações sobre o pico da subamostra estão contidas nas amostras ao seu redor. Você só precisa extraí-lo com um erro mínimo. Reuni algumas anotações aqui .
O método mais simples é a interpolação quadrática / parabólica, da qual tenho um exemplo em Python aqui . É supostamente exato se seu espectro é baseado em uma janela gaussiana ou se o pico cai exatamente no ponto médio entre as amostras, mas, de outra forma, apresenta algum erro . Portanto, no seu caso, você provavelmente deseja usar algo melhor.
Aqui está uma lista de estimadores mais complicados, mas mais precisos. "Dos métodos acima, o segundo estimador de Quinn tem o menor erro de RMS."
Não sei matemática, mas este artigo diz que a interpolação parabólica tem precisão teórica de 5% da largura de uma caixa de FFT.
O uso da interpolação FFT na saída de correlação cruzada não apresenta nenhum erro de polarização , portanto é melhor se você deseja uma precisão realmente boa. Se você precisar equilibrar precisão e velocidade de computação, é recomendável fazer uma interpolação por FFT e segui-la com um dos outros estimadores para obter um resultado "bom o suficiente".
Isso apenas usa o ajuste parabólico, mas gera o valor certo para o deslocamento se o ruído for baixo:
O ruído na sua amostra produz resultados que variam em mais do que uma amostra inteira, então eu o reduzi. Ajustar a curva usando mais pontos do pico ajuda a apertar um pouco a estimativa, mas não tenho certeza se isso é estatisticamente válido, e na verdade piora a estimativa para a situação de baixo ruído.
Com ruído = ajuste de 0,2 e 3 pontos, fornece valores como 0,398 e 0,402 para deslocamento = 0,4.
Com ruído = ajuste de 2,0 e 13 pontos, fornece valores como 0,156 e 0,595 para deslocamento = 0,4.
fonte