[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

制作流程


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

举报 使用道具

相关帖子

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