Changeset 530 for trunk/src/struct2nc.m


Ignore:
Timestamp:
Aug 27, 2012, 4:38:41 PM (12 years ago)
Author:
sommeria
Message:

new conventions for find_field_cells .

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/struct2nc.m

    r526 r530  
    137137
    138138
     139%'check_field_structure': check the validity of the field struture representation consistant with the netcdf format
     140%------------------------------------------------------------------------
     141% function [DataOut,errormsg]=check_field_structure(Data)
     142%
     143% OUTPUT:
     144% DataOut: structure reproducing the input structure Data (TODO: suppress this output)
     145% errormsg: error message which is not empty when the input structure does not have the right form
     146%
     147% INPUT:
     148% Data:   structure containing
     149%         (optional) .ListGlobalAttribute: cell listing the names of the global attributes
     150%                    .Att_1,Att_2... : values of the global attributes
     151%         (requested)  .ListVarName: list of variable names to select (cell array of  char strings {'VarName1', 'VarName2',...} )
     152%         (requested)  .VarDimName: list of dimension names for each element of .ListVarName (cell array of string cells)                         
     153%         (requested) .Var1, .Var2....: variables (Matlab arrays) with names listed in .ListVarName
     154
     155
     156function [errormsg,ListDimName,DimValue,VarDimIndex]=check_field_structure(Data)
     157errormsg='';
     158ListDimName={};
     159DimValue=[]; %default
     160VarDimIndex={};
     161if ~isstruct(Data)
     162    errormsg='input field is not a structure';
     163    return
     164end
     165if isfield(Data,'ListVarName') && iscell(Data.ListVarName)
     166    nbfield=numel(Data.ListVarName);
     167else
     168    errormsg='input field does not contain the cell array of variable names .ListVarName';
     169    return
     170end
     171%check dimension names
     172if (isfield(Data,'VarDimName') && iscell(Data.VarDimName))
     173    if  numel(Data.VarDimName)~=nbfield
     174       errormsg=' .ListVarName and .VarDimName have different lengths';
     175        return
     176    end
     177else
     178    errormsg='input field does not contain the  cell array of dimension names .VarDimName';
     179    return
     180end
     181% if isfield(Data,'DimValue')
     182%     Data=rmfield(Data,'DimValue');
     183% end
     184nbdim=0;
     185ListDimName={};
     186
     187%% main loop on the list of variables
     188for ivar=1:nbfield
     189    VarName=Data.ListVarName{ivar};
     190    if ~isfield(Data,VarName)
     191        errormsg=['the listed variable ' VarName ' is not found'];
     192        return
     193    end
     194    sizvar=size(Data.(VarName));% sizvar = dimension of variable
     195    DimCell=Data.VarDimName{ivar};
     196    if ischar(DimCell)
     197        DimCell={DimCell};%case of a single dimension name, defined by a string
     198    elseif ~iscell(DimCell)
     199        errormsg=['wrong format for .VarDimName{' num2str(ivar) ' (must be the cell of dimension names of the variable ' VarName];
     200        return
     201       
     202    end
     203    nbcoord=numel(sizvar);%nbre of coordinates for variable named VarName
     204    testrange=0;
     205    if numel(DimCell)==0
     206        errormsg=['empty declared dimension .VarDimName{' num2str(ivar) '} for ' VarName];
     207        return
     208    elseif numel(DimCell)==1% one dimension declared
     209        if nbcoord==2
     210            if sizvar(1)==1
     211                nbcoord=1;
     212                sizvar(1)=sizvar(2);
     213            elseif sizvar(2)==1
     214                nbcoord=1;
     215            else
     216                errormsg=['1 dimension declared in .VarDimName{' num2str(ivar) '} inconsistent with the nbre of dimensions =2 of the variable ' VarName];
     217                return
     218            end
     219            if sizvar(1)==2 && isequal(VarName,DimCell{1})
     220                testrange=1;% test for a dimension variable representing a range
     221            end
     222        else
     223            errormsg=['1 dimension declared in .VarDimName{' num2str(ivar) '} inconsistent with the nbre of dimensions =' num2str(nbcoord) ' of the variable ' VarName];
     224            return
     225        end
     226    else
     227        if numel(DimCell)>nbcoord
     228            sizvar(nbcoord+1:numel(DimCell))=1;% case of singleton dimensions (not seen by the function size)
     229           % DimCell=DimCell(end-nbcoord+1:end)%first singleton diemensions omitted,
     230        elseif nbcoord > numel(DimCell)
     231            errormsg=['nbre of declared dimensions in .VarDimName{' num2str(ivar) '} smaller than the nbre of dimensions =' num2str(nbcoord) ' of the variable ' VarName];
     232            return
     233        end
     234    end
     235    DimIndex=[];
     236    %for idim=1:nbcoord
     237    for idim=1:numel(DimCell) %loop on the coordinates of variable #ivar
     238        DimName=DimCell{idim};
     239        iprev=find(strcmp(DimName,ListDimName),1);%look for dimension name DimName in the current list
     240        if isempty(iprev)% append the dimension name to the current list
     241            nbdim=nbdim+1;
     242            RangeTest(nbdim)=0; %default
     243            if sizvar(idim)==2 && strcmp(DimName,VarName)%case of a coordinate defined by the two end values (regular spacing)
     244                RangeTest(nbdim)=1; %to be updated for a later variable 
     245            end
     246            DimValue(nbdim)=sizvar(idim);
     247            ListDimName{nbdim}=DimName;
     248            DimIndex=[DimIndex nbdim];
     249        else % DimName is detected in the current list of dimension names
     250            if ~isequal(DimValue(iprev),sizvar(idim))
     251                if isequal(DimValue(iprev),2)&& RangeTest(iprev)  % the dimension has been already detected as a range [min max]
     252                    DimValue(iprev)=sizvar(idim); %update with actual value
     253                elseif ~testrange               
     254                    errormsg=['dimension declaration inconsistent with the size =[' num2str(sizvar) '] for ' VarName];
     255                    return
     256                end
     257            end
     258            DimIndex=[DimIndex iprev];
     259        end
     260    end
     261    VarDimIndex{ivar}=DimIndex;
     262end
     263DataOut=Data;
Note: See TracChangeset for help on using the changeset viewer.