我的功率谱可信吗? lomb-scargle 和 fft 之间的比较(scipy.signal 和 numpy.fft)

2024-03-31

谁能指出为什么我得到截然不同的结果?
有很多不应该出现的峰。事实上,应该只有一个峰。
我是一个 python 新手,欢迎对下面我的代码发表所有评论。

测试数据在这里。在此输入链接描述 https://clbin.com/YJkwr
您可以直接wget https://clbin.com/YJkwr .
它的第一列是一系列光子的到达时间。光源随机发射光子。 总时间为55736s,有67398个光子。 我尝试检测光强度的某种周期性。
我们可以对时间进行分箱,光强度与每个时间箱中的光子数成正比。

我尝试了 scipy.signal 的 numpy.fft 和 lomb-scargle 来制作其功率谱,但得到了截然不同的结果。

fft

 import pylab as pl
 import numpy as np

 timepoints=np.loadtxt('timesequence',usecols=(0,),unpack=True,delimiter=",")
 binshu=50000
 interd=54425./binshu  
 t=np.histogram(timepoints,bins=binshu)[0]
 sp = np.fft.fft(t)
 freq = np.fft.fftfreq(len(t),d=interd)  
 freqnum = np.fft.fftfreq(len(t),d=interd).argsort()  
 pl.xlabel("frequency(Hz)")
 pl.plot(freq[freqnum],np.abs(sp)[freqnum])

隆姆斯卡格尔

 timepoints=np.loadtxt('timesequence',usecols=(0,),unpack=True,delimiter=",")
 binshu=50000
 intensity=np.histogram(timepoints,bins=binshu)[0].astype('float64') 
 middletime=np.histogram(timepoints,bins=binshu)[1][1:binshu+1]-np.histogram(timepoints,bins=binshu)[1][3]*0.5
 freq1=1./(timepoints.max()-timepoints.min())
 freq2=freq1*len(timepoints)
 freqs=np.linspace(freq1,freq2,1000)
 pm1=spectral.lombscargle(middletime,intensity,freqs)

 pl.xlabel("frequency(Hz)")
 pl.plot(freqs,pm1)
 pl.xlim(0.5*freq1,2*freq2)
 pl.ylim(0,250)
 pl.show()

**********************************
谢谢你,沃伦,我很感激。谢谢你的详细回复。

你是对的,有一个积分时间,这里大约是1.7s。
单次曝光次数较多,每次曝光耗时1.7s
在一次曝光中,我们无法准确判断其到达时间。

如果时间序列是这样的:
0 1.7 3.4 8.5 8.5

最后两个光子的积分时间为1.7s,not (8.5-3.4)s.所以我会修改你的部分代码。

然而我的问题仍然存在。您调整几个参数以获得0.024Hz峰在某种程度上是 lomb-scargle 峰。您可以使用它来指导 fft 中的参数。

如果您不知道号码0.024,也许你可以使用不同的参数来获得不同的最高峰?

如何保证每次都能做对num_ls_freqs?你可以看看我们是否选择不同num_ls_freqs,最高峰值偏移。

如果我有很多计时系列,每次我都必须指定不同的参数?以及如何获得它们?


看来 50000 个 bin 还不够。如果你改变binshu,您会看到尖峰的位置发生了变化,而且变化不只是一点点。

在深入研究 FFT 或 Lomb-Scargle 之前,我发现首先研究原始数据很有用。以下是文件的开头和结尾:

0,1,3.77903
0,1,4.96859
0,1,1.69098
1.74101,1,4.87652
1.74101,1,5.15564
1.74101,1,2.73634
3.48202,1,3.18583
3.48202,1,4.0806
5.2229,1,1.86738
6.96394,1,7.27398
6.96394,1,3.59345
8.70496,1,4.13443
8.70496,1,2.97584
...
55731.7,1,5.74469
55731.7,1,8.24042
55733.5,1,4.43419
55733.5,1,5.02874
55735.2,1,3.94129
55735.2,1,3.54618
55736.9,1,3.99042
55736.9,1,5.6754
55736.9,1,7.22691

有簇完全相同的到达时间。 (这是光子探测器的原始输出,还是该文件已以某种方式进行了预处理?)

因此,第一步是一次性将这些集群合并为一个数字,因此数据看起来像(时间点,计数),例如:

0, 3
1.74101, 3
3.48202, 2
5.2229, 1
etc

以下将完成计数:

times, inv = np.unique(timepoints, return_inverse=True)
counts = np.bincount(inv)

Now times是一个递增的唯一时间值的数组,并且counts是当时检测到的光子数。 (请注意,我猜测这是对数据的正确解释!)

让我们看看采样是否接近均匀。到达间隔时间的数组是

dt = np.diff(times)

如果采样完全均匀,则所有值dt会是一样的。我们可以使用上面使用的相同模式timepoints查找其中的唯一值(及其出现频率)dt:

dts, inv = np.unique(dt, return_inverse=True)
dt_counts = np.bincount(inv)

例如,这是dts如果我们打印它看起来像:

[  1.7       1.7       1.7       1.7       1.74      1.74      1.74      1.74
   1.74      1.74      1.74088   1.741     1.741     1.741     1.741
   1.741     1.741     1.741     1.74101   1.74102   1.74104   1.7411
   1.7411    1.7411    1.7411    1.7411    1.742     1.742     1.742
   1.746     1.75      1.8       1.8       1.8       1.8       3.4       3.4
   3.4       3.4       3.48      3.48      3.48      3.48      3.48      3.482
   3.482     3.482     3.482     3.482     3.4821    3.483     3.483     3.49
   3.49      3.49      3.49      3.49      3.5       3.5       5.2       5.2
   5.2       5.2       5.22      5.22      5.22      5.22      5.22      5.223
   5.223     5.223     5.223     5.223     5.223     5.23      5.23      5.23
   5.3       5.3       5.3       5.3       6.9       6.9       6.9       6.9
   6.96      6.96      6.964     6.964     6.9641    7.        8.7       8.7
   8.7       8.7       8.7       8.71     10.4      10.5      12.2    ]

(表面上的重复值实际上是不同的。未显示数字的完整精度。)如果采样完全均匀,则该列表中将只有一个数字。相反,我们看到的是数字簇,没有明显的主导值。 (1.74 的倍数占优势——这是探测器的特性吗?)

基于这一观察,我们将从 Lomb-Scargle 开始。下面的脚本包含计算和绘制 (times, counts) 数据。给出的频率为lombscargle不等于1/trange, where trange是数据的完整时间跨度,1/dt.min()。频率数为16000(num_ls_freqs在脚本中)。一些试验表明,这大致是解析频谱所需的最小数量。小于这个值,山峰就会开始移动。除此之外,频谱几乎没有变化。计算表明在0.0242 Hz处有一个峰值。其他峰值是该频率的谐波。

现在我们已经估计了基频,我们可以用它来指导直方图中 bin 大小的选择timepoints用于 FFT 计算。我们将使用导致基频过采样 8 倍的 bin 大小。(在下面的脚本中,这是m.) 也就是说,我们做

m = 8
nbins = int(m * ls_peak_freq * trange + 0.5)
hist, bin_edges = np.histogram(timepoints, bins=nbins, density=True)

(timepoints是从文件中读取的原始时间集;它包括许多重复的时间值,如上所述。)

然后我们应用FFThist。 (我们实际上会使用numpy.fft.rfft.) 以下是使用 FFT 计算的频谱图:

正如预期的那样,在 0.0242 Hz 处有一个峰值。

这是脚本:

import numpy as np
from scipy.signal import lombscargle
import matplotlib.pyplot as plt


timepoints = np.loadtxt('timesequence', usecols=(0,), delimiter=",")

# Coalesce the repeated times into the `times` and `counts` arrays.
times, inv = np.unique(timepoints, return_inverse=True)
counts = np.bincount(inv)

# Check the sample spacing--is the sampling uniform?
dt = np.diff(times)
dts, inv = np.unique(dt, return_inverse=True)
dt_counts = np.bincount(inv)
print dts
# Inspection of `dts` shows that the smallest dt is about 1.7, and there
# are many near multiples of 1.74,  but the sampling is not uniform,
# so we'll analyze the spectrum using lombscargle.


# First remove the mean from the data.  This is not essential; it just
# removes the large value at the 0 frequency that we don't care about.
counts0 = counts - counts.mean()

# Minimum interarrival time.
dt_min = dt.min()

# Total time span.
trange = times[-1] - times[0]

# --- Lomb-Scargle calculation ---
num_ls_freqs = 16000
ls_min_freq = 1.0 / trange
ls_max_freq = 1.0 / dt_min
freqs = np.linspace(ls_min_freq, ls_max_freq, num_ls_freqs)
ls_pgram = lombscargle(times, counts0, 2*np.pi*freqs)

ls_peak_k = ls_pgram.argmax()
ls_peak_freq = freqs[ls_peak_k]
print "ls_peak_freq  =", ls_peak_freq


# --- FFT calculation of the binned data ---
# Assume the Lomb-Scargle calculation gave a good estimate
# of the fundamental frequency.  Use a bin size for the histogram
# of timepoints that oversamples that period by m.
m = 8
nbins = int(m * ls_peak_freq * trange + 0.5)
hist, bin_edges = np.histogram(timepoints, bins=nbins, density=True)
delta = bin_edges[1] - bin_edges[0]

fft_coeffs = np.fft.rfft(hist - hist.mean())
fft_freqs = np.fft.fftfreq(hist.size, d=delta)[:fft_coeffs.size]
# Hack to handle the case when hist.size is even.  `fftfreq` puts
# -nyquist where we want +nyquist.
fft_freqs[-1] = abs(fft_freqs[-1])

fft_peak_k = np.abs(fft_coeffs).argmax()
fft_peak_freq = fft_freqs[fft_peak_k]
print "fft_peak_freq =", fft_peak_freq


# --- Lomb-Scargle plot ---
plt.figure(1)
plt.clf()
plt.plot(freqs, ls_pgram)
plt.title('Spectrum computed by Lomb-Scargle')
plt.annotate("%6.4f Hz" % ls_peak_freq, 
             xy=(ls_peak_freq, ls_pgram[ls_peak_k]),
             xytext=(10, -10), textcoords='offset points')
plt.xlabel('Frequency (Hz)')
plt.grid(True)


# --- FFT plot ---
plt.figure(2)
plt.clf()
plt.plot(fft_freqs, np.abs(fft_coeffs)**2)
plt.annotate("%6.4f Hz" % fft_peak_freq,
             xy=(fft_peak_freq, np.abs(fft_coeffs[fft_peak_k])**2),
             xytext=(10, -10), textcoords='offset points')
plt.title("Spectrum computed by FFT")
plt.grid(True)

plt.show()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我的功率谱可信吗? lomb-scargle 和 fft 之间的比较(scipy.signal 和 numpy.fft) 的相关文章

随机推荐

  • CreateProcess 执行 Windows 命令

    我正在尝试使用 CreateProcess 函数执行 dos 命令 LPWSTR cmd LPWSTR QString C windows system32 cmd exe subst DLetter mountPath utf16 STA
  • 如何在 R 中解决简单的优化问题

    我试图使用 R 中的 optim 函数来解决一个简单的问题 但我在如何实现它方面面临一些问题 e tot obs sum Var1 sum Var2 sum Var3 sum Var4 output Var1 Var2 Var3 Var4
  • 如何查看 git repo 的接收历史记录?

    我们有一个 中央 存储库 用于部署到我们的开发服务器 我知道git log将向我显示提交及其提交的日期 时间 但我想查看提交何时被推送到存储库 由存储库接收 有办法做到这一点吗 Git s reflogs https git scm com
  • IOS视图变换修改框架?

    我有一个视图 在其中我正在绘制矩形中进行一些特定的绘图 这些绘图是动态的 并且基于视图的宽度和高度 然后 包含它的视图对其应用旋转变换 然而 这种转换似乎调整了我的视图框架的值 这会影响我在drawRect中的绘图 NSLog 之前 f f
  • Windows XP、Vista 和 7 上安装了哪个版本的 .NET Framework?

    我有一个使用 NET Framework 3 5 的应用程序 我正在为一所大学构建这个应用程序来帮助学生学习 大多数学生通常使用Windows XP SP2 Windows Vista或Windows 7 对不起Mac用户 Mac版本将在大
  • 从代码更新 LinearDoubleKeyFrame KeyTime 值

    我有一些像这样的xaml
  • 集群中的用户(会话)计数

    有没有一种好方法可以获取集群中运行的 Java Web 应用程序的登录用户数 我写了一个简单的HttpSessionListener具有静态字段 但我认为这在集群中不起作用 我可以看到有一个 Spring Security 解决方案 但我在
  • 等待完成流的读取请求

    我在用着pngjs https github com niegowski node pngjs读取和写入一些 PNG 我定期收到此错误 Error There are some read requests waiting on finish
  • 节点号 X (RESHAPE) 准备失败。使用 tflite v2.2 调整张量大小

    这是重现错误的简单代码 import os os environ CUDA VISIBLE DEVICES 1 import numpy as np from keras models import Sequential from kera
  • android中JNI调用的命名约定是什么

    例如 在android Java代码中 它调用一个native方法 private native final String native getParameters 我应该在哪里 如何 grep C 方法在哪里定义native getPar
  • 使用子位置在 XSLT 中创建网格

    我正在尝试创建一个如下指定的网格
  • Google Colab 中的检查点

    如何在 Google Colab 上存储经过训练的模型并在本地磁盘上进一步检索 检查站会起作用吗 我如何存储它们并在一段时间后检索它们 您能否提及相关代码 这会很棒 Google Colab 实例是在您打开笔记本时创建的 稍后会被删除 因此
  • 排序组合框 VBA

    我一直在考虑如何对组合框中的值进行排序 我在初始化表单时将项目添加到组合框中 因为工作表上的值数量不断增加 我使用下一个代码来添加项目 With ComboBox1 lastcell ThisWorkbook Sheets 1 Range
  • Angular PrimeNG 表使用 cols 数组每列设置管道

    我正在尝试使用 PrimeNG 学习角度 链接在这里https primefaces org primeng table https primefaces org primeng table 是否还可以使用管道数组包含每列的管道 在 col
  • 从 iTunes 搜索 API(Apple 音乐)获取 ISRC 代码

    Apple 有一个搜索 API 可让您在 iTunes Store 中查询音乐 https affiliate itunes apple com resources documentation itunes store web servic
  • 获取多维访问的线性索引

    我正在尝试实现一个多维 std array 它保存大小为 Dim n 1 Dim n 2 Dim 1 的连续内存数组 为此 我使用 std array 的私有继承 constexpr std size t factorise std siz
  • Delphi - 获取应用程序打开了哪些文件

    如何使用 Delphi 获取应用程序打开的文件的列表 例如 winword exe 打开哪些文件 使用原生API函数NtQuery系统信息 http msdn microsoft com en us library ms724509 28V
  • 如何在子资源中添加 HATEOAS 链接

    我有一个名为 管理资源 的父资源和一个名为 管理模块资源 的子资源 父级资源已正确安装 HATEOAS 链接 firstname Stephane lastname Eybert email email protected cdn cgi
  • 在带有nodejs的azure函数应用程序中使用SSL证书

    我将 pfx 证书上传到我的函数应用程序 如何加载此证书以便在我的 Nodejs 代码中使用它 如果我把它放在项目目录中 我就可以使用它并且它工作正常 但我想避免将它放在项目中 Thanks 在Azure门户中 您可以按照下图上传您的私有证
  • 我的功率谱可信吗? lomb-scargle 和 fft 之间的比较(scipy.signal 和 numpy.fft)

    谁能指出为什么我得到截然不同的结果 有很多不应该出现的峰 事实上 应该只有一个峰 我是一个 python 新手 欢迎对下面我的代码发表所有评论 测试数据在这里 在此输入链接描述 https clbin com YJkwr您可以直接wget