在Matlab中为每个纬度/经度提取netCDF时间序列

时间:2013-05-13 12:28:14

标签: matlab netcdf

我目前正在处理气候模型的netCDF输出,并希望获得netCDF中每个纬度/经度组合的时间序列文本文件。例如,如果netCDF有10个纬度和10个经度,我将获得100个文本文件,每个文件具有列格式的时间序列。我对Matlab / netCDF语言非常熟悉,但我似乎无法理解这一点。命名文本文件并不重要;我将它们重命名为“latitude_longitude_PCP.txt”,其中PCP在纬度和经度位置处降水。

任何帮助将不胜感激。感谢。

- 达伦

2 个答案:

答案 0 :(得分:1)

有几种方法可以解决这个问题。

方法1.如果您能够将netcdf文件放在THREDDS数据服务器上,则可以使用NetCDF子集服务网格作为点来指定经度/纬度点并以CSV或XML格式返回数据。以下是Unidata的THREDDS数据服务器的示例:http://thredds.ucar.edu/thredds/ncss/grid/grib/NCEP/GFS/Global_0p5deg/best/pointDataset.html

方法2.如果您想使用Matlab在特定的经度/纬度位置提取时间序列,您可以使用NCTOOLBOX中的“nj_tseries”函数,可在以下位置获取:http://nctoolbox.github.io/nctoolbox/

方法3.如果你真的想使用Matlab在[time,lon,lat]网格中的每个i,j位置写一个ASCII时间序列,你可以做这样的事情(使用NCTOOLBOX):

url='http://thredds.ucar.edu/thredds/dodsC/grib/NCEP/GFS/Global_2p5deg/best';
nc = ncgeodataset(url);
nc.variables
var='Downward_Short-Wave_Radiation_Flux_surface_12_Hour_Average';
lon = nc.data('lon');
lat = nc.data('lat');
jd = nj_time(nc,var);
ncvar = nc.variable(var);
for j=1:length(lat)
    for i=1:length(lon)
        v=ncvar.data(:,j,i);
        outfile=sprintf('%6.2flon%6.2flat.csv',lon(i),lat(j))
        fid=fopen(outfile,'wt')
        data= [datevec(jd) v]
        fprintf(fid,'%2.2d %2.2d %2.2d %2.2d %2.2d %2.2d %7.2f\n',data')
        fclose(fid)
        disp([outfile ' created.'])
    end
end

如果你有足够的内存来将所有数据读入matlab,你可以在双循环之外读取,这会快得多。但是无论如何编写ASCII都很慢,所以它可能并不重要。

答案 1 :(得分:0)

%% Create demo data 
data = reshape(1:20*30*40,[20 30 40]);
nccreate('t.nc','data','Dimensions',{'lat', 20, 'lon',30, 'time', inf});
ncwrite('t.nc', 'data',data);
ncdisp('t.nc');

%% Write timeseries to ASCII files
% Giving an idea of the size of your data can help people 
% recommend different approaches tailored to the data size. 
% For smaller data, it might be faster to read in the full 
% 3D data into memory
varInfo = ncinfo('t.nc','data');
disp(varInfo);
for latInd =1:varInfo.Size(1)
    for lonInd =1:varInfo.Size(2)
        fileName = ['t_ascii_lat',num2str(latInd),'_lon',num2str(lonInd),'.txt'];
        tSeries  = ncread('t.nc','data',[latInd, lonInd, 1],[1,1,varInfo.Size(3)]);
        dlmwrite(fileName,squeeze(tSeries));
    end
end

%% spot check
act = dlmread('t_ascii_lat10_lon29.txt');
exp = squeeze(data(10,29,:));
assert(isequal(act,exp));