⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timenc.m

📁 matlacb程序包
💻 M
📖 第 1 页 / 共 2 页
字号:
function [gregorian_time, serial_time, gregorian_base, serial_base, ...	  sizem, serial_time_jd, serial_base_jd] = ...    timenc(file, time_var, bl_corner, tr_corner, calendar)% TIMENC   Returns time information for a file that meets COARDS standards.%% function [gregorian_time, serial_time, gregorian_base, serial_base, ...% 	  sizem, serial_time_jd, serial_base_jd] = ...%         timenc(file, time_var, bl_corner, tr_corner, calendar);%% DESCRIPTION:%% timenc finds the time vector and the corresponding base date for a% netcdf file or DODS/OPEnDAP dataset that meets COARDS standards. In% practice this means that time-like variable should have a units attribute% of a certain form. An example is:%      'seconds since 1992-10-8 15:15:42.5 -6:00'% This indicates seconds since October 8th, 1992 at 3 hours, 15% minutes and 42.5 seconds in the afternoon in the time zone% which is six hours to the west of Coordinated Universal Time% (i.e. Mountain Daylight Time). The time zone specification can% also be written without a colon using one or two-digits% (indicating hours) or three or four digits (indicating hours% and minutes).  Instead of 'seconds' the string may contain 'minutes',% 'hours', 'days' and 'weeks' and all of these may be singular or plural% and have capital first letters.  The letters 'UTC' or 'UT' are allowed at% the end of the string, but these are ignored.%% The parsing of the units attribute is done by the function PARSETNC. This% function can be called by itself to test that a string is sytactically% correct.%% It is possible to have many different types of calendars but timenc only% implements five at present. These are necessary because there is some% confusion with dates before October 15 1582 when the Gregorian calendar was% introduced. A problem also arises when the reference date in the units% attribute is before this. timenc deals with this by recognising some of the% CF conventions and returns different answers depending on the value of the% calendar attribute of the time-like variable. Also, some numerical models% like to pretend that every year has the same number of days - 365, 366 and% 360 are all used.%    1) calendar == 'standard', 'gregorian' (this is the default).% In this case the relevant calculations are done using the functions% get_calendar_date and get_julian_day which know about both the Julian and% Gregorian calendars and so work back to julian day 0 in the year% -4712. This means that the day after 4 October 1582 is 15 October 1582 as% decreed by Pope Gregory XIII. This is the calendar almost universally used% today and what udunits works with today. timenc has worked this way since% revision 1.10 in 2000.%    2) calendar == 'proleptic_gregorian'.% In this case the relevant calculations are done using the matlab functions% datenum and datevec which simply extend the way our present calendar works% backwards into the past. This follows international standard ISO 8601. This% means that dates are continuous, i.e., the day after 4 October 1582 is 5% October 1582, which does NOT correspond to historical time anywhere. As well% there is a year zero. timenc used to work this way before revision 1.10 in the% year 2000 and I believe that udunits also did at some stage in the past.%    3) calendar == 'noleap', '365_day'% Here it is assumed that every year has 365 days.%    4) calendar == 'all_leap', '366_day'% Here it is assumed that every year has 366 days.%    5) calendar == '360_day'% Here it is assumed that every year has 360 days and every month has 30 days.%% Note that other values of the calendar attribute produce an error% message. This can usually be avoided by the user specifying the calendar% explicitly in the call to timenc.%% INPUT:%  file may be the name of a netCDF file with or without the .cdf or .nc%    extent. file may also be the URL of a DODS/OPEnDAP dataset.% time_var: the name of the 'time' variable in the netCDF file or DODS/OPEnDAP%    dataset.  If this argument is missing then it is assumed that variable%    name is 'time'. If time_var is multi-dimensional then it will be handled%    as if it had been reshaped as one 'giant' vector.% bl_corner: a vector of length n specifying the hyperslab corner%    with the lowest index values (the bottom left-hand corner in a%    2-space).  The corners refer to the dimensions in the same%    order that these dimensions are listed in the relevant questions%    in getnc.m and in the inqnc.m description of the variable.  A%    negative element means that all values in that direction will be%    returned.  If this argument is missing or a negative scalar or empty%    array is used this means that all of the elements in the array will be%    returned.%  tr_corner is a vector of length n specifying the hyperslab corner%    with the highest index values (the top right-hand corner in a%    2-space).  The corners refer to the dimensions in the same order%    that these dimensions are listed in the relevant questions in%    getnc.m and in the inqnc.m description of the variable. A negative%    element means that the returned hyperslab should run to the highest%    possible index. Note, however, that the value of an element in the%    tr_corner vector will be ignored if the corresponding element in the%    corner vector is negative.%  calendar is a string determining the type of calendar to be used and is%    discussed above.%% OUTPUT:% gregorian_time: an Mx6 matrix where the rows refer to the M times%    specified in the 'time' variable in the netCDF file.  The columns%    are the year, month, day, hour, minute, second in that order, UT.% serial_time: an M vector giving the serial times (in UT) specified in the%    'time' variable in the netCDF file. Serial times are used by datestr,%    datevec & datenum. Thus gregorian_time = datevec(serial_time). Note that%    the 'time' variable actually contains the serial time relative to a%    base time.% gregorian_base: a 6-vector giving the year, month, day, hour, minute,%    second of the base time as specified in the 'units' attribute of%    the 'time' variable. This is in UT.% serial_base: the serial time of the base time, in UT, as determined by%    matlab's datenum function. Thus gregorian_base = datevec(serial_base).%    serial_base will be a NaN for times before October 15 1582, when the%    Gregorian calendar was adopted, since datenum is not meaningful in this%    case.% sizem: the size of the 'time' variable in the netCDF file.% serial_time_jd: an M vector giving the julian day number (in UT) specified%    in the 'time' variable in the netCDF file. (julian day numbers are used%    by get_julian_day and get_calendar_date. Thus gregorian_time =%    get_calendar_date(serial_time_jd).% serial_base_jd: the Julian day number of the base time, in UT, as%    determined by get_julian_day. Thus gregorian_base =%    get_calendar_date(serial_base_jd).%% EXAMPLES:%       1)%   [gregorian_time, serial_time] = timenc('file.nc', 't');%% This gives you the time information in gregorian and 'matlab' serial% time for a netcdf file named file.nc containing a time variable t.%%       2)%   [gregorian_time, serial_time] = timenc('file.nc', 't', 3, 8);%% This gives you the time information in gregorian and 'matlab' serial% time for elements 3 to 8 of the time variable t.%%       3)%   [gregorian_time, serial_time] = timenc('file.nc', 't', -1, -1, 'gregorian');%% The use of the 5th (calendar) input allows you to override the calendar% attribute in the original netcdf file. This attribute may be invalid or% simply not supported by timenc.%%     Copyright J. V. Mansbridge, CSIRO, Tue May  9 11:36:06 EST 1995%     (with the ability to handle a multi-dimensional time variable%     added by Rose O'Connor).% This function calls: check_nc.m, get_calendar_date.m, loaddap or%                      loaddods, mexnc, parsetnc.m, pos_cds.m%$Id: timenc.m Mon, Wed Nov 29 16:35:09 EDT 2006 $% Process the input argumentsif ~ismember(nargin , [1 2 4 5])  error('timenc takes either 1, 2, 4 or 5 input arguments (try "help timenc")')endif nargin == 1  time_var = 'time';endif nargin <= 2  get_all = 1;elseif nargin >= 4  if isempty(bl_corner) | isempty(tr_corner)    get_all = 1;  else    if (bl_corner < 1)      get_all = 1;    else      get_all = 0;    end  endendif nargin < 5  calendar = [];end% Do some initialisation.CSIRO_add_jar_file_maybe;[mex_name, full_name, desc_das, file_status, exe_name] = ...    choose_mexnc_opendap(file);% We also use method_of_call == 2 which, according to the documentation, does% the same thing as method_of_call == 1 but would be expected to be% slower. However, this is necessary for loaddods to work properly on Windows% boxes when an array is filled with characters. I have no idea what the bug% might be in loaddods. There is also a hint that the same problem can occur% with loaddap on some linux boxes.  method_of_call = 2;switch mex_name case 'mexnc'    %Open the netcdf file.  [cdfid, rcode] = mexnc('OPEN', full_name, 'NC_NOWRITE');  if rcode == -1    error(['** ERROR ** ncopen: rcode = ' num2str(rcode)])  end  %Suppress all error messages from netCDF   [rcode] = mexnc('setopts', 0);  %Get the id number of the variable 'time' and find out the info. about  %the variable 'time'.  [varid, rcode] = mexnc('varid', cdfid, time_var);  if rcode == -1    error(['** ERROR ** ncvarid: time variable = ''' time_var ''' not found'])  end  if get_all == 1    [varnam, vartypv, nvdims, vdims, nvatts, rcode] = ...	mexnc('ncvarinq', cdfid, varid);    if rcode == -1      error(['** ERROR ** ncvarinq: rcode = ' num2str(rcode) ...	     ', time variable = ''' time_var ''''])    end        %Find out the size of the dimension 'time' which is the same as the    %variable 'time'.    %[name, sizem, rcode] = mexnc('ncdiminq', cdfid, vdims(1));    %ROC    sizem = zeros(1,nvdims);    st    = zeros(1,nvdims);    for i = 1:nvdims      [name, sizem(i), rcode] = mexnc('ncdiminq', cdfid, vdims(i));      if rcode == -1	error(['** ERROR ** ncdiminq: rcode = ' num2str(rcode)])      end    end        %Retrieve the elements of the variable 'time'.  These are the serial day    %relative to the base date.    if any(sizem == 0)      serial_rel = []; % Presumably time is an unlimited dimension of length 0.      disp(['Warning: There are apparently no ''time'' records'])    else      %[serial_rel, rcode] = mexnc('ncvarget', cdfid, varid, 0, sizem);      [serial_rel, rcode] = mexnc('ncvarget', cdfid, varid, st, sizem);      if rcode == -1	error(['** ERROR ** ncvarget: rcode = ' num2str(rcode)])      end    end  else    [varnam, vartypv, nvdims, vdims, nvatts, rcode] = ...	mexnc('ncvarinq', cdfid, varid);    if rcode == -1      error(['** ERROR ** ncvarinq: rcode = ' num2str(rcode) ...	     ', time variable = ''' time_var ''''])    end        sizem = zeros(1,nvdims);    for i = 1:nvdims      [name, sizem(i), rcode] = mexnc('ncdiminq', cdfid, vdims(i));      if rcode == -1	error(['** ERROR ** ncdiminq: rcode = ' num2str(rcode)])      end      if tr_corner(i) < 0	tr_corner(i) = sizem(i);      end    end        if any(sizem == 0)      serial_rel = []; % Presumably time is an unlimited dimension of length 0.      disp(['Warning: There are apparently no ''time'' records'])    elseif any(bl_corner < 1)      error('bl_corner values are too small')    elseif any(tr_corner > sizem)      error('tr_corner values are too large')    else      [serial_rel, rcode] = mexnc('ncvarget', cdfid, varid, ...				  bl_corner-1, tr_corner-bl_corner+1);      if rcode == -1	error(['** ERROR ** ncvarget: rcode = ' num2str(rcode)])      end    end  end  %Get the string describing the base date.  [base_str, rcode] = mexnc('attget', cdfid, varid, 'units');  if rcode == -1    error(['** ERROR ** ncattget: rcode = ' num2str(rcode)])  end  %Close the netcdf file.  [rcode] = mexnc('ncclose', cdfid);  if rcode == -1    error(['** ERROR ** ncclose: rcode = ' num2str(rcode)])  end   case {'loaddap', 'loaddods'}  % Dealing with a DODS file.    % Check the value of time_var.   if ischar(time_var)    if ~isfield(desc_das, time_var)      error([time_var ' is not a variable in ' full_name])    end  else    error('For dods data varid must be a string')  end    % Get the structure of time_var and then use this to extract required  % information about attributes. We also strip off extraneous quote marks.    %desc_varid = desc_das.(time_var);  desc_varid = getfield(desc_das, time_var);  if isfield(desc_varid, 'units')    %base_str = desc_varid.('units');    base_str = getfield(desc_varid, 'units');    if ischar(base_str)      base_str = base_str(2:(end - 1));    else      error(['The units attribute of ' time_var ' is not a string'])    end  else    error([time_var ' does not have a units attribute']);  end  if isfield(desc_varid, 'DODS_ML_Size')    %sizem = desc_varid.('DODS_ML_Size');    sizem = getfield(desc_varid, 'DODS_ML_Size');  else    %xx = desc_varid.(time_var);    xx = getfield(desc_varid, time_var);    %sizem = xx.('DODS_ML_Size');    sizem = getfield(xx, 'DODS_ML_Size');  end  num_dim = length(sizem);  % Get the time vector. Note that we allow for the vector of variable values  % to be at different "depths" in the structure. It seems that a variable  % that is also a dimension will be at values_struct.time but otherwise it  % will be at values_struct.time.time.    if get_all    switch method_of_call     case 1      switch mex_name       case 'loaddap'	values_struct = loaddap('+v', [full_name '?' time_var]);       case 'loaddods'	values_struct = loaddods('+v', [full_name '?' time_var]);      end     case 2      switch mex_name       case 'loaddap'	loaddap('+v', [full_name '?' time_var]);       case 'loaddods'	loaddods('+v', [full_name '?' time_var]);      end      eval(['values_struct = ' time_var ';'])    end  else    str_h = [];    for ii = 1:num_dim

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -