如何使用 nco 或 cdo 找到 netcdf 文件中第一个正项的 time/date?
how to find the time/date of the first positive entry in a netcdf file using nco or cdo?
我有一个时间序列值,我想找到数据序列变为正时第一个时间步长的时间或日期。我知道我可以将它读入 python、R 或 Fortran 脚本来执行此操作,但我想知道我是否可以从 BASH 中的命令行执行此操作,也许使用 nco 或 cdo?
我想用
cdo gec,0.0 in.nc out.nc
制作面具,但这对我帮助不大。我需要以某种方式根据数据符号拆分文件,然后我可以简单地使用
获取日期
cdo showdate
通过管道传输到 awk。
这里有一个 link 的小示例文件:
http://clima-dods.ictp.it/Users/tompkins/se/trmm_per10_pc0_year2000_nc2.nc
有什么建议吗?
我绞尽脑汁想不出有 NCO 的灵丹妙药。
我为 ncap2 提出了以下代码片段。
(循环在 ncap2 中未优化)
运行 片段使用命令
ncap2 -v -O -S sign.nco trmm_per10_pc0_year2000_nc2.nc foo.nc out.nc
/****************** sign.nco***********************************/
lon_sz=$lon.size;
lat_sz=$lat.size;
time_sz=$time.size;
*precip_prev=precip(0,0,0);
*precip_cur=2.0;
for(*idx=0;idx<time_sz;idx++)
{
for(*jdx=0;jdx<lat_sz;jdx++)
{
for(*kdx=0;kdx<lon_sz;kdx++)
{
precip_cur= precip(idx,jdx,kdx);
if( precip_cur > 0.0 && precip_prev<0.0)
print(time(idx));
precip_prev=precip_cur;
}
}
}
/***************************************************************/
编辑后的答案:
使用已添加到 CDO v1.8.0 及更高版本 (https://code.zmaw.de/projects/cdo/embedded/index.html#x1-3300002.8.1) 的新 timcumsum 函数,现在可以为网格化字段完成此任务:
cdo gec,0 precip.nc mask.nc # positive entries are 1, negative are zero
cdo timcumsum mask.nc maskcum.nc # sum the mask in the time direction
# invert the mask so that you have 1 at start, but then zero from 1st +ve val
cdo lec,0.5 maskcum.nc maskinv.nc
# sum this new mask, and add 1, result is timestep when first positive value occurs:
cdo addc,1 -timcumsum maskinc.nc stepfirstpos.nc
我认为这个函数可以在一条线上完成所有工作
cdo addc,1 -timcumsum -lec,0.5 -timcumsum -gec,0 precip.nc stepfirstpos.nc
原始答案:
我花了一年时间,但我想出了一种方法,结合 NCO 和 CDO 来处理单个点文件而不是网格化字段:
#!/bin/bash
# code to find date of first positive file entry
file=trmm_per10_pc0_year2000_nc2.nc
# set negative values to missing
cdo -s setrtomiss,-1.e36,0.0 $file set.nc
ntime=`cdo -s ntime set.nc` # number of steps in file
# loop over steps to find first positive value
for i in `seq 1 ${ntime}` ; do
# nco counts from step 0, cdo from 1
ncoi=`expr $i - 1`
# print out the value in step i
op=`ncks -d time,$ncoi -s "%16.10f\n" -H -C -v precip set.nc`
if [[ $op != "_" ]] ; then # not missing
# print the date of timestep i
cdo -s showdate -seltimestep,$i set.nc
rm -f set.nc
exit
fi
done
# no positive value found
rm -f set.nc
echo "All values in $file are negative"
我有一个时间序列值,我想找到数据序列变为正时第一个时间步长的时间或日期。我知道我可以将它读入 python、R 或 Fortran 脚本来执行此操作,但我想知道我是否可以从 BASH 中的命令行执行此操作,也许使用 nco 或 cdo?
我想用
cdo gec,0.0 in.nc out.nc
制作面具,但这对我帮助不大。我需要以某种方式根据数据符号拆分文件,然后我可以简单地使用
获取日期cdo showdate
通过管道传输到 awk。
这里有一个 link 的小示例文件:
http://clima-dods.ictp.it/Users/tompkins/se/trmm_per10_pc0_year2000_nc2.nc
有什么建议吗?
我绞尽脑汁想不出有 NCO 的灵丹妙药。
我为 ncap2 提出了以下代码片段。
(循环在 ncap2 中未优化)
运行 片段使用命令
ncap2 -v -O -S sign.nco trmm_per10_pc0_year2000_nc2.nc foo.nc out.nc
/****************** sign.nco***********************************/
lon_sz=$lon.size;
lat_sz=$lat.size;
time_sz=$time.size;
*precip_prev=precip(0,0,0);
*precip_cur=2.0;
for(*idx=0;idx<time_sz;idx++)
{
for(*jdx=0;jdx<lat_sz;jdx++)
{
for(*kdx=0;kdx<lon_sz;kdx++)
{
precip_cur= precip(idx,jdx,kdx);
if( precip_cur > 0.0 && precip_prev<0.0)
print(time(idx));
precip_prev=precip_cur;
}
}
}
/***************************************************************/
编辑后的答案:
使用已添加到 CDO v1.8.0 及更高版本 (https://code.zmaw.de/projects/cdo/embedded/index.html#x1-3300002.8.1) 的新 timcumsum 函数,现在可以为网格化字段完成此任务:
cdo gec,0 precip.nc mask.nc # positive entries are 1, negative are zero
cdo timcumsum mask.nc maskcum.nc # sum the mask in the time direction
# invert the mask so that you have 1 at start, but then zero from 1st +ve val
cdo lec,0.5 maskcum.nc maskinv.nc
# sum this new mask, and add 1, result is timestep when first positive value occurs:
cdo addc,1 -timcumsum maskinc.nc stepfirstpos.nc
我认为这个函数可以在一条线上完成所有工作
cdo addc,1 -timcumsum -lec,0.5 -timcumsum -gec,0 precip.nc stepfirstpos.nc
原始答案:
我花了一年时间,但我想出了一种方法,结合 NCO 和 CDO 来处理单个点文件而不是网格化字段:
#!/bin/bash
# code to find date of first positive file entry
file=trmm_per10_pc0_year2000_nc2.nc
# set negative values to missing
cdo -s setrtomiss,-1.e36,0.0 $file set.nc
ntime=`cdo -s ntime set.nc` # number of steps in file
# loop over steps to find first positive value
for i in `seq 1 ${ntime}` ; do
# nco counts from step 0, cdo from 1
ncoi=`expr $i - 1`
# print out the value in step i
op=`ncks -d time,$ncoi -s "%16.10f\n" -H -C -v precip set.nc`
if [[ $op != "_" ]] ; then # not missing
# print the date of timestep i
cdo -s showdate -seltimestep,$i set.nc
rm -f set.nc
exit
fi
done
# no positive value found
rm -f set.nc
echo "All values in $file are negative"