试图将正弦函数拟合到相位光线曲线

时间:2016-12-16 20:07:26

标签: python-2.7 spyder light astronomy sine

import numpy as np
import matplotlib.pyplot as plt
from lmfit import Model,Parameters


f2= "KELT_N16_lc_006261_V01_west_tfa.dat"    
t2="TIMES"   # file name

NewData2 = np.loadtxt(t2, dtype=float, unpack=True)
NewData = np.loadtxt(f2,dtype=float, unpack=True, usecols=(1,))

flux = NewData   
time= NewData2

new_flux=np.hstack([flux,flux])

# fold
period = 2.0232               # period (must be known already!)

foldTimes = ((time)/ period)  # divide by period to convert to phase
foldTimes = foldTimes % 1   # take fractional part of phase only (i.e. discard whole number part)


new_phase=np.hstack([foldTimes+1,foldTimes])

print len(new_flux)
print len(new_phase)


def Wave(x, new_flux,new_phase):
    wave = new_flux*np.sin(new_phase+x)
    return wave
model = Model(Wave)
print "Independent Vars:", model.independent_vars
print "Parameters:",model.param_names
p = Parameters()
p.add_many(('new_flux',13.42, True, None, None, None) )   
p.add_many(('new_phase',0,True, None, None, None) )   

result=model.fit(new_flux,x=new_phase,params=p,weights= None)


plt.scatter(new_phase,new_flux,marker='o',edgecolors='none',color='blue',s=5.0, label="Period: 2.0232  days")   
plt.ylim([13.42,13.54])
plt.xlim(0,2)
plt.gca().invert_yaxis()
plt.title('HD 240121 Light Curve with BJD Correction')
plt.ylabel('KELT Instrumental Magnitude')
plt.xlabel('Phase')
legend = plt.legend(loc='lower right', shadow=True)
plt.scatter(new_phase,result.best_fit,label="One Oscillation Fit", color='red',s=60.0)
plt.savefig('NewEpoch.png')
print result.fit_report()

我正在尝试将正弦函数拟合到研究项目的阶段光曲线数据。但是,我不确定我哪里出错了,我相信它存在于我的参数中。看起来拟合的幅度太高,而且周期太长。任何帮助,将不胜感激。谢谢!

这就是图形现在的样子(尝试将正弦函数拟合到我的数据集中):

img

2 个答案:

答案 0 :(得分:1)

一些意见/建议:

首先,替换

几乎肯定更好
p = Parameters()
p.add_many(('new_flux',13.42, True, None, None, None) )
p.add_many(('new_phase',0,True, None, None, None) )

p = Parameters()
p.add('new_flux', value=13.42, vary=True)
p.add('new_phase', value=0, vary=True)

其次,您的模型不包括DC偏移,但您的数据显然有一个。偏移约为13.4,正弦波的幅度约为0.05。当你在它的时候,你可能想要包括一个比例相位和一个偏移量,以便模型

offset + amplitude * sin(scale*x + phase_shift)

您不一定要改变所有这些,但是让模型更加通用将允许查看相移和比例是如何相关的 - 给定数据中的噪声级别,这可能很重要。

使用更通用的模型,您可以尝试使用model.eval()来评估具有一组参数的模型的几组参数值。一旦你有一个更好的模型和合理的起点,你应该得到一个合理的契合。

答案 1 :(得分:0)

我们如何帮助您使用未注释的代码?

  • 我们如何知道它是什么以及它应该做什么?
  • 您使用什么方法进行拟合?
  • 数据在哪里以及以何种形式出现?

我将从计算近似正弦波参数开始。假设您以data点的形式获得了nx,y坐标y(t) = y0+A*sin(x0+x(t)*f) 。并希望适应一股罪恶的浪潮:

y0

x0是y偏移,A是相位偏移,f是幅度,y0 = sum(data[i].y)/n where i={0,1,2,...n-1} 是角频率。

我会:

  1. 计算平均值

    y0

    这是表示你的正弦波可能y偏移y0的平均值。

  2. 计算到d = sum (|data[i].y-y0|)/n where i={0,1,2,...n-1} 的平均距离

    A = sqrt(2)*d
    

    如果我的记忆很好,那么这应该是幅度的有效值,所以:

    x
  3. 在数据集中找到零交叉

    为此,数据集应按i排序,如果不是,则对其进行排序。请记住索引i0:第一次越过i1,最后一次越过j和找到的过境点数f=M_PI*double(j-1)/(datax[i1]-datax[i0]); x0=-datax[i0]*f; ,我们可以估算出频率和相位偏差:

    i1=i0+((i1-i0)/(j-1));
    if (datay[(i0+i1)>>1]<=y0) x0+=M_PI;
    

    确定我们对齐的半个正弦波只检查前两个零交叉点之间的中点符号

    x0,y0,f,A

    或者检查特定的过零模式。

    现在我们只有大约//--------------------------------------------------------------------------- #include <math.h> // input data const int n=5000; double datax[n]; double datay[n]; // fitted sin wave double A,x0,y0,f; //--------------------------------------------------------------------------- void data_generate() // genere random noisy sinvawe { int i; double A=150.0,x0=250.0,y0=200.0,f=0.03,r=20.0; double x,y; Randomize(); for (i=0;i<n;i++) { x=800.0*double(i)/double(n); y=y0+A*sin(x0+x*f); datax[i]=x+r*Random(); datay[i]=y+r*Random(); } } //--------------------------------------------------------------------------- void data_fit() // find raw approximate of x0,y0,f,A { int i,j,e,i0,i1; double x,y,q0,q1; // y0 = avg(y) for (y0=0.0,i=0;i<n;i++) y0+=datay[i]; y0/=double(n); // A = avg(|y-y0|) for (A=0.0,i=0;i<n;i++) A+=fabs(datay[i]-y0); A/=double(n); A*=sqrt(2.0); // bubble sort data by x asc for (e=1,j=n;e;j--) for (e=0,i=1;i<j;i++) if (datax[i-1]>datax[i]) { x=datax[i-1]; datax[i-1]=datax[i]; datax[i]=x; y=datay[i-1]; datay[i-1]=datay[i]; datay[i]=y; e=1; } // find zero crossings for (i=0,j=0;i<n;) { // find value below zero for (;i<n;i++) if (datay[i]-y0<=-0.75*A) break; e=i; // find value above zero for (;i<n;i++) if (datay[i]-y0>=+0.75*A) break; if (i>=n) break; // find point closest to zero for (i1=e;e<i;e++) if (fabs(datay[i1]-y0)>fabs(datay[e]-y0)) i1=e; if (!j) i0=i1; j++; } f=2.0*M_PI*double(j-1)/(datax[i1]-datax[i0]); x0=-datax[i0]*f; } //--------------------------------------------------------------------------- sinwave的参数。

  4. 这里我测试了一些 C ++ 代码(抱歉我不使用Python):

    $autoload['libraries'] = array('database','ci_session');
    

    预览:

    view

    点生成噪声数据,蓝色曲线适合sin波。

    除此之外,您还可以构建您的配件以提高精度。无论您将使用哪种方法搜索找到的参数。例如,我会去: