source: trunk/src/nc2struct.m @ 295

Last change on this file since 295 was 236, checked in by sommeria, 10 years ago

correct Matlab PIV, remove call to image tool box. Improve menu of uvmat VelType? (replacement of buttons)

File size: 10.8 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%  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(nc,varargin)
49
50if isempty(varargin)
51    varargin{1}='*';
52end
53hhh=which('netcdf.open');% look for built-in matlab netcdf library
54
55if ~isequal(hhh,'')
56    %% default output
57    Data=[];%default
58    var_detect=[];%default
59    ichoice=[];%default
60   
61    %% open the netcdf file for reading
62    if ischar(nc)
63        if exist(nc,'file')
64            try
65            nc=netcdf.open(nc,'NC_NOWRITE');
66            testfile=1;
67            catch ME
68              Data.Txt=['ERROR opening ' nc ': ' ME.message];
69              return
70            end
71        else
72           Data.Txt=['ERROR:file ' nc ' does not exist'];
73           return
74        end
75    else
76        testfile=0;
77    end
78   
79    %% short reading option for global attributes only, if the first argument is 'ListGlobalAttribute'
80    if isequal(varargin{1},'ListGlobalAttribute')
81        for ilist=2:numel(varargin)
82            valuestr=[];%default
83            try
84            valuestr = netcdf.getAtt(nc,netcdf.getConstant('NC_GLOBAL'),varargin{ilist});
85            catch ME
86            end
87            eval(['Data.' varargin{ilist} '=valuestr;'])
88        end
89        netcdf.close(nc)
90       return
91    end
92
93    %% full reading: get the nbre of dimensions, variables, global attributes
94    ListVarName=varargin{1};
95    [ndims,nvars,ngatts]=netcdf.inq(nc);%nbre of dimensions, variables, global attributes, in the netcdf file
96   
97    %%  -------- read all global attributes (constants)-----------
98    att_key={};%default
99%     iatt_g=0;
100    Data.ListGlobalAttribute={};%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               % valuestr=regexprep(valuestr,{'\\','\/','\.','\-',' '},{'_','_','_','_','_'})%remove  '\','.' or '-' if exists
111                eval(['Data.' keystr '=''' valuestr ''';'])
112%             elseif isempty(valuestr)
113%                 eval(['Data.' keystr '=[];'])
114            elseif isnumeric(valuestr)
115                eval(['Data.' keystr '=valuestr;'])
116            else
117                eval(['Data.' keystr '='';'])
118            end
119            att_key{iatt}=keystr;
120        catch ME
121            att_key{iatt}=['attr_' num2str(iatt)];
122            eval(['Data.' att_key{iatt} '=[];'])
123        end
124    end
125    Data.ListGlobalAttribute=att_key;
126
127    %%  -------- read dimension names-----------
128    ListDimNameNetcdf={};
129    dim_value=[];
130    for idim=1:ndims %loop on the dimensions of the netcdf file
131        [ListDimNameNetcdf{idim},dim_value(idim)] = netcdf.inqDim(nc,idim-1);%get name and value of each dimension
132    end
133    if ~isempty(ListDimNameNetcdf)
134        flag_used=zeros(1,ndims);%initialize the flag indicating the selected dimensions in the list (0=unused)
135    end
136 
137    %%  -------- read names of variables -----------
138    ListVarNameNetcdf={}; %default
139    dimids={};
140    nbatt=[];
141    for ncvar=1:nvars %loop on the variables of the netcdf file
142        %get name, type, dimensions and attribute numbers of each variable
143        [ListVarNameNetcdf{ncvar},xtype,dimids{ncvar},nbatt(ncvar)] = netcdf.inqVar(nc,ncvar-1);
144    end 
145    testmulti=0;
146    if isequal(ListVarName,'*')||isempty(ListVarName)
147        var_index=1:nvars; %all the variables are selected in the netcdf file
148        Data.ListVarName=ListVarNameNetcdf;
149    else   %select input variables, if requested by the input ListVarName
150        sizvar=size(ListVarName);
151        testmulti=(sizvar(1)>1);%test for multiple choice of variable ranked by order of priority
152        var_index=zeros(1,sizvar(2));%default
153        if testmulti %multiple choice of variable ranked by order of priority
154            for iline=1:sizvar(1)
155                search_index=find(strcmp(ListVarName{iline,1},ListVarNameNetcdf),1);%look for the first variable name in the list of netcdf variables
156                if ~isempty(search_index)
157                    break % go to the next line
158                end
159            end
160            ichoice=iline-1;%selected line number in the list of input names of variables
161        else
162            iline=1;
163        end
164        for ivar=1:sizvar(2)
165            search_index=find(strcmp(ListVarName{iline,ivar},ListVarNameNetcdf),1);%look for the variable name in the list of netcdf file
166            if ~isempty(search_index)
167                var_index(ivar)=search_index;%index of the netcdf list corresponding to the input list index ivar
168            end
169        end
170        var_detect=(var_index~=0);%=1 for detected variables         
171        list_index=find(var_index);% indices in the input list corresponding to a detected variable
172        var_index=var_index(list_index);% netcdf variable indices corresponding to the output list of read variable
173        Data.ListVarName=ListVarName(1,list_index);%the first line of ListVarName sets the output names of the variables
174    end
175     
176  %% get the dimensions and attributes associated to  variables
177    for ivar=1:length(var_index)
178        var_dim{ivar}=dimids{var_index(ivar)}+1; %netcdf dimension indices used by the variable #ivar
179        Data.VarDimName{ivar}=ListDimNameNetcdf(var_dim{ivar});
180        flag_used(var_dim{ivar})=ones(size(var_dim{ivar}));%flag_used =1 for the indices of used dimensions
181        for iatt=1:nbatt(var_index(ivar))
182            attname = netcdf.inqAttName(nc,var_index(ivar)-1,iatt-1);
183            valuestr= netcdf.getAtt(nc,var_index(ivar)-1,attname);
184            attname=regexprep(attname,{'\','/','\.','-',' '},{'','','','',''});%remove  '\','.' or '-' if exists
185            if strcmp(attname(1),'_')
186                attname(1)=[];
187            end
188            try
189            if ischar(valuestr)
190               % valuestr=regexprep(valuestr,{'\\','\/','\.','\-',' '},{'_','_','_','_','_'});%remove  '\','.' or '-' if exists
191                eval(['Data.VarAttribute{ivar}.' attname '=''' valuestr ''';'])
192            elseif isempty(valuestr)
193                eval(['Data.VarAttribute{ivar}.' attname '=[];'])
194            elseif isnumeric(valuestr)
195                eval(['Data.VarAttribute{ivar}.' attname '=valuestr;'])
196            end
197            catch ME
198                display(attname)
199                display(valuestr)
200                display(ME.message)         
201                eval(['Data.VarAttribute{ivar}.atrr_' num2str(iatt) '=''not read'';'])
202            end
203        end
204    end
205
206    %% select the dimensions used for the set of input variables
207    if ~isempty(var_index)     
208        dim_index=find(flag_used);%list of netcdf dimensions indices corresponding to used dimensions
209        Data.ListDimName=ListDimNameNetcdf(dim_index);
210        Data.DimValue=dim_value(dim_index);
211    end
212   
213    %% get the values of the input variables
214    if  ~isempty(ListVarName)
215        for ivar=1:length(var_index)
216            VarName=Data.ListVarName{ivar};
217            VarName=regexprep(VarName,'-',''); %suppress '-' if it exists in the netcdf variable name
218            eval(['Data.' VarName '=double(netcdf.getVar(nc,var_index(ivar)-1));'])%read the variable data
219        end
220    end
221   
222    %%  -------- close fle-----------
223    if testfile==1
224        netcdf.close(nc)
225    end
226   
227%% old netcdf library
228else
229    [Data,var_detect,ichoice]=nc2struct_toolbox(nc,varargin);
230end
Note: See TracBrowser for help on using the repository browser.