缘起 很多在中国气象网下载的站点降水数据多为 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
制作流程 # Q/ f# {( I4 Y) e! `& C3 Q! |5 Z
总体步骤为 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(定义全局属性) : q' e+ y @. W- t7 Q
: z$ j6 f* \. s }, [$ d0 g
0 s3 `# H" ~0 \* Q5 ]1. 创建nc文件
1 }# u* ^5 z' O, g, P7 p
[C] 纯文本查看 复制代码 outDir = 'H:\TempData\SationPrecp';
outFile = 'Precip_Daily_2481stations_China.nc';
outDirFile = [outDir, '\', outFile];
outid = netcdf.create(outDirFile, '64BIT_OFFSET'); ( G& U: Y9 i' t% i* 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 | * }3 o, N6 f& q
; y) r- X' X' J' Q3 e- Q
2.定义维度 - g- f* E$ ]1 n
[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.定义变量
+ b5 p3 g3 P) c; J( {/ [* v6 }
[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 B. ^( K1 O& Y V' 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); 0 P* [- h) K3 {& c( D) M
【提示】注意放置的数据时,变量一定要和自己在 2.定义维度 时的矩阵形状完全一致才行!这个形状也就是matllab 中用 ncdisp()函数显示出来的矩阵形状。 2 G# U" ?" w" Q T6 b& N, l1 A
& |: a% n0 s/ D& `5. 导入变量属性
6 b! S: ~6 @" f; I- e. \
[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));
% s6 y! l1 B/ J/ W# U6. 定义全局属性
7 \! c9 G' e1 ?) I h8 ~: g; M/ ?% C! h
[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);
, y8 i& J" P2 O) |2 [源代码
* h8 n: ^+ d" a% ?$ K7 Y- a
[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 - Z9 h2 Q7 e4 n5 w) S
% G" A& H9 x9 V$ x) l6 ^- E
7 j. p$ E& P! ?' N) v. \$ i |