source: trunk/src/proj_field.m @ 210

Last change on this file since 210 was 206, checked in by sommeria, 13 years ago

bug fixes to deal with volumes, storage of ACTION menu in series fixed

File size: 100.9 KB
Line 
1%'proj_field': projects the field on a projection object
2%--------------------------------------------------------------------------
3%  function [ProjData,errormsg]=proj_field(FieldData,ObjectData)
4%
5% OUTPUT:
6% ProjData structure containing the fields of the input field FieldData,
7% transmitted or projected on the object, plus the additional fields
8%    .UMax, .UMin, .VMax, .VMin: min and max of velocity components in a domain
9%    .UMean,VMean: mean of the velocity components in a domain
10%    .AMin, AMax: min and max of a scalar
11%    .AMean: mean of a scalar in a domain 
12%  .NbPix;
13%  .DimName=  names of the matrix dimensions (matlab cell)
14%  .VarName= names of the variables [ProjData.VarName {'A','AMean','AMin','AMax'}];
15%  .VarDimNameIndex= dimensions of the variables, indicated by indices in the list .DimName;
16%
17%INPUT
18% ObjectData: structure characterizing the projection object
19%    .Style : style of projection object
20%    .ProjMode=type of projection ;
21%    .CoordType: 'px' or 'phys' type of coordinates defining the object position
22%    .Phi  angle of rotation (=0 by default)
23%    .ProjAngle=angle of projection;
24%    .DX,.DY,.DZ=increments along each coordinate
25%    .Coord(nbpoints,3): set of coordinates defining the object position;
26
27%FieldData: data of the field to be projected on the projection object, with optional fields
28%    .Txt: error message, transmitted to the projection
29%    .CoordType: 'px' or 'phys' type of coordinates of the field, must be the same as for the projection object, transmitted
30%    .Mesh: typical distance between data points (used for mouse action or display), transmitted
31%    .CoordUnit, .TimeUnit, .dt: transmitted
32% standardised description of fields, nc-formated Matlab structure with fields:
33%         .ListGlobalAttribute: cell listing the names of the global attributes
34%        .Att_1,Att_2... : values of the global attributes
35%            .ListVarName: cell listing the names of the variables
36%           .VarAttribute: cell of structures s containing names and values of variable attributes (s.name=value) for each variable of .ListVarName
37%        .Var1, .Var2....: variables (Matlab arrays) with names listed in .ListVarName
38% The variables are grouped in 'fields', made of a set of variables with common dimensions (using the function find_field_indices)
39% The variable attribute 'Role' is used to define the role for plotting:
40%       Role = 'scalar':  (default) represents a scalar field
41%            = 'coord':  represents a set of unstructured coordinates, whose
42%                     space dimension is given by the last array dimension (called 'NbDim').
43%            = 'coord_x', 'coord_y',  'coord_z': represents a separate set of
44%                        unstructured coordinate x, y  or z
45%            = 'vector': represents a vector field whose number of components
46%                is given by the last dimension (called 'NbDim')
47%            = 'vector_x', 'vector_y', 'vector_z'  :represents the x, y or z  component of a vector 
48%            = 'warnflag' : provides a warning flag about the quality of data in a 'Field', default=0, no warning
49%            = 'errorflag': provides an error flag marking false data,
50%                   default=0, no error. Different non zero values can represent different criteria of elimination.
51%
52% Default role of variables (by name)
53%  vector field:
54%    .X,.Y: position of the velocity vectors, projected on the object
55%    .U, .V, .W: velocity components, projected on the object
56%    .C, .CName: scalar associated to the vector
57%    .F : equivalent to 'warnflag'
58%    .FF: equivalent to 'errorflag'
59%  scalar field or image:
60%    .AName: name of a scalar (to be calculated from velocity fields after projection), transmitted
61%    .A: scalar, projected on the object
62%    .AX, .AY: positions for the scalar
63%     case of a structured grid: A is a dim 2 matrix and .AX=[first last] (length 2 vector) represents the first and last abscissa of the grid
64%     case of an unstructured scalar: A is a vector, AX and AY the corresponding coordinates
65%
66%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
67%  Copyright Joel Sommeria, 2008, LEGI / CNRS-UJF-INPG, sommeria@coriolis-legi.org.
68%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
69%     This file is part of the toolbox UVMAT.
70%
71%     UVMAT is free software; you can redistribute it and/or modify
72%     it under the terms of the GNU General Public License as published by
73%     the Free Software Foundation; either version 2 of the License, or
74%     (at your option) any later version.
75%
76%     UVMAT is distributed in the hope that it will be useful,
77%     but WITHOUT ANY WARRANTY; without even the implied warranty of
78%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
79%     GNU General Public License (file UVMAT/COPYING.txt) for more details.
80%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
81
82function [ProjData,errormsg]=proj_field(FieldData,ObjectData)
83errormsg='';%default
84%% case of no projection (object is used only as graph display)
85if isfield(ObjectData,'ProjMode') && (isequal(ObjectData.ProjMode,'none')||isequal(ObjectData.ProjMode,'mask_inside')||isequal(ObjectData.ProjMode,'mask_outside'))
86    ProjData=[];
87    return
88end
89
90%% in the absence of object Style or projection mode, or object coordinaes, the input field is just tranfered without change
91if ~isfield(ObjectData,'Style')||~isfield(ObjectData,'ProjMode')
92    ProjData=FieldData;
93    return
94end
95if ~isfield(ObjectData,'Coord')
96    if strcmp(ObjectData.Style,'plane')
97        ObjectData.Coord=[0 0 0];%default
98    else
99        ProjData=FieldData;
100        return
101    end
102end
103       
104%% OBSOLETE
105if isfield(ObjectData,'XMax') && ~isempty(ObjectData.XMax)
106    ObjectData.RangeX(1)=ObjectData.XMax;
107end
108if isfield(ObjectData,'XMin') && ~isempty(ObjectData.XMin)
109    ObjectData.RangeX(2)=ObjectData.XMin;
110end
111if isfield(ObjectData,'YMax') && ~isempty(ObjectData.YMax)
112    ObjectData.RangeY(1)=ObjectData.YMax;
113end
114if isfield(ObjectData,'YMin') && ~isempty(ObjectData.YMin)
115    ObjectData.RangeY(2)=ObjectData.YMin;
116end
117if isfield(ObjectData,'ZMax') && ~isempty(ObjectData.ZMax)
118    ObjectData.RangeZ(1)=ObjectData.ZMax;
119end
120if isfield(ObjectData,'ZMin') && ~isempty(ObjectData.ZMin)
121    ObjectData.RangeZ(2)=ObjectData.ZMin;
122end
123%%%%%%%%%%
124
125%% apply projection depending on the object style
126switch ObjectData.Style
127    case 'points'
128    [ProjData,errormsg]=proj_points(FieldData,ObjectData);
129    case {'line','polyline'}
130     [ProjData,errormsg] = proj_line(FieldData,ObjectData);
131    case {'polygon','rectangle','ellipse'}
132        if isequal(ObjectData.ProjMode,'inside')||isequal(ObjectData.ProjMode,'outside')
133            [ProjData,errormsg] = proj_patch(FieldData,ObjectData);
134        else
135            [ProjData,errormsg] = proj_line(FieldData,ObjectData);
136        end
137    case 'plane'
138            [ProjData,errormsg] = proj_plane(FieldData,ObjectData);
139    case 'volume'
140        [ProjData,errormsg] = proj_volume(FieldData,ObjectData);
141end
142
143%-----------------------------------------------------------------
144%project on a set of points
145function  [ProjData,errormsg]=proj_points(FieldData,ObjectData)%%
146%-------------------------------------------------------------------
147
148siz=size(ObjectData.Coord);
149width=0;
150if isfield(ObjectData,'Range')
151    width=ObjectData.Range(1,2);
152end
153if isfield(ObjectData,'RangeX')&&~isempty(ObjectData.RangeX)
154    width=max(ObjectData.RangeX);
155end
156if isfield(ObjectData,'RangeY')&&~isempty(ObjectData.RangeY)
157    width=max(width,max(ObjectData.RangeY));
158end
159if isfield(ObjectData,'RangeZ')&&~isempty(ObjectData.RangeZ)
160    width=max(width,max(ObjectData.RangeZ));
161end
162if isequal(ObjectData.ProjMode,'projection')
163    if width==0
164        errormsg='projection range around points needed';
165        return
166    end
167elseif  ~isequal(ObjectData.ProjMode,'interp')
168    errormsg=(['ProjMode option ' ObjectData.ProjMode ' not available in proj_field']);
169        return
170end
171[ProjData,errormsg]=proj_heading(FieldData,ObjectData);
172ProjData.NbDim=0;
173%ProjData.ListDimName= {'nb_points'};
174%ProjData.DimValue=siz(1);  %nbre of projection points 
175
176
177% idimvar=0;
178[CellVarIndex,NbDim,VarTypeCell,errormsg]=find_field_indices(FieldData);
179if ~isempty(errormsg)
180    errormsg=['error in proj_field/proj_points:' errormsg];
181    return
182end
183%LOOP ON GROUPS OF VARIABLES SHARING THE SAME DIMENSIONS
184% CellVarIndex=cells of variable index arrays
185% ivar_new=0; % index of the current variable in the projected field
186% icoord=0;
187for icell=1:length(CellVarIndex)
188    if NbDim(icell)==1
189        continue
190    end
191    VarIndex=CellVarIndex{icell};%  indices of the selected variables in the list FieldData.ListVarName
192    VarType=VarTypeCell{icell};
193    ivar_X=VarType.coord_x;
194    ivar_Y=VarType.coord_y;
195    ivar_Z=VarType.coord_z;
196%     ivar_U=VarType.vector_x;
197%     ivar_V=VarType.vector_y;
198%     ivar_W=VarType.vector_z;
199%     ivar_C=VarType.scalar ;
200    ivar_Anc=VarType.ancillary;
201%     test_anc=zeros(size(VarIndex));
202    test_anc(ivar_Anc)=ones(size(ivar_Anc));
203    ivar_F=VarType.warnflag;
204    ivar_FF=VarType.errorflag;
205    VarIndex([ivar_X ivar_Y ivar_Z ivar_Anc ivar_F ivar_FF])=[];% not projected variables removed frlom list
206    if isempty(ivar_X)
207        test_grid=1;%test for input data on regular grid (e.g. image)coordinates
208     
209    else
210        if length(ivar_X)>1 | length(ivar_Y)>1 | length(ivar_Z)>1
211                 errormsg='multiple coordinate input in proj_field.m';
212                    return
213        end
214        if length(ivar_Y)~=1
215                errormsg='y coordinate not defined in proj_field.m';
216                return
217        end
218        test_grid=0;
219    end
220    ProjData.ListVarName={'Y','X','NbVal'};
221    ProjData.VarDimName={'nb_points','nb_points','nb_points'};
222    %ProjData.VarDimIndex={[1],[1],[1]};
223    ProjData.VarAttribute{1}.Role='ancillary';
224    ProjData.VarAttribute{2}.Role='ancillary';
225    ProjData.VarAttribute{3}.Role='ancillary';
226    for ivar=VarIndex       
227        VarName=FieldData.ListVarName{ivar};
228        ProjData.ListVarName=[ProjData.ListVarName {VarName}];
229        %ProjData.VarDimIndex=[ProjData.VarDimIndex {[1]}];
230        ProjData.VarDimName=[ProjData.VarDimName {'nb_points'}];
231    end
232    if ~test_grid
233        eval(['coord_x=FieldData.' FieldData.ListVarName{ivar_X} ';'])
234        eval(['coord_y=FieldData.' FieldData.ListVarName{ivar_Y} ';'])
235        test3D=0;% TEST 3D CASE : NOT COMPLETED ,  3D CASE : NOT COMPLETED
236        if length(ivar_Z)==1
237            eval(['coord_z=FieldData.' FieldData.ListVarName{ivar_Z} ';'])
238            test3D=1;
239        end
240        if length(ivar_F)>1 | length(ivar_FF)>1
241                 msgbox_uvmat('ERROR','multiple flag input in proj_field.m')
242                    return
243        end     
244        for ipoint=1:siz(1)
245           Xpoint=ObjectData.Coord(ipoint,:);
246           distX=coord_x-Xpoint(1);
247           distY=coord_y-Xpoint(2);         
248           dist=distX.*distX+distY.*distY;
249           indsel=find(dist<width*width);
250           ProjData.X(ipoint,1)=Xpoint(1);
251           ProjData.Y(ipoint,1)=Xpoint(2);
252           if isequal(length(ivar_FF),1)
253               FFName=FieldData.ListVarName{ivar_FF};
254               eval(['FF=FieldData.' FFName '(indsel);'])
255               ind_indsel=find(~FF);
256               indsel=indsel(ind_indsel);
257           end
258           ProjData.NbVal(ipoint,1)=length(indsel);
259            for ivar=VarIndex
260               VarName=FieldData.ListVarName{ivar};
261               if isempty(indsel)
262                    eval(['ProjData.' VarName '(ipoint,1)=NaN;'])
263               else
264                    eval(['Var=FieldData.' VarName '(indsel);'])
265                    eval(['ProjData.' VarName '(ipoint,1)=mean(Var);'])
266                    if isequal(ObjectData.ProjMode,'interp')
267                         eval(['ProjData.' VarName '(ipoint,1)=griddata_uvmat(coord_x(indsel),coord_y(indsel),Var,Xpoint(1),Xpoint(2)))';])
268                    end
269               end
270            end
271        end
272    else
273        %DimIndices=FieldData.VarDimIndex{VarIndex(1)};%indices of the dimensions of the first variable (common to all variables in the cell)
274        %case of structured coordinates
275        if  numel(VarType.coord)>=2 & VarType.coord(1:2) > 0;
276            AYName=FieldData.ListVarName{VarType.coord(1)};
277            AXName=FieldData.ListVarName{VarType.coord(2)};
278            eval(['AX=FieldData.' AXName ';']);% set of x positions
279            eval(['AY=FieldData.' AYName ';']);% set of y positions 
280            AName=FieldData.ListVarName{VarIndex(1)};
281            eval(['A=FieldData.' AName ';']);% scalar
282            npxy=size(A);
283
284% %             nbcolor=1; %default
285%             for idim=1:length(ListDimName)
286%                 DimName=ListDimName{idim};
287%                 if isequal(DimName,'rgb')|isequal(DimName,'nb_coord')|isequal(DimName,'nb_coord_i')
288%                    nbcolor=npxy(idim);
289%                    DimIndices(idim)=[];
290%                    npxy(idim)=[];
291%                 end
292%                 if isequal(DimName,'nb_coord_j')% NOTE: CASE OF TENSOR NOT TREATED
293%                     DimIndices(idim)=[];
294%                     npxy(idim)=[];
295%                 end
296%             end 
297            ind_1=find(npxy==1);
298            %DimIndices(ind_1)=[]; %suppress singleton dimensions
299%             indxy=find(DimVarIndex(DimIndices));%select dimension variables (DimIndices non zero)
300            %NbDim=length(DimIndices)%number of space dimensions
301            NbDim=numel(VarType.coord);
302            Coord_z=[];
303            Coord_y=[];
304            Coord_x=[];   
305            for idim=1:NbDim %loop on space dimensions
306                test_interp(idim)=0;%test for coordiate interpolation (non regular grid), =0 by default
307                test_coord(idim)=0;%test for defined coordinates, =0 by default
308                %ivar=DimVarIndex(DimIndices(idim));% index of the variable corresponding to the current dimension
309                ivar=VarType.coord(idim);
310%                 if ~isequal(ivar,0)%  a variable corresponds to the current dimension
311                    eval(['Coord{idim}=FieldData.' FieldData.ListVarName{ivar} ';']) ;% position for the first index
312                    if numel(Coord{idim})==2
313                       DCoord_min(idim)= (Coord{idim}(2)-Coord{idim}(1))/(npxy(idim)-1);
314                    else
315                        DCoord=diff(Coord{idim});
316                        DCoord_min(idim)=min(DCoord);
317                        DCoord_max=max(DCoord);
318                        test_direct(idim)=DCoord_max>0;% =1 for increasing values, 0 otherwise
319                        test_direct_min=DCoord_min(idim)>0;% =1 for increasing values, 0 otherwise
320                        if ~isequal(test_direct(idim),test_direct_min)
321                            errormsg=['non monotonic dimension variable # ' num2str(idim)  ' in proj_field.m'];
322                                    return
323                        end               
324                        test_interp(idim)=(DCoord_max-DCoord_min(idim))> 0.0001*abs(DCoord_max);% test grid regularity
325                        test_coord(idim)=1;
326                    end
327%                 else  % no variable associated with the first dimension, look fo variable  attributes Coord_1, _2 or _3
328%                     Coord_i_str=['Coord_' num2str(idim)];
329%                     DCoord_min(idim)=1;%default
330%                     Coord{idim}=[0.5 npxy(idim)];
331%                     test_direct(idim)=1;
332%                 end
333            end
334            DX=DCoord_min(2);
335            DY=DCoord_min(1);
336            for ipoint=1:siz(1)
337                xwidth=width/(abs(DX));
338                ywidth=width/(abs(DY));
339                i_min=round((ObjectData.Coord(ipoint,1)-Coord{2}(1))/DX+0.5-xwidth); %minimum index of the selected region
340                i_min=max(1,i_min);%restrict to field limit
341                i_plus=round((ObjectData.Coord(ipoint,1)-Coord{2}(1))/DX+0.5+xwidth);
342                i_plus=min(npxy(2),i_plus); %restrict to field limit
343                j_min=round((ObjectData.Coord(ipoint,2)-Coord{1}(1))/DY-ywidth+0.5);
344                j_min=max(1,j_min);
345                j_plus=round((ObjectData.Coord(ipoint,2)-Coord{1}(1))/DY+ywidth+0.5);
346                j_plus=min(npxy(1),j_plus);
347                ProjData.X(ipoint,1)=ObjectData.Coord(ipoint,1);
348                ProjData.Y(ipoint,1)=ObjectData.Coord(ipoint,2);
349                i_int=(i_min:i_plus);
350                j_int=(j_min:j_plus);
351                ProjData.NbVal(ipoint,1)=length(j_int)*length(i_int);
352                if isempty(i_int) || isempty(j_int)
353                   for ivar=VarIndex   
354                        eval(['ProjData.' FieldData.ListVarName{ivar} '(ipoint,:)=NaN;']);
355                   end
356                   errormsg=['no data points in the selected projection range ' num2str(width) ];
357                else
358                    %TODO: introduce circle in the selected subregion
359                    %[I,J]=meshgrid([1:j_int],[1:i_int]);
360                    for ivar=VarIndex   
361                        eval(['Avalue=FieldData.' FieldData.ListVarName{ivar} '(j_int,i_int,:);']);
362                        eval(['ProjData.' FieldData.ListVarName{ivar} '(ipoint,:)=mean(mean(Avalue));']);
363                    end
364                end
365            end
366        end
367   end
368end
369
370%-----------------------------------------------------------------
371%project in a patch
372function  [ProjData,errormsg]=proj_patch(FieldData,ObjectData)%%
373%-------------------------------------------------------------------
374[ProjData,errormsg]=proj_heading(FieldData,ObjectData);
375
376objectfield=fieldnames(ObjectData);
377widthx=0;
378widthy=0;
379if isfield(ObjectData,'RangeX')&~isempty(ObjectData.RangeX)
380    widthx=max(ObjectData.RangeX);
381end
382if isfield(ObjectData,'RangeY')&~isempty(ObjectData.RangeY)
383    widthy=max(ObjectData.RangeY);
384end
385
386%A REVOIR, GENERALISER: UTILISER proj_line
387ProjData.NbDim=1;
388ProjData.ListVarName={};
389ProjData.VarDimName={};
390ProjData.VarAttribute={};
391
392Mesh=zeros(1,numel(FieldData.ListVarName));
393if isfield (FieldData,'VarAttribute')
394    %ProjData.VarAttribute=FieldData.VarAttribute;%list of variable attribute names
395    for iattr=1:length(FieldData.VarAttribute)%initialization of variable attribute values
396%         ProjData.VarAttribute{iattr}={};
397        if isfield(FieldData.VarAttribute{iattr},'Unit')
398            unit{iattr}=FieldData.VarAttribute{iattr}.Unit;
399        end
400        if isfield(FieldData.VarAttribute{iattr},'Mesh')
401            Mesh(iattr)=FieldData.VarAttribute{iattr}.Mesh;
402        end
403    end
404end
405
406%group the variables (fields of 'FieldData') in cells of variables with the same dimensions
407testfalse=0;
408ListIndex={};
409% DimVarIndex=0;%initilise list of indices for dimension variables
410idimvar=0;
411[CellVarIndex,NbDim,VarTypeCell,errormsg]=find_field_indices(FieldData);
412if ~isempty(errormsg)
413    errormsg=['error in proj_field/proj_patch:' errormsg];
414    return
415end
416
417%LOOP ON GROUPS OF VARIABLES SHARING THE SAME DIMENSIONS
418dimcounter=0;
419for icell=1:length(CellVarIndex)
420    testX=0;
421    testY=0;
422    test_Amat=0;
423    testfalse=0;
424    VarIndex=CellVarIndex{icell};%  indices of the selected variables in the list FieldData.ListVarName
425    VarType=VarTypeCell{icell};
426  %  DimIndices=FieldData.VarDimIndex{VarIndex(1)};%indices of the dimensions of the first variable (common to all variables in the cell)
427    if NbDim(icell)~=2% proj_patch acts only on fields of space dimension 2
428        continue
429    end
430    testX=~isempty(VarType.coord_x) && ~isempty(VarType.coord_y);
431    testfalse=~isempty(VarType.errorflag);
432    testproj(VarIndex)=zeros(size(VarIndex));%default
433    testproj(VarType.scalar)=1;
434    testproj(VarType.vector_x)=1;
435    testproj(VarType.vector_y)=1;
436    testproj(VarType.vector_z)=1;
437    testproj(VarType.image)=1;
438    testproj(VarType.color)=1;
439    VarIndex=VarIndex(find(testproj(VarIndex)));%select only the projected variables
440    if testX %case of unstructured coordinates
441         eval(['nbpoint=numel(FieldData.' FieldData.ListVarName{VarIndex(1)} ');'])
442         for ivar=[VarIndex VarType.coord_x VarType.coord_y VarType.errorflag]
443               VarName=FieldData.ListVarName{ivar};
444            eval(['FieldData.' VarName '=reshape(FieldData.' VarName ',nbpoint,1);'])
445         end
446         XName=FieldData.ListVarName{VarType.coord_x};
447         YName=FieldData.ListVarName{VarType.coord_y};
448         eval(['coord_x=FieldData.' XName ';'])
449         eval(['coord_y=FieldData.' YName ';'])
450    end
451    if testfalse
452        FFName=FieldData.ListVarName{VarType.errorflag};
453        eval(['errorflag=FieldData.' FFName ';'])
454    end
455    % image or 2D matrix
456    if numel(VarType.coord)>=2 & VarType.coord(1:2) > 0;
457        test_Amat=1;% test for image or 2D matrix
458        AYName=FieldData.ListVarName{VarType.coord(1)};
459        AXName=FieldData.ListVarName{VarType.coord(2)};
460        eval(['AX=FieldData.' AXName ';'])% x coordinate
461        eval(['AY=FieldData.' AYName ';'])% y coordinate
462        VarName=FieldData.ListVarName{VarIndex(1)};
463        eval(['DimValue=size(FieldData.' VarName ');'])
464       if length(AX)==2
465           AX=linspace(AX(1),AX(end),DimValue(2));
466       end
467       if length(AY)==2
468           AY=linspace(AY(1),AY(end),DimValue(1));
469       end
470%         for idim=1:length(DimValue)       
471%             Coord_i_str=['Coord_' num2str(idim)];
472%             DCoord_min(idim)=1;%default
473%             Coord{idim}=[0.5 DimValue(idim)];
474%             test_direct(idim)=1;
475%         end
476%         AX=linspace(Coord{2}(1),Coord{2}(2),DimValue(2));
477%         AY=linspace(Coord{1}(1),Coord{1}(2),DimValue(1));  %TODO : 3D case
478        testcolor=find(numel(DimValue)==3);
479        if length(DimValue)==3
480            testcolor=1;
481            npxy(3)=3;
482        else
483            testcolor=0;
484            npxy(3)=1;
485        end
486        [Xi,Yi]=meshgrid(AX,AY);
487        npxy(1)=length(AY);
488        npxy(2)=length(AX);
489        Xi=reshape(Xi,npxy(1)*npxy(2),1);
490        Yi=reshape(Yi,npxy(1)*npxy(2),1);
491        for ivar=1:length(VarIndex)
492            VarName=FieldData.ListVarName{VarIndex(ivar)};
493            eval(['FieldData.' VarName '=reshape(FieldData.' VarName ',npxy(1)*npxy(2),npxy(3));']); % keep only non false vectors
494        end
495    end
496%select the indices in the range of action
497    testin=[];%default
498    if isequal(ObjectData.Style,'rectangle')
499%            if ~isfield(ObjectData,'RangeX')|~isfield(ObjectData,'RangeY')
500%                 errormsg='rectangle half sides RangeX and RangeY needed'
501%                 return
502%            end
503       if testX
504            distX=abs(coord_x-ObjectData.Coord(1,1));
505            distY=abs(coord_y-ObjectData.Coord(1,2));
506            testin=distX<widthx & distY<widthy;
507       elseif test_Amat
508           distX=abs(Xi-ObjectData.Coord(1,1));
509           distY=abs(Yi-ObjectData.Coord(1,2));
510           testin=distX<widthx & distY<widthy;
511       end
512    elseif isequal(ObjectData.Style,'polygon')
513        if testX
514            testin=inpolygon(coord_x,coord_y,ObjectData.Coord(:,1),ObjectData.Coord(:,2));
515        elseif test_Amat
516           testin=inpolygon(Xi,Yi,ObjectData.Coord(:,1),ObjectData.Coord(:,2));
517       else%calculate the scalar
518           testin=[]; %A REVOIR
519       end
520    elseif isequal(ObjectData.Style,'ellipse')
521       X2Max=widthx*widthx;
522       Y2Max=(widthy)*(widthy);
523       if testX
524            distX=(coord_x-ObjectData.Coord(1,1));
525            distY=(coord_y-ObjectData.Coord(1,2));
526            testin=(distX.*distX/X2Max+distY.*distY/Y2Max)<1;
527       elseif test_Amat %case of usual 2x2 matrix
528           distX=(Xi-ObjectData.Coord(1,1));
529           distY=(Yi-ObjectData.Coord(1,2));
530           testin=(distX.*distX/X2Max+distY.*distY/Y2Max)<1;
531       end
532    end
533    %selected indices
534    if isequal(ObjectData.ProjMode,'outside')
535            testin=~testin;
536    end
537    if testfalse
538        testin=testin & (errorflag==0); % keep only non false vectors         
539    end
540    indsel=find(testin);
541    for ivar=VarIndex
542        if testproj(ivar)
543            VarName=FieldData.ListVarName{ivar};
544            eval(['ProjData.' VarName 'Mean=mean(mean(double(FieldData.' VarName '(indsel,:))));']); % keep only non false vectors
545            eval(['ProjData.' VarName 'Min=min(min(double(FieldData.' VarName '(indsel,:))));']); % keep only non false vectors
546            eval(['ProjData.' VarName 'Max=max(max(double(FieldData.' VarName '(indsel,:))));']); % keep only non false vectors
547            if isequal(Mesh(ivar),0)
548                eval(['[ProjData.' VarName 'Histo,ProjData.' VarName ']=hist(double(FieldData.' VarName '(indsel,:)),100);']); % default histogram with 100 bins
549            else
550                eval(['ProjData.' VarName '=(ProjData.' VarName 'Min+Mesh(ivar)/2:Mesh(ivar):ProjData.' VarName 'Max);']); % list of bin values
551                eval(['ProjData.' VarName 'Histo=hist(double(FieldData.' VarName '(indsel,:)),ProjData.' VarName ');']); % histogram at predefined bin positions
552            end
553            ProjData.ListVarName=[ProjData.ListVarName {VarName} {[VarName 'Histo']} {[VarName 'Mean']} {[VarName 'Min']} {[VarName 'Max']}];
554            if test_Amat && testcolor
555                 ProjData.VarDimName=[ProjData.VarDimName  {VarName} {{VarName,'rgb'}} {'rgb'}];%{{'nb_point','rgb'}};
556            else
557               ProjData.VarDimName=[ProjData.VarDimName {VarName} {VarName} {'nbpoint'} {'nbpoint'} {'nbpoint'}];
558            end
559            ProjData.VarAttribute=[ProjData.VarAttribute FieldData.VarAttribute{ivar} {[]} {[]} {[]} {[]}];
560        end
561    end
562%     if test_Amat & testcolor
563%        %ProjData.ListDimName=[ProjData.ListDimName {'rgb'}];
564%       % ProjData.DimValue=[ProjData.DimValue 3];
565%       % ProjData.VarDimIndex={[1 2]};
566%        ProjData.VarDimName=[ProjData.VarDimName {VarName} {VarName,'rgb'}];%{{'nb_point','rgb'}};
567%        ProjData.VarDimName
568%     end
569end
570
571
572%-----------------------------------------------------------------
573%project on a line
574% AJOUTER flux,circul,error
575function  [ProjData,errormsg] = proj_line(FieldData, ObjectData)
576%-----------------------------------------------------------------
577[ProjData,errormsg]=proj_heading(FieldData,ObjectData);%transfer global attributes
578if ~isempty(errormsg)
579    return
580end
581ProjData.NbDim=1;
582%initialisation of the input parameters and defaultoutput
583ProjMode='projection';%direct projection on the line by default
584if isfield(ObjectData,'ProjMode'),ProjMode=ObjectData.ProjMode; end;
585ProjAngle=90; %90 degrees projection by default
586if isfield(FieldData,'ProjAngle'),ProjAngle=ObjectData.ProjAngle; end;
587width=0;%default width of the projection band
588if isfield(ObjectData,'Range')&size(ObjectData.Range,2)>=2
589    width=abs(ObjectData.Range(1,2));
590end
591if isfield(ObjectData,'RangeY')
592    width=max(ObjectData.RangeY);
593end
594
595% default output
596errormsg=[];%default
597Xline=[];
598flux=0;
599circul=0;
600liny=ObjectData.Coord(:,2);
601siz_line=size(ObjectData.Coord);
602if siz_line(1)<2
603    return% line needs at least 2 points to be defined
604end
605testfalse=0;
606ListIndex={};
607
608%angles of the polyline and boundaries of action
609dlinx=diff(ObjectData.Coord(:,1));
610dliny=diff(ObjectData.Coord(:,2));
611theta=angle(dlinx+i*dliny);%angle of each segment
612theta(siz_line(1))=theta(siz_line(1)-1);
613% determine a rectangles at +-width from the line (only used for the ProjMode='projection or 'filter')
614if isequal(ProjMode,'projection') || isequal(ProjMode,'filter')
615    xsup(1)=ObjectData.Coord(1,1)-width*sin(theta(1));
616    xinf(1)=ObjectData.Coord(1,1)+width*sin(theta(1));
617    ysup(1)=ObjectData.Coord(1,2)+width*cos(theta(1));
618    yinf(1)=ObjectData.Coord(1,2)-width*cos(theta(1));
619    for ip=2:siz_line(1)
620        xsup(ip)=ObjectData.Coord(ip,1)-width*sin((theta(ip)+theta(ip-1))/2)/cos((theta(ip-1)-theta(ip))/2);
621        xinf(ip)=ObjectData.Coord(ip,1)+width*sin((theta(ip)+theta(ip-1))/2)/cos((theta(ip-1)-theta(ip))/2);
622        ysup(ip)=ObjectData.Coord(ip,2)+width*cos((theta(ip)+theta(ip-1))/2)/cos((theta(ip-1)-theta(ip))/2);
623        yinf(ip)=ObjectData.Coord(ip,2)-width*cos((theta(ip)+theta(ip-1))/2)/cos((theta(ip-1)-theta(ip))/2);
624    end
625end
626
627%group the variables (fields of 'FieldData') in cells of variables with the same dimensions
628[CellVarIndex,NbDim,VarTypeCell,errormsg]=find_field_indices(FieldData);
629if ~isempty(errormsg)
630    errormsg=['error in proj_field/proj_line:' errormsg];
631    return
632end
633
634% loop on variable cells with the same space dimension
635ProjData.ListVarName={};
636ProjData.VarDimName={};
637for icell=1:length(CellVarIndex)
638    VarIndex=CellVarIndex{icell};%  indices of the selected variables in the list FieldData.ListVarName
639    VarType=VarTypeCell{icell}; %types of variables
640    if NbDim(icell)~=2% proj_line acts only on fields of space dimension 2, TODO: check 3D case
641        continue
642    end
643    testX=~isempty(VarType.coord_x) && ~isempty(VarType.coord_y);% test for unstructured coordinates
644    testU=~isempty(VarType.vector_x) && ~isempty(VarType.vector_y);% test for vectors
645    testfalse=~isempty(VarType.errorflag);% test for error flag
646    testproj(VarIndex)=zeros(size(VarIndex));% test =1 for simply projected variables, default =0
647                                             %=0 for vector components, treated separately
648    testproj(VarType.scalar)=1;
649    testproj(VarType.image)=1;
650    testproj(VarType.color)=1;
651    VarIndex=VarIndex(find(testproj(VarIndex)));%select only the projected variables
652    if testU
653         VarIndex=[VarIndex VarType.vector_x VarType.vector_y];%append u and v at the end of the list of variables
654    end
655    %identify vector components   
656    if testU
657        UName=FieldData.ListVarName{VarType.vector_x};
658        VName=FieldData.ListVarName{VarType.vector_y};
659        eval(['vector_x=FieldData.' UName ';'])
660        eval(['vector_y=FieldData.' VName ';'])
661    end 
662    %identify error flag
663    if testfalse
664        FFName=FieldData.ListVarName{VarType.errorflag};
665        eval(['errorflag=FieldData.' FFName ';'])
666    end   
667    % check needed object properties for unstructured positions (position given by the variables with role coord_x, coord_y
668    if testX
669        if  ~isequal(ProjMode,'interp')
670            if width==0
671                errormsg='range of the projection object is missing';
672                return     
673            else
674                lambda=2/(width*width); %smoothing factor used for filter: weight exp(-2) at distance width from the line
675            end
676        end
677        if ~isequal(ProjMode,'projection')
678            if isfield(ObjectData,'DX')&~isempty(ObjectData.DX)
679                DX=abs(ObjectData.DX);%mesh of interpolation points along the line
680            else
681                errormsg='DX missing';
682                return
683            end
684        end
685        XName= FieldData.ListVarName{VarType.coord_x};
686        YName= FieldData.ListVarName{VarType.coord_y};
687        eval(['coord_x=FieldData.' XName ';'])   
688        eval(['coord_y=FieldData.' YName ';'])
689    end   
690    %initiate projection
691    for ivar=1:length(VarIndex)
692        ProjLine{ivar}=[];
693    end
694    XLine=[];
695    linelengthtot=0;
696
697%         circul=0;
698%         flux=0;
699  %%%%%%%  % A FAIRE CALCULER MEAN DES QUANTITES    %%%%%%
700   %case of unstructured coordinates
701    if testX   
702        for ip=1:siz_line(1)-1     %Loop on the segments of the polyline
703            linelength=sqrt(dlinx(ip)*dlinx(ip)+dliny(ip)*dliny(ip)); 
704            %select the vector indices in the range of action
705            if testfalse
706                flagsel=(errorflag==0); % keep only non false vectors
707            else
708                flagsel=ones(size(coord_x));
709            end
710            if isequal(ProjMode,'projection') | isequal(ProjMode,'filter')
711                flagsel=flagsel & ((coord_y -yinf(ip))*(xinf(ip+1)-xinf(ip))>(coord_x-xinf(ip))*(yinf(ip+1)-yinf(ip))) ...
712                & ((coord_y -ysup(ip))*(xsup(ip+1)-xsup(ip))<(coord_x-xsup(ip))*(ysup(ip+1)-ysup(ip))) ...
713                & ((coord_y -yinf(ip+1))*(xsup(ip+1)-xinf(ip+1))>(coord_x-xinf(ip+1))*(ysup(ip+1)-yinf(ip+1))) ...
714                & ((coord_y -yinf(ip))*(xsup(ip)-xinf(ip))<(coord_x-xinf(ip))*(ysup(ip)-yinf(ip)));
715            end
716            indsel=find(flagsel);%indsel =indices of good vectors
717            X_sel=coord_x(indsel);
718            Y_sel=coord_y(indsel);
719            nbvar=0;
720            for iselect=1:numel(VarIndex)-2*testU
721                VarName=FieldData.ListVarName{VarIndex(iselect)};
722                eval(['ProjVar{iselect}=FieldData.' VarName '(indsel);']);%scalar value
723            end   
724            if testU
725                ProjVar{numel(VarIndex)-1}=cos(theta(ip))*vector_x(indsel)+sin(theta(ip))*vector_y(indsel);% longitudinal component
726                ProjVar{numel(VarIndex)}=-sin(theta(ip))*vector_x(indsel)+cos(theta(ip))*vector_y(indsel);%transverse component         
727            end
728            if isequal(ProjMode,'projection')
729                sintheta=sin(theta(ip));
730                costheta=cos(theta(ip));
731                Xproj=(X_sel-ObjectData.Coord(ip,1))*costheta + (Y_sel-ObjectData.Coord(ip,2))*sintheta; %projection on the line
732                [Xproj,indsort]=sort(Xproj);
733                for ivar=1:numel(ProjVar)
734                    if ~isempty(ProjVar{ivar})
735                        ProjVar{ivar}=ProjVar{ivar}(indsort);
736                     end
737                end
738            elseif isequal(ProjMode,'interp') %linear interpolation:
739                npoint=floor(linelength/DX)+1;% nbre of points in the profile (interval DX)
740                Xproj=linelength/(2*npoint):linelength/npoint:linelength-linelength/(2*npoint);
741                xreg=cos(theta(ip))*Xproj+ObjectData.Coord(ip,1);
742                yreg=sin(theta(ip))*Xproj+ObjectData.Coord(ip,2);
743                for ivar=1:numel(ProjVar)
744                     if ~isempty(ProjVar{ivar})
745                        ProjVar{ivar}=griddata_uvmat(X_sel,Y_sel,ProjVar{ivar},xreg,yreg);
746                     end
747                end
748            elseif isequal(ProjMode,'filter') %filtering
749                npoint=floor(linelength/DX)+1;% nbre of points in the profile (interval DX)
750                Xproj=[linelength/(2*npoint):linelength/npoint:linelength-linelength/(2*npoint)];
751                siz=size(X_sel);
752                xregij=cos(theta(ip))*Xproj'*ones(1,siz(2))+ObjectData.Coord(ip,1);
753                yregij=sin(theta(ip))*Xproj'*ones(1,siz(2))+ObjectData.Coord(ip,2);
754                xij=ones(npoint,1)*X_sel;
755                yij=ones(npoint,1)*Y_sel;
756                Aij=exp(-lambda*((xij-xregij).*(xij-xregij)+(yij-yregij).*(yij-yregij)));
757                norm=ones(1,siz(2))*Aij';
758                for ivar=1:numel(ProjVar)
759                     if ~isempty(ProjVar{ivar})
760                        ProjVar{ivar}=ProjVar{ivar}*Aij'./norm;
761                     end
762                end             
763            end
764            %prolongate the total record
765            for ivar=1:numel(ProjVar)
766                  if ~isempty(ProjVar{ivar})
767                     ProjLine{ivar}=[ProjLine{ivar}; ProjVar{ivar}];
768                  end
769            end
770            XLine=[XLine ;(Xproj+linelengthtot)];%along line abscissa
771            linelengthtot=linelengthtot+linelength;
772            %     circul=circul+(sum(U_sel))*linelength/npoint;
773            %     flux=flux+(sum(V_sel))*linelength/npoint;
774        end
775        ProjData.X=XLine';
776        cur_index=1;
777        ProjData.ListVarName=[ProjData.ListVarName {XName}];
778        ProjData.VarDimName=[ProjData.VarDimName {XName}];
779        ProjData.VarAttribute{1}.long_name='abscissa along line';
780        for iselect=1:numel(VarIndex)
781            VarName=FieldData.ListVarName{VarIndex(iselect)};
782            eval(['ProjData.' VarName '=ProjLine{iselect};'])
783            ProjData.ListVarName=[ProjData.ListVarName {VarName}];
784            ProjData.VarDimName=[ProjData.VarDimName {XName}];
785            ProjData.VarAttribute{iselect}=FieldData.VarAttribute{VarIndex(iselect)};
786            if strcmp(ProjMode,'projection')
787                ProjData.VarAttribute{iselect}.Role='discrete';
788            else
789                 ProjData.VarAttribute{iselect}.Role='continuous';
790            end
791        end
792   
793    %case of structured coordinates
794    elseif  numel(VarType.coord)>=2 & VarType.coord(1:2) > 0;
795        if ~isequal(ObjectData.Style,'line')% exclude polyline
796            errormsg=['no  projection available on ' ObjectData.Style 'for structured coordinates']; %
797        else
798            test_Amat=1;%image or 2D matrix
799            test_interp2=0;%default
800%             if ~isempty(VarType.coord_y) 
801            AYName=FieldData.ListVarName{VarType.coord(1)};
802            AXName=FieldData.ListVarName{VarType.coord(2)};
803            eval(['AX=FieldData.' AXName ';']);% set of x positions
804            eval(['AY=FieldData.' AYName ';']);% set of y positions 
805            AName=FieldData.ListVarName{VarIndex(1)};
806            eval(['A=FieldData.' AName ';']);% scalar
807            npxy=size(A);
808            npx=npxy(2);
809            npy=npxy(1);
810            if numel(AX)==2
811                DX=(AX(2)-AX(1))/(npx-1);
812            else
813                DX_vec=diff(AX);
814                DX=max(DX_vec);
815                DX_min=min(DX_vec);
816                if (DX-DX_min)>0.0001*abs(DX)
817                    test_interp2=1;
818                    DX=DX_min;
819                end   
820            end
821            if numel(AY)==2
822                DY=(AY(2)-AY(1))/(npy-1);
823            else
824                DY_vec=diff(AY);
825                DY=max(DY_vec);
826                DY_min=min(DY_vec);
827                if (DY-DY_min)>0.0001*abs(DY)
828                   test_interp2=1;
829                    DY=DY_min;
830                end     
831            end             
832            AXI=linspace(AX(1),AX(end), npx);%set of  x  positions for the interpolated input data
833            AYI=linspace(AY(1),AY(end), npy);%set of  x  positions for the interpolated input data
834            if isfield(ObjectData,'DX')
835                DXY_line=ObjectData.DX;%mesh on the projection line
836            else
837                DXY_line=sqrt(abs(DX*DY));% mesh on the projection line
838            end
839            dlinx=ObjectData.Coord(2,1)-ObjectData.Coord(1,1);
840            dliny=ObjectData.Coord(2,2)-ObjectData.Coord(1,2);
841            linelength=sqrt(dlinx*dlinx+dliny*dliny);
842            theta=angle(dlinx+i*dliny);%angle of the line   
843            if isfield(FieldData,'RangeX')
844                XMin=min(FieldData.RangeX);%shift of the origin on the line
845            else
846                XMin=0;
847            end
848            eval(['ProjData.' AXName '=linspace(XMin,XMin+linelength,linelength/DXY_line+1);'])%abscissa of the new pixels along the line
849            y=linspace(-width,width,2*width/DXY_line+1);%ordintes of the new pixels (coordinate across the line)
850            eval(['npX=length(ProjData.' AXName ');'])
851            npY=length(y); %TODO: utiliser proj_grid
852            eval(['[X,Y]=meshgrid(ProjData.' AXName ',y);'])%grid in the line coordinates
853            XIMA=ObjectData.Coord(1,1)+(X-XMin)*cos(theta)-Y*sin(theta);
854            YIMA=ObjectData.Coord(1,2)+(X-XMin)*sin(theta)+Y*cos(theta);
855            XIMA=(XIMA-AX(1))/DX+1;%  index of the original image along x
856            YIMA=(YIMA-AY(1))/DY+1;% index of the original image along y
857            XIMA=reshape(round(XIMA),1,npX*npY);%indices reorganized in 'line'
858            YIMA=reshape(round(YIMA),1,npX*npY);
859            flagin=XIMA>=1 & XIMA<=npx & YIMA >=1 & YIMA<=npy;%flagin=1 inside the original image
860            ind_in=find(flagin);
861            ind_out=find(~flagin);
862            ICOMB=(XIMA-1)*npy+YIMA;
863            ICOMB=ICOMB(flagin);%index corresponding to XIMA and YIMA in the aligned original image vec_A
864            nbcolor=1; %color images
865            if numel(npxy)==2
866                nbcolor=1;
867            elseif length(npxy)==3
868                nbcolor=npxy(3);
869            else
870                errormsg='multicomponent field not projected';
871                display(errormsg)
872                return
873            end
874            nbvar=length(ProjData.ListVarName);% number of var from previous cells
875            ProjData.ListVarName=[ProjData.ListVarName {AXName}];
876            ProjData.VarDimName=[ProjData.VarDimName {AXName}];
877            for ivar=VarIndex
878                VarName{ivar}=FieldData.ListVarName{ivar};
879                if test_interp2% interpolate on new grid
880                    eval(['FieldData.' VarName{ivar} '=interp2(FieldData.' AXName ',FieldData.' AYName ',FieldData.' VarName{ivar} ',AXI,AYI'');']) %TO TEST
881                end
882                eval(['vec_A=reshape(squeeze(FieldData.' VarName{ivar} '),npx*npy,nbcolor);']) %put the original image in colum
883                if nbcolor==1
884                    vec_B(ind_in)=vec_A(ICOMB);
885                    vec_B(ind_out)=zeros(size(ind_out));
886                    A_out=reshape(vec_B,npY,npX);
887                    eval(['ProjData.' VarName{ivar} '=((sum(A_out,1)/npY))'';']);
888                elseif nbcolor==3
889                    vec_B(ind_in,[1:3])=vec_A(ICOMB,:);
890                    vec_B(ind_out,1)=zeros(size(ind_out));
891                    vec_B(ind_out,2)=zeros(size(ind_out));
892                    vec_B(ind_out,3)=zeros(size(ind_out));
893                    A_out=reshape(vec_B,npY,npX,nbcolor);
894                    eval(['ProjData.' VarName{ivar} '=squeeze(sum(A_out,1)/npY);']);
895                end 
896                ProjData.ListVarName=[ProjData.ListVarName VarName{ivar} ];
897                ProjData.VarDimName=[ProjData.VarDimName {AXName}];%to generalize with the initial name of the x coordinate
898                ProjData.VarAttribute{ivar}.Role='continuous';% for plot with continuous line
899            end
900            if testU
901                 eval(['vector_x =ProjData.' VarName{VarType.vector_x} ';'])
902                 eval(['vector_y =ProjData.' VarName{VarType.vector_y} ';'])
903                 eval(['ProjData.' VarName{VarType.vector_x} '=cos(theta)*vector_x+sin(theta)*vector_y;'])
904                 eval(['ProjData.' VarName{VarType.vector_y} '=-sin(theta)*vector_x+cos(theta)*vector_y;'])
905            end
906            ProjData.VarAttribute{nbvar+1}.long_name='abscissa along line';
907            if nbcolor==3
908                ProjData.VarDimName{end}={AXName,'rgb'};
909            end
910        end     
911    end
912end
913
914% %shotarter case for horizontal or vertical line (A FAIRE
915% %     Rangx=[0.5 npx-0.5];%image coordiantes of corners
916% %     Rangy=[npy-0.5 0.5];
917% %     if isfield(Calib,'Pxcmx')&isfield(Calib,'Pxcmy')%old calib
918% %         Rangx=Rangx/Calib.Pxcmx;
919% %         Rangy=Rangy/Calib.Pxcmy;
920% %     else
921% %         [Rangx]=phys_XYZ(Calib,Rangx,[0.5 0.5],[0 0]);%case of translations without rotation and quadratic deformation
922% %         [xx,Rangy]=phys_XYZ(Calib,[0.5 0.5],Rangy,[0 0]);
923% %     end
924%
925% %     test_scal=0;%default% 3- 'UserData':(get(handles.Tag,'UserData')
926
927
928%-----------------------------------------------------------------
929%project on a plane
930% AJOUTER flux,circul,error
931 function  [ProjData,errormsg] = proj_plane(FieldData, ObjectData)
932%-----------------------------------------------------------------
933
934%% initialisation of the input parameters of the projection plane
935ProjMode='projection';%direct projection by default
936if isfield(ObjectData,'ProjMode'),ProjMode=ObjectData.ProjMode; end;
937
938%axis origin
939if isempty(ObjectData.Coord)
940    ObjectData.Coord(1,1)=0;%origin of the plane set to [0 0] by default
941    ObjectData.Coord(1,2)=0;
942    ObjectData.Coord(1,3)=0;
943end
944
945%rotation angles
946PlaneAngle=[0 0 0];
947norm_plane=[0 0 1];
948cos_om=1;
949sin_om=0;
950if isfield(ObjectData,'Angle')&& isequal(size(ObjectData.Angle),[1 3])&& ~isequal(ObjectData.Angle,[0 0 0])
951    PlaneAngle=ObjectData.Angle;
952    om=norm(PlaneAngle);%norm of rotation angle in radians
953    OmAxis=PlaneAngle/om; %unit vector marking the rotation axis
954    cos_om=cos(pi*om/180);
955    sin_om=sin(pi*om/180);
956    coeff=OmAxis(3)*(1-cos_om);
957    %components of the unity vector norm_plane normal to the projection plane
958    norm_plane(1)=OmAxis(1)*coeff+OmAxis(2)*sin_om;
959    norm_plane(2)=OmAxis(2)*coeff-OmAxis(1)*sin_om;
960    norm_plane(3)=OmAxis(3)*coeff+cos_om;
961end
962testangle=~isequal(PlaneAngle,[0 0 0]);
963% Phi=0;%default
964% Theta=0;
965% Psi=0;
966% if isfield(ObjectData,'Phi')&& ~isempty(ObjectData.Phi)
967%     Phi=(pi/180)*ObjectData.Phi;%first Euler angle in radian
968% end
969% if isfield(ObjectData,'Theta')&& ~isempty(ObjectData.Theta)
970%     Theta=(pi/180)*ObjectData.Theta;%second Euler angle in radian
971% end
972% if isfield(ObjectData,'Psi')&& ~isempty(ObjectData.Psi)
973%     Psi=(pi/180)*ObjectData.Psi;%third Euler angle in radian
974% end
975
976%components of the unity vector normal to the projection plane
977% NormVec_X=-sin(Phi)*sin(Theta);
978% NormVec_Y=cos(Phi)*sin(Theta);
979% NormVec_Z=cos(Theta);
980
981%mesh sizes DX and DY
982DX=0;
983DY=0; %default
984if isfield(ObjectData,'DX')&~isempty(ObjectData.DX)
985     DX=abs(ObjectData.DX);%mesh of interpolation points
986end
987if isfield(ObjectData,'DY')&~isempty(ObjectData.DY)
988     DY=abs(ObjectData.DY);%mesh of interpolation points
989end
990if  ~strcmp(ProjMode,'projection') && (DX==0||DY==0)
991        errormsg='DX or DY missing';
992        display(errormsg)
993        return
994end
995
996%extrema along each axis
997testXMin=0;
998testXMax=0;
999testYMin=0;
1000testYMax=0;
1001if isfield(ObjectData,'RangeX')
1002        XMin=min(ObjectData.RangeX);
1003        XMax=max(ObjectData.RangeX);
1004        testXMin=XMax>XMin;
1005        testXMax=1;
1006end
1007if isfield(ObjectData,'RangeY')
1008        YMin=min(ObjectData.RangeY);
1009        YMax=max(ObjectData.RangeY);
1010        testYMin=YMax>YMin;
1011        testYMax=1;
1012end
1013width=0;%default width of the projection band
1014if isfield(ObjectData,'RangeZ')
1015        width=max(ObjectData.RangeZ);
1016end
1017
1018% initiate Matlab  structure for physical field
1019[ProjData,errormsg]=proj_heading(FieldData,ObjectData);
1020ProjData.NbDim=2;
1021ProjData.ListVarName={};
1022ProjData.VarDimName={};
1023if ~isequal(DX,0)&& ~isequal(DY,0)
1024    ProjData.Mesh=sqrt(DX*DY);%define typical data mesh, useful for mouse selection in plots
1025elseif isfield(FieldData,'Mesh')
1026    ProjData.Mesh=FieldData.Mesh;
1027end
1028
1029error=0;%default
1030flux=0;
1031testfalse=0;
1032ListIndex={};
1033
1034%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1035%% group the variables (fields of 'FieldData') in cells of variables with the same dimensions
1036%-----------------------------------------------------------------
1037idimvar=0;
1038
1039[CellVarIndex,NbDimVec,VarTypeCell,errormsg]=find_field_indices(FieldData);
1040if ~isempty(errormsg)
1041    errormsg=['error in proj_field/proj_plane:' errormsg];
1042    return
1043end
1044
1045% LOOP ON GROUPS OF VARIABLES SHARING THE SAME DIMENSIONS
1046% CellVarIndex=cells of variable index arrays
1047ivar_new=0; % index of the current variable in the projected field
1048icoord=0;
1049nbcoord=0;%number of added coordinate variables brought by projection
1050nbvar=0;
1051for icell=1:length(CellVarIndex)
1052    NbDim=NbDimVec(icell);
1053    if NbDim<2
1054        continue
1055    end
1056    VarIndex=CellVarIndex{icell};%  indices of the selected variables in the list FieldData.ListVarName
1057    VarType=VarTypeCell{icell};
1058    ivar_X=VarType.coord_x;
1059    ivar_Y=VarType.coord_y;
1060    ivar_Z=VarType.coord_z;
1061    ivar_U=VarType.vector_x;
1062    ivar_V=VarType.vector_y;
1063    ivar_W=VarType.vector_z;
1064    ivar_C=VarType.scalar ;
1065    ivar_Anc=VarType.ancillary;
1066    test_anc=zeros(size(VarIndex));
1067    test_anc(ivar_Anc)=ones(size(ivar_Anc));
1068    ivar_F=VarType.warnflag;
1069    ivar_FF=VarType.errorflag;
1070    testX=~isempty(ivar_X) && ~isempty(ivar_Y);
1071    DimCell=FieldData.VarDimName{VarIndex(1)};
1072    if ischar(DimCell)
1073        DimCell={DimCell};%name of dimensions
1074    end
1075
1076%% case of input fields with unstructured coordinates
1077    if testX
1078        XName=FieldData.ListVarName{ivar_X};
1079        YName=FieldData.ListVarName{ivar_Y};
1080        eval(['coord_x=FieldData.' XName ';'])
1081        eval(['coord_y=FieldData.' YName ';'])
1082        if length(ivar_Z)==1
1083            ZName=FieldData.ListVarName{ivar_Z};
1084            eval(['coord_z=FieldData.' ZName ';'])
1085        end
1086
1087        % translate  initial coordinates
1088        coord_x=coord_x-ObjectData.Coord(1,1);
1089        coord_y=coord_y-ObjectData.Coord(1,2);
1090        if ~isempty(ivar_Z)
1091            coord_z=coord_z-ObjectData.Coord(1,3);
1092        end
1093       
1094        % selection of the vectors in the projection range (3D case)
1095        if length(ivar_Z)==1 &&  width > 0
1096            %components of the unitiy vector normal to the projection plane
1097            fieldZ=norm_plane(1)*coord_x + norm_plane(2)*coord_y+ norm_plane(3)*coord_z;% distance to the plane           
1098            indcut=find(abs(fieldZ) <= width);
1099            size(indcut)
1100            for ivar=VarIndex
1101                VarName=FieldData.ListVarName{ivar};
1102                eval(['FieldData.' VarName '=FieldData.' VarName '(indcut);']) 
1103                    % A VOIR : CAS DE VAR STRUCTUREE MAIS PAS GRILLE REGULIERE : INTERPOLER SUR GRILLE REGULIERE             
1104            end
1105            coord_x=coord_x(indcut);
1106            coord_y=coord_y(indcut);
1107            coord_z=coord_z(indcut);
1108        end
1109
1110       %rotate coordinates if needed
1111        if testangle
1112%             coord_X=coord_x;
1113%             coord_Y=coord_y;
1114%             if ~isequal(Theta,0)
1115%                 coord_Y=coord_Y *cos(Theta);
1116%             end
1117%         else
1118            coord_X=(coord_x *cos(Phi) + coord_y* sin(Phi));
1119            coord_Y=(-coord_x *sin(Phi) + coord_y *cos(Phi))*cos(Theta);
1120%         end
1121%         if ~isempty(ivar_Z)
1122            coord_Y=coord_Y+coord_z *sin(Theta);
1123%         end
1124%         if testangle
1125                coord_X=(coord_X *cos(Psi) - coord_Y* sin(Psi));%A VERIFIER
1126                coord_Y=(coord_X *sin(Psi) + coord_Y* cos(Psi));
1127        else
1128            coord_X=coord_x;
1129            coord_Y=coord_y;
1130        end
1131       
1132        %restriction to the range of x and y if imposed
1133        testin=ones(size(coord_X)); %default
1134        testbound=0;
1135        if testXMin
1136            testin=testin & (coord_X >= XMin);
1137            testbound=1;
1138        end
1139        if testXMax
1140            testin=testin & (coord_X <= XMax);
1141            testbound=1;
1142        end
1143        if testYMin
1144            testin=testin & (coord_Y >= YMin);
1145            testbound=1;
1146        end
1147        if testYMin
1148            testin=testin & (coord_Y <= YMax);
1149            testbound=1;
1150        end
1151        if testbound
1152            indcut=find(testin);
1153            for ivar=VarIndex
1154                VarName=FieldData.ListVarName{ivar};
1155                eval(['FieldData.' VarName '=FieldData.' VarName '(indcut);'])           
1156            end
1157            coord_X=coord_X(indcut);
1158            coord_Y=coord_Y(indcut);
1159            if length(ivar_Z)==1
1160                coord_Z=coord_Z(indcut);
1161            end
1162        end
1163        % different cases of projection
1164        if isequal(ObjectData.ProjMode,'projection')
1165            %the list of dimension
1166            %ProjData.ListDimName=[ProjData.ListDimName FieldData.VarDimName(VarIndex(1))];%add the point index to the list of dimensions
1167            %ProjData.DimValue=[ProjData.
1168             %length(coord_X)];
1169
1170            for ivar=VarIndex %transfer variables to the projection plane
1171                VarName=FieldData.ListVarName{ivar};
1172                if ivar==ivar_X %x coordinate
1173                    eval(['ProjData.' VarName '=coord_X;'])
1174                elseif ivar==ivar_Y % y coordinate
1175                    eval(['ProjData.' VarName '=coord_Y;'])
1176                elseif isempty(ivar_Z) || ivar~=ivar_Z % other variables (except Z coordinate wyhich is not reproduced)
1177                    eval(['ProjData.' VarName '=FieldData.' VarName ';'])
1178                end
1179                if isempty(ivar_Z) || ivar~=ivar_Z
1180                    ProjData.ListVarName=[ProjData.ListVarName VarName];
1181                    ProjData.VarDimName=[ProjData.VarDimName DimCell];
1182                    nbvar=nbvar+1;
1183                    if isfield(FieldData,'VarAttribute') && length(FieldData.VarAttribute) >=ivar
1184                        ProjData.VarAttribute{nbvar}=FieldData.VarAttribute{ivar};
1185                    end
1186                end
1187            end 
1188        elseif isequal(ObjectData.ProjMode,'interp')||isequal(ObjectData.ProjMode,'filter')%interpolate data on a regular grid
1189            coord_x_proj=XMin:DX:XMax;
1190            coord_y_proj=YMin:DY:YMax;
1191            DimCell={'coord_y','coord_x'};
1192            ProjData.ListVarName={'coord_y','coord_x'};
1193            ProjData.VarDimName={'coord_y','coord_x'};   
1194            nbcoord=2; 
1195            ProjData.coord_y=[YMin YMax];
1196            ProjData.coord_x=[XMin XMax];
1197            if isempty(ivar_X), ivar_X=0; end;
1198            if isempty(ivar_Y), ivar_Y=0; end;
1199            if isempty(ivar_Z), ivar_Z=0; end;
1200            if isempty(ivar_U), ivar_U=0; end;
1201            if isempty(ivar_V), ivar_V=0; end;
1202            if isempty(ivar_W), ivar_W=0; end;
1203            if isempty(ivar_F), ivar_F=0; end;
1204            if isempty(ivar_FF), ivar_FF=0; end;
1205            if ~isequal(ivar_FF,0)
1206                VarName_FF=FieldData.ListVarName{ivar_FF};
1207                eval(['indsel=find(FieldData.' VarName_FF '==0);'])
1208                coord_X=coord_X(indsel);
1209                coord_Y=coord_Y(indsel);
1210            end
1211            FF=zeros(1,length(coord_y_proj)*length(coord_x_proj));
1212            testFF=0;
1213            for ivar=VarIndex
1214                VarName=FieldData.ListVarName{ivar};
1215                if ~( ivar==ivar_X || ivar==ivar_Y || ivar==ivar_Z || ivar==ivar_F || ivar==ivar_FF || test_anc(ivar)==1)                 
1216                    ivar_new=ivar_new+1;
1217                    ProjData.ListVarName=[ProjData.ListVarName {VarName}];
1218                    ProjData.VarDimName=[ProjData.VarDimName {DimCell}];
1219                    if isfield(FieldData,'VarAttribute') && length(FieldData.VarAttribute) >=ivar
1220                        ProjData.VarAttribute{ivar_new+nbcoord}=FieldData.VarAttribute{ivar};
1221                    end
1222                    if  ~isequal(ivar_FF,0)
1223                        eval(['FieldData.' VarName '=FieldData.' VarName '(indsel);'])
1224                    end
1225                    eval(['ProjData.' VarName '=griddata_uvmat(double(coord_X),double(coord_Y),double(FieldData.' VarName '),coord_x_proj,coord_y_proj'');'])
1226                    eval(['varline=reshape(ProjData.' VarName ',1,length(coord_y_proj)*length(coord_x_proj));'])
1227                    FFlag= isnan(varline); %detect undefined values NaN
1228                    indnan=find(FFlag);
1229                    if~isempty(indnan)
1230                        varline(indnan)=zeros(size(indnan));
1231                        eval(['ProjData.' VarName '=reshape(varline,length(coord_y_proj),length(coord_x_proj));'])
1232                        FF(indnan)=ones(size(indnan));
1233                        testFF=1;
1234                    end
1235                    if ivar==ivar_U
1236                        ivar_U=ivar_new;
1237                    end
1238                    if ivar==ivar_V
1239                        ivar_V=ivar_new;
1240                    end
1241                    if ivar==ivar_W
1242                        ivar_W=ivar_new;
1243                    end
1244                end
1245            end
1246            if testFF
1247                ProjData.FF=reshape(FF,length(coord_y_proj),length(coord_x_proj));
1248                ProjData.ListVarName=[ProjData.ListVarName {'FF'}];
1249               ProjData.VarDimName=[ProjData.VarDimName {DimCell}];
1250                ProjData.VarAttribute{ivar_new+1+nbcoord}.Role='errorflag';
1251            end
1252        end
1253       
1254%% case of input fields defined on a structured  grid
1255    else
1256        VarName=FieldData.ListVarName{VarIndex(1)};%get the first variable of the cell to get the input matrix dimensions
1257        eval(['DimValue=size(FieldData.' VarName ');'])%input matrix dimensions
1258        DimValue(find(DimValue==1))=[];%remove singleton dimensions       
1259        NbDim=numel(DimValue);%update number of space dimensions
1260        nbcolor=1; %default number of 'color' components: third matrix index without corresponding coordinate
1261        if NbDim>=3
1262            if NbDim>3
1263                errormsg='matrices with more than 3 dimensions not handled';
1264                return
1265            else
1266                VarType.coord
1267                if numel(find(VarType.coord))==2% the third matrix dimension does not correspond to a space coordinate
1268                    nbcolor=DimValue(3);
1269                    DimValue(3)=[]; %number of 'color' components updated
1270                    NbDim=2;% space dimension set to 2
1271                end
1272            end
1273        end
1274        AYName=FieldData.ListVarName{VarType.coord(NbDim-1)};%name of input x coordinate (name preserved on projection)
1275        AXName=FieldData.ListVarName{VarType.coord(NbDim)};%name of input y coordinate (name preserved on projection)   
1276        eval(['AX=FieldData.' AXName ';'])
1277        eval(['AY=FieldData.' AYName ';'])
1278        ListDimName=FieldData.VarDimName{VarIndex(1)};
1279        ProjData.ListVarName=[ProjData.ListVarName {AYName} {AXName}]; %TODO: check if it already exists in Projdata (several cells)
1280        ProjData.VarDimName=[ProjData.VarDimName {AYName} {AXName}];
1281
1282%         for idim=1:length(ListDimName)
1283%             DimName=ListDimName{idim};
1284%             if strcmp(DimName,'rgb')||strcmp(DimName,'nb_coord')||strcmp(DimName,'nb_coord_i')
1285%                nbcolor=DimValue(idim);
1286%                DimValue(idim)=[];
1287%             end
1288%             if isequal(DimName,'nb_coord_j')% NOTE: CASE OF TENSOR NOT TREATED
1289%                 DimValue(idim)=[];
1290%             end
1291%         end 
1292        Coord_z=[];
1293        Coord_y=[];
1294        Coord_x=[];   
1295
1296        for idim=1:NbDim %loop on space dimensions
1297            test_interp(idim)=0;%test for coordiate interpolation (non regular grid), =0 by default
1298            ivar=VarType.coord(idim);% index of the variable corresponding to the current dimension
1299            if ~isequal(ivar,0)%  a variable corresponds to the dimension #idim
1300                eval(['Coord{idim}=FieldData.' FieldData.ListVarName{ivar} ';']) ;% coord values for the input field
1301                if numel(Coord{idim})==2 %input array defined on a regular grid
1302                   DCoord_min(idim)=(Coord{idim}(2)-Coord{idim}(1))/DimValue(idim);
1303                else
1304                    DCoord=diff(Coord{idim});%array of coordinate derivatives for the input field
1305                    DCoord_min(idim)=min(DCoord);
1306                    DCoord_max=max(DCoord);
1307                %    test_direct(idim)=DCoord_max>0;% =1 for increasing values, 0 otherwise
1308                    if abs(DCoord_max-DCoord_min(idim))>abs(DCoord_max/1000)
1309                        msgbox_uvmat('ERROR',['non monotonic dimension variable # ' num2str(idim)  ' in proj_field.m'])
1310                                return
1311                    end               
1312                    test_interp(idim)=(DCoord_max-DCoord_min(idim))> 0.0001*abs(DCoord_max);% test grid regularity
1313                end
1314                test_direct(idim)=(DCoord_min(idim)>0);
1315            else  % no variable associated with the  dimension #idim, the coordinate value is set equal to the matrix index by default
1316                Coord_i_str=['Coord_' num2str(idim)];
1317                DCoord_min(idim)=1;%default
1318                Coord{idim}=[0.5 DimValue(idim)-0.5];
1319                test_direct(idim)=1;
1320            end
1321        end
1322        if DY==0
1323            DY=abs(DCoord_min(NbDim-1));
1324        end
1325        npY=1+round(abs(Coord{NbDim-1}(end)-Coord{NbDim-1}(1))/DY);%nbre of points after interpol
1326        if DX==0
1327            DX=abs(DCoord_min(NbDim));
1328        end
1329        npX=1+round(abs(Coord{NbDim}(end)-Coord{NbDim}(1))/DX);%nbre of points after interpol
1330        for idim=[1:NbDim]
1331            if test_interp(idim)
1332                DimValue(idim)=1+round(abs(Coord{idim}(end)-Coord{idim}(1))/abs(DCoord_min(idim)));%nbre of points after possible interpolation on a regular gri
1333            end
1334        end       
1335        Coord_y=linspace(Coord{NbDim-1}(1),Coord{NbDim-1}(end),npY);
1336        test_direct_y=test_direct(NbDim-1);
1337        Coord_x=linspace(Coord{NbDim}(1),Coord{NbDim}(end),npX);
1338        test_direct_x=test_direct(NbDim);
1339        DAX=DCoord_min(NbDim);
1340        DAY=DCoord_min(NbDim-1); 
1341        minAX=min(Coord_x);
1342        maxAX=max(Coord_x);
1343        minAY=min(Coord_y);
1344        maxAY=max(Coord_y);
1345        xcorner=[minAX maxAX minAX maxAX]-ObjectData.Coord(1,1);
1346        ycorner=[maxAY maxAY minAY minAY]-ObjectData.Coord(1,2);
1347        xcor_new=xcorner*cos_om+ycorner*sin_om;%coord new frame
1348        ycor_new=-xcorner*sin_om+ycorner*cos_om;
1349        if ~testXMax
1350            XMax=max(xcor_new);
1351        end
1352        if ~testXMin
1353            XMin=min(xcor_new);
1354        end
1355        if ~testYMax
1356            YMax=max(ycor_new);
1357        end
1358        if ~testYMin
1359            YMin=min(ycor_new);
1360        end
1361        DXinit=(maxAX-minAX)/(DimValue(NbDim)-1);
1362        DYinit=(maxAY-minAY)/(DimValue(NbDim-1)-1);
1363        if DX==0
1364            DX=DXinit;
1365        end
1366        if DY==0
1367            DY=DYinit;
1368        end
1369        if NbDim==3
1370            DZ=(Coord{1}(end)-Coord{1}(1))/(DimValue(1)-1);
1371            if ~test_direct(1)
1372                DZ=-DZ;
1373            end
1374            Coord_z=linspace(Coord{1}(1),Coord{1}(end),DimValue(1));
1375            test_direct_z=test_direct(1);
1376        end
1377        npX=floor((XMax-XMin)/DX+1);
1378        npY=floor((YMax-YMin)/DY+1);   
1379        if test_direct_y
1380            coord_y_proj=linspace(YMin,YMax,npY);%abscissa of the new pixels along the line
1381        else
1382            coord_y_proj=linspace(YMax,YMin,npY);%abscissa of the new pixels along the line
1383        end
1384        if test_direct_x
1385            coord_x_proj=linspace(XMin,XMax,npX);%abscissa of the new pixels along the line
1386        else
1387            coord_x_proj=linspace(XMax,XMin,npX);%abscissa of the new pixels along the line
1388        end
1389       
1390        % case with no rotation and interpolation
1391        if isequal(ProjMode,'projection') && ~testangle
1392            if ~testXMin && ~testXMax && ~testYMin && ~testYMax && NbDim==2
1393                ProjData=FieldData;
1394            else
1395                indY=NbDim-1;
1396                if test_direct(indY)
1397                    min_indy=ceil((YMin-Coord{indY}(1))/DYinit)+1;
1398                    max_indy=floor((YMax-Coord{indY}(1))/DYinit)+1;
1399                    Ybound(1)=Coord{indY}(1)+DYinit*(min_indy-1);
1400                    Ybound(2)=Coord{indY}(1)+DYinit*(max_indy-1);
1401                else
1402                    min_indy=ceil((Coord{indY}(1)-YMax)/DYinit)+1;
1403                    max_indy=floor((Coord{indY}(1)-YMin)/DYinit)+1;
1404                    Ybound(2)=Coord{indY}(1)-DYinit*(max_indy-1);
1405                    Ybound(1)=Coord{indY}(1)-DYinit*(min_indy-1);
1406                end   
1407                if test_direct(NbDim)==1
1408                    min_indx=ceil((XMin-Coord{NbDim}(1))/DXinit)+1;
1409                    max_indx=floor((XMax-Coord{NbDim}(1))/DXinit)+1;
1410                    Xbound(1)=Coord{NbDim}(1)+DXinit*(min_indx-1);
1411                    Xbound(2)=Coord{NbDim}(1)+DXinit*(max_indx-1);
1412                else
1413                    min_indx=ceil((Coord{NbDim}(1)-XMax)/DXinit)+1;
1414                    max_indx=floor((Coord{NbDim}(1)-XMin)/DXinit)+1;
1415                    Xbound(2)=Coord{NbDim}(1)+DXinit*(max_indx-1);
1416                    Xbound(1)=Coord{NbDim}(1)+DXinit*(min_indx-1);
1417                end
1418                if NbDim==3
1419                    DimCell(1)=[]; %suppress z variable
1420                    DimValue(1)=[];
1421                                        %structured coordinates
1422                    if test_direct(1)
1423                        iz=ceil((ObjectData.Coord(1,3)-Coord{1}(1))/DZ)+1;
1424                    else
1425                        iz=ceil((Coord{1}(1)-ObjectData.Coord(1,3))/DZ)+1;
1426                    end
1427                end
1428                min_indy=max(min_indy,1);% deals with margin (bound lower than the first index)
1429                min_indx=max(min_indx,1);
1430                max_indy=min(max_indy,DimValue(1));
1431                max_indx=min(max_indx,DimValue(2));
1432                for ivar=VarIndex% loop on non coordinate variables
1433                    VarName=FieldData.ListVarName{ivar};
1434                    ProjData.ListVarName=[ProjData.ListVarName VarName];
1435                    ProjData.VarDimName=[ProjData.VarDimName {DimCell}];
1436                    if isfield(FieldData,'VarAttribute') && length(FieldData.VarAttribute)>=ivar
1437                        ProjData.VarAttribute{length(ProjData.ListVarName)}=FieldData.VarAttribute{ivar};
1438                    end
1439                    if NbDim==3
1440                        eval(['ProjData.' VarName '=squeeze(FieldData.' VarName '(iz,min_indy:max_indy,min_indx:max_indx));']);
1441                    else
1442                        eval(['ProjData.' VarName '=FieldData.' VarName '(min_indy:max_indy,min_indx:max_indx,:);']);
1443                    end
1444                end 
1445                eval(['ProjData.' AYName '=[Ybound(1) Ybound(2)];']) %record the new (projected ) y coordinates
1446                eval(['ProjData.' AXName '=[Xbound(1) Xbound(2)];']) %record the new (projected ) x coordinates
1447            end
1448        else       % case with rotation and/or interpolation
1449            if NbDim==2 %2D case
1450                [X,Y]=meshgrid(coord_x_proj,coord_y_proj);%grid in the new coordinates
1451                XIMA=ObjectData.Coord(1,1)+(X)*cos(Phi)-Y*sin(Phi);%corresponding coordinates in the original image
1452                YIMA=ObjectData.Coord(1,2)+(X)*sin(Phi)+Y*cos(Phi);
1453                XIMA=(XIMA-minAX)/DXinit+1;% image index along x
1454                YIMA=(-YIMA+maxAY)/DYinit+1;% image index along y
1455                XIMA=reshape(round(XIMA),1,npX*npY);%indices reorganized in 'line'
1456                YIMA=reshape(round(YIMA),1,npX*npY);
1457                flagin=XIMA>=1 & XIMA<=DimValue(2) & YIMA >=1 & YIMA<=DimValue(1);%flagin=1 inside the original image
1458                if isequal(ObjectData.ProjMode,'filter')
1459                    npx_filter=ceil(abs(DX/DAX));
1460                    npy_filter=ceil(abs(DY/DAY));
1461                    Mfilter=ones(npy_filter,npx_filter)/(npx_filter*npy_filter);
1462                    test_filter=1;
1463                else
1464                    test_filter=0;
1465                end
1466                eval(['ProjData.' AYName '=[coord_y_proj(1) coord_y_proj(end)];']) %record the new (projected ) y coordinates
1467                eval(['ProjData.' AXName '=[coord_x_proj(1) coord_x_proj(end)];']) %record the new (projected ) x coordinates
1468                for ivar=VarIndex
1469                    VarName=FieldData.ListVarName{ivar};
1470                    if test_interp(1) || test_interp(2)%interpolate on a regular grid       
1471                          eval(['ProjData.' VarName '=interp2(Coord{2},Coord{1},FieldData.' VarName ',Coord_x,Coord_y'');']) %TO TEST
1472                    end
1473                    %filter the field (image) if option 'filter' is used
1474                    if test_filter 
1475                         Aclass=class(FieldData.A);
1476                         eval(['ProjData.' VarName '=filter2(Mfilter,FieldData.' VarName ',''valid'');'])
1477                         if ~isequal(Aclass,'double')
1478                             eval(['ProjData.' VarName '=' Aclass '(FieldData.' VarName ');'])%revert to integer values
1479                         end
1480                    end
1481                    eval(['vec_A=reshape(FieldData.' VarName ',[],nbcolor);'])%put the original image in line             
1482                    %ind_in=find(flagin);
1483                    ind_out=find(~flagin);
1484                    ICOMB=(XIMA-1)*DimValue(1)+YIMA;
1485                    ICOMB=ICOMB(flagin);%index corresponding to XIMA and YIMA in the aligned original image vec_A
1486                    vec_B(flagin,1:nbcolor)=vec_A(ICOMB,:);
1487                    for icolor=1:nbcolor
1488                        vec_B(ind_out,icolor)=zeros(size(ind_out));
1489                    end
1490                    ProjData.ListVarName=[ProjData.ListVarName VarName];
1491                    ProjData.VarDimName=[ProjData.VarDimName {DimCell}];
1492                    if isfield(FieldData,'VarAttribute')&&length(FieldData.VarAttribute)>=ivar
1493                        ProjData.VarAttribute{length(ProjData.ListVarName)+nbcoord}=FieldData.VarAttribute{ivar};
1494                    end     
1495                    eval(['ProjData.' VarName '=reshape(vec_B,npY,npX,nbcolor);']);
1496                end
1497                ProjData.FF=reshape(~flagin,npY,npX);%false flag A FAIRE: tenir compte d'un flga antérieur 
1498                ProjData.ListVarName=[ProjData.ListVarName 'FF'];
1499                ProjData.VarDimName=[ProjData.VarDimName {DimCell}];
1500                ProjData.VarAttribute{length(ProjData.ListVarName)}.Role='errorflag';
1501            else %3D case
1502                if ~testangle     
1503                    % unstructured z coordinate
1504                    test_sup=(Coord{1}>=ObjectData.Coord(1,3));
1505                    iz_sup=find(test_sup);
1506                    iz=iz_sup(1);
1507                    if iz>=1 & iz<=npz
1508                        %ProjData.ListDimName=[ProjData.ListDimName ListDimName(2:end)];
1509                        %ProjData.DimValue=[ProjData.DimValue npY npX];
1510                        for ivar=VarIndex
1511                            VarName=FieldData.ListVarName{ivar};
1512                            ProjData.ListVarName=[ProjData.ListVarName VarName];
1513                            ProjData.VarAttribute{length(ProjData.ListVarName)}=FieldData.VarAttribute{ivar}; %reproduce the variable attributes 
1514                            eval(['ProjData.' VarName '=squeeze(FieldData.' VarName '(iz,:,:));'])% select the z index iz
1515                            %TODO : do a vertical average for a thick plane
1516                            if test_interp(2) || test_interp(3)
1517                                eval(['ProjData.' VarName '=interp2(Coord{3},Coord{2},ProjData.' VarName ',Coord_x,Coord_y'');'])
1518                            end
1519                        end
1520                    end
1521                else
1522                    errormsg='projection of structured coordinates on oblique plane not yet implemented';
1523                    %TODO: use interp3
1524                    return
1525                end
1526            end
1527        end
1528    end
1529
1530    %% projection of  velocity components in the rotated coordinates
1531    if testangle && length(ivar_U)==1
1532        if isempty(ivar_V)
1533            msgbox_uvmat('ERROR','v velocity component missing in proj_field.m')
1534            return
1535        end
1536        UName=FieldData.ListVarName{ivar_U};
1537        VName=FieldData.ListVarName{ivar_V};   
1538        eval(['ProjData.' UName  '=cos(Phi)*ProjData.' UName '+ sin(Phi)*ProjData.' VName ';'])
1539        eval(['ProjData.' VName  '=cos(Theta)*(-sin(Phi)*ProjData.' UName '+ cos(Phi)*ProjData.' VName ');'])
1540        if ~isempty(ivar_W)
1541            WName=FieldData.ListVarName{ivar_W};
1542            eval(['ProjData.' VName '=ProjData.' VName '+ ProjData.' WName '*sin(Theta);'])%
1543            eval(['ProjData.' WName '=NormVec_X*ProjData.' UName '+ NormVec_Y*ProjData.' VName '+ NormVec_Z* ProjData.' WName ';']);
1544        end
1545        if ~isequal(Psi,0)
1546            eval(['ProjData.' UName '=cos(Psi)* ProjData.' UName '- sin(Psi)*ProjData.' VName ';']);
1547            eval(['ProjData.' VName '=sin(Psi)* ProjData.' UName '+ cos(Psi)*ProjData.' VName ';']);
1548        end
1549    end
1550end
1551
1552%-----------------------------------------------------------------
1553%projection in a volume
1554 function  [ProjData,errormsg] = proj_volume(FieldData, ObjectData)
1555%-----------------------------------------------------------------
1556ProjData=FieldData;%default output
1557
1558%% initialisation of the input parameters of the projection plane
1559ProjMode='projection';%direct projection by default
1560if isfield(ObjectData,'ProjMode'),ProjMode=ObjectData.ProjMode; end;
1561
1562%% axis origin
1563if isempty(ObjectData.Coord)
1564    ObjectData.Coord(1,1)=0;%origin of the plane set to [0 0] by default
1565    ObjectData.Coord(1,2)=0;
1566    ObjectData.Coord(1,3)=0;
1567end
1568
1569%% rotation angles
1570VolumeAngle=[0 0 0];
1571norm_plane=[0 0 1];
1572if isfield(ObjectData,'Angle')&& isequal(size(ObjectData.Angle),[1 3])&& ~isequal(ObjectData.Angle,[0 0 0])
1573    PlaneAngle=ObjectData.Angle;
1574    VolumeAngle=ObjectData.Angle;
1575    om=norm(VolumeAngle);%norm of rotation angle in radians
1576    OmAxis=VolumeAngle/om; %unit vector marking the rotation axis
1577    cos_om=cos(pi*om/180);
1578    sin_om=sin(pi*om/180);
1579    coeff=OmAxis(3)*(1-cos_om);
1580    %components of the unity vector norm_plane normal to the projection plane
1581    norm_plane(1)=OmAxis(1)*coeff+OmAxis(2)*sin_om;
1582    norm_plane(2)=OmAxis(2)*coeff-OmAxis(1)*sin_om;
1583    norm_plane(3)=OmAxis(3)*coeff+cos_om;
1584end
1585testangle=~isequal(VolumeAngle,[0 0 0]);
1586
1587%% mesh sizes DX, DY, DZ
1588DX=0;
1589DY=0; %default
1590DZ=0;
1591if isfield(ObjectData,'DX')&~isempty(ObjectData.DX)
1592     DX=abs(ObjectData.DX);%mesh of interpolation points
1593end
1594if isfield(ObjectData,'DY')&~isempty(ObjectData.DY)
1595     DY=abs(ObjectData.DY);%mesh of interpolation points
1596end
1597if isfield(ObjectData,'DZ')&~isempty(ObjectData.DZ)
1598     DZ=abs(ObjectData.DZ);%mesh of interpolation points
1599end
1600if  ~strcmp(ProjMode,'projection') && (DX==0||DY==0||DZ==0)
1601        errormsg='grid mesh DX , DY or DZ is missing';
1602        return
1603end
1604
1605%% extrema along each axis
1606testXMin=0;
1607testXMax=0;
1608testYMin=0;
1609testYMax=0;
1610if isfield(ObjectData,'RangeX')
1611        XMin=min(ObjectData.RangeX);
1612        XMax=max(ObjectData.RangeX);
1613        testXMin=XMax>XMin;
1614        testXMax=1;
1615end
1616if isfield(ObjectData,'RangeY')
1617        YMin=min(ObjectData.RangeY);
1618        YMax=max(ObjectData.RangeY);
1619        testYMin=YMax>YMin;
1620        testYMax=1;
1621end
1622width=0;%default width of the projection band
1623if isfield(ObjectData,'RangeZ')
1624        ZMin=min(ObjectData.RangeZ);
1625        ZMax=max(ObjectData.RangeZ);
1626        testZMin=ZMax>ZMin;
1627        testZMax=1;
1628end
1629
1630%% initiate Matlab  structure for physical field
1631[ProjData,errormsg]=proj_heading(FieldData,ObjectData);
1632ProjData.NbDim=3;
1633ProjData.ListVarName={};
1634ProjData.VarDimName={};
1635if ~isequal(DX,0)&& ~isequal(DY,0)
1636    ProjData.Mesh=sqrt(DX*DY);%define typical data mesh, useful for mouse selection in plots
1637elseif isfield(FieldData,'Mesh')
1638    ProjData.Mesh=FieldData.Mesh;
1639end
1640
1641error=0;%default
1642flux=0;
1643testfalse=0;
1644ListIndex={};
1645
1646%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1647%% group the variables (fields of 'FieldData') in cells of variables with the same dimensions
1648%-----------------------------------------------------------------
1649idimvar=0;
1650[CellVarIndex,NbDimVec,VarTypeCell,errormsg]=find_field_indices(FieldData);
1651if ~isempty(errormsg)
1652    errormsg=['error in proj_field/proj_plane:' errormsg];
1653    return
1654end
1655
1656% LOOP ON GROUPS OF VARIABLES SHARING THE SAME DIMENSIONS
1657% CellVarIndex=cells of variable index arrays
1658ivar_new=0; % index of the current variable in the projected field
1659icoord=0;
1660nbcoord=0;%number of added coordinate variables brought by projection
1661nbvar=0;
1662for icell=1:length(CellVarIndex)
1663    NbDim=NbDimVec(icell);
1664    if NbDim<3
1665        continue
1666    end
1667    VarIndex=CellVarIndex{icell};%  indices of the selected variables in the list FieldData.ListVarName
1668    VarType=VarTypeCell{icell};
1669    ivar_X=VarType.coord_x;
1670    ivar_Y=VarType.coord_y;
1671    ivar_Z=VarType.coord_z;
1672    ivar_U=VarType.vector_x;
1673    ivar_V=VarType.vector_y;
1674    ivar_W=VarType.vector_z;
1675    ivar_C=VarType.scalar ;
1676    ivar_Anc=VarType.ancillary;
1677    test_anc=zeros(size(VarIndex));
1678    test_anc(ivar_Anc)=ones(size(ivar_Anc));
1679    ivar_F=VarType.warnflag;
1680    ivar_FF=VarType.errorflag;
1681    testX=~isempty(ivar_X) && ~isempty(ivar_Y);
1682    DimCell=FieldData.VarDimName{VarIndex(1)};
1683    if ischar(DimCell)
1684        DimCell={DimCell};%name of dimensions
1685    end
1686
1687%% case of input fields with unstructured coordinates
1688    if testX
1689        XName=FieldData.ListVarName{ivar_X};
1690        YName=FieldData.ListVarName{ivar_Y};
1691        eval(['coord_x=FieldData.' XName ';'])
1692        eval(['coord_y=FieldData.' YName ';'])
1693        if length(ivar_Z)==1
1694            ZName=FieldData.ListVarName{ivar_Z};
1695            eval(['coord_z=FieldData.' ZName ';'])
1696        end
1697
1698        % translate  initial coordinates
1699        coord_x=coord_x-ObjectData.Coord(1,1);
1700        coord_y=coord_y-ObjectData.Coord(1,2);
1701        if ~isempty(ivar_Z)
1702            coord_z=coord_z-ObjectData.Coord(1,3);
1703        end
1704       
1705        % selection of the vectors in the projection range
1706%         if length(ivar_Z)==1 &&  width > 0
1707%             %components of the unitiy vector normal to the projection plane
1708%             fieldZ=NormVec_X*coord_x + NormVec_Y*coord_y+ NormVec_Z*coord_z;% distance to the plane           
1709%             indcut=find(abs(fieldZ) <= width);
1710%             for ivar=VarIndex
1711%                 VarName=FieldData.ListVarName{ivar};
1712%                 eval(['FieldData.' VarName '=FieldData.' VarName '(indcut);']) 
1713%                     % A VOIR : CAS DE VAR STRUCTUREE MAIS PAS GRILLE REGULIERE : INTERPOLER SUR GRILLE REGULIERE             
1714%             end
1715%             coord_x=coord_x(indcut);
1716%             coord_y=coord_y(indcut);
1717%             coord_z=coord_z(indcut);
1718%         end
1719
1720       %rotate coordinates if needed: TODO modify
1721       if testangle
1722           coord_X=(coord_x *cos(Phi) + coord_y* sin(Phi));
1723           coord_Y=(-coord_x *sin(Phi) + coord_y *cos(Phi))*cos(Theta);
1724           if ~isempty(ivar_Z)
1725               coord_Y=coord_Y+coord_z *sin(Theta);
1726           end
1727           
1728           coord_X=(coord_X *cos(Psi) - coord_Y* sin(Psi));%A VERIFIER
1729           coord_Y=(coord_X *sin(Psi) + coord_Y* cos(Psi));
1730           
1731       else
1732           coord_X=coord_x;
1733           coord_Y=coord_y;
1734           coord_Z=coord_z;
1735       end
1736        %restriction to the range of x and y if imposed
1737        testin=ones(size(coord_X)); %default
1738        testbound=0;
1739        if testXMin
1740            testin=testin & (coord_X >= XMin);
1741            testbound=1;
1742        end
1743        if testXMax
1744            testin=testin & (coord_X <= XMax);
1745            testbound=1;
1746        end
1747        if testYMin
1748            testin=testin & (coord_Y >= YMin);
1749            testbound=1;
1750        end
1751        if testYMin
1752            testin=testin & (coord_Y <= YMax);
1753            testbound=1;
1754        end
1755        if testbound
1756            indcut=find(testin);
1757            for ivar=VarIndex
1758                VarName=FieldData.ListVarName{ivar};
1759                eval(['FieldData.' VarName '=FieldData.' VarName '(indcut);'])           
1760            end
1761            coord_X=coord_X(indcut);
1762            coord_Y=coord_Y(indcut);
1763            if length(ivar_Z)==1
1764                coord_Z=coord_Z(indcut);
1765            end
1766        end
1767        % different cases of projection
1768        if isequal(ObjectData.ProjMode,'projection')%%%%%%%   NOT USED %%%%%%%%%%
1769            for ivar=VarIndex %transfer variables to the projection plane
1770                VarName=FieldData.ListVarName{ivar};
1771                if ivar==ivar_X %x coordinate
1772                    eval(['ProjData.' VarName '=coord_X;'])
1773                elseif ivar==ivar_Y % y coordinate
1774                    eval(['ProjData.' VarName '=coord_Y;'])
1775                elseif isempty(ivar_Z) || ivar~=ivar_Z % other variables (except Z coordinate wyhich is not reproduced)
1776                    eval(['ProjData.' VarName '=FieldData.' VarName ';'])
1777                end
1778                if isempty(ivar_Z) || ivar~=ivar_Z
1779                    ProjData.ListVarName=[ProjData.ListVarName VarName];
1780                    ProjData.VarDimName=[ProjData.VarDimName DimCell];
1781                    nbvar=nbvar+1;
1782                    if isfield(FieldData,'VarAttribute') && length(FieldData.VarAttribute) >=ivar
1783                        ProjData.VarAttribute{nbvar}=FieldData.VarAttribute{ivar};
1784                    end
1785                end
1786            end 
1787        elseif isequal(ObjectData.ProjMode,'interp')||isequal(ObjectData.ProjMode,'filter')%interpolate data on a regular grid
1788            coord_x_proj=XMin:DX:XMax;
1789            coord_y_proj=YMin:DY:YMax;
1790            coord_z_proj=ZMin:DZ:ZMax;
1791            DimCell={'coord_z','coord_y','coord_x'};
1792            ProjData.ListVarName={'coord_z','coord_y','coord_x'};
1793            ProjData.VarDimName={'coord_z','coord_y','coord_x'};   
1794            nbcoord=2; 
1795            ProjData.coord_z=[ZMin ZMax];
1796            ProjData.coord_y=[YMin YMax];
1797            ProjData.coord_x=[XMin XMax];
1798            if isempty(ivar_X), ivar_X=0; end;
1799            if isempty(ivar_Y), ivar_Y=0; end;
1800            if isempty(ivar_Z), ivar_Z=0; end;
1801            if isempty(ivar_U), ivar_U=0; end;
1802            if isempty(ivar_V), ivar_V=0; end;
1803            if isempty(ivar_W), ivar_W=0; end;
1804            if isempty(ivar_F), ivar_F=0; end;
1805            if isempty(ivar_FF), ivar_FF=0; end;
1806            if ~isequal(ivar_FF,0)
1807                VarName_FF=FieldData.ListVarName{ivar_FF};
1808                eval(['indsel=find(FieldData.' VarName_FF '==0);'])
1809                coord_X=coord_X(indsel);
1810                coord_Y=coord_Y(indsel);
1811            end
1812            FF=zeros(1,length(coord_y_proj)*length(coord_x_proj));
1813            testFF=0;
1814            [X,Y,Z]=meshgrid(coord_y_proj,coord_z_proj,coord_x_proj);%grid in the new coordinates
1815            for ivar=VarIndex
1816                VarName=FieldData.ListVarName{ivar};
1817                if ~( ivar==ivar_X || ivar==ivar_Y || ivar==ivar_Z || ivar==ivar_F || ivar==ivar_FF || test_anc(ivar)==1)                 
1818                    ivar_new=ivar_new+1;
1819                    ProjData.ListVarName=[ProjData.ListVarName {VarName}];
1820                    ProjData.VarDimName=[ProjData.VarDimName {DimCell}];
1821                    if isfield(FieldData,'VarAttribute') && length(FieldData.VarAttribute) >=ivar
1822                        ProjData.VarAttribute{ivar_new+nbcoord}=FieldData.VarAttribute{ivar};
1823                    end
1824                    if  ~isequal(ivar_FF,0)
1825                        eval(['FieldData.' VarName '=FieldData.' VarName '(indsel);'])
1826                    end
1827                    eval(['InterpFct=TriScatteredInterp(double(coord_X),double(coord_Y),double(coord_Z),double(FieldData.' VarName '))'])
1828                    eval(['ProjData.' VarName '=InterpFct(X,Y,Z);'])
1829%                     eval(['varline=reshape(ProjData.' VarName ',1,length(coord_y_proj)*length(coord_x_proj));'])
1830%                     FFlag= isnan(varline); %detect undefined values NaN
1831%                     indnan=find(FFlag);
1832%                     if~isempty(indnan)
1833%                         varline(indnan)=zeros(size(indnan));
1834%                         eval(['ProjData.' VarName '=reshape(varline,length(coord_y_proj),length(coord_x_proj));'])
1835%                         FF(indnan)=ones(size(indnan));
1836%                         testFF=1;
1837%                     end
1838                    if ivar==ivar_U
1839                        ivar_U=ivar_new;
1840                    end
1841                    if ivar==ivar_V
1842                        ivar_V=ivar_new;
1843                    end
1844                    if ivar==ivar_W
1845                        ivar_W=ivar_new;
1846                    end
1847                end
1848            end
1849            if testFF
1850                ProjData.FF=reshape(FF,length(coord_y_proj),length(coord_x_proj));
1851                ProjData.ListVarName=[ProjData.ListVarName {'FF'}];
1852               ProjData.VarDimName=[ProjData.VarDimName {DimCell}];
1853                ProjData.VarAttribute{ivar_new+1+nbcoord}.Role='errorflag';
1854            end
1855        end
1856       
1857%% case of input fields defined on a structured  grid
1858    else
1859        VarName=FieldData.ListVarName{VarIndex(1)};%get the first variable of the cell to get the input matrix dimensions
1860        eval(['DimValue=size(FieldData.' VarName ');'])%input matrix dimensions
1861        DimValue(find(DimValue==1))=[];%remove singleton dimensions       
1862        NbDim=numel(DimValue);%update number of space dimensions
1863        nbcolor=1; %default number of 'color' components: third matrix index without corresponding coordinate
1864        if NbDim>=3
1865            if NbDim>3
1866                errormsg='matrices with more than 3 dimensions not handled';
1867                return
1868            else
1869                VarType.coord
1870                if numel(find(VarType.coord))==2% the third matrix dimension does not correspond to a space coordinate
1871                    nbcolor=DimValue(3);
1872                    DimValue(3)=[]; %number of 'color' components updated
1873                    NbDim=2;% space dimension set to 2
1874                end
1875            end
1876        end
1877        AYName=FieldData.ListVarName{VarType.coord(NbDim-1)};%name of input x coordinate (name preserved on projection)
1878        AXName=FieldData.ListVarName{VarType.coord(NbDim)};%name of input y coordinate (name preserved on projection)   
1879        eval(['AX=FieldData.' AXName ';'])
1880        eval(['AY=FieldData.' AYName ';'])
1881        ListDimName=FieldData.VarDimName{VarIndex(1)};
1882        ProjData.ListVarName=[ProjData.ListVarName {AYName} {AXName}]; %TODO: check if it already exists in Projdata (several cells)
1883        ProjData.VarDimName=[ProjData.VarDimName {AYName} {AXName}];
1884
1885%         for idim=1:length(ListDimName)
1886%             DimName=ListDimName{idim};
1887%             if strcmp(DimName,'rgb')||strcmp(DimName,'nb_coord')||strcmp(DimName,'nb_coord_i')
1888%                nbcolor=DimValue(idim);
1889%                DimValue(idim)=[];
1890%             end
1891%             if isequal(DimName,'nb_coord_j')% NOTE: CASE OF TENSOR NOT TREATED
1892%                 DimValue(idim)=[];
1893%             end
1894%         end 
1895        Coord_z=[];
1896        Coord_y=[];
1897        Coord_x=[];   
1898
1899        for idim=1:NbDim %loop on space dimensions
1900            test_interp(idim)=0;%test for coordiate interpolation (non regular grid), =0 by default
1901            ivar=VarType.coord(idim);% index of the variable corresponding to the current dimension
1902            if ~isequal(ivar,0)%  a variable corresponds to the dimension #idim
1903                eval(['Coord{idim}=FieldData.' FieldData.ListVarName{ivar} ';']) ;% coord values for the input field
1904                if numel(Coord{idim})==2 %input array defined on a regular grid
1905                   DCoord_min(idim)=(Coord{idim}(2)-Coord{idim}(1))/DimValue(idim);
1906                else
1907                    DCoord=diff(Coord{idim});%array of coordinate derivatives for the input field
1908                    DCoord_min(idim)=min(DCoord);
1909                    DCoord_max=max(DCoord);
1910                %    test_direct(idim)=DCoord_max>0;% =1 for increasing values, 0 otherwise
1911                    if abs(DCoord_max-DCoord_min(idim))>abs(DCoord_max/1000)
1912                        msgbox_uvmat('ERROR',['non monotonic dimension variable # ' num2str(idim)  ' in proj_field.m'])
1913                                return
1914                    end               
1915                    test_interp(idim)=(DCoord_max-DCoord_min(idim))> 0.0001*abs(DCoord_max);% test grid regularity
1916                end
1917                test_direct(idim)=(DCoord_min(idim)>0);
1918            else  % no variable associated with the  dimension #idim, the coordinate value is set equal to the matrix index by default
1919                Coord_i_str=['Coord_' num2str(idim)];
1920                DCoord_min(idim)=1;%default
1921                Coord{idim}=[0.5 DimValue(idim)-0.5];
1922                test_direct(idim)=1;
1923            end
1924        end
1925        if DY==0
1926            DY=abs(DCoord_min(NbDim-1));
1927        end
1928        npY=1+round(abs(Coord{NbDim-1}(end)-Coord{NbDim-1}(1))/DY);%nbre of points after interpol
1929        if DX==0
1930            DX=abs(DCoord_min(NbDim));
1931        end
1932        npX=1+round(abs(Coord{NbDim}(end)-Coord{NbDim}(1))/DX);%nbre of points after interpol
1933        for idim=1:NbDim
1934            if test_interp(idim)
1935                DimValue(idim)=1+round(abs(Coord{idim}(end)-Coord{idim}(1))/abs(DCoord_min(idim)));%nbre of points after possible interpolation on a regular gri
1936            end
1937        end       
1938        Coord_y=linspace(Coord{NbDim-1}(1),Coord{NbDim-1}(end),npY);
1939        test_direct_y=test_direct(NbDim-1);
1940        Coord_x=linspace(Coord{NbDim}(1),Coord{NbDim}(end),npX);
1941        test_direct_x=test_direct(NbDim);
1942        DAX=DCoord_min(NbDim);
1943        DAY=DCoord_min(NbDim-1); 
1944        minAX=min(Coord_x);
1945        maxAX=max(Coord_x);
1946        minAY=min(Coord_y);
1947        maxAY=max(Coord_y);
1948        xcorner=[minAX maxAX minAX maxAX]-ObjectData.Coord(1,1);
1949        ycorner=[maxAY maxAY minAY minAY]-ObjectData.Coord(1,2);
1950        xcor_new=xcorner*cos(Phi)+ycorner*sin(Phi);%coord new frame
1951        ycor_new=-xcorner*sin(Phi)+ycorner*cos(Phi);
1952        if ~testXMax
1953            XMax=max(xcor_new);
1954        end
1955        if ~testXMin
1956            XMin=min(xcor_new);
1957        end
1958        if ~testYMax
1959            YMax=max(ycor_new);
1960        end
1961        if ~testYMin
1962            YMin=min(ycor_new);
1963        end
1964        DXinit=(maxAX-minAX)/(DimValue(NbDim)-1);
1965        DYinit=(maxAY-minAY)/(DimValue(NbDim-1)-1);
1966        if DX==0
1967            DX=DXinit;
1968        end
1969        if DY==0
1970            DY=DYinit;
1971        end
1972        if NbDim==3
1973            DZ=(Coord{1}(end)-Coord{1}(1))/(DimValue(1)-1);
1974            if ~test_direct(1)
1975                DZ=-DZ;
1976            end
1977            Coord_z=linspace(Coord{1}(1),Coord{1}(end),DimValue(1));
1978            test_direct_z=test_direct(1);
1979        end
1980        npX=floor((XMax-XMin)/DX+1);
1981        npY=floor((YMax-YMin)/DY+1);   
1982        if test_direct_y
1983            coord_y_proj=linspace(YMin,YMax,npY);%abscissa of the new pixels along the line
1984        else
1985            coord_y_proj=linspace(YMax,YMin,npY);%abscissa of the new pixels along the line
1986        end
1987        if test_direct_x
1988            coord_x_proj=linspace(XMin,XMax,npX);%abscissa of the new pixels along the line
1989        else
1990            coord_x_proj=linspace(XMax,XMin,npX);%abscissa of the new pixels along the line
1991        end
1992       
1993        % case with no rotation and interpolation
1994        if isequal(ProjMode,'projection') && isequal(Phi,0) && isequal(Theta,0) && isequal(Psi,0)
1995            if ~testXMin && ~testXMax && ~testYMin && ~testYMax && NbDim==2
1996                ProjData=FieldData;
1997            else
1998                indY=NbDim-1;
1999                if test_direct(indY)
2000                    min_indy=ceil((YMin-Coord{indY}(1))/DYinit)+1;
2001                    max_indy=floor((YMax-Coord{indY}(1))/DYinit)+1;
2002                    Ybound(1)=Coord{indY}(1)+DYinit*(min_indy-1);
2003                    Ybound(2)=Coord{indY}(1)+DYinit*(max_indy-1);
2004                else
2005                    min_indy=ceil((Coord{indY}(1)-YMax)/DYinit)+1;
2006                    max_indy=floor((Coord{indY}(1)-YMin)/DYinit)+1;
2007                    Ybound(2)=Coord{indY}(1)-DYinit*(max_indy-1);
2008                    Ybound(1)=Coord{indY}(1)-DYinit*(min_indy-1);
2009                end   
2010                if test_direct(NbDim)==1
2011                    min_indx=ceil((XMin-Coord{NbDim}(1))/DXinit)+1;
2012                    max_indx=floor((XMax-Coord{NbDim}(1))/DXinit)+1;
2013                    Xbound(1)=Coord{NbDim}(1)+DXinit*(min_indx-1);
2014                    Xbound(2)=Coord{NbDim}(1)+DXinit*(max_indx-1);
2015                else
2016                    min_indx=ceil((Coord{NbDim}(1)-XMax)/DXinit)+1;
2017                    max_indx=floor((Coord{NbDim}(1)-XMin)/DXinit)+1;
2018                    Xbound(2)=Coord{NbDim}(1)+DXinit*(max_indx-1);
2019                    Xbound(1)=Coord{NbDim}(1)+DXinit*(min_indx-1);
2020                end
2021                if NbDim==3
2022                    DimCell(1)=[]; %suppress z variable
2023                    DimValue(1)=[];
2024                                        %structured coordinates
2025                    if test_direct(1)
2026                        iz=ceil((ObjectData.Coord(1,3)-Coord{1}(1))/DZ)+1;
2027                    else
2028                        iz=ceil((Coord{1}(1)-ObjectData.Coord(1,3))/DZ)+1;
2029                    end
2030                end
2031                min_indy=max(min_indy,1);% deals with margin (bound lower than the first index)
2032                min_indx=max(min_indx,1);
2033                max_indy=min(max_indy,DimValue(1));
2034                max_indx=min(max_indx,DimValue(2));
2035                for ivar=VarIndex% loop on non coordinate variables
2036                    VarName=FieldData.ListVarName{ivar};
2037                    ProjData.ListVarName=[ProjData.ListVarName VarName];
2038                    ProjData.VarDimName=[ProjData.VarDimName {DimCell}];
2039                    if isfield(FieldData,'VarAttribute') && length(FieldData.VarAttribute)>=ivar
2040                        ProjData.VarAttribute{length(ProjData.ListVarName)}=FieldData.VarAttribute{ivar};
2041                    end
2042                    if NbDim==3
2043                        eval(['ProjData.' VarName '=squeeze(FieldData.' VarName '(iz,min_indy:max_indy,min_indx:max_indx));']);
2044                    else
2045                        eval(['ProjData.' VarName '=FieldData.' VarName '(min_indy:max_indy,min_indx:max_indx,:);']);
2046                    end
2047                end 
2048                eval(['ProjData.' AYName '=[Ybound(1) Ybound(2)];']) %record the new (projected ) y coordinates
2049                eval(['ProjData.' AXName '=[Xbound(1) Xbound(2)];']) %record the new (projected ) x coordinates
2050            end
2051        else       % case with rotation and/or interpolation
2052            if NbDim==2 %2D case
2053                [X,Y]=meshgrid(coord_x_proj,coord_y_proj);%grid in the new coordinates
2054                XIMA=ObjectData.Coord(1,1)+(X)*cos(Phi)-Y*sin(Phi);%corresponding coordinates in the original image
2055                YIMA=ObjectData.Coord(1,2)+(X)*sin(Phi)+Y*cos(Phi);
2056                XIMA=(XIMA-minAX)/DXinit+1;% image index along x
2057                YIMA=(-YIMA+maxAY)/DYinit+1;% image index along y
2058                XIMA=reshape(round(XIMA),1,npX*npY);%indices reorganized in 'line'
2059                YIMA=reshape(round(YIMA),1,npX*npY);
2060                flagin=XIMA>=1 & XIMA<=DimValue(2) & YIMA >=1 & YIMA<=DimValue(1);%flagin=1 inside the original image
2061                if isequal(ObjectData.ProjMode,'filter')
2062                    npx_filter=ceil(abs(DX/DAX));
2063                    npy_filter=ceil(abs(DY/DAY));
2064                    Mfilter=ones(npy_filter,npx_filter)/(npx_filter*npy_filter);
2065                    test_filter=1;
2066                else
2067                    test_filter=0;
2068                end
2069                eval(['ProjData.' AYName '=[coord_y_proj(1) coord_y_proj(end)];']) %record the new (projected ) y coordinates
2070                eval(['ProjData.' AXName '=[coord_x_proj(1) coord_x_proj(end)];']) %record the new (projected ) x coordinates
2071                for ivar=VarIndex
2072                    VarName=FieldData.ListVarName{ivar};
2073                    if test_interp(1) || test_interp(2)%interpolate on a regular grid       
2074                          eval(['ProjData.' VarName '=interp2(Coord{2},Coord{1},FieldData.' VarName ',Coord_x,Coord_y'');']) %TO TEST
2075                    end
2076                    %filter the field (image) if option 'filter' is used
2077                    if test_filter 
2078                         Aclass=class(FieldData.A);
2079                         eval(['ProjData.' VarName '=filter2(Mfilter,FieldData.' VarName ',''valid'');'])
2080                         if ~isequal(Aclass,'double')
2081                             eval(['ProjData.' VarName '=' Aclass '(FieldData.' VarName ');'])%revert to integer values
2082                         end
2083                    end
2084                    eval(['vec_A=reshape(FieldData.' VarName ',[],nbcolor);'])%put the original image in line             
2085                    %ind_in=find(flagin);
2086                    ind_out=find(~flagin);
2087                    ICOMB=(XIMA-1)*DimValue(1)+YIMA;
2088                    ICOMB=ICOMB(flagin);%index corresponding to XIMA and YIMA in the aligned original image vec_A
2089                    vec_B(flagin,1:nbcolor)=vec_A(ICOMB,:);
2090                    for icolor=1:nbcolor
2091                        vec_B(ind_out,icolor)=zeros(size(ind_out));
2092                    end
2093                    ProjData.ListVarName=[ProjData.ListVarName VarName];
2094                    ProjData.VarDimName=[ProjData.VarDimName {DimCell}];
2095                    if isfield(FieldData,'VarAttribute')&&length(FieldData.VarAttribute)>=ivar
2096                        ProjData.VarAttribute{length(ProjData.ListVarName)+nbcoord}=FieldData.VarAttribute{ivar};
2097                    end     
2098                    eval(['ProjData.' VarName '=reshape(vec_B,npY,npX,nbcolor);']);
2099                end
2100                ProjData.FF=reshape(~flagin,npY,npX);%false flag A FAIRE: tenir compte d'un flga antérieur 
2101                ProjData.ListVarName=[ProjData.ListVarName 'FF'];
2102                ProjData.VarDimName=[ProjData.VarDimName {DimCell}];
2103                ProjData.VarAttribute{length(ProjData.ListVarName)}.Role='errorflag';
2104            else %3D case
2105                if ~testangle     
2106                    % unstructured z coordinate
2107                    test_sup=(Coord{1}>=ObjectData.Coord(1,3));
2108                    iz_sup=find(test_sup);
2109                    iz=iz_sup(1);
2110                    if iz>=1 & iz<=npz
2111                        %ProjData.ListDimName=[ProjData.ListDimName ListDimName(2:end)];
2112                        %ProjData.DimValue=[ProjData.DimValue npY npX];
2113                        for ivar=VarIndex
2114                            VarName=FieldData.ListVarName{ivar};
2115                            ProjData.ListVarName=[ProjData.ListVarName VarName];
2116                            ProjData.VarAttribute{length(ProjData.ListVarName)}=FieldData.VarAttribute{ivar}; %reproduce the variable attributes 
2117                            eval(['ProjData.' VarName '=squeeze(FieldData.' VarName '(iz,:,:));'])% select the z index iz
2118                            %TODO : do a vertical average for a thick plane
2119                            if test_interp(2) || test_interp(3)
2120                                eval(['ProjData.' VarName '=interp2(Coord{3},Coord{2},ProjData.' VarName ',Coord_x,Coord_y'');'])
2121                            end
2122                        end
2123                    end
2124                else
2125                    errormsg='projection of structured coordinates on oblique plane not yet implemented';
2126                    %TODO: use interp3
2127                    return
2128                end
2129            end
2130        end
2131    end
2132
2133    %% projection of  velocity components in the rotated coordinates
2134    if testangle
2135        if isempty(ivar_V)
2136            msgbox_uvmat('ERROR','v velocity component missing in proj_field.m')
2137            return
2138        end
2139        UName=FieldData.ListVarName{ivar_U};
2140        VName=FieldData.ListVarName{ivar_V};   
2141        eval(['ProjData.' UName  '=cos(Phi)*ProjData.' UName '+ sin(Phi)*ProjData.' VName ';'])
2142        eval(['ProjData.' VName  '=cos(Theta)*(-sin(Phi)*ProjData.' UName '+ cos(Phi)*ProjData.' VName ');'])
2143        if ~isempty(ivar_W)
2144            WName=FieldData.ListVarName{ivar_W};
2145            eval(['ProjData.' VName '=ProjData.' VName '+ ProjData.' WName '*sin(Theta);'])%
2146            eval(['ProjData.' WName '=NormVec_X*ProjData.' UName '+ NormVec_Y*ProjData.' VName '+ NormVec_Z* ProjData.' WName ';']);
2147        end
2148        if ~isequal(Psi,0)
2149            eval(['ProjData.' UName '=cos(Psi)* ProjData.' UName '- sin(Psi)*ProjData.' VName ';']);
2150            eval(['ProjData.' VName '=sin(Psi)* ProjData.' UName '+ cos(Psi)*ProjData.' VName ';']);
2151        end
2152    end
2153end
2154
2155%------------------------------------------------------------------------
2156%--- transfer the global attributes
2157function [ProjData,errormsg]=proj_heading(FieldData,ObjectData)
2158%------------------------------------------------------------------------
2159ProjData=[];%default
2160errormsg='';%default
2161
2162%% transfer error
2163if isfield(FieldData,'Txt')
2164    errormsg=FieldData.Txt; %transmit erreur message
2165    return;
2166end
2167
2168%% transfer global attributes
2169if ~isfield(FieldData,'ListGlobalAttribute')
2170    ProjData.ListGlobalAttribute={};
2171else
2172    ProjData.ListGlobalAttribute=FieldData.ListGlobalAttribute;
2173end
2174for iattr=1:length(ProjData.ListGlobalAttribute)
2175    AttrName=ProjData.ListGlobalAttribute{iattr};
2176    if isfield(FieldData,AttrName)
2177        eval(['ProjData.' AttrName '=FieldData.' AttrName ';']);
2178    end
2179end
2180
2181%% transfer coordinate unit
2182if isfield(FieldData,'CoordUnit')
2183    if isfield(ObjectData,'CoordUnit')&~isequal(FieldData.CoordUnit,ObjectData.CoordUnit)
2184        errormsg=[ObjectData.Style ' in ' ObjectData.CoordUnit ' coordinates, while field in ' FieldData.CoordUnit ];
2185        return
2186    else
2187         ProjData.CoordUnit=FieldData.CoordUnit;
2188    end
2189end
2190
2191%% store the properties of the projection object
2192ListObject={'Style','ProjMode','RangeX','RangeY','RangeZ','Phi','Theta','Psi','Coord'};
2193for ilist=1:length(ListObject)
2194    if isfield(ObjectData,ListObject{ilist})
2195        eval(['val=ObjectData.' ListObject{ilist} ';'])
2196        if ~isempty(val)
2197            eval(['ProjData.Object' ListObject{ilist} '=val;']);
2198            ProjData.ListGlobalAttribute=[ProjData.ListGlobalAttribute {['Object' ListObject{ilist}]}];
2199        end
2200    end   
2201end
Note: See TracBrowser for help on using the repository browser.