getnc_s.m

来自「读取Network Common Data Form (netCDF)数据」· M 代码 · 共 1,042 行 · 第 1/3 页

M
1,042
字号
  error(['** ERROR ** ncvarinq: rcode = ' num2str(rcode)])end% Turn off the rescaling of the byte type data because ncmex does not do this% for variables anyway. The rescaling of the VALUES array will be done% explicitly.if vartypv == nc_byte  rescale_var = 0;  rescale_att = 0;end% Do checks on corner, end_point, stride and order.% If there were 2 input arguments then set the values of corner, end_point% and stride to their default values.  If there were 4 input arguments% then set the value of stride to its default value.  Otherwise, check% that the last input arguments are acceptable.  Also set take_stride% which specifies whether strides need to be taken.  The cases where% corner, end_point and stride are -1 or -1*ones(nvdims, 1) are checked% for and handled here.  Note that stride may also be a scalar 1 when a% vector may seem to be required.  Finally check that the value of order is% acceptable.if nvdims == 0  corner = 1;  end_point = 1;  stride = 1;else  if nargin == 2    corner = ones(nvdims, 1);    end_point = -1*ones(nvdims, 1);    stride = ones(nvdims, 1);  elseif nargin == 4    if length(corner) == 1      if corner < 0	corner = ones(nvdims, 1);        end_point = -1*ones(nvdims, 1);      end    elseif length(corner) ~= nvdims      error('The corner vector is the wrong length')    end    stride = ones(nvdims, 1);    if (sum(abs(size(corner) - size(end_point)))) ~= 0      error('The sizes of corner and end_point do not agree')    end  else    if length(corner) == 1      if corner < 0	corner = ones(nvdims, 1);        end_point = -1*ones(nvdims, 1);      end    elseif length(corner) ~= nvdims      error('The corner vector is the wrong length')    end      if length(stride) == 1      if stride < 0 | stride == 1	stride = ones(nvdims, 1);      end    elseif length(stride) ~= nvdims      error('The stride vector is the wrong length')    end  endendcorner_min = min(size(corner));corner_max = max(size(corner));end_point_min = min(size(end_point));end_point_max = max(size(end_point));stride_min = min(size(stride));stride_max = max(size(stride));if corner_min ~= end_point_min | corner_min ~= stride_min | ...		 corner_max ~= end_point_max | corner_max ~= stride_max  error('The sizes of corner, end_point and stride do not agree')end% Set take_stride.if max(stride) > 1  take_stride = 1;else  take_stride = 0;end% Make corner, end_point, stride and order into column vectors.corner = corner(:);end_point = end_point(:);stride = stride(:);order = order(:);% Check orderif length(order) == 1  if order == 1 % Special case where the netcdf variable is a vector    order = -1;  elseif order ~= -1 & order ~= -2    error('ERROR: if order is a scalar it must be -1 or -2')  endelse  if length(order) ~= nvdims    error('The order vector is the wrong length')  elseif sum(abs(sort(order) - (1:nvdims)')) ~= 0    error(['The order vector must be a rearrangement of the numbers 1 to ' ...	  num2str(nvdims)])  endend% Check the values of change_miss, new_miss and squeeze_it.if length(change_miss) ~= 1  error('ERROR: change_miss must be a scalar')endif all ( change_miss ~= [ 1 2 3 ] )  if change_miss < 0    change_miss = 2;  else   error([ 'getnc_s was passed change_miss = ' int2str(change_miss) ]) endendif length(new_miss) ~= 1  error('ERROR: new_miss must be a scalar')end  if length(squeeze_it) ~= 1  error('ERROR: squeeze_it must be a scalar')endif any ( ~isreal(squeeze_it) )   error([ 'getnc_s was passed squeeze_it = ' num2str(squeeze_it) ])end       % Find out whether to return a scalar, vector or matrix.  It is here% that corner is decremented and edge is calculated so that the c-style% conventions in ncmex will be followed.if nvdims == 0  edge = 1;else  edge = ones(nvdims, 1);  for i = 1:nvdims    dimid = vdims(i);    [name, sizem, rcode] = ncmex('ncdiminq', cdfid, dimid);    if rcode == -1      error(['** ERROR ** ncdiminq: rcode = ' num2str(rcode)])    end    if ( corner(i) < 0 |  end_point(i) < 0 )      corner(i) = 0;      edge(i) = sizem;    else      % Check that corner & end_point are in the correct range.  If they      % are then calculate edge.  Note that because I am using the      % matlab & fortran conventions for counting indices I must      % subtract 1 from the corner and end point values.          corner(i) = corner(i) - 1;      end_point(i) = end_point(i) - 1;      if corner(i) >= sizem | end_point(i) < 0 | end_point(i) >= sizem	s = [ 'getnc_s was passed corner = ' int2str(corner(i)+1) ...	      ' & end_point = ' int2str(end_point(i)+1) ...	      ' for dimension ' name ];	error(s)      end      if stride(i) > 1	edge(i) = fix( ( end_point(i) - corner(i) )/stride(i) ) + 1;      else	edge(i) = end_point(i) - corner(i) + 1;      end    end  endendnum_edge = length( find(edge ~= 1) );if num_edge == 0  % Get the scalar.  [values, rcode] = ncmex('ncvarget1', cdfid, varid, corner, rescale_var);  if rcode == -1    error(['** ERROR ** ncvarget1: rcode = ' num2str(rcode)])  end    % Do possible byte correction.    if vartypv == nc_byte    ff = find(values > 127);    if ~isempty(ff)      values(ff) = values(ff) - 256;    end  endelse  % Get the full hyperslab and return it as an array of the appropriate  % dimensions.  Note that we must allow for the C-type notation where  % the fastest changing index is the last mentioned.  if take_stride    [values, rcode] = ncmex('ncvargetg', cdfid, varid, corner, edge, stride, imap, rescale_var);    if rcode == -1      error(['** ERROR ** ncvargetg: rcode = ' num2str(rcode)])    end  else    [values, rcode] = ncmex('ncvarget', cdfid, varid, corner, edge, rescale_var);    if rcode == -1      error(['** ERROR ** ncvarget: rcode = ' num2str(rcode)])    end  end    % Do possible byte correction.    if vartypv == nc_byte    ff = find(values > 127);    if ~isempty(ff)      values(ff) = values(ff) - 256;    end  end  % Permute the array as required.  Note that the default behaviour is to  % reverse the order of the indices to map between the matlab and C  % conventions for ordering indices.     if order == -1    values = permute(values, (ndims(values):-1:1));  elseif order ~= -2    values = permute(values, (ndims(values):-1:1));    values = permute(values, order);  end     % Squeeze the array if required.     if squeeze_it ~= 0    values = squeeze(values);  end  % After squeezing a vector may be a row or column vector and so  % turn any row vector into a column vector for consistency.     if ndims(values) == 2    [m_temp, n_temp] = size(values);    if m_temp == 1      values = values(:);    end  endend% If the missing values are to be replaced then do it here.scalef = [];addoff = [];if change_miss ~= 1  % Find any scale factors or offsets.  attstring = fill_att(cdfid, varid, nvatts);  if rescale_att == 1 | vartypv == nc_byte    pos = check_st('scale_factor', attstring, nvatts);    if pos > 0      [scalef, rcode] = ncmex('attget', cdfid, varid, 'scale_factor');      if rcode == -1	error(['** ERROR ** ncattget: rcode = ' num2str(rcode)])      end    end    pos = check_st('add_offset', attstring, nvatts);    if pos > 0      [addoff, rcode] = ncmex('attget', cdfid, varid, 'add_offset');      if rcode == -1	error(['** ERROR ** ncattget: rcode = ' num2str(rcode)])      end    end  end  % check for missing values.  Note that a  % missing value is taken to be one less than valid_min, greater than  % valid_max or 'close to' _FillValue or missing_value.  % Note 1: valid_min and valid_max may be specified by the attribute  % valid_range and if valid_range exists than the existence of  % valid_min and valid_max is not checked.  % Note 2: a missing value must be OUTSIDE the valid range to be  % recognised.  % Note 3: a range does not make sense for character arrays.  % Note 4: By 'close to' _FillValue I mean that an integer or character  % must equal _FillValue and a real must be in the range  % 0.99999*_FillValue tp 1.00001*_FillValue.  This allows real*8   % rounding errors in moving the data from the netcdf file to matlab;  % these errors do occur although I don't know why given that matlab  % works in double precision.  % Note 5: An earlier version of this software checked for an attribute  % named missing_value.  This check was taken out because,  % although in common use, missing_value was not given in the netCDF  % manual list of attribute conventions.  Since it has now appeared in  % the netCDF manual I have put the check back in.    % The indices of the data points containing missing value indicators  % will be stored separately in index_miss_low, index_miss_up,   % index_missing_value and index__FillValue.    index_miss_low = [];  index_miss_up = [];  index__FillValue = [];  index_missing_value = [];  miss_low_orig = [];  miss_up_orig = [];  fill_value_orig = [];    % First find the indices of the data points that are outside the valid  % range.    pos_vr = check_st('valid_range', attstring, nvatts);  if pos_vr > 0    [attype, attlen, rcode] = ncmex('ncattinq', cdfid, varid, 'valid_range');    if rcode == -1      error(['** ERROR ** ncattinq: rcode = ' num2str(rcode)])    end    [ miss, rcode] = ncmex('ncattget', cdfid, varid, 'valid_range');    if rcode == -1      error(['** ERROR ** ncattget: rcode = ' num2str(rcode)])    end          % Check that valid_range is a 2 element vector.        if length(miss) ~= 2      error(['The valid_range attribute must be a vector'])    end        % Correct for possible faulty handling of byte type        if attype == nc_byte      if miss(1) > 127; miss(1) = miss(1) - 256; end      if miss(2) > 127; miss(2) = miss(2) - 256; end    end    miss_low = miss(1);    miss_up = miss(2);    miss_low_orig = miss_low;    miss_up_orig = miss_up;        % Rescale & add offsets if required.        if rescale_att == 1      if isempty(scalef) == 0	miss_low = miss_low*scalef;	miss_up = miss_up*scalef;      end      if isempty(addoff) == 0	miss_low = miss_low + addoff;

⌨️ 快捷键说明

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