Как открыть netCDF файл в MATLAB

В данной заметке я покажу два способа открыть NetCDF-файл в MATLAB, один способ более продвинутый и более сложный, а второй более простой. 

Несколько лет назад брат написал статью в своём блоге koldunov.net, где показал, как открыть в MATLAB файлы формата netCDF.

Он использовал функцию netcdf и всю процедуру необходимо было выполнять в несколько шагов. Не буду полностью повторять его статью, но вкратце напомню примерный порядок действий.

Для начала нужно открыть netCDF файл, в результате чего в переменную ncid будет записано число, которое будет являеться неким идентификатором, при помощи которого мы сможем вдальнейшем обращаться к нашему файлу:

ncid = netcdf.open('temperature_and_salinity_2018.nc','NC_NOWRITE');

Зная название (информацию о файле можно получить при помощи функции ncdisp) нужной вам переменной (например, температуры) внутри netCDF-файла, определить её ID (который на самом деле является просто порядковым номером переменной внутри файла; счёт начинается с нуля)

varid = netcdf.inqVarID(ncid,'temperature')
varid =

     3

Затем выудить по полученному ID данные для нужной нам характеристики:

data = netcdf.getVar(ncid,3);

Вот и всё, мы открыли наши данные. Но этих процедур часто бывает недостаточно, потому как для уменьшения размеров netCDF файлов прибегают к различного рода хитростям, например приводят все данные к целочисленным значениям и вычитают какое-нибудь число, если все данные больше этого самого числа.

Кроме того, пропущенные значения заполнены каким-нибудь большим числом, типа -9999 (для работы это не годится, нужно заменить на NaN). Поэтому необходимо ещё выудить из нашего файла следующие атрибуты переменной "temperature":

add_off = netcdf.getAtt(ncid,3,'add_offset')
scale_factor  = netcdf.getAtt(ncid,3,'scale_factor')
fillvalue  = netcdf.getAtt(ncid,3,'_FillValue')

После чего привести данные к виду, с которым нам уже можно будет работать:

data_single = single(data);
data_single (data_single == fillvalue) = NaN;
data_scaled = (data_single*scale_factor)+add_off;

В файлах netDCF атрибуты могут быть не только у переменных, бывает необходимо получить значение глобальной переменной, запись при этом следующая:

sart_date = netcdf.getAtt(ncid,netcdf.getConstant('NC_GLOBAL'),'sart_date');

Как вы скоро поймёте, это был сложный вариант для продвинутых пользователей. Функция netcdf имеет ещё много настроек, однако для человека, желающего открыть файл с данными, столь муторная процедура кажется странной, ведь большинство манипуляций можно было бы автоматизировать. Так и есть, встречайте, функция ncread.

Эта функция, насколько мне известно, впервые появилась в том же 2011 году, в котором брат писал свою заметку. Но несмотря на введение этой функции, ещё долгое время в поисковых системах, а также в поиске по хэлпу Матлаба предлагался именно тот вариант работы с netCDF, который мы рассмотрели выше. И это не говоря о русскоязычных ресурсах, где вообще мало информации о работе с netCDF и вообще оеканологическими данными.

Итак, если мы напишем в командной строке

data  = ncread('temperature_and_salinity_2018.nc', 'temperature');

то произойдёт несколько вещей: откроется наш netCDF файл, оттуда загрузится переменная "temperature", все пропущенные значения (_FillValue) заменятся на NaN, данные умножатся на scale_factor и к ним будет прибавлен add_offset. Результат будет записан в переменную data. Вот так просто и без лишних хлопот.

Если вам всё-таки необходимо заполучить какие-то атрибуты, то делается это при помощи функции ncreadatt:

scale_factor = ncreadatt('temperature_and_salinity_2018.nc','temperature','scale_factor);

Если же вам нужен глобальный атрибут, то:

sart_date = ncreadatt('temperature_and_salinity_2018.nc',' /', 'sart_date');
 telegram

Чтобы не пропустить новые материалы, подпишитесь на канал в Telegram: https://t.me/koldunovaleksey