| 1 | %'check_field_structure': check the validity of the field struture representation consistant with the netcdf format |
|---|
| 2 | %---------------------------------------------------------------------- |
|---|
| 3 | % function [DataOut,errormsg]=check_field_structure(Data) |
|---|
| 4 | % |
|---|
| 5 | % OUTPUT: |
|---|
| 6 | % Data: structure reproducing the input structure Data, with the additional elements: |
|---|
| 7 | % with fields: |
|---|
| 8 | % |
|---|
| 9 | % .ListDimName: cell listing the names of the array dimensions |
|---|
| 10 | % .DimValue: array dimension values (Matlab vector with the same length as .ListDimName |
|---|
| 11 | % .VarDimIndex: cell containing the set of dimension indices (in list .ListDimName) for each variable of .ListVarName |
|---|
| 12 | % .VarDimName: cell containing a cell of dimension names (in list .ListDimName) for each variable of .ListVarName |
|---|
| 13 | % errormsg: error message which is not empty when the input structure does not have the right form |
|---|
| 14 | % |
|---|
| 15 | %INPUT: |
|---|
| 16 | % Data: structure containing |
|---|
| 17 | % (optional) .ListGlobalAttribute: cell listing the names of the global attributes |
|---|
| 18 | % .Att_1,Att_2... : values of the global attributes |
|---|
| 19 | % (requested) .ListVarName: list of variable names to select (cell array of char strings {'VarName1', 'VarName2',...} ) |
|---|
| 20 | % (requested) .VarDimName: list of dimension names for each element of .ListVarName (cell array of string cells) |
|---|
| 21 | % (requested) .Var1, .Var2....: variables (Matlab arrays) with names listed in .ListVarName |
|---|
| 22 | |
|---|
| 23 | |
|---|
| 24 | function [DataOut,errormsg]=check_field_structure(Data) |
|---|
| 25 | DataOut=[]; %default |
|---|
| 26 | errormsg=[]; |
|---|
| 27 | if ~isstruct(Data) |
|---|
| 28 | errormsg='input field is not a structure'; |
|---|
| 29 | return |
|---|
| 30 | end |
|---|
| 31 | if isfield(Data,'ListVarName') && iscell(Data.ListVarName) |
|---|
| 32 | nbfield=numel(Data.ListVarName); |
|---|
| 33 | else |
|---|
| 34 | errormsg='input field does not contain the list of variables .ListVarNames'; |
|---|
| 35 | return |
|---|
| 36 | end |
|---|
| 37 | %check dimension names |
|---|
| 38 | % definition by VarDimIndex (obsolete) |
|---|
| 39 | % if ~isfield(Data,'VarDimName') && isfield(Data,'VarDimIndex') && isfield(Data,'ListDimName')%old convention |
|---|
| 40 | % for ivar=1:nbfield |
|---|
| 41 | % DimCell=Data.VarDimIndex{ivar}; |
|---|
| 42 | % if isnumeric(DimCell) |
|---|
| 43 | % if DimCell <= numel(Data.ListDimName) |
|---|
| 44 | % Data.VarDimName{ivar}=Data.ListDimName(DimCell); |
|---|
| 45 | % else |
|---|
| 46 | % errormsg='dimension names not defined'; |
|---|
| 47 | % return |
|---|
| 48 | % end |
|---|
| 49 | % else |
|---|
| 50 | % errormsg='unrecognized format for .VarDimIndex'; |
|---|
| 51 | % end |
|---|
| 52 | % end |
|---|
| 53 | % end |
|---|
| 54 | if ~(isfield(Data,'VarDimName') && iscell(Data.VarDimName)) |
|---|
| 55 | errormsg='input field does not contain the list of dimensions .VarDimName'; |
|---|
| 56 | return |
|---|
| 57 | end |
|---|
| 58 | if isfield(Data,'DimValue') |
|---|
| 59 | Data=rmfield(Data,'DimValue'); |
|---|
| 60 | end |
|---|
| 61 | if isfield(Data,'VarDimName') && iscell(Data.VarDimName) |
|---|
| 62 | nbdim=0; |
|---|
| 63 | if numel(Data.VarDimName)==nbfield |
|---|
| 64 | for ivar=1:nbfield |
|---|
| 65 | VarName=Data.ListVarName{ivar}; |
|---|
| 66 | if ~isfield(Data,VarName) |
|---|
| 67 | errormsg=['the listed variable ' VarName ' is not found']; |
|---|
| 68 | return |
|---|
| 69 | else |
|---|
| 70 | eval(['sizvar=size(Data.' VarName ');'])% sizvar = dimension of variable |
|---|
| 71 | DimCell=Data.VarDimName{ivar}; |
|---|
| 72 | if ischar(DimCell) |
|---|
| 73 | DimCell={DimCell}; |
|---|
| 74 | elseif ~iscell(DimCell) |
|---|
| 75 | errormsg=['wrong format for .VarDimName{' num2str(ivar) ' (must be the cell of dimension names of the variable ' VarName]; |
|---|
| 76 | return |
|---|
| 77 | end |
|---|
| 78 | nbcoord=numel(sizvar); |
|---|
| 79 | if numel(DimCell)==0 |
|---|
| 80 | errormsg=['empty declared dimension .VarDimName{' num2str(ivar) '} for ' VarName]; |
|---|
| 81 | return |
|---|
| 82 | elseif numel(DimCell)==1% one dimension declared |
|---|
| 83 | if nbcoord==2 |
|---|
| 84 | if sizvar(1)==1 |
|---|
| 85 | nbcoord=1; |
|---|
| 86 | sizvar(1)=sizvar(2); |
|---|
| 87 | elseif sizvar(2)==1 |
|---|
| 88 | nbcoord=1; |
|---|
| 89 | else |
|---|
| 90 | errormsg=['1 dimension declared in .VarDimName{' num2str(ivar) '} inconsistent with the nbre of dimensions =2 of the variable ' VarName]; |
|---|
| 91 | return |
|---|
| 92 | end |
|---|
| 93 | else |
|---|
| 94 | errormsg=['1 dimension declared in .VarDimName{' num2str(ivar) '} inconsistent with the nbre of dimensions =' num2str(nbcoord) ' of the variable ' VarName]; |
|---|
| 95 | return |
|---|
| 96 | end |
|---|
| 97 | else |
|---|
| 98 | if numel(DimCell)>nbcoord |
|---|
| 99 | DimCell=DimCell(end-nbcoord+1:end);%first singleton diemnsions omitted, |
|---|
| 100 | elseif nbcoord > numel(DimCell) |
|---|
| 101 | errormsg=['nbre of declared dimensions in .VarDimName{' num2str(ivar) '} smaller than the nbre of dimensions =' num2str(nbcoord) ' of the variable ' VarName]; |
|---|
| 102 | return |
|---|
| 103 | end |
|---|
| 104 | end |
|---|
| 105 | DimIndex=[]; |
|---|
| 106 | for idim=1:nbcoord %loop on the coordinates of variable #ivar |
|---|
| 107 | DimName=DimCell{idim}; |
|---|
| 108 | testprev=0; |
|---|
| 109 | for iprev=1:nbdim %check previously listed dimension names |
|---|
| 110 | if strcmp(Data.ListDimName{iprev},DimName) |
|---|
| 111 | if ~isequal(Data.DimValue(iprev),sizvar(idim)) |
|---|
| 112 | if isequal(Data.DimValue(iprev),0) % the dimension has been already detected as a range [min max] |
|---|
| 113 | Data.DimValue(idim)=sizvar(idim); %update with actual value |
|---|
| 114 | elseif sizvar(idim)==2 && strcmp(DimName,VarName) |
|---|
| 115 | %case of a regularly spaced coordinate defined by the first and last values: dimension will be determined later |
|---|
| 116 | else |
|---|
| 117 | errormsg=['dimension declaration inconsistent with the size =[' num2str(sizvar) '] for ' VarName]; |
|---|
| 118 | return |
|---|
| 119 | end |
|---|
| 120 | end |
|---|
| 121 | DimIndex=[DimIndex iprev]; |
|---|
| 122 | testprev=1; |
|---|
| 123 | break |
|---|
| 124 | end |
|---|
| 125 | end |
|---|
| 126 | if ~testprev % a new dimension is appended to the list |
|---|
| 127 | nbdim=nbdim+1; |
|---|
| 128 | if sizvar(idim)==2 && strcmp(DimName,VarName) |
|---|
| 129 | Data.DimValue(nbdim)=0; %to be updated for a later variable |
|---|
| 130 | % Data.VarType{ivar}='range'; |
|---|
| 131 | else |
|---|
| 132 | Data.DimValue(nbdim)=sizvar(idim); |
|---|
| 133 | end |
|---|
| 134 | Data.ListDimName{nbdim}=DimName; |
|---|
| 135 | DimIndex=[DimIndex nbdim]; |
|---|
| 136 | end |
|---|
| 137 | end |
|---|
| 138 | Data.VarDimIndex{ivar}=DimIndex; |
|---|
| 139 | end |
|---|
| 140 | end |
|---|
| 141 | else |
|---|
| 142 | errormsg=' .ListVarNames and .VarDimName have different lengths'; |
|---|
| 143 | return |
|---|
| 144 | end |
|---|
| 145 | else |
|---|
| 146 | errormsg='input field does not contain the cell of dimension names .VarDimName for variables'; |
|---|
| 147 | return |
|---|
| 148 | end |
|---|
| 149 | DataOut=Data; |
|---|
| 150 | |
|---|
| 151 | |
|---|