localtime.F90
快速理解
它做什么: 独立命令行程序,把 3D/4D 变量沿时间维插值到指定本地时刻,输出 input_LT.nc。
基本过程: 按经度把 GCM 时间轴转为本地时 → 相邻本地时样本按 lt_hour/24 写入。
关键结果: <输入基名>_LT.nc,各经度对齐到同一组本地时,便于昼夜对比。
路径
LMDZ.MARS\util\localtime.F90
所属目录/模块
util
文件定位
localtime.F90 是 LMD Mars GCM 输出的本地时重排工具。它读取 diagfi.nc、stats.nc、concat.nc 一类 NetCDF 文件,把用户选择的 3D (longitude,latitude,Time) 或 4D (longitude,latitude,altitude,Time) 变量沿时间维插值到若干指定本地时刻,并输出 input_LT.nc。
程序不改变水平网格或垂直坐标。核心变换是把每个经度上的 GCM 时间轴转换为本地时坐标:
lt_gcm(t) = time(t) + 0.5 * longitude / 180
即经度 360 度对应 1 sol,相邻本地时样本按 lt_hour/24 写入输出 Time。
定义的符号
| 符号 | 类型 | 行号 | 作用 |
|---|---|---|---|
localtime |
program | 1 | 主程序:读取输入、变量列表和目标本地时,创建 *_LT.nc 并对变量做时间插值。 |
initiate |
internal subroutine | 752 | 创建输出 NetCDF 文件,定义坐标、Time、GCM_layers 和可选 controle。 |
init2 |
internal subroutine | 956 | 复制可选 aps/bps hybrid 坐标和 phisinit 到输出文件。 |
def_var |
internal subroutine | 1132 | 定义输出变量并写入 long_name、units 属性。 |
missing_value |
internal subroutine | 1181 | 把输入变量的 valid_range 和 missing_value 属性写入输出变量。 |
interpolf |
internal subroutine | 1259 | 一维线性插值;若目标点不在已知坐标范围内或邻点缺测,则返回 missing。 |
依赖
| 依赖 | 用途 |
|---|---|
include "netcdf.inc" |
使用旧式 NetCDF Fortran NF_* 接口。 |
调用的关键例程
| 被调用例程 | 所在位置 | 作用 |
|---|---|---|
NF_OPEN / NF_CLOSE |
NetCDF 库 | 打开输入文件、关闭输入和输出文件。 |
NF_INQ_NVARS / NF_INQ_VARNAME / NF_INQ_VARNDIMS |
NetCDF 库 | 枚举变量、按变量名过滤坐标和静态字段、确认 3D/4D 变量。 |
NF_INQ_DIMID / NF_INQ_VARID / NF_INQ_DIMLEN |
NetCDF 库 | 读取坐标维度,兼容 latitude/lat、longitude/lon、Time/time_counter。 |
NF_GET_VAR_REAL / NF_PUT_VARA_REAL |
NetCDF 库 | 读取输入变量、写入插值后变量和输出时间轴。 |
NF_GET_ATT_TEXT / NF_GET_ATT_REAL / NF_PUT_ATT_* |
NetCDF 库 | 复制 long_name/title、units、missing_value、valid_range 等属性。 |
initiate / init2 / def_var / missing_value / interpolf |
本文件 | 输出文件初始化、辅助字段复制、属性写入和线性插值。 |
输入
| 输入 | 来源 | 类型/维度 | 单位 | 含义 |
|---|---|---|---|---|
| 输入文件名 | stdin / localtime.def |
NetCDF 文件名 | - | diagfi.nc、stats.nc、concat.nc 等。 |
| 变量列表 | stdin / localtime.def |
all 或逐行变量名,空行结束 |
- | 要重排到固定本地时的变量;3D 或 4D 才会处理。 |
latitude / lat |
输入 NetCDF | 1D | degrees_north | 纬度坐标。 |
longitude / lon |
输入 NetCDF | 1D | degrees_east | 经度坐标,用于本地时换算。 |
altitude |
输入 NetCDF | 1D | 输入属性 | 4D 变量垂直坐标,属性会复制。 |
Time / time_counter |
输入 NetCDF | 1D | sol 类时间 | 输入时间轴;若属性说明为 Solar longitude,程序停止。 |
GCM_layers |
输入 NetCDF | 维度 | - | 可选;存在时用于 aps/bps 长度,否则等于 altlen。 |
controle |
输入 NetCDF | 1D | - | 可选控制数组;存在时复制到输出。 |
aps/bps |
输入 NetCDF | GCM_layers |
- | 可选 hybrid 中层坐标;存在时复制到输出。 |
phisinit |
输入 NetCDF | (longitude,latitude) |
- | 可选地表位势;存在时复制到输出。 |
| 目标本地时列表 | stdin / localtime.def |
nhour + nhour 个数值 |
hour | 要输出的本地时刻,注释要求 0<t<24。 |
输出
| 输出 | 去向 | 类型/维度 | 单位 | 含义 |
|---|---|---|---|---|
input_LT.nc |
磁盘 NetCDF | 文件 | - | 输入文件名去掉 .nc 后追加 _LT.nc。 |
latitude / longitude / altitude |
输出 NetCDF | 1D | 输入或固定属性 | 原坐标复制。 |
Time |
输出 NetCDF | unlimited | stats 时为小时,否则为 sol + local hour/24 | 目标本地时组合后的输出时间轴。 |
GCM_layers / aps / bps / phisinit |
输出 NetCDF | 可选 | - | 从输入文件复制的辅助坐标和地形字段。 |
| 用户选择变量 | 输出 NetCDF | 3D 或 4D | 输入 units |
插值到指定本地时后的变量。 |
副作用
- 使用
NF_CLOBBER和NF_64BIT_OFFSET创建输出,同名_LT.nc会被覆盖。 - 标准输入顺序严格依赖
localtime.def:文件名、变量列表、空行、目标本地时数量、目标本地时列表。 - 所选变量整块读入内存,再整块写出;大文件会占用较高内存。
- 缺少必要坐标、输入时间轴是 Solar longitude、NetCDF 读写失败时会
stop。
核心逻辑
- 读输入文件与变量列表:先枚举所有变量,排除
Time/controle/latitude/longitude/altitude/aps/bps/ap/bp/soildepth/cu/cv/aire/phisinit等 16 个不处理字段;用户可输入all或逐行变量名。 - 生成输出名:
filename=file(1:len_trim(file)-3)//"_LT.nc"。 - 读取坐标和兼容名称:
- 纬度维度/变量可用
latitude或lat。 - 经度维度/变量可用
longitude或lon。 - 时间维度/变量可用
Time或time_counter。 altitude是必需字段,属性long_name/units/positive会复制。
- 纬度维度/变量可用
- 拒绝 Ls 时间轴:若
Time的long_name或title包含Solar,程序停止,因为本地时插值要求 sol 时间轴。 - 构造输出时间轴:
- 若输入
timelen==12、time(1)==2、time(12)==24,识别为stats文件,把输入时间从小时除以 24 映射到 0-1 sol,输出Time写为目标小时。 - 否则按
nsol=int(time(last))-int(time(first)),对每个 sol 和每个目标小时生成lt_out = int(time(1))+k-1+lt_hour/24。 - 若只有 1 个 sol,追加一个周期性时间点参与插值。
- 若输入
- 创建输出文件并复制辅助字段:
initiate写坐标和Time;init2复制可选aps/bps/phisinit。 - 逐变量插值:
- 只处理维度数不少于 3 的变量;
ndim==3按(lon,lat,time),ndim==4按(lon,lat,alt,time)。 - 对每个经度构造
lt_gcm=time+0.5*lon/180。 - 若目标本地时超出当前经度的输入本地时范围,则用前一天或后一天修正
lt_outc。 - 对每个
(lon,lat)或(lon,lat,alt)时间序列调用interpolf。
- 只处理维度数不少于 3 的变量;
- 写变量和属性:输出变量保留输入的
long_name或title、units;若输入有missing_value,则调用missing_value写valid_range和missing_value。
伪代码
read input file name
open input and list processable variables
read selected variable names
read lon, lat, alt, Time and optional controle/GCM_layers
reject Time axis if it is Solar longitude
read target local hours
if stats-like file:
convert input hours to fractions of one sol
output Time = requested hours
else:
build output Time = sol start + requested hour/24
create infile_LT.nc and copy coords
copy aps/bps and phisinit if present
for each selected 3D/4D variable:
read full variable
for each longitude:
lt_gcm = time + 0.5*lon/180
wrap target times by +/- 1 sol if needed
interpolate each lat or lat-alt time series with interpolf
write interpolated variable and missing/valid_range attrs
参与的主题流程
| 主题 | 参与方式 |
|---|---|
| util 后处理链 | 常接在 concatnc 后,把多 sol 输出重排到固定本地时,便于日变化比较。 |
| 观测比较链 | 与 simu_MCS、extract 类工具类似,把 GCM 输出转换到观测或分析所需的时间采样。 |
复现要点
- 输入时间轴必须是 sol 时间,不可先用
concatnc的 Ls 时间轴模式替换为 Solar longitude。 - 目标本地时以小时输入;
localtime.def示例中先列变量tsurf、ps,空行后输入2、2、14。 - 非
stats文件的nsol由int(time(last))-int(time(first))得到;若时间覆盖不足或首尾不是预期 sol 边界,输出时刻数会受影响。 - 对 3D/4D 变量以外的变量会跳过或不适合处理。
- 插值遇到
missing_value邻点时结果保持 missing;如果输入没有missing_value属性,missing变量没有显式初始化,复现时应留意该路径。
待确认
all分支按变量编号Nnotprocessed+1:nbvarfile推定可处理变量,但notprocessed数量只是命中的排除项数量,不保证这些变量在文件变量表中连续排在最前;在变量顺序不同的 NetCDF 文件中可能选入不该处理的字段。- 若输入没有
missing_value属性,missing的值未显式初始化;但interpolf仍用该值判断缺测,需确认编译器/运行时实际行为。 Time输出属性固定为years since 0000-00-0 00:00:00,但非 stats 分支写入的是 sol 加小时分数,stats 分支写入的是小时值;单位语义需确认。- 读取
altitude的long_name失败时,源码转而从timevar读取title到long_name,疑似变量名写错。
复现风险
_LT.nc会覆盖同名文件。- 变量整块读写,内存随
lon*lat*alt*time增长。 - 输入经度若不符合模型常规经度定义,本地时换算
0.5*lon/180的物理含义需检查。 - 缺少
aps/bps或phisinit不会阻止主变量输出,但输出辅助坐标会不完整。
相关页面
- util/index.md - util 后处理工具总览。
- concatnc.md - 常见上游时间拼接工具。
- extract.md - 点值/廓线抽取工具。
- simu_MCS.md - MCS 观测模拟工具。