缘起 很多在中国气象网下载的站点降水数据多为 txt格式,读写起来甚为不便,于是便萌生了将其制作为 netcdf 文件的想法。 原始数据格式(txt)及形式逐列显示,通过将其导入到matlab中,显示如下
制作好之后的netcdf文件为以(日,月,年,站点ID)为索引的数据,用matlab的ncdisp()函数的显示结果如下: [C] 纯文本查看 复制代码 >> ncdisp('Precip_Daily_2481stations_China.nc')[/color][/p][p=null, 2, left]
Source:
H:\TempData\SationPrecp\Precip_Daily_2481stations_China.nc
Format:
64bit
Global Attributes:
Title = 'Station daily rainfall data'
Data Period = '1951-2018'
Author = 'Dayon, SYSU, Email:wangdy58@mail2.sysu.edu.cn'
History = 'created on: 04-Mar-2021 10:12:52'
Dimensions:
numStat = 2481
year = 68
mon = 12
day = 31
Variables:
stid
Size: 2481x1
Dimensions: numStat
Datatype: single
lon
Size: 2481x1
Dimensions: numStat
Datatype: single
Attributes:
longname = 'longitude'
units = 'degrees_east'
lat
Size: 2481x1
Dimensions: numStat
Datatype: single
Attributes:
longname = 'latitude'
bounds = 'degrees_north'
alt
Size: 2481x1
Dimensions: numStat
Datatype: single
Attributes:
longname = 'height above sea level'
units = 'm'
Prec
Size: 31x12x68x2481
Dimensions: day,mon,year,numStat
Datatype: single
Attributes:
longname = 'daily rainfall'
units = 'mm/day'
_FillValue = -999
missing_value = -999
制作流程 ' g6 g! s! a7 E7 P. [8 U& ~
总体步骤为 0. create nc file(创建nc文件) 1. define dimensions(定义维度) 2. define variables(定义变量) 3. put variables into nc(导入变量) 4. put attribute into nc(导入变量属性) 5. define global attribution(定义全局属性)
r( r! y7 t' z2 k# f 5 h9 D" N a8 J, ?1 n* |
: `! W# P3 K: I8 W4 f* H; r
1. 创建nc文件
5 y; I/ j" G6 Q9 g: o
[C] 纯文本查看 复制代码 outDir = 'H:\TempData\SationPrecp';
outFile = 'Precip_Daily_2481stations_China.nc';
outDirFile = [outDir, '\', outFile];
outid = netcdf.create(outDirFile, '64BIT_OFFSET'); ) i- S, t U: }
【提示】事先想好需要存储变量的结构及维度,之后需要注意的是创建 nc 文件的 类 型类型,以下供参考: 类型名 | 描述 | ‘NOCLOBBER’ | Prevent overwriting of existing file with the same name.(不覆盖已经有的同名文件) | 'CLOBBER' | Overwrite any existing file with the same name.(覆盖任何已有的同名文件) | 'SHARE' | Allow synchronous file updates.(允许同步文件更新) | '64BIT_OFFSET' | Allow easier creation of files and variables which are larger than two gigabytes.(可创建>2G的文件) | 'NETCDF4' | Create a NetCDF-4/HDF5 file(普通) | 'CLASSIC_MODEL' | Enforce the classic model; has no effect unless used in a bitwise-or with NETCDF4 | ' @' d7 k, s5 W
1 U) b4 x# T+ m" j7 I6 t2.定义维度
" v {- ^ Q8 z
[C] 纯文本查看 复制代码 numStatdimID = netcdf.defDim(outid,'numStat', 2481);
yeardimID = netcdf.defDim(outid,'year', 68);
mondimID = netcdf.defDim(outid,'mon', 12);
daydimID = netcdf.defDim(outid,'day', 31); 3.定义变量 * n) v$ h$ ]/ S
[C] 纯文本查看 复制代码 lon_id = netcdf.defVar(outid,'lon','NC_FLOAT', numStatdimID);
lat_id = netcdf.defVar(outid,'lat','NC_FLOAT', numStatdimID);
alt_id = netcdf.defVar(outid,'alt','NC_FLOAT', numStatdimID);
Prec_id = netcdf.defVar(outid,'Prec','NC_FLOAT',[daydimID, mondimID, yeardimID, numStatdimID]);
netcdf.endDef(outid); 4.导入变量 6 d) z' n; f) d' z1 k/ t
[C] 纯文本查看 复制代码 netcdf.putVar(outid, lon_id, UnqLon/100);
netcdf.putVar(outid, lat_id, UnqLat/100);
netcdf.putVar(outid, alt_id, UnqAlt/100);
netcdf.putVar(outid, Prec_id, Precmmd);
netcdf.reDef(outid); 5 `+ F0 e9 G4 x& H) a7 o
【提示】注意放置的数据时,变量一定要和自己在 2.定义维度 时的矩阵形状完全一致才行!这个形状也就是matllab 中用 ncdisp()函数显示出来的矩阵形状。
/ ?0 T ^1 {1 T3 b5 G* P* g( s! a4 G% j7 r3 [2 y
5. 导入变量属性
* x$ N8 ] ^/ D1 M$ Y+ h& J
[C] 纯文本查看 复制代码 netcdf.putAtt(outid, lon_id, 'longname', 'longitude');
netcdf.putAtt(outid, lon_id, 'units', 'degrees_east');
netcdf.putAtt(outid, lat_id, 'longname', 'latitude');
netcdf.putAtt(outid, lat_id, 'bounds', 'degrees_north');
netcdf.putAtt(outid, alt_id, 'longname', 'height above sea level');
netcdf.putAtt(outid, alt_id, 'units', 'm');
netcdf.putAtt(outid, Prec_id, 'longname', 'daily rainfall');
netcdf.putAtt(outid, Prec_id, 'units', 'mm/day');
netcdf.putAtt(outid, Prec_id, '_FillValue', single(-999));
netcdf.putAtt(outid, Prec_id, 'missing_value', single(-999)); / {$ t1 G m' v( Y: r4 @: ?
6. 定义全局属性
$ o3 u, w) Y3 Y; ^& \9 ^
[C] 纯文本查看 复制代码 netcdf.putAtt(outid, netcdf.getConstant('NC_GLOBAL'), 'title', 'station daily rainfall data');
netcdf.putAtt(outid, netcdf.getConstant('NC_GLOBAL'), 'Data_Period', '1951-2018');
netcdf.putAtt(outid, netcdf.getConstant('NC_GLOBAL'), 'Author', 'Dayon, SYSU, Email : [email]wangdy58@mail2.sysu.edu.cn[/email]');
netcdf.putAtt(outid, netcdf.getConstant('NC_GLOBAL'), 'History', ['created on: ',datestr(now)]);
netcdf.close(outid); 3 T% V5 A' [# k# N5 X
源代码 # K1 e7 [2 i/ j
[C] 纯文本查看 复制代码 % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
% Aim: this script aim at transfering Precp data of Station to nc type file
% Date: 2022-01-21
% Author: Dayon, Sun Yat-sen University
% % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
tic
clc; clear;
% read data from station
inDir = ('H:\TempData\SationPrecp');
inFile = ('PREC_Station_data.mat');
inDirFile = [inDir, '\', inFile];
load (inDirFile);
stationId = PREC(:, 1);
N = length(stationId);
Lat = PREC(:, 2);
Lon = PREC(:, 3);
Alt = PREC(:, 4);
Year = PREC(:, 5);
Month = PREC(:, 6);
Day = PREC(:, 7);
ValPrecp = PREC(:, 8);
[Unqid, ind, ~] = unique(stationId, 'stable');
UnqLat = Lat(ind);
UnqLon = Lon(ind);
UnqAlt = Alt(ind);
numStat = length(Unqid);
for i = 1 : numStat
stationId(stationId == Unqid(i)) = i;
end
YRbeg = min(Year);
YRend = max(Year);
numYR = YRend - YRbeg + 1;
for j = 1 : numYR
Year(Year == YRbeg + j - 1 ) = j;
end
Precmmd = -999 * ones(31, 12, numYR, numStat);
for k = 1 : N
iDay = Day(k);
iMon = Month(k);
iYear = Year(k);
iStat = stationId(k);
Precmmd(iDay, iMon, iYear, iStat) = ValPrecp(k);
% check schedule
if mod(k, 10^6) == 0
disp(['----- ',num2str(k),' -----'])
end
end
Precmmd = single(Precmmd);
% PREC = [Day, Month, Year, stationId];
%----------------------------------------------------------------------
% make nc
%----------------------------------------------------------------------
outDir = 'H:\TempData\SationPrecp';
outFile = 'Precip_Daily_2481stations_China.nc';
outDirFile = [outDir, '\', outFile];
outid = netcdf.create(outDirFile, '64BIT_OFFSET');
% define dimensions
numStatdimID = netcdf.defDim(outid,'numStat', 2481);
yeardimID = netcdf.defDim(outid,'year', 68);
mondimID = netcdf.defDim(outid,'mon', 12);
daydimID = netcdf.defDim(outid,'day', 31);
% define variables
station_id = netcdf.defVar(outid,'stid','NC_FLOAT', numStatdimID);
lon_id = netcdf.defVar(outid,'lon','NC_FLOAT', numStatdimID);
lat_id = netcdf.defVar(outid,'lat','NC_FLOAT', numStatdimID);
alt_id = netcdf.defVar(outid,'alt','NC_FLOAT', numStatdimID);
Prec_id = netcdf.defVar(outid,'Prec','NC_FLOAT',[daydimID, mondimID, yeardimID, numStatdimID]);
netcdf.endDef(outid);
% put variables into nc
netcdf.putVar(outid, station_id, Unqid);
netcdf.putVar(outid, lon_id, UnqLon/100);
netcdf.putVar(outid, lat_id, UnqLat/100);
netcdf.putVar(outid, alt_id, UnqAlt/100);
netcdf.putVar(outid, Prec_id, Precmmd);
netcdf.reDef(outid);
% put attribute into nc
netcdf.putAtt(outid, lon_id, 'longname', 'original station id');
netcdf.putAtt(outid, lon_id, 'longname', 'longitude');
netcdf.putAtt(outid, lon_id, 'units', 'degrees_east');
netcdf.putAtt(outid, lat_id, 'longname', 'latitude');
netcdf.putAtt(outid, lat_id, 'bounds', 'degrees_north');
netcdf.putAtt(outid, alt_id, 'longname', 'height above sea level');
netcdf.putAtt(outid, alt_id, 'units', 'm');
netcdf.putAtt(outid, Prec_id, 'longname', 'daily rainfall');
netcdf.putAtt(outid, Prec_id, 'units', 'mm/day');
netcdf.putAtt(outid, Prec_id, '_FillValue', single(-999));
netcdf.putAtt(outid, Prec_id, 'missing_value', single(-999));
% define global attribution
netcdf.putAtt(outid, netcdf.getConstant('NC_GLOBAL'), 'Title', 'Station daily rainfall data');
netcdf.putAtt(outid, netcdf.getConstant('NC_GLOBAL'), 'Data Period', '1951-2018');
netcdf.putAtt(outid, netcdf.getConstant('NC_GLOBAL'), 'Author', 'Dayon, SYSU, Email : [email]wangdy58@mail2.sysu.edu.cn[/email]');
netcdf.putAtt(outid, netcdf.getConstant('NC_GLOBAL'), 'History', ['created on: ',datestr(now)]);
netcdf.close(outid);
toc
8 j: R7 O5 M' |. u! R$ p3 c" E
+ V5 x: U9 l& G, E0 h9 z
: p. A/ J# O9 c; F% r" ] |