[Matlab] 能不能用Matlab将站点降水数据直接制作成Netcdf文件

[复制链接]

缘起

很多在中国气象网下载的站点降水数据多为 txt格式,读写起来甚为不便,于是便萌生了将其制作为 netcdf 文件的想法。

原始数据格式(txt)及形式逐列显示,通过将其导入到matlab中,显示如下

de680f91f41bf51172390df5bde7d3fc.png

制作好之后的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 t

2.定义维度


" 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" ]
回复

举报 使用道具

相关帖子

全部回帖
暂无回帖,快来参与回复吧
懒得打字?点击右侧快捷回复 【吾爱海洋论坛发文有奖】
您需要登录后才可以回帖 登录 | 立即注册
文星雨
活跃在4 天前
快速回复 返回顶部 返回列表