<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://liuniu.fun/feed.xml" rel="self" type="application/atom+xml" /><link href="https://liuniu.fun/" rel="alternate" type="text/html" /><updated>2026-08-21T22:22:28+08:00</updated><id>https://liuniu.fun/feed.xml</id><title type="html">Niu Liu (刘牛)</title><subtitle>My personal website</subtitle><author><name>Niu Liu</name><email>niu.liu@nju.edu.cn</email></author><entry><title type="html">安装SGDASS可能遇到的问题及解决方案</title><link href="https://liuniu.fun/blogs/sgdass_installation_notes.html" rel="alternate" type="text/html" title="安装SGDASS可能遇到的问题及解决方案" /><published>2023-12-15T00:00:00+08:00</published><updated>2023-12-15T00:00:00+08:00</updated><id>https://liuniu.fun/blogs/sgdass_installation_notes</id><content type="html" xml:base="https://liuniu.fun/blogs/sgdass_installation_notes.html"><![CDATA[<p>SGDASS全称为Space Geodesy Data Analysis Software System，
是Leonid Petrov开发的空间测地数据分析软件套装。
本文提到的问题都是在首次安装SGDASS和<code class="language-plaintext highlighter-rouge">pSolve</code>时遇到的，不适用于软件升级的情况。</p>

<!-- more -->

<p>SGDASS的官网地址为：<a href="http://astrogeo.org/sgdass/">http://astrogeo.org/sgdass/</a>。
安装教程地址为<a href="http://astrogeo.org/backup/sgdass_20211218_INSTALL.txt">http://astrogeo.org/backup/sgdass_20211218_INSTALL.txt</a>。
尽管Leonid已经写了非常详细的安装教程,
并写了自动化安装脚本<code class="language-plaintext highlighter-rouge">sgdass_install.py</code>，
其目的我想也是为了简化用户的安装过程，省去不必要的麻烦。
即使这样，我在安装的时候仍遇到了问题，现记录如下，以作为安装教程的补充。</p>

<h2 id="编译器问题">编译器问题</h2>

<p>SGDASS的安装教程提到安装SGDASS最好使用gcc-11.2.0版本（Leonid测试时用的版本）以及相应的gfortran和g++。
为此，我将服务器系统升级到了Ubuntu 21.10，
此时系统自带的gcc编译器(<code class="language-plaintext highlighter-rouge">/usr/bin/gcc</code>)就是11.2版本。
然而，如果使用系统自带的gcc和gfortran编译器，在编译<code class="language-plaintext highlighter-rouge">hdf5</code>时就会得到如下的报错</p>

<blockquote>
  <p>f951: Fatal Error: Reading module ‘h5global.mod’ at line 1556 column 38: Unexpected EOF</p>
</blockquote>

<p>这是由于编译器的库依赖不兼容导致的。
检查服务器自带的gcc版本，得到结果如下</p>

<blockquote>
  <p>Using built-in specs.</p>

  <p>COLLECT_GCC=/usr/bin/gcc</p>

  <p>COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper</p>

  <p>OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa</p>

  <p>OFFLOAD_TARGET_DEFAULT=1</p>

  <p>Target: x86_64-linux-gnu</p>

  <p>Configured with: ../src/configure -v –with-pkgversion=’Ubuntu 11.2.0-7ubuntu2’ –with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs –enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 –prefix=/usr –with-gcc-major-version-only –program-suffix=-11 –program-prefix=x86_64-linux-gnu- –enable-shared –enable-linker-build-id –libexecdir=/usr/lib –without-included-gettext –enable-threads=posix –libdir=/usr/lib –enable-nls –enable-bootstrap –enable-clocale=gnu –enable-libstdcxx-debug –enable-libstdcxx-time=yes –with-default-libstdcxx-abi=new –enable-gnu-unique-object –disable-vtable-verify –enable-plugin –enable-default-pie –with-system-zlib –enable-libphobos-checking=release –with-target-system-zlib=auto –enable-objc-gc=auto –enable-multiarch –disable-werror –enable-cet –with-arch-32=i686 –with-abi=m64 –with-multilib-list=m32,m64,mx32 –enable-multilib –with-tune=generic –enable-offload-targets=nvptx-none=/build/gcc-11-ZPT0kp/gcc-11-11.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-ZPT0kp/gcc-11-11.2.0/debian/tmp-gcn/usr –without-cuda-driver –enable-checking=release –build=x86_64-linux-gnu –host=x86_64-linux-gnu –target=x86_64-linux-gnu –with-build-config=bootstrap-lto-lean –enable-link-serialization=2</p>

  <p>Thread model: posix</p>

  <p>Supported LTO compression algorithms: zlib zstd</p>

  <p>gcc version 11.2.0 (Ubuntu 11.2.0-7ubuntu2)</p>
</blockquote>

<p>Leonid认为可能是<code class="language-plaintext highlighter-rouge">--with-arch-32=i686</code>的编译flag，
导致编译生成了32位架构的模块(<code class="language-plaintext highlighter-rouge">h5global.mod</code>?)，从而产生了错误。</p>

<p>解决方法是依照SGDASS安装说明中第V条的方法，在<code class="language-plaintext highlighter-rouge">/opt64/</code>目录下编译安装gcc-11.2.0，
并使用新编译的gcc和gfortran编译器来编译安装SGDASS。</p>

<h2 id="编译vex_parser和sur_sked时的问题">编译<code class="language-plaintext highlighter-rouge">vex_parser</code>和<code class="language-plaintext highlighter-rouge">sur_sked</code>时的问题</h2>

<p>在解决编译器的问题之后，<code class="language-plaintext highlighter-rouge">hdf5</code>编译非常顺利，但是在编译<code class="language-plaintext highlighter-rouge">vex_parser</code>时又遇到了报错</p>
<blockquote>

  <p>make[1]: Entering directory ‘/data/sgdass/progs/vex_parser_20210707/src’</p>

  <p>I/opt64/include -I../include -c -o get_band_range.o get_band_range.f</p>

  <p>I/opt64/include -I../include -c -o matsub_nh.o matsub_nh.f</p>

  <p>I/opt64/include -I../include -c -o vex_ang_fmts.o vex_ang_fmts.f</p>

  <p>I/opt64/include -I../include -c -o vex_compar.o vex_compar.f</p>

  <p>I/opt64/include -I../include -c -o vex_flags.o vex_flags.f</p>

  <p>I/opt64/include -I../include -c -o vex_lists.o vex_lists.f</p>

  <p>I/opt64/include -I../include -c -o vex_parser.o vex_parser.f</p>

  <p>I/opt64/include -I../include -c -o vex_sou_idx.o vex_sou_idx.f</p>

  <p>I/opt64/include -I../include -c -o vex_sta_idx.o vex_sta_idx.f</p>

  <p>I/opt64/include -I../include -c -o sou_struc_fil_gen.o sou_struc_fil_gen.f</p>

  <p>I/opt64/include -I../include -c -o souivs_to_sourfc.o souivs_to_sourfc.f</p>

  <p>I/opt64/include -I../include -c -o sourfc_to_souivs.o sourfc_to_souivs.f</p>

  <p>I/opt64/include: Command not found.</p>

  <p>I/opt64/include: Command not found.</p>

  <p>I/opt64/include: Command not found.</p>

  <p>I/opt64/include: Command not found.</p>

  <p>make[1]: [makefile:14: vex_compar.o] Error 1 (ignored)</p>

  <p>I/opt64/include -I../include -c -o stp_compar.o stp_compar.f</p>

  <p>make[1]: [makefile:14: matsub_nh.o] Error 1 (ignored)</p>

  <p>make[1]: [makefile:14: vex_ang_fmts.o] Error 1 (ignored)</p>

  <p>I/opt64/include -I../include -c -o stp_dir_parser.o stp_dir_parser.f</p>

  <p>I/opt64/include: Command not found.</p>

  <p>make[1]: [makefile:14: get_band_range.o] Error 1 (ignored)</p>

  <p>I/opt64/include -I../include -c -o stp_fil_parser.o stp_fil_parser.f</p>

  <p>I/opt64/include: Command not found.</p>

  <p>I/opt64/include -I../include -c -o stp_obs_err.o stp_obs_err.f</p>

  <p>I/opt64/include: Command not found.</p>

  <p>make[1]: [makefile:14: vex_flags.o] Error 1 (ignored)</p>

  <p>I/opt64/include -I../include -c -o stp_sefd.o stp_sefd.f</p>

  <p>make[1]: [makefile:14: vex_lists.o] Error 1 (ignored)</p>

  <p>make[1]: [makefile:14: vex_parser.o] Error 1 (ignored)</p>

  <p>I/opt64/include -I../include -c -o stp_snr.o stp_snr.f</p>

  <p>I/opt64/include -I../include -c -o stp_sta_idx.o stp_sta_idx.f</p>

  <p>I/opt64/include: Command not found.</p>

  <p>I/opt64/include: Command not found.</p>

  <p>编译<code class="language-plaintext highlighter-rouge">sur_sked</code>遇到的问题与此类似，二者均是因为环境变量的设置问题。
具体而言，编译这两个软件需要使用一些在<code class="language-plaintext highlighter-rouge">/opt64/bin/petools_vars</code>中定义的环境变量，
但是这些变量并没有在定义。</p>
</blockquote>

<p>解决方法：在<code class="language-plaintext highlighter-rouge">.cshrc</code>中加入一行</p>

<p><code class="language-plaintext highlighter-rouge">source /opt64/bin/petools_vars</code></p>

<p>来实现这些变量的定义。
不过，<code class="language-plaintext highlighter-rouge">petools_vars</code>是在编译<code class="language-plaintext highlighter-rouge">petools</code>时从<code class="language-plaintext highlighter-rouge">petools</code>代码压缩包中解压并复制到<code class="language-plaintext highlighter-rouge">/opt64/bin/</code>
目录下的。
因此，为了保证编译顺利，有两种解决方法：</p>

<ul>
  <li>解压<code class="language-plaintext highlighter-rouge">petools</code>代码压缩包，手动复制<code class="language-plaintext highlighter-rouge">petools_vars</code>到<code class="language-plaintext highlighter-rouge">/opt64/bin/</code>目录下；</li>
  <li>编译两次。</li>
</ul>

<h2 id="postinstall之前的准备"><code class="language-plaintext highlighter-rouge">postinstall</code>之前的准备</h2>

<p>在编译完成之后，需要进行一些额外的配置，来保证<code class="language-plaintext highlighter-rouge">pSolve</code>和<code class="language-plaintext highlighter-rouge">PIMA</code>的正常工作。
首先就是要将<code class="language-plaintext highlighter-rouge">/opt64/bin</code>加入在<code class="language-plaintext highlighter-rouge">PATH</code>路径变量中去。</p>

<p>查看安装配置文件的末尾，如<code class="language-plaintext highlighter-rouge">sgdass_config_astrogeo.cnf</code>，有</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[PostInstall]:

psolve    psolve_reset AU 48000 48000

vtd       ${prefix}/bin/vtd_apriori_update.py -c /vlbi/vtd_data/apr.conf

pima      ${prefix}/bin/create_fftw_plan MEASURE 1           ${prefix}/share/pima/pima_wis_big.inp ${prefix}/share/pima/pima_wis_big_1thr.wis
pima      ${prefix}/bin/create_fftw_plan MEASURE 16          ${prefix}/share/pima/pima_wis_big.inp ${prefix}/share/pima/pima_wis_big_16thr.wis
pima      ${prefix}/bin/create_fftw_plan MEASURE ${num_proc} ${prefix}/share/pima/pima_wis_big.inp ${prefix}/share/pima/pima_wis_big_${num_proc}thr.wis

malo      ${prefix}/bin/malo_fftw_plan_create.csh
</code></pre></div></div>

<p>熟悉<code class="language-plaintext highlighter-rouge">Solve</code>的人可能知道，每次添加一名Solve的新用户（假设代号为XX），
首先需要在<code class="language-plaintext highlighter-rouge">letok</code>文件中加入一行</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>XX  Some_Note
</code></pre></div></div>

<p>，之后运行</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>solve_reset XX max_num_obs(具体数字) max_num_par(具体数字) 
</code></pre></div></div>

<p>来配置。
<code class="language-plaintext highlighter-rouge">solve_reset</code>的用法可以通过运行<code class="language-plaintext highlighter-rouge">solve_reset</code>来获知，此处不细说。</p>

<p>使用<code class="language-plaintext highlighter-rouge">pSolve</code>也需要执行同样的步骤。
对于<code class="language-plaintext highlighter-rouge">pSolve</code>，<code class="language-plaintext highlighter-rouge">letok</code>文件所在的目录为<code class="language-plaintext highlighter-rouge">/opt64/share/psolve/</code>。
在加入新用户之后，将SGDASS安装配置文件的用户代号（
如<code class="language-plaintext highlighter-rouge">sgdass_config_astrogeo.cnf</code>中的“AU”）替换为新用户的代号。
如果服务器上有多个用户，每个用户都需要执行一次<code class="language-plaintext highlighter-rouge">psolve_reset</code>。</p>

<h2 id="结语">结语</h2>

<p>写到这里，整个安装过程近乎完成。
如果将来我遇到了新的安装问题，我将会在这里更新。
像<code class="language-plaintext highlighter-rouge">Calc/Solve</code>和<code class="language-plaintext highlighter-rouge">pSolve</code>这样非常小众的软件包，维护有限，用户手册也不多，
安装时遇到的问题很多且没有现成的解决方案，初学者常止步于安装这一步。
这一点我自己是深有体会的。
Leonid在方便用户安装他的软件包方面做了很好的示范，我在这里也分享我的一点经验，
希望可以帮到国内的同行。</p>]]></content><author><name>Neo</name></author><category term="VLBI" /><category term="software" /><summary type="html"><![CDATA[SGDASS全称为Space Geodesy Data Analysis Software System， 是Leonid Petrov开发的空间测地数据分析软件套装。 本文提到的问题都是在首次安装SGDASS和pSolve时遇到的，不适用于软件升级的情况。]]></summary></entry><entry><title type="html">统计天体测量</title><link href="https://liuniu.fun/blogs/statistical_astrometry.html" rel="alternate" type="text/html" title="统计天体测量" /><published>2022-12-15T00:00:00+08:00</published><updated>2022-12-15T00:00:00+08:00</updated><id>https://liuniu.fun/blogs/statistical_astrometry</id><content type="html" xml:base="https://liuniu.fun/blogs/statistical_astrometry.html"><![CDATA[<p>本章为《Astrometry for Astrophysics》的第16章，由Anthony G. A. Brown编写。</p>

<p>统计天体测量（Statistical astrometry）指的是从一组恒星或其他源样本中推断天体物理量，通常得到的是该天体物理量的平均值或对其分布的描述，应用广阔，包括：光度定标、星团成员星证认、分离银河系结构成分、探测银晕中低对比度子结构。天体测量星表给出的大量视差测量结果使这些研究变得很有意思。然而，有很多因素使得天体物理量的推断存在偏倚，从而使对天体测量数据的分析变得复杂。本章重点讨论这些复杂因素，以期为在统计研究中最优使用天体测量数据提供指导。
<!-- more --></p>

<p>本文的PDF版本见<a href="https://liuniu.fun/files/note/statistical_astrometry.pdf">这里</a>。</p>

<h2 id="161-使天体测量数据分析复杂化的效应effects-complicating-the-interpretation-of-astrometric-data">16.1 使天体测量数据分析复杂化的效应（Effects complicating the interpretation of astrometric data）</h2>

<ul>
  <li>样本不完备性和选择效应 （Completeness and selection effects）</li>
</ul>

<p>从一本天体测量星表中选择的任何一个样本都存在数据不完备性和选择效应。这两个问题都与天体测量巡天特性和样本的选取方式相关。此外，它们也可能与天区位置或目标源特性相关。因此，所选取的样本几乎不可能代表样本源在天体物理参数空间的真实分布。忽略这一点可能会导致统计推断得到有偏结果。</p>

<ul>
  <li>相关误差（Correlated errors）</li>
</ul>

<p>一般而言，一个给定天体的天体测量参数误差在统计上是相互不独立的。此外，在不同天体间这些误差也可能相关。忽略这些相关性可能会使所导出的天体物理量分布存在虚假特征。</p>

<ul>
  <li>与天区位置相关的系统误差（Systematics as a function of sky position）</li>
</ul>

<p>天体测量观测方式特征会反映在误差和天区相关性的系统变化中，如照相底片巡天中的系统区域误差（systematic zonal error）、Hipparcos和Gaia项目扫描模式所引入的系统误差。考虑这些系统误差对基于遍及大面积天区的源样本的研究尤为重要。</p>

<ul>
  <li>估计天体物理量（Estimating astrophysical quantities）</li>
</ul>

<p>在估计某一类天体样本的天体物理量时，首先要从每一个天体的天体测量资料中计算这些天体物理量，再分析这些天体物理量在参数空间中的分布。这些天体物理量包括距离、速度、光度、角动量等。但是，实际测量数据并非是与这些天体物理参数直接相关。如直接的测量量不是天体的距离，而是由于地球绕日运动引起的视差位移。许多天体物理量是天体测量参数的非线性函数。例如，恒星的距离、绝对星等和角动量分别是\(\dfrac{1}{\varpi}\)、\(\log \varpi\)和\(\dfrac{1}{\varpi^2}\)的函数。因此，利用天体测量数据简单估计天体物理参数会产生错误结果。唯一可靠的方法是数据的正向建模。</p>

<p>尽管不存在完美解决这些问题的通用方案，不过有许多“绝佳实践案例”值得借鉴。</p>

<h2 id="162-了解你的星表know-your-catalog">16.2 了解你的星表（Know your catalog）</h2>

<p>为了完全考虑观测误差、完备性和选择效应，理解天体测量星表的内容很重要，至少要对星表的编制过程有基本了解。</p>

<p>以Hipparcos星表为例，它包含11多万颗源（多数为单星）、2500多个双星和多星系统、60多颗太阳系内天体和1颗类星体。每颗源有5参数解和其他附加和补充信息，如天体测量参数之间的相关性、星等、颜色等。</p>

<p>在Hipparcos星表中，恒星的天球分布明显不同于在光学波段上恒星的真实分布。Hipparcos的观测方式是基于输入星表设置的，因而Hipparcos恒星天球分布表现出与输入星表相关的特征。最显著的特征是Gould带的近邻OB星协。因此，在从Hipparcos星表中选取一组恒星来导出某种平均物理量（如光度函数）时需要慎重处理这些选择效应。Gaia和HST GSC星表不会包含这些明确的选择效应；然而，由于不同的完备性，这些星表可能会含有微笑的选择效应，这些效应与天空中源的密度、成像分辨率和探测算法性能的相关。</p>

<p>Hipparcos星表另一个值得关注的特征是赤经坐标、赤经自行和视差的精确度与黄纬强相关，这可以从Hipparcos的天空扫描方式角度来理解。Hipparcos总是以大角度穿过黄道面，这意味着对于位于黄道面附近的源，黄经方向上的任何位移在测量方向上的投影非常小。这导致黄经坐标和黄经自行存在较大误差，转换到赤道坐标系后就表现为赤经坐标和赤经自行的较大误差。视差误差与黄纬的相关性来源于另一个事实：对于在黄道面附近的源，视差位移主要在黄经方向上。</p>

<p>最后，对Hipparcos星表的统计显示，天体测量参数间的相关性在天球上系统性地变化。一些系统误差是由于将测量实际发生的黄道坐标系转换到最终星表使用的赤道坐标系导致的。大部分系统误差都与扫描模式的细节、观测的时间分布以及观测相对于太阳的位置的分布相关。</p>

<p>类似的与天球坐标相关的系统误差也将会出现在Gaia和其他大型巡天（如LSST、Pan-Starrs、GSC星表等）中。意识到并理解这些因素的起因是很重要的，尤其是在数据中搜寻微弱的大尺度特征时。</p>

<h2 id="163-处理相关误差dealing-with-correlated-errors">16.3 处理相关误差（Dealing with correlated errors）</h2>

<p>一般而言，一颗给定源的天体测量参数是通过用源的运动模型对天体测量数据的数值拟合得到的。这个模型通常是恒星运动的标准模型，但也可能更加复杂，如双星系统的轨道运动模型。这种拟合给出的是对天体测量参数矢量\(\bf{a}\)及其协方差矩阵\(\bf{C}_a\)的估计。记\(\bf{a^{\rm true}}\)和\(\bf{a^{\rm est}}\)分别为\(\bf{a}\)矢量的真值和估计值，\({\rm E}[\bf{x}]\)为\(\bf{x}\)矢量的数学期望，则协方差矩阵可表示为
\begin{equation}
\bf{C_a}={\rm E}[(\bf{a^{\rm est}}-\bf{a^{\rm true}})(\bf{a^{\rm est}}-\bf{a^{\rm true}})^{\prime}]={\rm E}[\Delta \bf{a}\Delta \bf{a}^{\prime}].
\end{equation}
其元素\(c_{ij}\)由下式给出
\begin{equation}
c_{ii}=\sigma_i^2, c_{ij}=\rho_{i,j}\sigma_i \sigma_j.
\end{equation}
其中，\(\sigma_i\)为\(a_i\)分量的标准误差，\(\rho_{i,j}\)为\(a_i\)分量与\(a_j\)分量之间的相关系数。</p>

<p>相关系数一般不为零，因为\(\bf{a}\)的分量估计都基于同一组测量数据得到的。因此，只依靠标准误差来处理天体测量参数的不确定度是不够的。可以通过误差棒的一般形式来考虑协方差矩阵。在真值附件的置信区间可以用下式中的量来描述：
\begin{equation}
z=\Delta \bf{a}^{\prime} \bf{C_a^{-1}}\Delta\bf{a}
\end{equation}
\(z\)服从\(\chi^2_{\nu}\)分布，其中\(\nu\)为自由度，一般等于\(\bf{a}\)的维数。如果矢量\(\bf{b}\)通过\(\bf{a}\)的某种转换关系\(\bf{f}(\bf{a})\)得到，则\(\bf{b}\)的协方差矩阵为
\begin{equation}
\bf{C_b = J C_a J^{\prime}}
\end{equation}
其中，\(\bf{J}\)为转换关系的雅可比矩阵，其元素为
\begin{equation}
J_{ij}=\dfrac{\partial f_i}{\partial a_j}
\end{equation}
由此，我们可以计算由观测天体测量参数导出的任意一组变量的协方差矩阵。一个重要的应用就是天体测量参数误差随时间的传递。</p>

<p>在基于天体测量数据的天体物理研究中使用协方差矩阵，一个很好的例子就是Perryman等人在1998年利用Hipparcos数据研究毕星团（Hyades cluster）。星团成员星都是基于它们在空间中以共同速度运动（不考虑较小的速度弥散）的假设下选出。单颗恒星的空间速度由天体测量和视向速度计算而得，其协方差矩阵用于判断该恒星的空间运动是否与星团的平均运动一致。随后，对相对于平均速度的速度残差的分析表明，存在具有特定轴方向的速度椭球。此外，速度残差矢量似乎表明速度场中存在剪切或旋转。这些特性将影响星团动力学研究。然而，Perryman等人1998年的工作表明，这些特征都可以被解释为天体测量参数的相关性与毕星团相对于太阳的空间位置和速度两个因素相结合的结果。</p>

<p>天体测量参数的相关性（以及不同源天体测量参数之间的相关性）不能被忽视，需要在数据分析中考虑。</p>

<h2 id="164-通过反演的天体物理参数估算astrophysical-parameter-estimation-through-inversion">16.4 通过反演的天体物理参数估算（Astrophysical parameter estimation through inversion）</h2>

<p>天体测量巡天计划的主要目的是测量视差，这是对太阳系外天体唯一不需要假定待测源内禀特性的距离测量手段。因此，视差对估计天体物理参数（如恒星光度和在相空间中的恒星分布函数）非常重要。如前所述，最直观的方法就是通过天体测量观测量来反演距离或绝对星等。然而，这种方法会导致错误结果。这里借助利用三角视差数据校准恒星光度（绝对星等）来说明其中的问题。</p>

<h3 id="1641-简单光度校准中的统计偏差statistical-biases-in-simplistic-luminosity-calibration">16.4.1 简单光度校准中的统计偏差（Statistical biases in simplistic luminosity calibration）</h3>

<p>假设对某种特定光度型的所有恒星都测量了视差，且这些恒星都在以太阳为中心的空间内均匀分布。待研究的问题是：这一类恒星的平均绝对星等\(\mu_M\)以及相对于平均值的方差\(\sigma^2_M\)分别是多少？巡天计划得到的数据是视差测量值\(\varpi_0\)、视星等\(m\)和它们各自的观测误差（分别记为\(\sigma_\varpi\)和\(\sigma_m\)）。观测误差与视星等相关，恒星越亮，观测误差就越小。回答上述问题最直接的方法就是用下式估计第\(i\)颗星的绝对星等：
\(\begin{equation}
\tilde{M}_{i}=m_{i}+5 \log \varpi_{0,i}+5
\end{equation}\)
再从算得的\(\tilde{M}_{i}\)的分布中估计\(\mu_M\)和\(\sigma^2_M\)。在最实际的情形下，存在下述三个问题，将会导致错误的结果。</p>

<ul>
  <li>转换偏倚（Transformation bias）</li>
</ul>

<p>由天体测量观测估计得到的视差测量值\(\varpi_0\)总是包含误差且服从某种分布，通常假设其在视差真值\(\varpi\)附近服从高斯分布，即
 \begin{equation}
 P\left(\varpi_{0} \mid \varpi\right)=\frac{1}{\sigma_{\varpi} \sqrt{2 \pi}} e^{-\left(\varpi_{0}-\varpi\right)^{2} / 2 \sigma_{\varpi}^{2}}
 \end{equation}
 其中，\(P\left(\varpi_{0} \mid \varpi\right)\)指的是在给定视差真值\(\varpi\)的情况下，观测得到\(\varpi_0\)的概率。在没有系统误差时，\(\varpi_0\)是\(\varpi\)的无偏估计，即
 \begin{equation}
 E\left[\varpi_{0}\right]=\varpi
 \end{equation}
 但对于距离来说却不是：
 \begin{equation}
 E\left[1 / \varpi_{0}\right] \neq 1 / \varpi
 \end{equation}
 对绝对星等来说也是如此：
 \begin{equation}
 E\left[\log \varpi_{0}\right] \neq \log \varpi
 \end{equation}
 可以对距离和绝对星等估计中的偏倚建模，不过该模型包含对视差真值的积分，并在较小视差和负视差时失效。有很多工作尝试改正这一偏倚，但它们都依赖于某种消除零和负视差以便计算积分的技巧。这些做法高度可疑，无法解决偏倚改正对视差真值（永远不可能知晓）的依赖问题，在现实情况下具有非常大的方差（<em>即计算得到的偏倚改正值本身就不准确</em>），使得这些“改正”毫无意义。</p>

<ul>
  <li>卢茨—凯克尔效应（The Lutz-Kelker effect）</li>
</ul>

<p>上述转换偏倚之所以存在，是因为在利用观测视差推断距离或绝对星等时只使用了恒星的观测视差及其误差和视星等。可以通过已掌握的关于样本的其他信息来改进这种方法，如</p>

<ul>
  <li>巡天的星等极限，可以限制\(M\)的合理取值范围并在给定\(M\)时为\(\varpi\)设置下限；</li>
  <li>恒星的空间分布，已知是有限的，在太阳近邻可以近似为均匀分布；</li>
  <li>恒星的类型，可以为\(M\)的数值提供先验信息
 Lutz和Kelker在1973年提出了这一思路，并写了一篇非常有影响力的论文来展示对基于三角视差光度校准的统计偏倚的改正。该改正通过采用部分贝叶斯方法并引入恒星空间分布的先验信息（即假设恒星的空间密度恒定）推导出。在给定测量视差\(\varpi_0\)的情况下，恒星视差真值为\(\varpi\)的概率为
 \begin{equation}
 P\left(\varpi \mid \varpi_{0}\right) \propto P\left(\varpi_{0} \mid \varpi\right) \varpi^{-4}
 \end{equation}
 上述方程表达了这样一个事实：恒星数量随距离快速增长。这使得真实视差值比观测值小的可能性很高（即更多视差小恒星的观测视差值过大，反之亦然。<em>理解这个说法要把上面的式子反过来看，即看右边的概率代表观测到某一结果的可能性</em>）。他们使用上述视差真值概率分布的表达式来推导出绝对星等的真实值与观测值之差\(\Delta M = M - M_0\)的数学期望。这就是所谓的”卢茨—凯克尔效应”。他们给出的结果通常被应用于由视差计算得到的绝对星等。然而，这些改正只在满足下述条件时才适用：</li>
  <li>恒星在空间中的分布时均匀的；</li>
  <li>样本在一定的距离范围内是完备的；</li>
  <li>
    <p>相对视差误差是恒定的。
 另外，当恒星的光度函数在某一绝对星等范围内分布均匀时，只能通过假设\(\varpi / \varpi_{\mathrm{0}}\)存在下限且要将样本限制在\(\sigma_{\varpi} / \varpi_{0}&lt;0.175\)来计算改正值。这些需求使得Lutz-Kelker改正在很大程度上是毫无意义的。
 这一问题在该论文发表后很快就被发现，其他学者也试图通过引入对光度函数的附加假设或放宽对恒星空间分布的假设并考虑自行来推导出更加可靠的偏倚改正。</p>
  </li>
  <li>马尔姆奎斯特偏倚（Malmquist bias）
 这种偏倚是由以下事实造成：随着样本距离增加，任何一个在星等上完备的样本将会系统性地包含更多亮星，这是由于对视亮度的选择和源绝对星等的内禀扩散结合起来引起的。在前述的光度校准问题中，样本的视星等极限会使得优先选择更近的或者本质上更亮的恒星。这将使得样本中的绝对星等和视差分布不具备代表性，从而引起\(\mu_M\)估计中的系统误差，即”Malmquist bias”。
 正如卢茨—凯克尔效应，在对样本采取某种假设后，可以推导出对马尔姆奎斯特偏倚的“改正”。但是，这些改正也存在如同卢茨—凯克尔改正一样的问题。</li>
</ul>

<h3 id="1642-用其他方法最小化偏倚minimizing-bias-with-alternative-approaches">16.4.2 用其他方法最小化偏倚（Minimizing bias with alternative approaches）</h3>

<p>由于前文讨论的直接方法存在诸多问题，可以尝试其他替代方法。其中一种思路就是将研究的问题重新表述，来避免视差的非线性变换。</p>

<p>例如，在研究造父变星周光关系的零点问题时，Feast和Catchpole在1997年改写了周光关系，使得零点与视差存在线性关系，从而在不用担心计算绝对星等值时引入的转换偏倚对推导造父变星周光关系零点的影响。类似地，Arenou和Luri在1990年提议使用“基于天体测量的光度”（astrometry based luminosity）
\begin{equation}
a_{V}=\varpi_{0} 10^{0.2 V-1}
\end{equation}
<em>（指数里面似乎是0.2V+1）</em>。这一恒星光度物理参数可用于建立不受卢茨—凯克尔偏倚影响的赫罗图，并且适用于负视差和相对视差误差较大的情形。然而，需要注意的是，诸如\(a_V\)之类的物理参数，尽管随视差线性变化，但是与\(V\)是非线性关系。这意味着使用新的非线性转换时偏倚依旧存在，即使是在\(V\)的相对误差远小于视差相对误差的情况下。此外，这种形式上的改写不能解决由样本选择效应引起的偏倚。</p>

<h2 id="165-数据正向建模forward-modeling-of-the-data">16.5 数据正向建模（Forward modeling of the data）</h2>

<p>前文提到的处理天体测量数据的思路主要是将天体测量观测量转换成天体物理参数，然后将得到的天体物理参数固定在转换值上。相应的”改正项”只能在极不现实的假设下才能计算，且只适应于移除负视差和小视差值的样本。这样截断数据的处理方式是非常浪费的，且会使结果的偏倚增大。此外，数据本身也存在一种内含在测量过程中的系统误差，与对测量结果的处理无关。而前文讨论的偏倚与数据本身无关，完全是由对数据处理不当引起的。即使是对没有系统误差的数据，偏倚问题依然存在。</p>

<p>保留数据原本的样子，通过数据建模来估计目标天体物理参数，可以完全避免偏倚问题。即由模型预言天体测量观测量，再将它们与实际的观测结果比对，从而确定模型参数的数值。这种方法的缺点是参数估计依赖于模型，不过正如前文所讨论的那样，直接方法也是依赖于模型的。这体现在偏倚改正值的推导需要引入大量对样本特性的假设上。在数据建模中也可以考虑样本特性和选择效应。作者以简单的贝叶斯光度校准为例来说明数据建模方法。</p>

<h3 id="1651-贝叶斯光度校准bayesian-luminosity-calibration">16.5.1 贝叶斯光度校准（Bayesian luminosity calibration）</h3>

<p>观测数据形式同第16.4节描述的一样，不过所研究的问题变了：在给定观测量\(\mathbf{o}=\left\{\varpi_{\mathrm{o}, i}, m_{i}\right\}(i=0, \ldots, N-1)\)的情况下，\(\mu_M\)和\(\sigma_M\)最有可能的取值为多少？可以依据贝叶斯定理将该事件发生的概率表述出来：
\begin{equation}
P\left(\mu_{M}, \sigma_{M}, \mathbf{t} \mid \mathbf{o}\right)=\frac{P\left(\mathbf{o} \mid \mu_{M}, \sigma_{M}, \mathbf{t}\right) P\left(\mu_{M}, \sigma_{M}, \mathbf{t}\right)}{P(\mathbf{o})}
\end{equation}
上式各项参数的含义为：</p>

<ul>
  <li>\(P\left(\mu_{M}, \sigma_{M}, \mathbf{t} \mid \mathbf{o}\right)\): 在给定观测数据\(\mathbf{o}\)下，\(\mu_M\)、\(\sigma_M\)和每颗恒星的视差和绝对星等真值\(\mathbf{t}=\left\{\varpi_{i}, M_{i}\right\}\)的联合分布</li>
  <li>\(P\left(\mathbf{o} \mid \mu_{M}, \sigma_{M}, \mathbf{t}\right)\)：在给定观测量真值的情况下得到观测数据的概率，即似然函数</li>
  <li>\(P\left(\mu_{M}, \sigma_{M}, \mathbf{t}\right)\)：观测量真值和光度分布模型参数的联合分布，代表的是对恒星空间分布和光度分布函数的先验信息</li>
  <li>\(P(\mathbf{o})\)：获得观测数据的概率，在本问题中可被视为归一化常数</li>
</ul>

<p>估计\(\mu_M\)和\(\sigma_M\)需要最大化后验概率\(P\left(\mu_{M}, \sigma_{M}, \mathbf{t} \mid \mathbf{o}\right)\)。可以将上述方程改写为
\begin{equation}
\begin{array}{l}
P\left(\mu_{M}, \sigma_{M}, \mathbf{t} \mid \mathbf{0}\right) \propto <br />
\prod_{i} \exp \left[-\frac{1}{2}\left(\frac{\varpi_{o, i}-w_{i}}{\sigma_{w, i}}\right)^{2}\right] \times \exp \left[-\frac{1}{2}\left(\frac{m_{i}-M_{i}+5 \log \varpi_{i}+5}{\sigma_{m, i}}\right)^{2}\right] <br />
\times \varpi_{i}^{-4} \times \frac{1}{\sigma_{M} \sqrt{2 \pi}} \exp \left[-\frac{1}{2}\left(\frac{M_{i}-\mu_{M}}{\sigma_{M}}\right)^{2}\right] P\left(\mu_{M}\right) P\left(\sigma_{M}\right)
\end{array}
\end{equation}
上式中的各项对应着不同的假设和先验信息</p>

<ul>
  <li>前两项：假设视差和视星等的测量误差是高斯型</li>
  <li>\(\varpi_i^{-4}\)：假设恒星在以太阳为中心的空间内均匀分布</li>
  <li>第三个高斯函数：假设样本中恒星的光度分布函数为高斯函数</li>
  <li>\(P\left(\mu_{M}\right)\)和\(P\left(\sigma_{M}\right)\)：对\(\mu_M\)和\(\sigma_M\)取值范围的先验信息</li>
</ul>

<p>接下来的工作就是根据上述方程算出后验似然函数，之后通过对“nuisance parameters” \(\mathbf{t}\)进行积分，得到 \((\mu_M,\sigma_M)\)的边缘分布函数，再依据这个分布确定估计值\(\widetilde{\mu_{M}}\)和\(\widetilde{\sigma_{M}}\)，如取平均值。问题在于\(P\left(\mu_{M}, \sigma_{M}, \mathbf{t} \mid \mathbf{o}\right)\)是个高维空间的函数，无法利用分析方法计算。此时需要借助数值方法来对后验分布进行采样，建立后验分布。常用的方法就是Markov Chain Monte Carlo (MCMC)方法。基本思路是通过可控的随机行走来遍历参数空间\(\left(\mu_{M}, \sigma_{M},\mathbf{t}\right)\)进行采样。采样将生成参数点在参数空间中的分布，其密度正比于后验似然函数。从参数点的分布可以画出\(\mu_M\)和\(\sigma_M\)的直方图，用来代表在对其他模型参数积分后，\(\mu_M\)和\(\sigma_M\)的后验概率分布函数。这反映了在考虑所有由观测误差和先验信息含糊导致的不确定性后得到的对光度函数参数的后验认知。</p>

<p>之后作者使用模拟数据作为算例，来演示该算法。</p>

<ul>
  <li>假设该巡天数据包含\(N=400\)颗同一类型的恒星</li>
  <li>恒星的绝对星等服从\(N(9,0.49)\)的分布，即\(\mu_M=9\)，\(\sigma_M=0.7\)</li>
  <li>恒星在1 pc和100 pc距离范围内均匀分布，即\(10 \text { mas } \leq \varpi_{i} \leq 1000 \text { mas }\)</li>
  <li>该巡天计划在一定距离上是完备的</li>
  <li>已知观测误差\(\sigma_{\varpi, i}\)和\(\sigma_{m, i}\)随视星等变化（根据光子噪声）且对于亮星包含校准本底</li>
  <li>假设我们已知恒星的分布是均匀的且已知视差真值分布的极值</li>
  <li>待估参数为\(\mu_M\)和\(\sigma_M\)</li>
  <li>\(\mu_M\)的先验分布假设为\(\mu_M\)在\(-5\)和\(+16\)之间均匀分布</li>
  <li>\(\sigma_M\)的先验分布假设为\(\sigma_M^2\)在\(0.01\)和\(1.0\)之间的概率密度正比于\(\dfrac{1}{\sigma_M^2}\)</li>
</ul>

<p>MCMC方法使用了25万个”burn-in”步长生成一百万个迭代样本，并将每第150个样本存储下来作为观测数据。生成的观测视差包含小视差（小于10 mas）和负视差，这些值也用于参数估计。得到的结果如下</p>

<table>
  <thead>
    <tr>
      <th>Condition</th>
      <th>\(\mu_M\)</th>
      <th>\(\sigma_M^2\)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>True</td>
      <td>9</td>
      <td>0.49</td>
    </tr>
    <tr>
      <td>All sample</td>
      <td>\(8.96\pm0.05\)</td>
      <td>\(0.50 \pm 0.06\)</td>
    </tr>
    <tr>
      <td>Only positive parallaxes</td>
      <td>8.8</td>
      <td>3.2</td>
    </tr>
    <tr>
      <td>\(0&lt;\sigma_{\varpi} / \varpi_{o} \leq 0.175\)</td>
      <td>8.7</td>
      <td>0.5</td>
    </tr>
  </tbody>
</table>

<p>可见，截断数据会使估计值更加偏离真值。同时，施加Lutz-Kelker改正也会使估计值变小，远离真值。</p>

<p>当然上述方法也存在若干问题：</p>

<ul>
  <li>在实际测量中，视差的真实分布是不可能准确预知的。不过，可以通过引入更多参数来调整\(P(\varpi)\)，如\(P(\varpi)=\varpi^{a+4}\)并将视差的上下限设为未知量。</li>
  <li>更严格地说，任何实际测量得到的样本总是包含选择效应的，如星等极限。这些选择效应也可以作为已知或含待估参数的选择函数，被纳入在正向模型中。</li>
</ul>

<p>这里想传达的主要信息是基于概率推断的正向建模可以考虑天体测量数据中的复杂因素，包括负视差和视差相对误差较大的结果、（相对）观测误差的变化和相关误差。</p>

<h3 id="1652-天体测量数据建模的其他例子other-examples-of-astrometric-data-modeling">16.5.2 天体测量数据建模的其他例子(Other examples of astrometric data modeling)</h3>

<p>Luri等人1996年提出了一种基于最大似然函数数据建模的光度校准方法。该方法不仅使用了视星等和视差数据，也考虑了自行和视向速度。在模型方面，考虑了光度函数、运动学、恒星的空间分布、恒星类型、观测误差和选择效应。所有视差数据都被使用了。最重要的一点是使用所有可用数据。尽管这会使数据分析变复杂，却极大地增加了数据包含的信息量。例如，自行可以作为距离的替代，从而为恒星光度提供了额外的约束。对自行、视向速度和视差的运动学分析可以区分不同恒星族。</p>

<p>另一个例子是星团天体测量数据的运动学建模。假设星团成员星都以相同的空间速度运动，数据就可以用这种运动模型描述。此时考虑星团内部速度场。星团模型包含自身视差作为待估参数。三角视差测量结果与运动学视差（由恒星自行与横向速度算得）的结果可以提升视差的测量精度。其基本原因在于使用了成员星自行中包含的距离信息。运动学模型还提供了一种不同于分光方法的视向速度测量方法。</p>

<p>建模是一种强大的统计天体测量工具，尤其在使用所有可用数据以及其他巡天计划的补充数据时。如对Gaia，LSST等，建模将是一种不可或缺的数据分析方法。</p>

<h2 id="166-建议recommendations">16.6 建议（Recommendations）</h2>

<p>作者根据前文的描述，总结出来了一些指导性建议，可作为使用统计天体测量来研究天文问题的参考。</p>

<ul>
  <li>要意识到几乎所有天体物理量都是天体测量参数的非线性函数，这主要是因为计算这些物理量时要使用的是距离而非视差，如从自行到横向速度、恒星轨道的角动量和能量、作用角变量等</li>
  <li>仔细考虑要研究的问题。要测定哪些天体物理参数？直接方法是否可取？是否需要改写（重新表述）问题以避免非线性变换？</li>
  <li>理解所用星表，选择样本时要有明确定义的标准。只有详细了解样本的特性，才能消除最终结果中的潜在偏倚。</li>
  <li>在使用直接方法时永远不要试图改正Malmquist或Lutz-Kelker效应。在大部分情况下，这两种效应同时发生，使得标准改正失效。此外，标准改正所隐含的假设几乎不可能成立。</li>
  <li>通过预测观测量并判断模型在数据空间的拟合优度来进行数据建模。这可以完全避免由非线性转换引入的偏倚问题，同时为考虑选择效应提供了一种直观方法。在这方面，贝叶斯数据分析是一个非常强大的工具。</li>
  <li>对于特定样本或单个恒星，可以只考虑视差相对误差较小（如小于10%）的恒星。但是，这隐含了对真实视差的截断（真实视差较大往往对应着较小的视差相对误差）且偏向于亮星（视差绝对视差较小）。因此，结果中仍可能出现严重偏倚。</li>
  <li>使用所有可用数据，不仅是自行和视向速度，也包括测光和恒星天体物理特性（光谱型、光度型、金属丰度等）。这些补充信息会对距离和光度提供额外的约束，并可用区分恒星类型。此外，测光或分光距离可以用于替代相对不准确的视差，这些距离将会在Gaia项目之后得到很好的校准。</li>
  <li>在使用补充信息时，需要注意结果可能存在循环相关。恒星距离和天体物理参数的校准本质上与一小部分标准星的视差测量值紧密相连，因此需要确保这些校准与标准星的视差数据相符。</li>
  <li>不要忽略天体测量误差中的相关性以及它们随天空位置的变化</li>
  <li>在没有充分理由时不要丢弃负视差或者低精度的视差，这些数据也包含信息。</li>
</ul>]]></content><author><name>Neo</name></author><category term="astrometry" /><category term="statistics" /><summary type="html"><![CDATA[本章为《Astrometry for Astrophysics》的第16章，由Anthony G. A. Brown编写。 统计天体测量（Statistical astrometry）指的是从一组恒星或其他源样本中推断天体物理量，通常得到的是该天体物理量的平均值或对其分布的描述，应用广阔，包括：光度定标、星团成员星证认、分离银河系结构成分、探测银晕中低对比度子结构。天体测量星表给出的大量视差测量结果使这些研究变得很有意思。然而，有很多因素使得天体物理量的推断存在偏倚，从而使对天体测量数据的分析变得复杂。本章重点讨论这些复杂因素，以期为在统计研究中最优使用天体测量数据提供指导。]]></summary></entry><entry><title type="html">VLBI 数据文件的命名规则</title><link href="https://liuniu.fun/blogs/VLBI-session-name.html" rel="alternate" type="text/html" title="VLBI 数据文件的命名规则" /><published>2022-09-28T00:00:00+08:00</published><updated>2022-09-28T00:00:00+08:00</updated><id>https://liuniu.fun/blogs/VLBI_session_name</id><content type="html" xml:base="https://liuniu.fun/blogs/VLBI-session-name.html"><![CDATA[<p>在 2023 年以前，VLBI 数据文件的命名遵循以下规则：日期 <code class="language-plaintext highlighter-rouge">yyMMMdd</code> 加 DBC 代码，即 database code，一个或两个字母，一共是 8 到 9 个字符。</p>

<p><strong>注意</strong>：自 2023 年之后，VLBI 数据文件的命名规则改为 <code class="language-plaintext highlighter-rouge">yyyymmdd</code> 加 session 代码，其中 session 代码最长可达 12 个字符。</p>

<p>这里简单介绍一下 DBC 代码的含义。</p>

<!-- more -->

<h2 id="dbc-代码说明表">DBC 代码说明表</h2>

<p>对于 DBC 代码的说明，可以在 <a href="https://cddis.nasa.gov/archive/vlbi/ivsformats/master-format.txt">master 文件的格式说明文档</a> 中找到。这里列举如下表所示：</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">DBC</th>
      <th style="text-align: left">CODES</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">D</td>
      <td style="text-align: left">DSN</td>
    </tr>
    <tr>
      <td style="text-align: left">DD</td>
      <td style="text-align: left">DSN</td>
    </tr>
    <tr>
      <td style="text-align: left">DO</td>
      <td style="text-align: left">GSI</td>
    </tr>
    <tr>
      <td style="text-align: left">DX</td>
      <td style="text-align: left">GSI, CRL, CDP</td>
    </tr>
    <tr>
      <td style="text-align: left">KL</td>
      <td style="text-align: left">V230L</td>
    </tr>
    <tr>
      <td style="text-align: left">KR</td>
      <td style="text-align: left">V230R</td>
    </tr>
    <tr>
      <td style="text-align: left">KV</td>
      <td style="text-align: left">BR079, BL115</td>
    </tr>
    <tr>
      <td style="text-align: left">LL</td>
      <td style="text-align: left">CDP</td>
    </tr>
    <tr>
      <td style="text-align: left">MH</td>
      <td style="text-align: left">INT southern baseline</td>
    </tr>
    <tr>
      <td style="text-align: left">MV</td>
      <td style="text-align: left">CRL</td>
    </tr>
    <tr>
      <td style="text-align: left">RR</td>
      <td style="text-align: left">CDP</td>
    </tr>
    <tr>
      <td style="text-align: left">SL</td>
      <td style="text-align: left">VLBA</td>
    </tr>
    <tr>
      <td style="text-align: left">SV</td>
      <td style="text-align: left">VLBA</td>
    </tr>
    <tr>
      <td style="text-align: left">VC</td>
      <td style="text-align: left">VGOS-INT</td>
    </tr>
    <tr>
      <td style="text-align: left">VB</td>
      <td style="text-align: left">VGOS, VGOS-INT, VGOS tests</td>
    </tr>
    <tr>
      <td style="text-align: left">VE</td>
      <td style="text-align: left">EU-VGOS</td>
    </tr>
    <tr>
      <td style="text-align: left">VG</td>
      <td style="text-align: left">VGOS operational, VGOS tests</td>
    </tr>
    <tr>
      <td style="text-align: left">VH</td>
      <td style="text-align: left">VGOS-INT</td>
    </tr>
    <tr>
      <td style="text-align: left">VI</td>
      <td style="text-align: left">VGOS-INT</td>
    </tr>
    <tr>
      <td style="text-align: left">VJ</td>
      <td style="text-align: left">VGOS-INT</td>
    </tr>
    <tr>
      <td style="text-align: left">VK</td>
      <td style="text-align: left">VGOS-INT</td>
    </tr>
    <tr>
      <td style="text-align: left">VT</td>
      <td style="text-align: left">VGOS-INT</td>
    </tr>
    <tr>
      <td style="text-align: left">VX</td>
      <td style="text-align: left">GSI</td>
    </tr>
    <tr>
      <td style="text-align: left">X</td>
      <td style="text-align: left">CDP, POLA, MOBL, IRIS-A, NRL, GERMAN, EUR, NGS</td>
    </tr>
    <tr>
      <td style="text-align: left">XM</td>
      <td style="text-align: left">MOBL, EURMOB, IRIS-A</td>
    </tr>
    <tr>
      <td style="text-align: left">X2</td>
      <td style="text-align: left">VLBA</td>
    </tr>
    <tr>
      <td style="text-align: left">X5</td>
      <td style="text-align: left">SGP</td>
    </tr>
    <tr>
      <td style="text-align: left">X9</td>
      <td style="text-align: left"> </td>
    </tr>
    <tr>
      <td style="text-align: left">XA</td>
      <td style="text-align: left">SGP, POLA, CDP, MOBL, IRIS-A, NGS, EUR, VLBA</td>
    </tr>
    <tr>
      <td style="text-align: left">XB</td>
      <td style="text-align: left">POLA, IRIS-A, SGP, EUR, VLBA</td>
    </tr>
    <tr>
      <td style="text-align: left">XC</td>
      <td style="text-align: left">SGP, EUR</td>
    </tr>
    <tr>
      <td style="text-align: left">XD</td>
      <td style="text-align: left">SGP</td>
    </tr>
    <tr>
      <td style="text-align: left">XE</td>
      <td style="text-align: left">NEOS-A, NEOS-B, SGP</td>
    </tr>
    <tr>
      <td style="text-align: left">XF</td>
      <td style="text-align: left">JADE</td>
    </tr>
    <tr>
      <td style="text-align: left">XG</td>
      <td style="text-align: left">CDP</td>
    </tr>
    <tr>
      <td style="text-align: left">XH</td>
      <td style="text-align: left">IRIS-S</td>
    </tr>
    <tr>
      <td style="text-align: left">XI</td>
      <td style="text-align: left">IRIS-A</td>
    </tr>
    <tr>
      <td style="text-align: left">XJ</td>
      <td style="text-align: left">MOBL, NAVINT, NAVEX</td>
    </tr>
    <tr>
      <td style="text-align: left">XK</td>
      <td style="text-align: left">CDP, SGP</td>
    </tr>
    <tr>
      <td style="text-align: left">XL</td>
      <td style="text-align: left">VLBA</td>
    </tr>
    <tr>
      <td style="text-align: left">XM</td>
      <td style="text-align: left">NRL, IRIS-I</td>
    </tr>
    <tr>
      <td style="text-align: left">XN</td>
      <td style="text-align: left">NRL, CRF</td>
    </tr>
    <tr>
      <td style="text-align: left">XO</td>
      <td style="text-align: left">USNO, NAVNET, NAVEX, APT</td>
    </tr>
    <tr>
      <td style="text-align: left">XP</td>
      <td style="text-align: left">POLA, IRIS-A, CDP, IRIS-P</td>
    </tr>
    <tr>
      <td style="text-align: left">XQ</td>
      <td style="text-align: left">CDP, SGP</td>
    </tr>
    <tr>
      <td style="text-align: left">XR</td>
      <td style="text-align: left">MOBL, IRIS-I, NRL, IRIS-A, GERMAN</td>
    </tr>
    <tr>
      <td style="text-align: left">XS</td>
      <td style="text-align: left">NGS</td>
    </tr>
    <tr>
      <td style="text-align: left">XT</td>
      <td style="text-align: left">MK1, CDP, VLBA, NEOS-I</td>
    </tr>
    <tr>
      <td style="text-align: left">XU</td>
      <td style="text-align: left">IRIS-I, NEOS-I</td>
    </tr>
    <tr>
      <td style="text-align: left">XV</td>
      <td style="text-align: left">VLBA, CRF, NEOS-I</td>
    </tr>
    <tr>
      <td style="text-align: left">XW</td>
      <td style="text-align: left">CDP, SGP</td>
    </tr>
    <tr>
      <td style="text-align: left">XX</td>
      <td style="text-align: left">CDP, GERMAN, CRL, GSI, SYOWA</td>
    </tr>
    <tr>
      <td style="text-align: left">XY</td>
      <td style="text-align: left">CRL</td>
    </tr>
    <tr>
      <td style="text-align: left">XZ</td>
      <td style="text-align: left">INT</td>
    </tr>
    <tr>
      <td style="text-align: left">ZZ</td>
      <td style="text-align: left">CDP</td>
    </tr>
  </tbody>
</table>

<p>上述代码可以简单分为以下几类。</p>

<h2 id="表征观测网名称">表征观测网名称</h2>

<h3 id="deep-space-network">Deep Space Network</h3>

<p>Deep Space Network，简称 DSN，是美国 NASA 深空网。其 VLBI 观测开始于 1967 年，最早在 <i>S</i> 波段观测河外源 3C273。</p>

<p>尽管 DSN VLBI 观测网的主要目的是支持 NASA 航天器的运行和为深空探测研究服务，它的空闲时间，约占总观测时间的 1% 到 2%，也用于地基天文观测。</p>

<p>DSN 中的 VLBI 望远镜代号一般为 <code class="language-plaintext highlighter-rouge">DSNxx</code>，其中 <code class="language-plaintext highlighter-rouge">xx</code> 为数字，主要分布于三个地方：美国加州的 Goldstone，西班牙马德里的 Robledo，以及澳大利亚堪培拉的 Tidbinbilla。</p>

<p>目前在 <i>X/Ka</i> 波段的天球参考架，例如 ICRF3 [<a href="#Charlot2020">1</a>]，主要建立在 DSN VLBI 观测网的观测上。Altunin 等人的论文 [<a href="#Altunin2000">2</a>] 为 DSN 的 VLBI 观测网提供了更为详细的说明。更多 DSN 在科学中的应用可以参考 <a href="https://rahist.nrao.edu/11-Montreal-Jauncey.pdf">David L. Jauncey 的报告</a>。</p>

<p>对于 VLBI 观测而言，<strong>DBC 代码为 <code class="language-plaintext highlighter-rouge">D</code> 或 <code class="language-plaintext highlighter-rouge">DD</code></strong> 表示该观测来自于 DSN 的 VLBI 观测网。</p>

<h3 id="very-long-baseline-array">Very Long Baseline Array</h3>

<p>Very Long Baseline Array，简称 VLBA，是美国甚长基线射电望远镜阵，由 10 架口径为 25 米的天线组成，最长基线超过 8000 km，工作频率为 330 MHz 至 43 GHz，对射电天体的成图分辨率好于 1 mas [<a href="#Kellermann1985">3</a>]。</p>

<p><strong>DBC 代码为 <code class="language-plaintext highlighter-rouge">SL</code>、<code class="language-plaintext highlighter-rouge">SV</code>、<code class="language-plaintext highlighter-rouge">X2</code> 或 <code class="language-plaintext highlighter-rouge">XL</code>，以及可能的 <code class="language-plaintext highlighter-rouge">XA</code>、<code class="language-plaintext highlighter-rouge">XB</code> 或 <code class="language-plaintext highlighter-rouge">XT</code></strong> 表示该观测可能来自于 VLBA 观测网。</p>

<h3 id="europe">Europe</h3>

<p>Europe，简称 EUR，指只使用欧洲 VLBI 网的观测，从 1990 年开始 [<a href="#Krasna2013">4</a>]。</p>

<h3 id="german">GERMAN</h3>

<p>GERMAN 从字面上推测是德国的 VLBI 观测网。IVS 数据库里面找不到相关数据。</p>

<h3 id="usno-navy-network">USNO Navy Network</h3>

<p>USNO Navy Network，简称 NAVNET，是 USNO 主导的 VLBI 观测网，主要用于监测地球自转。它每周观测一次，时间上与 IRIS 错开 [<a href="#Freedman1994">5</a>]。观测周期为 1989 年 1 月至 1993 年 4 月，共 226 期数据。</p>

<h3 id="navex">NAVEX</h3>

<p>NAVEX 是 USNO 主导的国际联测网项目。观测周期为 1990 年 4 月至 1999 年 9 月，共 75 期数据。</p>

<h3 id="asia-pacific-telescope">Asia Pacific Telescope</h3>

<p>Asia Pacific Telescope，简称 APT。由<a href="http://astro.sci.yamaguchi-u.ac.jp/eavn/aboutapt.html">相关网页</a>可知，这是一个亚洲、大西洋、南美洲和非洲之间的 VLBI 联测网。</p>

<p>IVS 数据库中只有 4 期资料，分别为 <code class="language-plaintext highlighter-rouge">95JUN27XO</code>、<code class="language-plaintext highlighter-rouge">95JUN28XO</code>、<code class="language-plaintext highlighter-rouge">97JAN16XA</code> 和 <code class="language-plaintext highlighter-rouge">97JAN17XA</code>。</p>

<h2 id="表征运行观测的机构名称">表征运行观测的机构名称</h2>

<h3 id="geographical-survey-institute">Geographical Survey Institute</h3>

<p>Geographical Survey Institute，简称 GSI，是日本国土地理院 Geospatial Information Authority of Japan 的前身。其主要工作是进行测地 VLBI 观测，改进日本测地基准点位置的测量，并监测日本附近的板块运动和地壳形变 [<a href="#Fukuzaki2001">6</a>]。</p>

<p>GSI 于 1981 年开始研制可移动的 VLBI 系统，该系统在 1986 年至 1993 年间用于 VEGA，即 VLBI Experiment for Geodetic Application 项目。在 2010 年左右，GSI 仍在建设可移动的短基线，约 10 km，VLBI 系统，以用于检查和验证 GPS 接收机等测绘仪器的性能 [<a href="#Ishii2010">7</a>]。</p>

<p><strong>DBC 代码为 <code class="language-plaintext highlighter-rouge">DO</code> 或 <code class="language-plaintext highlighter-rouge">VX</code>，以及可能的 <code class="language-plaintext highlighter-rouge">DX</code> 或 <code class="language-plaintext highlighter-rouge">XX</code></strong> 表示该观测可能来自于 GSI 的 VLBI 观测网。</p>

<h3 id="communications-research-laboratory">Communications Research Laboratory</h3>

<p>Communications Research Laboratory，简称 CRL，是日本通信综合研究所，领导日本 VLBI 系统的发展，开发过 K-3 和 K-4 VLBI 系统，是 IVS 的 Technology Development Centers 之一 [<a href="#Kondo2000">8</a>]。</p>

<p>CRL 负责硬件开发和观测，有 4 架天线，口径分别为 3 m、10 m、26 m 和 34 m，包括 Kashima，也参与测地观测，例如 CDP 项目 [<a href="#Takaba1991">9</a>]。</p>

<p><strong>DBC 代码为 <code class="language-plaintext highlighter-rouge">MV</code> 或 <code class="language-plaintext highlighter-rouge">XY</code>，以及可能的 <code class="language-plaintext highlighter-rouge">DX</code> 或 <code class="language-plaintext highlighter-rouge">XX</code></strong> 表示该观测可能来自于 CRL 的 VLBI 观测网。</p>

<h3 id="naval-research-laboratory">Naval Research Laboratory</h3>

<p>Naval Research Laboratory，简称 NRL，是美国海军研究实验室。IVS 数据库里面找不到相关数据。</p>

<h3 id="united-states-naval-observatory">United States Naval Observatory</h3>

<p>United States Naval Observatory，简称 USNO，是美国海军天文台。IVS 数据库里面找不到相关数据。</p>

<h3 id="syowa">SYOWA</h3>

<p>SYOWA 是由日本 Japanese Antarctic Research Expeditions，简称 JAREs，在南极洲建立的 Syowa 站与澳大利亚 Hobart 站、南非 Hartebeesthoek 站组成的观测网，用于测量南极洲的板块运动 [<a href="#Fukuzaki2005">10</a>]。</p>

<h2 id="表征观测项目或计划名称">表征观测项目或计划名称</h2>

<h3 id="crustal-dynamics-project">Crustal Dynamics Project</h3>

<p>Crustal Dynamics Project，简称 CDP，是美国 NASA 的大地测量计划，执行时期为 1979 年 10 月至 1991 年 12 月，共 12 年 [<a href="#Bosworth1993">11</a>]。</p>

<p>该项目的主要科学目标包括提升对北美西部板块边界区域大型地震引起的区域形变和应力积累的认知和理解，以及研究相对板块运动等。测量手段包括 VLBI 和 SLR [<a href="#Coates1983">12</a>]。</p>

<p>根据 <a href="https://cddis.nasa.gov/Programs/Historical_Programs.html#CDP">NASA 官网的介绍</a>，该项目的主要成果之一是表明主要板块的现在运动与地质学上测量的数百万年内平均运动相接近。</p>

<p><strong>DBC 代码为 <code class="language-plaintext highlighter-rouge">LL</code>、<code class="language-plaintext highlighter-rouge">RR</code>、<code class="language-plaintext highlighter-rouge">XG</code> 或 <code class="language-plaintext highlighter-rouge">ZZ</code>，以及可能的 <code class="language-plaintext highlighter-rouge">DX</code>、<code class="language-plaintext highlighter-rouge">X</code>、<code class="language-plaintext highlighter-rouge">XK</code>、<code class="language-plaintext highlighter-rouge">XP</code>、<code class="language-plaintext highlighter-rouge">XT</code>、<code class="language-plaintext highlighter-rouge">XW</code> 或 <code class="language-plaintext highlighter-rouge">XX</code></strong> 表示该观测可能来自于 CDP 计划的 VLBI 观测。</p>

<h3 id="polar-motion-analysis-by-radio-interferometric-surveying">POLar-motion Analysis by Radio Interferometric Surveying</h3>

<p>POLar-motion Analysis by Radio Interferometric Surveying，简称 POLARIS，对应的代号为 POLA。它是由 NGS 主导的大地测量项目，1980 年末开始观测，使用由 Haystack 和 HRAS 站组成的基线。1981 年 1 月，Haystack 站被 Westford 站替代。</p>

<p>此时的基线长度超过 3100 km，主要沿东西走向，与赤道面夹角约 20 度，因此对地球自转的变化非常敏感。1983 年末，第三个测站 OVRO 开始运行。每次实验总时长为 24 hr，单颗射电源每次典型观测时间为 2 到 3 min。每次实验对 14 颗射电源进行超过 200 次的观测 [<a href="#Robertson1986">13</a>]。</p>

<p>自 1984 年开始，POLARIS 加入 MERIT 计划，与其他国家的观测站一起联测，此时的代号为 POLAR。该项目结束于 1996 年。</p>

<p><strong>DBC 代码为 <code class="language-plaintext highlighter-rouge">X</code>、<code class="language-plaintext highlighter-rouge">XA</code>、<code class="language-plaintext highlighter-rouge">XB</code> 或 <code class="language-plaintext highlighter-rouge">XP</code></strong> 表示该观测可能来自于 POLARIS 项目的观测。</p>

<h3 id="international-radio-interferometric-surveying">International Radio Interferometric Surveying</h3>

<p>International Radio Interferometric Surveying，简称 IRIS。由于 POLARIS 观测网是美国本土的局域网，观测精度受限，因此需要寻求国际合作，在原有的 POLARIS 观测网的基础上添加新的观测站，以扩大观测网的覆盖面积。这就是美国国家海洋和大气管理局，National Oceanic and Atmospheric Administration，简称 NOAA，主导的 IRIS 项目。</p>

<p>该项目首先与瑞典 Onsala 空间天文台合作，每月参与一次 POLARIS 的观测。1983 年末，德国 Wettzell 站也加入了观测 [<a href="#Robertson1986">13</a>]。</p>

<p>由美国三个站和欧洲两个站组成的观测网称为 IRIS-A，观测开始于 1984 年初，每 5 天观测一次，结束于 1993 年 4 月，共有 639 期资料。</p>

<p>此外，IRIS 还有另外两个观测网。一个 IRIS 观测网被称为 IRIS-P，即 Pacific，由美国的三个观测站 Fairbanks、Mojave 和 Richmond，以及日本 Kashima 站组成，1987 年 4 月开始观测，结束于 1994 年 10 月，共有 90 多期资料。另一个 IRIS 观测网叫 IRIS-S，即 South，由南非 Hartebeesthoek 站与美国和欧洲的站组成 [<a href="#Schuh1990">14</a>]，观测自 1986 年 1 月开始，结束于 2001 年末，共有 169 期资料。</p>

<p>IRIS-I 观测网指的是 IRIS-Intensive，暂时没有找到相关信息，目前 IVS 数据库中也没有相应的数据。</p>

<p><strong>DBC 代码为 <code class="language-plaintext highlighter-rouge">XI</code>，以及可能的 <code class="language-plaintext highlighter-rouge">X</code>、<code class="language-plaintext highlighter-rouge">XM</code>、<code class="language-plaintext highlighter-rouge">XA</code>、<code class="language-plaintext highlighter-rouge">XB</code>、<code class="language-plaintext highlighter-rouge">XP</code> 或 <code class="language-plaintext highlighter-rouge">XR</code></strong> 表示该观测可能来自于 IRIS-A 观测网。<strong>DBC 代码为 <code class="language-plaintext highlighter-rouge">XP</code></strong> 表示该观测可能来自于 IRIS-P 观测网。<strong>DBC 代码为 <code class="language-plaintext highlighter-rouge">XH</code></strong> 表示该观测来自于 IRIS-S 观测网。</p>

<h3 id="monitor-earth-rotation-and-intercompare-techniques">Monitor Earth Rotation and Intercompare Techniques</h3>

<p>Monitor Earth Rotation and Intercompare Techniques，简称 MERIT，于 1978 年启动，旨在综合利用 VLBI、LLR 和 SLR 技术来进行大地测量研究。观测周期为 1980 年 7 月至 10 月，共 17 期数据。该项目的成功促使了 IERS 的建立 [<a href="#Robertson1986">13</a>]。</p>

<p><strong>DBC 代码为 <code class="language-plaintext highlighter-rouge">X</code></strong> 表示该观测可能来自于 MERIT 项目的 VLBI 观测。</p>

<h3 id="national-earth-orientation-survey">National Earth Orientation Survey</h3>

<p>National Earth Orientation Survey，简称 NEOS。NEOS-A 观测网由 NOAA 的 IRIS 观测网和 USNO 的 NAVNET 观测网合并而成，由 USNO 负责，每周观测一次，目标是监测 EOP，并建立和维持 ICRF。</p>

<p>NEOS-A 观测网主要由美国的 Green Bank 站和 Kokee Park 站、巴西的 Fortaleza 站和德国的 Wettzell 站构成，美国的 Fairbanks 站或挪威的 Ny-Ålesund 站作为补充。加拿大的 Algonquin Park 站偶尔加入观测 [<a href="#Schuh2000">15</a>]。观测周期为 1993 年 5 月至 2001 年 12 月，共 452 期数据。</p>

<p>NEOS-B 观测由 NOAA 资助，每月观测一次，目的是提升 TRF 的精度。但由于 NOAA 的 VLBI 预算缩减，1994 年被迫终止观测 [<a href="#Arias1997">16</a>]。观测周期为 1993 年 5 月至 1994 年 10 月，共 19 期数据。</p>

<p>NEOS-I 观测网指的是 NEOS-Intensive，暂时没有找到相关信息，目前 IVS 数据库中也没有相应的数据。</p>

<h3 id="continuous-observations-of-the-rotation-of-the-earth">Continuous Observations of the Rotation of the Earth</h3>

<p>Continuous Observations of the Rotation of the Earth，简称 CORE，主要目的是评估不同 VLBI 观测网得到的 EOP 测量之间的符合程度，从 1997 年 1 月开始，结束于 2001 年 10 月。</p>

<p>与 NEOS 观测网同步观测的称为 CORE-A 观测网，在 NEOS 网观测的相邻日期进行观测的称为 CORE-B 观测网 [<a href="#MacMillan2000">17</a>]。CORE-A 观测网共有 81 期观测数据，而 CORE-B 观测网有 60 期。</p>

<h3 id="national-geodetic-survey">National Geodetic Survey</h3>

<p>National Geodetic Survey，简称 NGS，现由 NOAA 主导的大地测量计划。IVS 数据库里面找不到相关数据。</p>

<h3 id="space-geodesy-project">Space Geodesy Project</h3>

<p>Space Geodesy Project，简称 SGP，是 NASA 的项目。IVS 数据库里面找不到相关数据。</p>

<h3 id="japanese-dynamic-earth-observation-by-vlbi">JApanese Dynamic Earth observation by VLBI</h3>

<p>JApanese Dynamic Earth observation by VLBI，简称 JADE，是日本国内的 VLBI 观测网，由 4 个 GSI 观测站 TSUKUB32、SINTOTU3、CHICHI10 和 AIRA，以及两个 VERA 观测站 ERAMZSW 和 VERAISGK 组成 [<a href="#Miura2009">18</a>]。观测周期为 1996 年 6 月至 2015 年 12 月，共 166 期数据。</p>

<p><strong>DBC 代码为 <code class="language-plaintext highlighter-rouge">XF</code></strong> 表示该观测来自于 JADE 观测网。</p>

<h3 id="ivs-regular">IVS Regular</h3>

<p>IVS Regular，包括 IVS-R1 和 IVS-R4，是自 2002 年开始的 IVS 常规观测。它们分别在每周一和周四进行观测，分别由 NASA 的 GSFC 和 USNO 负责 [<a href="#Behrend2011">19</a>]。</p>

<h3 id="ivs-t2">IVS-T2</h3>

<p>IVS-T2 由波恩大学地球科学研究所 Institute of Geodesy and Geoinformation 协调，每两个月观测一次，每次有 12 个观测台站参与，目的是利用所有 IVS 观测台站每年至少观测 3 到 4 次，以监测 TRF [<a href="#Behrend2011">19</a>]。</p>

<h3 id="ivs-celestial-reference-frame">IVS Celestial Reference Frame</h3>

<p>IVS Celestial Reference Frame，简称 IVS-CRF，以及 CRF median-south，简称 IVS-CRMS，和 CRF deep-south，简称 IVS-CRD，均由 USNO 协调。它们的目的是提升现有 CRF 的精度，并通过新的射电源来扩充 CRF [<a href="#Behrend2011">19</a>]，每 3 到 4 周观测一次 [<a href="#Schluter2007">20</a>]。</p>

<h3 id="ivs-research-and-development">IVS research and development</h3>

<p>IVS research and development，简称 IVS-R&amp;D，每月观测一次，用于研究仪器效应、观测网偏差，以及改进技术和产品的新方法 [<a href="#Schluter2007">20</a>]。</p>

<h3 id="rd-with-the-vlba">R&amp;D with the VLBA</h3>

<p>R&amp;D with the VLBA，简称 RDV，每两个月一次，提供精准度最高的天体测量数据，并为 ICRF 源提供成图资料 [<a href="#Schluter2007">20</a>]。</p>

<h3 id="continuous-vlbi-campaign">Continuous VLBI campaign</h3>

<p>Continuous VLBI campaign，简称 CONT，是每三年一次、长达 15 天的连续观测，已有 CONT02、CONT05、CONT08、CONT11、CONT14 和 CONT17。其目的是利用最好的 VLBI 观测设备来展示 VLBI 技术的能力和最佳精度 [<a href="#Schluter2007">20</a>]。</p>

<h3 id="vlbi-global-observing-system">VLBI Global Observing System</h3>

<p>VLBI Global Observing System，简称 VGOS，是下一代 VLBI 系统，采用 12 米口径的天线，目标是与下一代其他空间大地测量技术一起实现台站的 1 mm 定位精度和 0.1 mm/yr 测速精度 [<a href="#Niell2018">21</a>]。</p>

<h3 id="european-vgos">EUropean-VGOS</h3>

<p>EUropean-VGOS，简称 EU-VGOS，是利用三个欧洲 VGOS 台站 Wettzell、Onsala 和 Yebes 开展的 VGOS 测试实验 [<a href="#Alef2019">22</a>]。</p>

<h3 id="intensive">Intensive</h3>

<p>Intensive，简称 INT，是 UT1 加强观测，观测时长为 1 小时，使用单基线。</p>

<p>INT1 基线由美国夏威夷的 Kokee 站，有时是 MK-VLBA，和德国的 Wettzell 站组成，周一到周五观测。INT2 基线由德国的 Wettzell 站和日本的 Tsukuba 站，后改为 Ishioka，组成，周末观测。INT3 观测网是由三个测站组成的三角观测网，三个测站分别为挪威的 Ny-Ålesund 站、德国的 Wettzell 站、日本的测站或者中国的佘山站 Seshan25，从 2007 年开始运行，每周一观测 [<a href="#Bohm2022">23</a>]。</p>

<h3 id="southern-intensives">Southern Intensives</h3>

<p>Southern Intensives，简称 SI，于 2019 年启动，目的是弥补参与 UT1 加强观测的观测网均位于北半球而导致的观测几何不均匀不足。</p>

<p>该观测网由南非的 Hartebeesthoek 站 HART15M，简称 Ht，澳大利亚的 Yarragadee 站 YARRA12M，简称 Yg，以及 Hobart 站 HOBART12，简称 Hb，组成 [<a href="#Bohm2022">23</a>]。DBC 代码为 <code class="language-plaintext highlighter-rouge">MH</code>。</p>

<h3 id="navint">NAVINT</h3>

<p>NAVINT 从字面推测，是 NAVNET 观测网的 UT1 加强观测。观测周期为 1989 年 4 月至 1993 年 4 月，共 129 期数据。</p>

<h3 id="vgos-intensives">VGOS Intensives</h3>

<p>VGOS Intensives，简称 VGOS-INT，是 VGOS 观测网的 UT1 加强观测，从 2020 年开始。</p>

<p>VGOS-B 和 VGOS-C 观测网由瑞典 Onsala 站的两台天线与日本的 Ishioka 站组成 [<a href="#Bohm2022">23</a>]，DBC 代码分别为 <code class="language-plaintext highlighter-rouge">VB</code> 和 <code class="language-plaintext highlighter-rouge">VC</code>。此外，还有由德国 Wettzell 站 WETTZ13S，简称 Ws，和美国 Kokee Park 站 KOKEE12M，简称 K2，组成的基线，DBC 代码为 <code class="language-plaintext highlighter-rouge">VI</code>；以及由德国 Ws 站和美国 McDonald Geodetic Observatory 的 MACGO12M 站，简称 Mg，组成的基线，DBC 代码为 <code class="language-plaintext highlighter-rouge">VT</code> 或 <code class="language-plaintext highlighter-rouge">VJ</code>。</p>

<p>目前还没有 DBC 代码为 <code class="language-plaintext highlighter-rouge">VH</code> 或 <code class="language-plaintext highlighter-rouge">VK</code> 的数据。</p>

<h2 id="特殊观测实验">特殊观测实验</h2>

<h3 id="v230l-和-v230r">V230L 和 V230R</h3>

<p>V230L 和 V230R 这两个代码，DBC 代码分别为 <code class="language-plaintext highlighter-rouge">KL</code> 和 <code class="language-plaintext highlighter-rouge">KR</code>，各自只有一个观测数据，分别为 <code class="language-plaintext highlighter-rouge">07JUN24KL</code> 和 <code class="language-plaintext highlighter-rouge">07JUN24KR</code>。它们是 LBA 的 V230 观测实验的不同极化方式结果，即 RR 和 LL。</p>

<p>这次实验的负责人为 Leonid Petrov。根据<a href="http://astrogeo.org/petrov/discussion/v230/lba_dec2006.pdf">观测申请书</a>，其主要目的是利用 <i>K</i> 波段的观测来测定 Atca、Ceduna 和 Mopra 这三个站的位置，预期精度为 5 至 10 厘米。Leonid 也给出了<a href="http://astrogeo.org/petrov/discussion/v230/">实验分析结果</a>。</p>

<p>显然，这次实验数据不适合作为 <i>S/X</i> 波段全局解的输入数据。</p>

<h3 id="br079bl115-和-bl122">BR079、BL115 和 BL122</h3>

<p>BR079、BL115 和 BL122 的 DBC 代码均为 <code class="language-plaintext highlighter-rouge">KV</code>，共有 10 次观测实验，是为了将 ICRF 拓展到 <i>K</i> 和 <i>Q</i> 波段而进行的先期实验。观测数据的分析结果见 [<a href="#Lanyi2010">24</a>] 和 [<a href="#Charlot2010">25</a>]。</p>

<h3 id="bp125c">BP125C</h3>

<p>BP125C 的 DBC 代码为 <code class="language-plaintext highlighter-rouge">KV</code>，session 名称为 <code class="language-plaintext highlighter-rouge">06OCT10KV</code>，为 VGaPS，即 Galactic Plane Survey 项目在 <i>K</i> 波段的观测。VGaPS 项目的目的是观测约 500 颗源，以增加银道面附近的 <i>K</i> 波段参考源数目。相关信息可见 http://astrogeo.org/gaps/。</p>

<h3 id="mobl-或-eurmob">MOBL 或 EURMOB</h3>

<p>MOBL 或 EURMOB 从字面上推测应该是可移动的 VLBI 天线。IVS 数据库里面找不到相关数据。</p>

<h2 id="参考文献">参考文献</h2>

<ul>
  <li><span id="Charlot2020">[1] Charlot P, Jacobs C S, Gordon D, et al. The third realization of the International Celestial Reference Frame by very long baseline interferometry[J]. Astronomy &amp; Astrophysics, 2020, 644: A159.</span></li>
  <li><span id="Altunin2000">[2] Altunin V. VLBI in the Deep Space Network: Challenges and Prospects[J]. 2000.</span></li>
  <li><span id="Kellermann1985">[3] Kellermann K I, Thompson A R. The Very Long Baseline Array[J]. Science, 1985, 229(4709): 123-130.</span></li>
  <li><span id="Krasna2013">[4] Krásná H, Tierno Ros C, Pavetich P, et al. Investigation of crustal motion in Europe by analysing the European VLBI sessions[J]. Acta Geodaetica et Geophysica, 2013, 48(4): 389-404.</span></li>
  <li><span id="Freedman1994">[5] Freedman A P, Steppe J A, Dickey J O, et al. The short-term prediction of universal time and length of day using atmospheric angular momentum[J]. Journal of Geophysical Research: Solid Earth, 1994, 99(B4): 6981-6996.</span></li>
  <li><span id="Fukuzaki2001">[6] Fukuzaki Y. Geodetic VLBI activities at GSI[J]. Communications Research Laboratory Journal, 2001, 48: 17.</span></li>
  <li><span id="Ishii2010">[7] Ishii A, Ichikawa R, Takiguchi H, et al. Current Status of the Development of a Transportable and Compact VLBI System by NICT and GSI[C]//Proceedings of the Sixth General Meeting of the International VLBI Service for Geodesy and Astrometry. 2010.</span></li>
  <li><span id="Kondo2000">[8] Kondo T. Technology Development Center at CRL[J]. In: N. R. Vandenberg and K. D. Baver, eds., International VLBI Service for Geodesy and Astrometry 2000 Annual Report, NASA/TP-2001-209979, 2000: 263-266.</span></li>
  <li><span id="Takaba1991">[9] Takaba H. VLBI of the Communications Research Laboratory[J]. Communications Research Laboratory Journal, 1991, 38(3): 417-433.</span></li>
  <li><span id="Fukuzaki2005">[10] Fukuzaki Y, Shibuya K, Ozawa T, et al. Results of the VLBI experiments conducted with Syowa Station, Antarctica[J]. Journal of Geodesy, 2005, 79(6): 379-388.</span></li>
  <li><span id="Bosworth1993">[11] Bosworth J M, Coates R J. The development of NASA’s Crustal Dynamics Project[J]. Contributions of Space Geodesy to Geodynamics: Technology, 1993, 25: 1-20.</span></li>
  <li><span id="Coates1983">[12] Coates R J. The Crustal Dynamics Project[C]//Multidisciplinary Use of the Very Long Baseline Array. 1983: 64.</span></li>
  <li><span id="Robertson1986">[13] Robertson D S. The Astrometric Possibilities of Very-Long-Baseline Interferometry[C]//Symposium - International Astronomical Union. Cambridge University Press, 1986, 109: 143-155.</span></li>
  <li><span id="Schuh1990">[14] Schuh H. Earth’s rotation measured by VLBI[M]//Earth’s Rotation from Eons to Days. Springer, Berlin, Heidelberg, 1990: 1-12.</span></li>
  <li><span id="Schuh2000">[15] Schuh H, Schmitz-Hübsch H. Short period variations in Earth rotation as seen by VLBI[J]. Surveys in Geophysics, 2000, 21(5): 499-520.</span></li>
  <li><span id="Arias1997">[16] Arias F, Capitaine N, Dehant V, et al. Commission 19: Earth Rotation [Rotation De La Terre][J]. 1997.</span></li>
  <li><span id="MacMillan2000">[17] MacMillan D, Ma C. Improvement of VLBI EOP accuracy and precision[C]//International VLBI Service for Geodesy and Astrometry 2000 General Meeting Proceedings. 2000: 247-251.</span></li>
  <li><span id="Miura2009">[18] Miura Y, Kokado K, Kurihara S. Tsukuba VLBI Correlator[J]. management, 2009, 1: 1.</span></li>
  <li><span id="Behrend2011">[19] Behrend D, Haas R, Nothnagel A. Reports of IERS Components: International VLBI Service [IVS][J]. IERS Annual Report 2008-09. Frankfurt am Main: Verlag des Bundesamts für Kartographie und Geodäsie, 2011: 72-82.</span></li>
  <li><span id="Schluter2007">[20] Schlüter W, Behrend D. The International VLBI Service for Geodesy and Astrometry IVS: current capabilities and future prospects[J]. Journal of Geodesy, 2007, 81(6): 379-387.</span></li>
  <li><span id="Niell2018">[21] Niell A, Barrett J, Burns A, et al. Demonstration of a broadband very long baseline interferometer system: a new instrument for high-precision space geodesy[J]. Radio Science, 2018, 53(10): 1269-1291.</span></li>
  <li><span id="Alef2019">[22] Alef W, Anderson J M, Bernhart S, et al. The EUropean-VGOS Project[C]//Proceedings of the 24th European VLBI Group for Geodesy and Astrometry Working Meeting. 2019, 107: 111.</span></li>
  <li><span id="Bohm2022">[23] Böhm S, Böhm J, Gruber J, et al. Probing a southern hemisphere VLBI Intensive baseline configuration for UT1 determination[J]. Earth, Planets and Space, 2022, 74(1): 1-16.</span></li>
  <li><span id="Lanyi2010">[24] Lanyi G E, Boboltz D A, Charlot P, et al. The Celestial Reference Frame at 24 and 43 GHz. I. Astrometry[J]. The Astronomical Journal, 2010, 139(5): 1695.</span></li>
  <li><span id="Charlot2010">[25] Charlot P, Boboltz D A, Fey A L, et al. The Celestial Reference Frame at 24 and 43 GHz. II. Imaging[J]. The Astronomical Journal, 2010, 139(5): 1713.</span></li>
</ul>]]></content><author><name>Niu Liu</name></author><category term="VLBI" /><summary type="html"><![CDATA[在 2023 年以前，VLBI 数据文件的命名遵循以下规则：日期 yyMMMdd 加 DBC 代码，即 database code，一个或两个字母，一共是 8 到 9 个字符。 注意：自 2023 年之后，VLBI 数据文件的命名规则改为 yyyymmdd 加 session 代码，其中 session 代码最长可达 12 个字符。 这里简单介绍一下 DBC 代码的含义。]]></summary></entry><entry><title type="html">JPL DE 历表的使用</title><link href="https://liuniu.fun/blogs/use_of_jpl_de.html" rel="alternate" type="text/html" title="JPL DE 历表的使用" /><published>2022-03-13T00:00:00+08:00</published><updated>2022-03-13T00:00:00+08:00</updated><id>https://liuniu.fun/blogs/use_of_jpl_de</id><content type="html" xml:base="https://liuniu.fun/blogs/use_of_jpl_de.html"><![CDATA[<p>今天翻到了 2016 年写的关于 JPL DE 历表使用的笔记，就随手上传了。
里面记录的信息也许已经过时了。
后续我会进行测试并更新，以确保本文内容是准确的。</p>

<!-- more -->

<p>有关 DE 历表的信息(参考系、历表的历元区间等)在 README 中均能找到。这里主要讲实际使用。</p>

<p>下载到的 DE 历表数据一般为 ascii 文件，而现有的读取数据软件几乎都是用来处理二进制文件的，因此，使用DE历表之前要先将 ascii 文件转为二进制文件。如何测试转换得到的二进制文件的正确性？JPL提供了<code class="language-plaintext highlighter-rouge">testpo.XXX</code>（XXX 对应于历表的版本号）文件来验证，用来计算的程序名（JPL提供的）为<code class="language-plaintext highlighter-rouge">testeph.f</code>。其实处理DE历表数据的程序有很多，各种语言版本的都有，相关下载信息在<code class="language-plaintext highlighter-rouge">other-users.txt</code>文件里。我用的是使用 JPL 提供的数据转换程序和用于历表计算的 Caleph 程序（C语言版本）。这里仅介绍数据转换程序的用法。</p>

<p>对于用户而言，一般只需了解程序的功能以及可调参数即可。首先，数据格式转换的程序名为<code class="language-plaintext highlighter-rouge">asci2ehp.f</code>，基于F77语言编写，需要关注的参数有两处</p>

<ul>
  <li>
    <p>关于记录数据长度的NREL参数。这和机器本身相关，程序里面提供了<code class="language-plaintext highlighter-rouge">NREL=1</code>和<code class="language-plaintext highlighter-rouge">NREL=4</code>两种选择，去掉对应语句前面的注释即可使用，一般选<code class="language-plaintext highlighter-rouge">NREL=4</code>。</p>
  </li>
  <li>
    <p>\(T_1\)、\(T_2\)。提取数据的区间，对应的时间尺度是 JD，依据自己的选择，选择默认值也可以，对应的应该是提取所有历元跨度的参数（反正对于现在的机器来说，储存空间不是问题）。</p>
  </li>
</ul>

<p>转换使用方法也有很多，这里提供 Linux 终端下的使用方法。假设编译源代码得到的可执行性程序为<code class="language-plaintext highlighter-rouge">asci2eph</code>，那么，输入</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cat header. XXX ascXXX. XXX | ./asci2eph
</code></pre></div></div>

<p>它会先输出常数值，以及计算结果（日期），最后输出“OK”，生成 JPLEPH 文件即最终的数据文件。</p>

<p>接着，测试得到的数据，即与 JPL 计算的结果相比对。源代码为<code class="language-plaintext highlighter-rouge">testeph.f</code>。这个源代码很重要，里面写的一些子程序可以复制，用于历表计算。 主要有</p>

<ul>
  <li>
    <p>subroutine FSIZER1
subroutine FSIZER2
subroutine FSIZER3
具体选哪个与机器记录的数据长度有关。为了编译通过，需要给里面的一些变量赋值。比如<code class="language-plaintext highlighter-rouge">NREC=4</code>，<code class="language-plaintext highlighter-rouge">KSIZE</code>要依据历表的不同赋不同的值。源代码里面有说明。</p>
  </li>
  <li>
    <p>PLEPH （很重要）
用于历表计算，得到天体之间的相对位置（<code class="language-plaintext highlighter-rouge">target</code>和<code class="language-plaintext highlighter-rouge">center</code>）、章动、月球天平动。可以复制到自己的程序里面。<code class="language-plaintext highlighter-rouge">target</code>和<code class="language-plaintext highlighter-rouge">center</code>用整数代表天体，程序里面有说明，实际计算时可以自定义，但测试时不要改动。</p>
  </li>
  <li>
    <p>INTERP
由chebyshev系数计算得到位置和速度（PV）。</p>
  </li>
  <li>
    <p>SPLIT
把历元分为整数和小数部分，为的是不损失精度。</p>
  </li>
  <li>STATE
输入输出的各种声明，如用户需要选择使用哪种<code class="language-plaintext highlighter-rouge">FSIZER</code>，一般选择<code class="language-plaintext highlighter-rouge">FSIZER3</code>。
这里需要注意的两类变量，在自己的代码使用这些子程序时根据需要设置，测试时不要改动。
    <ul>
      <li>与单位相关
        <ul>
          <li><code class="language-plaintext highlighter-rouge">KM=.TRUE</code>（km， km/s）</li>
          <li><code class="language-plaintext highlighter-rouge">KM=.FALSE</code> （AU和AU/d， 默认）</li>
        </ul>
      </li>
      <li>参考点（参考系原点）
        <ul>
          <li><code class="language-plaintext highlighter-rouge">BARY=.TRUE</code>（太阳系质心）</li>
          <li><code class="language-plaintext highlighter-rouge">BARY=.FALSE</code>（太阳）</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>CONST
定义了一些常数。</li>
</ul>

<p>实际使用时，以上提到的子程序最好一并复制过去。</p>

<p><code class="language-plaintext highlighter-rouge">testeph.f</code>默认的输入数据文件名为<code class="language-plaintext highlighter-rouge">JPLEPH</code>，也可以设成自己想要的值，对应的文件名变量在<code class="language-plaintext highlighter-rouge">FSIZER</code>那三个程序中。</p>

<p>假设编译<code class="language-plaintext highlighter-rouge">testeph.f</code>得到<code class="language-plaintext highlighter-rouge">testeph</code>。测试用法如下：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cat testpo.XXX | ./testeph
</code></pre></div></div>

<p>没有输出warning和ERROR信息的话，说明转换的数据没有问题。</p>

<p>2016，6，6 夜</p>]]></content><author><name>Neo</name></author><category term="ephemerides" /><summary type="html"><![CDATA[今天翻到了 2016 年写的关于 JPL DE 历表使用的笔记，就随手上传了。 里面记录的信息也许已经过时了。 后续我会进行测试并更新，以确保本文内容是准确的。]]></summary></entry><entry><title type="html">二维情况下的最小二乘拟合问题</title><link href="https://liuniu.fun/blogs/WLS_for_2D.html" rel="alternate" type="text/html" title="二维情况下的最小二乘拟合问题" /><published>2022-03-07T00:00:00+08:00</published><updated>2022-03-07T00:00:00+08:00</updated><id>https://liuniu.fun/blogs/WLS_for_2D</id><content type="html" xml:base="https://liuniu.fun/blogs/WLS_for_2D.html"><![CDATA[<p>天体测量的数据中，因变量通常是二维的，如位置偏差、自行、章动角、极移等，且这些二维观测量的分量存在一定的相关性。教科书上常用的最小二乘估计法一般是针对一维因变量型的数据，而缺乏基于二维因变量型的观测数据进行最小二乘估计的方案，尤其是需要考虑观测量分量之间相关性的情形。在这里我尝试推导过二维情形下的最小二乘估计的目标函数，并给出了相应的正规方程及其矩阵形式。</p>

<!-- more -->

<p>本文的PDF版本见<a href="https://liuniu.fun/files/notes/wls_for_2d.pdf">这里</a>。</p>

<h1 id="引言">引言</h1>

<p>根据《天文数据处理》中的描述[<a href="#ding1998">1</a>]，参数估计问题可以转换为下述的数学问题：若两个观测量 \(x\) 和 \(y\) 存在某种关于 \(m\) 个待定参数 \(c_k\)（\(k=1,2,\dots,m\)）的形式已知的函数关系，对于 \(N\) 对观测值（\(x_i\)，\(y_i\)）（\(i=1,2,\dots,N\)），确定参数 \(c_k\) 的某一估计值 \(\hat{c}_k\)，使某个目标函数
\begin{equation}
  d = d(x_1,x_2,\dots,x_N; y_1, y_2, \dots, y_N; c_1, c_2, \dots, c_m) \tag{1}
  \label{eq:sample}
\end{equation}
因此，曲线拟合就是对目标函数进行最优化计算，寻求是目标函数 \(d\) 取极值的一组参数值。显然，这样的表述是针对观测量 \(y\) 为一维的情形给出的。
当观测量 \(\mathbfit{y}\)（为了区分我使用了黑体）为二维变量时，我们可以将上面的描述外推，得到当因变量为二维变量时的最小二乘参数估计形式。</p>

<h1 id="最小二乘估计的目标函数">最小二乘估计的目标函数</h1>

<h2 id="回顾一维情形">回顾一维情形</h2>

<p>首先考虑双变量型数据，数据形式可以表述为
\begin{equation}
    (x_i,\sigma_{x,i}, y_i, \sigma_{y,i}), i=1,2,\dots,n \label{eq:data-1d} \tag{2}
\end{equation}
其中，\(x_i\) 为自变量，\(y_i\) 为因变量，也就是观测量，\(\sigma_{x,i}\) 和 \(\sigma_{y,i}\) 分别为相应的测量误差。一般假设观测量彼此之间相互独立，即对于任意的 \(i \ne j\)，\(y_i\) 与 \(y_j\) 相互独立。一般假设自变量的测量误差为零，即
\begin{equation}
\sigma_{x,i} = 0 \tag{3}
\end{equation}
在天文观测资料处理过程中，对观测误差的估计通常与观测值本身之间相互独立，即 \(y_i\) 与 \(\sigma_{y,i}\) 相互独立。为了讨论方便，假设观测量的理论模型为线性模型，具体形式为
\begin{equation}
        F(x_i, \mathbfit{c}) = \sum_{j=1}^m c_j F_j (x_i) \tag{4}
\end{equation}
其中模型中有 \(m\) 个未知参数需要估计，待估参数向量可记为
\begin{equation}
        \mathbfit{c} = (c_1, c_2, \dots, c_m)^{\rm T} \tag{5}
\end{equation}
则第 \(i\) 次的观测值可写为
\begin{equation}
        y_i = F(x_i, \mathbfit{c}) + \epsilon_i \label{eq:model-1d} \tag{6}
\end{equation}
其中 \(\epsilon_i\) 为第 \(i\) 次观测值与理论值之间的偏差，即残差。归一化残差（即加权后的残差）为
\begin{equation}
        X_i = \frac{\epsilon_i}{\sigma_{y,i}} \tag{7}
\end{equation}
最小二乘意义下的参数估计就是选取各观测点的归一化残差平方和作为目标函数
\begin{equation}
    X^2 = \sum_{i=1} ^N X_i^2 = \sum_{i=1} ^N \frac{\epsilon_i^2}{\sigma_{y,i}^2} = \sum_{i=1} ^N \frac{\left(y_i - \sum_{j=1} ^m c_j F_j (x_i)\right)^2}{\sigma_{y,i}^2} \tag{8} \label{eq:x2-1d}
\end{equation}
\(X^2\) 也就是常说的 \(\chi^2\)。选取一组合适的参数值 \(\hat{c}_k\)，使得目标函数 \(X^2\) 取极小值，此时，\(X^2\) 相对于未知参数 \(c_k\) 的偏导为零，即
\begin{equation}
        0 = \frac{\partial X^2}{\partial c_j} = \sum_{i=1}^N \frac{\partial X_i^2}{\partial c_j}, j=1,2,\dots,m \tag{9} \label{eq:dfunc-1d}
\end{equation}</p>

<h2 id="延伸至二维情形">延伸至二维情形</h2>

<p>现在我们考虑当观测量 \(\mathbfit{y_i}\) 为二维变量时的情形，即</p>

<p>\begin{equation}
    \mathbfit{y_i} = \left( y^{(1)}_{i}, y^{(2)} _{i} \right)^{\mathrm T}  \tag{10}
\end{equation}</p>

<p>数据形式变为
\(\begin{equation}
    (x _i,\sigma_{x,i}, y^{(1)} _{i}, y^{(2)}_{i}, \sigma^{(1)} _{y,i},
     \sigma^{(2)}_{y,i}, \rho _i), i=1,2,\dots,n \tag{11}
\end{equation}\)
其中，\(\rho_i\) 表示第 \(i\) 次的观测值向量 \(\mathbfit{y_i}\) 两个分量 \(y^{(1)}_{i}\) 和 \(y^{(2)}_{i}\) 之间的（Pearson）相关性系数。
这里，我们再次假设任意两次观测的观测量分量之间相互独立，即对于任意的 \(i \ne j\)，\(y^{(1)}_{i}\) 和 \(y^{(2)}_{i}\)、\(y^{(1)}_{i}\) 和 \(y^{(2)}_{j}\)、\(y^{(1)}_{j}\) 和 \(y^{(2)}_{i}\)、\(y^{(1)}_{j}\) 和 \(y^{(2)}_{j}\) 均相互独立。</p>

<p>第 \(i\) 次的观测量 \(\mathbfit{y_i}\) 的两个分量对应的理论模型为
\(\begin{equation}
    \begin{aligned}
        F^{(1)}(x _i, \mathbfit{c}) = \sum_{j=1}^m c _j F^{(1)}_{j} (x _i)  \\
F^{(2)}(x_i, \mathbfit{c}) = \sum_{j=1}^m c_j F^{(2)} _{j} (x_i)
    \end{aligned} \tag{12}
\end{equation}\)
则第 \(i\) 次观测值的两个分量可以表示为
\(\begin{equation}
    \begin{aligned}
        y^{(1)} _{i} = F^{(1)} (x_i, \mathbfit{c}) + \epsilon^{(1)}_{i} \\
y^{(2)}_{i} = F^{(2)} (x_i, \mathbfit{c}) + \epsilon^{(2)}_{i}
    \end{aligned} \tag{13}
\end{equation}\)
归一化的残差分别为
\(\begin{equation}
        X^{(1)} _{i} = \frac{\epsilon^{(1)}_{i}}{\sigma^{(1)} _{y,i}},\quad X^{(2)}_{i} = \frac{\epsilon^{(2)} _{i}}{\sigma^{(2)}_{y,i}}
        \tag{14}
\end{equation}\)
借用Mignard等人[<a href="#mignard2016">2</a>]提出的 \(X\) 统计量，归一化的二维残差 \(X_i\) 可由下式导出</p>

\[\begin{aligned}
    X _i^{2} &amp;= {
    \left[\begin{array}{cc}
    X^{(1)} _{i} &amp; X^{(2)} _{i}
    \end{array}\right]
    } \left[\begin{array}{cc}
    1 &amp; \rho _i \\\\
    \rho _i &amp; 1
    \end{array}\right]^{-1} \left[\begin{array}{c}
    X^{(1)} _{i} \\\\
    X^{(2)} _{i}
    \end{array}\right] \\\\
    &amp; = \frac{1}{1-\rho _i^2} \left[\begin{array}{cc}
    X^{(1)} _{i} &amp; X^{(2)} _{i}
    \end{array}\right] \left[\begin{array}{cc}
    1 &amp; -\rho _i \\\\
    -\rho _i &amp; 1
    \end{array}\right]\left[\begin{array}{c}
    X^{(1)} _{i} \\\\
    X^{(2)} _{i}
    \end{array}\right] \\\\
    &amp; = \frac{1}{1-\rho _i^2}\left[\left( X^{(1)} _{i}\right)^2 + \left(X^{(2)} _{i}\right)^2 - 2\rho _i X^{(1)} _{i} X^{(2)} _{i} \right]
\end{aligned}
    \tag{15}\]

<p>目标函数即归一化的二维残差平方和为
\(\begin{equation}
    X^2= \sum _{i=1} ^N X_i^2 = \sum_{i=1} ^N \frac{1}{1-\rho_i^2}\left[ \left( X^{(1)} _{i} \right)^2 + \left( X^{(2)} _{i} \right)^2 - 2\rho  _i X^{(1)} _{i} X^{(2)} _{i} \right] \tag{16} \label{eq:x2-2d}
\end{equation}\)
当观测量\(\mathbfit{y_i}\)的两个分量之间不相关时，即
\(\begin{equation}
    \rho_i = 0, \quad i = 1, 2, \dots, N \tag{17}
\end{equation}\)
此时，目标函数变为
\(\begin{equation}
        X^2= \sum _{i=1} ^N X_i^2 = \sum_{i=1} ^N \left( X^{(1)}_{i} \right)^2 + \sum_{i=1} ^N \left( X^{(2)}_{i} \right)^2 = \left( X^{(1)} \right)^2 + \left( X^{(2)} \right)^2 \tag{18}
\end{equation}\)
即将两个分量视为相互独立的一维观测量时得到的目标函数之和。</p>

<h2 id="由极大似然估计间接导出">由极大似然估计间接导出</h2>

<p>在观测量\(\mathbfit{y}\)为一维情形下，若观测残差\(\epsilon_i\) 只包含随机噪声，即观测残差服从高斯分布
\(\begin{equation}
    \epsilon _i \sim N(0, \sigma_{y,i}) \tag{19} \label{eq:nor-dist-1d}
\end{equation}\)
此时，极大似然估计等价于最小二乘估计。这一结论也可以推广到二维甚至更高维情形。现在我先简单给出一维情形下的不严格证明，之后再从二维情形下的极大似然估计出发给出二维情形下的最小二乘估计的目标函数。</p>

<p>假设在方程\eqref{eq:model-1d}对应的模型下，在待估参数 \(\mathbfit{c}\) 处得到一对观测值（\(x_i\)，\(y_i\)）的概率密度为 \(f(x _i, y_i; \mathbfit{c})\)。现在进行了 \(N\) 次观测之后，得到一组如方程\eqref{eq:data-1d}所示的观测值这一事件 \(p\) 发生的概率密度为[<a href="#feigelson2012">3</a>]
\(\begin{equation}
L(\mathbfit{c}) = \prod_{i=1}^{N} f(x_i, y _i; \mathbfit{c}) \tag{20}
\end{equation}\)
上式中的\(L(\mathbfit{c})\) 即似然函数。由于事件\(p\)是真实发生的，因此在待估参数\(\mathbfit{c}\)取得最佳估计 \(\hat{\mathbfit{c}}\) 时，\(L(\mathbfit{c})\) 取得极大值。 但因为 \(L(\mathbfit{c})\) 是连乘形式，不利于计算，常选取其对数形式，即对数似然函数 \(l(\mathbfit{c})\) 来进行参数估计，其表达式为
\(\begin{equation}
l(\mathbfit{c}) =  \ln L(\mathbfit{c}) = \sum_{i=1}^{N} \ln f(x _i, y_i; \mathbfit{c}) \tag{21}
\end{equation}\)
这就是极大似然估计法的目标函数。不同于最小二乘估计，这里取目标函数的极大值。
在方程\eqref{eq:nor-dist-1d}的假设下，有
\(\begin{equation}
f(x_i, y_i; \mathbfit{c}) = f(\epsilon _i; \mathbfit{c})  = \frac{1}{\sqrt{2\pi} \sigma_i} \exp{\left(-\frac{\epsilon_i^2}{2\sigma^2_{y,i}}\right)} \tag{22}
\end{equation}\)
由此可以计算得
\(\begin{equation}
l(\mathbfit{c}) = \sum_{i=1}^{N} \left[ -\ln{\left( \sqrt{2\pi} \sigma _i \right)} -\frac{\epsilon _i^2}{2\sigma^2 _{y,i}}\right] = - \sum_{i=1}^{N} \frac{\epsilon_i^2}{2\sigma^2_{y,i}}  + {\rm const} \tag{23}
\end{equation}\)
上式等号右边最后一项为与任一待估参数\(c_k\)均无关的常数项。
可见，对数似然函数 \(l(\mathbfit{c})\) 取极大值等价于方程\eqref{eq:x2-1d}中的 \(X^2\) 取极小值，因此，此时的极大似然估计等价于最小二乘估计。
我不加证明地将这一结论外推到二维乃至高维情形，并利用这一结论反推出二维情形下最小二乘估计法的目标函数。</p>

<p>在二维情形下，若观测残差 \(\mathbfit{\epsilon_i}\) 服从二维高斯分布，则有</p>

\[\begin{aligned}
    &amp; \quad f(\epsilon^{(1)} _i, \epsilon^{(2)} _i; \mathbfit{c}) \\\\
    &amp;= \frac{1}{2\pi \sigma^{(1)} _{y,i} \sigma^{(2)} _{y,i} \sqrt{1-\rho^2 _i}} \exp{\left\{  -\frac{1}{2 (1-\rho _i^2)} \left[\left( \frac{\epsilon^{(1)} _i}{\sigma^{(1)} _{y,i}}\right)^2 +  \left( \frac{\epsilon^{(2)} _i}{\sigma^{(2)} _{y,i}}\right)^2 -2\rho _i \frac{\epsilon^{(1)} _i}{\sigma^{(1)} _{y,i}}\frac{\epsilon^{(2)} _i}{\sigma^{(2)} _{y,i}} \right] \right \} } \\\\
    &amp;= \frac{1}{2\pi \sigma^{(1)} _{y,i} \sigma^{(2)} _{y,i} \sqrt{1-\rho^2 _i}}
    \exp{\left \{  -\frac{1}{2 (1-\rho _i^2)} \left[\left( X _i^{(1)} \right)^2 +  \left( X _i^{(2)}\right)^2 -2\rho _i X _i^{(1)}X _i^{(2)} \right] \right\} }
\end{aligned} \tag{24}\]

<p>由此可知对数似然函数 \(l(\mathbfit{c})\) 的表达式为</p>

\[\begin{aligned}
    l(\mathbfit{c}) &amp;= \sum _{i=1}^{N} \left\{  -\frac{1}{2 (1-\rho_i^2)} \left[\left( X _i^{(1)} \right)^2 +  \left( X _i^{(2)}\right)^2 -2\rho _i X _i^{(1)}X _i^{(2)} \right] -\ln{ \left( 2\pi \sigma^{(1)} _{y,i} \sigma^{(2)} _{y,i} \sqrt{1-\rho^2 _i} \right) } \right\}  \\\\
    &amp; = - \sum _{i=1}^{N} -\frac{1}{2 (1-\rho _i^2)} \left[\left( X _i^{(1)} \right)^2 +  \left( X _i^{(2)}\right)^2 -2\rho _i X _i^{(1)}X _i^{(2)} \right] + {\rm const}
\end{aligned} \tag{25}\]

<p>可见，上式的对数似然函数 \(l(\mathbfit{c})\) 取极大值等价于方程\eqref{eq:x2-2d}中的 \(X^2\) 取极小值。
这也反过来说明了方程\eqref{eq:x2-2d}的正确性。</p>

<h1 id="二维情形下最小二乘估计法的实现">二维情形下最小二乘估计法的实现</h1>

<p>前面分别给出了最小二乘估计法在一维和二维情形下的目标函数，这里我将导出相应的正规方程，从而给出最小二乘估计法的具体实现。
我依然先推导一维情形的正规方程。
利用方程\eqref{eq:x2-1d}将方程\eqref{eq:dfunc-1d}展开，对任意的 \(j=1,2,\dots,m\) 均有
\(\begin{equation}
    0 = \sum _{i=1} ^N \frac{\partial X^2_i}{\partial c_j} = \sum_{i=1} ^N 2X_i \frac{\partial X_i}{\partial c _j} = \sum_{i=1} ^N -2\left( y _i - \sum_k^m c_k F_k (x _i) \right)  \frac{F_j (x_i)}{\sigma^2_{y,i}} \tag{26} \label{eq:par-eq-1d}
\end{equation}\)
进一步展开，有
\(\begin{equation}
\sum_{i=1} ^N \sum_k^m \frac{c _k F_j (x_i) F_k (x _i)}{\sigma^2_{y,i}} = \sum _{i=1} ^N \frac{F_j (x_i) y_i}{\sigma^2 _{y,i}}
    , j=1,2,\dots,m \tag{27} \label{eq:nor-eq-1d}
\end{equation}\)
考虑一个模型理论值向量
\(\begin{equation}
\mathbfit{F} = \left( F(x_1,\mathbfit{c}), F(x_2,\mathbfit{c}), \dots, F(x_N,\mathbfit{c}) \right)^{\rm T} \tag{28}
\end{equation}\)
向量 \(\mathbfit{F}\) 相对于 \(\mathbfit{c}\) 的偏导构成了雅可比矩阵
\(\begin{equation}
    \mathcal{J} = \frac{\partial \mathbfit{F}}{\partial \mathbfit{c}}, \quad \mathcal{J} _{ij}=\frac{\partial F(x_i,\mathbfit{c})}{\partial c_j}=F_j(x _i,\mathbfit{c}) \tag{29}
\end{equation}\)
向量 \(\mathbfit{F}\) 相对于任一待估参数 \(c_j\) 的偏导构成了向量
\(\begin{equation}
\frac{\partial \mathbfit{F}}{\partial c_j} = \left( F_j(x _1,\mathbfit{c}), F_j(x_2,\mathbfit{c}), \dots,  F_j(x _N,\mathbfit{c}) \right)^{\rm T} \tag{30}
\end{equation}\)
可见，\(\dfrac{\partial \mathbfit{F}}{\partial c_j}\)是雅可比矩阵\(\mathcal{J}\)的第\(j\)列，而 \(\left( \dfrac{\partial \mathbfit{F}}{\partial c_j}\right)^{\rm T}\) 是雅可比矩阵的转置矩阵 \(\mathcal{J}^{\rm T}\) 的第 \(j\) 行。
引入一个加权矩阵 \(\mathcal{M}\)，它可以看作是观测向量 \(\mathbfit{y}\) 的协方差矩阵 \(\mathcal{V}\) 的求逆，其表达式分别为</p>

\[\mathcal{V} = \left(\begin{array}{cccc}
    \sigma _{y,1}^{2} &amp; O &amp; \dots &amp; O \\\\
    O &amp; \sigma _{y,2}^{2} &amp; \dots &amp; O \\\\
    \vdots &amp; \vdots &amp; \ddots &amp; \vdots \\\\
    O &amp; O &amp; \dots &amp; \sigma _{y,N}^{2}
    \end{array}\right),
    \mathcal{M} = \left(\begin{array}{cccc}
    \sigma _{y,1}^{-2} &amp; O &amp; \dots &amp; O \\\\
    O &amp; \sigma _{y,2}^{-2} &amp; \dots &amp; O \\\\
    \vdots &amp; \vdots &amp; \ddots &amp; \vdots \\\\
    O &amp; O &amp; \dots &amp; \sigma _{y,N}^{-2}
    \end{array}\right) = \mathcal{V}^{-1}
    \tag{31} \label{eq:cov-wgt}\]

<p>一组观测值构成一个观测值向量，即
\begin{equation}
    \mathbfit{y} = (y _1, y_2, \dots, y_N)^{\rm T} \tag{32}
\end{equation}
那么，方程\eqref{eq:nor-eq-1d}中对 \(i\) 求和可以写为</p>

\[\begin{aligned}
        \sum _{i=1} ^N \dfrac{F _j (x _i) F _k (x _i)}{\sigma^2 _{y,i}} c _k  &amp;= \left( \dfrac{\partial \mathbfit{F}}{\partial c _j} \right)^{\rm T} \mathcal{M} \dfrac{\partial \mathbfit{F}}{\partial c _k} c _k  \\\\
        \sum _{i=1} ^N \dfrac{F _j (x _i) y _i}{\sigma^2 _{y,i}} &amp;= \left( \dfrac{\partial \mathbfit{F}}{\partial c _j} \right)^{\rm T} \mathcal{M} \mathbfit{y}
    \end{aligned} \tag{33} \label{eq:nor-eq-2d-k}\]

<p>类似地，方程\eqref{eq:nor-eq-2d-k}再对 \(k\) 求和也可以写成矩阵乘积的形式，为
\(\begin{equation}
    \left( \frac{\partial \mathbfit{F}}{\partial c _j} \right)^{\rm T} \sum_{k=1} ^m \frac{\partial \mathbfit{F}}{\partial c _k} c_k = \left( \frac{\partial \mathbfit{F}}{\partial c_j} \right)^{\rm T} \mathcal{J} \mathbfit{c} \tag{34}
\end{equation}\)
方程\eqref{eq:nor-eq-1d}可以写成矩阵相乘的形式，有
\(\begin{equation}
\left( \frac{\partial \mathbfit{F}}{\partial c_j} \right)^{\rm T} \mathcal{M} \mathcal{J} \mathbfit{c} = \left( \frac{\partial \mathbfit{F}}{\partial c _j} \right)^{\rm T} \mathcal{M} \mathbfit{y}, j=1,2,\dots,m \tag{35} \label{eq:JVMat-1d}
\end{equation}\)
将所有的 \(j=1,2,\dots,m\) 对应的上述方程叠加在一起，则有
\begin{equation}
    \mathcal{J}^T \mathcal{M} \mathcal{J} \mathbfit{c} = \mathcal{J}^T \mathcal{M} \mathbfit{y} \tag{36} \label{eq:nor-mat-eq}
\end{equation}
从而，可以求出未知参数向量的最小二乘估计
\begin{equation}
    \hat{\mathbfit{c}} = \left(\mathcal{J}^T \mathcal{M} \mathcal{J}\right)^{-1} \mathcal{J}^T \mathcal{M} \mathbfit{y} \tag{37} \label{eq:pmt}
\end{equation}</p>

<p>当观测量\(\mathbfit{y}\)为二维时，情况要复杂得多。
类似于方程\eqref{eq:par-eq-1d}，有</p>

\[\begin{aligned}
    \frac{\partial X^2 _i}{\partial c _j} &amp;= \frac{1}{1-\rho _i^2} \left( 2 X^{(1)} _{i} \frac{\partial X^{(1)} _{i}}{\partial c _j} + 2 X^{(2)} _{i} \frac{\partial X^{(2)} _{i}}{\partial c _j} - 2\rho _i \frac{\partial X^{(1)} _{i}}{\partial c _j} X^{(2)} _{i} - 2\rho _i X^{(1)} _{i} \frac{\partial X^{(2)} _{i}}{\partial c _j} \right) \\\\
    &amp;=  \frac{2}{1-\rho _i^2} \left[  -\left( y^{(1)} _{i} - \sum _k^m c _k F^{(1)} _{k} (x _i) \right)  \frac{F^{(1)} _{j} (x _i)}{(\sigma^{(1)} _{y,i})^2}  - \left( y^{(2)} _{i} - \sum _k^m c _k F^{(2)} _{k} (x _i) \right)  \frac{F^{(2)} _{j} (x _i)}{(\sigma^{(2)} _{y,i})^2} \right. \\\\
    &amp;\quad \left. + \rho _i \left( y^{(2)} _{i} - \sum _k^m c _k F^{(2)} _{k} (x _i) \right)  \frac{F^{(1)} _{j} (x _i)}{\sigma^{(1)} _{y,i}\sigma^{(2)} _{y,i}} + \rho _i \left( y^{(1)} _{i} - \sum _k^m c _k F^{(1)} _{k} (x _i) \right) \frac{F^{(2)} _{j} (x _i)}{\sigma^{(1)} _{y,i}\sigma^{(2)} _{y,i}} \right], \\\\
    &amp; j=1,2,\dots,m
\end{aligned}  \tag{38} \label{eq:nor-eq-2d}\]

<p>将上式对 \(i\) 求和，并令其等于0，有</p>

\[\tag{39}
    \begin{aligned}
      &amp;\sum _{i=1} ^N \sum _k^m \frac{ c _k}{1-\rho _i^2} \left[ \frac{F^{(1)} _{j} (x _i) F^{(1)} _{k} (x _i)}{(\sigma^{(1)} _{y,i})^2} + \frac{F^{(2)} _{j} (x _i) F^{(2)} _{k} (x _i)}{(\sigma^{(2)} _{y,i})^2} - \frac{\rho _i \left( F^{(1)} _{j} (x _i) F^{(2)} _{k} (x _i) + F^{(2)} _{j} (x _i) F^{(1)} _{k} (x _i) \right)}{\sigma^{(1)} _{y,i}\sigma^{(2)} _{y,i}}  \right]  \\\\
     &amp;= \sum _{i=1} ^N \sum _k^m  \frac{1}{1-\rho _i^2}  \left[ \frac{F^{(1)} _{j} (x _i) y^{(1)} _{i}}{(\sigma^{(1)} _{y,i})^2} + \frac{F^{(2)} _{j} (x _i) y^{(2)} _{i}}{(\sigma^{(2)} _{y,i})^2} - \frac{\rho _i \left( F^{(1)} _{j} (x _i) y^{(2)} _{i} + F^{(2)} _{j} (x _i) y^{(1)} _{i} \right)}{\sigma^{(1)} _{y,i}\sigma^{(2)} _{y,i}} \right],  \\\\
      &amp;   j=1,2,\dots,m
    \end{aligned} \label{eq:nor-eq-2d-new}\]

<p>方程\eqref{eq:nor-eq-2d-new}等式左边求和子项可以写为</p>

\[\begin{aligned}
        &amp;\quad \left( \begin{array}{cc}
            F^{(1)} _{j} (x _i) &amp;F^{(2)} _{j} (x _i)
        \end{array}   \right) \left( \begin{array}{cc}
            (\sigma^{(1)} _{y,i})^{-1} &amp;0 \\\\
            0 &amp;(\sigma^{(2)} _{y,i})^{-1}
        \end{array}   \right) \frac{1}{1-\rho _i^2} \left( \begin{array}{cc}
            1 &amp;-\rho _i \\\\
            -\rho _i &amp;1
        \end{array}   \right) \left( \begin{array}{cc}
            (\sigma^{(1)} _{y,i})^{-1} &amp;0 \\\\
            0 &amp;(\sigma^{(2)} _{y,i})^{-1}
        \end{array}   \right) \left( \begin{array}{c}
            F^{(1)} _{k} (x _i) \\\\
            F^{(2)} _{k} (x _i)
        \end{array}   \right)  \\\\
        &amp;= \left( \begin{array}{cc}
            F^{(1)} _{j} (x _i) &amp;F^{(2)} _{j} (x _i)
        \end{array}   \right) \left( \begin{array}{cc}
            (\sigma^{(1)} _{y,i})^2 &amp;\rho _i \sigma^{(1)} _{y,i} \sigma^{(2)} _{y,i} \\\\
            \rho _i \sigma^{(1)} _{y,i} \sigma^{(2)} _{y,i} &amp;(\sigma^{(2)} _{y,i})^2
        \end{array}   \right)^{-1} \left( \begin{array}{c}
            F^{(1)} _{k} (x _i) \\\\
            F^{(2)} _{k} (x _i)
        \end{array}   \right)
    \end{aligned} \tag{40}\]

<p>上式第二项即为第 \(i\) 次观测量 \(\mathbfit{y _i}\) 的协方差矩阵。
同样地，方程\eqref{eq:nor-eq-2d-new}等号右边求和子项可以写为</p>

\[\left( \begin{array}{cc}
        F^{(1)} _{j} (x _i) &amp;F^{(2)} _{j} (x _i)
    \end{array}   \right) \left( \begin{array}{cc}
        (\sigma^{(1)} _{y,i})^2 &amp;\rho _i \sigma^{(1)} _{y,i} \sigma^{(2)} _{y,i} \\\\
        \rho _i \sigma^{(1)} _{y,i} \sigma^{(2)} _{y,i} &amp;(\sigma^{(2)} _{y,i})^2
    \end{array}   \right)^{-1} \left( \begin{array}{c}
        y^{(1)} _{i} \\\\
        y^{(2)} _{i}
    \end{array}   \right) \tag{41}\]

<p>我们可以构建合适的矩阵 \(\mathcal{J}\)、\(\mathcal{M}\) 和 \(\mathbfit{y}\)，来将方程\eqref{eq:nor-eq-2d-new}改写成如方程\eqref{eq:JVMat-1d}的矩阵形式。 至少有两种方案可以实现上述目的。
第一种方案的矩阵 \(\mathcal{J}\)、\(\mathcal{V}\) 和 \(\mathbfit{y}\) 如下所示：</p>

\[\begin{aligned}
        \mathcal{J} &amp;= \left( \begin{array}{cc}
            \dfrac{\partial \mathbfit{F}^{(1)}}{\partial \mathbfit{c}} &amp;\dfrac{\partial \mathbfit{F}^{(2)}}{\partial \mathbfit{c}}
        \end{array} \right), \\\\
        \mathcal{J} _{ij} &amp;= \frac{\partial F^{(1)}(x _i,\mathbfit{c})}{\partial c _j}=F^{(1)} _j(x _i,\mathbfit{c}) \\\\
        \mathcal{J} _{(i+N),j} &amp;= \frac{\partial F^{(2)}(x _i,\mathbfit{c})}{\partial c _j}=F^{(2)} _j(x _i,\mathbfit{c})
    \end{aligned} \tag{42}\]

\[\tag{43} \label{eq:covmat-2d-1}
        \mathcal{V} = \left(\begin{array}{cccccc}
        \left(\sigma^{(1)} _{y,1}\right)^2 &amp;\dots &amp;O &amp;\rho _1 \sigma^{(1)} _{y,1} \sigma^{(2)} _{y,1} &amp;\dots &amp;O \\\\
        \vdots &amp;\ddots &amp;\vdots &amp;\vdots &amp;\ddots &amp;\vdots \\\\
        O &amp;\dots &amp;\left(\sigma^{(1)} _{y,N}\right)^2 &amp;O &amp;\dots &amp;\rho _N \sigma^{(1)} _{y,N} \sigma^{(2)} _{y,N} \\\\
        \rho _1 \sigma^{(1)} _{y,1} \sigma^{(2)} _{y,1} &amp;\dots &amp;O &amp; \left(\sigma^{(2)} _{y,1}\right)^2 &amp;\dots &amp;O \\\\
        \vdots &amp;\ddots &amp;\vdots &amp;\vdots &amp; \ddots &amp;\vdots  \\\\
        O &amp;\dots &amp;\rho _N \sigma^{(1)} _{y,N} \sigma^{(2)} _{y,N} &amp;O &amp;\dots &amp;\left(\sigma^{(2)} _{y,N}\right)^2
        \end{array}\right)\]

<p>\begin{equation}
    \tag{44} \label{eq:obs-2d-1}
    \mathbfit{y} = \left( \begin{array}{c}
        \mathbfit{y}^{(1)}   \<br />
        \mathbfit{y}^{(2)}
    \end{array} \right)^{\rm T} = (y^{(1)} _1, y^{(1)}_2, \dots, y^{(1)} _N, y^{(2)}_1, y^{(2)} _2, \dots, y^{(2)}_N)^{\rm T}
\end{equation}</p>

<p>另一种方案则是这样的：</p>

\[\tag{45}
    \begin{aligned}
        \mathcal{J} _{(2i-1),j} &amp;= \frac{\partial F^{(1)}(x _i,\mathbfit{c})}{\partial c _j}=F^{(1)} _j(x _i,\mathbfit{c}) \\\\
        \mathcal{J} _{(2i),j} &amp;= \frac{\partial F^{(2)}(x _i,\mathbfit{c})}{\partial c _j}=F^{(2)} _j(x _i,\mathbfit{c})
    \end{aligned}\]

\[\tag{46} \label{eq:covmat-2d-2}
    \mathcal{V} = \left(\begin{array}{ccccc}
    \left(\sigma^{(1)} _{y,1}\right)^2 &amp;\rho _1 \sigma^{(1)} _{y,1} \sigma^{(2)} _{y,1} &amp;\dots &amp; O &amp; O \\\\
    \rho _1 \sigma^{(1)} _{y,1} \sigma^{(2)} _{y,1} &amp;\left(\sigma^{(2)} _{y,1}\right)^2 &amp;\dots &amp;O &amp;O \\\\
    \vdots &amp;\vdots &amp;\ddots &amp;\ddots &amp;\vdots \\\\
    \vdots &amp;\vdots &amp;\ddots &amp;\left(\sigma^{(1)} _{y,N}\right)^2 &amp;\rho _N \sigma^{(1)} _{y,N} \sigma^{(2)} _{y,N} \\\\
    O &amp;O &amp;\dots &amp; \rho _N \sigma^{(1)} _{y,N} \sigma^{(2)} _{y,N} &amp;\left(\sigma^{(2)} _{y,N}\right)^2
    \end{array}\right)\]

<p>\begin{equation}
\tag{47}\label{eq:obs-2d-2}
    \mathbfit{y}  = (y^{(1)} _1, y^{(2)}_1, y^{(1)} _2, y^{(2)}_2,  \dots, y^{(1)} _N, y^{(2)}_N)^{\rm T}
\end{equation}
\(\mathcal{M}\)可由方程\eqref{eq:covmat-2d-1}或\eqref{eq:covmat-2d-2}，结合方程\eqref{eq:cov-wgt}得出。利用方程\eqref{eq:nor-mat-eq}和\eqref{eq:pmt}，就可以得到未知参数的估计值。方程\eqref{eq:obs-2d-1}和\eqref{eq:obs-2d-2}实际上是将二维的观测值向量转换成了一维观测值向量。</p>

<p>当观测量 \(\mathbfit{y}\) 的两个分量不相关时，目标函数可以简化为
\(\begin{equation}
    \tag{48}
    X^2= \sum _{i=1} ^N X_i^2 = \sum_{i=1} ^N \left( X^{(1)}_{i} \right)^2 + \sum_{i=1} ^N \left( X^{(2)}_{i} \right)^2 = \left(X^{(1)}\right)^2 + \left(X^{(2)}\right)^2
\end{equation}\)
方程\eqref{eq:covmat-2d-1}和\eqref{eq:covmat-2d-2}给出的协方差矩阵 \(\mathcal{V}\) 和相应的加权矩阵 \(\mathcal{M}\) 均变为对角矩阵。</p>

<h1 id="总结与讨论">总结与讨论</h1>

<p>借由上述推导，我们得到了在观测因变量为二维情况下的最小二乘估计的具体实现。对于更高维度的情形，可以进行类似的分析。对我个人而言，最容易理解的就是方程\eqref{eq:nor-mat-eq}到\eqref{eq:obs-2d-2}的矩阵形式。对于更加复杂的情况，如不同次的观测值 \(\mathbfit{y} _i\) 之间存在某种相关性且相关性系数（或者协方差）已知，只需将协方差矩阵 \(\mathcal{V}\) 的对应元素作出相应调整（从零调整为协方差）即可。观测量分量之间的相关性究竟如何影响到参数的最小二乘估计结果？对于这一问题，目前我还没有明确的结果和结论，后续我会利用一些典型的研究问题进行分析比较。</p>

<h1 id="参考文献">参考文献</h1>

<ul>
  <li>
    <p><span id="ding1998">[1] 丁月蓉. 天文数据处理方法[M]. 南京大学出版社, 1998.</span></p>
  </li>
  <li>
    <p><span id="mignard2016">[2] Mignard F, Klioner S, Lindegren L, et al. Gaia Data Release 1: Reference frame and optical properties of ICRF sources[J]. Astronomy &amp; Astrophysics, 2016, 595: A5.</span></p>
  </li>
  <li>
    <p><span id="feigelson2012">[3] Feigelson E D, Babu G J. Modern statistical methods for astronomy: with R applications[M]. Cambridge University Press, 2012.</span></p>
  </li>
</ul>]]></content><author><name>Neo</name></author><category term="statistics" /><category term="astrometry" /><summary type="html"><![CDATA[天体测量的数据中，因变量通常是二维的，如位置偏差、自行、章动角、极移等，且这些二维观测量的分量存在一定的相关性。教科书上常用的最小二乘估计法一般是针对一维因变量型的数据，而缺乏基于二维因变量型的观测数据进行最小二乘估计的方案，尤其是需要考虑观测量分量之间相关性的情形。在这里我尝试推导过二维情形下的最小二乘估计的目标函数，并给出了相应的正规方程及其矩阵形式。]]></summary></entry><entry><title type="html">为SGDASS添加新的用户</title><link href="https://liuniu.fun/blogs/configuration_for_sgdass_new_user.html" rel="alternate" type="text/html" title="为SGDASS添加新的用户" /><published>2022-03-04T00:00:00+08:00</published><updated>2022-03-04T00:00:00+08:00</updated><id>https://liuniu.fun/blogs/configuration_for_sgdass_new_user</id><content type="html" xml:base="https://liuniu.fun/blogs/configuration_for_sgdass_new_user.html"><![CDATA[<p>当 SGDASS 由课题组内共用时，每当有新的成员加入课题组，就需要新建一个用户并进行相关配置。
这里介绍一下我所使用的方法，仅供参考。</p>

<!-- more -->

<h2 id="在服务器上新建用户">在服务器上新建用户</h2>

<p>我的服务器操作系统为Ubuntu24.04。为了便于文件权限的管理，我建立了一个名为<code class="language-plaintext highlighter-rouge">vlbi</code>的用户组，并将所有与SGDASS相关的文件夹和文件的读写权限赋予该用户组成员。
因此，新建的用户也应该被包含在 vlbi 用户组中。</p>

<p>假设需要建立一个名为somebody的新用户，运行</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>username=somebody
sudo useradd -m -s /usr/bin/bash ${username}
sudo usermod -a -G vlbi ${username}
</code></pre></div></div>
<p>之后，运行</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pass ${username}
</code></pre></div></div>
<p>来为新用户设置密码。</p>

<h2 id="为新用户配置运行环境">为新用户配置运行环境</h2>

<p>SGDASS在tcsh下运行，因此，需要在<code class="language-plaintext highlighter-rouge">~/.tcshrc</code>文件（如果没有请新建该文件）中加入与SGDASS相关的语句。
我的配置文件如下所示：</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># /etc/csh.cshrc: system-wide .cshrc file for csh(1) and tcsh(1)

if ($?tcsh &amp;&amp; $?prompt) then

	bindkey "\e[1~" beginning-of-line # Home
	bindkey "\e[7~" beginning-of-line # Home rxvt
	bindkey "\e[2~" overwrite-mode    # Ins
	bindkey "\e[3~" delete-char       # Delete
	bindkey "\e[4~" end-of-line       # End
	bindkey "\e[8~" end-of-line       # End rxvt

	set autoexpand
	set autolist
    set prompt = "%U%m%u:%B%~%b%# "
endif

set dir=/etc/csh/cshrc.d
if (-e $dir &amp;&amp; `/bin/ls $dir` != "") then
  foreach FILE (`/bin/ls $dir/*`)
    source $FILE;
  end;
endif

set cr = "%{\e[31m%}" 
set cg = "%{\e[32m%}" 
set c0 = "%{\e[0m%}"  

# Set some variables for interactive shells
if ( $?prompt ) then
    if ( "$uid" == "0" ) then
        set prompt = "%B%U%n%u@%m.$cr%l$c0%b %c2 %B%%%b " 
    else
        set prompt = "%B%U%n%u@%m.$cg%l$c0%b %c2 %B%%%b "
    endif
endif

# For SGDASS
# gfortran compiler 
# Note: These lines are stored in ~/.login as suggested by Leonid, while his
# method does not work for me. Therefore, I put them in .tcshrc.
limit coredumpsize 0
limit stacksize 8000000
limit maxproc 16384
limit descriptors 2048
setenv GOMP_STACKSIZE 2000000
setenv LD_LIBRARY_PATH /opt64/lib:/opt64/lib64:/usr/lib:/usr/lib64
setenv PATH "/opt64/bin:/opt64/psolve/bin:${PATH}"
# pSolve
setenv PSOLVE_SAVE_DIR "/opt64/share/psolve"
# VTD
setenv VTD_CONF_SES /opt64/share/psolve/solve_lite.vtd
# PIMA
setenv PIMA_NUM_THREADS 8
# pgplot configuration
setenv PGPLOT_DEV "/xw"                      # tells that default is to print
                                              # the graphics to the screen
setenv PGPLOT_XW_MARGIN "1.0"                 # sets display margins
setenv PGPLOT_XSIZE_MM 400.0                  # specifies with width of the PGPLOT window

xrdb -merge ~/.Xdefaults
# setenv DIAGI_SCREEN "vast" # For big screen
setenv DIAGI_SCREEN "small"  # For laptop screen
</code></pre></div></div>
<p>从上面内容中很容易就可以找到与SGDASS相关的配置语句及其用途。</p>

<p>此外，还需要在<code class="language-plaintext highlighter-rouge">~/.Xdefaults</code>文件（如果没有请新建该文件）中加入</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pgxwin.Win.iconize:     True
pgxwin.Win.geometry:	1080x750+0+50
pgxwin.server.visible:	True
pgxwin.Win.maxColors:   230
</code></pre></div></div>

<p>至此，新用户应该就可以顺利运行SGDASS中的软件了。</p>]]></content><author><name>Neo</name></author><category term="VLBI" /><category term="software" /><summary type="html"><![CDATA[当 SGDASS 由课题组内共用时，每当有新的成员加入课题组，就需要新建一个用户并进行相关配置。 这里介绍一下我所使用的方法，仅供参考。]]></summary></entry><entry><title type="html">安装nuSolve时的Qt5库函数问题</title><link href="https://liuniu.fun/blogs/qt5_for_nuSolve.html" rel="alternate" type="text/html" title="安装nuSolve时的Qt5库函数问题" /><published>2022-02-11T00:00:00+08:00</published><updated>2022-02-11T00:00:00+08:00</updated><id>https://liuniu.fun/blogs/qt5_for_nusolve</id><content type="html" xml:base="https://liuniu.fun/blogs/qt5_for_nuSolve.html"><![CDATA[<p>昨天尝试在Ubuntu 21.10服务器上安装<a href="https://sourceforge.net/projects/nusolve/">nuSolve</a>,
结果遇到了与Qt5库函数的编译问题，在这里记录一下解决办法。
桌面版也许没有此类问题。</p>

<!-- more -->

<p>在网上搜索“在Ubuntu上安装Qt5”，得到的答案多数是</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install qt5-default
</code></pre></div></div>

<p>可惜的是，这对于Ubuntu 21.10来说属于是过期攻略了。
因为，在Ubuntu 21.10的仓库里面，Qt5库函数的名称改变了，新的名称以及对应的安装指令如下：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo apt install qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools 

sudo apt install libqt5script5 libqt5scripttools5 qtscript5-dev
</code></pre></div></div>

<p>不过，问题并没有就此结束。
在执行<code class="language-plaintext highlighter-rouge">configure</code>脚本配置<code class="language-plaintext highlighter-rouge">nuSolve</code>的编译环境时，脚本试图寻找<code class="language-plaintext highlighter-rouge">libQt5Script.so</code>文件，
但是在我的对应目录下却没有该文件。
因此，我建立了一个软链接，运行的指令如下：</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd /usr/lib/x86_64-linux-gnu

sudo ln -s libQt5Script.so.5.15.2 libQt5Script.so
</code></pre></div></div>

<p>最后，需要注意的是，如果你使用<code class="language-plaintext highlighter-rouge">conda</code>，在编译<code class="language-plaintext highlighter-rouge">nuSolve</code>时需要关闭<code class="language-plaintext highlighter-rouge">conda</code>环境，
否则，配置脚本会定位到<code class="language-plaintext highlighter-rouge">conda</code>目录下的Qt5函数库。
在我的测试中，使用<code class="language-plaintext highlighter-rouge">conda</code>的Qt5函数库时，编译无法顺利完成。</p>]]></content><author><name>Neo</name></author><category term="VLBI" /><category term="software" /><summary type="html"><![CDATA[昨天尝试在Ubuntu 21.10服务器上安装nuSolve, 结果遇到了与Qt5库函数的编译问题，在这里记录一下解决办法。 桌面版也许没有此类问题。]]></summary></entry><entry><title type="html">Ubuntu 21.10 上安装 Calc/Solve</title><link href="https://liuniu.fun/blogs/install_solve.html" rel="alternate" type="text/html" title="Ubuntu 21.10 上安装 Calc/Solve" /><published>2022-02-06T00:00:00+08:00</published><updated>2022-02-06T00:00:00+08:00</updated><id>https://liuniu.fun/blogs/install_calc_solve</id><content type="html" xml:base="https://liuniu.fun/blogs/install_solve.html"><![CDATA[<p>本文介绍的是 <code class="language-plaintext highlighter-rouge">Calc/Solve</code> 的安装方法。我的测试环境如下：</p>

<ul>
  <li>操作系统：Ubuntu 21.10，GNU/Linux 5.13.0-28-generic x86_64；</li>
  <li><code class="language-plaintext highlighter-rouge">gcc</code> 和 <code class="language-plaintext highlighter-rouge">gfortran</code>：gcc version 11.2.0，Ubuntu 11.2.0-7ubuntu2；</li>
  <li>Intel Fortran 编译器：<code class="language-plaintext highlighter-rouge">ifort</code> 2021.5.0；</li>
  <li><code class="language-plaintext highlighter-rouge">Calc/Solve</code> 发行版本：<code class="language-plaintext highlighter-rouge">SOLVE_mk5_20200123</code>。</li>
</ul>

<p>本文或许也适用于其他操作系统和软件版本，但并不保证所有命令都能直接复用。本文提及的代码可以在我的 <a href="https://github.com/Niu-Liu/calc-solve-install">GitHub 仓库</a> 中找到。</p>

<blockquote>
  <p>注：本文记录的是我在 Ubuntu 21.10、Intel oneAPI 2022 和 <code class="language-plaintext highlighter-rouge">SOLVE_mk5_20200123</code> 环境下安装 <code class="language-plaintext highlighter-rouge">Calc/Solve</code> 的过程。Ubuntu 21.10 已停止支持，因此本文更适合作为旧环境下的复现实验记录，而不是当前系统上的通用安装教程。如果在 Ubuntu 22.04、Ubuntu 24.04 或更新版本上安装 <code class="language-plaintext highlighter-rouge">Calc/Solve</code>，建议参考本文中的思路，而不是逐条照搬命令。</p>
</blockquote>

<!-- more -->

<p><code class="language-plaintext highlighter-rouge">Calc/Solve</code> 软件包是美国国家航空航天局 NASA 下属的 Goddard Space Flight Center 在 20 世纪 80 年代左右开发的一套 VLBI 数据分析和处理工具。它历史悠久，但维护得比较有限，因此在较新的 Linux 系统上安装时可能会出现各种问题。</p>

<p>近期我又重新在 Ubuntu 21.10 系统上测试了一下软件安装过程，并在这里记录下全过程，供同行参考。在软件安装问题上，我曾与上海天文台肖威讨论过，我的安装方法也部分参考了他的笔记，在这里向肖威表示感谢。</p>

<h2 id="1-前期准备">1. 前期准备</h2>

<p>将软件包 <code class="language-plaintext highlighter-rouge">SOLVE_mk5_20200123.tar</code> 解压。<code class="language-plaintext highlighter-rouge">Calc/Solve</code> 的安装说明在压缩包的 <code class="language-plaintext highlighter-rouge">help.zip</code> 中，对应的文件主要有三个：</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">INSTALL</code>；</li>
  <li><code class="language-plaintext highlighter-rouge">INSTALL.hpu</code>；</li>
  <li><code class="language-plaintext highlighter-rouge">INSTALL.linux</code>。</li>
</ul>

<p>由于我使用的是 Linux 系统，所以主要参考 <code class="language-plaintext highlighter-rouge">INSTALL</code> 和 <code class="language-plaintext highlighter-rouge">INSTALL.linux</code>。大致顺序是：先依照 <code class="language-plaintext highlighter-rouge">INSTALL.linux</code> 安装一些必要的函数库和工具，之后再依照 <code class="language-plaintext highlighter-rouge">INSTALL</code> 中的说明安装 <code class="language-plaintext highlighter-rouge">Calc/Solve</code>。</p>

<p><strong>需要注意的是</strong>：这些安装说明文档是早年写的，适用于以前的版本。现在编译 <code class="language-plaintext highlighter-rouge">Calc/Solve</code> 不一定需要严格遵照这些说明文档。例如，ATLAS 库函数并不是必须的，我的安装过程就没有这一步。</p>

<h3 id="11-安装库依赖">1.1 安装库依赖</h3>

<p><code class="language-plaintext highlighter-rouge">Calc/Solve</code> 软件包需要在支持 32 位的环境下编译安装，因此首先要添加 32 位库函数支持：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>dpkg <span class="nt">--add-architecture</span> i386
<span class="nb">sudo </span>apt update
</code></pre></div></div>

<p>同时确保 <code class="language-plaintext highlighter-rouge">gfortran</code> 支持 32 位：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>gfortran-multilib
</code></pre></div></div>

<p>其他需要的软件和库函数包括：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt <span class="nb">install </span>libpng-dev libpng-dev:i386 libjpeg-dev:i386

<span class="c"># Curses</span>
<span class="nb">sudo </span>apt-get <span class="nb">install </span>libncurses5 libncurses5:i386 libncurses5-dev libncurses5-dev:i386

<span class="c"># X11</span>
<span class="nb">sudo </span>apt-get <span class="nb">install </span>libx11-6 libx11-dev libx11-6:i386 libx11-dev:i386

<span class="c"># RPC</span>
<span class="nb">sudo </span>apt <span class="nb">install </span>libntirpc-dev

<span class="c"># Mail client</span>
<span class="nb">sudo </span>apt <span class="nb">install </span>mailutils
</code></pre></div></div>

<p>这里列举的可能并非所有需要的库依赖。例如 <code class="language-plaintext highlighter-rouge">zlib</code> 等库函数，我的系统中可能之前已经安装过了。如果在后续编译过程中出现报错，可以根据报错信息继续补充对应依赖。</p>

<h3 id="12-安装-intel-fortran-编译器">1.2 安装 Intel Fortran 编译器</h3>

<p>现在的 Intel Fortran 编译器被包含在 Intel oneAPI HPC Toolkit 中，因此安装这个工具包即可。具体方法可以参考 Intel 官方文档。</p>

<p>我当时使用的是 Intel oneAPI 2022，对应的安装方式如下：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Use wget to fetch the Intel repository public key</span>
<span class="nb">cd</span> /tmp
wget https://apt.repos.intel.com/intel-gpg-keys/GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB

<span class="c"># Add the public key</span>
<span class="nb">sudo </span>apt-key add GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB

<span class="c"># Remove the downloaded public key</span>
<span class="nb">rm </span>GPG-PUB-KEY-INTEL-SW-PRODUCTS.PUB

<span class="c"># Configure the APT client to use Intel's repository</span>
<span class="nb">sudo </span>add-apt-repository <span class="s2">"deb https://apt.repos.intel.com/oneapi all main"</span>

<span class="nb">sudo </span>apt update

<span class="c"># Install the desired packages</span>
<span class="nb">sudo </span>apt <span class="nb">install </span>intel-basekit
<span class="nb">sudo </span>apt <span class="nb">install </span>intel-basekit-32bit
<span class="nb">sudo </span>apt <span class="nb">install </span>intel-hpckit
<span class="nb">sudo </span>apt <span class="nb">install </span>intel-hpckit-32bit
</code></pre></div></div>

<p>需要说明的是，<code class="language-plaintext highlighter-rouge">apt-key</code> 是当时常见的写法，但在较新的 Ubuntu 系统中已经不再推荐。如果使用较新的系统或较新的 oneAPI 版本，请优先参考 Intel 官方文档中的最新安装方式。</p>

<p>安装完成之后，需要在 <code class="language-plaintext highlighter-rouge">.bashrc</code> 或 <code class="language-plaintext highlighter-rouge">.cshrc</code> 中添加相应设置。以 bash 为例，可以加入：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">MK5_FC</span><span class="o">=</span>/opt/intel/oneapi/compiler/2022.0.2/linux/bin/ia32/ifort
<span class="nb">source</span> /opt/intel/oneapi/setvars.sh ia32
</code></pre></div></div>

<p>值得一提的是，这一版本的 <code class="language-plaintext highlighter-rouge">icc</code> 号称与 <code class="language-plaintext highlighter-rouge">gcc</code> 兼容：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>icc <span class="nt">-v</span>
</code></pre></div></div>

<p>输出示例为：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>icc version 2021.5.0 (gcc version 11.2.0 compatibility)
</code></pre></div></div>

<p>这对 <code class="language-plaintext highlighter-rouge">Calc/Solve</code> 的编译应该是一个好消息。</p>

<h3 id="13-安装-netcdf">1.3 安装 NetCDF</h3>

<p>编译 <code class="language-plaintext highlighter-rouge">Calc/Solve</code> 需要 NetCDF 的 32 位库函数支持。由于 Ubuntu 21.10 仓库里的 NetCDF 库函数只有 64 位，因此需要自行编译安装。</p>

<p>我选用的编译器为 Intel 编译器。类似的安装教程可以在很多地方找到，例如：</p>

<ul>
  <li><a href="https://blog.csdn.net/weixin_41890971/article/details/86763859">CESM 优化——Intel 编译器编译安装 NetCDF 库（C+Fortran）</a>；</li>
  <li><a href="https://www.cnblogs.com/gabriel-sun/p/12128386.html">服务器安装 netcdf 说明</a>；</li>
  <li><a href="https://blog.csdn.net/qq_39970131/article/details/116861365">Ubuntu 20.04 下 netcdf 库的安装（ifort 编译器）</a>。</li>
</ul>

<p>下面给出我自己的安装方案。我的安装目录为 <code class="language-plaintext highlighter-rouge">/opt32</code>，源码包下载目录为 <code class="language-plaintext highlighter-rouge">/opt32/incoming</code>，解压目录为 <code class="language-plaintext highlighter-rouge">/opt32/dist</code>。</p>

<p>需要编译安装的软件包及版本如下：</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">hdf-4.2.15</code>；</li>
  <li><code class="language-plaintext highlighter-rouge">hdf5-1.12.0</code>；</li>
  <li><code class="language-plaintext highlighter-rouge">netcdf-c-4.8.1</code>；</li>
  <li><code class="language-plaintext highlighter-rouge">netcdf-fortran-4.5.4</code>。</li>
</ul>

<p>编译之前需要进行一些全局环境配置。在 <code class="language-plaintext highlighter-rouge">.bashrc</code> 或 <code class="language-plaintext highlighter-rouge">.cshrc</code> 中添加下列语句即可。以 bash 为例：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Intel compiler</span>
<span class="nb">source</span> /opt/intel/oneapi/setvars.sh ia32

<span class="nb">export </span><span class="nv">CC</span><span class="o">=</span>icc
<span class="nb">export </span><span class="nv">CXX</span><span class="o">=</span>icpc
<span class="nb">export </span><span class="nv">FC</span><span class="o">=</span>ifort
<span class="nb">export </span><span class="nv">F90</span><span class="o">=</span>ifort
<span class="nb">export </span><span class="nv">F77</span><span class="o">=</span>ifort
</code></pre></div></div>

<h4 id="131-hdf4-函数库">1.3.1 HDF4 函数库</h4>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">PREFIX</span><span class="o">=</span>/opt32
<span class="nv">ver</span><span class="o">=</span>4.2.15

<span class="nb">cd</span> <span class="k">${</span><span class="nv">PREFIX</span><span class="k">}</span>/incoming
wget https://support.hdfgroup.org/ftp/HDF/releases/HDF<span class="k">${</span><span class="nv">ver</span><span class="k">}</span>/src/hdf-<span class="k">${</span><span class="nv">ver</span><span class="k">}</span>.tar.gz

<span class="c"># Unzip</span>
<span class="nb">cd</span> <span class="k">${</span><span class="nv">PREFIX</span><span class="k">}</span>/dist
<span class="nb">tar</span> <span class="nt">-xf</span> <span class="k">${</span><span class="nv">PREFIX</span><span class="k">}</span>/incoming/hdf-<span class="k">${</span><span class="nv">ver</span><span class="k">}</span>.tar.gz
<span class="nb">cd </span>hdf-<span class="k">${</span><span class="nv">ver</span><span class="k">}</span>

<span class="k">if</span> <span class="o">[</span> <span class="o">!</span> <span class="nt">-d</span> build <span class="o">]</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">mkdir </span>build
<span class="k">fi
</span><span class="nb">cd </span>build

<span class="nv">CFLAGS</span><span class="o">=</span><span class="s1">'-m32 -I/usr/include/tirpc'</span> <span class="se">\</span>
    <span class="nv">CPPFLAGS</span><span class="o">=</span><span class="s1">'-m32 -I/usr/include/tirpc'</span> <span class="se">\</span>
    <span class="nv">CXXFLAGS</span><span class="o">=</span><span class="s1">'-m32'</span> <span class="se">\</span>
    <span class="nv">FFLAGS</span><span class="o">=</span><span class="s1">'-m32'</span> <span class="se">\</span>
    <span class="nv">LDFLAGS</span><span class="o">=</span><span class="s1">'-ltirpc -L/opt32/lib -L/usr/lib/i386-linux-gnu'</span> <span class="se">\</span>
    ../configure <span class="nt">--prefix</span><span class="o">=</span>/opt32 <span class="nt">--disable-netcdf</span> <span class="nt">--enable-fortran</span>

<span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">echo</span> <span class="s2">"Configuration failed."</span>
    <span class="nb">exit
</span><span class="k">fi

</span>make
<span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">echo</span> <span class="s2">"Make failed."</span>
    <span class="nb">exit
</span><span class="k">fi

</span>make <span class="nb">install
</span><span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">echo</span> <span class="s2">"Make install failed."</span>
    <span class="nb">exit
</span><span class="k">fi

</span>make distclean
<span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">echo</span> <span class="s2">"Make clean failed."</span>
    <span class="nb">exit
</span><span class="k">fi</span>
</code></pre></div></div>

<h4 id="132-hdf5-函数库">1.3.2 HDF5 函数库</h4>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">PREFIX</span><span class="o">=</span>/opt32

<span class="c"># Download the source code to ${PREFIX}/incoming first.</span>

<span class="nb">cd</span> <span class="k">${</span><span class="nv">PREFIX</span><span class="k">}</span>/dist
<span class="nb">tar</span> <span class="nt">-xzf</span> <span class="k">${</span><span class="nv">PREFIX</span><span class="k">}</span>/incoming/hdf5-1_12_0.tar.gz

<span class="nb">cd</span> <span class="k">${</span><span class="nv">PREFIX</span><span class="k">}</span>/dist/hdf5-1.12.0
make distclean

<span class="k">if</span> <span class="o">[</span> <span class="o">!</span> <span class="nt">-d</span> build <span class="o">]</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">mkdir </span>build
<span class="k">fi
</span><span class="nb">cd </span>build

<span class="nv">CFLAGS</span><span class="o">=</span><span class="s1">'-m32 -I/opt32/include'</span> <span class="se">\</span>
    <span class="nv">CPPFLAGS</span><span class="o">=</span><span class="s1">'-m32 -I/opt32/include'</span> <span class="se">\</span>
    <span class="nv">FFLAGS</span><span class="o">=</span><span class="s1">'-m32'</span> <span class="se">\</span>
    <span class="nv">LDFLAGS</span><span class="o">=</span><span class="s1">'-L/opt32/lib -L/usr/lib/i386-linux-gnu'</span> <span class="se">\</span>
    ../configure <span class="nt">--prefix</span><span class="o">=</span>/opt32 <span class="nt">--enable-fortran</span> <span class="nt">--enable-hl</span>

<span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">echo</span> <span class="s2">"Configuration failed."</span>
    <span class="nb">exit
</span><span class="k">fi

</span>make
<span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">echo</span> <span class="s2">"Make failed."</span>
    <span class="nb">exit
</span><span class="k">fi

</span>make <span class="nb">install
</span><span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">echo</span> <span class="s2">"Make install failed."</span>
    <span class="nb">exit
</span><span class="k">fi

</span>make distclean
<span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">echo</span> <span class="s2">"Make clean failed."</span>
    <span class="nb">exit
</span><span class="k">fi</span>
</code></pre></div></div>

<h4 id="133-netcdf-函数库">1.3.3 NetCDF 函数库</h4>

<p>下面的脚本分别编译安装 NetCDF-C 和 NetCDF-Fortran：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>install_c<span class="o">()</span> <span class="o">{</span>
    <span class="nb">echo</span> <span class="s2">"Install netcdf-C"</span>
    <span class="nb">cd </span>netcdf-c-<span class="k">${</span><span class="nv">CVER</span><span class="k">}</span>
    make distclean

    <span class="k">if</span> <span class="o">[</span> <span class="nt">-d</span> build <span class="o">]</span><span class="p">;</span> <span class="k">then
        </span><span class="nb">rm</span> <span class="nt">-r</span> build
    <span class="k">fi

    </span><span class="nb">mkdir </span>build <span class="o">&amp;&amp;</span> <span class="nb">cd </span>build

    <span class="nv">CFLAGS</span><span class="o">=</span><span class="s2">"-m32"</span> <span class="se">\</span>
        <span class="nv">LDFLAGS</span><span class="o">=</span><span class="s1">'-L/opt32/lib -L/usr/lib/i386-linux-gnu'</span> <span class="se">\</span>
        <span class="nv">CPPFLAGS</span><span class="o">=</span><span class="s1">'-m32 -I/opt32/include'</span> <span class="se">\</span>
        ../configure <span class="nt">--prefix</span><span class="o">=</span>/opt32 <span class="nt">--with-hdf4</span><span class="o">=</span>/opt32

    <span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
        </span><span class="nb">echo</span> <span class="s2">"NETCDF-C Configuration failed."</span>
        <span class="nb">exit
    </span><span class="k">fi

    </span>make
    <span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
        </span><span class="nb">echo</span> <span class="s2">"NETCDF-C Make failed."</span>
        <span class="nb">exit
    </span><span class="k">fi

    </span>make <span class="nb">install
    </span><span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
        </span><span class="nb">echo</span> <span class="s2">"NETCDF-C Make install failed."</span>
        <span class="nb">exit
    </span><span class="k">fi

    </span>make distclean
    <span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
        </span><span class="nb">echo</span> <span class="s2">"NETCDF-C Make clean failed."</span>
        <span class="nb">exit
    </span><span class="k">fi</span>
<span class="o">}</span>

install_f<span class="o">()</span> <span class="o">{</span>
    <span class="nb">echo</span> <span class="s2">"Install netcdf-Fortran"</span>
    <span class="nb">cd </span>netcdf-fortran-<span class="k">${</span><span class="nv">FVER</span><span class="k">}</span>

    <span class="k">if</span> <span class="o">[</span> <span class="nt">-d</span> build <span class="o">]</span><span class="p">;</span> <span class="k">then
        </span><span class="nb">rm</span> <span class="nt">-r</span> build
    <span class="k">fi

    </span><span class="nb">mkdir </span>build <span class="o">&amp;&amp;</span> <span class="nb">cd </span>build

    <span class="nv">CFLAGS</span><span class="o">=</span><span class="s1">'-m32'</span> <span class="se">\</span>
        <span class="nv">CPPFLAGS</span><span class="o">=</span><span class="s1">'-m32 -I/opt32/include'</span> <span class="se">\</span>
        <span class="nv">FCFLAGS</span><span class="o">=</span><span class="s1">'-m32'</span> <span class="se">\</span>
        <span class="nv">FFLAGS</span><span class="o">=</span><span class="s1">'-m32'</span> <span class="se">\</span>
        <span class="nv">LDFLAGS</span><span class="o">=</span><span class="s1">'-L/opt32/lib -L/usr/lib/i386-linux-gnu'</span> <span class="se">\</span>
        ../configure <span class="nt">--prefix</span><span class="o">=</span>/opt32 <span class="nt">--disable-fortran-type-check</span>

    <span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
        </span><span class="nb">echo</span> <span class="s2">"NETCDF-Fortran Configuration failed."</span>
        <span class="nb">exit
    </span><span class="k">fi

    </span>make
    <span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
        </span><span class="nb">echo</span> <span class="s2">"NETCDF-Fortran Make failed."</span>
        <span class="nb">exit
    </span><span class="k">fi

    </span>make <span class="nb">install
    </span><span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
        </span><span class="nb">echo</span> <span class="s2">"NETCDF-Fortran Make install failed."</span>
        <span class="nb">exit
    </span><span class="k">fi

    </span>make distclean
    <span class="k">if</span> <span class="o">((</span> <span class="nv">$?</span> <span class="o">))</span><span class="p">;</span> <span class="k">then
        </span><span class="nb">echo</span> <span class="s2">"NETCDF-Fortran Make clean failed."</span>
        <span class="nb">exit
    </span><span class="k">fi</span>
<span class="o">}</span>

<span class="nb">export </span><span class="nv">LD_LIBRARY_PATH</span><span class="o">=</span><span class="s2">"/opt32/lib:/usr/lib/i386-linux-gnu:</span><span class="k">${</span><span class="nv">LD_LIBRARY_PATH</span><span class="k">}</span><span class="s2">"</span>

<span class="nv">PREFIX</span><span class="o">=</span>/opt32
<span class="nv">CVER</span><span class="o">=</span>4.8.1
<span class="nv">FVER</span><span class="o">=</span>4.5.4

<span class="nb">cd</span> <span class="k">${</span><span class="nv">PREFIX</span><span class="k">}</span>/incoming
wget https://downloads.unidata.ucar.edu/netcdf-c/<span class="k">${</span><span class="nv">CVER</span><span class="k">}</span>/src/netcdf-c-<span class="k">${</span><span class="nv">CVER</span><span class="k">}</span>.tar.gz
wget https://downloads.unidata.ucar.edu/netcdf-fortran/<span class="k">${</span><span class="nv">FVER</span><span class="k">}</span>/netcdf-fortran-<span class="k">${</span><span class="nv">FVER</span><span class="k">}</span>.tar.gz

<span class="c"># Unzip</span>
<span class="nb">cd</span> <span class="k">${</span><span class="nv">PREFIX</span><span class="k">}</span>/dist
<span class="nb">tar</span> <span class="nt">-xvzf</span> <span class="k">${</span><span class="nv">PREFIX</span><span class="k">}</span>/incoming/netcdf-c-<span class="k">${</span><span class="nv">CVER</span><span class="k">}</span>.tar.gz
<span class="nb">tar</span> <span class="nt">-xvzf</span> <span class="k">${</span><span class="nv">PREFIX</span><span class="k">}</span>/incoming/netcdf-fortran-<span class="k">${</span><span class="nv">FVER</span><span class="k">}</span>.tar.gz

install_c
install_f
</code></pre></div></div>

<p>如果一切顺利，至此，前期准备工作已经完成。</p>

<h2 id="2-开始编译">2. 开始编译</h2>

<p>编译安装可以参照安装说明文档进行。这里我只列举一些需要特别注意的地方。</p>

<h3 id="21-设置编译器和路径">2.1 设置编译器和路径</h3>

<p>前面在安装 NetCDF 时，我将编译器全部设置为 Intel 编译器。在编译 <code class="language-plaintext highlighter-rouge">Calc/Solve</code> 时，需要将那些全局编译器设置注释掉，并加入下面的设置：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">MK5_FC</span><span class="o">=</span>/opt/intel/oneapi/compiler/2022.0.2/linux/bin/ia32/ifort
<span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span><span class="s2">".:</span><span class="k">${</span><span class="nv">PATH</span><span class="k">}</span><span class="s2">"</span>
</code></pre></div></div>

<p>然后关闭终端并重新打开，准备编译。</p>

<h3 id="22-函数库的配置">2.2 函数库的配置</h3>

<p>对于一些没有安装在标准库路径下的库函数，例如我安装在 <code class="language-plaintext highlighter-rouge">/opt32</code> 下的 NetCDF，需要通过配置文件告诉编译器到哪里寻找需要的库文件和头文件。这些配置文件均在 <code class="language-plaintext highlighter-rouge">${MK5_ROOT}/local</code> 路径下。</p>

<p>我在安装时添加了两个配置文件，分别为 <code class="language-plaintext highlighter-rouge">lib.lcl</code> 和 <code class="language-plaintext highlighter-rouge">inc.lcl</code>。</p>

<p><code class="language-plaintext highlighter-rouge">lib.lcl</code> 的内容如下：</p>

<pre><code class="language-csh">#!/bin/csh
# ************************************************************************
# -                                                                      *
# -   Local Customization for Solve libraries.                           *
# -                                                                      *
# -  ### 07-OCT-2003   lib.lcl     v1.0 (c)  L. Petrov  07-OCT-2003 ###  *
# -                                                                      *
# ************************************************************************

setenv SOLVE_LIB_X11 "/lib/i386-linux-gnu/libX11.so"

setenv SOLVE_LIB_BLAS "-L /opt/intel/oneapi/mkl/2022.0.2/lib/ia32/ -lmkl_intel -lmkl_sequential -lpthread -lmkl_core"

setenv SOLVE_LIB_CURSES "/lib/i386-linux-gnu/libcurses.so"

setenv SOLVE_LIB_NETCDF "-L /opt32/lib/ -lnetcdf -lnetcdff"
</code></pre>

<p>从文件模板的头部信息来看，这是 Leonid 在 2003 年写的。现在的安装包中已经找不到相应文件了。</p>

<p><code class="language-plaintext highlighter-rouge">inc.lcl</code> 的内容如下：</p>

<pre><code class="language-csh">setenv SOLVE_NETCDF_INCLUDE "/opt32/include"
</code></pre>

<h3 id="23-pgplot522-编译问题">2.3 <code class="language-plaintext highlighter-rouge">pgplot522</code> 编译问题</h3>

<p>在编译 <code class="language-plaintext highlighter-rouge">pgplot522</code> 时，可能会出现以下错误：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ld: libpgplot.a(grdate.o): in function `grdate':
grdate.c:(.text+0xfe): undefined reference to `__stack_chk_fail_local'
ld: libpgplot.a(grtermio.o): in function `groter':
grtermio.c:(.text+0xa4): undefined reference to `__stack_chk_fail_local'
ld: libpgplot.a(grtermio.o): in function `grpter':
grtermio.c:(.text+0x2b0): undefined reference to `__stack_chk_fail_local'
ld: libpgplot.a(xwdriv_plus.o): in function `xw_bound_cursor':
xwdriv_plus.c:(.text+0x456): undefined reference to `__stack_chk_fail_local'
ld: libpgplot.a(xwdriv_plus.o): in function `xw_locate_cursor':
xwdriv_plus.c:(.text+0xf09): undefined reference to `__stack_chk_fail_local'
</code></pre></div></div>

<p>参考<a href="https://stackoverflow.com/questions/4492799/undefined-reference-to-stack-chk-fail">网友的解答</a>，可以修改 <code class="language-plaintext highlighter-rouge">${MK5_ROOT}/support/mk5_f95_intel_gcc.conf</code> 文件。</p>

<p>将第 60 行由：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">CFLAGC</span><span class="o">=</span><span class="s2">"-m32 -Wall -fPIC -O"</span>
</code></pre></div></div>

<p>改为：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">CFLAGC</span><span class="o">=</span><span class="s2">"-m32 -Wall -fPIC -O -fno-stack-protector"</span>
</code></pre></div></div>

<p>此后，编译过程就可以顺利结束。</p>

<h2 id="3-安装之后的配置">3. 安装之后的配置</h2>

<p>在编译安装完成之后，需要继续配置 Solve。具体步骤可以参考 <a href="http://astrogeo.org/psolve/doc/solve_guide_01.html">pSolve 的文档</a>。这个文档在 <code class="language-plaintext highlighter-rouge">${MK5_ROOT}/help</code> 路径下应该也可以找到。</p>

<p>到这里，<code class="language-plaintext highlighter-rouge">Calc/Solve</code> 的初步安装就结束了。但这并不意味着软件就一定能顺利运行。后续我会继续更新一些我所发现的代码问题和运行问题。</p>

<p>由于本文依赖的系统和编译器版本都比较旧，如果在 Ubuntu 22.04、Ubuntu 24.04 或更新版本上安装 <code class="language-plaintext highlighter-rouge">Calc/Solve</code>，建议优先参考本文中的思路，而不是逐条照搬命令。</p>]]></content><author><name>Niu Liu</name></author><category term="VLBI" /><category term="software" /><summary type="html"><![CDATA[本文介绍的是 Calc/Solve 的安装方法。我的测试环境如下： 操作系统：Ubuntu 21.10，GNU/Linux 5.13.0-28-generic x86_64； gcc 和 gfortran：gcc version 11.2.0，Ubuntu 11.2.0-7ubuntu2； Intel Fortran 编译器：ifort 2021.5.0； Calc/Solve 发行版本：SOLVE_mk5_20200123。 本文或许也适用于其他操作系统和软件版本，但并不保证所有命令都能直接复用。本文提及的代码可以在我的 GitHub 仓库 中找到。 注：本文记录的是我在 Ubuntu 21.10、Intel oneAPI 2022 和 SOLVE_mk5_20200123 环境下安装 Calc/Solve 的过程。Ubuntu 21.10 已停止支持，因此本文更适合作为旧环境下的复现实验记录，而不是当前系统上的通用安装教程。如果在 Ubuntu 22.04、Ubuntu 24.04 或更新版本上安装 Calc/Solve，建议参考本文中的思路，而不是逐条照搬命令。]]></summary></entry><entry><title type="html">SGDASS的安装教程</title><link href="https://liuniu.fun/blogs/install_sgdass.html" rel="alternate" type="text/html" title="SGDASS的安装教程" /><published>2022-02-01T00:00:00+08:00</published><updated>2026-07-07T00:00:00+08:00</updated><id>https://liuniu.fun/blogs/install_sgdass</id><content type="html" xml:base="https://liuniu.fun/blogs/install_sgdass.html"><![CDATA[<p><a href="http://astrogeo.org/sgdass/">SGDASS</a> 全称为 Space Geodesy Data Analysis Software System，是 Leonid Petrov 博士开发的空间测地数据分析软件套装。SGDASS 主要用于甚长基线干涉测量（Very Long Baseline Interferometry, VLBI）数据分析，也可以作为空间测地数据处理流程的一部分。</p>

<p>Leonid 已经写了非常详细的<a href="http://astrogeo.org/sgdass/">官方安装说明</a>，并提供了自动化安装脚本 <code class="language-plaintext highlighter-rouge">sgdass_install.py</code>。自动化安装脚本的目的显然是尽量简化安装过程，减少用户手动处理依赖和配置的麻烦。本文试图在官方说明的基础上进行简化和补充，以方便国内同行安装 SGDASS。</p>

<blockquote>
  <p>注：本文最初写于 2022 年，后根据 2023 年及之后的安装经验进行过更新。SGDASS 版本更新较快，安装前请务必以官方页面、安装包中的 <code class="language-plaintext highlighter-rouge">INSTALL</code> 文件以及官方安装说明为准。本文主要记录我在 Linux 环境下的安装流程和注意事项。</p>
</blockquote>

<!-- more -->

<h2 id="说明">说明</h2>

<p>官方安装说明中提到：</p>

<blockquote>
  <p>SGDASS fully supports Linux and MACOS.</p>
</blockquote>

<p>不过，根据我的实际经验，SGDASS 在 macOS 上的安装并不一定顺利。我和 Leonid 曾在 macOS Sonoma 14.1.1 上进行过尝试，但没有成功完成安装。</p>

<p>因此，从可复现性和节省时间的角度出发，我个人更建议在 Linux 环境下安装和使用 SGDASS。至于 macOS，除非有明确需求，否则不建议作为首选安装环境。</p>

<p>下面的安装说明主要面向 Linux 系统。</p>

<h2 id="1-安装库函数依赖">1. 安装库函数依赖</h2>

<p>SGDASS 需要的依赖大体可以分为两类。</p>

<p>第一类是通常需要由系统包管理器安装的依赖，因此一般需要 root 权限或 <code class="language-plaintext highlighter-rouge">sudo</code> 权限。例如：</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">tcsh</code>，并且 <code class="language-plaintext highlighter-rouge">csh</code> 应该是指向 <code class="language-plaintext highlighter-rouge">tcsh</code> 的符号链接；</li>
  <li>X11 相关头文件和工具；</li>
  <li><code class="language-plaintext highlighter-rouge">perl</code>；</li>
  <li><code class="language-plaintext highlighter-rouge">python3</code>，版本应为 3.4 或更高。</li>
</ul>

<p>第二类是可以由系统包管理器安装，也可以从源代码编译安装的依赖。例如：</p>

<ul>
  <li>PostScript 阅读器，例如 ImageMagick；</li>
  <li>GIF 阅读器，例如 ImageMagick；</li>
  <li><code class="language-plaintext highlighter-rouge">gcc</code>；</li>
  <li><code class="language-plaintext highlighter-rouge">g++</code>；</li>
  <li><code class="language-plaintext highlighter-rouge">gfortran</code>；</li>
  <li><code class="language-plaintext highlighter-rouge">CMake</code>。</li>
</ul>

<p>下面分别以 Fedora 和 Ubuntu 为例，给出安装这些软件包的命令。不同 Linux 发行版和版本中的软件包名称可能略有差异，因此以下命令仅作参考。若安装失败，应根据系统提示查找对应的软件包名称。</p>

<p>在 Fedora 上，可以参考：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>yum <span class="nb">install </span>tcsh gcc gcc-c++ gcc-gfortran perl libX11-devel libXp-devel libXt-devel xorg-x11-server-utils ImageMagick-devel
</code></pre></div></div>

<p>在 Ubuntu 22.04 LTS 上，可以参考：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>tcsh gcc gfortran cmake g++ libx11-dev libxt-dev x11-xserver-utils imagemagick autoconf m4 libtirpc-dev
</code></pre></div></div>

<p>此外，SGDASS 需要使用许多第三方开源软件包。这些软件包可能已经存在于 Linux 系统中，但并非所有系统自带版本都能直接与 SGDASS 协同工作，因为 SGDASS 对部分软件包的编译方式有特殊要求。因此，比较稳妥的做法是使用 SGDASS 提供的安装流程，对这些第三方软件包进行编译安装。</p>

<p>安装 SGDASS 需要较新的 <code class="language-plaintext highlighter-rouge">gcc</code> 和 <code class="language-plaintext highlighter-rouge">gfortran</code>，通常要求版本为 8.0.0 或更高。更低版本的编译器可能无法正常工作。SGDASS 提供了安装新版本 <code class="language-plaintext highlighter-rouge">gcc</code>、<code class="language-plaintext highlighter-rouge">g++</code> 和 <code class="language-plaintext highlighter-rouge">gfortran</code> 的方法，因此如果系统自带编译器版本较低，也可以按照官方流程重新编译安装这些编译器。</p>

<h2 id="2-安装前的准备">2. 安装前的准备</h2>

<p>首先需要创建相应的工作目录。SGDASS 使用固定的目录名称，而且这些目录通常位于根目录下。因此，需要直接创建这些目录，或者设置符号链接。</p>

<p>我更推荐第二种方式：先在自己的工作空间中创建 SGDASS 根目录，然后把根目录下需要的目录名软链接到实际工作目录。</p>

<p>首先设置 SGDASS 的根目录。请将下面的路径替换成你自己的安装位置：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">sgdass_home</span><span class="o">=</span><span class="s2">"/path/to/your/sgdass/home"</span>
</code></pre></div></div>

<p>然后运行以下脚本创建目录和符号链接。</p>

<p>需要特别注意：下面的脚本会在根目录下创建一系列符号链接，例如 <code class="language-plaintext highlighter-rouge">/apr</code>、<code class="language-plaintext highlighter-rouge">/opt64</code>、<code class="language-plaintext highlighter-rouge">/vlbi</code> 等。运行前请务必确认这些路径没有被系统或其他软件使用。如果某个路径已经存在且不是符号链接，脚本会停止运行，并要求你手动检查。</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">#!/usr/bin/env bash</span>

<span class="nb">set</span> <span class="nt">-euo</span> pipefail

<span class="nv">sgdass_home</span><span class="o">=</span><span class="s2">"/path/to/your/sgdass/home"</span>

<span class="k">if</span> <span class="o">[</span> <span class="nt">-z</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">"</span> <span class="o">]</span> <span class="o">||</span> <span class="o">[</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">"</span> <span class="o">=</span> <span class="s2">"/"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then
  </span><span class="nb">echo</span> <span class="s2">"Error: sgdass_home is empty or invalid."</span>
  <span class="nb">exit </span>1
<span class="k">fi

</span><span class="nb">dirs</span><span class="o">=(</span>
  <span class="s2">"apr"</span> <span class="s2">"auto"</span> <span class="s2">"cont"</span> <span class="s2">"dist"</span> <span class="s2">"images"</span> <span class="s2">"image_orig"</span> <span class="s2">"incoming"</span> <span class="s2">"l0"</span> <span class="s2">"l1a"</span>
  <span class="s2">"l1b"</span> <span class="s2">"l2"</span> <span class="s2">"l3"</span> <span class="s2">"logs"</span> <span class="s2">"opt64"</span> <span class="s2">"progs"</span> <span class="s2">"scr"</span> <span class="s2">"sde"</span> <span class="s2">"sol"</span> <span class="s2">"vlbi"</span> <span class="s2">"imls"</span>
<span class="o">)</span>

<span class="k">for </span><span class="nb">dir </span><span class="k">in</span> <span class="s2">"</span><span class="k">${</span><span class="nv">dirs</span><span class="p">[@]</span><span class="k">}</span><span class="s2">"</span><span class="p">;</span> <span class="k">do
  </span><span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/</span><span class="k">${</span><span class="nv">dir</span><span class="k">}</span><span class="s2">"</span>
  <span class="nb">chmod </span>775 <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/</span><span class="k">${</span><span class="nv">dir</span><span class="k">}</span><span class="s2">"</span>

  <span class="k">if</span> <span class="o">[</span> <span class="nt">-L</span> <span class="s2">"/</span><span class="k">${</span><span class="nv">dir</span><span class="k">}</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">sudo rm</span> <span class="s2">"/</span><span class="k">${</span><span class="nv">dir</span><span class="k">}</span><span class="s2">"</span>
  <span class="k">elif</span> <span class="o">[</span> <span class="nt">-e</span> <span class="s2">"/</span><span class="k">${</span><span class="nv">dir</span><span class="k">}</span><span class="s2">"</span> <span class="o">]</span><span class="p">;</span> <span class="k">then
    </span><span class="nb">echo</span> <span class="s2">"Error: /</span><span class="k">${</span><span class="nv">dir</span><span class="k">}</span><span class="s2"> already exists and is not a symbolic link."</span>
    <span class="nb">echo</span> <span class="s2">"Please check it manually before continuing."</span>
    <span class="nb">exit </span>1
  <span class="k">fi

  </span><span class="nb">sudo ln</span> <span class="nt">-s</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/</span><span class="k">${</span><span class="nv">dir</span><span class="k">}</span><span class="s2">"</span> <span class="s2">"/</span><span class="k">${</span><span class="nv">dir</span><span class="k">}</span><span class="s2">"</span>
<span class="k">done</span>
</code></pre></div></div>

<p>接下来继续创建 SGDASS 所需的子目录：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/apr/eop"</span>                 <span class="c"># apriori Earth orientation parameters</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/apr/eph"</span>                 <span class="c"># apriori ephemerides</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/apr/iono"</span>                <span class="c"># apriori ionosphere data</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/apr/load_bds"</span>            <span class="c"># apriori mass loading time series in bindisp format</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/apr/load_hps"</span>            <span class="c"># apriori mass loading harmonic variations</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/apr/psolve"</span>              <span class="c"># apriori files for pSolve</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/apr/sou"</span>                 <span class="c"># apriori source positions</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/apr/spd"</span>                 <span class="c"># apriori station path delays</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/apr/sta"</span>                 <span class="c"># apriori station positions</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/apr/temp"</span>                <span class="c"># apriori temporary files</span>

<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/l2/gvf"</span>                  <span class="c"># Level 2 VLBI data in GVF format</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/l2/vda"</span>                  <span class="c"># Level 2 VLBI data in vgosda format</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/l2/vdb"</span>                  <span class="c"># Level 2 VLBI data in vgosdb format</span>

<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/logs/sgdass"</span>             <span class="c"># logs from SGDASS installation</span>

<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/scr/pima"</span>                <span class="c"># PIMA related files created during processing</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/scr/psolve"</span>              <span class="c"># temporary files created by pSolve</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/scr/psolve/cgm_dir"</span>      <span class="c"># auxiliary combined global matrices created by pSolve</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/scr/psolve/tpd"</span>          <span class="c"># auxiliary path-delay files created by pSolve</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/scr/psolve/spool_dir"</span>    <span class="c"># listings of solutions generated by pSolve</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/scr/psolve/sub_matrices"</span> <span class="c"># auxiliary temporary files created by pSolve</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/scr/psolve/work_dir"</span>     <span class="c"># auxiliary files used by pSolve</span>

<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/sol/heo"</span>                 <span class="c"># High-frequency Earth orientation parameter VLBI solutions</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/sol/qua"</span>                 <span class="c"># Quarterly VLBI solutions</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/sol/rewei"</span>               <span class="c"># Reweighting VLBI solutions</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/sol/rfc"</span>                 <span class="c"># Astrometric VLBI solutions</span>

<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/vlbi/vtd_data"</span>           <span class="c"># data files for VTD</span>

<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/imls/oper_model"</span>         <span class="c"># IMLS operational models</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/imls/devel_model"</span>        <span class="c"># IMLS development models</span>
</code></pre></div></div>

<p>然后在 <a href="http://astrogeo.org/sgdass/">SGDASS 官方页面</a> 下载最新的软件包，并将其保存在 <code class="language-plaintext highlighter-rouge">${sgdass_home}/incoming</code> 目录下。以下命令中的版本号仅作示例，实际安装时请替换成官方页面显示的最新版本：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/incoming"</span>
wget http://astrogeo.org/data_archive/sgdass-YYYYMMDD.tar
</code></pre></div></div>

<p>例如，如果当前官方版本为 <code class="language-plaintext highlighter-rouge">sgdass-20260516.tar</code>，则命令为：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/incoming"</span>
wget http://astrogeo.org/data_archive/sgdass-20260516.tar
</code></pre></div></div>

<p>随后在 <code class="language-plaintext highlighter-rouge">${sgdass_home}/progs</code> 下解压：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/progs"</span>
<span class="nb">tar</span> <span class="nt">-xvf</span> ../incoming/sgdass-YYYYMMDD.tar
</code></pre></div></div>

<p>如果下载的是 <code class="language-plaintext highlighter-rouge">sgdass-20260516.tar</code>，则对应为：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">cd</span> <span class="s2">"</span><span class="k">${</span><span class="nv">sgdass_home</span><span class="k">}</span><span class="s2">/progs"</span>
<span class="nb">tar</span> <span class="nt">-xvf</span> ../incoming/sgdass-20260516.tar
</code></pre></div></div>

<p>软件包通常包括：</p>

<ul>
  <li>第三方软件的源代码；</li>
  <li>SGDASS 安装包；</li>
  <li>安装配置示例文件；</li>
  <li>官方安装说明文件。</li>
</ul>

<p>设置用户组权限：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">umask </span>002
</code></pre></div></div>

<p>如果使用 <code class="language-plaintext highlighter-rouge">tcsh</code>，可以在 <code class="language-plaintext highlighter-rouge">~/.cshrc</code> 中添加以下内容。如果没有该文件，可以新建：</p>

<pre><code class="language-tcsh">setenv LD_LIBRARY_PATH "/opt64/lib:/opt64/lib64:/usr/lib64:/usr/lib"
setenv PATH "/opt64/bin:/opt64/psolve/bin:${PATH}"
</code></pre>

<h2 id="3-安装编译器和-cmake">3. 安装编译器和 CMake</h2>

<p>编译器和 SGDASS 的安装建议在 <code class="language-plaintext highlighter-rouge">tcsh</code> 环境中进行。</p>

<p>可以使用下面的命令进入 <code class="language-plaintext highlighter-rouge">tcsh</code>：</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>tcsh
</code></pre></div></div>

<p>SGDASS 支持通过编译源代码的方式，将 <code class="language-plaintext highlighter-rouge">gcc</code>、<code class="language-plaintext highlighter-rouge">g++</code> 和 <code class="language-plaintext highlighter-rouge">gfortran</code> 安装在 <code class="language-plaintext highlighter-rouge">/opt64</code> 目录下。</p>

<p>进入 SGDASS 安装目录。下面路径中的版本号请根据实际下载的版本进行修改：</p>

<pre><code class="language-tcsh">cd ${sgdass_home}/progs/sgdass
</code></pre>

<p>复制 <code class="language-plaintext highlighter-rouge">gcc</code> 安装配置示例文件，并将新文件命名为 <code class="language-plaintext highlighter-rouge">gcc_linux.cnf</code>：</p>

<pre><code class="language-tcsh">cp example_gcc_linux.cnf gcc_linux.cnf
</code></pre>

<p>打开 <code class="language-plaintext highlighter-rouge">gcc_linux.cnf</code>，根据实际情况进行修改。通常情况下，不需要做太多修改，或者只需要更改 <code class="language-plaintext highlighter-rouge">num_proc</code> 变量的值。Leonid 在较新的配置文件中已经将其设为 <code class="language-plaintext highlighter-rouge">all</code>，因此可以根据机器情况决定是否保留默认设置。</p>

<p>运行以下命令安装编译器和相关工具：</p>

<pre><code class="language-tcsh">python3 sgdass_install.py -c gcc_linux.cnf build all
</code></pre>

<p>这一过程可能需要较长时间，具体取决于机器性能和网络情况。</p>

<h2 id="4-安装-sgdass">4. 安装 SGDASS</h2>

<p>SGDASS 的安装过程同样由配置文件控制。示例文件通常为 <code class="language-plaintext highlighter-rouge">example_sgdass_linux.cnf</code>。复制该文件：</p>

<pre><code class="language-tcsh">cp example_sgdass_linux.cnf sgdass_linux.cnf
</code></pre>

<p>然后打开 <code class="language-plaintext highlighter-rouge">sgdass_linux.cnf</code>，根据机器实际情况进行修改。</p>

<p>需要特别注意：配置文件中软件包的顺序很重要，不建议随意修改。</p>

<p>自动安装命令为：</p>

<pre><code class="language-tcsh">python3 sgdass_install.py -c sgdass_linux.cnf build all
python3 sgdass_install.py -c sgdass_linux.cnf postinstall all
</code></pre>

<p>如果机器上已经安装过 SGDASS，那么在执行安装指令之前，需要先关闭 SGDASS 相关的所有进程，尤其是 pSolve 相关进程。</p>

<p>整个过程可能需要相当长的时间，从几小时到几天不等，具体取决于机器性能、网络情况和需要编译的软件包数量。</p>

<h2 id="5-安装后的设置">5. 安装后的设置</h2>

<p>建议使用 <code class="language-plaintext highlighter-rouge">tcsh</code> 启动 SGDASS 中的程序。假设使用 <code class="language-plaintext highlighter-rouge">tcsh</code>，可以进行如下配置。</p>

<h3 id="51-配置-login">5.1 配置 <code class="language-plaintext highlighter-rouge">~/.login</code></h3>

<p>在 <code class="language-plaintext highlighter-rouge">~/.login</code> 中添加以下内容。如果没有该文件，可以新建：</p>

<pre><code class="language-tcsh">limit coredumpsize     0
limit stacksize        8000000
limit maxproc          16384
limit descriptors      2048
setenv GOMP_STACKSIZE  2000000
</code></pre>

<h3 id="52-配置-xdefaults">5.2 配置 <code class="language-plaintext highlighter-rouge">~/.Xdefaults</code></h3>

<p>在 <code class="language-plaintext highlighter-rouge">~/.Xdefaults</code> 中添加以下内容：</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pgxwin.Win.iconize:     True
pgxwin.Win.geometry: 1080x750+0+50
pgxwin.server.visible: True
pgxwin.Win.maxColors:   230
</code></pre></div></div>

<p>其中，第二行确定了 <code class="language-plaintext highlighter-rouge">DIAGI</code> 软件的窗口尺寸，可以根据实际显示器尺寸进行修改。</p>

<h3 id="53-配置-tcshrc">5.3 配置 <code class="language-plaintext highlighter-rouge">~/.tcshrc</code></h3>

<p>在 <code class="language-plaintext highlighter-rouge">~/.tcshrc</code> 中添加以下内容：</p>

<pre><code class="language-tcsh"># For SGDASS
setenv PGPLOT_DEV  "/XW"                      # default graphics device
setenv PGPLOT_XW_MARGIN "1.0"                 # display margins
setenv PGPLOT_XSIZE_MM 400.0                  # width of the PGPLOT window

setenv LD_LIBRARY_PATH /opt64/lib:/opt64/lib64:/usr/lib:/usr/lib64
setenv PATH "/opt64/bin:/opt64/psolve/bin:${PATH}"
setenv PSOLVE_SAVE_DIR "/opt64/share/psolve"

xrdb -merge ~/.Xdefaults
</code></pre>

<p>保存配置文件后，重新打开终端，或重新加载相应配置文件。</p>

<h2 id="6-可能遇到的问题">6. 可能遇到的问题</h2>

<p>SGDASS 的安装过程比较复杂，涉及编译器、系统库、X11、PGPLOT、pSolve 以及多个第三方软件包。因此，在安装过程中可能会遇到其他问题。</p>

<p>我在另一篇文章“<a href="sgdass_installation_notes.html">安装 SGDASS 可能遇到的问题及解决方案</a>”中对部分问题进行了总结，欢迎参考。</p>

<p>最后再次提醒：SGDASS 更新较快，不同版本的依赖、配置文件和安装流程可能会有所差异。实际安装时，请优先参考官方页面、安装包中的 <code class="language-plaintext highlighter-rouge">INSTALL</code> 文件和最新安装说明。</p>]]></content><author><name>Neo</name></author><category term="VLBI" /><category term="software" /><summary type="html"><![CDATA[SGDASS 全称为 Space Geodesy Data Analysis Software System，是 Leonid Petrov 博士开发的空间测地数据分析软件套装。SGDASS 主要用于甚长基线干涉测量（Very Long Baseline Interferometry, VLBI）数据分析，也可以作为空间测地数据处理流程的一部分。 Leonid 已经写了非常详细的官方安装说明，并提供了自动化安装脚本 sgdass_install.py。自动化安装脚本的目的显然是尽量简化安装过程，减少用户手动处理依赖和配置的麻烦。本文试图在官方说明的基础上进行简化和补充，以方便国内同行安装 SGDASS。 注：本文最初写于 2022 年，后根据 2023 年及之后的安装经验进行过更新。SGDASS 版本更新较快，安装前请务必以官方页面、安装包中的 INSTALL 文件以及官方安装说明为准。本文主要记录我在 Linux 环境下的安装流程和注意事项。]]></summary></entry><entry><title type="html">利用 GitHub Pages 搭建个人主页的全过程</title><link href="https://liuniu.fun/blogs/create_blog_with_github_pages.html" rel="alternate" type="text/html" title="利用 GitHub Pages 搭建个人主页的全过程" /><published>2022-01-31T00:00:00+08:00</published><updated>2022-01-31T00:00:00+08:00</updated><id>https://liuniu.fun/blogs/create_blog_with_github_pages</id><content type="html" xml:base="https://liuniu.fun/blogs/create_blog_with_github_pages.html"><![CDATA[<blockquote>
  <p>注：本文写于 2022 年，主要记录本站最初搭建时的折腾过程。网站结构后来经过多次调整，文中的部分路径和代码写法已经按照当前版本略作更新。</p>
</blockquote>

<p>这是我的个人主页搭建完成之后的第一篇博文。整个搭建过程花了四天时间，所以我想记录一下其中的过程，包括我的需求、具体实现方式，以及遇到的问题和解决方法。</p>

<p>需要声明的是，这并不是一篇严格意义上的教程，而是对我自己瞎折腾过程的记录，仅作自娱自乐之用。关于更系统的搭建教程，我推荐这篇文章：《<a href="https://lemonchann.github.io/create_blog_with_github_pages/">可能是最全面的 GitHub Pages 搭建个人博客教程</a>》。实际上，我也借鉴了这位作者的模板。</p>

<p>我主要参考了以下几个模板：</p>

<ul>
  <li><a href="https://github.com/academicpages/academicpages.github.io">academicpages</a>，适合学术展示；</li>
  <li><a href="https://github.com/lemonchann/lemonchann.github.io">lemonchann</a>，非常简洁的博客模板；</li>
  <li><a href="https://github.com/nrandecker/particle">particle</a> 和 <a href="https://github.com/tzuehlke/jekyll-uno-timeline/">jekyll-uno-timeline</a>，我很喜欢它们的首页风格。</li>
</ul>

<p>由于个人需求比较混杂，最终我的个人主页就成了一个融合三类模板的“缝合怪”。如果你也在寻找合适的模板，可以参考上面的几个项目。</p>

<!-- more -->

<p>接下来进入正式内容。</p>

<h2 id="起因">起因</h2>

<p>一直以来，我都有搭建个人学术主页的想法。尽管学校也提供了个人信息页，但可定制化的内容很少，而且对上传文件的支持也不够方便。因此，我想利用 GitHub Pages 自己搭建一个个人主页。</p>

<p>此外，Leonid Petrov 最近推出了一个新的 VLBI 数据处理软件包：<a href="http://astrogeo.org/sgdass/">Space Geodesy Data Analysis Software System</a>。安装这个软件包花了我不少时间，将来学习使用它肯定也需要更多时间，所以我想写一些博文记录相关过程。正好今年过年要在老家待一周，于是我就利用这段时间开始摸索个人主页的搭建。</p>

<p>综合上述情况，我对个人主页的主要需求是：</p>

<ul>
  <li>适合学术展示；</li>
  <li>支持博客功能。</li>
</ul>

<p>如果仅考虑以上需求，<a href="https://github.com/academicpages/academicpages.github.io">academicpages</a> 就是一个非常合适的模板。在搜索模板的时候，我发现 <a href="https://github.com/lemonchann/lemonchann.github.io">lemonchann</a> 的风格也很喜欢，简约但功能比较完整。此外，<a href="https://github.com/nrandecker/particle">particle</a> 的首页背景很好看。</p>

<p>最终，我决定做一个“融合怪”：即 <code class="language-plaintext highlighter-rouge">particle</code> 的首页风格，加上 <code class="language-plaintext highlighter-rouge">lemonchann</code> 的博客配置，再加上 <code class="language-plaintext highlighter-rouge">academicpages</code> 的学术主页配置。这也借鉴了 <a href="https://github.com/tzuehlke/jekyll-uno-timeline/">jekyll-uno-timeline</a> 的思路：这位作者的主页中，点击 “Projects” 时，在侧边栏显示的是 GitHub 项目的时间轴；点击 “Blogs” 之后，则切换到另一种完全不同的风格。</p>

<p>思路确定之后，接下来就是具体实现了。</p>

<h2 id="前期准备">前期准备</h2>

<p>如果完全使用某一个模板，通常只需要修改根目录下的 <code class="language-plaintext highlighter-rouge">_config.yml</code>。但是，如果要实现自己的定制，我觉得下列信息还是需要简单了解一下：</p>

<ul>
  <li>Node.js、npm、gem 和 yarn 的区别与基本使用；</li>
  <li>Jekyll 常用目录配置；</li>
  <li>模板的目录结构，例如 <code class="language-plaintext highlighter-rouge">css</code> 和 <code class="language-plaintext highlighter-rouge">scss</code> 对应的目录，以及样式文件的生成逻辑。</li>
</ul>

<h2 id="模板混用">模板混用</h2>

<p>我采取的是“加法原则”，即选择一个最简单的模板作为基础，然后往里面依次添加其他功能。我从 <code class="language-plaintext highlighter-rouge">particle</code> 开始，将 <code class="language-plaintext highlighter-rouge">particle</code> 的所有目录和文件复制到我的主页文件夹下。</p>

<h3 id="particle-模板的修改修改首页图标"><code class="language-plaintext highlighter-rouge">particle</code> 模板的修改：修改首页图标</h3>

<p><code class="language-plaintext highlighter-rouge">particle</code> 的本地预览需要通过 <code class="language-plaintext highlighter-rouge">gulp</code> 命令实现，具体操作可以在 <code class="language-plaintext highlighter-rouge">gulpfile.js</code> 中查看。<code class="language-plaintext highlighter-rouge">particle</code> 的 <code class="language-plaintext highlighter-rouge">.scss</code> 文件放在 <code class="language-plaintext highlighter-rouge">src/styles/</code> 目录下，因此如果要修改页面样式，就需要修改这里面的文件。</p>

<p><code class="language-plaintext highlighter-rouge">particle</code> 首页原本有四个图标，分别是 Email、Twitter、Google Plus 和 GitHub。其中 Twitter 和 Google Plus 的图标我不需要，同时我希望新增一些学术相关的图标和链接。</p>

<p>这时，我注意到 <code class="language-plaintext highlighter-rouge">academicpages</code> 模板中提供了 ORCID、ADS 和 ResearchGate 的图标，这些图标非常适合添加到学术主页上。通过查找，我发现这些学术相关图标都由 <a href="https://jpswalsh.github.io/academicons/">Academicons</a> 提供。相关文件在 <code class="language-plaintext highlighter-rouge">academicpages</code> 模板的 <code class="language-plaintext highlighter-rouge">/assets/css/</code> 目录下，主要包括 <code class="language-plaintext highlighter-rouge">academicons.css</code> 和 <code class="language-plaintext highlighter-rouge">academicons.min.css</code>。</p>

<p>将这两个文件复制到我的 <code class="language-plaintext highlighter-rouge">/assets/css/</code> 目录下，然后在 <code class="language-plaintext highlighter-rouge">_includes/head.html</code> 中添加：</p>

<div class="language-liquid highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;link rel="stylesheet" href="/assets/css/academicons.min.css"&gt;
</code></pre></div></div>

<p>最终相关部分如下：</p>

<div class="language-liquid highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;link rel="stylesheet" href="/assets/css/academicons.min.css"&gt;
&lt;link rel="stylesheet" href="/assets/css/main.css"&gt;
</code></pre></div></div>

<p>此后，在 <code class="language-plaintext highlighter-rouge">_includes/header.html</code> 中删去 Twitter 和 Google Plus 图标，新增 ORCID、ADS 和 ResearchGate 图标。当前版本可以写成：</p>

<div class="language-liquid highlighter-rouge"><div class="highlight"><pre class="highlight"><code>&lt;div class="header-icons"&gt;
  
    &lt;a aria-label="Send email" target="_blank" href="mailto:niu.liu@nju.edu.cn"&gt;
      &lt;i class="icon fa fa-envelope" aria-hidden="true"&gt;&lt;/i&gt;
    &lt;/a&gt;
  

  
    &lt;a aria-label="My ORCID" target="_blank" href="https://orcid.org/0000-0003-2778-002X"&gt;
      &lt;i class="icon ai ai-orcid" aria-hidden="true"&gt;&lt;/i&gt;
    &lt;/a&gt;
  

  
    &lt;a aria-label="My ResearchGate" target="_blank" href="https://www.researchgate.net/profile/Niu-Liu?ev=hdr_xprf"&gt;
      &lt;i class="icon ai ai-researchgate" aria-hidden="true"&gt;&lt;/i&gt;
    &lt;/a&gt;
  

  
    &lt;a aria-label="My GitHub" target="_blank" href="https://github.com/Niu-Liu"&gt;
      &lt;i class="icon fa fa-github-alt" aria-hidden="true"&gt;&lt;/i&gt;
    &lt;/a&gt;
  

  
    &lt;a aria-label="Search me on ADS" target="_blank" href="https://ui.adsabs.harvard.edu/user/libraries/EWTz-0tVSn6LqIz7ZgLMgg"&gt;
      &lt;i class="icon ai ai-ads" aria-hidden="true"&gt;&lt;/i&gt;
    &lt;/a&gt;
  
&lt;/div&gt;
</code></pre></div></div>

<p>图标栏下方的导航栏修改相对容易，此处不再细说。此外，我也在 <code class="language-plaintext highlighter-rouge">#about</code> 和 <code class="language-plaintext highlighter-rouge">#projects</code> 两个部分进行了相应修改，用来添加个人简介和项目信息。</p>

<h3 id="引入-academicpages-模板的功能">引入 <code class="language-plaintext highlighter-rouge">academicpages</code> 模板的功能</h3>

<p><code class="language-plaintext highlighter-rouge">academicpages</code> 模板的页面样式配置文件主要放在 <code class="language-plaintext highlighter-rouge">_sass</code> 目录下，最终的 CSS 文件由 <code class="language-plaintext highlighter-rouge">/assets/css/main.scss</code> 生成。因此，我将这些 <code class="language-plaintext highlighter-rouge">_sass</code> 目录和 <code class="language-plaintext highlighter-rouge">/assets/css/main.scss</code> 复制到自己的项目中。</p>

<p>为了避免和原有首页的 <code class="language-plaintext highlighter-rouge">main.css</code> 冲突，需要将 <code class="language-plaintext highlighter-rouge">main.scss</code> 重命名，例如改成 <code class="language-plaintext highlighter-rouge">academicmain.scss</code>，对应生成的文件为 <code class="language-plaintext highlighter-rouge">academicmain.css</code>。</p>

<p><code class="language-plaintext highlighter-rouge">academicpages</code> 模板的页面模板主要放在 <code class="language-plaintext highlighter-rouge">_includes</code> 和 <code class="language-plaintext highlighter-rouge">_layouts</code> 目录下。复制到相应目录之后，也需要根据自己的项目结构进行重命名和调整。此时，还需要修改 <code class="language-plaintext highlighter-rouge">academicpages</code> 模板中的 <code class="language-plaintext highlighter-rouge">head.html</code>，让它加载新的 CSS 文件，而不是默认的 <code class="language-plaintext highlighter-rouge">main.css</code>。</p>

<p>在 <code class="language-plaintext highlighter-rouge">_config.yml</code> 中，需要引入 <code class="language-plaintext highlighter-rouge">academicpages</code> 模板的相关配置，并仔细检查同名变量是否发生冲突。</p>

<p>学术页面的内容则可以存放在 <code class="language-plaintext highlighter-rouge">_pages</code> 目录下。将需要的页面复制过来之后，再修改页面文件中的 <code class="language-plaintext highlighter-rouge">layout</code> 值即可。我忽略了其中与博客相关的文件，因为博客页面要另外定制。</p>

<h3 id="引入-lemonchann-模板的功能">引入 <code class="language-plaintext highlighter-rouge">lemonchann</code> 模板的功能</h3>

<p>这一步与上一步类似，不再赘述。需要注意的是，<code class="language-plaintext highlighter-rouge">lemonchann</code> 模板的目录设置与前两个模板不太一样。为了让站点结构更统一，我选择修改 <code class="language-plaintext highlighter-rouge">lemonchann</code> 模板文件中的目录信息，使其适应当前网站结构。</p>

<p>由于我的博客首页不是根目录，而是 <code class="language-plaintext highlighter-rouge">/blogs/</code>，因此还需要修改分页插件 <code class="language-plaintext highlighter-rouge">jekyll-paginate</code> 的配置。原来的设置是：</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">paginate_path</span><span class="pi">:</span> <span class="s2">"</span><span class="s">page:num"</span>
</code></pre></div></div>

<p>需要改为：</p>

<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">paginate_path</span><span class="pi">:</span> <span class="s2">"</span><span class="s">/blogs/page:num/"</span>
</code></pre></div></div>

<p>这样，分页插件就会在 <code class="language-plaintext highlighter-rouge">/blogs/</code> 目录下创建子目录。</p>

<p><code class="language-plaintext highlighter-rouge">lemonchann</code> 模板原本利用 <a href="https://github.com/gitalk/gitalk">Gitalk</a> 实现评论功能，但遗憾的是它不支持匿名评论。一位名叫 <a href="https://github.com/xingty">bigbyto</a> 的开发者写过一篇《<a href="https://wiyi.org/gitalk-anonymous-comment.html">给 Gitalk 添加匿名评论功能</a>》。于是，我参考了他的个人主页配置，尤其是其中的 <code class="language-plaintext highlighter-rouge">_includes/comments-providers/gitalk.html</code>，并对 <code class="language-plaintext highlighter-rouge">lemonchann</code> 模板中的 <code class="language-plaintext highlighter-rouge">_includes/gitalk.html</code> 做了相应修改。</p>

<p>此外，还需要自己部署后端来转发评论。这些内容都可以在 bigbyto 的仓库里找到，非常棒。</p>

<p>到了这一步，我的个人网页基本上就搭建好了。正巧赶上大年夜，希望新的一年里能多写博文，多发 paper 吧！</p>

<h2 id="致谢">致谢</h2>

<p>感谢 <a href="https://www.jekyll.com.cn/">Jekyll</a> 提供的技术支持，让我能够搭建这个博客。</p>

<p>感谢 <a href="https://github.com/academicpages/academicpages.github.io">academicpages</a>、<a href="https://github.com/lemonchann/lemonchann.github.io">lemonchann</a> 和 <a href="https://github.com/nrandecker/particle">particle</a> 提供的原始模板。本站是在这些模板的基础上进行二次开发而成的。</p>]]></content><author><name>Niu Liu</name></author><category term="website" /><summary type="html"><![CDATA[注：本文写于 2022 年，主要记录本站最初搭建时的折腾过程。网站结构后来经过多次调整，文中的部分路径和代码写法已经按照当前版本略作更新。 这是我的个人主页搭建完成之后的第一篇博文。整个搭建过程花了四天时间，所以我想记录一下其中的过程，包括我的需求、具体实现方式，以及遇到的问题和解决方法。 需要声明的是，这并不是一篇严格意义上的教程，而是对我自己瞎折腾过程的记录，仅作自娱自乐之用。关于更系统的搭建教程，我推荐这篇文章：《可能是最全面的 GitHub Pages 搭建个人博客教程》。实际上，我也借鉴了这位作者的模板。 我主要参考了以下几个模板： academicpages，适合学术展示； lemonchann，非常简洁的博客模板； particle 和 jekyll-uno-timeline，我很喜欢它们的首页风格。 由于个人需求比较混杂，最终我的个人主页就成了一个融合三类模板的“缝合怪”。如果你也在寻找合适的模板，可以参考上面的几个项目。]]></summary></entry></feed>