source: trunk/src/proj_field.m @ 491

Last change on this file since 491 was 491, checked in by sommeria, 12 years ago

fix the the way to deal with filter fields using tps
fix the main projection plane in uvmat

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