[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

制作流程

* B- R+ a& \; j$ 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(定义全局属性)

    / m5 ?9 o8 [' N

" P( J3 b! n6 A2 K7 `- s5 @( T; D, z$ L7 l2 c

1. 创建nc文件

7 S7 b, u) M" D1 V" q$ `2 y9 G+ i

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

outFile    = 'Precip_Daily_2481stations_China.nc';

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

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


: S3 h7 V, A* F4 \4 Y5 `( ?$ n

【提示】事先想好需要存储变量的结构及维度,之后需要注意的是创建 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


4 f4 n$ ~2 l- P
) r" G! f% U" g3 `, W

2.定义维度


6 A0 H( g5 u' V3 w

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

2 u6 z: \! `( g! O8 H; X* S" v

[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.导入变量

) l* L9 z; F" ]. x3 b

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

4 s' N$ _- n6 c  j7 s" J

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

1 S9 B1 p$ l2 v! \0 c, f
2 T( U# g  c* }: D

5. 导入变量属性


7 z; b, Q+ Z5 o) {' [8 \

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


6 h- ?2 p( M) _) b5 D  `  U6 f

6. 定义全局属性

  r& p! g0 T, I0 q1 ~

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


' v0 d) B! ]9 O2 M8 h( R' t% ~; s

源代码


7 ?: V3 |  o) }1 x

[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

( g- j6 B$ N0 W/ \4 I6 j+ W
  a+ B9 `  i3 j- P1 l
, p; }: t) U& l( V+ G, m
回复

举报 使用道具

相关帖子

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