1## Copyright (C) 2013 Alexander Barth 2## 3## This program is free software; you can redistribute it and/or modify 4## it under the terms of the GNU General Public License as published by 5## the Free Software Foundation; either version 2 of the License, or 6## (at your option) any later version. 7## 8## This program is distributed in the hope that it will be useful, 9## but WITHOUT ANY WARRANTY; without even the implied warranty of 10## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11## GNU General Public License for more details. 12## 13## You should have received a copy of the GNU General Public License 14## along with this program; If not, see <http://www.gnu.org/licenses/>. 15 16## -*- texinfo -*- 17## @deftypefn {Function File} {@var{info} =} ncinfo (@var{filename}) 18## @deftypefnx {Function File} {@var{info} =} ncinfo (@var{filename}, @var{varname}) 19## @deftypefnx {Function File} {@var{info} =} ncinfo (@var{filename}, @var{groupname}) 20## return information about an entire NetCDF file @var{filename} (i.e. the root 21## group "/"), about the variable called @var{varname} or the group called 22## @var{groupname}. 23## 24## The structure @var{info} has always the following fields: 25## @itemize 26## @item @var{Filename}: the name of the NetCDF file 27## @item @var{Format}: one of the strings "CLASSIC", "64BIT", "NETCDF4" 28## or "NETCDF4_CLASSIC" 29## @end itemize 30## 31## The structure @var{info} has additional fields depending on wether a 32## group of variable is queried. 33## 34## Groups 35## 36## Groups are returned as an array structure with the following fields: 37## 38## @itemize 39## @item @var{Name}: the group name. The root group is named "/". 40## @item @var{Dimensions}: a array structure with the dimensions. 41## @item @var{Variables}: a array structure with the variables. 42## @item @var{Attributes}: a array structure with global attributes. 43## @item @var{Groups}: a array structure (one for each group) with the 44## same fields as this structure. 45## @end itemize 46## 47## Dimensions 48## 49## Dimensions are returned as an array structure with the following fields: 50## @itemize 51## @item @var{Name}: the name of the dimension 52## @item @var{Length}: the length of the dimension 53## @item @var{Unlimited}: true of the dimension has no fixed limited, false 54## @end itemize 55## 56## Variables 57## 58## Variables are returned as an array structure with the following fields: 59## @itemize 60## @item @var{Name}: the name of the dimension 61## @item @var{Dimensions}: array structure of all dimensions of this variable 62## with the same structure as above. 63## @item @var{Size}: array with the size of the variable 64## @item @var{Datatype}: string with the corresponding octave data-type 65## (see below) 66## @item @var{Attributes}: a array structure of attributes 67## @item @var{FillValue}: the NetCDF fill value of the variable. If the fill 68## value is not defined, then this attribute is an empty array ([]). 69## @item @var{DeflateLevel}: the NetCDF deflate level between 0 (no 70## compression) and 9 (maximum compression). 71## @item @var{Shuffle}: is true if the shuffle filter is activated to improve 72## compression, otherwise false. 73## @item @var{CheckSum}: is set to "fletcher32", if check-sums are used, 74# otherwise this field is not defined. 75## @end itemize 76## 77## Attributes 78## 79## Attributes are returned as an array structure with the following fields: 80## @itemize 81## @item @var{Name}: the name of the attribute 82## @item @var{Value}: the value of the attribute (with the corresponding type) 83## @item @var{Unlimited}: true of the dimension has no fixed limited, false 84## @end itemize 85## 86## Data-types 87## 88## The following the the correspondence between the Octave and NetCDF 89## data-types: 90## 91## @multitable @columnfractions .5 .5 92## @headitem Octave type @tab NetCDF type 93## @item @code{int8} @tab @code{NC_BYTE} 94## @item @code{uint8} @tab @code{NC_UBYTE} 95## @item @code{int16} @tab @code{NC_SHORT} 96## @item @code{uint16} @tab @code{NC_USHORT} 97## @item @code{int32} @tab @code{NC_INT} 98## @item @code{uint32} @tab @code{NC_UINT} 99## @item @code{int64} @tab @code{NC_INT64} 100## @item @code{uint64} @tab @code{NC_UINT64} 101## @item @code{single} @tab @code{NC_FLOAT} 102## @item @code{double} @tab @code{NC_DOUBLE} 103## @item @code{char} @tab @code{NC_CHAR} 104## @end multitable 105## 106## The output of @code{ncinfo} can be used to create a NetCDF file with the same 107## meta-data using @code{ncwriteschema}. 108## 109## Note: If there are no attributes (or variable or groups), the corresponding 110## field is an empty matrix and not an empty struct array for compability 111## with matlab. 112## 113## @seealso{ncread,nccreate,ncwriteschema,ncdisp} 114## 115## @end deftypefn 116 117function info = ncinfo(filename,name) 118 119ncid = netcdf_open(filename,"NC_NOWRITE"); 120info.Filename = filename; 121 122if nargin == 1 123 name = "/"; 124endif 125 126[gid,varid] = ncloc(ncid,name); 127 128if isempty(varid) 129 info = ncinfo_group(info,gid); 130else 131 unlimdimIDs = netcdf_inqUnlimDims(gid); 132 info = ncinfo_var(info,gid,varid,unlimdimIDs); 133endif 134 135# NetCDF format 136ncformat = netcdf_inqFormat(ncid); 137info.Format = lower(strrep(ncformat,'FORMAT_','')); 138 139netcdf_close(ncid); 140endfunction 141 142function dims = ncinfo_dim(ncid,dimids,unlimdimIDs) 143 144dims = []; 145for i=1:length(dimids) 146 tmp = struct(); 147 148 [tmp.Name, tmp.Length] = netcdf_inqDim(ncid,dimids(i)); 149 tmp.Unlimited = any(unlimdimIDs == dimids(i)); 150 151 if isempty(dims) 152 dims = [tmp]; 153 else 154 dims(i) = tmp; 155 endif 156endfor 157endfunction 158 159 160function vinfo = ncinfo_var(vinfo,ncid,varid,unlimdimIDs) 161 162[vinfo.Name,xtype,dimids,natts] = netcdf_inqVar(ncid,varid); 163 164% Information about dimension 165 166vinfo.Dimensions = ncinfo_dim(ncid,dimids,unlimdimIDs); 167if isempty(vinfo.Dimensions) 168 vinfo.Size = []; 169else 170 vinfo.Size = cat(2,vinfo.Dimensions.Length); 171end 172 173% Data type 174 175vinfo.Datatype = nc2octtype(xtype); 176 177% Attributes 178 179vinfo.Attributes = []; 180 181for i = 0:natts-1 182 tmp = struct(); 183 tmp.Name = netcdf_inqAttName(ncid,varid,i); 184 tmp.Value = netcdf_getAtt(ncid,varid,tmp.Name); 185 186 if isempty(vinfo.Attributes) 187 vinfo.Attributes = [tmp]; 188 else 189 vinfo.Attributes(i+1) = tmp; 190 endif 191endfor 192 193% chunking, fillvalue, compression 194 195[storage,vinfo.ChunkSize] = netcdf_inqVarChunking(ncid,varid); 196 197[nofill,vinfo.FillValue] = netcdf_inqVarFill(ncid,varid); 198if nofill 199 vinfo.FillValue = []; 200endif 201 202[shuffle,deflate,vinfo.DeflateLevel] = ... 203 netcdf_inqVarDeflate(ncid,varid); 204 205if ~deflate 206 vinfo.DeflateLevel = []; 207endif 208vinfo.Shuffle = shuffle; 209 210# add checksum information if defined (unlike matlab) 211checksum = netcdf_inqVarFletcher32(ncid,varid); 212if ~strcmp(checksum,'nochecksum'); 213 vinfo.Checksum = checksum; 214endif 215 216endfunction 217 218 219function info = ncinfo_group(info,ncid) 220 221info.Name = netcdf_inqGrpName(ncid); 222unlimdimIDs = netcdf_inqUnlimDims(ncid); 223 224[ndims,nvars,ngatts] = netcdf_inq(ncid); 225 226% dimensions 227 228dimids = netcdf_inqDimIDs(ncid); 229info.Dimensions = ncinfo_dim(ncid,dimids,unlimdimIDs); 230 231% variables 232for i=1:nvars 233 info.Variables(i) = ncinfo_var(struct(),ncid,i-1,unlimdimIDs); 234endfor 235 236% global attributes 237info.Attributes = []; 238gid = netcdf_getConstant('NC_GLOBAL'); 239for i = 0:ngatts-1 240 tmp = struct(); 241 tmp.Name = netcdf_inqAttName(ncid,gid,i); 242 tmp.Value = netcdf_getAtt(ncid,gid,tmp.Name); 243 244 if isempty(info.Attributes) 245 info.Attributes = [tmp]; 246 else 247 info.Attributes(i+1) = tmp; 248 endif 249endfor 250 251info.Groups = []; 252gids = netcdf_inqGrps(ncid); 253for i = 1:length(gids) 254 tmp = ncinfo_group(struct(),gids(i)); 255 256 if isempty(info.Groups) 257 info.Groups = [tmp]; 258 else 259 info.Groups(i) = tmp; 260 endif 261endfor 262 263endfunction 264