[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

制作流程


/ l7 G; W$ p* w# a

总体步骤为

  • 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(定义全局属性)


    7 d! J; ]1 @. v9 O1 L, B" I- x

5 H5 t- ?1 z' |, S
/ S' O+ F7 U6 A$ S& X

1. 创建nc文件

" X. s+ |7 b$ l% ]& }7 ]

[C] 纯文本查看 复制代码
outDir     = 'H:\TempData\SationPrecp';

outFile    = 'Precip_Daily_2481stations_China.nc';

outDirFile = [outDir, '\', outFile];

outid      = netcdf.create(outDirFile, '64BIT_OFFSET');


3 G5 V5 s* |1 _+ \! 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


. \- `. s$ H* R9 b  X4 `; F; q9 Q* a4 K3 K! Y  w

2.定义维度


. v) g$ o. E4 v* m6 U

[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.定义变量


9 H' G8 l$ J1 I( ]" {0 A) g8 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.导入变量


# b$ \# Z- K; F& w7 [* s( 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);


; z" w* H3 n) ^( E) H

【提示】注意放置的数据时,变量一定要和自己在 2.定义维度 时的矩阵形状完全一致才行!这个形状也就是matllab 中用 ncdisp()函数显示出来的矩阵形状。


, w6 q5 u, }( X: a* M. |
4 `9 N8 k7 C$ i7 L  Y, s8 u; J

5. 导入变量属性


- v% \& K! z! n& d  A# g

[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));


+ b5 F* E4 g" T# f4 I

6. 定义全局属性

" Y; ~" {- n* J- D7 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);

# A( H7 ]- y. |

源代码

2 x. C( t) q3 k& d% _- ~8 n

[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

& r0 b$ ], d6 P7 S

. L* `# |4 O& H1 S( ~7 o4 k
# T+ V  V5 o/ z% p3 u2 e2 X
回复

举报 使用道具

相关帖子

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