source: trunk/src/nc2struct.m @ 534

Last change on this file since 534 was 534, checked in by sommeria, 8 years ago

bugs repaired. color images

File size: 11.1 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%----------------------------------------------------------------------
5% function [Data,var_detect,ichoice]=nc2struct(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%         .Txt: error message
18%  var_detect: vector with same length as the cell array ListVarName, = 1 for each detected variable and 0 else.
19%            var_detect=[] in the absence of input cell array
20%  ichoice: index of the selected line in the case of multiple choice
21%        (cell array of varible names with multiple lines) , =[] by default
22%INPUT:
23%  nc:  name of a netcdf file (char string) or netcdf object   
24%  additional arguments:
25%       -no additional arguments: all the variables of the netcdf fiel are read.
26%       -a cell array, ListVarName, made of  char strings {'VarName1', 'VarName2',...} )
27%         if ListVarName=[] or {}, no variables is read (only global attributes)
28%         if ListVarName is absent, or = '*', ALL the variables of the netcdf file are read.
29%         if ListVarName is a cell array with n lines, the set of variables will be sought by order of priority
30%                  in the list, while output names will be set by the first line
31%        - the string 'ListGlobalAttribute' followed by a list of attribute  names: reads only these attributes (fast reading)
32%
33%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
34%  Copyright Joel Sommeria, 2008, LEGI / CNRS-UJF-INPG, sommeria@coriolis-legi.org.
35%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
36%     This file is part of the toolbox UVMAT.
37%
38%     UVMAT is free software; you can redistribute it and/or modify
39%     it under the terms of the GNU General Public License as published by
40%     the Free Software Foundation; either version 2 of the License, or
41%     (at your option) any later version.
42%
43%     UVMAT is distributed in the hope that it will be useful,
44%     but WITHOUT ANY WARRANTY; without even the implied warranty of
45%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
46%     GNU General Public License (file UVMAT/COPYING.txt) for more details.
47%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
48   
49function [Data,var_detect,ichoice]=nc2struct(nc,varargin)
50
51if isempty(varargin)
52    varargin{1}='*';
53end
54hhh=which('netcdf.open');% look for built-in matlab netcdf library
55
56if ~isequal(hhh,'')
57    %% default output
58    Data=[];%default
59    var_detect=[];%default
60    ichoice=[];%default
61   
62    %% open the netcdf file for reading
63    if ischar(nc)
64        if exist(nc,'file')
65            try
66            nc=netcdf.open(nc,'NC_NOWRITE');
67            testfile=1;
68            catch ME
69              Data.Txt=['ERROR opening ' nc ': ' ME.message];
70              return
71            end
72        else
73           Data.Txt=['ERROR:file ' nc ' does not exist'];
74           return
75        end
76    else
77        testfile=0;
78    end
79   
80    %% short reading option for global attributes only, if the first argument is 'ListGlobalAttribute'
81    if isequal(varargin{1},'ListGlobalAttribute')
82        for ilist=2:numel(varargin)
83            valuestr=[];%default
84            try
85            valuestr = netcdf.getAtt(nc,netcdf.getConstant('NC_GLOBAL'),varargin{ilist});
86            catch ME
87            end
88            eval(['Data.' varargin{ilist} '=valuestr;'])
89        end
90        netcdf.close(nc)
91       return
92    end
93
94    %% full reading: get the nbre of dimensions, variables, global attributes
95    ListVarName=varargin{1};
96    [ndims,nvars,ngatts]=netcdf.inq(nc);%nbre of dimensions, variables, global attributes, in the netcdf file
97   
98    %%  -------- read all global attributes (constants)-----------
99    Data.ListGlobalAttribute={};%default
100    att_key=cell(1,ngatts);%default
101    for iatt=1:ngatts
102        keystr= netcdf.inqAttName(nc,netcdf.getConstant('NC_GLOBAL'),iatt-1);
103        valuestr = netcdf.getAtt(nc,netcdf.getConstant('NC_GLOBAL'),keystr);
104        keystr=regexprep(keystr,{'\','/','\.','-',' '},{'','','','',''});%remove  '\','.' or '-' if exists
105        if strcmp(keystr(1),'_')
106            keystr(1)=[];
107        end
108        try
109            if ischar(valuestr) %& length(valuestr)<200 & double(valuestr)<=122 & double(valuestr)>=48 %usual characters
110                eval(['Data.' keystr '=''' valuestr ''';'])
111            elseif isnumeric(valuestr)
112                eval(['Data.' keystr '=valuestr;'])
113            else
114                eval(['Data.' keystr '='';'])
115            end
116            att_key{iatt}=keystr;
117        catch ME
118            att_key{iatt}=['attr_' num2str(iatt)];
119            Data.(att_key{iatt})=[];
120        end
121    end
122    Data.ListGlobalAttribute=att_key;
123
124    %%  -------- read dimension names-----------
125    ListDimNameNetcdf=cell(1,ndims);
126    dim_value=zeros(1,ndims);
127    for idim=1:ndims %loop on the dimensions of the netcdf file
128        [ListDimNameNetcdf{idim},dim_value(idim)] = netcdf.inqDim(nc,idim-1);%get name and value of each dimension
129    end
130    if ~isempty(ListDimNameNetcdf)
131        flag_used=zeros(1,ndims);%initialize the flag indicating the selected dimensions in the list (0=unused)
132    end
133 
134    %%  -------- read names of variables -----------
135    ListVarNameNetcdf=cell(1,nvars); %default
136    dimids=cell(1,nvars);
137    nbatt=zeros(1,nvars);
138    for ncvar=1:nvars %loop on the variables of the netcdf file
139        %get name, type, dimensions and attribute numbers of each variable
140        [ListVarNameNetcdf{ncvar},xtype,dimids{ncvar},nbatt(ncvar)] = netcdf.inqVar(nc,ncvar-1);
141    end 
142    testmulti=0;
143    if isequal(ListVarName,'*')||isempty(ListVarName)
144        var_index=1:nvars; %all the variables are selected in the netcdf file
145        Data.ListVarName=ListVarNameNetcdf;
146    else   %select input variables, if requested by the input ListVarName
147        ind_remove=[];
148        check_keep=ones(1,size(ListVarName,2));
149        for ivar=1:size(ListVarName,2) % check redondancy of variable names
150            if ~isempty(find(strcmp(ListVarName{1,ivar},ListVarName(1:ivar-1)), 1))
151                check_keep(ivar)=0;% the variable #ivar is already in the list
152            end
153        end
154        ListVarName=ListVarName(:,logical(check_keep));         
155        sizvar=size(ListVarName);
156        testmulti=(sizvar(1)>1);%test for multiple choice of variable ranked by order of priority
157        var_index=zeros(1,sizvar(2));%default
158        if testmulti %multiple choice of variable ranked by order of priority
159            for iline=1:sizvar(1)
160                search_index=find(strcmp(ListVarName{iline,1},ListVarNameNetcdf),1);%look for the first variable name in the list of netcdf variables
161                if ~isempty(search_index)
162                    break % go to the next line
163                end
164            end
165            ichoice=iline-1;%selected line number in the list of input names of variables
166        else
167            iline=1;
168        end
169        for ivar=1:sizvar(2)
170            search_index=find(strcmp(ListVarName{iline,ivar},ListVarNameNetcdf),1);%look for the variable name in the list of netcdf file
171            if ~isempty(search_index)
172                var_index(ivar)=search_index;%index of the netcdf list corresponding to the input list index ivar
173            end
174        end
175        var_detect=(var_index~=0);%=1 for detected variables         
176        list_index=find(var_index);% indices in the input list corresponding to a detected variable
177        var_index=var_index(list_index);% netcdf variable indices corresponding to the output list of read variable
178        Data.ListVarName=ListVarName(1,list_index);%the first line of ListVarName sets the output names of the variables
179    end
180     
181  %% get the dimensions and attributes associated to  variables
182    for ivar=1:length(var_index)
183        var_dim{ivar}=dimids{var_index(ivar)}+1; %netcdf dimension indices used by the variable #ivar
184        Data.VarDimName{ivar}=ListDimNameNetcdf(var_dim{ivar});
185        flag_used(var_dim{ivar})=ones(size(var_dim{ivar}));%flag_used =1 for the indices of used dimensions
186        for iatt=1:nbatt(var_index(ivar))
187            attname = netcdf.inqAttName(nc,var_index(ivar)-1,iatt-1);
188            valuestr= netcdf.getAtt(nc,var_index(ivar)-1,attname);
189            attname=regexprep(attname,{'\','/','\.','-',' '},{'','','','',''});%remove  '\','.' or '-' if exists
190            if strcmp(attname(1),'_')
191                attname(1)=[];
192            end
193            try
194            if ischar(valuestr)
195               % valuestr=regexprep(valuestr,{'\\','\/','\.','\-',' '},{'_','_','_','_','_'});%remove  '\','.' or '-' if exists
196                eval(['Data.VarAttribute{ivar}.' attname '=''' valuestr ''';'])
197            elseif isempty(valuestr)
198                eval(['Data.VarAttribute{ivar}.' attname '=[];'])
199            elseif isnumeric(valuestr)
200                eval(['Data.VarAttribute{ivar}.' attname '=valuestr;'])
201            end
202            catch ME
203                display(attname)
204                display(valuestr)
205                display(ME.message)         
206                eval(['Data.VarAttribute{ivar}.atrr_' num2str(iatt) '=''not read'';'])
207            end
208        end
209    end
210
211    %% select the dimensions used for the set of input variables
212    if ~isempty(var_index)     
213        dim_index=find(flag_used);%list of netcdf dimensions indices corresponding to used dimensions
214        Data.ListDimName=ListDimNameNetcdf(dim_index);
215        Data.DimValue=dim_value(dim_index);
216    end
217   
218    %% get the values of the input variables
219    if  ~isempty(ListVarName)
220        for ivar=1:length(var_index)
221            VarName=Data.ListVarName{ivar};
222            VarName=regexprep(VarName,'-',''); %suppress '-' if it exists in the netcdf variable name
223            eval(['Data.' VarName '=double(netcdf.getVar(nc,var_index(ivar)-1));'])%read the variable data
224        end
225    end
226   
227    %%  -------- close fle-----------
228    if testfile==1
229        netcdf.close(nc)
230    end
231   
232%% old netcdf library
233else
234    [Data,var_detect,ichoice]=nc2struct_toolbox(nc,varargin);
235end
Note: See TracBrowser for help on using the repository browser.