“在某处,有不可思议的事物正在等待被发现。”——卡尔·萨根,《宇宙》(Cosmos, 1980)
1977 年,天文学家杰里·埃曼在俄亥俄州立大学望远镜的打印纸上写下了“Wow!”。那段持续约 72 秒的信号来自人马座方向,至今仍没有被完全解释。
图 1:1977 年 Wow! 信号的计算机打印记录。图片来源:Wikimedia Commons,原始来源为 Big Ear Radio Observatory and North American AstroPhysical Observatory。
从那次观测到今天,射电天文学已经积累了更灵敏的接收设备和更大的公开数据集。2015 年启动的 Breakthrough Listen 是由加州大学伯克利分校 SETI(地外文明搜寻)研究中心组织的项目,使用绿岸射电望远镜(GBT)和帕克斯望远镜等设备,系统寻找可能来自其他文明的无线电信号。
射电望远镜接收的是一段频率范围内的电磁波。如果一个信号的能量覆盖较宽的频率范围,我们称它为宽带信号;如果能量集中在很窄的频率范围内,则称为窄带信号。电视台载波、卫星通信和雷达都可能产生窄带成分。SETI 优先检查窄带信号,因为有意传输的信息往往集中在特定频率附近,而多数自然天体辐射的频率范围要宽得多。
如果信号源和望远镜之间存在相对运动,接收到的频率会随时间改变,这就是多普勒漂移。程序用漂移率表示这种变化的速度,单位是 Hz/s:正值代表频率向高处移动,负值代表向低处移动。把频率画在横轴、时间画在纵轴时,固定频率的信号接近竖线,发生漂移的信号才会逐渐偏向一侧。
最后还要判断信号是否明显高于背景。搜索结果中的 SNR 是信噪比,用来比较候选信号与附近噪声的强弱;SNR 越高,信号相对背景越突出,但仍需要进一步复核。观测中还混有 RFI,即射频干扰(radio-frequency interference),来源包括地面通信设备、卫星、雷达和望远镜自身的电子部件。后面的分析会同时使用窄带特征、漂移率和 SNR 筛选候选,再逐一排查这些干扰。
望远镜记录的是混杂着噪声和干扰的无线电功率数据,而我们的目标就是从这些数据中找出异常模式。
过去,这类分析通常依赖观测机构的专用软件和计算设施。现在,只要使用公开数据配合 Python 脚本,就可以在本地完成对这些数据的分析。本文使用 blimpy 和 turboSETI 两个第三方库,读取观测文件,生成瀑布图,调用漂移搜索器,并把候选信号的频率、漂移率和信噪比写入结果文件。然后对这些候选结果进行射频干扰排除、多波束比较和独立观测验证,判断某个候选是否值得继续研究。
下面从一份公开观测开始,按这个顺序完成数据读取、可视化和漂移搜索。
图 2:从公开观测文件到候选信号的基本处理链。
Breakthrough Listen 在 Open Data 页面公开了 GBT 和 Parkes 的部分观测,常见格式是 .h5 和 .fil。这两种格式都可以保存频率通道、时间采样和功率值,只是具体的文件组织方式不同。
本文使用一份来自 GBT 的 HIP17147 观测文件,读者可以自行下载:
HIP17147 GBT 观测文件地址
拿到数据文件后,就可以使用 blimpy 对其进行读取。读取观测文件只需要创建一个 Waterfall 对象:
from pathlib import Pathfrom blimpy import Waterfallfile_path = Path("data/hip17147_gbt_0002.h5")obs = Waterfall(str(file_path))obs.info()
Waterfall 会读取文件头中的目标名称、频率上下界、通道数和时间分辨率等信息:
--- File Info ---DIMENSION_LABELS : ['frequency' 'feed_id' 'time'] az_start : 0.0 data_type : 1 fch1 : 2802.83203125 MHz foff : -0.00286102294921875 MHz machine_id : 20 nbits : 32 nchans : 351232 nifs : 1 source_name : HIP17147 src_dej : -3:27:36.009 src_raj : 3:40:22.676 telescope_id : 6 tsamp : 1.0737418239999998 tstart (ISOT) : 2016-10-07T08:01:40.000 tstart (MJD) : 57668.33449074074 za_start : 0.0
如果 obs.info() 显示的频率范围不包含计划查看的区间,可以调整参数或换一份数据。
原始文件里保存的是连续时间片上的功率数组,直接查看数字很难判断信号的变化。分析时把每个时间片的频谱按顺序堆叠起来,再用颜色表示功率强弱,就能得到瀑布图(waterfall plot)。瀑布图将每次采样得到的频谱按时间顺序排列:横轴是频率,纵轴是观测时间,颜色表示接收到的功率强弱。始终停留在同一频率上的信号会形成竖线,频率随时间变化时,轨迹会向一侧倾斜。
使用本文附带的 src/inspect_waterfall.py 脚本就可以生成指定频率范围的瀑布图:
python src/inspect_waterfall.py \ data/hip17147_gbt_0002.h5 \ --f-start 1800 --f-stop 2800 \ --output outputs/waterfall.png
运行后得到的图片如下:
图 3:使用公开的 HIP17147 GBT 观测文件生成的频谱瀑布图。
图 3 中最显眼的是贯穿整个观测时段的竖直色带,其中约 2190 MHz 附近有一条较亮的窄带。这些色带说明接收功率会随频率发生明显变化,但它们形成的原因还无法从这张图中确定,既可能与射频干扰有关,也可能来自望远镜接收系统的频率响应。
为了寻找值得进一步追踪的信号源,不能只看某个频率在图上有多亮,还需要考虑它的强度是否持续,以及所在频率是否随时间改变。对于持续发射的窄带信号,信号源和望远镜之间的相对运动会让接收频率随时间改变,这种变化称为多普勒漂移。我们用“漂移率”表示频率改变的快慢,单位是 Hz/s;它取决于观测频率以及信号源与望远镜之间的径向运动。由于真实漂移率事先未知,搜索时要先设定一个范围,再在范围内逐一检验不同的数值。
由 Breakthrough Listen 团队开发的 turboSETI 专门用于搜索具有多普勒漂移的窄带信号。对每一个待检验的漂移率,它会把各次采样中预测位置的频率通道重新对齐,将这些位置上的功率累加,再与附近的背景噪声比较;这个过程称为去多普勒漂移(de-Doppler)。
我们只要指定观测文件、漂移率范围和信噪比(SNR)门槛等参数就可以进行搜索:
from turbo_seti.find_doppler.find_doppler import FindDopplersearch = FindDoppler( "data/hip17147_gbt_0002.h5", max_drift=4, # 搜索 -4 到 +4 Hz/s snr=10, # 只保留 SNR >= 10 的候选 out_dir="outputs/turboSETI",)search.search()
max_drift=4 表示搜索范围从 -4 到 +4 Hz/s,同时覆盖向高频和向低频移动的情况;snr=10 要求候选轨迹的信噪比至少达到 10。
可以直接使用本文附带的 src/search_doppler.py 脚本搜索候选信号:
python src/search_doppler.py \ data/hip17147_gbt_0002.h5 \ --max-drift 8 \ --snr 10 \ --out-dir outputs/turboSETI
运行后,turboSETI 会在指定目标生成一个 .dat 文件,其中头部包含了一些搜索参数和元数据:
# -------------------------- o --------------------------# File ID: hip17147_gbt_0002.h5# -------------------------- o --------------------------# Source:HIP17147# MJD: 57668.334490740737 RA: 3h40m22.676s DEC: -3d27m36.009s# DELTAT: 1.073742 DELTAF(Hz): -2861.022949 max_drift_rate: 8.000000 obs_length: 293.131518# --------------------------
搜索完成后,满足阈值的数据会追加在文件头之后,记录漂移率、SNR 和频率等字段:
如果没有发现任何记录,可以尝试调整max-drift和snr参数。
turboSETI 采用线性漂移率模型,但实际天体运动(如行星轨道加速度、星际介质色散)可能引入高阶非线性分量,导致信号能量在FFT频谱中无法被有效积分;SNR 阈值的设定则面临检测理论中的根本困境——降低阈值会大幅增加RFI污染和统计涨落误报,提高阈值则可能遗漏真实但较弱的窄带发射。
因此,获取候选清单只是一个起点,真正区分天体信号与地球干扰需要经过多层验证。
1. 多波束比较:信号是否只在目标波束出现,而不是同时出现在 off-target 或旁瓣观测中。
2. 频率重合查询:信号是否与已知卫星、航空、地面台站或仪器频率重合。可以通过 astropy 库查询已知天体谱线频率,卫星频段和地面台站归属需查阅国际电信联盟(ITU)《无线电规则》及各国家的频率分配表。
3. 跨观测复现:信号是否在不同历元或不同望远镜中重复出现。
4. 信号形态分析:信号形态是否符合窄带漂移模型,而非固定频率的本地干扰。
如果某个窄带信号在目标方向出现,漂移率合理,并且通过了这些验证,它才值得进入后续的天文学研究。
从 Wow! 信号到今天的公开数据档案,SETI 始终在追问同一个问题:我们在宇宙中,究竟是不是孤独的。
过去,这个问题似乎只属于拥有巨型射电望远镜和专业设备的研究机构。如今,一个普通的 Python 开发者就可以下载真实的射电观测数据,从频谱中寻找异常,运行漂移搜索算法,并亲手验证一个候选信号。
本文用一份公开的 GBT 观测文件完成了从数据读取、瀑布图绘制到多普勒漂移搜索的基本流程。读者可以在相同环境中重新运行这些脚本,调整漂移率范围和 SNR 门槛,再对输出的候选结果进行验证。后续工作仍然依赖更完整的观测数据和严格的射频干扰排查。
代码和文档地址:https://pan.baidu.com/s/1Ty-dxvJVzXU_kWHDE_WFYg?pwd=sfsq