经过多天的思考,终于决定把看pride代码的心得写在博客里面了,有很多不太懂的地方也请大家一起探讨。
pirde_pppar.sh是pride软件的核心执行脚本,其自动的对数据进行处理和解算。
使用方式:
pride_pppar config_template YYYYMMDD YYYYMMDD y/n
其中,config_template是配置文件;第一个YYYYMMDD是处理数据的起始时间;第二个YYYYMMDD是处理数据的结束时间;最后y/n是是否固定模糊度。
vim pride_pppar.sh
打开pride_pppar.sh第一个函数就是该脚本的主程序:
main()
{
CheckCmdArgs "$@" || exit 1
CheckExecutables || exit 1
local ctrl_file="$1"
local ymd_start=(${2:0:4} ${2:4:2} ${2:6:2})
local ymd_end=(${3:0:4} ${3:4:2} ${3:6:2})
local AR="${4:0:1}"
ctrl_file=$(readlink -f "$ctrl_file") # convert to absolute path
# Output processing infomation
echo -e "$MSGINF Processing date range: ${ymd_start[*]} <==> ${ymd_end[*]}"
echo -e "$MSGINF Control file: ${ctrl_file}"
echo -e "$MSGINF AR switch: ${AR}"
# Processing day-by-day
readonly local mjd_start=$(ymd2mjd ${ymd_start[*]})
readonly local mjd_end=$(ymd2mjd ${ymd_end[*]})
local work_dir=$(pwd) ydoy
for mjd in $(seq $mjd_start $mjd_end)
do
cd "${work_dir}"
ydoy=($(mjd2ydoy ${mjd}))
mkdir -p ./${ydoy[0]}/${ydoy[1]}
cd ./${ydoy[0]}/${ydoy[1]}
if [ $? -eq 0 ]; then
ProcessSingleDay $mjd "$ctrl_file" ${AR} || echo -e "$MSGWAR ${ydoy[*]} processing failed"
else
echo -e "$MSGERR no such directory: ${work_dir}/$year/$doy"
echo -e "$MSGWAR skip processing: $year $doy"
fi
done
}
主程序前两行检查分别调用CheckArgs
和CheckExecutables
函数检查了pride_pppar 后面跟的参数的个数是否满足要求以及是否包含pride执行所需的一些执行程序,例如lsq
、get_args
、arsig
等等,这些执行程序都是pride软件自带的可执行程序,当然还会检查一些其他linux脚本处理程序,如wget
、readlink
。
然后就是一系列的基本操作,如将pride_pppar后面参数读入并赋值给本地变量;将配置文件转换为绝对路径;输出处理过程的信息等。
然后在起始时间和结束时间之间按天进行循环处理。在处理的时候会创建一个新的二重文件夹,以year/ydoy
的形式将处理所需文件、结果文件输出到对应的ydoy文件夹中。调用的函数为ProcessSingleDay
ProcessSingleDay
的内容如下:
ProcessSingleDay() { # purpose: process data of single day
# usage : ProcessSingleDay mjd ctrl_file AR(y/n)
local mjd=$1
local ctrl_file="$2"
local AR=$3
local ydoy=($(mjd2ydoy $mjd))
local year=${ydoy[0]}
local doy=${ydoy[1]}
local ymd=($(ydoy2ymd ${ydoy[*]}))
local mon=${ymd[1]}
local day=${ymd[2]}
unset ydoy ymd
echo -e "$MSGSTA ProcessSingleDay $year $doy..."
# Copy a local ctrl_file
cp -f "$ctrl_file" . || return 1
ctrl_file=$(basename "$ctrl_file")
# Create ctrl_file for current day
sed -i -e "/^Session time/s/-YYYY-/$year/g" \
-e "/^Session time/s/-MM-/$mon/g" \
-e "/^Session time/s/-DD-/$day/g" "$ctrl_file"
sed -i "/Rinex directory/s/-YEAR-/$year/g; s/-DOY-/$doy/g" "$ctrl_file"
# Prepare products & tables
local table_dir=$(get_ctrl "$ctrl_file" "Table directory")
local product_dir=$(get_ctrl "$ctrl_file" "Sp3 directory")
CopyTables "$table_dir" $mjd || return 1
PrepareProducts $mjd "$product_dir" ${ctrl_file} ${AR}
if [ $? -ne 0 ]; then
echo -e "$MSGERR PrepareProducts failed"
return 1
fi
# Download rinexnav file
local rinex_dir=$(get_ctrl "$ctrl_file" "Rinex directory")
local rinexnav="brdc${doy}0.${year:2:2}n"
local urlnav="ftp://igs.gnsswhu.cn/pub/gps/data/daily/${year}/$doy/${year:2:2}n/${rinexnav}.Z"
if [ ! -f "${rinex_dir}/${rinexnav}" ]; then
echo -e "$MSGSTA Downloading ${rinexnav}..."
WgetDownload "$urlnav"
if [ $? -eq 0 ]; then
uncompress -f ${rinexnav}.Z && mv ${rinexnav} ${rinex_dir}
[ -f ${rinex_dir}/${rinexnav} ] && echo -e "$MSGSTA Downloading ${rinexnav} done" || return 1
else
echo -e "$MSGERR download rinexnav failed: ${rinex_dir}/${rinexnav}"
return 1
fi
fi
sites=($(awk '/^ [0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z][0-9a-zA-Z] [KS]/ {print $1}' "$ctrl_file"))
[ ${#sites[@]} -eq 0 ] && echo -e "$MSGWAR ${year} ${doy}: no site to be processed" && return 1
for site in ${sites[*]}
do
ProcessSingleSite "$site" $year $doy "${ctrl_file}" $AR
if [ $? -ne 0 ]; then
echo -e "$MSGWAR ProcessSingleDay: skip processing $year $doy $site"
local tp types=(kin pos rck ztd htg amb res stt con)
for tp in ${types[*]}
do
rm -f ${tp}_${year}${doy}
done
fi
done
rm -f ${ctrl_file}
echo -e "$MSGSTA ProcessSingleDay $year $doy done"
}
该函数是内嵌在pride_pppar.sh中的处理单天GPS数据的函数。处理流程如下:
config_template
)PrepareProducts
准备该天处理所需的产品,如clk、fcb、dcb、sp3等,若没有,就从pride默认的网站下载。WgetDownload
函数从默认的网站下载。ProcessSingleSite
函数处理单站ProcessSingleSite
函数的处理流程如下:
该文件是pride_pppar的配置文件,包括PPP处理策略以及解算测站等等信息。其内容非常关键。
Interval = 30
#Rinex数据的处理间隔
Session time = -YYYY- -MM- -DD- 00 00 00 86360
# -YYYY- RINEX数据的年份, -MM- 和 –DD- 代表月和天。 实际处理的时候 –YYYY-, -MM- and –DD- 可以不用更改,‘pride_pppar’可以自动识别并自动填写, 下面的 ‘-YEAR-‘, ‘-DOY-’ 也是这样。
Rinex directory = /home/username/path-to-data/-YEAR-/-DOY-/
# RIinex文件夹的绝对路径,其中的username和path-to-data需要自行更改
Sp3 directory = /home/username/path-to-product/product/
# SP3文件的绝对路径,同上更改
Table directory = /home/username/path-to-table/table/
# Table文件夹的绝对路径
Remove bias = YES
# 是否使用fcb移除相位偏差,倘若是LAMBDA方法则不需要
ZTD model = PWC:60
# 天顶对流层延迟模型,采用分段常数,60:1小时
HTG model = PWC:720
# 对流层水平梯度:分段常数
Ambiguity fixing = FIX
# 模糊度固定与否
Common observing = 600
# 最小共同观测时间,用于模糊度解算时检验有效时间是否大于此
Cutoff elevation =n 15
# 模糊度固定的截止高度角
Widelane decision = 0.20 0.15 1000.
# 锥函数的阈值偏差(=0.4 in Dong和Bock;/ 锥形函数的阈值σ(=0.33 in Dong和Bock;/ 判定函数的错误率
Narrowlane decision = 0.15 0.15 1000.
# 同上
Critical search = 2 4 1.8 3.0
# 最大删除模糊度/最小保留模糊度/卡方检验统计量/比值试验临界值
## Satellite list
+GPS satellites
*PN
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
-GPS satellite
#可以通过在卫星号前面加‘#’来排除该卫星
# Station list
+Station used
*NAME TP MAP CLKm EV ZTDm PoDm HTGm PoDm RAGm PHSc PoXEm PoYNm PoZHm
algo S GMF 9000 7 0.20 .020 .005 .002 3.00 .006 10.00 10.00 10.00
zimm S GMF 9000 7 0.20 .020 .005 .002 3.00 .006 10.00 10.00 10.00
-Station used
# 可以自行添加测站,按照上面‘*’后面的格式
#TP:【K/S】指代动态或者静态模式
# MAP:对流层投影函数(如:GMF,VM1,NMF)
# CLKm: lsq中的初始接收机钟经度/m
# EV: 截至高度角/度
# ZTDm: 先验对流层延迟模型经度/m
# PoDm:分段天顶对流层延迟参数的푚/√h过程噪声
# HTGm: 以米为单位的先验水平对流层梯度值精度
#PoDm: 分段天顶水平对流层梯度参数的푚/√h过程噪声
# RAGm: lsq中伪距观测值的噪声/m
# PHSc: lsq中相位观测值的噪声/周
#PoXE PoYN PoZH : 初始坐标(XYZ/ENU)的先验经度/m
config_template
文件到工作目录,并修改其中的部分内容,必须修改的内容:观测值绝对路径、tables文件夹绝对路径,处理测站。leap.sec
文件和jpleph_de04
(此文件有效期到2019年12月31日)。lib/rdsp3.f90
中第71行为:if (line(1:2).ne.'#c'.and.line(1:2).ne.'#d') cycle
pride_pppar config_template YYYYMMDD YYYYMMDD y/n
即可