source: trunk/src/proj_field.m @ 236

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

correct Matlab PIV, remove call to image tool box. Improve menu of uvmat VelType? (replacement of buttons)

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