source: trunk/src/check_field_structure.m @ 511

Last change on this file since 511 was 508, checked in by sommeria, 12 years ago

various improvements

File size: 5.3 KB
RevLine 
[38]1%'check_field_structure': check the validity of the field struture representation consistant with the netcdf format
[89]2%------------------------------------------------------------------------
[8]3% function [DataOut,errormsg]=check_field_structure(Data)
4%
5% OUTPUT:
[404]6% DataOut: structure reproducing the input structure Data (TODO: suppress this output)
[8]7% errormsg: error message which is not empty when the input structure does not have the right form
8%
[89]9% INPUT:
[8]10% Data:   structure containing
11%         (optional) .ListGlobalAttribute: cell listing the names of the global attributes
12%                    .Att_1,Att_2... : values of the global attributes
13%         (requested)  .ListVarName: list of variable names to select (cell array of  char strings {'VarName1', 'VarName2',...} )
14%         (requested)  .VarDimName: list of dimension names for each element of .ListVarName (cell array of string cells)                         
15%         (requested) .Var1, .Var2....: variables (Matlab arrays) with names listed in .ListVarName
16
17
[404]18function [errormsg,ListDimName,DimValue,VarDimIndex]=check_field_structure(Data)
[406]19errormsg='';
20ListDimName={};
21DimValue=[]; %default
22VarDimIndex={};
[8]23if ~isstruct(Data)
24    errormsg='input field is not a structure';
25    return
26end
27if isfield(Data,'ListVarName') && iscell(Data.ListVarName)
28    nbfield=numel(Data.ListVarName);
29else
[508]30    errormsg='input field does not contain the cell array of variable names .ListVarName';
[8]31    return
32end
33%check dimension names
[140]34if (isfield(Data,'VarDimName') && iscell(Data.VarDimName))
35    if  numel(Data.VarDimName)~=nbfield
36       errormsg=' .ListVarName and .VarDimName have different lengths';
37        return
38    end
39else
40    errormsg='input field does not contain the  cell array of dimension names .VarDimName';
[8]41    return
42end
[404]43% if isfield(Data,'DimValue')
44%     Data=rmfield(Data,'DimValue');
45% end
[140]46nbdim=0;
[404]47ListDimName={};
[158]48
49%% main loop on the list of variables
[140]50for ivar=1:nbfield
51    VarName=Data.ListVarName{ivar};
52    if ~isfield(Data,VarName)
53        errormsg=['the listed variable ' VarName ' is not found'];
54        return
55    end
[382]56    sizvar=size(Data.(VarName));% sizvar = dimension of variable
[140]57    DimCell=Data.VarDimName{ivar};
58    if ischar(DimCell)
59        DimCell={DimCell};%case of a single dimension name, defined by a string
60    elseif ~iscell(DimCell)
61        errormsg=['wrong format for .VarDimName{' num2str(ivar) ' (must be the cell of dimension names of the variable ' VarName];
62        return
[382]63       
[140]64    end
[158]65    nbcoord=numel(sizvar);%nbre of coordinates for variable named VarName
66    testrange=0;
[140]67    if numel(DimCell)==0
68        errormsg=['empty declared dimension .VarDimName{' num2str(ivar) '} for ' VarName];
69        return
70    elseif numel(DimCell)==1% one dimension declared
71        if nbcoord==2
72            if sizvar(1)==1
73                nbcoord=1;
74                sizvar(1)=sizvar(2);
75            elseif sizvar(2)==1
76                nbcoord=1;
77            else
78                errormsg=['1 dimension declared in .VarDimName{' num2str(ivar) '} inconsistent with the nbre of dimensions =2 of the variable ' VarName];
[8]79                return
[140]80            end
[158]81            if sizvar(1)==2 && isequal(VarName,DimCell{1})
82                testrange=1;% test for a dimension variable representing a range
83            end
[140]84        else
85            errormsg=['1 dimension declared in .VarDimName{' num2str(ivar) '} inconsistent with the nbre of dimensions =' num2str(nbcoord) ' of the variable ' VarName];
86            return
87        end
88    else
89        if numel(DimCell)>nbcoord
[382]90            sizvar(nbcoord+1:numel(DimCell))=1;% case of singleton dimensions (not seen by the function size)
91           % DimCell=DimCell(end-nbcoord+1:end)%first singleton diemensions omitted,
[140]92        elseif nbcoord > numel(DimCell)
93            errormsg=['nbre of declared dimensions in .VarDimName{' num2str(ivar) '} smaller than the nbre of dimensions =' num2str(nbcoord) ' of the variable ' VarName];
94            return
95        end
96    end
97    DimIndex=[];
[382]98    %for idim=1:nbcoord
99    for idim=1:numel(DimCell) %loop on the coordinates of variable #ivar
[140]100        DimName=DimCell{idim};
[404]101        iprev=find(strcmp(DimName,ListDimName),1);%look for dimension name DimName in the current list
[140]102        if isempty(iprev)% append the dimension name to the current list
103            nbdim=nbdim+1;
[158]104            RangeTest(nbdim)=0; %default
[140]105            if sizvar(idim)==2 && strcmp(DimName,VarName)%case of a coordinate defined by the two end values (regular spacing)
106                RangeTest(nbdim)=1; %to be updated for a later variable 
107            end
[404]108            DimValue(nbdim)=sizvar(idim);
109            ListDimName{nbdim}=DimName;
[140]110            DimIndex=[DimIndex nbdim];
111        else % DimName is detected in the current list of dimension names
[404]112            if ~isequal(DimValue(iprev),sizvar(idim))
113                if isequal(DimValue(iprev),2)&& RangeTest(iprev)  % the dimension has been already detected as a range [min max]
114                    DimValue(iprev)=sizvar(idim); %update with actual value
[158]115                elseif ~testrange               
[140]116                    errormsg=['dimension declaration inconsistent with the size =[' num2str(sizvar) '] for ' VarName];
[8]117                    return
118                end
119            end
[140]120            DimIndex=[DimIndex iprev];
121        end
[8]122    end
[404]123    VarDimIndex{ivar}=DimIndex;
[8]124end
125DataOut=Data;
126   
127   
Note: See TracBrowser for help on using the repository browser.