VTD 如何读取射电源先验星表
射电源先验星表为 VTD 计算理论时延提供源坐标。对于一次实验,VTD 需要从星表中找出本次观测的源,并读取它们的先验坐标。VTD 读取射电源先验星表的核心程序是 VTD_LOAD_SOUCOO(vtd/src/vtd_load_soucoo.f)。它根据文件首行的标识判断格式,再按固定列位置读取源名、赤经和赤纬。这里记录其读取过程
一、VTD 如何读取星表
- 调用程序先用
VTD_INIT初始化 VTD,再用VTD_CONF读取控制文件。控制文件最多可以指定 4 份先验星表,下面的例子使用了其中两份。
SOURCE_COORDINATES: /path/to/main_catalogue.txt
SOURCE_COORDINATES_2ND: /path/to/supplement_catalogue.txt
SOURCE_COORDINATES_3RD: NONE
SOURCE_COORDINATES_4TH: NONE
它们依次写入 VTD%CONF%FINAM_SOUCOO(1:4)。后三项可以使用 NONE;第一项直接检查文件是否存在,没有相同的 NONE 处理。
-
调用者向
VTD_LOAD提供本次实验的源数L_SOU和源名列表C_SOU。以 pSolve 为例,这两项分别来自当前实验 GVF 数据库中的NUMB_SOU和SRCNAMES。这样,实验数据库决定要查哪些源,控制文件决定去哪些星表查。通常,VTD_LOAD接着调用VTD_LOAD_SOUCOO读取源坐标。VTD__BYPS表示跳过装载,当VTD%STATUS_SOU == VTD__BYPS时,VTD_LOAD跳过这一步。 -
VTD_LOAD_SOUCOO调用RD_TEXT依次读取各份星表,根据每个文件的首行识别格式,再用数据行中的源名匹配C_SOU。只装入本次实验需要的源。对于同一个普通射电源,后读到的坐标覆盖先前的坐标。因此,第 4 份星表优先于第 3 份,依此类推,同一文件中也是后面的记录优先。如果读完所有星表仍未找到某个请求的普通射电源,程序报告错误。 -
将射电源表中的坐标转为弧度,保存到
VTD%SOU。赤经通过HR_TAT从时、分、秒转换为弧度,赤纬通过GR_TAT从度、角分、角秒转换为弧度,并计算空固系中的方向单位向量:
\(\boldsymbol{s}
=
\begin{pmatrix}
\cos\delta\cos\alpha\\
\cos\delta\sin\alpha\\
\sin\delta
\end{pmatrix}.\)
赤经、赤纬和方向单位向量分别保存在 ALPHA、DELTA 和 S_CRS(1:3) 中,供后续时延计算使用。
二、VTD 支持的七种先验源表格式
在上述读取过程中,源名、赤经和赤纬各占哪些列,取决于文件首行的标识。VTD_LOAD_SOUCOO 识别下表中的 7 种标识,表中编号就是源码中 I_FMT 的值。
| 编号 | 文件第一行的标识 | 用途 |
|---|---|---|
| 1 | # VLBI SOURCE POSITION CATALOGUE Format version of 2004.01.21 |
射电源位置星表 |
| 2 | $$ SOU-MODFILE Format pre-2000 |
旧式射电源位置文件 |
| 3 | # Catalogue of source positions and velocities. Format version of 2005.12.29 |
此读取分支提取目标名称、类型及轨道目标名称 |
| 4 | # SOURCE-NAMES v 2.0 2005.09.06 |
源名、别名及先验位置 |
| 5 | # Source position file format 1.0 of 2019.08.08 |
射电源先验位置文件 |
| 6 | # VLBI SOURCE POSITION CATALOGUE Format version of 2024.10.14 |
较新的射电源位置星表 |
| 7 | # SOURCE-NAMES v 3.0 2025.09.06 |
包含普通射电源和轨道目标的分支 |
程序直接检查首行,因此标识中的大小写和内部空格应保留,前面也不要添加空行或缩进。识别格式后,程序按相应的固定列读取数据。下表列出普通射电源的源名和坐标列位,适用于格式 1、2、4、5、6,以及格式 7 的普通源记录。格式 3 用于关联观测源名与轨道目标名,格式 7 也可以指定轨道文件或目录,这两类记录在各自的示例中说明。
| 字段 | 格式 1 | 格式 2 | 格式 4 | 格式 5 | 格式 6,以及格式 7 的普通源分支 |
|---|---|---|---|---|---|
| 主要匹配源名 | 1:8 |
5:12 |
1:8 |
4:11 |
17:24 |
| J2000 名称 | 10:19 |
不读取,设为 ?????????? |
11:20 |
14:23 |
5:14 |
| 赤经:时 | 22:23 |
15:16 |
46:47 |
26:27 |
27:28 |
| 赤经:分 | 25:26 |
18:19 |
49:50 |
29:30 |
30:31 |
| 赤经:秒 | 28:36 |
21:31 |
52:58 |
32:40 |
33:41 |
| 赤纬:符号及度 | 38:40 |
35:37 |
60:62 |
43:45 |
43:45 |
| 赤纬:角分 | 42:43 |
39:40 |
64:65 |
47:48 |
47:48 |
| 赤纬:角秒 | 45:52 |
42:51 |
67:72 |
50:57 |
50:57 |
表中的列号从 1 起算,起止列都包括在内。各格式对这些字段的读法略有不同。
- 格式 1、2 分别截取三个坐标分量,再用
_拼接后解析。 - 格式 4 直接解析
46:58和60:72,典型写法是12_34_56.1234、+12_34_56.123。 - 格式 5 直接解析
26:40和43:57,典型写法是12:34:56.123456、+12:34:56.12345。 - 格式 6 会将第
29、32、46、49列改成冒号,然后解析坐标。因此,原始记录可以采用时、分、秒之间用空格分隔的形式。 - 程序用“主要匹配源名”一栏所列的字段查找
C_SOU中的源。格式 4 还会尝试别名。各格式中的 J2000 名称字段用于保存名称,不参与这里的匹配。 - 星表中的位置误差、相关系数、流量密度等附加字段,没有被这个坐标读取程序读入。
1. 2004年版 VLBI 射电源位置星表
第一行标明版本 2004.01.21。以 3C273B 为例,把坐标按格式 1 重排,就可以将上表中的列位与实际数据行逐项对照。
# VLBI SOURCE POSITION CATALOGUE Format version of 2004.01.21
3C273B J1229+0203 12 29 06.699755 +02 03 08.59830
| 字段 | 源码读取的列 | 示例值 |
|---|---|---|
IVS 名称,用于匹配 C_SOU |
1:8 |
3C273B |
| J2000 名称 | 10:19 |
J1229+0203 |
| 赤经的时、分、秒 | 22:23、25:26、28:36 |
12 29 06.699755 |
| 赤纬的符号及度、角分、角秒 | 38:40、42:43、45:52 |
+02 03 08.59830 |
程序分别截取赤经、赤纬的三个分量,用下划线拼起来,再转换为弧度。
2. SOU-MODFILE
这是 VTD 为兼容旧文件保留的格式。下面是格式说明中的原始示例,数据行开头有 4 个空格。
$$ SOU-MODFILE Format pre-2000
2357-326 00 00 20.399945 -32 21 01.23327 0.60 ! J0000-3221
| 字段 | 源码读取的列 | 示例值 |
|---|---|---|
IVS 名称,用于匹配 C_SOU |
5:12 |
2357-326 |
| 赤经的时、分、秒 | 15:16、18:19、21:31 |
00 00 20.399945 |
| 赤纬的符号及度、角分、角秒 | 35:37、39:40、42:51 |
-32 21 01.23327 |
值得注意的是,行末虽然写着 ! J0000-3221,但这是注释。这个分支把 J2000_NAME 直接设成 ??????????,也不读取 0.60 这个位置误差值。
3. 2005年版 VLBI 射电源位置与速度星表
源代码中的 vtd/share/titan_apr.src 使用这种格式。下面是它的第一条数据记录,HYIGENS 保留文件中的实际拼写。
# Catalogue of source positions and velocities. Format version of 2005.12.29
2005.01.14_10:00:00.0000000000 TAI S S_000001 HYIGENS
| 字段 | 列位置 | 示例值 | VTD_LOAD_SOUCOO 的处理 |
|---|---|---|---|
| 日期及时间尺度 | 1:30、33:35 |
2005.01.14_10:00:00.0000000000、TAI |
本分支不解析这两个字段 |
| 目标类型 | 38 |
S |
写入 OBJ_TYPE,这里表示太阳系内的近场目标 |
| 观测源名 | 41:48 |
S_000001 |
与 C_SOU 匹配,写入 IVS_NAME |
| 轨道目标名 | 51:58 |
HYIGENS |
写入 NZO_NAME,用于关联轨道数据 |
这条记录的含义是:实验中的 S_000001 对应轨道目标 HYIGENS。下一条记录又把 S_000002 指向同一个 HYIGENS。尽管格式名称里有“位置和速度”,这个读取分支实际只取目标类型和两个名称。
4. SOURCE-NAMES v2.0
这是源代码中 vtd/share/source.names 使用的格式。一条记录同时给出同一个射电源的多个名称和一组先验坐标。下面是 3C273B 的原始记录。
# SOURCE-NAMES v 2.0 2005.09.06
3C273B J1229+0203 1226+023 3C273 C 12_29_06.6997 +02_03_08.598 0.17 ! rfc_2024c
| 字段 | 源码读取的列 | 示例值 | 用途 |
|---|---|---|---|
| IVS 名称 | 1:8 |
3C273B |
第一个尝试匹配的名称,也是最终保存的 IVS_NAME |
| J2000 名称 | 11:20 |
J1229+0203 |
保存到 J2000_NAME,不参与这个分支的名称匹配 |
| B1950 名称 | 23:30 |
1226+023 |
第二个尝试匹配的名称 |
| 其他名称,本例为 AIPS 名称 | 33:42 |
3C273 |
第三个尝试匹配的名称 |
| 赤经、赤纬 | 46:58、60:72 |
12_29_06.6997、+02_03_08.598 |
转换为弧度 |
需要注意,即使实验数据中给的是 1226+023,程序也能找到这一行,但保存的 IVS_NAME 仍是 3C273B。后续 VTD_SOU_INDEX 按 3C273B 查找这条记录。
5. 2019年版 VLBI 射电源位置星表
格式 4 把 3C273B 和 1226+023 放在同一行。再看使用格式 5 的 vtd/share/glo.src,这两个名称分别出现在相邻的两行中。数据行开头各有 3 个空格。
# Source position file format 1.0 of 2019.08.08
3C273B J1229+0203 12:29:06.699755 +02:03:08.59830 0.170 1 ! rfc_2026a
1226+023 J1229+0203 12:29:06.74 +02:03:08.3 999.999 0 ! apriori bc191
这个分支用 4:11 的名称匹配 C_SOU,从 14:23 保存 J2000 名称,从 26:40 和 43:57 分别读取赤经、赤纬。两行虽然共用 J1229+0203,VTD 却会根据实验名单选取不同的坐标。名单中给 3C273B 就匹配第一行,给 1226+023 就匹配第二行。
Leonid 经常使用这种格式。下面这份文件保留了表头,可以对照其中的字段说明和实际数据行。
# Source position file format 1.0 of 2019.08.08
#
# Generated with update_apr_cat /sol/rfc/rfc_2025b/rfc_2025b_apr.src /tmp/rfc_2025b_cat.txt rfc_2025b /sol/rfc/rfc_2025b/rfc_2025b_aposteriori.src nokeepICRFdef
#
# EPOCH 2016.01.01
#
# Last update: 2026.06.24_15:08:15
#
# Modifications:
#
# who when what
# L. Petrov 2026.06.24 Upated according to rfc_2026b solution
#
# Format description
#
# Byte-by-byte description of file:
# --------------------------------------------------------------------------------
# Bytes Format Units Label Explanations
# --------------------------------------------------------------------------------
# 4-11 A8 --- Name IVS source name in B1950 IAU notation
# 14-23 A10 --- Name RFC source ID in J2000 IAU notation
# 26-27 I2 h RAh Hour of Right Ascension (J2000)
# 28-28 A1 --- : Delimiter: colon
# 29-30 I2 m RAm Minutes of Right Ascension (J2000)
# 32-41 F10.7 s RAs Second of Right Ascension (J2000)
# 43-43 A1 --- DE- Sign of the Declination (J2000): either - or +
# 44-45 I2 deg DEd Degree of Declination (J2000)
# 46-46 A1 --- : Delimiter: colon
# 47-48 I2 arcmin DEm Arcminute of Declination (J2000)
# 49-49 A1 --- : Delimiter: colon
# 50-58 F9.6 arcsec DEs Arcsecond of Declination (J2000)
# 61-67 F7.3 arcsec SigMaj Semi-major error ellipse axis in mas
# 70-70 I1 --- Class Source class:
# 0 -- non-detected source
# 1 -- detected non-geodetic source
# 2 -- geodetic source
# 3 -- geodetic source candidate
# 9 -- ghost source
# 73-73 A1 --- ! Delimiter: exclamation sign
# 75- A --- Comm Comment
#
# IVS name RFC ID Right ascension Declination Error C !
# -----------------------------------------------------------------------
#
0000-000 0000-000 00:00:00.00 00:00:00.0 999.999 0 ! J0000-0000 filler
NOFRINGE NOFRINGE 00:00:00.00 00:00:00.0 999.999 0 ! NOFRINGE filler
GALCENTR J1745-2900 17:45:40.0360 -29:00:28.167 999.999 0 ! Galactic center
#
2357+67A J0000+6810 00:00:01.536 +68:10:02.42 999.999 0 ! apriori BP252AL pri 41.0 mJy 1.5 arcsec
2357-006 J0000-0021 00:00:01.659837 -00:22:10.02335 2.700 1 ! rfc_2026b
6. 2024年版 VLBI 射电源位置星表
与格式 1 相比,最明显的变化是两个名称的排列顺序反过来了。文件先写 RFC 标识,再写用于匹配的常用名。下面将 3C273B 的坐标按格式 6 重排,只保留 VTD 所需的部分。
# VLBI SOURCE POSITION CATALOGUE Format version of 2024.10.14
RFC J1229+0203 3C273B 12 29 06.699755 +02 03 08.59830
| 字段 | 列位置 | 示例值 |
|---|---|---|
| 完整 RFC 标识 | 1:14 |
RFC J1229+0203 |
其中保存为 J2000_NAME 的部分 |
5:14 |
J1229+0203 |
常用名,用于匹配并保存为 IVS_NAME |
17:24 |
3C273B |
| 赤经 | 27:41 |
12 29 06.699755 |
| 赤纬 | 43:57 |
+02 03 08.59830 |
程序把第 29、32、46、49 列的分隔符改成冒号,再转换坐标。完整 RFC 记录后面还可以有位置误差、相关系数、观测数和流量密度等字段,这个读取分支只取名称和坐标。
7. SOURCE-NAMES v3.0
这个格式在同一个文件里允许两类记录。程序先读第 43 列:D 或 F 进入轨道目标分支,其他字符进入普通射电源分支。下面按源码实际读取的列位构造三条示例,后两行的轨道路径是示意路径。
# SOURCE-NAMES v 3.0 2025.09.06
RFC J1229+0203 3C273B 12 29 06.699755 +02 03 08.59830
N_12345 12345 E F /example/orbits/12345.tle
N_23456 23456 E D /example/orbits/gnss
第一条是普通射电源。 第 43 列是赤纬的正号 +。程序按格式 6 的布局读取,用 17:24 的 3C273B 匹配源名,用 27:41、43:57 读取赤经、赤纬。这里有一处重要的文档差异:vtd_formats.txt 为 v3 普通源规定的是 1:8 的 IVS 名、46:58 的赤经和 60:72 的赤纬。按文档排出的普通源记录,当前源码可能找不到源,或者从错误的列读取坐标。把格式 4 的 source.names 只换成 v3 的首行,不能完成格式转换。
第二、三条是轨道目标。 它们按以下字段读取。
| 列位置 | 含义 | 第二条示例 | 第三条示例 |
|---|---|---|---|
1:8 |
与 C_SOU 匹配的目标名 |
N_12345 |
N_23456 |
11:15 |
NORAD 编号,空白时设为 0 | 12345 |
23456 |
41 |
目标类型 | E |
E |
43 |
轨道数据所在位置 | F,指定文件 |
D,指定目录 |
46: |
文件或目录路径 | /example/orbits/12345.tle |
/example/orbits/gnss |
对于轨道目标,第 41 列给出目标类型,允许值见下表。第 43 列决定如何检查路径。若为 D,指定的目录必须存在。若为 F,指定的文件必须存在,程序还会检查轨道文件格式。如果是 TLE 文件,程序会核对文件中的 NORAD 编号与星表第 11:15 列是否一致。
类型常量在 vtd_i.templ 中定义:
| 值 | 源码定义 |
|---|---|
S |
太阳系内的近场目标 |
E |
地球附近的近场目标 |
R |
射电发射体 |
三、位置参考历元
前面各例说明了 VTD 怎样从数据行读取源名和坐标。坐标的参考历元则由注释行给出,如格式 5 示例中的 # EPOCH 2016.01.01。程序识别以下三种写法,均取第三个字段作为日期。
# EPOCH 2016.01.01
# EPOCH: 2016.01.01_00:00:00
# Reference_epoch: 2016.01.01_00:00:00
VTD_LOAD_SOUCOO 在开始处理各份星表之前,将参考历元设为 MJD_REF = 51544、TAI_REF = 0。遇到历元行时,程序调用 DATE_TO_TIME 将日期转换成新的 MJD_REF 和 TAI_REF,供后续源记录使用。进入下一份星表时,这两个变量不会重新初始化。因此,若主星表给出了 2016 年的参考历元,而补充星表没有自己的历元行,补充星表中的普通源也会沿用这一历元。组合多份星表时,最好在每份文件的数据行之前明确写出参考历元。普通源的位置记录给出坐标,历元行说明这些坐标对应的参考历元。自行和视差另有来源,由 VTD_LOAD_SOUPRL 读取控制文件中 SOURCE_PRLX_PRP_MOTION: 指定的文件。