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 | % DataOut: 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 cell array of variable names .ListVarNames'; |
---|
35 | return |
---|
36 | end |
---|
37 | %check dimension names |
---|
38 | if (isfield(Data,'VarDimName') && iscell(Data.VarDimName)) |
---|
39 | if numel(Data.VarDimName)~=nbfield |
---|
40 | errormsg=' .ListVarName and .VarDimName have different lengths'; |
---|
41 | return |
---|
42 | end |
---|
43 | else |
---|
44 | errormsg='input field does not contain the cell array of dimension names .VarDimName'; |
---|
45 | return |
---|
46 | end |
---|
47 | if isfield(Data,'DimValue') |
---|
48 | Data=rmfield(Data,'DimValue'); |
---|
49 | end |
---|
50 | nbdim=0; |
---|
51 | Data.ListDimName={}; |
---|
52 | |
---|
53 | %% main loop on the list of variables |
---|
54 | for ivar=1:nbfield |
---|
55 | VarName=Data.ListVarName{ivar}; |
---|
56 | if ~isfield(Data,VarName) |
---|
57 | errormsg=['the listed variable ' VarName ' is not found']; |
---|
58 | return |
---|
59 | end |
---|
60 | sizvar=size(Data.(VarName));% sizvar = dimension of variable |
---|
61 | DimCell=Data.VarDimName{ivar}; |
---|
62 | if ischar(DimCell) |
---|
63 | DimCell={DimCell};%case of a single dimension name, defined by a string |
---|
64 | elseif ~iscell(DimCell) |
---|
65 | errormsg=['wrong format for .VarDimName{' num2str(ivar) ' (must be the cell of dimension names of the variable ' VarName]; |
---|
66 | return |
---|
67 | |
---|
68 | end |
---|
69 | nbcoord=numel(sizvar);%nbre of coordinates for variable named VarName |
---|
70 | testrange=0; |
---|
71 | if numel(DimCell)==0 |
---|
72 | errormsg=['empty declared dimension .VarDimName{' num2str(ivar) '} for ' VarName]; |
---|
73 | return |
---|
74 | elseif numel(DimCell)==1% one dimension declared |
---|
75 | if nbcoord==2 |
---|
76 | if sizvar(1)==1 |
---|
77 | nbcoord=1; |
---|
78 | sizvar(1)=sizvar(2); |
---|
79 | elseif sizvar(2)==1 |
---|
80 | nbcoord=1; |
---|
81 | else |
---|
82 | errormsg=['1 dimension declared in .VarDimName{' num2str(ivar) '} inconsistent with the nbre of dimensions =2 of the variable ' VarName]; |
---|
83 | return |
---|
84 | end |
---|
85 | if sizvar(1)==2 && isequal(VarName,DimCell{1}) |
---|
86 | testrange=1;% test for a dimension variable representing a range |
---|
87 | end |
---|
88 | else |
---|
89 | errormsg=['1 dimension declared in .VarDimName{' num2str(ivar) '} inconsistent with the nbre of dimensions =' num2str(nbcoord) ' of the variable ' VarName]; |
---|
90 | return |
---|
91 | end |
---|
92 | else |
---|
93 | if numel(DimCell)>nbcoord |
---|
94 | sizvar(nbcoord+1:numel(DimCell))=1;% case of singleton dimensions (not seen by the function size) |
---|
95 | % DimCell=DimCell(end-nbcoord+1:end)%first singleton diemensions omitted, |
---|
96 | elseif nbcoord > numel(DimCell) |
---|
97 | errormsg=['nbre of declared dimensions in .VarDimName{' num2str(ivar) '} smaller than the nbre of dimensions =' num2str(nbcoord) ' of the variable ' VarName]; |
---|
98 | return |
---|
99 | end |
---|
100 | end |
---|
101 | DimIndex=[]; |
---|
102 | %for idim=1:nbcoord |
---|
103 | for idim=1:numel(DimCell) %loop on the coordinates of variable #ivar |
---|
104 | DimName=DimCell{idim}; |
---|
105 | iprev=find(strcmp(DimName,Data.ListDimName),1);%look for dimension name DimName in the current list |
---|
106 | if isempty(iprev)% append the dimension name to the current list |
---|
107 | nbdim=nbdim+1; |
---|
108 | RangeTest(nbdim)=0; %default |
---|
109 | if sizvar(idim)==2 && strcmp(DimName,VarName)%case of a coordinate defined by the two end values (regular spacing) |
---|
110 | RangeTest(nbdim)=1; %to be updated for a later variable |
---|
111 | end |
---|
112 | Data.DimValue(nbdim)=sizvar(idim); |
---|
113 | Data.ListDimName{nbdim}=DimName; |
---|
114 | DimIndex=[DimIndex nbdim]; |
---|
115 | else % DimName is detected in the current list of dimension names |
---|
116 | if ~isequal(Data.DimValue(iprev),sizvar(idim)) |
---|
117 | if isequal(Data.DimValue(iprev),2)&& RangeTest(iprev) % the dimension has been already detected as a range [min max] |
---|
118 | Data.DimValue(iprev)=sizvar(idim); %update with actual value |
---|
119 | elseif ~testrange |
---|
120 | errormsg=['dimension declaration inconsistent with the size =[' num2str(sizvar) '] for ' VarName]; |
---|
121 | return |
---|
122 | end |
---|
123 | end |
---|
124 | DimIndex=[DimIndex iprev]; |
---|
125 | end |
---|
126 | end |
---|
127 | Data.VarDimIndex{ivar}=DimIndex; |
---|
128 | end |
---|
129 | DataOut=Data; |
---|
130 | |
---|
131 | |
---|