缘起 很多在中国气象网下载的站点降水数据多为 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
制作流程
1 W3 |5 U1 ?1 x) P# {8 C3 C: M, h总体步骤为 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(定义全局属性) % V, _! E9 y2 S' @+ f; B
3 e' @0 B4 ~# S! ~' `7 p% G V2 R/ e7 J4 [
1. 创建nc文件 4 }: r7 P/ t8 t x
[C] 纯文本查看 复制代码 outDir = 'H:\TempData\SationPrecp';
outFile = 'Precip_Daily_2481stations_China.nc';
outDirFile = [outDir, '\', outFile];
outid = netcdf.create(outDirFile, '64BIT_OFFSET'); + x9 t* n! Z9 b# `: _' D
【提示】事先想好需要存储变量的结构及维度,之后需要注意的是创建 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 | O8 a: i4 e/ X% w, i6 u# t9 k
; u4 g7 h$ I" L7 \4 p/ N, l
2.定义维度
+ [7 o' ?# p; J3 ]: C
[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% X2 @8 b2 T- l
[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.导入变量
; G( j* c1 T% k; r- \
[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); 8 s7 s; n; L7 `+ i8 M
【提示】注意放置的数据时,变量一定要和自己在 2.定义维度 时的矩阵形状完全一致才行!这个形状也就是matllab 中用 ncdisp()函数显示出来的矩阵形状。
# A) b u) `7 o, e7 d2 x9 R) ]4 E3 t
5. 导入变量属性 7 C0 R) p6 H: U8 a1 J, m# e0 N. 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)); 1 O% Y& q0 F, z" I
6. 定义全局属性
( @7 I2 Y' J* H+ p( P
[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);
! D0 f1 T9 d1 j6 J6 g% j4 j源代码 Z' v7 S' o# f9 r" n; h
[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 3 q4 g6 g9 \5 v1 f; f& d8 z! M
0 |/ V6 u% ~; f# i- v: ^
8 p' J; m2 m3 T! T1 l |