简体   繁体   English

我正在尝试使用 scipy curve_fit 将周期数据拟合到模板中,但它没有找到周期

[英]I am trying to fit periodic data to a template with scipy curve_fit but it doesn't find the period

I am trying to write a script that takes in photometry data of a potentially variable star and tries to fit a theoretical template to it to determine several characteristics about it such as period and amplitude.我正在尝试编写一个脚本,该脚本接收潜在变星的光度测量数据,并尝试为其拟合理论模板以确定有关它的几个特征,例如周期和幅度。

The data comes with a date/time (in mjd, essentially the number of days since January 1, 4713 BC) and a brightness in magnitudes.数据带有日期/时间(以 mjd 为单位,基本上是自公元前 4713 年 1 月 1 日以来的天数)和亮度。

The template is an array of phase and y values, the phase going from t=0 to t=.998 (in increments of.002) as y goes from 0 to 1 and back to 0 over the period.模板是相位和 y 值的数组,相位从 t=0 到 t=.998(增量为 0.002),因为 y 在此期间从 0 变为 1 并返回 0。

My model function will stretch and shift the template to have same peak-to-peak amplitude and same range as the data's y values.我的 model function 将拉伸和移动模板,使其具有与数据的 y 值相同的峰峰值幅度和相同范围。 I shift the given t value then divide by the period to get time in terms of phase.我移动给定的 t 值,然后除以周期以获得相位时间。 I use %1 to remove everything but the fractional values, since I don't care which period the data comes from, just where in the period it lies.我使用 %1 删除除小数值以外的所有内容,因为我不在乎数据来自哪个时期,只关心它位于哪个时期。 (ex 347.65 -> 0.65) (例如 347.65 -> 0.65)

class tmpfitter:
    def __init__ (self, templets)
        self.n=0
        self.tmps=templets

    def model(self, t, period, t0, amplitude, yoffset):
        # modify the template using peak-to-peak amplitude, yoffset
        # shift times so phases line up, fold input times t by period
        xtemp = self.tmps[self.n,:,0]
        ytemp = self.tmps[self.n,:,1]*amplitude + yoffset
        ph = (t - t0) / period % 1 #Folds data into single period
        # interpolate the modified template at the phase we want
        return interp1d(xtemp,ytemp)(ph)


def tmpfit(templets,data,pinit):
    datfit = []
    npars = []
    fitter = tmpfitter(templets)
    # Iterate through all templates, finding a best fit for each, find best fit of best fits at end.
    for i in range(len(templets)):
        fitter.n = i
        pars, cov = curve_fit(fitter.model, data[:,0], data[:,1], sigma=data[:,2], p0=pinit, maxfev=10000)
        datfit.append(median(abs(fitter.model(data[:,0],pars[0],pars[1],pars[2],pars[3])-data[:,1])))
        npars.append(pars)
    n = np.argmin(datfit)
    return n, npars[n]

This correctly finds values for t0, amplitude and yoffset, but it is incapable of finding a period.这可以正确找到 t0、幅度和 yoffset 的值,但无法找到周期。 If I give the correct period in the initial guess (p0) then this successfully fits the templates to the data.如果我在初始猜测(p0)中给出正确的时间段,那么这成功地将模板拟合到数据中。 But if the period is off it will not change the period from the initial guess.但如果周期关闭,它不会改变最初猜测的周期。

I suspect this is because of how I fold the data and chop off the whole number part, but am not knowledgeable enough about the curve_fit function to find a fix.我怀疑这是因为我如何折叠数据并切掉整数部分,但对curve_fit function 的了解不足,无法找到修复方法。 I also tried using scipy's least_squares function (I know curve_fit is a wrapper for it) but couldn't get it to work either.我也尝试使用 scipy 的 least_squares function (我知道curve_fit 是它的包装器)但也无法让它工作。

what would be a better way to do this fit?有什么更好的方法来做到这一点?

This function will "fold" your time series for some period. 这个 function将在一段时间内“折叠”您的时间序列。 You can then fit the resulting folded time curve to a sinusoid (or whatever model), and see what period gives the best results.然后,您可以将生成的折叠时间曲线拟合到正弦曲线(或任何模型),并查看哪个周期给出了最佳结果。

If you don't want to just randomly try different periods, you can take a fourier transform of the data and look for the period that gives the highest power.如果您不想只是随机尝试不同的周期,您可以对数据进行傅立叶变换并寻找具有最高功率的周期。 Though, that linked function I think requires evenly spaced data...虽然,我认为链接 function 需要均匀间隔的数据......

Here is a good description of how time series are handled when it comes to Cepheid variables.这里很好地描述了在涉及造父变星时如何处理时间序列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM