缘起 很多在中国气象网下载的站点降水数据多为 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
制作流程 % C. r& [1 M* d
总体步骤为 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(定义全局属性)
- U5 G6 r# `$ z, M+ c " Q9 k# r8 L2 O( A2 u3 V8 y" `
: y7 X' C' Q6 C1. 创建nc文件 2 \; N7 D0 t8 J' d* f2 Z
[C] 纯文本查看 复制代码 outDir = 'H:\TempData\SationPrecp';
outFile = 'Precip_Daily_2481stations_China.nc';
outDirFile = [outDir, '\', outFile];
outid = netcdf.create(outDirFile, '64BIT_OFFSET'); % |! I" a& w& c5 K/ v
【提示】事先想好需要存储变量的结构及维度,之后需要注意的是创建 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 | 1 A- n. ~1 {8 s o; }. T
0 [8 q. m) ?8 O3 {
2.定义维度 7 T* v2 J( I( O1 t8 b4 z7 C# w
[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.定义变量 - L! `/ l2 Z6 F5 s, O v
[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.导入变量 2 p. F- v% R* b( B
[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);
; m+ Z* G1 Q6 `$ l# q+ o
【提示】注意放置的数据时,变量一定要和自己在 2.定义维度 时的矩阵形状完全一致才行!这个形状也就是matllab 中用 ncdisp()函数显示出来的矩阵形状。
4 b& q9 u5 C" c( Y
2 ]) k3 e: j4 y$ T7 H5. 导入变量属性 4 }4 n4 a9 l$ j- K
[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));
) P& Z& r% U! U6 r6. 定义全局属性
; c" x6 @" J1 _& R. d
[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); " v# Q8 r& G8 n
源代码 0 d1 h, e1 S6 W" l- t3 `# g
[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 ; \" y/ u- m7 R" g% f3 h
/ N# K, X* `2 [' E
; a9 t$ R0 D* p* n8 x |