[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] | 18 | function [errormsg,ListDimName,DimValue,VarDimIndex]=check_field_structure(Data) |
---|
[406] | 19 | errormsg=''; |
---|
| 20 | ListDimName={}; |
---|
| 21 | DimValue=[]; %default |
---|
| 22 | VarDimIndex={}; |
---|
[8] | 23 | if ~isstruct(Data) |
---|
| 24 | errormsg='input field is not a structure'; |
---|
| 25 | return |
---|
| 26 | end |
---|
| 27 | if isfield(Data,'ListVarName') && iscell(Data.ListVarName) |
---|
| 28 | nbfield=numel(Data.ListVarName); |
---|
| 29 | else |
---|
[140] | 30 | errormsg='input field does not contain the cell array of variable names .ListVarNames'; |
---|
[8] | 31 | return |
---|
| 32 | end |
---|
| 33 | %check dimension names |
---|
[140] | 34 | if (isfield(Data,'VarDimName') && iscell(Data.VarDimName)) |
---|
| 35 | if numel(Data.VarDimName)~=nbfield |
---|
| 36 | errormsg=' .ListVarName and .VarDimName have different lengths'; |
---|
| 37 | return |
---|
| 38 | end |
---|
| 39 | else |
---|
| 40 | errormsg='input field does not contain the cell array of dimension names .VarDimName'; |
---|
[8] | 41 | return |
---|
| 42 | end |
---|
[404] | 43 | % if isfield(Data,'DimValue') |
---|
| 44 | % Data=rmfield(Data,'DimValue'); |
---|
| 45 | % end |
---|
[140] | 46 | nbdim=0; |
---|
[404] | 47 | ListDimName={}; |
---|
[158] | 48 | |
---|
| 49 | %% main loop on the list of variables |
---|
[140] | 50 | for 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] | 124 | end |
---|
| 125 | DataOut=Data; |
---|
| 126 | |
---|
| 127 | |
---|