Source MatLab: http://ecco2.jpl.nasa.gov/data1/matlab/netcdf_toolbox/netcdf/@ncvar/resize.m

function theResult = resize(self, newSize)

% ncvar/resize - Resize variable dimensions.
% resize(self, newSize) resizes the dimensions of self,
% an "ncvar" object. All variables related to the
% changed dimensions are similarly affected. The
% newSize must have the same number of dimensions
% as the existing variable. The new self is returned.

% Copyright (C) 1998 Dr. Charles R. Denham, ZYDECO.
% All Rights Reserved.
% Disclosure without explicit written consent from the
% copyright owner does not constitute publication.

% Version of 03-Nov-1998 08:52:22.
% Updated 12-Aug-1999 09:42:01.

if nargin < 1, help(mfilename), return, end
if nargout > 0, theResult = self; end

% Check for no-change.

if isequal(ncsize(self), newSize)
result = self;
if nargout > 0
theResult = result;
else
ncans(result)
end
return
end

theItemName = name(self);

% Check for writeability.

f = parent(self);
thePermission = permission(f);
theSrcName = name(f);

if isequal(thePermission, 'nowrite')
disp([' ## NetCDF source file must be writeable.'])
return
end

% Check request.

d = dim(self);
for i = 1:length(d)
if \~isrecdim(d[i]) & newSize(i) <= 0
disp(\[' ## Dimension "' name(d[i]) '" size requires positive integer.'\])
return
end
end

% Create temporary file.

g = \[\];

i = 0;
while isempty(g)
i = i + 1;
theTmpName = ['tmp_' int2str(i) '.nc'|'tmp_' int2str(i) '.nc'];
if exist(theTmpName, 'file') \~= 2
g = netcdf(theTmpName, 'noclobber');
end
end

theTmpName = name(g);

% Copy affected dimensions first.

d = dim(self);
for i = 1:length(d)
if isrecdim(d[i])
g(name(d[i])) = 0;
elseif newSize(i) <= 0
error(\[' ## Dimension "' name(d[i]) '" requires positive integer.'\])
else
g(name(d[i])) = newSize(i) ;
end
end

% Copy other dimensions.

d = dim(f);
for i = 1:length(d)
g(name(d[i])) = ncsize(d[i]);
end

% Copy global attributes.

a = att(f);
for i = 1:length(a)
copy(a[i], g)
end

% Copy variable definitions and attributes.

v = var(f);
for i = 1:length(v)
copy(v[i], g, 0, 1)
end

% Copy variable data as minimal rectangular array.
% Note that the "()" operator is out-of-context
% inside this method, so we have to build our own
% calls to "ncvar/subsref" and "ncvar/subsasgn".
% It might be easier for us to use "virtual"
% variables instead, which could be transferred
% with the more intelligent "ncvar/copy" method.

v = var(f);
w = var(g);

for i = 1:length(v)
sv = ncsize(v[i]);
sw = ncsize(w[i]);
if \~isempty(sw)
d = dim(w[i]);
if isrecdim(d[1])
if sw(1) == 0
if isequal(name(d[1]), theItemName)
sw(1) = newSize;
else
sw(1) = sv(1);
end
end
end
end
theMinimalSize = min(sv, sw);
if prod(theMinimalSize) > 0
if isequal(sv, sw)
copy(v[i], g, 1)
else
theIndices = cell(size(theMinimalSize));
for j = 1:length(theIndices)
theIndices[j] = 1:theMinimalSize(j);
end
theStruct.type = '()';
theStruct.subs = theIndices;
theData = subsref(v[i], theStruct);
w[i] = subsasgn(w[i], theStruct, theData);
end
end
end

% Close both files.

f = close(f);
g = close(g);

{color:#ff0000}% Delete old file.{color}

{color:#ff0000}delete(theSrcName){color}

{color:#ff0000}% Rename new file to old file name.{color}

{color:#ff0000}fcopy(theTmpName, theSrcName){color}
{color:#ff0000}delete(theTmpName){color}

{color:#ff0000}% Open the new file.{color}

{color:#ff0000}g = netcdf(theSrcName, thePermission);{color}

% Return the resized variable.

result = g[theItemName];

if nargout > 0
theResult = result;
else
ncans(result)
end
  • No labels

3 Comments

  1. Unknown User (berg_p)

    Hi Alex,

    Can you add some descriptive text, because without some explanation/introduction this is greek to me.

    Paul

  2. Unknown User (alex)

    Hi Paul,

    Yep, you're right. We are trying to achieve some functionality about resizing grids (changing the resolution) using NetCdf.
    Because NetCdf is based on a fixed dimension (coordinates) we wondered if making a new file with a new fixed dimension and setting the values by copying/interpolating the old values will be the only way.

    The makers of MatLab also create a new file.

  3. Hi Paul, Alex,

    Chuck Denham isn't a maker of MATLAB, but he did a lot of work on e.g. supporting netCDF files from within MATLAB.
    The netCDF file contains a header with the dimension information and subsequently the data of the variables; the data of a variable is defined in one block (unless you have a dimension that can change in size).
    If you add a variable to a netCDF file, the header size will change and thus the contents of the whole file needs to be "shifted down" a couple of bytes.
    If you change the size of a variable, then the data block of that variable needs to grow. This also requires moving all the data blocks behind it.
    Hence in most cases you'll need to rewrite the whole file. This isn't an attractive solution if the file is big.
    As mentioned above netCDF allows for dimensions that can change (more precisely: that can grow in size), but that can be only one dimension per variable. This is generally used in simulations as the time dimension.
    The new HDF5 based implementation of netCDF4 does allow for multiple growing dimensions. This might be a solution for the (near) future.
    If you anticipate to resize an array frequently, you may consider overdimensioning an array in the netCDF file and incrementing the array size by a certain percentage at once instead of by a single value each time.