[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

制作流程


9 ?" q2 {: O7 \2 I  p0 C+ W

总体步骤为

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

    + j$ f* @2 q  e+ W' X0 }* Y8 H; x
! T% o# n/ H' V3 G
7 a  P; @* \5 \0 h, M# W" K

1. 创建nc文件

2 M& ]4 j$ P' v6 }& v1 o

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

outFile    = 'Precip_Daily_2481stations_China.nc';

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

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

# W  R+ g6 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


# F7 h' F1 ^1 h* u* k
2 c' M8 K' a( g, j

2.定义维度

9 Z- ?4 ]. M' E8 w9 h2 A  j

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

; A' m$ t3 S9 G

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


% }" I9 C  R, \1 F  o  i2 \

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


1 h# H: R5 m- `# X* U

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

$ J0 t- x, x& W9 Z4 q8 v1 a) K& ~

- V! Z6 z3 D- Z) s

5. 导入变量属性

8 u2 Y4 {" k$ w

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


+ n+ d8 S! y7 g( y( [

6. 定义全局属性

+ \3 }% D( B; O3 u' Y) R

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


6 c8 Z6 T& E( ^8 t

源代码

5 u2 u5 \" J( F, W% r

[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


4 X9 s2 s$ \% o/ ~) T7 m
! v$ K7 t! j3 L3 A1 ]7 Q* H! }$ V6 u& m( L
回复

举报 使用道具

相关帖子

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