source: trunk/src/nc2struct.m @ 227

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

add function sub_field_series to apply the sub_field operation to a series of fileds (for instance subtracting a background to an image series)

File size: 10.8 KB
RevLine 
[8]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%----------------------------------------------------------------------
[56]5% function [Data,var_detect,ichoice]=nc2struct(nc,varargin)
[8]6%
7% OUTPUT:
8%  Data: structure containing all the information of the netcdf file (or netcdf object)
[140]9%           with (optional)fields:
10%                    .ListGlobalAttribute: cell listing the names of the global attributes
[55]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)
[140]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
[8]21%INPUT:
[140]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',...} )
[56]26%         if ListVarName=[] or {}, no variables is read (only global attributes)
[140]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
[56]30%        - the string 'ListGlobalAttribute' followed by a list of attribute  names: reads only these attributes (fast reading)
[8]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)
[56]49
[55]50if isempty(varargin)
[56]51    varargin{1}='*';
[8]52end
53hhh=which('netcdf.open');% look for built-in matlab netcdf library
54
55if ~isequal(hhh,'')
[140]56    %% default output
57    Data=[];%default
58    var_detect=[];%default
[8]59    ichoice=[];%default
[140]60   
61    %% open the netcdf file for reading
[8]62    if ischar(nc)
63        if exist(nc,'file')
[150]64            try
[8]65            nc=netcdf.open(nc,'NC_NOWRITE');
66            testfile=1;
[227]67            catch ME
68              Data.Txt=['ERROR opening ' nc ': ' ME.message];
[150]69              return
70            end
[8]71        else
72           Data.Txt=['ERROR:file ' nc ' does not exist'];
73           return
74        end
75    else
76        testfile=0;
77    end
[140]78   
[227]79    %% short reading option for global attributes only, if the first argument is 'ListGlobalAttribute'
[56]80    if isequal(varargin{1},'ListGlobalAttribute')
81        for ilist=2:numel(varargin)
[227]82            valuestr=[];%default
[45]83            try
[56]84            valuestr = netcdf.getAtt(nc,netcdf.getConstant('NC_GLOBAL'),varargin{ilist});
[227]85            catch ME
[45]86            end
[56]87            eval(['Data.' varargin{ilist} '=valuestr;'])
[8]88        end
89        netcdf.close(nc)
90       return
91    end
92
[140]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
[8]96   
[140]97    %%  -------- read all global attributes (constants)-----------
[8]98    att_key={};%default
[227]99%     iatt_g=0;
[8]100    Data.ListGlobalAttribute={};%default
101    for iatt=1:ngatts
102        keystr= netcdf.inqAttName(nc,netcdf.getConstant('NC_GLOBAL'),iatt-1);
[227]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 '=[];'])
[8]114            elseif isnumeric(valuestr)
115                eval(['Data.' keystr '=valuestr;'])
[227]116            else
117                eval(['Data.' keystr '='';'])
[8]118            end
[227]119            att_key{iatt}=keystr;
120        catch ME
121            att_key{iatt}=['attr_' num2str(iatt)];
122            eval(['Data.' att_key{iatt} '=[];'])
[8]123        end
124    end
125    Data.ListGlobalAttribute=att_key;
126
[140]127    %%  -------- read dimension names-----------
128    ListDimNameNetcdf={};
[8]129    dim_value=[];
[140]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
[8]132    end
[140]133    if ~isempty(ListDimNameNetcdf)
134        flag_used=zeros(1,ndims);%initialize the flag indicating the selected dimensions in the list (0=unused)
[8]135    end
136 
[140]137    %%  -------- read names of variables -----------
138    ListVarNameNetcdf={}; %default
[8]139    dimids={};
140    nbatt=[];
[140]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);
[8]144    end 
145    testmulti=0;
[140]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
[8]150        sizvar=size(ListVarName);
[140]151        testmulti=(sizvar(1)>1);%test for multiple choice of variable ranked by order of priority
[8]152        var_index=zeros(1,sizvar(2));%default
[140]153        if testmulti %multiple choice of variable ranked by order of priority
[8]154            for iline=1:sizvar(1)
[140]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
[8]158                end
159            end
[140]160            ichoice=iline-1;%selected line number in the list of input names of variables
161        else
162            iline=1;
[8]163        end
[140]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
[8]168            end
169        end
[140]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
[8]174    end
[140]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
[8]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);
[227]184            attname=regexprep(attname,{'\','/','\.','-',' '},{'','','','',''});%remove  '\','.' or '-' if exists
185            if strcmp(attname(1),'_')
186                attname(1)=[];
187            end
188            try
[8]189            if ischar(valuestr)
[227]190               % valuestr=regexprep(valuestr,{'\\','\/','\.','\-',' '},{'_','_','_','_','_'});%remove  '\','.' or '-' if exists
[8]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
[227]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
[8]203        end
204    end
205
[140]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);
[8]211    end
[140]212   
213    %% get the values of the input variables
[8]214    if  ~isempty(ListVarName)
[140]215        for ivar=1:length(var_index)
[8]216            VarName=Data.ListVarName{ivar};
[140]217            VarName=regexprep(VarName,'-',''); %suppress '-' if it exists in the netcdf variable name
[100]218            eval(['Data.' VarName '=double(netcdf.getVar(nc,var_index(ivar)-1));'])%read the variable data
[8]219        end
220    end
[140]221   
222    %%  -------- close fle-----------
[8]223    if testfile==1
224        netcdf.close(nc)
225    end
[140]226   
227%% old netcdf library
[8]228else
229    [Data,var_detect,ichoice]=nc2struct_toolbox(nc,varargin);
230end
Note: See TracBrowser for help on using the repository browser.