source: trunk/src/nc2struct_toolbox.m @ 356

Last change on this file since 356 was 140, checked in by sommeria, 10 years ago

bug repair in netcdf file reading, dealing with unavailable variables, + cleaning

File size: 10.0 KB
Line 
1%'nc2struct_toolbox': transform a netcdf file in a corresponding matlab structure, USE OLD NETCDF LIBRARY
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%----------------------------------------------------------------------
5% function [Data,var_detect,ichoice]=nc2struct_toolbox(nc,varargin)
6%
7% OUTPUT:
8%  Data: structure containing all the information of the netcdf file (or netcdf object)
9%           with (optional)fields:
10%                    .ListGlobalAttribute: cell listing the names of the global attributes
11%                    .Att_1,Att_2... : values of the global attributes
12%                    .ListVarName: list of variable names to select (cell array of  char strings {'VarName1', 'VarName2',...} )
13%                    .VarDimName: list of dimension names for each element of .ListVarName (cell array of string cells)                         
14%                    .Var1, .Var2....: variables (Matlab arrays) with names listed in .ListVarName
15%                    .ListDimName=list of dimension (added information, not requested for field description)
16%                    .DimValue= vlalues of dimensions (added information, not requested for field description)
17%  var_detect: vector with same length as the cell array ListVarName, = 1 for each detected variable and 0 else.
18%            var_detect=[] in the absence of input cell array
19%  ichoice: index of the selected line in the case of multiple choice
20%        (cell array of varible names with multiple lines) , =[] by default
21%INPUT:
22%  nc:  name of a netcdf file (char string) or netcdf object   
23%  additional arguments:
24%       -no additional arguments: all the variables of the netcdf fiel are read.
25%       -a cell array, ListVarName, made of  char strings {'VarName1', 'VarName2',...} )
26%         if ListVarName=[] or {}, no variables is read (only global attributes)
27%         if ListVarName is absent, or = '*', ALL the variables of the netcdf file are read.
28%         if ListVarName is a cell array with n lines, the set of variables will be sought by order of priority
29%                  in the list, while output names will be set by the first line
30%        - the string 'ListGlobalAttribute' followed by a list of attribute  names: reads only these attributes (fast reading)
31%
32%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
33%  Copyright Joel Sommeria, 2008, LEGI / CNRS-UJF-INPG, sommeria@coriolis-legi.org.
34%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
35%     This file is part of the toolbox UVMAT.
36%
37%     UVMAT is free software; you can redistribute it and/or modify
38%     it under the terms of the GNU General Public License as published by
39%     the Free Software Foundation; either version 2 of the License, or
40%     (at your option) any later version.
41%
42%     UVMAT is distributed in the hope that it will be useful,
43%     but WITHOUT ANY WARRANTY; without even the implied warranty of
44%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
45%     GNU General Public License (file UVMAT/COPYING.txt) for more details.
46%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
47
48function [Data,var_detect,ichoice]=nc2struct_toolbox(nc,varargin)
49
50List=varargin{1};
51%default output
52Data=[];
53var_detect=[];
54ichoice=[];%default
55
56%open the netcdf file for reading
57if ischar(nc)
58    if exist(nc,'file') % rmq: time for exist search = 0.5 ms CPU
59        nc=netcdf(nc,'nowrite'); % rmq: time needed for opening = 2 ms CPU
60        testfile=1;
61    else
62       Data.Txt=['ERROR:file ' nc ' does not exist'];
63       return
64    end
65else
66    testfile=0;
67end
68
69% short reading of global attributes
70if ~isempty(List) && isequal(List{1},'ListGlobalAttribute')
71    for ilist=2:numel(List)
72        att_str=List{ilist};
73        eval(['Data.' att_str '=nc.' att_str '(:);'])
74    end
75    close(nc)
76        %total time from beginning : 15 ms for a single attribute
77   return
78end
79
80% reading of variables, including attributes
81if isempty(List)
82   ListVarName='*';
83else
84%     if isempty(List{1})
85%         ListVarName='*';
86%     else
87        ListVarName=List{1}; 
88%     end
89end
90%  -------- read global attributes -----------             
91att_read=att(nc);%cell of 'global attributes' (nc objects), CPU time 30 ms   
92att_key={};%default
93iatt_g=0;
94for iatt=1:length(att_read)
95    aa=att_read{iatt};
96    keystr=name(aa);
97    indstr1=regexp(keystr,'\\');%replace dots'
98    indstr2=regexp(keystr,'\.');%replace dots'
99    if ~isequal(keystr,'title') % PROBLEM WITH civx files do not read 'title'
100        if  isempty(indstr1) && isempty(indstr2) %
101           eval(['valuestr=nc.' keystr '(:);'])
102            if ischar(valuestr) && length(valuestr)<200
103                iatt_g=iatt_g+1;
104                indstr1=regexp(keystr,'\\');%replace dots'
105                indstr2=regexp(keystr,'\.');%replace dots'
106                if isempty(indstr1) && isempty(indstr2)
107                    eval(['Data.' keystr '=''' valuestr ''';'])
108                    att_key{iatt_g}=keystr;
109                end
110            elseif isempty(valuestr)
111                iatt_g=iatt_g+1;
112                eval(['Data.' keystr '=[];'])
113                att_key{iatt_g}=keystr;
114            elseif isnumeric(valuestr)
115                iatt_g=iatt_g+1;
116                eval(['Data.' keystr '=valuestr;'])
117                att_key{iatt_g}=keystr;
118            end
119        end
120    end
121end
122Data.ListGlobalAttribute=att_key;
123nbattr=length(att_key);
124neworder=[nbattr+1 (1:nbattr)];
125Data=orderfields(Data,neworder);
126
127%  -------- read dimensions -----------
128dim_read=dim(nc);%cell of variable dimension names (nc objects): CPU time 0.0013
129dim_name={};
130dim_value=[];
131for idim=1:length(dim_read);
132    aa=dim_read{idim};
133    if ~isempty(aa)
134    dim_name{idim}=name(aa);
135    dim_value(idim)=length(aa);
136    end
137end
138if ~isempty(dim_name) && ~isempty(dim_value)
139    Data.ListDimName=dim_name;
140    Data.DimValue=dim_value;
141    used=zeros(1,length(dim_value));%initialize test of used dimensions
142end
143
144%  -------- read variables -----------
145var_read={}; %default
146testmulti=0;
147OutputList=[];
148if isequal(ListVarName,'*')%|| isempty(ListVarName)
149     var_read=var(nc);%cell of all variables
150elseif ~isempty(ListVarName)
151    sizvar=size(ListVarName);
152    testmulti=(sizvar(1)>1);
153    if testmulti
154        OutputList=ListVarName(1,:);
155        testend=0;
156        for iline=1:sizvar(1)
157            if testend
158                break
159            end
160            for ivar=1:sizvar(2)
161                var_read{ivar}=[];%default
162                var_detect(ivar)=0;%default
163                VarName=ListVarName{iline,ivar};
164                if ~isempty(VarName)
165                     var_read{ivar}=nc{VarName};%select the input variable names
166                     if ivar==1
167                        if isempty (var_read{ivar})
168                            break%go to next line if the first nc variable is not found
169                        else
170                            testend=1; %this line will be read
171                            ichoice=iline-1; %selectedline number in the list of input names of variables
172                            var_detect(ivar)=1;
173                        end
174                     else
175                          var_detect(ivar)=~isempty (var_read{ivar});
176                     end
177                end
178            end
179        end
180        if ~isempty(find(var_detect,1))
181            OutputList=OutputList(find(var_detect)); 
182        end
183    else   %single list of input variables
184        var_detect=ones(size(ListVarName));
185        for ivar=1:sizvar(2)
186            var_read{ivar}=nc{ListVarName{ivar}};%select the input variable names
187            var_detect(ivar)=~isempty(var_read{ivar});
188        end
189    end
190    var_read=var_read(find(var_detect));
191end
192
193% var_dim_index=[]; %default
194Data.ListVarName={};%default
195for ivar=1:length(var_read)
196    vv=var_read{ivar};
197    Data.ListVarName{ivar}=name(vv);%name of the variable
198    if testmulti
199        Data.ListVarName{ivar}=OutputList{ivar};
200    else
201        Data.ListVarName{ivar}=name(vv);%name of the variable
202    end
203    var_dim=dim(vv);%dimension netcdf object of the variable
204    for ivardim=1:length(var_dim)
205        var_dim_name=name(var_dim{ivardim});%name of the dimension
206        for idim=1:length(dim_name)% find the index of the current dimension in the list of dimensions
207            if isequal(dim_name{idim},var_dim_name)
208                VarDimIndex{ivar}(ivardim)=idim;
209                used(idim)=1;
210                break
211            end
212        end
213    end
214    Data.VarDimName{ivar}={};
215    %variable attributes
216    Data.VarAttribute{ivar}=[];%initialisation of the list of variable attributes
217    %variable attributes
218    att_read=att(vv);
219    for iatt=1:length(att_read)
220        aa=att_read{iatt};
221        eval(['valuestr=vv.' name(aa) '(:);'])
222        if ischar(valuestr)
223            eval(['Data.VarAttribute{ivar}.' name(aa) '=''' valuestr ''';'])
224        elseif isempty(valuestr)
225            eval(['Data.VarAttribute{ivar}.' name(aa) '=[];'])
226        elseif isnumeric(valuestr)
227            eval(['Data.VarAttribute{ivar}.' name(aa) '=valuestr;'])
228        end
229    end
230end
231
232%select the used dimensions
233if isempty(var_read)
234    if isfield(Data,'ListDimName') && isfield(Data,'DimValue')
235    Data=rmfield(Data,'ListDimName');
236    Data=rmfield(Data,'DimValue');
237    end
238else
239    old_dim_index=find(used); %dimension indices which are used by the selected variables
240    old2new=cumsum(used);
241    Data.ListDimName=Data.ListDimName(old_dim_index);
242    Data.DimValue=Data.DimValue(old_dim_index);
243end
244for ivar=1:length(var_read)
245    VarDimIndex{ivar}=(old2new(VarDimIndex{ivar}));
246    Data.VarDimName{ivar}=(Data.ListDimName(VarDimIndex{ivar}));
247end
248%variable values
249
250if  ~isempty(ListVarName)
251    for ivar=1:length(Data.ListVarName)
252        vv=var_read{ivar};
253        vdata=vv(:);%data array of the field variable
254        eval(['Data.' Data.ListVarName{ivar} '=vdata;'])%read the variable data
255    end
256end
257%  -------- close fle-----------
258if testfile==1
259    close(nc)
260end
261
262%total time from beginning : 150 ms for a full civ2 field, 65 ms for four fields
263
Note: See TracBrowser for help on using the repository browser.