我有一个脚本,它会生成由3条不同正弦曲线组成的噪声曲线。使用LombScargle我找到由于这些曲线而占主导地位的时期并消除原始曲线。
这涉及相位折叠,使用SciPy优化拟合正弦曲线,然后将拟合曲线从相空间外推到原始多正弦波曲线上,然后减去此拟合以消除数据。
我迭代这个过程,以便最终当LombScargle上的信号小于某个预先生成的噪声高度的3倍时,迭代停止。 (相当于信噪比变得太小)。
但是在第一次迭代之后,拟合曲线的相位就越远了!我不明白为什么会这样。有人可以帮忙吗?
import matplotlib.pyplot as plt
import numpy as np
import math
from scipy.optimize import leastsq
from astropy.stats import LombScargle
t = np.linspace(15,30,1000)
y = 5 * np.sin(2*np.pi * 1./2. * (t + 1)) + 30
y1 = 11 * np.sin(2*np.pi * 1./3. * (t + 1))
y4 = 2 * np.sin(2*np.pi * 1./7. * (t + 1))
sampl = np.random.uniform(low = 0, high = 2.5, size = len(t))
y2 = y+y1+y4+sampl
y2 = y2/np.nanmedian(y2)
freq = np.linspace(1./150.,1./0.5,10000)
power2 = LombScargle(t,sampl).power(freq)
for _ in range(5):
plt.figure()
plt.subplot(221)
plt.plot(t,y2,'-')
plt.grid()
power = LombScargle(t,y2).power(freq)
p = 1./freq[np.argmax(power)]
plt.title(p)
plt.subplot(222)
plt.plot(1./freq,power)
plt.grid()
# print p
if np.max(power) <= np.max(power2)*3:
print 'done'
break
else:
foldtimes = (t - t[0])/p
FoldTimes = foldtimes % 1
p_0 = np.min(FoldTimes)
dp = 0.01
its = math.ceil((np.max(FoldTimes)-p_0)/dp)
n = np.linspace(0,its,its+1)
binned_flux = []
binned_phase = []
for i in range(len(n)):
indices = np.where(((p_0 + (n[i]*dp)) <= FoldTimes) & (FoldTimes <= (p_0 + (n[i]*dp)+dp)))[0]
if len(indices)>1:
binned_flux.append( np.nanmedian(y2[indices])) ##continuously adds the averaged fluxes to list
binned_phase.append (np.mean(FoldTimes[indices])) #same for hjs averages
binned_flux = np.array(binned_flux)
binned_phase = np.array(binned_phase)
plt.subplot(223)
plt.grid()
plt.plot(binned_phase,binned_flux,'.',linestyle='None')
plt.ylabel('Relative Flux')
plt.xlabel('Phase')
guess_mean = np.mean(y2)
guess_A = (np.max(y2) - np.min(y2))/2.
guess_phase = 0
optimize_func = lambda x: ((x[0] * np.sin(2*np.pi*(np.sort(binned_phase) + x[1]))) + x[2]) - binned_flux
est_A, est_phase, est_mean = leastsq(optimize_func, [guess_A,guess_phase,guess_mean])[0]
print est_phase
fit = (est_A*np.sin(2*np.pi*(1./p)*(t+ (est_phase*p)))) + est_mean
fit_p = (est_A*np.sin(2*np.pi*(1.)*(np.sort(binned_phase)+(est_phase)))) + est_mean
plt.plot(binned_phase,fit_p)
plt.subplot(224)
plt.plot(t,y2,'-')
plt.plot(t,fit)
plt.grid()
y2 = (y2 - fit) + est_mean #rewrites the original curve minus the fit