Main Content

NetCDF ファイルと OPeNDAP データのインポート

いくつかの方法で netCDF ファイルからデータを読み取ることができます。プログラムによって行う場合は、MATLAB® の高水準の netCDF 関数、または低水準関数の netCDF ライブラリの名前空間を使用できます。対話的に行う場合は、[データのインポート] ライブ エディター タスクまたはインポート ツール アプリ (MATLAB Online™ 内) を使用できます。

MATLAB NetCDF 機能

Network Common Data Form (NetCDF) は一連のソフトウェア ライブラリとハードウェア非依存型のデータ形式であり、配列指向の科学データの作成、アクセスおよび共有をサポートしています。NetCDF は、データ共有を目的とする標準のデータ保存方法が必要な工学および科学の諸分野で幅広く使用されています。

MATLAB の高水準関数により、NetCDF ファイルまたは OPeNDAP NetCDF データ ソースからのデータのインポート処理が簡略化されます。MATLAB の低水準関数では、NetCDF C ライブラリ内のルーチンにアクセスして、インポート処理をさらに制御できます。低水準関数を効果的に使用するには、NetCDF C インターフェイスに関する知識が必要です。NetCDF ドキュメンテーションは、Unidata Web サイトで入手できます。

メモ

互換性のない異なる形式の Common Data Format (CDF) ファイルのインポートの詳細は、低水準関数による CDF ファイルのインポートを参照してください。

OPeNDAP サーバーへの接続時のセキュリティに関する考慮事項

信頼済みの OPeNDAP サーバーにのみ接続することを強く推奨します。R2020b 以降、既定では、MATLAB NetCDF インターフェイスは、サーバー証明書およびホスト名の検証を実行することにより、信頼済みのデータ アクセス プロトコル (DAP) エンドポイントにのみ接続します。以前は、OPeNDAP サーバーにアクセスした場合、サーバー証明書とホスト名の両方の検証が既定で無効になっていました。

サーバー証明書とホスト名の検証を無効にする場合は、現在のディレクトリ内の .dodsrc ファイルに以下の行を追加します。

[mylocaltestserver.lab] HTTP.SSL.VALIDATE=0

これにより、MATLAB NetCDF インターフェイスは、サーバー証明書またはホスト名の検証を実行せずに、URI mylocaltestserver.lab で指定された名前の OPeNDAP サーバーに接続するようになります。この変更は、次回以降の MATLAB セッションでも維持されます。

高水準関数による NetCDF ファイルからの読み取り

この例では、高水準関数を使用して NetCDF ファイルの内容を表示し、読み取る方法を説明します。

サンプルの NetCDF ファイル example.nc の内容を表示します。

ncdisp('example.nc')
Source:
           \\matlabroot\toolbox\matlab\demos\example.nc
Format:
           netcdf4
Global Attributes:
           creation_date = '29-Mar-2010'
Dimensions:
           x = 50
           y = 50
           z = 5
Variables:
    avagadros_number
           Size:       1x1
           Dimensions: 
           Datatype:   double
           Attributes:
                       description = 'this variable has no dimensions'
    temperature     
           Size:       50x1
           Dimensions: x
           Datatype:   int16
           Attributes:
                       scale_factor = 1.8
                       add_offset   = 32
                       units        = 'degrees_fahrenheit'
    peaks           
           Size:       50x50
           Dimensions: x,y
           Datatype:   int16
           Attributes:
                       description = 'z = peaks(50);'
Groups:
    /grid1/
        Attributes:
                   description = 'This is a group attribute.'
        Dimensions:
                   x    = 360
                   y    = 180
                   time = 0     (UNLIMITED)
        Variables:
            temp
                   Size:       []
                   Dimensions: x,y,time
                   Datatype:   int16
    
    /grid2/
        Attributes:
                   description = 'This is another group attribute.'
        Dimensions:
                   x    = 360
                   y    = 180
                   time = 0     (UNLIMITED)
        Variables:
            temp
                   Size:       []
                   Dimensions: x,y,time
                   Datatype:   int16

ncdisp は、ファイルのすべてのグループ、次元および変数定義を表示します。制限のない次元は UNLIMITED というラベルで識別されます。

変数 peaks からデータを読み取ります。

peaksData  = ncread('example.nc','peaks');

peaksData 出力に関する情報を表示します。

whos peaksData
  Name            Size            Bytes  Class    Attributes

  peaksData      50x50             5000  int16  

変数に関連付けられている description 属性を読み取ります。

peaksDesc  = ncreadatt('example.nc','peaks','description')
peaksDesc =

z = peaks(50);

変数データの 3 次元表面プロットを作成します。description 属性の値を Figure のタイトルとして使用します。

surf(double(peaksData))
title(peaksDesc);

/grid1/ グループに関連付けられている description 属性を読み取ります。関数 ncreadatt の 2 番目の入力としてグループ名を指定します。

g = ncreadatt('example.nc','/grid1/','description')
g =

This is a group attribute.

グローバル属性 creation_date を読み取ります。グローバル属性の場合は、ncreadatt の 2 番目の入力引数を '/' として指定します。

creation_date = ncreadatt('example.nc','/','creation_date')
creation_date =

29-Mar-2010

NetCDF ファイルのすべての制限のない次元の検索

この例では、高水準関数を使用して、NetCDF ファイルに含まれる 1 つのグループ内の制限のない次元をすべて検索する方法を説明します。

関数 ncinfo を使用して、サンプル ファイル example.nc/grid2/ グループに関する情報を取得します。

ginfo = ncinfo('example.nc','/grid2/')
ginfo = 

      Filename: '\\matlabroot\toolbox\matlab\demos\example.nc'
          Name: 'grid2'
    Dimensions: [1x3 struct]
     Variables: [1x1 struct]
    Attributes: [1x1 struct]
        Groups: []
        Format: 'netcdf4'

ncinfo は、グループに関する情報を含む構造体配列を返します。

このグループの制限のない次元を示すブール値のベクトルを取得します。

unlimDims = [ginfo.Dimensions.Unlimited]
unlimDims =

     0     0     1

unlimDims ベクトルを使用して、制限のない次元を表示します。

disp(ginfo.Dimensions(unlimDims))
         Name: 'time'
       Length: 0
    Unlimited: 1

低水準関数による NetCDF ファイルからの読み取り

この例では、netcdf 名前空間の MATLAB 低水準関数を使用して、netCDF ファイルの次元、変数、および属性に関する情報を取得する方法を説明します。これらの関数を効果的に使用するには、netCDF C インターフェイスに関する知識が必要です。

NetCDF ファイルを開く

関数 netcdf.open を使用して、サンプルの netCDF ファイル example.nc を読み取り専用アクセスで開きます。

ncid = netcdf.open("example.nc","NC_NOWRITE");

netcdf.open はファイル識別子を返します。

NetCDF ファイルの情報の取得

関数 netcdf.inq を使用して、ファイルの内容に関する情報を取得します。この関数は、NetCDF ライブラリ C API の関数 nc_inq に相当します。

[ndims,nvars,natts,unlimdimID] = netcdf.inq(ncid)
ndims = 3
nvars = 3
natts = 1
unlimdimID = -1

netcdf.inq では、ファイルの次元、変数およびグローバル属性の数と、ファイルに含まれる制限のない次元の識別子が返されます。制限のない次元は増大の可能性があります。

関数 netcdf.inqAttName を使用してファイルのグローバル属性の名前を取得します。この関数は、NetCDF ライブラリ C API の関数 nc_inq_attname に相当します。属性名を取得するには、その属性が関連付けられている変数の ID と属性番号を指定しなければなりません。特定の変数に関連付けられていないグローバル属性にアクセスするには、定数 "NC_GLOBAL" を変数 ID として使用します。

global_att_name = netcdf.inqAttName(ncid,...
    netcdf.getConstant("NC_GLOBAL"),0)
global_att_name = 
'creation_date'

関数 netcdf.inqAtt を使用して、属性のデータ型と長さに関する情報を取得します。この関数は、NetCDF ライブラリ C API の関数 nc_inq_att に相当します。この場合も、netcdf.getConstant("NC_GLOBAL") を使用して変数 ID を指定します。

[xtype,attlen] = netcdf.inqAtt(ncid,...
    netcdf.getConstant("NC_GLOBAL"),global_att_name)
xtype = 2
attlen = 11

関数 netcdf.getAtt を使用して属性の値を取得します。

global_att_value = netcdf.getAtt(ncid,...
    netcdf.getConstant("NC_GLOBAL"),global_att_name)
global_att_value = 
'29-Mar-2010'

関数 netcdf.inqDim を使用して、ファイルの最初の次元に関する情報を取得します。この関数は、NetCDF ライブラリ C API の関数 nc_inq_dim に相当します。関数 netcdf.inqDim の 2 番目の入力は次元 ID であり、次元を識別するための 0 ベースのインデックスです。最初の次元のインデックス値は 0 です。

[dimname,dimlen] = netcdf.inqDim(ncid,0)
dimname = 
'x'
dimlen = 50

netcdf.inqDim は、次元の名前と長さを返します。

関数 netcdf.inqVar を使用してファイルの最初の変数に関する情報を取得します。この関数は、NetCDF ライブラリ C API の関数 nc_inq_var に相当します。関数 netcdf.inqVar の 2 番目の入力は変数 ID であり、変数を識別するための 0 ベースのインデックスです。最初の変数のインデックス値は 0 です。

[varname,vartype,dimids,natts] = netcdf.inqVar(ncid,0)
varname = 
'avagadros_number'
vartype = 6
dimids =

     []
natts = 1

netcdf.inqVar によって、変数の名前、データ型、次元 ID および変数に関連付けられている属性の数が返されます。vartype で返されるデータ型の情報は、NC_INTNC_BYTE などの netCDF データ型定数の数値です。これらの定数の詳細は、netCDF ドキュメンテーションを参照してください。

NetCDF ファイルからのデータの読み取り

関数 netcdf.getVar を使用して、サンプル ファイル内の変数 avagadros_number に関連付けられたデータを読み取ります。関数 netcdf.getVar の 2 番目の入力は変数 ID であり、変数を識別するための 0 ベースのインデックスです。変数 avagadros_number のインデックス値は 0 です。

A_number = netcdf.getVar(ncid,0)
A_number = 6.0221e+23

A_number のデータ型を表示します。

whos A_number
  Name          Size            Bytes  Class     Attributes

  A_number      1x1                 8  double              

netcdf 名前空間の関数では、NetCDF データ型に最も一致する MATLAB クラスが自動的に選択されますが、netcdf.getVar にオプションの引数を使用して、返されるデータのクラスを指定することもできます。

avagadros_number に関連付けられたデータを読み取り、データを single クラスとして返します。

A_number = netcdf.getVar(ncid,0,"single")
A_number = single
    6.0221e+23
whos A_number
  Name          Size            Bytes  Class     Attributes

  A_number      1x1                 4  single              

NetCDF ファイルを閉じる

netCDF ファイル example.nc を閉じます。

netcdf.close(ncid)

NetCDF ファイルからのデータの対話的な読み取り

この例では、[データのインポート] タスクを使用して netCDF ファイルの構造を調べ、ファイルからデータをインポートしてから、データを解析して可視化する方法を示します。

データセットのダウンロード

米国海洋大気庁物理科学研究所 (NOAA PSL) は、米国国立雪氷データ センター (NSIDC) によって編纂された北半球における積雪の内挿データのデータセットをホストしています。このデータセットを現在のフォルダーにダウンロードします。

filename = "snowcover.mon.mean.nc";
url = "https://downloads.psl.noaa.gov/Datasets/snowcover/snowcover.mon.mean.nc";
fullLocalPath = websave(filename,url);

データの探索とインポート

[ライブ エディター] タブで [タスク]、[データのインポート] を選択して、ライブ エディターで [データのインポート] タスクを開きます。[ファイル] フィールドに、netCDF データセットのファイル名 snowcover.mon.mean.nc を入力します。タスクを使用して、変数とその属性を含むデータの構造を探索します。

  • グローバル属性により、参照など、ファイルに含まれているデータを全般的に把握できます。

  • このデータセットには 3 つの次元が含まれています。2 つの空間次元 (latlon) と 1 つの時間次元 (time) です。

  • 変数 lat のサイズは 90 で、units という属性があり、その値は 'degrees_north' です。この変数は、測定が行われた地点の緯度を、北緯で表します。

  • 変数 lon のサイズは 360 で、units という属性があり、その値は 'degrees_east' です。この変数は、測定が行われた地点の経度を、東経で表します。

  • 変数 time のサイズは 297 で、無制限の次元をもち、units という属性があり、その値は 'hours since 1800-01-01 00:00:0.0' です。この変数は、測定が行われた時間を表します。

  • 変数 snowcover のサイズは 360×90×297 で、3 番目の次元は無制限です。units という属性があり、その値は '%' です。また、long_name という属性があり、その値は 'Monthly Means Snowcover Extent' です。変数 snowcover は、変数 latlon、および time を結合します。これは、特定の月における北半球の特定の地点の積雪の月平均を表しています。単位は雪で覆われた地面の割合 (%) です。

変数 latlontime、および snowcover からデータを選択してインポートします。

Import Data Live Editor task with the snowcover.mon.mean.nc file imported, showing all variables selected for import

このタスクにより生成されるコードを確認するには、タスク パラメーター エリアの下部にある [コードの表示] をクリックしてタスクの表示を展開します。

% Create a structure to store imported netCDF data
snowcover_mon_mean = struct();

filename = "snowcover.mon.mean.nc";
snowcover_mon_mean.Variables(1).Name = "lat";
snowcover_mon_mean.Variables(2).Name = "lon";
snowcover_mon_mean.Variables(3).Name = "time";
snowcover_mon_mean.Variables(4).Name = "snowcover";

snowcover_mon_mean.Variables(1).Value = ncread(filename, "/lat");

snowcover_mon_mean.Variables(2).Value = ncread(filename, "/lon");

snowcover_mon_mean.Variables(3).Value = ncread(filename, "/time");

snowcover_mon_mean.Variables(4).Value = ncread(filename, "/snowcover");

clear filename

データの整理と準備

データセットの変数ごとにローカル変数を作成します。

lats = snowcover_mon_mean.Variables(1).Value;
lons = snowcover_mon_mean.Variables(2).Value;
times = snowcover_mon_mean.Variables(3).Value;
snows = snowcover_mon_mean.Variables(4).Value;

latslons の表示バージョンを作成して、データをプロットする準備をします。各軸に 10 個のラベルを表示する表示スケールを選択します。

numLabels = 10;

latDisps = strings(length(lats),1);
latsLabelInterval = length(lats)/numLabels;
latLabelInds = latsLabelInterval:latsLabelInterval:length(lats);
latDisps(latLabelInds) = lats(latLabelInds);

lonDisps = strings(length(lons),1);
lonsLabelInterval = length(lons)/numLabels;
lonLabelInds = lonsLabelInterval:lonsLabelInterval:length(lons);
lonDisps(lonLabelInds) = lons(lonLabelInds);

変数 timeunits 属性は、time の単位が 1800 年の最初以降の時間数であることを示しています。さらに、変数 snowcoverlong_name 属性は、値が月平均であることを示しています。この情報を使用して、times ベクトルを対応する datetime 値に変換し、また月と年を含めるが日を非表示にした times の表示バージョンを作成します。

sampTimes = datetime("1800-01-01 00:00:00") + hours(times);
sampTimes.Format = "MMM-yyyy";
sampTimeDisps = string(sampTimes);

snows の最初の次元は緯度を表し、2 番目の次元は経度を表します。このデータのヒートマップを作成するには、最初の次元が列 (経度) に対応し、2 番目の次元が行 (緯度) に対応する必要があります。snows のこれらの 2 つの次元を並べ替えます。

snows = permute(snows,[2 1 3]);

データのプロット

最初の 1 か月分のデータのヒートマップを作成します。

h = heatmap(lons,lats,snows(:,:,1));
h.XLabel = "Longitude (°E)";
h.YLabel = "Latitude (°N)";
h.XDisplayLabels = lonDisps;
h.YDisplayLabels = latDisps;
h.Colormap = winter;
h.GridVisible = "off";

利用可能なすべての時間のデータをループして、ヒートマップをアニメーション化します。

for i = 1:numel(sampTimeDisps)
    h.ColorData = snows(:,:,i);
    h.Title = "Percent Snow Cover vs. Location (" + sampTimeDisps(i) + ")";
    pause(0.1)
end

Figure contains an object of type heatmap. The chart of type heatmap has title Percent Snow Cover vs. Location (Sep-1995).

最大積雪の時間の計算

総積雪を時間の関数として計算してプロットします。

cumSnowsbyTime = squeeze(sum(snows,[1 2])) / (length(lats)*length(lons));

plot(sampTimes,cumSnowsbyTime)
xlabel("Date")
ylabel("Total Snow Cover (%)")
title("Total Snow Cover vs. Date")

Figure contains an axes object. The axes object with title Total Snow Cover vs. Date, xlabel Date, ylabel Total Snow Cover (%) contains an object of type line.

最大積雪の時間を求めてプロットします。

[maxSnowsbyTime,maxSnowsbyTimeInd] = max(cumSnowsbyTime);

h = heatmap(lons,lats,snows(:,:,maxSnowsbyTimeInd));
h.XLabel = "Longitude (°E)";
h.YLabel = "Latitude (°N)";
h.Title = "Percent Snow Cover vs. Location (" + sampTimeDisps(maxSnowsbyTimeInd) + ")";
h.XDisplayLabels = lonDisps;
h.YDisplayLabels = latDisps;
h.Colormap = winter;
h.GridVisible = "off";

Figure contains an object of type heatmap. The chart of type heatmap has title Percent Snow Cover vs. Location (Feb-1978).

最大積雪の月は 1978 年 2 月でした。

最大積雪の場所の計算

平均積雪を場所の関数として計算してプロットします。

cumSnowsbyLoc = sum(snows,3) / length(times);

h = heatmap(lons,lats,cumSnowsbyLoc);
h.XLabel = "Longitude (°E)";
h.YLabel = "Latitude (°N)";
h.Title = "Average Percent Snow Cover vs. Location";
h.XDisplayLabels = lonDisps;
h.YDisplayLabels = latDisps;
h.Colormap = winter;
h.GridVisible = "off";

Figure contains an object of type heatmap. The chart of type heatmap has title Average Percent Snow Cover vs. Location.

最大積雪の場所を求めてプロットします。

maxSnowsbyLocVal = max(cumSnowsbyLoc,[],"all");
maxSnowsbyLoc = maxSnowsbyLocVal*(cumSnowsbyLoc == maxSnowsbyLocVal);

h = heatmap(lons,lats,maxSnowsbyLoc);
h.XLabel = "Longitude (°E)";
h.YLabel = "Latitude (°N)";
h.Title = "Locations of Maximum Snow Cover";
h.XDisplayLabels = lonDisps;
h.YDisplayLabels = latDisps;
h.Colormap = winter;
h.GridVisible = "off";

Figure contains an object of type heatmap. The chart of type heatmap has title Locations of Maximum Snow Cover.

最大積雪の場所には、グリーンランドの大部分、およびスバールバル諸島とフランツ ヨシフ諸島の一部が含まれています。

著作権表示

北半球Ease-Grid積雪データ。NOAA PSL (米国コロラド州ボルダー) のウェブサイト https://psl.noaa.gov. から抜粋。

参考

関数

ライブ エディター タスク

関連するトピック

外部の Web サイト