分类: 未分类

  • DiFX 运行和测试结果分析

    DiFX研究整体流程:

    图 1:从 VDIF 输入到复可见度分析的完整流程


    1. 本次完成了什么

    完整流程如下:

    源码安装
    → 生成 Synthetic VDIF
    → mpifxcorr 互相关
    → 生成 test-usb.difx
    → difx2fits 生成 test-usb.fits
    → Astropy 读取 UV_DATA
    → 计算幅度和相位
    

    本次结果如下:

    项目结果
    DiFX 版本2.9.0
    输入文件TEST1.vdifTEST2-usb.vdif
    模拟台站T1、T2
    基线数量1 条
    UV_DATA 记录数30
    频率通道数4096
    FLUX 长度8192
    参考频率200 MHz
    单通道带宽976.5625 Hz
    总带宽约 4 MHz

    本次测试证明了软件和数据处理链路已经跑通,但并不代表已经得到真实天体图像。


    2. DiFX 安装与环境配置

    2.1 下载并固定版本

    mkdir -p ~/software
    cd ~/software
    
    git clone --recurse-submodules https://github.com/difx/difx.git
    cd difx
    
    git checkout V2.9.0
    git submodule update --init --recursive
    git describe --tags --always
    

    正常情况下应显示:

    v2.9.0
    

    2.2 关键环境路径

    配置路径
    DIFXROOT$HOME/difx-2.9.0
    MPICXX/usr/bin/mpicxx
    IPPROOT/opt/intel/oneapi/ipp/2022.3
    PGPLOTDIR/usr/lib

    加载环境:

    source ~/software/difx/setup.bash
    

    检查变量:

    echo "$DIFXROOT"
    echo "$MPICXX"
    echo "$IPPROOT"
    echo "$PGPLOTDIR"
    

    2.3 编译安装

    mkdir -p ~/build/difx-2.9.0
    cd ~/build/difx-2.9.0
    
    source ~/software/difx/setup.bash
    ~/software/difx/install-difx --ipp 2>&1 | tee install.log
    

    检查核心相关器:

    which mpifxcorr
    
    test -x "$DIFXROOT/bin/mpifxcorr" \
      && echo "DiFX 核心相关器安装成功"
    

    3. 生成 Synthetic 模拟数据

    复制官方测试目录:

    mkdir -p ~/difx_work
    cp -a ~/software/difx/tests/Synthetic ~/difx_work/
    cd ~/difx_work/Synthetic
    

    为了缩短测试时间,将 createData.sh 中的:

    export DURATION=1200
    

    改为:

    export DURATION=10
    

    运行:

    ./createData.sh 2>&1 | tee createData.log
    

    本次生成了 8 个 VDIF 文件,总大小约 154 MB,其中测试使用:

    TEST1.vdif
    TEST2-usb.vdif
    

    VDIF 保存的是带时间标记的数字采样帧,不是图像,也不是最终科学结果。


    4. 运行最小互相关测试

    执行:

    cd ~/difx_work/Synthetic
    
    unset DISPLAY XAUTHORITY WAYLAND_DISPLAY
    ./run-usb.sh 2>&1 | tee run-usb.log
    

    脚本会自动完成:

    生成 test-usb.input / .calc / .threads
    → 调用 mpifxcorr
    → 生成 test-usb.difx
    → 调用 difx2fits
    → 生成 test-usb.fits
    

    成功日志应包含:

    Conversion successful
    1 of 1 jobs converted to 1 FITS files
    

    检查输入配置:

    grep -niE "DATA FORMAT|DATA SOURCE|BASELINE|FILE" test-usb.input
    

    本次关键结果为:

    DATA FORMAT:       VDIF
    DATA SOURCE:       FILE
    BASELINE ENTRIES:  1
    FILE 0/0:          TEST1.vdif
    FILE 1/0:          TEST2-usb.vdif
    

    这说明相关器确实读取了两路 VDIF,并完成了 T1—T2 一条基线的互相关。


    5. 配置文件和输出文件

    DiFX 不能只依靠 VDIF 文件运行,还需要配置文件说明台站、时间、频率、边带和时延模型。

    文件作用
    .vex观测计划、台站、源、频率和扫描
    .v2d数据路径与相关参数
    .inputmpifxcorr 的核心执行配置
    .calc几何时延和台站模型
    .threads线程分配
    machinesMPI 节点清单

    主要输出文件:

    输出含义
    test-usb.difx/mpifxcorr 原生复可见度结果
    DIFX_*.difx 内部的实际相关数据
    test-usb.fitsFITS-IDI 标准数据容器

    注意:FITS 文件包含二进制表,直接用文本编辑器打开出现乱码。


    6. UV_DATA 和 FLUX 的结构

    使用 Astropy 读取后,实验结果如下:

    图 2:UV_DATA结构

    本次 UV_DATA 包含:

    • 30 条记录;
    • 每条 13 个字段;
    • 1 个极化产品;
    • 1 个频带;
    • 4096 个频率通道;
    • 每条 FLUX 长度为 8192。

    为什么通道数是 4096,而 FLUX 长度是 8192?

    是由于$ N_{\mathrm{FLUX}} = 2\times1\times4096\times1\times1\times1 = 8192 $

    其中 COMPLEX = 2,表示每个通道保存实部和虚部:

    R₁, I₁, R₂, I₂, R₃, I₃, ...
    

    因此第 (k) 个通道的复可见度为:

    $ V_k=R_k+iI_k $

    第一条记录如下:

    图 3:第一条 UV_DATA 记录

    字段实际值含义
    BASELINE258$(256\times1+2)$,即 T1—T2
    INTTIM1.048576 s单条记录积分时间
    WEIGHT0.9892578相关权重,不是准确率
    UU/VV/WW基线在空间频率坐标中的投影

    7. 幅度、相位和带宽公式

    幅度:

    $ A_k=\lvert V_k\rvert =\sqrt{R_k^2+I_k^2} $

    相位:

    $ \phi_k=\operatorname{atan2}(I_k,R_k) $

    总带宽:

    $ B=N_{\mathrm{chan}}\Delta f $

    代入本次参数:

    $ B = 4096\times976.5625\ \mathrm{Hz} = 4\ \mathrm{MHz} $

    由于当前 FLUX 单位为 UNCALIB,因此幅度只是未标定相关幅度,不能直接写成 Jy。


    8. Python 读取与绘图

    安装依赖:

    python -m pip install astropy numpy matplotlib
    

    核心代码:

    from astropy.io import fits
    import matplotlib.pyplot as plt
    import numpy as np
    
    with fits.open("test-usb.fits") as hdul:
        row = hdul["UV_DATA"].data[0]
    
        flux = np.asarray(row["FLUX"], dtype=float).ravel()
    
        real = flux[0::2]
        imag = flux[1::2]
    
        visibility = real + 1j * imag
        amplitude = np.abs(visibility)
        phase_deg = np.angle(visibility, deg=True)
    
    channel = np.arange(len(visibility))
    
    plt.plot(channel, amplitude)
    plt.xlabel("Channel number")
    plt.ylabel("Visibility amplitude")
    plt.grid()
    plt.show()
    
    plt.plot(channel, phase_deg)
    plt.xlabel("Channel number")
    plt.ylabel("Visibility phase (degrees)")
    plt.grid()
    plt.show()
    

    完整脚本位于:

    scripts/analyze_difx_fits.py
    

    9. 幅度图分析

    可见度幅度:

    图 4:第一条记录的 4096 通道可见度幅度

    主要特征:

    • 频带两端逐渐下降,说明存在通带边缘滚降;
    • 中间多数通道幅度约在 0.02~0.12 范围内波动;
    • 约第 1020 通道出现最高窄峰,幅度约 0.44;
    • 约第 1530 通道出现另一明显窄峰,幅度约 0.36。

    这些峰只能称为较强窄带相关分量。由于当前是 Synthetic 数据,不能直接说成真实谱线、RFI 或某个天体信号。

    这张图表示的是一条基线、一个时间积分内,不同频率通道上的相关强度。


    10. 相位图分析

    可见度相位:

    图 5:第一条记录的 4096 通道原始包裹相位

    相位范围为:

    $ -180^\circ\leq\phi_k\leq180^\circ $

    相位密集跳变的原因主要包括:

    • 当前只使用第一条记录;
    • 没有筛选高信噪比通道;
    • 没有进行时间平均;
    • 没有相位展开;
    • 低幅度通道的相位更容易受到噪声影响;
    • 相位跨过 (180^\circ) 后会跳回 (-180^\circ)。

    因此不能说已经得到稳定条纹。

    如果要估计残余时延,应先进行通道筛选、时间平均和相位展开,再拟合:

    $ \phi(f)=\phi_0+2\pi f\tau_{\mathrm{res}} $

    残余时延为:

    $ \tau_{\mathrm{res}} = \frac{1}{2\pi} \frac{\mathrm{d}\phi}{\mathrm{d}f} $


    11. 当前结论与下一步

    11.1 已经证明

    • DiFX 2.9.0 安装成功;
    • Synthetic VDIF 数据生成成功;
    • T1—T2 一条基线互相关成功;
    • .difx 和 FITS-IDI 输出成功;
    • Astropy 能读取 UV_DATA
    • 4096 通道复可见度能够拆分并绘制幅相图。

    11.2 暂时不能证明

    • 当前幅度已经是 Jy;
    • 两个窄峰就是真实天文谱线或 RFI;
    • 原始相位已经稳定;
    • 已经完成条纹搜索和残余时延测量;
    • 已经处理 /data/Difx_data 中的真实数据。

    真实数据阶段应先检查是否存在:

    .input / .calc / .threads
    

    或者:

    .vex / .v2d
    

    随后选择小规模任务运行:

    vex2difx experiment.v2d
    calcif2 experiment
    mpirun -np 4 mpifxcorr experiment.input
    difx2fits experiment
    

    12. 总结

    本次已经完整跑通:

    VDIF 输入
    → mpifxcorr 互相关
    → .difx 输出
    → FITS 转换
    → UV_DATA 读取
    → FLUX 拆分
    → 幅度和相位提取
    

    最终确认:

    • test-usb.fits 中有 30 条 UV_DATA 记录;
    • 每条记录包含 4096 个频率通道;
    • FLUX 中的 8192 个数对应 4096 组实部和虚部;
    • 幅度图显示通带边缘滚降和两个明显窄带峰;
    • 相位图显示原始包裹相位;
    • 幅度尚未标定,相位尚未平均和展开。

    最终结论: DiFX 2.9.0 的安装、Synthetic VDIF 生成、基线互相关、.difx 输出、FITS 转换、UV_DATA 读取和幅相提取流程均已正常运行。下一步重点是处理小规模真实数据,并完成配置核验、条纹搜索、相位展开、残余时延拟合和幅相标定。

  • 格式测试

    测试标题

    内容

    define a = 0
    

    这里是 git.nvnn.org

    • 1
    • 2

    质能方程为 $E=mc^2$,其中 $c$ 表示光速。

    分数:$\frac{a}{b}$

    上下标:$x_i^2$

    希腊字母:$\alpha,\beta,\gamma,\sigma,\Delta$

    平方根:$\sqrt{x^2+y^2}$

    求和:$\sum_{i=1}^{N} x_i$

    积分:$\int_{0}^{\infty} e^{-x^2}\,dx$

    向量:$\boldsymbol{x}$

    偏导数:$\frac{\partial f}{\partial x}$