source: trunk/src/private/nc2struct.m @ 8

Last change on this file since 8 was 8, checked in by gostiaux, 15 years ago
File size: 11.0 KB
Line 
1%'nc2struct': transform a netcdf file in a corresponding matlab structure
2% it reads all the global attributes and all variables, or a selected list.
3% The corresponding dimensions and variable attributes are then extracted
4%%%%%% TODO: add the possibility to read only attributes, see  nc2struct_toolbox %%%
5%----------------------------------------------------------------------
6% function [Data,var_detect,ichoice]=nc2struct(nc,ListVarName)
7%
8% OUTPUT:
9%  Data: structure containing all the information of the netcdf file (or netcdf object)
10%           with fields:
11%    .ListGlobalAttribute: cell listing the names of the global attributes
12%        .Att_1,Att_2... : values of the global attributes
13%            .ListDimName: cell listing the names of the array dimensions
14%               .DimValue: array dimension values (Matlab vector with the same length as .ListDimName
15%            .ListVarName: cell listing the names of the variables
16%            .VarDimIndex: cell containing the set of dimension indices (in list .ListDimName) for each variable of .ListVarName
17%            .VarDimName: cell containing a cell of dimension names (in list .ListDimName) for each variable of .ListVarName
18%           .VarAttribute: cell of structures s containing names and values of variable attributes (s.name=value) for each variable of .ListVarName
19%        .Var1, .Var2....: variables (Matlab arrays) with names listed in .ListVarName
20%  var_detect: vector with same length as ListVarName, with 1 for each detected variable and 0 else.
21%  ichoice: = line
22%
23%INPUT:
24%     nc:      name of a netcdf file (char string) or netcdf object   
25% ListVarName: optional list of variable names to select (cell array of  char strings {'VarName1', 'VarName2',...} )
26%         if ListVarName=[] or {}, no variables is read (only global attributes and lists of dimensions, variables and attriburtes)
27%         if ListVarName is absent, or = '*', ALL the variables are read.
28%        if ListVarName is a cell array with n lines, the set of variables
29%                        will be sought by order of priority in the list, while output names will be set by the first line
30%
31%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
32%  Copyright Joel Sommeria, 2008, LEGI / CNRS-UJF-INPG, sommeria@coriolis-legi.org.
33%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
34%     This file is part of the toolbox UVMAT.
35%
36%     UVMAT is free software; you can redistribute it and/or modify
37%     it under the terms of the GNU General Public License as published by
38%     the Free Software Foundation; either version 2 of the License, or
39%     (at your option) any later version.
40%
41%     UVMAT is distributed in the hope that it will be useful,
42%     but WITHOUT ANY WARRANTY; without even the implied warranty of
43%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
44%     GNU General Public License (file UVMAT/COPYING.txt) for more details.
45%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
46   
47function [Data,var_detect,ichoice]=nc2struct(nc,varargin)
48List=varargin;
49if nargin==0
50    List{1}='*';
51end
52% if ~exist('ListVarName','var')
53%     ListVarName='*';
54% end
55hhh=which('netcdf.open');% look for built-in matlab netcdf library
56
57if ~isequal(hhh,'')
58    %default output
59    Data=[];
60    var_detect=[];
61    ichoice=[];%default
62    %open the netcdf file for reading
63    if ischar(nc)
64        if exist(nc,'file')
65            nc=netcdf.open(nc,'NC_NOWRITE');
66            testfile=1;
67        else
68           Data.Txt=['ERROR:file ' nc ' does not exist'];
69           return
70        end
71    else
72        testfile=0;
73    end
74    % short reading of global attributes
75    if isequal(List{1},'ListGlobalAttribute')
76        for ilist=2:numel(List)
77            valuestr = netcdf.getAtt(nc,netcdf.getConstant('NC_GLOBAL'),List{ilist});
78            eval(['Data.' List{ilist} '=valuestr;'])
79        end
80        netcdf.close(nc)
81       return
82    end
83
84    % reading of variables, including attributes
85    ListVarName=List{1}; 
86    [ndims,nvars,ngatts]=netcdf.inq(nc);%nbre of dimensions, variables, attributes
87   
88    %  -------- read global attributes (constants)-----------
89    att_key={};%default
90    iatt_g=0;
91    Data.ListGlobalAttribute={};%default
92    for iatt=1:ngatts
93        keystr= netcdf.inqAttName(nc,netcdf.getConstant('NC_GLOBAL'),iatt-1);
94        indstr1=regexp(keystr,'\\');%detect '\\'
95        indstr2=regexp(keystr,'\.');%detect '\.'
96        if isempty(indstr1) && isempty(indstr2)
97           valuestr = netcdf.getAtt(nc,netcdf.getConstant('NC_GLOBAL'),keystr);
98           if ischar(valuestr) && length(valuestr)<200
99                iatt_g=iatt_g+1;
100                indstr1=regexp(keystr,'\\');%detect '\\'
101                indstr2=regexp(keystr,'\.');%detect '\.'
102                if isempty(indstr1) && isempty(indstr2)
103                    eval(['Data.' keystr '=''' valuestr ''';'])
104                    att_key{iatt_g}=keystr;
105                end
106            elseif isempty(valuestr)
107                iatt_g=iatt_g+1;
108                eval(['Data.' keystr '=[];'])
109                att_key{iatt_g}=keystr;
110            elseif isnumeric(valuestr)
111                iatt_g=iatt_g+1;
112                eval(['Data.' keystr '=valuestr;'])
113                att_key{iatt_g}=keystr;
114            end
115        end
116    end
117    Data.ListGlobalAttribute=att_key;
118
119    %  -------- read dimensions -----------
120    dim_name={};
121    dim_value=[];
122    for idim=1:ndims%length(dim_read);
123        [dim_name{idim},dim_value(idim)] = netcdf.inqDim(nc,idim-1);
124    end
125    if ~isempty(dim_name) && ~isempty(dim_value)
126        Data.ListDimName=dim_name;
127        Data.DimValue=dim_value;
128%         DimIndices=[1:ndims]; %index of the dimension in the netcdf file
129        dim_used=zeros(1,ndims);%initialize test of used dimensions
130    end
131 
132    %  -------- read variables -----------
133    var_read={}; %default
134    dimids={};
135    nbatt=[];
136    for ivar=1:nvars
137        [var_read{ivar},xtype,dimids{ivar},nbatt(ivar)] = netcdf.inqVar(nc,ivar-1);
138    end 
139    var_index=1:nvars; %default set of variable indices in the netcdf file
140    testmulti=0;
141    OutputList=[];
142    %select input variables, if requested by the input ListVarName
143    if ~(isequal(ListVarName,'*')||isempty(ListVarName))
144        sizvar=size(ListVarName);
145        testmulti=(sizvar(1)>1);
146        var_index=zeros(1,sizvar(2));%default
147        if testmulti
148            OutputList=ListVarName(1,:);
149            testend=0;
150            for iline=1:sizvar(1)
151                if testend
152                    break
153                end
154          %      var_index=zeros(size(ListVarName));%default
155                for ivar=1:sizvar(2)
156                    if ~isempty(ListVarName{iline,ivar})
157                         for ilist=1:nvars
158                            if isequal(var_read{ilist},ListVarName{iline,ivar})
159                                var_index(ivar)=ilist;
160     %                          var_detect(ivar)=1;
161                            break
162                            end
163                         end
164                         if ivar==1
165                            if var_index(ivar)==0
166                                break%go to next line if the first nc variable is not found
167                            else
168                                testend=1; %this line will be read
169                                ichoice=iline-1; %selectedline number in the list of input names of variables
170                            end
171                         end
172                    end
173                end
174            end
175        else   %single list of input variables
176            for ivar=1:sizvar(2)
177                for ilist=1:nvars
178                    if isequal(var_read{ilist},ListVarName{ivar})
179                        var_index(ivar)=ilist;
180                        var_detect(ivar)=1;
181                        break
182                    end
183                end
184            end
185        end
186        list_index=find(var_index);
187        if ~isempty(list_index)
188            if testmulti
189                OutputList=OutputList(list_index);
190            end
191            var_index=var_index(list_index);
192            var_detect=(var_index~=0);
193            var_read=var_read(var_index);         
194        end
195    end
196   
197   
198    %select variable attributes and associate dimensions
199%     var_dim_index=[]; %default
200    Data.ListVarName={};%default
201    VarDimIndex={};%default
202    for ivar=1:length(var_read)
203        if testmulti
204            Data.ListVarName{ivar}=OutputList{ivar};%new name given by ListVarName(1,:)
205        else
206            Data.ListVarName{ivar}=var_read{ivar};%name of the variable
207        end
208        var_dim=dimids{var_index(ivar)}+1; %dimension indices used by the variable
209        dim_used(var_dim)=ones(size(var_dim));
210        VarDimIndex{ivar}=var_dim;
211
212        %variable attributes
213        if ivar==1
214            Data.VarAttribute={};%initialisation of the list of variable attributes
215        end
216        %variable attributes
217        for iatt=1:nbatt(var_index(ivar))
218            attname = netcdf.inqAttName(nc,var_index(ivar)-1,iatt-1);
219            valuestr= netcdf.getAtt(nc,var_index(ivar)-1,attname);
220            if ischar(valuestr)
221                eval(['Data.VarAttribute{ivar}.' attname '=''' valuestr ''';'])
222            elseif isempty(valuestr)
223                eval(['Data.VarAttribute{ivar}.' attname '=[];'])
224            elseif isnumeric(valuestr)
225                eval(['Data.VarAttribute{ivar}.' attname '=valuestr;'])
226            end
227        end
228    end
229
230    %select the used dimensions
231    if isempty(var_read)
232        if isfield(Data,'ListDimName') && isfield(Data,'DimValue')
233        Data=rmfield(Data,'ListDimName');
234        Data=rmfield(Data,'DimValue');
235        end
236    else
237%         list_dim=1:ndims;
238        dim_index=find(dim_used);
239%         list_dim=list_dim(dim_index);
240        old2new=cumsum(dim_used);
241        Data.ListDimName=Data.ListDimName(dim_index);
242        Data.DimValue=Data.DimValue(dim_index);
243    end
244    for ivar=1:length(var_read)
245        Data.VarDimIndex{ivar}=old2new(VarDimIndex{ivar});% ENLEVER Data.VarDimIndex ulterieurement
246        Data.VarDimName{ivar}=Data.ListDimName(Data.VarDimIndex{ivar});
247    end
248    %variable values
249    if  ~isempty(ListVarName)
250        for ivar=1:length(Data.ListVarName)
251            VarName=Data.ListVarName{ivar};
252            indstr=regexp(VarName,'-');%detect '-'
253            if ~isempty(indstr)
254                VarName(indstr)=[];
255            end
256            eval(['Data.' VarName '=netcdf.getVar(nc,var_index(ivar)-1);'])%read the variable data
257            eval(['siz=size(Data.' VarName ');'])
258            if numel(siz)<=2
259            eval(['Data.' VarName '=Data.' VarName ''';'])%read the variable data
260            end
261        end
262    end
263    %  -------- close fle-----------
264    if testfile==1
265        netcdf.close(nc)
266    end
267else
268    [Data,var_detect,ichoice]=nc2struct_toolbox(nc,varargin);
269end
Note: See TracBrowser for help on using the repository browser.