EXTRACTING NETCDF DATA BASED ON TIME
古いコメントを表示
Good afternoon:
I am operating on a NetCDF file that contains data for 20 variables over a period of 8 months. This is too much data, so I am trying to extract data based on the time of day. That is, to extract data for all variables from 11pm to 4am for each day in the data file. I have been able to pull out the date / time in the format "dd-mmm-yyyy hh:mm:ss". I can extract and work on ranges of time, but not a range of time per day, for many days.
I can see in my head how to do this, but I am unsure of an efficient way to code it. Experimenting with different time functions, (datenum,hours, datetime, datevec) with other structure and NetCDF tools have been unsucessful. I could use a shove in the right direction. Thank you.
採用された回答
その他の回答 (2 件)
Tanziha Mahjabin
2020 年 1 月 29 日
編集済み: Walter Roberson
2020 年 1 月 29 日
Hi,
I want to cut some time from a bid data, using ncread(source,varname,start,count).
for your information,
UCUR_sd
Size: 69x69x45588
Dimensions: J,I,TIME
Datatype: single
Attributes:
long_name = 'Standard deviation of sea water velocity U component values in 1 hour.'
units = 'm s-1'
valid_min = -10
valid_max = 10
cell_methods = 'TIME: standard_deviation'
coordinates = 'TIME LATITUDE LONGITUDE'
_FillValue = 999999
ancillary_variables = 'NOBS1 NOBS2 UCUR_quality_control'
Now if i write,
u=ncread(ncfile,'UCUR',[1 1 1],[Inf Inf 44931]);
it takes the command as the start time is from the start.
But what should i write if i want cut the time from somewhere middle?
I tried to define index,
ind=find(time>=datenum(2017,02,16,0,0,0)&time<=datenum(2017,02,17,0,0,0))
u=ncread(ncfile,'UCUR',[1 1 ind],[Inf Inf 44931]);
But it is not working. Any helpful suggestion please.
1 件のコメント
Walter Roberson
2020 年 1 月 29 日
netcdf times are never in MATLAB serial datenum . Instead they are in some time units relative to a particular epoch that is defined in the attributes, such as "seconds since Jul 1, 1983 00:00:00 UTC" . You need to examine the attributes for the TIME coordinate and do the conversion.
Tanziha Mahjabin
2020 年 1 月 30 日
Hi Walter,
Thanks for the comment. I did the conversion.
ncfile='IMOS_aggregation_20200124T074252Z.nc';
rtime=ncread(ncfile,'TIME');
time=datenum(rtime+datenum(1950,1,1,0,0,0));
When i write something like this, ru=ncread(ncfile,'UCUR',[1 1 1],[Inf Inf 931]); it works as the time starts from the beginning.
But i want to start the time from somewhere else as i mentioned in my question. So i defined index and try to start according to that.
ind=find(time>=datenum(2017,02,16,0,0,0)&time<=datenum(2017,02,17,0,0,0))
u=ncread(ncfile,'UCUR',[1 1 ind],[Inf Inf 44931]);
It didn't work.
8 件のコメント
Walter Roberson
2020 年 1 月 30 日
Is the time in the file days since that particular date? Not impossible for netcdf but tends to be a different time unit.
Tanziha Mahjabin
2020 年 1 月 30 日
no, it is hourly average.
Walter Roberson
2020 年 1 月 30 日
You coded
time=datenum(rtime+datenum(1950,1,1,0,0,0));
When you used datenum(1950,1,1,0,0,0) you would have gotten back a MATLAB serial date number, which would be in full days since Jan 1 0000 . When you add rtime to that, you are adding rtime days, so for example 27 would be 27 days after the base time, not 27 hours. You would have to use
time=datenum(rtime/24+datenum(1950,1,1,0,0,0));
However, unless you have special reason otherwise, I would recommend that you switch to using datetime objects:
time = datetime(1950,1,1,0,0,0)) + hours(rtime);
ind = isbetween(time, datetime(2017,02,16,0,0,0), datetime(2017,02,17,0,0,0));
Tanziha Mahjabin
2020 年 1 月 30 日
Sorry to bother you again. i tried both, but they didn't work. they are giving empty matrix for ind.
I guess because they are already hourly values.
If i write according to my code, ind=find(time>=datenum(2017,02,16,0,0,0)&time<=datenum(2017,02,17,0,0,0))
it gives me the correct count numbers during 16Feb2017 to 17Feb2017.
only it doesn't work when i input it in this line:
u=ncread(ncfile,'UCUR',[1 1 ind],[Inf Inf 44931]);
Walter Roberson
2020 年 1 月 30 日
ncread cannot read selected indices from an array, except that it can read a consecutive subsection.
mask = time>=datenum(2017,02,16,0,0,0) & time<=datenum(2017,02,17,0,0,0);
firstind = find(mask,1,'first');
lastind = find(mask,1,'last');
reduced_mask = mask(firstind:lastind);
most_u = ncread(ncfile,'UCUR',[1 1 firstind],[Inf Inf lastind-firstind+1]);
u = most_u(:,:,reduced_mask);
In the special case that time is sorted, the true entries in mask would be consecutive and the result of ncread could be used without further subselection.
mask = time>=datenum(2017,02,16,0,0,0) & time<=datenum(2017,02,17,0,0,0);
firstind = find(mask,1,'first');
lastind = find(mask,1,'last');
u = ncread(ncfile,'UCUR',[1 1 firstind],[Inf Inf lastind-firstind+1]);
Tanziha Mahjabin
2020 年 1 月 30 日
編集済み: Walter Roberson
2022 年 10 月 24 日
I did manage to do it. Thank you for your time.
ncfile='IMOS_aggregation_20200124T074252Z.nc';
time=ncread(ncfile,'TIME');
begin = datenum('01 January 1950 00:00:00');
time=time+begin;
date_start=datestr(time(1));
date_end=datestr(time(end));
t0=find((datenum('16 February 2017 00:00:00'))==time);
t1=find((datenum('16 February 2017 23:00:00'))==time);
mtime=time(t0:t1);
date=datestr(mtime);
coo=0; nt=length(mtime);
for i=1:nt;
coo=coo+1;
% get each hours data
rtime=datenum(mtime(i));
[y m d hr min sec]=datevec(rtime);
start=datenum(y,m,d,hr,0,0);
ru=single(ncread(ncfile,'UCUR',[1 1 t0-1],[Inf Inf nt]));
Walter Roberson
2020 年 1 月 30 日
I don't think you want that read inside a for loop??
Mehak S
2024 年 4 月 8 日
Why 't0-1' and not t0 while reading the file?
カテゴリ
ヘルプ センター および File Exchange で Standard File Formats についてさらに検索
製品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!