source: trunk/src/uvmat.m @ 494

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

various bugs corrected after testing in Windows OS. Introduction
of filter tps

File size: 208.4 KB
RevLine 
[387]1%'uvmat': function associated with the GUI 'uvmat.fig' for images and data field visualization
2%------------------------------------------------------------------------
3% function huvmat=uvmat(input)
4%
5%OUTPUT
6% huvmat=current handles of the GUI uvmat.fig
7%%
8%
9%INPUT:
10% input: input file name (if character chain), or input image matrix to
11% visualize, or Matlab structure representing  netcdf fields (with fields
12% ListVarName....)
13%
14%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
15%  Copyright Joel Sommeria,  2008, LEGI / CNRS-UJF-INPG, joel.sommeria@legi.grenoble-inp.fr.
16%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
17%     This open is part of the toolbox UVMAT.
18%
19%     UVMAT is free software; you can redistribute it and/or modify
20%     it under the terms of the GNU General Public License as published by
21%     the Free Software Foundation; either version 2 of the License, or
22%     (at your option) any later version.
23%
24%     UVMAT is distributed in the hope that it will be useful,
25%     but WITHOUT ANY WARRANTY; without even the implied warranty of
26%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27%     GNU General Public License (open UVMAT/COPYING.txt) for more details.
28%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
29%
30% Information stored on the interface:
31%    'Strings' of all edit boxes and menus: get(handles.Tag,'String')
32%    'Values' of all menus and toggle buttons: get(handles.Tag,'Value')
33%     Matlab structure called UvData stored as 'UserData' of the figure uvmat.fig,(can be obtained by right mouse click on the interface).
34%          It contains the following fields:
35%     - Fixed specifiacation of plotting figures and axes (defined bu uvmat_OpeningFcn)
36%          .PosColorbar: [0.8210 0.4710 0.0190 0.4450]; specified position of the colorbar on figures
37%     - Information read in the documentation open of a series (activated by RootPath_Callback) :
38%          .XmlData, with fields:
39%               .Time: matrix of times of the images with index i and j
40%               .GeometryCalib: [1x1 struct]
41%     - Information defined from the interface:
42%           .NewSeries: =1 when the first view of a new field series is displayed, else 0
[450]43%           .FileName:(char string)
[387]44%           .FieldName: (char string) main field selected('image', 'velocity'...)
45%           .CName: (char string)name of the scalar used for vector colors
46%          .MovieObject{1}: movie object representing an input movie
47%          .MovieObject{2}: idem for a second input series (_1)
[450]48%          .FileName_1 : last second input file name (to deal with a constant second input without reading again the file)
[387]49%          .ZMin, .ZMax: range of the z coordinate
50%..... to complement
51%     - Information on  projection objects
52%           .Object: {[1x1 struct]}
53%           .CurrentObjectIndex: index of the projection object .Object currently selected for editing
54%     -Information on the current field (Field{i})
55%            .Txt : text information to display (e.g. error message)
56%            .NbDim: number of dimensions (=0 by default)
57%            .NbCoord: number of vector components
58%            .CoordType: expresses the type of coordinate ('px' for image, 'sig' for instruments, or 'phys')
59%            .dt: time interval for the corresponding image pair
60%            .Mesh: estimated typical distance between vectors
61%            .ZMax:
62%            .ZMin:
63%            .X, .Y, .Z: set of vector coordinates
64%            .U,.V,.W: corresponding set of vector components
65%            .F: corresponding set of warning flags
66%            .FF: corresponding set of false flags, =0 for good vectors
67%            .C: corresponding values of the scalar used for vector color
68%             (.X, .Y, .Z,.U,.V,.W,.F,.FF,.C are matlab vectors of the same length,
69%                     equal to the number of vectors stored in the input open)
70%            .CName: name of the scalar .C
71%            .CType: type of the scalar .C, setting how the scalar is obtained (see 'Scalars' below)
72%            .A image or scalar
73%            .AX: vector of dimension 2 representing the first and last values
74%              of the X coordinates for the image or scalar known on a regular grid,
75%              or vector of dimension .A for a scaler defined on irregular grid.
76%            .AY: same as .AX along the Y direction
77%            .AName: name of the scalar, ='image' for an image
78
79% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%   DATA FLOW  (for run0_Callback) %%%%%%%%%%%%%%%%%%%%:
80%
[406]81%
82% 1) Input filenames are determined by MenuBrowse (first field), MenuBrowse_1
83% (second field), or by the stored file names under  Browse, or as an input of uvmat.
84% 2) These functions call 'display_file_name.m' which detects the file series, and fills the file index boxes
85% 3) Then 'update_rootinfo.m' Updates information about a new field series (indices to scan, timing, calibration from an xml file)
86% 4) Then fields are opened and visualised by the main sub-function 'refresh_field.m'
[387]87% The function first reads the name of the input file from the edit boxes  of the GUI
[406]88% A second input file can be introduced for file comparison
[387]89% It then reads the input file(s) with the appropriate function, read for
90% images, read_civxdata.m for CIVx PIV data, nc2struct for other netcdf
91% files.
92%               Main input open   second input open(_1)        second image (pair animation)
93%            |                 |                             
94%            |                 |                                               
95%                     Field{1}         Field{2}               
96%                                                                         |
97% coord transform (phys.m) or other user defined  fct acting on Field{i}  |
98%                                                                   Field{i}
99%                                                                    |
100% calc_field.m: calculate scalar or other derived fields (vort, div..).
101%
102% sub_field.m: combine the input Field{i} in a single set of fields (vector + scalar):
103%              Field{i=1->3}.X --> UvData.X                          |
104%                                                                    |
105%                                                                 UvData
106%                                                                    |
107% plot histograms of the whole  field
108% proj_field.m: project the set of fields on the current projection objects defined by UvData.Object
109%                                                                    |                                                                          |
110%                                                                ObjectData
111%                                                                    |
112% plot_field.m: plot the projected fields and store them as          |
113% UvData.axes3                                        |
114%                                                                    |
115%                                                                AxeData
116%
117%%%%%%%%%%%%%%    SCALARS: %%%%%%%%%%%%??%%%
118% scalars are displayed either as an image or countour plot, either as a color of
119% velocity vectors. The scalar values in the first case is represented by
120% UvData.Field.A, and by UvData.Field.C in the second case. The corresponding set of X
121% and Y coordinates are represented by UvData.Field.AX and UvData.Field.AY, and .X and
122% .Y for C (the same as velocity vectors). If A is a nxxny matrix (scalar
123% on a regtular grid), then .AX andf.AY contains only two elements, represneting the
124% coordinates of the four image corners. The scalar name is represented by
125% the strings .AName and/or .CName.
126% If the scalar exists in an input open (image or scalar stored under its
127% name in a netcdf open), it is directly read at the level of Field{1}or Field{2}.
128% Else only its name AName is recorded in Field{i}, and its field is then calculated
129%by the fuction calc_scal after the coordinate transform or after projection on an edit_object
130     
131% Properties attached to plotting figures (standard Matlab properties):
132%    'CurrentAxes'= gca or get(gcf,'CurrentAxes');
133%    'CurrentPoint'=get(gcf,'CurrentPoint'): figure coordinates of the point over which the mouse is positioned
134%    'CurrentCharacter'=get(gcf,'CurrentCharacter'): last character typed  over the figure where the mouse is positioned
135%    'WindowButtonMotionFcn': function permanently called by mouse motion over the figure
136%    'KeyPressFcn': function called by pressing a key on the key board
137%    'WindowButtonDownFcn':  function called by pressing the mouse over the  figure
138%    'WindowButtonUpFcn': function called by releasing  the mouse pressure over the  figure
139
140% Properties attached to plotting axes:
141%    'CurrentPoint'=get(gca,'CurrentPoint'); (standard Matlab) same as for the figure, but position in plot coordinates.
142%     AxeData:=get(gca,'UserData');
143%     AxeData.Drawing  = create: create a new object
144%                       = deform: modify an existing object by moving its defining create
145%                      = off: no current drawing action
146%                     = translate: translate an existing object
147%                    = calibration: move a calibration point
148%                    = CheckZoom: isolate a subregion for CheckZoom in=1 if an object is being currently drawn, 0 else (set to 0 by releasing mouse button)
149%            .CurrentOrigin: Origin of a curently drawn edit_object
150%            .CurrentLine: currently drawn menuline (A REVOIR)
151%            .CurrentObject: handle of the currently drawn edit_object
152%            .CurrentRectZoom: current rectangle used for CheckZoom
153
154% Properties attached to projection objects (create, menuline, menuplane...):
155%    'Tag'='proj_object': for all projection objects
156%    ObjectData.Type=...: style of projection object:
157%              .ProjMode
158%              .Coord: defines the position of the object
159%              .XMin,YMin....
160%              .XMax,YMax....
161%              .DX,DY,DZ
162%              .Phi, .Theta, .Psi : Euler angles
163%              .X,.Y,.U,.V.... : field data projected on the object
164%              .IndexObj: index in the list of UvData.Object
165           %during plotting
166%               .plotaxes: handles of the current axes used to plot the  result of field projection on the object
167%               .plothandle: vector of handle(s) of the object graphic represnetation in all the opened plotting axes
168% To each projection object #iobj, corresponds an axis
169% Object{iobj}.plotaxes and nbobj representation graphs  Object{iobj}.plothandles(:) (where nbobj is the
170% nbre of current objects opened in uvmat. Note that Object{iobj}.plothandles(iobj)=[] : an object is not represented in its own projection field;
171
172%------------------------------------------------------------------------
173%------------------------------------------------------------------------
[406]174%  I - MAIN FUNCTION uvmat
[387]175%------------------------------------------------------------------------
176%------------------------------------------------------------------------
177function varargout = uvmat(varargin)
178
179% Begin initialization code - DO NOT EDIT
180gui_Singleton = 1;
181gui_State = struct('gui_Name',          mfilename, ...
182                   'gui_Singleton',     gui_Singleton, ...
183                   'gui_OpeningFcn',    @uvmat_OpeningFcn, ...
184                   'gui_OutputFcn',     @uvmat_OutputFcn, ...
185                   'gui_LayoutFcn',     [], ...
186                   'gui_Callback',      []);
187if nargin && ischar(varargin{1})&& ~isempty(regexp(varargin{1},'_Callback','once'))
188    gui_State.gui_Callback = str2func(varargin{1});
189end
190
191if nargout
192    varargout{1:nargout} = gui_mainfcn(gui_State, varargin{:});
193else
194    gui_mainfcn(gui_State, varargin{:});
195end
196% End initialization code - DO NOT EDIT
197
198%------------------------------------------------------------------------
199% --- Executes just before the GUI uvmat is made visible.
200function uvmat_OpeningFcn(hObject, eventdata, handles, input )
201%------------------------------------------------------------------------
202
203%% Choose default command menuline output for uvmat (standard GUI)
204handles.output = hObject;
205
206%% Update handles structure (standard GUI)
207guidata(hObject, handles);
208
209%% set the position of colorbar and ancillary GUIs:
210set(hObject,'Units','Normalized')
211movegui(hObject,'center')
212UvData.OpenParam.PosColorbar=[0.805 0.022 0.019 0.445];
213UvData.OpenParam.SetObjectOrigin=[-0.05 -0.03]; %position for set_object
214UvData.OpenParam.SetObjectSize=[0.3 0.7];
215UvData.OpenParam.CalOrigin=[0.95 -0.03];%position for geometry_calib (TO IMPROVE)
216UvData.OpenParam.CalSize=[0.28 1];
217UvData.axes3=[];%initiate the record of plotted field
218UvData.axes2=[];
219UvData.axes1=[];
220AxeData.LimEditBox=1; %initialise AxeData
221set(handles.axes3,'UserData',AxeData)
222
223%% set functions for the mouse and keyboard
224set(hObject,'KeyPressFcn',{'keyboard_callback',handles})%set keyboard action function
225set(hObject,'WindowButtonMotionFcn',{'mouse_motion',handles})%set mouse action functio
226set(hObject,'WindowButtonDownFcn',{'mouse_down'})%set mouse click action function
227set(hObject,'WindowButtonUpFcn',{'mouse_up',handles})
228set(hObject,'DeleteFcn',{@closefcn})%
229
230%% refresh projection plane
[424]231set(handles.ListObject,'Value',1)% default: empty projection objectproj_field
[429]232set(handles.ListObject,'String',{'plane'})
[410]233set(handles.ListObject_1,'Value',1)% default: empty projection objectproj_field
[429]234set(handles.ListObject_1,'String',{'plane'})
[387]235set(handles.Fields,'Value',1)
236set(handles.Fields,'string',{''})
237
238%% TRANSFORM menu: builtin fcts
239menu_str={'';'phys';'px';'phys_polar'};
240UvData.OpenParam.NbBuiltin=numel(menu_str); %number of functions
241path_uvmat=fileparts(which('uvmat'));
242addpath (path_uvmat) ; %add the path to UVMAT, (useful in case of change of working directory after civ has been s opened in the working directory)
243addpath(fullfile(path_uvmat,'transform_field'))%add the path to transform functions,
244fct_handle{1,1}=[];
245testexist=zeros(size(menu_str'));%default
246testexist(1)=1;
247for ilist=2:length(menu_str)
248    if exist(menu_str{ilist},'file')
249        fct_handle{ilist,1}=str2func(menu_str{ilist});
250        testexist(ilist)=1;
251    else
252        testexist(ilist)=0;
253    end
254end
255rmpath(fullfile(path_uvmat,'transform_field'))
256
257%% load the list of previously browsed files in menus Open and Open_1
258 dir_perso=prefdir; % path to the directory .matlab for personal data
259 profil_perso=fullfile(dir_perso,'uvmat_perso.mat');% personal data file uvmauvmat_perso.mat' in .matlab
260 if exist(profil_perso,'file')
261      h=load (profil_perso);
262      if isfield(h,'MenuFile')
263          for ifile=1:min(length(h.MenuFile),5)
264              eval(['set(handles.MenuFile_' num2str(ifile) ',''Label'',h.MenuFile{ifile});'])
265               eval(['set(handles.MenuFile_' num2str(ifile) '_1,''Label'',h.MenuFile{ifile});'])
266          end
267      end
268      if isfield(h,'transform_fct') && iscell(h.transform_fct)
269         for ilist=1:length(h.transform_fct);
270             if exist(h.transform_fct{ilist},'file')
271                [path,file]=fileparts(h.transform_fct{ilist});
272                addpath(path)
273                h_func=str2func(file);
274                rmpath(path)
275                testexist=[testexist 1];
276             else
277                file='';
278                h_func=[];
279                testexist=[testexist 0];
280             end
281             fct_handle=[fct_handle; {h_func}]; %concatene the list of paths
282             menu_str=[menu_str; {file}];
283         end
284      end
285 end
286menu_str=menu_str(testexist==1);%=menu_str(testexist~=0)
287fct_handle=fct_handle(testexist==1);
288menu_str=[menu_str;{'more...'}];
289set(handles.transform_fct,'String',menu_str)
290set(handles.transform_fct,'UserData',fct_handle)% store the list of path in UserData of ACTION
291
292%% case of an input argument for uvmat
293testinputfield=0;
294inputfile=[];
295Field=[];
296if exist('input','var')
297    if ishandle(handles.UVMAT_title)
298        delete(handles.UVMAT_title)
299    end   
300    if isstruct(input)
301        if isfield(input,'InputFile')
302            inputfile=input.InputFile;
303        end
304        if isfield(input,'TimeIndex')
305            set(handles.i1,num2str(input.TimeIndex))
306        end
307        if isfield(input,'FieldsString')
308            UvData.FieldsString=input.FieldsString;
309        end
310    elseif ischar(input)% file name introduced as input
311           inputfile=input;
312    elseif isnumeric(input)%simple matrix introduced as input
313        sizinput=size(input);
314        if sizinput(1)<=1 || sizinput(2)<=1
315            msgbox_uvmat('ERROR','bad input for uvmat: file name, structure or numerical matrix accepted')
316            return
317        end
318        UvData.Field.ListVarName={'A','coord_y','coord_x'};
319        UvData.Field.VarDimName={{'coord_y','coord_x'},'cord_y','coord_x'};
320        UvData.Field.A=input;
321        UvData.Field.coord_x=[0.5 size(input,2)-0.5];
322        UvData.Field.coord_y=[size(input,1)-0.5 0.5];
323        testinputfield=1;
324    end
325else
[476]326    %% check the path and date of modification of all functions in uvmat
327    path_to_uvmat=which ('uvmat');% check the path detected for source file uvmat
328    [infomsg,date_str,svn_info]=check_files;%check the path of the functions called by uvmat.m   
329    date_str=['last modification: ' date_str];
330    if ishandle(handles.UVMAT_title)
331        set(handles.UVMAT_title,'String',...
332            [{'Copyright  LEGI UMR 5519 /CNRS-UJF-Grenoble INP, 2010'};...
333            {'GNU General Public License'};...
334            {path_to_uvmat};...
335            {date_str};...
336            infomsg]);
337    end
[387]338end
339set(handles.uvmat,'UserData',UvData)
340if ~isempty(inputfile)
341    %%%%% display the input field %%%%%%%
[406]342    display_file_name(handles,inputfile)
[387]343    %%%%%%%
344    testinputfield=1;
345end
346
347%% plot input field if exists
348if testinputfield
349    %delete drawn objects
350    hother=findobj(handles.axes3,'Tag','proj_object');%find all the proj objects
351    for iobj=1:length(hother)
352        delete_object(hother(iobj))
353    end 
354    if isempty(inputfile)
355        errormsg=refresh_field(handles,[],[],[],[],[],[],{Field});
356        set(handles.MenuTools,'Enable','on')
357        set(handles.OBJECT_txt,'Visible','on')
358        set(handles.edit_object,'Visible','on')
[410]359%         set(handles.ListObject_1,'Visible','on')
[387]360        set(handles.frame_object,'Visible','on')
361        if ~isempty(errormsg)
362            msgbox_uvmat('ERROR',errormsg)
363        end
364    end
365end
366
367set_vec_col_bar(handles) %update the display of color code for vectors
368
369%------------------------------------------------------------------------
370% --- Outputs from this function are returned to the command menuline.
371function varargout = uvmat_OutputFcn(hObject, eventdata, handles)
372varargout{1} = handles.output;% the only output argument is the handle to the GUI figure
373
374%------------------------------------------------------------------------
[402]375% --- executed when closing uvmat: delete or desactivate the associated figures if exist
376function closefcn(gcbo,eventdata)
[387]377%------------------------------------------------------------------------
[402]378hh=findobj(allchild(0),'tag','view_field');
379if ~isempty(hh)
380    delete(hh)
381end
382hh=findobj(allchild(0),'tag','geometry_calib');
383if ~isempty(hh)
384    delete(hh)
385end
386hh=findobj(allchild(0),'tag','set_object');
387if ~isempty(hh)
388    hhh=findobj(hh,'tag','PLOT');
389    set(hhh,'enable','off')
390end
391
392%------------------------------------------------------------------------
393%------------------------------------------------------------------------
[387]394%  II - FUNCTIONS FOR INTRODUCING THE INPUT FILES
395% automatically sets the global properties when the rootfile name is introduced
396% then activate the view-field action if selected
397% it is activated either by clicking on the RootPath window or by the
398% browser
399%------------------------------------------------------------------------
400%------------------------------------------------------------------------
401% --- Executes on the menu Open/Browse...
402% search the files, recognize their type according to their name and fill the rootfile input windows
403function MenuBrowse_Callback(hObject, eventdata, handles)
404[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
405oldfile=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
406if isempty(oldfile)||isequal(oldfile,'') %loads the previously stored file name and set it as default in the file_input box
407         dir_perso=prefdir;
408         profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
409         if exist(profil_perso,'file')
410              h=load (profil_perso);
411             if isfield(h,'MenuFile_1')
412                  oldfile=h.MenuFile_1;
413             end
414         end
415end
[421]416% [FileName, PathName] = uigetfile( ...
417%        {'*.xml;*.xls;*.civ;*.png;*.jpg;*.tif;*.avi;*.AVI;*.vol;*.nc;*.cmx;*.fig;*.log;*.dat;*.bat;', ' (*.xml,*.xls,*.civ,*.jpg ,*.png, .tif, *.avi,*.vol,*.nc,*.cmx,*.fig,*.log,*.dat,*.bat)';
418%        '*.xml',  '.xml files '; ...
419%         '*.xls',  '.xls files '; ...
420%         '*.civ',  '.civ files '; ...
421%         '*.jpg',' jpeg image files'; ...
422%         '*.png','.png image files'; ...
423%         '*.tif','.tif image files'; ...
424%         '*.avi;*.AVI','.avi movie files'; ...
425%         '*.vol','.volume images (png)'; ...
426%         '*.nc','.netcdf files'; ...
427%         '*.cdf','.netcdf files'; ...
428%         '*.cmx','.cmx text files ';...
429%         '*.fig','.fig files (matlab fig)';...
430%         '*.log','.log text files ';...
431%         '*.dat','.dat text files ';...
432%         '*.bat','.bat system command text files';...
433%         '*.*',  'All Files (*.*)'}, ...
434%         'Pick a file',oldfile);
435
436[FileName, PathName] = uigetfile({'*.*','All Files(*.*)'},'Pick a file',oldfile);
[387]437fileinput=[PathName FileName];%complete file name
438sizf=size(fileinput);
439if (~ischar(fileinput)||~isequal(sizf(1),1)),return;end
440
441% display the selected field and related information
[406]442display_file_name( handles,fileinput)
[387]443
444% -----------------------------------------------------------------------
445% --- Open again the file whose name has been recorded in MenuFile_1
446function MenuFile_1_Callback(hObject, eventdata, handles)
447%------------------------------------------------------------------------
448fileinput=get(handles.MenuFile_1,'Label');
[406]449display_file_name( handles,fileinput)
[387]450
451% -----------------------------------------------------------------------
452% --- Open again the file whose name has been recorded in MenuFile_2
453function MenuFile_2_Callback(hObject, eventdata, handles)
454%------------------------------------------------------------------------
455fileinput=get(handles.MenuFile_2,'Label');
[406]456display_file_name(handles,fileinput)
[387]457
458% -----------------------------------------------------------------------
459% --- Open again the file whose name has been recorded in MenuFile_3
460function MenuFile_3_Callback(hObject, eventdata, handles)
461%------------------------------------------------------------------------
462fileinput=get(handles.MenuFile_3,'Label');
[406]463display_file_name(handles,fileinput)
[387]464
465% -----------------------------------------------------------------------
466% --- Open again the file whose name has been recorded in MenuFile_4
467function MenuFile_4_Callback(hObject, eventdata, handles)
468%------------------------------------------------------------------------
469fileinput=get(handles.MenuFile_4,'Label');
[406]470display_file_name(handles,fileinput)
[387]471
472% -----------------------------------------------------------------------
473% --- Open again the file whose name has been recorded in MenuFile_5
474function MenuFile_5_Callback(hObject, eventdata, handles)
475%------------------------------------------------------------------------
476fileinput=get(handles.MenuFile_5,'Label');
[406]477display_file_name(handles,fileinput)
[387]478
[402]479%------------------------------------------------------------------------
480% --- Executes on the menu Open/Browse_1 for the second input field,
481%     search the files, recognize their type according to their name and fill the rootfile input windows
482function MenuBrowse_1_Callback(hObject, eventdata, handles)
483%------------------------------------------------------------------------
484RootPath=get(handles.RootPath,'String');
[421]485% [FileName, PathName, filterindex] = uigetfile( ...
486%        {'*.xml;*.xls;*.civ;*.jpg;*.png;*.avi;*.AVI;*.nc;*.cmx;*.fig;*.log;*.dat', ' (*.xml,*.xls,*.civ, *.jpg,*.png, *.avi,*.nc,*.cmx ,*.fig,*.log,*.dat)';
487%        '*.xml',  '.xml files '; ...
488%         '*.xls',  '.xls files '; ...
489%         '*.civ',  '.civ files '; ...
490%         '*.jpg','.jpg image files'; ...
491%         '*.png','.png image files'; ...
492%         '*.avi;*.AVI','.avi movie files'; ...
493%         '*.nc','.netcdf files'; ...
494%         '*.cdf','.netcdf files'; ...
495%         '*.cmx','.cmx text files';...
496%         '*.cmx2','.cmx2 text files';...
497%         '*.fig','.fig files (matlab fig)';...
498%         '*.log','.log text files ';...
499%         '*.dat','.dat text files ';...
500%         '*.*',  'All Files (*.*)'}, ...
501%         'Pick a second file for comparison',RootPath);
502[FileName, PathName] = uigetfile({'*.*','All Files(*.*)'},'Pick a file',RootPath);
[402]503fileinput_1=[PathName FileName];%complete file name
504sizf=size(fileinput_1);
505if (~ischar(fileinput_1)||~isequal(sizf(1),1)),return;end
506
507% refresh the current displayed field
508set(handles.SubField,'Value',1)
[406]509display_file_name(handles,fileinput_1,2)
[402]510
511%update list of recent files in the menubar
512MenuFile_1=fileinput_1;
513MenuFile_2=get(handles.MenuFile_1,'Label');
514MenuFile_3=get(handles.MenuFile_2,'Label');
515MenuFile_4=get(handles.MenuFile_3,'Label');
516MenuFile_5=get(handles.MenuFile_4,'Label');
517set(handles.MenuFile_1,'Label',MenuFile_1)
518set(handles.MenuFile_2,'Label',MenuFile_2)
519set(handles.MenuFile_3,'Label',MenuFile_3)
520set(handles.MenuFile_4,'Label',MenuFile_4)
521set(handles.MenuFile_5,'Label',MenuFile_5)
522set(handles.MenuFile_1_1,'Label',MenuFile_1)
523set(handles.MenuFile_2_1,'Label',MenuFile_2)
524set(handles.MenuFile_3_1,'Label',MenuFile_3)
525set(handles.MenuFile_4_1,'Label',MenuFile_4)
526set(handles.MenuFile_5_1,'Label',MenuFile_5)
527dir_perso=prefdir;
528profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
529if exist(profil_perso,'file')
530    save (profil_perso,'MenuFile_1','MenuFile_2','MenuFile_3','MenuFile_4', 'MenuFile_5','-append'); %store the file names for future opening of uvmat
531else
532    txt=ver('MATLAB');
533    Release=txt.Release;
534    relnumb=str2double(Release(3:4));
535    if relnumb >= 14
536        save (profil_perso,'MenuFile_1','MenuFile_2','MenuFile_3','MenuFile_4', 'MenuFile_5','-V6'); %store the file names for future opening of uvmat
537    else
538        save (profil_perso,'MenuFile_1','MenuFile_2','MenuFile_3','MenuFile_4', 'MenuFile_5'); %store the file names for future opening of uvmat
539    end
540end
541
542% -----------------------------------------------------------------------
543% --- Open again as second field the file whose name has been recorded in MenuFile_1
544function MenuFile_1_1_Callback(hObject, eventdata, handles)
545% -----------------------------------------------------------------------
546fileinput_1=get(handles.MenuFile_1_1,'Label');
547set(handles.SubField,'Value',1)
[406]548display_file_name(handles,fileinput_1,2)
[402]549
550% -----------------------------------------------------------------------
551% --- Open again as second field the file whose name has been recorded in MenuFile_2
552function MenuFile_2_1_Callback(hObject, eventdata, handles)
553% -----------------------------------------------------------------------
554fileinput_1=get(handles.MenuFile_2_1,'Label');
555set(handles.SubField,'Value',1)
[406]556display_file_name(handles,fileinput_1,2)
[402]557
558% -----------------------------------------------------------------------
559% --- Open again as second field the file whose name has been recorded in MenuFile_3
560function MenuFile_3_1_Callback(hObject, eventdata, handles)
561% -----------------------------------------------------------------------
562fileinput_1=get(handles.MenuFile_3_1,'Label');
563set(handles.SubField,'Value',1)
[406]564display_file_name(handles,fileinput_1,2)
[402]565
566% -----------------------------------------------------------------------
567% --- Open again as second field the file whose name has been recorded in MenuFile_4
568function MenuFile_4_1_Callback(hObject, eventdata, handles)
569% -----------------------------------------------------------------------
570fileinput_1=get(handles.MenuFile_4_1,'Label');
571set(handles.SubField,'Value',1)
[406]572display_file_name(handles,fileinput_1,2)
[402]573
574% -----------------------------------------------------------------------
575% --- Open again as second field the file whose name has been recorded in MenuFile_5
576function MenuFile_5_1_Callback(hObject, eventdata, handles)
577% -----------------------------------------------------------------------
578fileinput_1=get(handles.MenuFile_5_1,'Label');
579set(handles.SubField,'Value',1)
[406]580display_file_name(handles,fileinput_1,2)
[402]581
582%------------------------------------------------------------------------
583% --- Called by action in RootPath edit box
584function RootPath_Callback(hObject,eventdata,handles)
585%------------------------------------------------------------------------
586% read the current input file name:
587[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
[456]588if ~exist(fullfile(RootPath,SubDir),'dir')
589    msgbox_uvmat('ERROR',['directory ' fullfile(RootPath,SubDir) ' does not exist'])
590    return
591end
[402]592% detect the file type, get the movie object if relevant, and look for the corresponding file series:
593[RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,tild,FileType,MovieObject]=find_file_series(fullfile(RootPath,SubDir),[RootFile FileIndices FileExt]);
594% initiate the input file series and refresh the current field view:
[406]595update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,MovieObject,1);
[402]596
597%-----------------------------------------------------------------------
598% --- Called by action in RootPath_1 edit box
599function RootPath_1_Callback(hObject,eventdata,handles)
600% -----------------------------------------------------------------------
601% update_rootinfo_1(hObject,eventdata,handles)
602[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes_1(handles);
[456]603if ~exist(fullfile(RootPath,SubDir),'dir')
604    msgbox_uvmat('ERROR',['directory ' fullfile(RootPath,SubDir) ' does not exist'])
605    return
606end
[402]607% detect the file type, get the movie object if relevant, and look for the corresponding file series:
608[RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,tild,FileType,MovieObject]=find_file_series(fullfile(RootPath,SubDir),[RootFile FileIndices FileExt]);
609% initiate the input file series and refresh the current field view:
610update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,MovieObject,2);
611
612%------------------------------------------------------------------------
613% --- Called by action in RootFile edit box
614function SubDir_Callback(hObject, eventdata, handles)
615%------------------------------------------------------------------------
616%refresh the menu of input fields
617Fields_Callback(hObject, eventdata, handles);
618% refresh the current field view
619run0_Callback(hObject, eventdata, handles);
620
621%------------------------------------------------------------------------
622% --- Called by action in RootFile edit box
623function RootFile_Callback(hObject, eventdata, handles)
624%------------------------------------------------------------------------
625RootPath_Callback(hObject,eventdata,handles)
626
627%-----------------------------------------------------------------------
628% --- Called by action in RootFile_1 edit box
629function RootFile_1_Callback(hObject, eventdata, handles)
630% -----------------------------------------------------------------------
631RootPath_1_Callback(hObject,eventdata,handles)
632
633%------------------------------------------------------------------------
634% --- Called by action in FileIndex edit box
635function FileIndex_Callback(hObject, eventdata, handles)
636%------------------------------------------------------------------------
637[tild,tild,tild,i1,i2,j1,j2]=fileparts_uvmat(get(handles.FileIndex,'String'));
638set(handles.i1,'String',num2str(i1));
639set(handles.i2,'String',num2str(i2));
640set(handles.j1,'String',num2str(j1));
641set(handles.j2,'String',num2str(j2));
642
643% refresh the current field view
644run0_Callback(hObject, eventdata, handles)
645
646%------------------------------------------------------------------------
647% --- Called by action in FileIndex_1 edit box
648function FileIndex_1_Callback(hObject, eventdata, handles)
649%------------------------------------------------------------------------
650run0_Callback(hObject, eventdata, handles)
651
652%------------------------------------------------------------------------
653% --- Called by action in NomType edit box
654function NomType_Callback(hObject, eventdata, handles)
655%------------------------------------------------------------------------
656i1=str2num(get(handles.i1,'String'));
657i2=str2num(get(handles.i2,'String'));
658j1=str2num(get(handles.j1,'String'));
659j2=str2num(get(handles.j2,'String'));
660FileIndex=fullfile_uvmat('','','','',get(handles.NomType,'String'),i1,i2,j1,j2);
661set(handles.FileIndex,'String',FileIndex)
662% refresh the current settings and refresh the field view
663RootPath_Callback(hObject,eventdata,handles)
664
665%------------------------------------------------------------------------
666% --- Called by action in NomType edit box
667function NomType_1_Callback(hObject, eventdata, handles)
668%------------------------------------------------------------------------
669i1=str2num(get(handles.i1,'String'));
670i2=str2num(get(handles.i2,'String'));
671j1=str2num(get(handles.j1,'String'));
672j2=str2num(get(handles.j2,'String'));
673FileIndex=fullfile_uvmat('','','','',get(handles.NomType_1,'String'),i1,i2,j1,j2);
674set(handles.FileIndex_1,'String',FileIndex)
675% refresh the current settings and refresh the field view
676RootPath_1_Callback(hObject,eventdata,handles)
677
[387]678%------------------------------------------------------------------------
679% --- Fills the edit boxes RootPath, RootFile,NomType...from an input file name 'fileinput'
[406]680function display_file_name(handles,fileinput,index)
[387]681%------------------------------------------------------------------------
682%% look for the input file existence
683if ~exist(fileinput,'file')
684    msgbox_uvmat('ERROR',['input file ' fileinput  ' does not exist'])
685    return
686end
687
688%% set the mouse pointer to 'watch'
689set(handles.uvmat,'Pointer','watch')
690set(handles.RootPath,'BackgroundColor',[1 1 0])
691drawnow
692
[406]693%% define the relevant handles for the first field series (index=1) or the second file series (index=2)
[387]694if ~exist('index','var')
695    index=1;
696end
697if index==1
698    handles_RootPath=handles.RootPath;
699    handles_SubDir=handles.SubDir;
700    handles_RootFile=handles.RootFile;
701    handles_FileIndex=handles.FileIndex;
702    handles_NomType=handles.NomType;
703    handles_FileExt=handles.FileExt;
704elseif index==2
705    handles_RootPath=handles.RootPath_1;
706    handles_SubDir=handles.SubDir_1;
707    handles_RootFile=handles.RootFile_1;
708    handles_FileIndex=handles.FileIndex_1;
709    handles_NomType=handles.NomType_1;
710    handles_FileExt=handles.FileExt_1;
711    set(handles.RootPath_1,'Visible','on')
712    set(handles.RootFile_1,'Visible','on')
713    set(handles.SubDir_1,'Visible','on');
714    set(handles.FileIndex_1,'Visible','on');
715    set(handles.FileExt_1,'Visible','on');
716    set(handles.NomType_1,'Visible','on');
717end
718
719%% detect root name, nomenclature and indices in the input file name:
[398]720[FilePath,FileName,FileExt]=fileparts(fileinput);
[387]721% detect the file type, get the movie object if relevant, and look for the corresponding file series:
[398]722% the root name and indices may be corrected by including the first index i1 if a corresponding xml file exists
723[RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,NomType,FileType,MovieObject,i1,i2,j1,j2]=find_file_series(FilePath,[FileName FileExt]);
[387]724
725%% open the file or fill the GUI uvmat according to the detected file type
726switch FileType
727    case ''
728        msgbox_uvmat('ERROR','invalid input file type')
729    case 'txt'
730        edit(fileinput)
731    case 'figure'                           %display matlab figure
732        hfig=open(fileinput);
733        set(hfig,'WindowButtonMotionFcn','mouse_motion')%set mouse action functio
734        set(hfig,'WindowButtonUpFcn','mouse_up')%set mouse click action function
735        set(hfig,'WindowButtonUpFcn','mouse_down')%set mouse click action function
736    case {'xml','xls'}                % edit xml or Excel files
737        editxml(fileinput);
738    otherwise
739        set(handles_RootPath,'String',RootPath);
740        rootname=fullfile(RootPath,SubDir,RootFile);
741        set(handles_SubDir,'String',['/' SubDir]);
742        set(handles_RootFile,'String',['/' RootFile]); %display the separator
743        indices=fileinput(length(rootname)+1:end);
744        indices(end-length(FileExt)+1:end)=[]; %remove extension
745        set(handles_FileIndex,'String',indices);
746        set(handles_NomType,'String',NomType);
747        set(handles_FileExt,'String',FileExt);
748        if index==1
749            % fill file index counters if the first file series is opened
750            set(handles.i1,'String',num2str(i1));
751            set(handles.i2,'String',num2str(i2));
752            set(handles.j1,'String',num2stra(j1,NomType));
753            set(handles.j2,'String',num2stra(j2,NomType));
754        else %read the current field index if the second file series is opened
755            i1=str2num(get(handles.i1,'String'));
756            i2=str2num(get(handles.i2,'String'));
757            j1=stra2num(get(handles.j1,'String'));
758            j2=stra2num(get(handles.j2,'String'));
759        end
760       
761        % synchronise indices of the second  input file if it exists
762        if get(handles.SubField,'Value')==1% if the subfield button is activated, update the field numbers
763            Input=read_GUI(handles.InputFile);
764            if ~isfield(Input,'RootPath_1')||strcmp(Input.RootPath_1,'"')
765                Input.RootPath_1=Input.RootPath;
766            end
767            if ~isfield(Input,'SubDir_1')||strcmp(Input.SubDir_1,'"')
768                Input.SubDir_1=Input.SubDir;
769            end
770            if ~isfield(Input,'RootFile_1')||strcmp(Input.RootFile_1,'"')
771                Input.RootFile_1=Input.RootFile;
772            end
[405]773            if ~isfield(Input,'FileExt_1')||strcmp(Input.FileExt_1,'"')
774                Input.FileExt_1=Input.FileExt;
775            end
776            if ~isfield(Input,'NomType_1')||strcmp(Input.NomType_1,'"')
777                Input.NomType_1=Input.NomType;
778            end
[387]779            %updtate the indices of the second field series to correspond to the newly opened one
780            FileName_1=fullfile_uvmat(Input.RootPath_1,Input.SubDir_1,Input.RootFile_1,Input.FileExt_1,Input.NomType_1,i1,i2,j1,j2);
781            if exist(FileName_1,'file')
782                FileIndex_1=fullfile_uvmat('','','','',Input.NomType_1,i1,i2,j1,j2);
783                set(handles.FileIndex_1,'String',FileIndex_1)
784            else
[408]785                msgbox_uvmat('WARNING','unable to synchronise the indices of the two series')
[387]786            end
787        end
788       
789        %enable other menus
790        set(handles.MenuOpen_1,'Enable','on')
791        set(handles.MenuFile_1_1,'Enable','on')
792        set(handles.MenuFile_2_1,'Enable','on')
793        set(handles.MenuFile_3_1,'Enable','on')
794        set(handles.MenuFile_4_1,'Enable','on')
795        set(handles.MenuFile_5_1,'Enable','on')
796        set(handles.MenuExport,'Enable','on')
797        set(handles.MenuExportFigure,'Enable','on')
798        set(handles.MenuExportMovie,'Enable','on')
799        set(handles.MenuTools,'Enable','on')
[424]800%         set(handles.OBJECT_txt,'Visible','on')
801%         set(handles.edit_object,'Visible','on')
802%          set(handles.ListObject_1,'Visible','on')
803%          set(handles.ViewObject,'Visible','on')
804%         set(handles.frame_object,'Visible','on')
[387]805       
806        % initiate input file series and refresh the current field view:     
807        update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,MovieObject,index);
808
809end
810
811%% set back the mouse pointer to arrow
812set(handles.uvmat,'Pointer','arrow')
813
814
815%------------------------------------------------------------------------
816% --- Update information about a new field series (indices to scan, timing,
817%     calibration from an xml file, then refresh current plots
[397]818function update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,VideoObject,index)
[387]819%------------------------------------------------------------------------
820%% define the relevant handles depending on the index (1=first file series, 2= second file series)
821if ~exist('index','var')
822    index=1;
823end
824if index==1
825    handles_RootPath=handles.RootPath;
826    handles_Fields=handles.Fields;
827elseif index==2
828    handles_RootPath=handles.RootPath_1;
829    handles_Fields=handles.Fields_1;
830end
831
832set(handles_RootPath,'BackgroundColor',[1 1 0])
833drawnow
834set(handles.Fields,'UserData',[])% reinialize data from uvmat opening
835UvData=get(handles.uvmat,'UserData');%huvmat=handles of the uvmat interface
836UvData.NewSeries=1; %flag for run0: begin a new series
837UvData.TestInputFile=1;
838UvData.FileType{index}=FileType;
839UvData.i1_series{index}=i1_series;
840UvData.i2_series{index}=i2_series;
841UvData.j1_series{index}=j1_series;
842UvData.j2_series{index}=j2_series;
843set(handles.FixVelType,'Value',0); %desactivate fixed veltype
844if index==1
845    [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
846else
847    [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes_1(handles);
848end
849FileName=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
850FileBase=fullfile(RootPath,RootFile);
851if ~exist(FileName,'file')
852   msgbox_uvmat('ERROR',['input file ' FileName ' not found']);
853    return
854end
[484]855% nbfield=[];%default
856% nbfield_j=[];%default
[387]857
858%% read timing and total frame number from the current file (movie files) !! may be overrid by xml file
859XmlData.Time=[];%default
860XmlData.GeometryCalib=[];%default
[494]861TimeUnit='';%default
862Time=[];
[387]863testima=0; %test for image input
864imainfo=[];
865ColorType='falsecolor'; %default
[397]866hhh=[];
867UvData.MovieObject{index}=VideoObject;
868if ~isempty(VideoObject)
869    imainfo=get(VideoObject);
[387]870    testima=1;
[484]871%     nbfield_j=1;
[387]872    TimeUnit='s';
[494]873    if isempty(j1_series); %frame index along i
874        Time=(0:1/imainfo.FrameRate:(imainfo.NumberOfFrames)/imainfo.FrameRate)';
875    else
876    Time=ones(size(i1_series,1),1)*(0:1/imainfo.FrameRate:(imainfo.NumberOfFrames)/imainfo.FrameRate);
877    end
[484]878    %nbfield=imainfo.NumberOfFrames;
[397]879    set(handles.Dt_txt,'String',['Dt=' num2str(1000/imainfo.FrameRate) 'ms']);%display the elementary time interval in millisec
880    ColorType='truecolor';
[387]881elseif ~isempty(FileExt(2:end))&&(~isempty(imformats(FileExt(2:end))) || isequal(FileExt,'.vol'))%&& isequal(NomType,'*')% multi-frame image
882    testima=1;
883    if ~isequal(SubDir,'')
[397]884        RootFile=get(handles.RootFile,'String');
[387]885        imainfo=imfinfo([fullfile(RootPath,SubDir,RootFile) FileIndices FileExt]);
886    else
887        imainfo=imfinfo([FileBase FileIndices FileExt]);
888    end
889    ColorType=imainfo.ColorType;%='truecolor' for color images
890    if length(imainfo) >1 %case of image with multiple frames
[484]891       % nbfield=length(imainfo);
892       % nbfield_j=1;
[397]893    end
[387]894end
895if isfield(imainfo,'Width') && isfield(imainfo,'Height')
896    if length(imainfo)>1
897        set(handles.num_Npx,'String',num2str(imainfo(1).Width));%fills nbre of pixels x box
898        set(handles.num_Npy,'String',num2str(imainfo(1).Height));%fills nbre of pixels x box
899    else
900        set(handles.num_Npx,'String',num2str(imainfo.Width));%fills nbre of pixels x box
901        set(handles.num_Npy,'String',num2str(imainfo.Height));%fills nbre of pixels x box
902    end
903else
904    set(handles.num_Npx,'String','');%fills nbre of pixels x box
905    set(handles.num_Npy,'String','');%fills nbre of pixels x box
906end
907set(handles.CheckBW,'Value',strcmp(ColorType,'grayscale'))% select handles.CheckBW if grayscale image
908
909%% read parameters (time, geometric calibration..) from a documentation file (.xml advised)
[469]910XmlFileName=find_imadoc(RootPath,SubDir,RootFile,FileExt);
911[tild,tild,DocExt]=fileparts(XmlFileName);
[387]912warntext='';%default warning message
913NbSlice=1;%default
914set(handles.RootPath,'BackgroundColor',[1 1 1])
[469]915if ~isempty(XmlFileName)
[387]916    set(handles.view_xml,'Visible','on')
917    set(handles.view_xml,'BackgroundColor',[1 1 0])
918    set(handles.view_xml,'String','view .xml')
919    drawnow
[469]920    [XmlDataRead,warntext]=imadoc2struct(XmlFileName);
[387]921    if ~isempty(warntext)
[456]922        msgbox_uvmat('WARNING',warntext)
[387]923    end
[456]924    if isempty(XmlDataRead)
925        set(handles.view_xml,'Visible','off')
926    else
927        set(handles.view_xml,'String',['view ' DocExt])   
928        XmlData=XmlDataRead;
929        if isfield(XmlData,'TimeUnit')
930            if isfield(XmlData,'TimeUnit')&& ~isempty(XmlData.TimeUnit)
931                TimeUnit=XmlData.TimeUnit;
932            end
[387]933        end
[456]934        set(handles.view_xml,'BackgroundColor',[1 1 1])
935        drawnow
936        if isfield(XmlData, 'GeometryCalib') && ~isempty(XmlData.GeometryCalib)
937            if isfield(XmlData.GeometryCalib,'VolumeScan') && isequal(XmlData.GeometryCalib.VolumeScan,'y')
938                set (handles.nb_slice,'String','volume')
939            end
940            hgeometry_calib=findobj('tag','geometry_calib');
941            if ~isempty(hgeometry_calib)
942                GUserData=get(hgeometry_calib,'UserData');
[469]943                if ~(isfield(GUserData,'XmlInputFile') && strcmp(GUserData.XmlInputFile,XmlFileName))
[456]944                    answer=msgbox_uvmat('INPUT_Y-N','replace the display of geometry_calib with the new input data?');
945                    if strcmp(answer,'Yes')
[469]946                        geometry_calib(XmlFileName);%diplay the new calibration points and parameters in geometry_calib
[456]947                    end
[387]948                end
949            end
950        end
[441]951    end
[387]952end
[494]953if ~(isfield(XmlData,'Time')&& ~isempty(XmlData.Time))
954    XmlData.Time=Time; %time set by video
955end
[387]956
957%% store last index in handles.lat_i and .last_j
958nbfield=max(max(i2_series));
959if isempty(nbfield)
960    nbfield=max(max(i1_series));
961end
962nbfield_j=max(max(j2_series));
963if isempty(nbfield_j)
964    nbfield_j=max(max(j1_series));
965end
966if ~isempty(XmlData.Time)
967    %transform .Time to a column vector if it is a line vector the nomenclature uses a single index
[441]968    if isequal(size(XmlData.Time,1),1)
[387]969        NomType=get(handles.NomType,'String');
[456]970        XmlData.Time=(XmlData.Time)';
[387]971    end
972end
973last_i_cell=get(handles.last_i,'String');
974if isempty(nbfield)
975    last_i_cell{1}='';
976else
977    last_i_cell{1}=num2str(nbfield);
978end
979set(handles.last_i,'String',last_i_cell)
980last_j_cell=get(handles.last_j,'String');
981if isempty(nbfield_j)
982     last_j_cell{1}='';
983else
984     last_j_cell{1}=num2str(nbfield_j);
985end
986set(handles.last_j,'String',last_j_cell);
987
988%% store geometric calibration in UvData
989if isfield(XmlData,'GeometryCalib')
990    GeometryCalib=XmlData.GeometryCalib;
991    if isempty(GeometryCalib)
992        set(handles.pxcm,'String','')
993        set(handles.pycm,'String','')
994        set(handles.transform_fct,'Value',1); %  no transform by default
995    else
996        if (isfield(GeometryCalib,'R')&& ~isequal(GeometryCalib.R(2,1),0) && ~isequal(GeometryCalib.R(1,2),0)) ||...
997            (isfield(GeometryCalib,'kappa1')&& ~isequal(GeometryCalib.kappa1,0))
998            set(handles.pxcm,'String','var')
999            set(handles.pycm,'String','var')
1000        elseif isfield(GeometryCalib,'fx_fy')
1001            pixcmx=GeometryCalib.fx_fy(1);%*GeometryCalib.R(1,1)*GeometryCalib.sx/(GeometryCalib.Tz*GeometryCalib.dpx);
1002            pixcmy=GeometryCalib.fx_fy(2);%*GeometryCalib.R(2,2)/(GeometryCalib.Tz*GeometryCalib.dpy);
1003            set(handles.pxcm,'String',num2str(pixcmx))
1004            set(handles.pycm,'String',num2str(pixcmy))
1005        end
1006        if ~get(handles.CheckFixLimits,'Value')
1007            set(handles.transform_fct,'Value',2); % phys transform by default if fixedLimits is off
1008        end
1009        if isfield(GeometryCalib,'SliceCoord')
1010           
1011           siz=size(GeometryCalib.SliceCoord);
1012           if siz(1)>1
1013               NbSlice=siz(1);
1014               set(handles.slices,'Visible','on')
1015               set(handles.slices,'Value',1)
1016           end
1017           if isfield(GeometryCalib,'VolumeScan') && isequal(GeometryCalib.VolumeScan,'y')
1018               set(handles.nb_slice,'String','volume')
1019           else
1020               set(handles.nb_slice,'String',num2str(NbSlice))
1021           end
1022           slices_Callback([],[], handles)
1023        end           
1024    end
1025end
1026
1027%% update the data attached to the uvmat interface
1028if ~isempty(TimeUnit)
1029    set(handles.time_txt,'String',['time (' TimeUnit ')'])
1030end
1031UvData.TimeUnit=TimeUnit;
1032UvData.XmlData{index}=XmlData;
1033UvData.NewSeries=1;
1034% UvData.MovieObject=MovieObject;
1035
1036%display warning message
1037if ~isequal(warntext,'')
1038    msgbox_uvmat('WARNING',warntext);
1039end
1040
1041%% set default options in menu 'Fields'
1042if ~testima
1043    testcivx=0;
1044    if isfield(UvData,'FieldsString') && isequal(UvData.FieldsString,{'get_field...'})% field menu defined as input (from get_field)
1045        set(handles_Fields,'Value',1)
1046        set(handles_Fields,'String',{'get_field...'})
1047        UvData=rmfield(UvData,'FieldsString');
1048    else
1049        Data=nc2struct(FileName,'ListGlobalAttribute','Conventions','absolut_time_T0','civ');
1050        if strcmp(Data.Conventions,'uvmat/civdata') ||( ~isempty(Data.absolut_time_T0)&& ~isequal(Data.civ,0))%if the new input is Civx
1051            FieldList=calc_field;
1052            set(handles_Fields,'String',[{'image'};FieldList;{'get_field...'}]);%standard menu for civx data
1053            set(handles_Fields,'Value',2) % set menu to 'velocity'
1054            col_vec=FieldList;
1055            col_vec(1)=[];%remove 'velocity' option for vector color (must be a scalar)
1056            testcivx=1;
1057        end
1058        if ~testcivx
1059            set(handles_Fields,'Value',1) % set menu to 'get_field...
1060            set(handles_Fields,'String',{'get_field...'})
1061            col_vec={'get_field...'};
1062        end
[405]1063        set(handles.ColorScalar,'String',col_vec)
[387]1064    end
1065end
1066set(handles.uvmat,'UserData',UvData)
1067
1068%% set index navigation options and refresh plots
1069scan_option='i';%default
1070state_j='off'; %default
1071if index==2
1072    if get(handles.scan_j,'Value')
[494]1073        scan_option='j'; %keep the scan option for the second file series
[387]1074    end
1075    if strcmp(get(handles.j1,'Visible'),'on')
1076        state_j='on';
1077    end
1078end
[494]1079[ref_i,ref_j]=find(i1_series);
[387]1080if ~isempty(j1_series)
1081        state_j='on';
[494]1082        if index==1
1083            if isequal(ref_i,ref_i(1)*ones(size(ref_j)))% if ref_i is always equal to its first vzlue
1084                scan_option='j'; %scan j indext               
1085            end
1086        end
[387]1087end
1088if isequal(scan_option,'i')
[494]1089    diff_ref_i=diff(ref_i,1);
1090    if isempty(diff_ref_i)
1091        diff_ref_i=1;
1092    end
1093    if isequal (diff_ref_i,diff_ref_i(1)*ones(size(diff_ref_i)))
1094        set(handles.increment_scan,'String',num2str(diff_ref_i(1)))
1095    end
[387]1096     set(handles.scan_i,'Value',1)
1097     scan_i_Callback([],[], handles);
1098else
[494]1099    diff_ref_j=diff(ref_j);
1100    if isempty(diff_ref_j)
1101        diff_ref_j=1;
1102    end
1103    if isequal (diff_ref_j,diff_ref_j(1)*ones(size(diff_ref_j)))
1104        set(handles.increment_scan,'String',num2str(diff_ref_j(1)))
1105    end
[387]1106     set(handles.scan_j,'Value',1)
1107     scan_j_Callback([],[], handles);
1108end
1109set(handles.scan_j,'Visible',state_j)
1110set(handles.j1,'Visible',state_j)
1111set(handles.j2,'Visible',state_j)
1112set(handles.last_j,'Visible',state_j);
1113set(handles.frame_j,'Visible',state_j);
1114set(handles.j_text,'Visible',state_j);
1115if ~isempty(i2_series)||~isempty(j2_series)
1116    set(handles.CheckFixPair,'Visible','on')
1117elseif index==1
1118    set(handles.CheckFixPair,'Visible','off')
1119end
1120
1121%% view the field 
1122run0_Callback([],[], handles); %view field
1123mask_test=get(handles.CheckMask,'value');
1124if mask_test
1125    MaskData=get(handles.CheckMask,'UserData');
1126    if isfield(MaskData,'maskhandle') && ishandle(MaskData.maskhandle)
1127          delete(MaskData.maskhandle)    %delete old mask
1128    end
1129    CheckMask_Callback([],[],handles)
1130end
1131
[406]1132%% update list of recent files in the menubar and save it for future opening
[387]1133MenuFile=[{get(handles.MenuFile_1,'Label')};{get(handles.MenuFile_2,'Label')};...
1134    {get(handles.MenuFile_3,'Label')};{get(handles.MenuFile_4,'Label')};{get(handles.MenuFile_5,'Label')}];
1135str_find=strcmp(FileName,MenuFile);
1136if isempty(find(str_find,1))
1137    MenuFile=[{FileName};MenuFile];%insert the current file if not already in the list
1138end
1139for ifile=1:min(length(MenuFile),5)
1140    eval(['set(handles.MenuFile_' num2str(ifile) ',''Label'',MenuFile{ifile});'])
1141    eval(['set(handles.MenuFile_' num2str(ifile) '_1,''Label'',MenuFile{ifile});'])
1142end
1143dir_perso=prefdir;
1144profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
1145if exist(profil_perso,'file')
1146    save (profil_perso,'MenuFile','-append'); %store the file names for future opening of uvmat
1147else
1148    save (profil_perso,'MenuFile','-V6'); %store the file names for future opening of uvmat
1149end
1150
1151
1152%------------------------------------------------------------------------
1153% --- switch file index scanning options scan_i and scan_j in an exclusive way
1154function scan_i_Callback(hObject, eventdata, handles)
1155%------------------------------------------------------------------------
1156if get(handles.scan_i,'Value')==1
1157    set(handles.scan_i,'BackgroundColor',[1 1 0])
1158    set(handles.scan_j,'Value',0)
1159else
1160    set(handles.scan_i,'BackgroundColor',[0.831 0.816 0.784])
1161    set(handles.scan_j,'Value',1)
1162end
1163scan_j_Callback(hObject, eventdata, handles)
1164
1165%------------------------------------------------------------------------
1166% --- switch file index scanning options scan_i and scan_j in an exclusive way
1167function scan_j_Callback(hObject, eventdata, handles)
1168%------------------------------------------------------------------------
1169if get(handles.scan_j,'Value')==1
1170    set(handles.scan_j,'BackgroundColor',[1 1 0])
1171    set(handles.scan_i,'Value',0)
1172    set(handles.scan_i,'BackgroundColor',[0.831 0.816 0.784])
1173%     NomType=get(handles.NomType,'String');
1174%     switch NomType
1175%     case {'_1_1-2','#_ab','%3dab'},% pair with j index
1176%         set(handles.CheckFixPair,'Visible','on')% option fixed pair on/off made visible (choice of avaible pair with buttons + and - if ='off')
1177%     otherwise
1178%         set(handles.CheckFixPair,'Visible','off')
1179%     end
1180else
1181    set(handles.scan_j,'BackgroundColor',[0.831 0.816 0.784])
1182    set(handles.scan_i,'Value',1)
1183    set(handles.scan_i,'BackgroundColor',[1 1 0])
1184    set(handles.CheckFixPair,'Visible','off')
1185end
1186
1187%------------------------------------------------------------------------
1188function i1_Callback(hObject, eventdata, handles)
1189%------------------------------------------------------------------------
1190set(handles.i1,'BackgroundColor',[0.7 0.7 0.7])
1191NomType=get(handles.NomType,'String');
1192i1=stra2num(get(handles.i1,'String'));
1193i2=stra2num(get(handles.i2,'String'));
1194j1=stra2num(get(handles.j1,'String'));
1195j2=stra2num(get(handles.j2,'String'));
1196indices=fullfile_uvmat('','','','',NomType,i1,i2,j1,j2);
1197%indices=name_generator('',num1,num_a,'',NomType,1,num2,num_b,'');
1198set(handles.FileIndex,'String',indices)
1199set(handles.FileIndex,'BackgroundColor',[0.7 0.7 0.7])
1200if get(handles.SubField,'Value')==1
1201    NomType_1=get(handles.NomType_1,'String');
1202    indices=fullfile_uvmat('','','','',NomType,i1,i2,j1,j2);
1203     %indices=name_generator('',num1,num_a,'',NomType_1,1,num2,num_b,'');
1204     set(handles.FileIndex_1,'String',indices)
1205     set(handles.FileIndex_1,'BackgroundColor',[0.7 0.7 0.7])
1206end
1207
1208%------------------------------------------------------------------------
1209function i2_Callback(hObject, eventdata, handles)
1210%------------------------------------------------------------------------
1211set(handles.i2,'BackgroundColor',[0.7 0.7 0.7])
1212i1_Callback(hObject, eventdata, handles)
1213
1214%------------------------------------------------------------------------
1215function j1_Callback(hObject, eventdata, handles)
1216%------------------------------------------------------------------------
1217set(handles.j1,'BackgroundColor',[0.7 0.7 0.7])
1218i1_Callback(hObject, eventdata, handles)
1219
1220%------------------------------------------------------------------------
1221function j2_Callback(hObject, eventdata, handles)
1222%------------------------------------------------------------------------
1223set(handles.j2,'BackgroundColor',[0.7 0.7 0.7])
1224i1_Callback(hObject, eventdata, handles)
1225
1226%------------------------------------------------------------------------
1227function slices_Callback(hObject, eventdata, handles)
1228%------------------------------------------------------------------------
1229if get(handles.slices,'Value')==1
1230    set(handles.slices,'BackgroundColor',[1 1 0])
1231    set(handles.nb_slice,'Visible','on')
1232    set(handles.z_text,'Visible','on')
1233    set(handles.z_index,'Visible','on')
1234    nb_slice_Callback(hObject, eventdata, handles)
1235else
1236    set(handles.nb_slice,'Visible','off')
1237    set(handles.slices,'BackgroundColor',[0.7 0.7 0.7])
1238    set(handles.z_text,'Visible','off')
1239    set(handles.z_index,'Visible','off')
1240    set(handles.masklevel,'Value',1)
1241    set(handles.masklevel,'String',{'1'})
1242end
1243
1244%------------------------------------------------------------------------
1245function nb_slice_Callback(hObject, eventdata, handles)
1246%------------------------------------------------------------------------
1247nb_slice_str=get(handles.nb_slice,'String');
1248if isequal(nb_slice_str,'volume')
1249    num=stra2num(get(handles.j1,'String'));
1250    last_j=get(handles.last_j,'String');
1251    nbslice=str2double(last_j{1});
1252else
1253    num=str2double(get(handles.i1,'String'));
1254    nbslice=str2double(get(handles.nb_slice,'String'));
1255end
1256z=mod(num-1,nbslice)+1;
1257set(handles.z_index,'String',num2str(z))
1258for ilist=1:nbslice
1259    list_index{ilist,1}=num2str(ilist);
1260end   
1261set(handles.masklevel,'String',list_index)
1262set(handles.masklevel,'Value',z)
1263
1264%------------------------------------------------------------------------
1265% --- Executes on button press in view_xml.
1266function view_xml_Callback(hObject, eventdata, handles)
1267%------------------------------------------------------------------------
1268%[FileName,RootPath,FileBase,FileIndices,FileExt]=read_file_boxes(handles);
1269 [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
1270FileBase=fullfile(RootPath,RootFile);
1271option=get(handles.view_xml,'String');
1272if isequal(option,'view .xml')
[494]1273    FileXml=fullfile(RootPath,[SubDir '.xml']);
1274    if ~exist(FileXml,'file')% case of civ files , removes the extension for subdir
1275        FileXml=fullfile(RootPath,[regexprep(SubDir,'\..+$','') '.xml']);
1276    end
[387]1277    heditxml=editxml(FileXml);
1278end
1279
1280%------------------------------------------------------------------------
1281% --- Executes on button press in CheckMask.
1282function CheckMask_Callback(hObject, eventdata, handles)
1283%------------------------------------------------------------------------
1284%case of view mask selection
1285if isequal(get(handles.CheckMask,'Value'),1)
1286     [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
1287     FileBase=fullfile(RootPath,RootFile);
1288    num_i1=stra2num(get(handles.i1,'String'));
1289    num_j1=stra2num(get(handles.j1,'String'));
1290    currentdir=pwd; 
1291    cd(RootPath);
1292    maskfiles=dir('*_*mask_*.png');%look for a mask file
1293    cd(currentdir);%come back to the working directory
1294    mdetect=0;
1295    if ~isempty(maskfiles)
1296        for ilist=1:length(maskfiles)
1297            maskname=maskfiles(ilist).name;% take the first mask file in the list
1298            [tild,tild,tild,tild,tild,tild,tild,MaskExt,Mask_NomType{ilist}]=fileparts_uvmat(maskname);
1299             [tild,Name]=fileparts(maskname);
1300            Namedouble=double(Name);
1301            val=(48>Namedouble)|(Namedouble>57);% select the non-numerical characters
1302            ind_mask=findstr('mask',Name);
1303            i=ind_mask-1;
1304            while val(i)==0 && i>0
1305                i=i-1;
1306            end
1307            nbmask_str=str2num(Name(i+1:ind_mask-1));
1308            if ~isempty(nbmask_str)
1309                nbslice(ilist)=nbmask_str; % number of different masks (slices)
1310            end
1311        end
1312        if isequal(min(nbslice),max(nbslice))
1313            nbslice=nbslice(1);
1314        else
1315            msgbox_uvmat('ERROR','several inconsistent mask sets coexist in the current image directory')
1316            return
1317        end
1318        if ~isempty(nbslice) && Name(i)=='_'
1319            Mask.Base=[FileBase Name(i:ind_mask+3)];
1320            Mask.NbSlice=nbslice;
1321            num_i1=mod(num_i1-1,nbslice)+1;
1322            Mask.NomType=regexprep(Mask_NomType{1},'0','');%remove '0' in nom type for masks
1323            [RootPath,RootFile]=fileparts(Mask.Base);
1324            maskname=fullfile_uvmat(RootPath,'',RootFile,'.png',Mask.NomType,num_i1,[],num_j1);
1325            %maskname=name_generator(Mask.Base,num_i1,num_j1,'.png',Mask.NomType);%
1326            mdetect=exist(maskname,'file');
1327            if mdetect
1328                set(handles.nb_slice,'String',Name(i+1:ind_mask-1));
1329                set(handles.nb_slice,'BackgroundColor',[1 1 0])
1330                set(handles.CheckMask,'UserData',Mask);
1331                set(handles.CheckMask,'BackgroundColor',[1 1 0])
1332                if nbslice > 1
1333                    set(handles.slices,'value',1)
1334                    slices_Callback(hObject, eventdata, handles)
1335                end
1336            end
1337        end
1338    end
1339    errormsg=[];%default
1340    if mdetect==0
1341        [FileName, PathName, filterindex] = uigetfile( ...
1342            {'*.png', ' (*.png)';
1343            '*.png',  '.png files '; ...
1344            '*.*', 'All Files (*.*)'}, ...
1345            'Pick a mask file *.png',FileBase);
1346        maskname=fullfile(PathName,FileName);
1347        if ~exist(maskname,'file')
1348            errormsg='no file browsed';
1349        end
[444]1350        [RootDir,SubDir,RootFile,tild,tild,tild,tild,tild,Mask.NomType]=fileparts_uvmat(maskname);
1351        Mask.Base=fullfile(RootDir,SubDir,RootFile);
[387]1352        Mask.NbSlice=1;
1353        set(handles.CheckMask,'UserData',Mask);
1354        set(handles.CheckMask,'BackgroundColor',[1 1 0])
1355    end
1356    if isempty(errormsg)
1357        errormsg=update_mask(handles,num_i1,num_j1);
1358    end
1359    if ~isempty(errormsg)
1360            set(handles.CheckMask,'Value',0)
1361            set(handles.CheckMask,'BackgroundColor',[0.7 0.7 0.7])
1362     end
1363else % desactivate mask display
1364    MaskData=get(handles.CheckMask,'UserData');
1365    if isfield(MaskData,'maskhandle') && ishandle(MaskData.maskhandle)
1366          delete(MaskData.maskhandle)   
1367    end
1368    set(handles.CheckMask,'UserData',[])   
1369    UvData=get(handles.uvmat,'UserData');
1370    if isfield(UvData,'MaskName')
1371        UvData=rmfield(UvData,'MaskName');
1372        set(handles.uvmat,'UserData',UvData)
1373    end
1374    set(handles.CheckMask,'BackgroundColor',[0.7 0.7 0.7])
1375end
1376
1377%------------------------------------------------------------------------
1378function errormsg=update_mask(handles,num_i1,num_j1)
1379%------------------------------------------------------------------------
1380errormsg=[];%default
1381MaskData=get(handles.CheckMask,'UserData');
1382if isfield(MaskData,'maskhandle')&& ishandle(MaskData.maskhandle)
1383    uistack(MaskData.maskhandle,'top');
1384end
1385num_i1_mask=mod(num_i1-1,MaskData.NbSlice)+1;
1386[RootPath,RootFile]=fileparts(MaskData.Base);
1387MaskName=fullfile_uvmat(RootPath,'',RootFile,'.png',MaskData.NomType,num_i1_mask,[],num_j1);
1388UvData=get(handles.uvmat,'UserData');
1389%update mask image if the mask is new
1390if ~ (isfield(UvData,'MaskName') && isequal(UvData.MaskName,MaskName))
1391    UvData.MaskName=MaskName; %update the recorded name on UvData
1392    set(handles.uvmat,'UserData',UvData);
1393    if ~exist(MaskName,'file')
1394        if isfield(MaskData,'maskhandle')&& ishandle(MaskData.maskhandle)
1395            delete(MaskData.maskhandle)   
1396        end
1397    else
1398        %read mask image
1399        Mask.AName='image';
1400        Mask.A=imread(MaskName);
1401        npxy=size(Mask.A);
1402        test_error=0;
1403        if length(npxy)>2
1404            errormsg=[MaskName ' is not a grey scale image'];
1405            return
1406        elseif ~isa(Mask.A,'uint8')
1407            errormsg=[MaskName ' is not a 8 bit grey level image'];
1408            return
1409        end
1410        Mask.AX=[0.5 npxy(2)-0.5];
1411        Mask.AY=[npxy(1)-0.5 0.5 ];
1412        Mask.CoordUnit='pixel';
1413        if isequal(get(handles.slices,'Value'),1)
1414           NbSlice=str2num(get(handles.nb_slice,'String'));
1415           num_i1=str2num(get(handles.i1,'String'));
1416           Mask.ZIndex=mod(num_i1-1,NbSlice)+1;
1417        end
1418        %px to phys or other transform on field
1419         menu_transform=get(handles.transform_fct,'String');
1420        choice_value=get(handles.transform_fct,'Value');
1421        transform_name=menu_transform{choice_value};%name of the transform fct  given by the menu 'transform_fct'
1422        transform_list=get(handles.transform_fct,'UserData');
1423        transform=transform_list{choice_value};
1424        if  ~isequal(transform_name,'') && ~isequal(transform_name,'px')
1425            if isfield(UvData,'XmlData') && isfield(UvData.XmlData{1},'GeometryCalib')%use geometry calib recorded from the ImaDoc xml file as first priority
1426                Calib=UvData.XmlData{1}.GeometryCalib;
1427                Mask=transform(Mask,UvData.XmlData{1});
1428            end
1429        end
1430        flagmask=Mask.A < 200;
1431       
1432        %make brown color image
1433        imflag(:,:,1)=0.9*flagmask;
1434        imflag(:,:,2)=0.7*flagmask;
1435        imflag(:,:,3)=zeros(size(flagmask));
1436       
1437        %update mask image
1438        hmask=[]; %default
1439        if isfield(MaskData,'maskhandle')&& ishandle(MaskData.maskhandle)
1440            hmask=MaskData.maskhandle;
1441        end
1442        if ~isempty(hmask)
1443            set(hmask,'CData',imflag)   
1444            set(hmask,'AlphaData',flagmask*0.6)
1445            set(hmask,'XData',Mask.AX);
1446            set(hmask,'YData',Mask.AY);
1447%             uistack(hmask,'top')
1448        else
1449            axes(handles.axes3)
1450            hold on   
[452]1451            size(flagmask)
1452           % MaskData.maskhandle=image(Mask.AX,Mask.AY,imflag,'Tag','mask','HitTest','off','AlphaData',0.6*flagmask);
1453            MaskData.maskhandle=image(Mask.AX,Mask.AY,imflag,'Tag','mask','HitTest','off','AlphaData',0.6*ones(size(flagmask)));
[387]1454%             set(MaskData.maskhandle,'AlphaData',0.6*flagmask)
1455            set(handles.CheckMask,'UserData',MaskData)
1456        end
1457    end
1458end
1459
1460%------------------------------------------------------------------------
1461%------------------------------------------------------------------------
1462% III - MAIN REFRESH FUNCTIONS : 'FRAME PLOT'
1463%------------------------------------------------------------------------
1464
1465%------------------------------------------------------------------------
1466% --- Executes on button press in runplus: make one step forward and call
1467% --- run0. The step forward is along the fields series 1 or 2 depending on
1468% --- the scan_i and scan_j check box (exclusive each other)
1469function runplus_Callback(hObject, eventdata, handles)
1470%------------------------------------------------------------------------
1471set(handles.runplus,'BackgroundColor',[1 1 0])%paint the command button in yellow
1472drawnow
1473%TODO: introduce the option: increment ='*' to move to the next available view
1474increment=str2num(get(handles.increment_scan,'String')); %get the field increment d
1475% if isnan(increment)
1476%     set(handles.increment_scan,'String','1')%default value
1477%     increment=1;
1478% end
1479errormsg=runpm(hObject,eventdata,handles,increment);
1480if ~isempty(errormsg)
1481    msgbox_uvmat('ERROR',errormsg);
1482end
1483set(handles.runplus,'BackgroundColor',[1 0 0])%paint the command button back to red
1484
1485%------------------------------------------------------------------------
1486% --- Executes on button press in runmin: make one step backward and call
1487% --- run0. The step backward is along the fields series 1 or 2 depending on
1488% --- the scan_i and scan_j check box (exclusive each other)
1489function runmin_Callback(hObject, eventdata, handles)
1490%------------------------------------------------------------------------
1491set(handles.runmin,'BackgroundColor',[1 1 0])%paint the command button in yellow
1492drawnow
1493increment=-str2num(get(handles.increment_scan,'String')); %get the field increment d
1494% if isnan(increment)
1495%     set(handles.increment_scan,'String','1')%default value
1496%     increment=1;
1497% end
1498errormsg=runpm(hObject,eventdata,handles,increment);
1499if ~isempty(errormsg)
1500    msgbox_uvmat('ERROR',errormsg);
1501end
1502set(handles.runmin,'BackgroundColor',[1 0 0])%paint the command button back to red
1503
1504%------------------------------------------------------------------------
1505% -- Executes on button press in Movie: make a series of +> steps
1506function Movie_Callback(hObject, eventdata, handles)
1507%------------------------------------------------------------------------
1508set(handles.Movie,'BackgroundColor',[1 1 0])%paint the command button in yellow
1509drawnow
1510increment=str2num(get(handles.increment_scan,'String')); %get the field increment d
1511% if isnan(increment)
1512%     set(handles.increment_scan,'String','1')%default value
1513%     increment=1;
1514% end
1515set(handles.STOP,'Visible','on')
1516set(handles.speed,'Visible','on')
1517set(handles.speed_txt,'Visible','on')
1518set(handles.Movie,'BusyAction','queue')
1519UvData=get(handles.uvmat,'UserData');
1520
[435]1521while get(handles.Movie,'Value')==1 && get(handles.speed,'Value')~=0 && isequal(get(handles.Movie,'BusyAction'),'queue') % enable STOP command
[387]1522        errormsg=runpm(hObject,eventdata,handles,increment);
1523        if ~isempty(errormsg)
1524            set(handles.Movie,'BackgroundColor',[1 0 0])%paint the command buttonback to red
1525            return
1526        end
1527        pause(1.02-get(handles.speed,'Value'))% wait for next image
1528end
1529if isfield(UvData,'aviobj') && ~isempty( UvData.aviobj),
1530    UvData.aviobj=close(UvData.aviobj);
1531   set(handles.uvmat,'UserData',UvData);
1532end
1533set(handles.Movie,'BackgroundColor',[1 0 0])%paint the command buttonback to red
1534
1535%------------------------------------------------------------------------
1536% -- Executes on button press in Movie: make a series of <- steps
1537function MovieBackward_Callback(hObject, eventdata, handles)
1538%------------------------------------------------------------------------
1539set(handles.MovieBackward,'BackgroundColor',[1 1 0])%paint the command button in yellow
1540drawnow
1541increment=-str2num(get(handles.increment_scan,'String')); %get the field increment d
1542set(handles.STOP,'Visible','on')
1543set(handles.speed,'Visible','on')
1544set(handles.speed_txt,'Visible','on')
1545set(handles.MovieBackward,'BusyAction','queue')
1546UvData=get(handles.uvmat,'UserData');
1547
[435]1548while get(handles.MovieBackward,'Value')==1 && get(handles.speed,'Value')~=0 && isequal(get(handles.MovieBackward,'BusyAction'),'queue') % enable STOP command
[387]1549        errormsg=runpm(hObject,eventdata,handles,increment);
1550        if ~isempty(errormsg)
1551            set(handles.MovieBackward,'BackgroundColor',[1 0 0])%paint the command buttonback to red
1552            return
1553        end
1554        pause(1.02-get(handles.speed,'Value'))% wait for next image
1555end
1556if isfield(UvData,'aviobj') && ~isempty( UvData.aviobj),
1557    UvData.aviobj=close(UvData.aviobj);
1558   set(handles.uvmat,'UserData',UvData);
1559end
1560set(handles.MovieBackward,'BackgroundColor',[1 0 0])%paint the command buttonback to red
1561
1562%------------------------------------------------------------------------
1563function STOP_Callback(hObject, eventdata, handles)
1564%------------------------------------------------------------------------
1565set(handles.movie_pair,'BusyAction','Cancel')
1566set(handles.movie_pair,'value',0)
1567set(handles.Movie,'BusyAction','Cancel')
1568set(handles.MovieBackward,'BusyAction','Cancel')
1569set(handles.MenuExportMovie,'BusyAction','Cancel')
1570set(handles.movie_pair,'BackgroundColor',[1 0 0])%paint the command buttonback to red
1571set(handles.Movie,'BackgroundColor',[1 0 0])%paint the command buttonback to red
1572set(handles.MovieBackward,'BackgroundColor',[1 0 0])%paint the command buttonback to red
1573
1574%------------------------------------------------------------------------
1575% --- function activated by runplus and run minus
1576function errormsg=runpm(hObject,eventdata,handles,increment)
1577%------------------------------------------------------------------------
1578errormsg='';%default
1579%% check for movie pair status
1580movie_status=get(handles.movie_pair,'Value');
1581if isequal(movie_status,1)
1582    STOP_Callback(hObject, eventdata, handles)%interrupt movie pair if active
1583end
1584
1585%% read the current input file name(s) and field indices
1586InputFile=read_GUI(handles.InputFile);
1587InputFile.RootFile=regexprep(InputFile.RootFile,'^[\\/]|[\\/]$','');%suppress possible / or \ separator at the beginning or the end of the string
1588InputFile.SubDir=regexprep(InputFile.SubDir,'^[\\/]|[\\/]$','');%suppress possible / or \ separator at the beginning or the end of the string
1589FileExt=InputFile.FileExt;
1590NomType=get(handles.NomType,'String');
1591i1=str2num(get(handles.i1,'String'));%read the field indices (for movie, it is not given by the file name)
1592i2=[];%default
1593if strcmp(get(handles.i2,'Visible'),'on')
1594    i2=str2num(get(handles.i2,'String'));
1595end
1596j1=[];
1597if strcmp(get(handles.j1,'Visible'),'on')
1598    j1=stra2num(get(handles.j1,'String'));
1599end
1600j2=j1;
1601if strcmp(get(handles.j2,'Visible'),'on')
1602    j2=stra2num(get(handles.j2,'String'));
1603end
1604sub_value= get(handles.SubField,'Value');
1605if sub_value % a second input file has been entered
[428]1606     [InputFile.RootPath_1,InputFile.SubDir_1,InputFile.RootFile_1,InputFile.FileIndex_1,InputFile.FileExt_1,InputFile.NomType_1]=read_file_boxes_1(handles);   
1607    [tild,tild,tild,i1_1,i2_1,j1_1,j2_1]=fileparts_uvmat(InputFile.FileIndex_1);
1608%     InputFile.NomType_1=get(handles.NomType_1,'String');
[387]1609else
1610    filename_1=[];
1611end   
1612
1613%% increment (or decrement) the field indices and update the input filename(s)
1614CheckSearch=0;
1615if isempty(increment)
1616    CheckSearch=1;% search for the next available file
1617    set(handles.CheckFixPair,'Value',0)
1618end
1619CheckFixPair=get(handles.CheckFixPair,'Value')||(isempty(i2)&&isempty(j2));
[427]1620
1621% the pair i1-i2 or j1-j2 is imposed (check box CheckFixPair selected)
[387]1622if CheckFixPair
1623    if get(handles.scan_i,'Value')==1% case of scanning along index i
1624        i1=i1+increment;
1625        i2=i2+increment;
1626        if sub_value
1627            i1_1=i1_1+increment;
1628            i2_1=i2_1+increment;
1629        end
1630    else % case of scanning along index j (burst numbers)
1631        j1=j1+increment;
1632        j2=j2+increment;
1633        if sub_value
1634            j1_1=j1_1+increment;
1635            j2_1=j2_1+increment;
1636        end
1637    end
[427]1638   
1639% the pair i1-i2 or j1-j2 is free (check box CheckFixPair not selected):
1640% the list of existing indices recorded in UvData is used
[387]1641else
1642    UvData=get(handles.uvmat,'UserData');
1643    ref_i=i1;
1644    if ~isempty(i2)
[427]1645        ref_i=floor((i1+i2)/2);% current reference index i
[387]1646    end
1647    ref_j=1;
1648    if ~isempty(j1)
1649        ref_j=j1;
1650        if ~isempty(j2)
[427]1651            ref_j=floor((j1+j2)/2);% current reference index j
[387]1652        end
1653    end
1654    if ~isempty(increment)
1655        if get(handles.scan_i,'Value')==1% case of scanning along index i
[427]1656            ref_i=ref_i+increment;% increment the current reference index i
[387]1657        else % case of scanning along index j (burst numbers)
[427]1658            ref_j=ref_j+increment;% increment the current reference index j if scan_j option is used
[387]1659        end
[388]1660    else % free increment
[387]1661        if isequal(get(handles.runplus,'BackgroundColor'),[1 1 0])% if runplus is activated
1662            step=1;
1663        else
1664            step=-1;
1665        end
1666        if get(handles.scan_i,'Value')==1% case of scanning along index i
1667            ref_i=ref_i+step;
1668            while ref_i>=0  && size(UvData.i1_series{1},1)>=ref_i+1 && UvData.i1_series{1}(ref_i+1,ref_j+1,1)==0
1669                ref_i=ref_i+step;
1670            end
1671        else % case of scanning along index j (burst numbers)
1672            ref_j=ref_j+step;
1673            while ref_j>=0  && size(UvData.i1_series{1},2)>=ref_j+1 && UvData.i1_series{1}(ref_i+1,ref_j+1,1)==0
1674                ref_j=ref_j+step;
1675            end
1676        end
1677    end
1678    if ref_i<0
1679        errormsg='minimum i index reached';
1680    elseif ref_j<0
1681        errormsg='minimum j index reached';
1682    elseif ref_i+1>size(UvData.i1_series{1},1)
1683        errormsg='maximum i index reached';
1684    elseif ref_j+1>size(UvData.i1_series{1},2)
1685        errormsg='maximum j index reached';
1686    end
1687    if ~isempty(errormsg)
1688        return
1689    end
[427]1690    i1_subseries=UvData.i1_series{1}(ref_i+1,ref_j+1,:);
[387]1691    i1_subseries=i1_subseries(i1_subseries>0);
1692    if isempty(i1_subseries)
1693        errormsg='no next file';
1694        return
[427]1695    else
1696        i1=i1_subseries(end);
[387]1697    end
1698    if ~isempty(UvData.i2_series{1})
[427]1699        i2_subseries=UvData.i2_series{1}(ref_i+1,ref_j+1,:);
[387]1700        i2_subseries=i2_subseries(i2_subseries>0);
1701        i2=i2_subseries(end);
1702    end
1703    if ~isempty(UvData.j1_series{1})
[427]1704        j1_subseries=UvData.j1_series{1}(ref_i+1,ref_j+1,:);
[387]1705        j1_subseries=j1_subseries(j1_subseries>0);
1706        j1=j1_subseries(end);
1707    end
1708    if ~isempty(UvData.j2_series{1})
[427]1709        j2_subseries=UvData.j2_series{1}(ref_i+1,ref_j+1,:);
[387]1710        j2_subseries=j2_subseries(j2_subseries>0);
1711        j2=j2_subseries(end);
[427]1712    end 
1713    % case of a second file series
1714    if numel(UvData.i1_series)>=2
1715        i1_subseries=UvData.i1_series{2}(ref_i+1,ref_j+1,:);
1716        i1_subseries=i1_subseries(i1_subseries>0);
1717        i1_1=i1_subseries(end);
1718        if ~isempty(UvData.i2_series{2})
1719            i2_subseries=UvData.i2_series{2}(ref_i+1,ref_j+1,:);
1720            i2_subseries=i2_subseries(i2_subseries>0);
1721            i2_1=i2_subseries(end);
1722        end
1723        if ~isempty(UvData.j1_series{2})
1724            j1_subseries=UvData.j1_series{2}(ref_i+1,ref_j+1,:);
1725            j1_subseries=j1_subseries(j1_subseries>0);
1726            j1_1=j1_subseries(end);
1727        end
1728        if ~isempty(UvData.j2_series{2})
1729            j2_subseries=UvData.j2_series{2}(ref_i+1,ref_j+1,:);
1730            j2_subseries=j2_subseries(j2_subseries>0);
1731            j2_1=j2_subseries(end);
1732        end
[387]1733    end
1734end
1735filename=fullfile_uvmat(InputFile.RootPath,InputFile.SubDir,InputFile.RootFile,FileExt,NomType,i1,i2,j1,j2);
1736if sub_value
[428]1737    filename_1=fullfile_uvmat(InputFile.RootPath_1,InputFile.SubDir_1,InputFile.RootFile_1,InputFile.FileExt_1,InputFile.NomType_1,i1_1,i2_1,j1_1,j2_1);
[387]1738end
1739
1740%% refresh plots
1741errormsg=refresh_field(handles,filename,filename_1,i1,i2,j1,j2);
1742
1743%% update the index counters if the index move is successfull
1744if isempty(errormsg)
1745    set(handles.i1,'String',num2stra(i1,NomType,1));
1746    if isequal(i2,i1)
1747        set(handles.i2,'String','');
1748    else
1749        set(handles.i2,'String',num2stra(i2,NomType,1));
1750    end
1751    set(handles.j1,'String',num2stra(j1,NomType,2));
1752    if isequal(j2,j1)
1753        set(handles.j2,'String','');
1754    else
1755        set(handles.j2,'String',num2stra(j2,NomType,2));
1756    end
1757    indices=fullfile_uvmat('','','','',NomType,i1,i2,j1,j2);
1758    set(handles.FileIndex,'String',indices);
1759    if ~isempty(filename_1)
[428]1760        indices_1=fullfile_uvmat('','','','',InputFile.NomType_1,i1_1,i2_1,j1_1,j2_1);
[387]1761        set(handles.FileIndex_1,'String',indices_1);
1762    end
1763    if isequal(movie_status,1)
1764        set(handles.movie_pair,'Value',1)
1765        movie_pair_Callback(hObject, eventdata, handles); %reactivate moviepair if it was activated
1766    end
1767end
1768
1769%------------------------------------------------------------------------
1770% --- Executes on button press in movie_pair: create an alternating movie with two view
1771function movie_pair_Callback(hObject, eventdata, handles)
1772%------------------------------------------------------------------------
1773%% stop movie action if the movie_pair button is off
1774if ~get(handles.movie_pair,'value')
1775    set(handles.movie_pair,'BusyAction','Cancel')%stop movie pair if button is 'off'
1776    set(handles.i2,'String','')
1777    set(handles.j2,'String','')
1778    return
1779else
1780    set(handles.movie_pair,'BusyAction','queue')
1781end
1782
1783%% initialisation
1784set(handles.movie_pair,'BackgroundColor',[1 1 0])%paint the command button in yellow
1785drawnow
1786list_fields=get(handles.Fields,'String');% list menu fields
1787index_fields=get(handles.Fields,'Value');% selected string index
1788FieldName=list_fields{index_fields}; % selected field
1789UvData=get(handles.uvmat,'UserData');
1790if isequal(FieldName,'image')
1791    test_1=0;
1792    [RootPath,SubDir,RootFile,FileIndices,Ext]=read_file_boxes(handles);
1793    NomType=get(handles.NomType,'String');
1794else
1795    list_fields=get(handles.Fields_1,'String');% list menu fields
1796    index_fields=get(handles.Fields_1,'Value');% selected string index
1797    FieldName=list_fields{index_fields}; % selected field
1798    if isequal(FieldName,'image')
1799        test_1=1;
1800        [RootPath,tild,RootFile,FileIndex_1,Ext,NomType]=read_file_boxes_1(handles);
1801    else
1802        msgbox_uvmat('ERROR','an image or movie must be first introduced as input')
1803        set(handles.movie_pair,'BackgroundColor',[1 0 0])%paint the command button in red
1804        set(handles.movie_pair,'Value',0)
1805        return
1806    end
1807end
1808num_i1=str2num(get(handles.i1,'String'));
1809num_j1=stra2num(get(handles.j1,'String'));
1810num_i2=str2num(get(handles.i2,'String'));
1811num_j2=stra2num(get(handles.j2,'String'));
1812if isempty(num_j2)
1813    if isempty(num_i2)   
1814        msgbox_uvmat('ERROR', 'a second image index i2 or j2 is needed to show the pair as a movie')
1815        set(handles.movie_pair,'BackgroundColor',[1 0 0])%paint the command button in red
1816         set(handles.movie_pair,'Value',0)
1817        return
1818    else
1819        num_j2=num_j1;%repeat the index i1 by default
1820    end
1821end
1822if isempty(num_i2)
1823    num_i2=num_i1;%repeat the index i1 by default
1824end
1825% imaname_1=name_generator(filebase,num_i2,num_j2,Ext,NomType);
[439]1826imaname_1=fullfile_uvmat(RootPath,SubDir,RootFile,Ext,NomType,num_i2,[],num_j2);
[387]1827if ~exist(imaname_1,'file')
1828      msgbox_uvmat('ERROR',['second input open (-)  ' imaname_1 ' not found']);
1829      set(handles.movie_pair,'BackgroundColor',[1 0 0])%paint the command button in red
1830       set(handles.movie_pair,'Value',0)
1831      return
1832end
1833
1834%% read the second image
1835Field.AName='image';
1836if test_1
1837    Field_a=UvData.Field_1;
1838else
1839    Field_a=UvData.Field;
1840end
1841Field_b.AX=Field_a.AX;
1842Field_b.AY=Field_a.AY;
1843% z index
1844nbslice=str2double(get(handles.nb_slice,'String'));
1845if ~isempty(nbslice)
1846    Field_b.ZIndex=mod(num_i2-1,nbslice)+1;
1847end
1848Field_b.CoordUnit='pixel';
1849
1850%% determine the input file type
1851if (test_1 && isfield(UvData,'MovieObject')&& numel(UvData.MovieObject>=2))||(~test_1 && ~isempty(UvData.MovieObject{1}))
1852    FileType='movie';
1853elseif isequal(lower(Ext),'.avi')
1854    FileType='avi';
1855elseif isequal(lower(Ext),'.vol')
1856    FileType='vol';
1857else
1858   form=imformats(Ext(2:end));
1859   if ~isempty(form)% if the extension corresponds to an image format recognized by Matlab
1860       if isequal(NomType,'*');
1861           FileType='multimage';
1862       else
1863           FileType='image';
1864       end
1865   end
1866end
1867switch FileType
1868        case 'movie'
1869            if test_1
1870                Field_b.A=read(UvData.MovieObject{2},num_i2);
1871            else
1872                Field_b.A=read(UvData.MovieObject{1},num_i2);
1873            end
1874        case 'avi'
1875            mov=aviread(imaname_1,num_i2);
1876            Field_b.A=frame2im(mov(1));
1877        case 'vol'
1878            Field_b.A=imread(imaname_1);
1879        case 'multimage'
1880            Field_b.A=imread(imaname_1,num_i2);
1881        case 'image'
1882            Field_b.A=imread(imaname_1);
1883end
1884if get(handles.slices,'Value')
1885    Field.ZIndex=str2double(get(handles.z_index,'String'));
1886end
1887
1888%px to phys or other transform on field
1889menu_transform=get(handles.transform_fct,'String');
1890choice_value=get(handles.transform_fct,'Value');
1891transform_name=menu_transform{choice_value};%name of the transform fct  given by the menu 'transform_fct'
1892transform_list=get(handles.transform_fct,'UserData');
1893transform=transform_list{choice_value};
1894if  ~isequal(transform_name,'') && ~isequal(transform_name,'px')
1895    if test_1 && isfield(UvData,'XmlData') && numel(UvData.XmlData)==2 && isfield(UvData.XmlData{2},'GeometryCalib')%use geometry calib recorded from the ImaDoc xml file as first priority
1896        Field_a=transform(Field_a,UvData.XmlData{2});%the first field has been stored without transform
1897        Field_b=transform(Field_b,UvData.XmlData{2});
1898    elseif ~test_1 && isfield(UvData,'XmlData') && isfield(UvData.XmlData{1},'GeometryCalib')%use geometry calib
1899        Field_b=transform(Field_b,UvData.XmlData{1});
1900    end
1901end
1902
1903 % make movie until movie speed is set to 0 or STOP is activated
1904hima=findobj(handles.axes3,'Tag','ima');% %handles.axes3 =main plotting window (A GENERALISER)
1905set(handles.STOP,'Visible','on')
1906set(handles.speed,'Visible','on')
1907set(handles.speed_txt,'Visible','on')
1908while get(handles.speed,'Value')~=0 && isequal(get(handles.movie_pair,'BusyAction'),'queue')%isequal(get(handles.run0,'BusyAction'),'queue'); % enable STOP command
1909    % read and plot the series of images in non erase mode
1910    set(hima,'CData',Field_b.A);
1911    pause(1.02-get(handles.speed,'Value'));% wait for next image
1912    set(hima,'CData',Field_a.A);
1913    pause(1.02-get(handles.speed,'Value'));% wait for next image
1914end
1915set(handles.movie_pair,'BackgroundColor',[1 0 0])%paint the command button in red
1916 set(handles.movie_pair,'Value',0)
1917
1918%------------------------------------------------------------------------
1919% --- Executes on button press in run0.
1920function run0_Callback(hObject, eventdata, handles)
1921%------------------------------------------------------------------------
1922set(handles.run0,'BackgroundColor',[1 1 0])%paint the command button in yellow
1923drawnow
1924[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
1925filename=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
1926filename_1=[];%default
1927if get(handles.SubField,'Value')
1928    [RootPath_1,SubDir_1,RootFile_1,FileIndices_1,FileExt_1]=read_file_boxes_1(handles);
1929    filename_1=[fullfile(RootPath_1,SubDir_1,RootFile_1) FileIndices_1 FileExt_1];
1930end
1931num_i1=stra2num(get(handles.i1,'String'));
1932num_i2=stra2num(get(handles.i2,'String'));
1933num_j1=stra2num(get(handles.j1,'String'));
1934num_j2=stra2num(get(handles.j2,'String'));
1935
1936errormsg=refresh_field(handles,filename,filename_1,num_i1,num_i2,num_j1,num_j2);
1937
1938if ~isempty(errormsg)
1939      msgbox_uvmat('ERROR',errormsg);
1940else
1941    set(handles.i1,'BackgroundColor',[1 1 1])
1942    set(handles.i2,'BackgroundColor',[1 1 1])
1943    set(handles.j1,'BackgroundColor',[1 1 1])
1944    set(handles.j2,'BackgroundColor',[1 1 1])
1945    set(handles.FileIndex,'BackgroundColor',[1 1 1])
1946    set(handles.FileIndex_1,'BackgroundColor',[1 1 1])
1947end   
1948set(handles.run0,'BackgroundColor',[1 0 0])
1949
1950
1951%------------------------------------------------------------------------
1952% --- read the input files and refresh all the plots, including projection.
1953% OUTPUT:
1954%  errormsg: error message char string  =[] by default
1955% INPUT:
1956% filename: first input file (=[] in the absence of input file)
1957% filename_1: second input file (=[] in the asbsenc of secodn input file)
1958% num_i1,num_i2,num_j1,num_j2; frame indices
1959% Field: structure describing an optional input field (then replace the input file)
[397]1960
[450]1961function errormsg=refresh_field(handles,FileName,FileName_1,num_i1,num_i2,num_j1,num_j2,Field)
[387]1962%------------------------------------------------------------------------
1963
1964%% initialisation
1965abstime=[];
1966abstime_1=[];
1967dt=[];
1968if ~exist('Field','var')
1969    Field={};
1970end
1971UvData=get(handles.uvmat,'UserData');
1972if ishandle(handles.UVMAT_title) %remove title panel on uvmat
1973    delete(handles.UVMAT_title)
1974end
1975
1976%% determine the main input file information for action
1977FileType=[];%default
[450]1978if ~exist(FileName,'file')
1979    errormsg=['input file ' FileName ' does not exist'];
[387]1980    return
1981end
1982NomType=get(handles.NomType,'String');
[494]1983NomType_1='';
1984if strcmp(get(handles.NomType_1,'Visible'),'on')
1985    NomType_1=get(handles.NomType_1,'String');
1986end
[387]1987% NomType=get(handles.FileIndex,'UserData');
1988%update the z position index
1989nbslice_str=get(handles.nb_slice,'String');
1990if isequal(nbslice_str,'volume')%NOT USED
1991    z_index=num_j1;
1992    set(handles.z_index,'String',num2str(z_index))
1993else
1994    nbslice=str2num(nbslice_str);
1995    z_index=mod(num_i1-1,nbslice)+1;
1996    set(handles.z_index,'String',num2str(z_index))
1997end
1998% refresh menu for save_mask if relevant
1999masknumber=get(handles.masklevel,'String');
2000if length(masknumber)>=z_index
2001    set(handles.masklevel,'Value',z_index)
2002end
2003
2004%% read the first input field if a filename has been introduced
[421]2005ParamIn.ColorVar='';%default variable name for vector color
[445]2006frame_index=1;%default
[450]2007if ~isempty(FileName)
[404]2008    FieldName='';%default
2009    VelType='';%default
2010%     FileType=UvData.FileType{1};
2011    switch UvData.FileType{1}
[387]2012        case {'civx','civdata','netcdf'};
2013            list_fields=get(handles.Fields,'String');% list menu fields
[404]2014  %          index_fields=get(handles.Fields,'Value');% selected string index
2015            FieldName= list_fields{get(handles.Fields,'Value')}; % selected field
[387]2016            if ~strcmp(FieldName,'get_field...')
[389]2017                if get(handles.FixVelType,'Value')
2018                    VelTypeList=get(handles.VelType,'String');
2019                    VelType=VelTypeList{get(handles.VelType,'Value')};
[387]2020                end
2021            end
2022            if strcmp(FieldName,'velocity')
[405]2023                list_code=get(handles.ColorCode,'String');% list menu fields
2024                index_code=get(handles.ColorCode,'Value');% selected string index
[387]2025                if  ~strcmp(list_code{index_code},'black') &&  ~strcmp(list_code{index_code},'white')
[405]2026                    list_code=get(handles.ColorScalar,'String');% list menu fields
2027                    index_code=get(handles.ColorScalar,'Value');% selected string index
[387]2028                    ParamIn.ColorVar= list_code{index_code}; % selected field
2029                end
2030            end
[435]2031        case {'video','mmreader'}
[450]2032            ParamIn=UvData.MovieObject{1};     
[445]2033            if ~strcmp(NomType,'*')
2034                frame_index=num_j1;%frame index for movies or multimage
2035            else
2036                frame_index=num_i1;
2037            end
2038        case 'multimage'
2039            if ~strcmp(NomType,'*')
2040                frame_index=num_j1;%frame index for movies or multimage
2041            else
2042                frame_index=num_i1;
2043            end
[387]2044        case 'vol' %TODO: update
2045            if isfield(UvData.XmlData,'Npy') && isfield(UvData.XmlData,'Npx')
2046                ParamIn.Npy=UvData.XmlData.Npy;
2047                ParamIn.Npx=UvData.XmlData.Npx;
2048            else           
2049                errormsg='Npx and Npy need to be defined in the xml file for volume images .vol';
2050                return
2051            end
2052    end
[452]2053    if isstruct (ParamIn)
[387]2054    ParamIn.FieldName=FieldName;
2055    ParamIn.VelType=VelType;
2056    ParamIn.GUIName='get_field';
[452]2057    end
[450]2058    [Field{1},ParamOut,errormsg] = read_field(FileName,UvData.FileType{1},ParamIn,frame_index);
[387]2059    if ~isempty(errormsg)
[450]2060        errormsg=['error in reading ' FileName ': ' errormsg];
[387]2061        return
2062    end 
2063    if isfield(ParamOut,'Npx')&& isfield(ParamOut,'Npy')
2064        set(handles.num_Npx,'String',num2str(ParamOut.Npx));% display image size on the interface
2065        set(handles.num_Npy,'String',num2str(ParamOut.Npy));
2066    end
[415]2067    if isfield(ParamOut,'TimeIndex')% case of time obtained from get_field
[387]2068        set(handles.i1,'String',num2str(ParamOut.TimeIndex))
2069    end
2070    if isfield(ParamOut,'TimeValue')
[415]2071        Field{1}.Time=ParamOut.TimeValue;% case of time obtained from get_field
[387]2072    end
2073end
2074
[450]2075%% choose and read a second field FileName_1 if defined
[387]2076VelType_1=[];%default
2077FieldName_1=[];
2078ParamOut_1=[];
[445]2079frame_index_1=1;
[450]2080if ~isempty(FileName_1)
2081    if ~exist(FileName_1,'file')
2082        errormsg=['second file ' FileName_1 ' does not exist'];
[387]2083        return
2084    end
[450]2085    Name=FileName_1;
[404]2086    switch UvData.FileType{2}
[387]2087        case {'civx','civdata','netcdf'};
2088            list_fields=get(handles.Fields_1,'String');% list menu fields
[389]2089            FieldName_1= list_fields{get(handles.Fields_1,'Value')}; % selected field
[387]2090            if ~strcmp(FieldName,'get_field...')
[389]2091                if get(handles.FixVelType,'Value')
2092                    VelTypeList=get(handles.VelType_1,'String');
2093                    VelType_1=VelTypeList{get(handles.VelType_1,'Value')};% read the velocity type.
[387]2094                end
2095            end
[405]2096            if strcmp(FieldName_1,'velocity')&& strcmp(get(handles.ColorCode,'Visible'),'on')
2097                list_code=get(handles.ColorCode,'String');% list menu fields
2098                index_code=get(handles.ColorCode,'Value');% selected string index
[387]2099                if  ~strcmp(list_code{index_code},'black') &&  ~strcmp(list_code{index_code},'white')
[405]2100                    list_code=get(handles.ColorScalar,'String');% list menu fields
2101                    index_code=get(handles.ColorScalar,'Value');% selected string index
2102                    ParamIn_1.ColorVar= list_code{index_code}; % selected field for vector color display                 
[387]2103                end
2104            end
[435]2105        case {'video','mmreader'}
[450]2106            ParamIn_1=UvData.MovieObject{2};
[445]2107                        if ~strcmp(NomType_1,'*')
2108                frame_index_1=num_j1;%frame index for movies or multimage
2109            else
2110                frame_index_1=num_i1;
2111            end 
2112         case 'multimage'
2113            if ~strcmp(NomType_1,'*')
2114                frame_index_1=num_j1;%frame index for movies or multimage
2115            else
2116                frame_index_1=num_i1;
2117            end   
[387]2118        case 'vol' %TODO: update
2119            if isfield(UvData.XmlData,'Npy') && isfield(UvData.XmlData,'Npx')
[405]2120                ParamIn_1.Npy=UvData.XmlData.Npy;
2121                ParamIn_1.Npx=UvData.XmlData.Npx;
[387]2122            else
2123                errormsg='Npx and Npy need to be defined in the xml file for volume images .vol';
2124                return
2125            end
2126    end
[428]2127    if isequal(get(handles.NomType_1,'Visible'),'on')
[387]2128    NomType_1=get(handles.NomType_1,'String');
[428]2129    else
2130        NomType_1=get(handles.NomType,'String');
2131    end
[387]2132    test_keepdata_1=0;% test for keeping the previous stored data if the input files are unchanged
2133    if ~isequal(NomType_1,'*')%in case of a series of files (not avi movie)
[450]2134        if isfield(UvData,'FileName_1')%&& isfield(UvData,'VelType_1') && isfield(UvData,'FieldName_1')
2135            test_keepdata_1= strcmp(FileName_1,UvData.FileName_1) ;%&& strcmp(FieldName_1,UvData.FieldName_1);
[387]2136        end
2137    end
2138    if test_keepdata_1
[389]2139        Field{2}=UvData.Field_1;% keep the stored field
[427]2140        ParamOut_1=UvData.ParamOut_1;
[387]2141    else
[494]2142        if isstruct(ParamIn_1)
[405]2143        ParamIn_1.FieldName=FieldName_1;
2144        ParamIn_1.VelType=VelType_1;
2145        ParamIn_1.GUIName='get_field_1';
[494]2146        end
[445]2147        [Field{2},ParamOut_1,errormsg] = read_field(Name,UvData.FileType{2},ParamIn_1,frame_index_1);
[387]2148        if ~isempty(errormsg)
[450]2149            errormsg=['error in reading ' FieldName_1 ' in ' FileName_1 ': ' errormsg];
[387]2150            return
2151        end
[405]2152%         UvData.Field_1=Field{2}; %store the second field for possible use at next RUN
[387]2153    end
2154end
2155
2156%% update uvmat interface
2157if isfield(ParamOut,'Npx')
2158    set(handles.num_Npx,'String',num2str(ParamOut.Npx));% display image size on the interface
2159    set(handles.num_Npy,'String',num2str(ParamOut.Npy));
2160elseif isfield(ParamOut_1,'Npx')
2161    set(handles.num_Npx,'String',num2str(ParamOut_1.Npx));% display image size on the interface
2162    set(handles.num_Npy,'String',num2str(ParamOut_1.Npy));
2163end
2164
2165%% update the display menu for the first velocity type (first menuline)
2166test_veltype=0;
2167% if ~isequal(FileType,'netcdf')|| isequal(FieldName,'get_field...')
[404]2168if (strcmp(UvData.FileType{1},'civx')||strcmp(UvData.FileType{1},'civdata'))&& ~strcmp(FieldName,'get_field...')
[387]2169    test_veltype=1;
2170    set(handles.VelType,'Visible','on')
2171    set(handles.VelType_1,'Visible','on')
2172    set(handles.FixVelType,'Visible','on')
[404]2173    menu=set_veltype_display(ParamOut.CivStage,UvData.FileType{1});
[387]2174    index_menu=strcmp(ParamOut.VelType,menu);%look for VelType in  the menu
2175    index_val=find(index_menu,1);
2176    if isempty(index_val)
2177        index_val=1;
2178    end
2179    set(handles.VelType,'Value',index_val)
2180    if ~get(handles.SubField,'value')
2181        set(handles.VelType,'String',menu)
2182        set(handles.VelType_1,'Value',1)
2183        set(handles.VelType_1,'String',[{''};menu])
2184    end
2185else
2186    set(handles.VelType,'Visible','off')
2187end
[405]2188% display the Fields menu from the input file and pick the selected one:
[452]2189if isstruct(ParamOut)
[387]2190field_index=strcmp(ParamOut.FieldName,ParamOut.FieldList);
2191set(handles.Fields,'String',ParamOut.FieldList); %update the field menu
2192set(handles.Fields,'Value',find(field_index,1))
[452]2193end
[387]2194
2195%% update the display menu for the second velocity type (second menuline)
2196test_veltype_1=0;
[450]2197if isempty(FileName_1)
[387]2198    set(handles.Fields_1,'Value',1); %update the field menu
[452]2199    if isstruct(ParamOut)
[387]2200    set(handles.Fields_1,'String',[{''};ParamOut.FieldList]); %update the field menu
[452]2201    end
[405]2202elseif ~test_keepdata_1
[404]2203    if (~strcmp(UvData.FileType{2},'netcdf')&&~strcmp(UvData.FileType{2},'civdata')&&~strcmp(UvData.FileType{2},'civx'))|| isequal(FieldName_1,'get_field...')
[387]2204        set(handles.VelType_1,'Visible','off')
[405]2205    else
[387]2206        test_veltype_1=1;
2207        set(handles.VelType_1,'Visible','on')
[494]2208        menu=set_veltype_display(ParamOut_1.CivStage);
2209        index_menu=strcmp(ParamOut_1.VelType,menu);
2210        set(handles.VelType_1,'Value',1+find(index_menu,1))
2211        set(handles.VelType_1,'String',[{''};menu])
[387]2212    end
[405]2213    % update the second field menu: the same quantity
[494]2214    if isstruct(ParamOut_1)
[405]2215    set(handles.Fields_1,'String',[{''};ParamOut_1.FieldList]); %update the field menu
2216    % display the Fields menu from the input file and pick the selected one:
2217    field_index=strcmp(ParamOut_1.FieldName,ParamOut_1.FieldList);
2218    set(handles.Fields_1,'Value',find(field_index,1)+1) 
[494]2219    end
2220   
[387]2221end
2222if test_veltype||test_veltype_1
2223     set(handles.FixVelType,'Visible','on')
2224else
2225     set(handles.FixVelType,'Visible','off')
2226end
[405]2227
2228% field_index=strcmp(ParamOut_1.FieldName,ParamOut_1.FieldList);
2229% set(handles.Fields,'String',ParamOut.FieldList); %update the field menu
2230% set(handles.Fields,'Value',find(field_index,1))
[387]2231   
2232%% introduce w as background image by default for a new series (only for nbdim=2)
2233if ~isfield(UvData,'NewSeries')
2234    UvData.NewSeries=1;
2235end
2236%put W as background image by default if NbDim=2:
2237if  UvData.NewSeries && isequal(get(handles.SubField,'Value'),0) && isfield(Field{1},'W') && ~isempty(Field{1}.W) && ~isequal(Field{1}.NbDim,3);
2238        set(handles.SubField,'Value',1);
2239        set(handles.RootPath_1,'String','"')
2240        set(handles.RootFile_1,'String','"')
2241        set(handles.SubDir_1,'String','"');
2242         indices=fullfile_uvmat('','','','',NomType,num_i1,num_i2,num_j1,num_j2);
2243        set(handles.FileIndex_1,'String',indices)
2244        set(handles.FileExt_1,'String','"');
2245        set(handles.Fields_1,'Visible','on');
2246        set(handles.Fields_1,'Visible','on');
2247        set(handles.RootPath_1,'Visible','on')
2248        set(handles.RootFile_1,'Visible','on')
2249        set(handles.SubDir_1,'Visible','on');
2250        set(handles.FileIndex_1,'Visible','on');
2251        set(handles.FileExt_1,'Visible','on');
2252        set(handles.Fields_1,'Visible','on');
2253        Field{1}.AName='w';
2254end           
2255
[415]2256%% display time
2257testimedoc=0;
2258TimeUnit='';
2259if isfield(Field{1},'Time')
2260    abstime=Field{1}.Time;%time read from the netcdf input file
2261end
2262if numel(Field)==2 && isfield(Field{2},'Time')
2263    abstime_1=Field{2}.Time;%time read from the netcdf input file
2264end
2265if isfield(Field{1},'Dt')
2266    dt=Field{1}.Dt;%dt read from the netcdf input file
2267    if isfield(Field{1},'TimeUnit')
2268       TimeUnit=Field{1}.TimeUnit;
2269    end
2270elseif numel(Field)==2 && isfield(Field{2},'Dt')%dt obtained from the second field if not defined in the first
2271    dt=Field{2}.Dt;%dt read from the netcdf input file
2272    if isfield(Field{2},'TimeUnit')
2273       TimeUnit=Field{2}.TimeUnit;
2274    end
2275end
2276% time from xml file overset previous result
2277if isfield(UvData,'XmlData') && isfield(UvData.XmlData{1},'Time')
2278    if isempty(num_i2)||isnan(num_i2)
2279        num_i2=num_i1;
2280    end
2281    if isempty(num_j1)||isnan(num_j1)
2282        num_j1=1;
2283    end
2284    if isempty(num_j2)||isnan(num_j2)
2285        num_j2=num_j1;
2286    end
2287    siz=size(UvData.XmlData{1}.Time);
[446]2288    if ~isempty(num_i1)&& ~isempty(num_i2)&&siz(1)>=max(num_i1,num_i2) && siz(2)>=max(num_j1,num_j2)
[415]2289        abstime=(UvData.XmlData{1}.Time(num_i1,num_j1)+UvData.XmlData{1}.Time(num_i2,num_j2))/2;%overset the time read from files
2290        dt=(UvData.XmlData{1}.Time(num_i2,num_j2)-UvData.XmlData{1}.Time(num_i1,num_j1));
2291        Field{1}.Dt=dt;
2292        if isfield(UvData.XmlData{1},'TimeUnit')
2293            TimeUnit=UvData.XmlData{1}.TimeUnit;
2294        end
2295    end
2296    if numel(UvData.XmlData)==2
2297        [tild,tild,tild,num_i1,num_i2,num_j1,num_j2]=fileparts_uvmat(['xx' get(handles.FileIndex_1,'String') get(handles.FileExt_1,'String')]);
2298        if isempty(num_i2)
2299            num_i2=num_i1;
2300        end
2301        if isempty(num_j1)
2302            num_j1=1;
2303        end
2304        if isempty(num_j2)
2305            num_j2=num_j1;
2306        end
2307        siz=size(UvData.XmlData{2}.Time);
2308        if ~isempty(num_i1) && siz(1)>=max(num_i1,num_i2) && siz(2)>=max(num_j1,num_j2)
2309            abstime_1=(UvData.XmlData{2}.Time(num_i1,num_j1)+UvData.XmlData{2}.Time(num_i2,num_j2))/2;%overset the time read from files
2310            Field{2}.Dt=(UvData.XmlData{2}.Time(num_i2,num_j2)-UvData.XmlData{2}.Time(num_i1,num_j1));
2311        end
2312    end
2313end
2314if ~isequal(numel(abstime),1)
2315    abstime=[];
2316end
2317if ~isequal(numel(abstime_1),1)
2318      abstime_1=[];
2319end 
[456]2320set(handles.abs_time,'String',num2str(abstime,5))
2321set(handles.abs_time_1,'String',num2str(abstime_1,5))
[415]2322% if testimedoc && isfield(UvData,'dt')
2323%     dt=UvData.dt;
2324% end
2325if isempty(dt)||isequal(dt,0)
2326    set(handles.Dt_txt,'String','')
2327else
2328    if  isempty(TimeUnit)
2329        set(handles.Dt_txt,'String',['Dt=' num2str(1000*dt,3) '  10^(-3)'] )
2330    else
2331        set(handles.Dt_txt,'String',['Dt=' num2str(1000*dt,3) '  m' TimeUnit] )
2332    end
2333end
2334
2335
[387]2336%% store the current open names, fields and vel types in uvmat interface
[450]2337UvData.FileName_1=FileName_1;
[387]2338
2339%% apply coordinate transform or other user fct
2340XmlData=[];%default
2341XmlData_1=[];%default
2342if isfield(UvData,'XmlData')%use geometry calib recorded from the ImaDoc xml file as first priority
2343    XmlData=UvData.XmlData{1};
2344    if numel(UvData.XmlData)==2
2345        XmlData_1=UvData.XmlData{2};
2346    end
2347end
2348choice_value=get(handles.transform_fct,'Value');
2349transform_list=get(handles.transform_fct,'UserData');
2350transform=transform_list{choice_value};%selected function handles
2351% z index
[450]2352if ~isempty(FileName)
[387]2353    Field{1}.ZIndex=z_index;
2354end
[389]2355if ~isempty(transform)
[387]2356    if length(Field)>=2
2357        Field{2}.ZIndex=z_index;
2358        [Field{1},Field{2}]=transform(Field{1},XmlData,Field{2},XmlData_1);
2359        if isempty(Field{2})
2360            Field(2)=[];
2361        end
2362    else
2363        Field{1}=transform(Field{1},XmlData);
2364    end
[494]2365   
2366    %% check whether tps is needed, then calculate tps coefficients if needed
2367    check_tps=0;
2368    if strcmp(UvData.FileType{1},'civdata')|| strcmp(UvData.FileType{1},'civx')
2369        switch ParamOut.FieldName
2370            case {'vort','div','strain'}
2371                check_tps=1;
2372            otherwise
2373                check_tps=0;
2374                if isfield(UvData,'Object')
2375                for iobj=1:numel(UvData.Object)
2376                    UvData.Object{iobj}
2377                    if isfield(UvData.Object{iobj},'ProjMode')&& strcmp(UvData.Object{iobj}.ProjMode,'filter')
2378                        check_tps=1;
2379                        break
2380                    end
2381                end
2382                end
2383        end
[389]2384    end
[494]2385    if check_tps
2386        SubDomain=1500; %default, estimated nbre of vectors in a subdomain used for tps
2387        if isfield(Field{1},'SubDomain')
2388            SubDomain=Field{1}.SubDomain;%
[389]2389        end
[494]2390        [Field{1}.SubRange,Field{1}.NbSites,Field{1}.Coord_tps,Field{1}.U_tps,Field{1}.V_tps,tild,U_smooth,V_smooth,W_smooth,FF] =...
2391           filter_tps([Field{1}.X(Field{1}.FF==0) Field{1}.Y(Field{1}.FF==0)],Field{1}.U(Field{1}.FF==0),Field{1}.V(Field{1}.FF==0),[],SubDomain,0);
2392        nbvar=numel(Field{1}.ListVarName);
2393        Field{1}.ListVarName=[Field{1}.ListVarName {'SubRange','NbSites','Coord_tps','U_tps','V_tps'}];
2394        Field{1}.VarDimName=[Field{1}.VarDimName {{'nb_coord','nb_bounds','nb_subdomain'},{'nb_subdomain'},...
2395            {'nb_tps','nb_coord','nb_subdomain'},{'nb_tps','nb_subdomain'},{'nb_tps','nb_subdomain'}}];
2396        Field{1}.VarAttribute{nbvar+3}.Role='coord_tps';
2397        Field{1}.VarAttribute{nbvar+4}.Role='vector_x';
2398        Field{1}.VarAttribute{nbvar+5}.Role='vector_y';
2399        if isfield(Field{1},'ListDimName')%cleaning
2400            Field{1}=rmfield(Field{1},'ListDimName');
2401        end
2402        if isfield(Field{1},'DimValue')%cleaning
2403            Field{1}=rmfield(Field{1},'DimValue');
2404        end
[389]2405    end
[387]2406end
2407
2408%% calculate scalar
[491]2409if isstruct(ParamOut)&&~strcmp(ParamOut.FieldName,'get_field...')&& (strcmp(UvData.FileType{1},'civdata')||strcmp(UvData.FileType{1},'civx'))
2410    if isfield(Field{1},'Coord_tps')
2411        Field{1}.FieldList=[{ParamOut.FieldName} {ParamOut.ColorVar}];
2412    else
[405]2413    Field{1}=calc_field([{ParamOut.FieldName} {ParamOut.ColorVar}],Field{1});
[491]2414    end
[405]2415end
[491]2416if isstruct(ParamOut_1)&& numel(Field)==2 && ~strcmp(ParamOut_1.FieldName,'get_field...')&& ~test_keepdata_1 && (strcmp(UvData.FileType{2},'civdata')||strcmp(UvData.FileType{2},'civx'))...
2417        &&~strcmp(ParamOut_1.FieldName,'velocity') && ~strcmp(ParamOut_1.FieldName,'get_field...')
2418    if isfield(Field{2},'Coord_tps')
2419        Field{2}.FieldList=[{ParamOut_1.FieldName} {ParamOut_1.ColorVar}];
2420    else
[405]2421     Field{2}=calc_field([{ParamOut_1.FieldName} {ParamOut_1.ColorVar}],Field{2});
[491]2422    end
[405]2423end
[387]2424
2425%% combine the two input fields (e.g. substract velocity fields)
[405]2426%Field{1}.FieldList=[{ParamOut.FieldName} {ParamOut.ColorVar}];
[387]2427if numel(Field)==2
[402]2428   [UvData.Field,errormsg]=sub_field(Field{1},Field{2}); 
[405]2429   UvData.Field_1=Field{2}; %store the second field for possible use at next RUN
[427]2430   UvData.ParamOut_1=ParamOut_1;
[387]2431else
2432   UvData.Field=Field{1};
2433end
[402]2434if ~isempty(errormsg)
2435    errormsg=['error in uvmat/refresh_field/sub_field:' errormsg];
2436    return
2437end
[404]2438%UvData.Field.FieldList={FieldName}; % TODO: to generalise, used for proj_field with tps interpolation
[387]2439
[434]2440%% analyse input field
[387]2441test_x=0;
2442test_z=0;% test for unstructured z coordinate
[434]2443[errormsg,ListDimName,DimValue,VarDimIndex]=check_field_structure(UvData.Field);% check the input field structure
[387]2444if ~isempty(errormsg)
[434]2445    errormsg=['error in uvmat/refresh_field/check_field_structure: ' errormsg];% display error
[387]2446    return
2447end
[434]2448[CellVarIndex,NbDim,VarType,errormsg]=find_field_indices(UvData.Field);% analyse  the input field structure
[387]2449if ~isempty(errormsg)
[434]2450    errormsg=['error in uvmat/refresh_field/find_field_indices: ' errormsg];% display error
[387]2451    return
2452end
[421]2453[NbDim,imax]=max(NbDim);% spatial dimension of the input field
[387]2454if isfield(UvData.Field,'NbDim')
2455    NbDim=UvData.Field.NbDim;% deal with plane fields containing z coordinates
2456end
[434]2457
2458%% get bounds and mesh (needed for mouse action and to open set_object)
[435]2459if NbDim>1
2460    XName=''; %default
2461    YName='';
2462    %unstructured coordinates
2463    if ~isempty(VarType{imax}.coord_x)&&~isempty(VarType{imax}.coord_y)
2464        XName=UvData.Field.ListVarName{VarType{imax}.coord_x};
[434]2465        YName=UvData.Field.ListVarName{VarType{imax}.coord_y};
2466        %nbvec=length(UvData.Field.(XName));%nbre of measurement points (e.g. vectors)
2467        test_x=1;%test for unstructured coordinates
2468        if ~isempty(VarType{imax}.coord_z)
2469            ZName=UvData.Field.ListVarName{VarType{imax}.coord_z};
2470        else
2471            NbDim=2;
2472        end
[435]2473        %structured coordinate
2474    elseif numel(VarType)>=imax && numel(VarType{imax}.coord)>=NbDim && VarType{imax}.coord(NbDim)>0
2475        XName=UvData.Field.ListVarName{VarType{imax}.coord(NbDim)};
2476        if NbDim> 1 && VarType{imax}.coord(NbDim-1)>0
2477            YName=UvData.Field.ListVarName{VarType{imax}.coord(NbDim-1)}; %structured coordinates
2478        end
2479        % VarIndex=CellVarIndex{imax}; % list of variable indices
2480        DimIndex=VarDimIndex{CellVarIndex{imax}(1)}; %list of dim indices for the variable
2481        nbpoints_x=DimValue(DimIndex(NbDim));
2482        XMax=nbpoints_x;%default
2483        XMin=1;%default
[387]2484    end
[435]2485   
2486    if NbDim==3
2487        if ~test_x
2488            ZName=UvData.Field.ListVarName{VarType{imax}.coord(1)};%structured coordinates in 3D
2489        end
2490        ZMax=max(UvData.Field.(ZName));
2491        ZMin=min(UvData.Field.(ZName));
2492        UvData.Field.ZMax=ZMax;
2493        UvData.Field.ZMin=ZMin;
2494        test_z=1;
2495        if isequal(ZMin,ZMax)%no z dependency
2496            NbDim=2;
2497            test_z=0;
2498        end
[387]2499    end
[435]2500    if ~isempty (XName)
2501        XMax=max(max(UvData.Field.(XName)));
2502        XMin=min(min(UvData.Field.(XName)));
2503        UvData.Field.NbDim=NbDim;
2504        UvData.Field.XMax=XMax;
2505        UvData.Field.XMin=XMin;
2506        if NbDim >1&& ~isempty(YName)
2507            YMax=max(max(UvData.Field.(YName)));
2508            YMin=min(min(UvData.Field.(YName)));
2509            UvData.Field.YMax=YMax;
2510            UvData.Field.YMin=YMin;
2511        end
2512        nbvec=length(UvData.Field.(XName));
2513        if test_x %unstructured coordinates
2514            if test_z
2515                UvData.Field.Mesh=((XMax-XMin)*(YMax-YMin)*(ZMax-ZMin))/nbvec;% volume per vector
2516                UvData.Field.Mesh=(UvData.Field.Mesh)^(1/3);
2517            else
2518                UvData.Field.Mesh=sqrt((XMax-XMin)*(YMax-YMin)/nbvec);%2D
2519            end
2520        end
2521    end
2522    % case of structured coordinates
[387]2523    if ~test_x
[435]2524        DX=(XMax-XMin)/(nbpoints_x-1);
2525        if NbDim >1
2526            nbpoints_y=DimValue(DimIndex(NbDim-1));
2527            if isempty(YName)% if the y coordinate is not expressed, it is taken as the matrix index
2528                DY=1;
2529                UvData.Field.YMax=nbpoints_y;
2530                UvData.Field.YMin=1;
2531            else
2532                DY=(YMax-YMin)/(nbpoints_y-1);
2533            end
[387]2534        end
[435]2535        if NbDim==3
2536            nbpoints_z=DimValue(DimIndex(1));
2537            DZ=(ZMax-ZMin)/(nbpoints_z-1);
2538            UvData.Field.Mesh=(DX*DY*DZ)^(1/3);
2539            UvData.Field.ZMax=ZMax;
2540            UvData.Field.ZMin=ZMin;
[421]2541        else
[435]2542            UvData.Field.Mesh=DX;%sqrt(DX*DY);
[387]2543        end
2544    end
[435]2545    % adjust the mesh to a value 1, 2 , 5 *10^n
2546    ord=10^(floor(log10(UvData.Field.Mesh)));%order of magnitude
2547    if UvData.Field.Mesh/ord>=5
2548        UvData.Field.Mesh=5*ord;
2549    elseif UvData.Field.Mesh/ord>=2
2550        UvData.Field.Mesh=2*ord;
[404]2551    else
[435]2552        UvData.Field.Mesh=ord;
[404]2553    end
[491]2554    % default projection plane
2555    if ~isfield(UvData,'Object')
2556        UvData.Object{1}.Type='plane';%main plotting plane
2557        UvData.Object{1}.ProjMode='projection';%main plotting plane
2558        UvData.Object{1}.DisplayHandle.uvmat=[]; %plane not visible in uvmat
2559        UvData.Object{1}.DisplayHandle.view_field=[]; %plane not visible in uvmat
2560    end
[435]2561    %% 3D case (menuvolume)
2562    if NbDim==3% && UvData.NewSeries
2563        test_set_object=1;
2564        hset_object=findobj(allchild(0),'tag','set_object');% look for the set_object GUI
2565        ZBounds(1)=UvData.Field.ZMin; %minimum for the Z slider
2566        ZBounds(2)=UvData.Field.ZMax;%maximum for the Z slider
2567        if ~isempty(hset_object) %if set_object is detected
2568            delete(hset_object);% delete the GUI set_object if it does not fit
[387]2569        end
[435]2570        if test_set_object% reinitiate the GUI set_object
2571            delete_object(1);% delete the current projection object in the list UvData.Object, delete its graphic representations and update the list displayed in handles.ListObject and 2
2572            UvData.Object{1}.NbDim=NbDim;%test for 3D objects
2573            UvData.Object{1}.RangeZ=UvData.Field.Mesh;%main plotting plane
2574            UvData.Object{1}.Coord(1,3)=(UvData.Field.ZMin+UvData.Field.ZMax)/2;%section at a middle plane chosen
2575            UvData.Object{1}.Angle=[0 0 0];
2576            UvData.Object{1}.HandlesDisplay=plot(0,0,'Tag','proj_object');% A REVOIR
2577            UvData.Object{1}.Name='1-PLANE';
2578            UvData.Object{1}.enable_plot=1;
2579            set_object(UvData.Object{1},handles,ZBounds);
2580            set(handles.ListObject,'Value',1);
2581            set(handles.ListObject,'String',{'1-PLANE'});
2582            set(handles.edit_object,'Value',1)% put the plane in edit mode to enable the z cursor
2583            edit_object_Callback([],[], handles)
[387]2584        end
[435]2585        %multilevel case (single menuplane in a 3D space)
2586    elseif isfield(UvData,'Z')
2587        if isfield(UvData,'CoordType')&& isequal(UvData.CoordType,'phys') && isfield(UvData,'XmlData')
2588            XmlData=UvData.XmlData{1};
2589            if isfield(XmlData,'PlanePos')
2590                UvData.Object{1}.Coord=XmlData.PlanePos(UvData.ZIndex,:);
2591            end
2592            if isfield(XmlData,'PlaneAngle')
2593                siz=size(XmlData.PlaneAngle);
2594                indangle=min(siz(1),UvData.ZIndex);%take first angle if a single angle is defined (translating scanning)
2595                UvData.Object{1}.PlaneAngle=XmlData.PlaneAngle(indangle,:);
2596            end
2597        elseif isfield(UvData,'ZIndex')
2598            UvData.Object{1}.ZObject=UvData.ZIndex;
2599        end
[387]2600    end
2601end
[435]2602
[387]2603testnewseries=UvData.NewSeries;
2604UvData.NewSeries=0;% put to 0 the test for a new field series (set by RootPath_callback)
2605set(handles.uvmat,'UserData',UvData)
2606
2607%% reset the min and max of scalar if only the mask is displayed(TODO: check the need)
[405]2608% if isfield(UvData,'Mask')&& ~isfield(UvData,'A')
2609%     set(handles.num_MinA,'String','0')
2610%     set(handles.num_MaxA,'String','255')
2611% end
[387]2612
[434]2613%% usual 1D (x,y) plots
2614if NbDim<=1
2615    set(handles.Objects,'Visible','off')
2616    set(handles.ListObject_1_title,'Visible','off')
2617    set(handles.ListObject_1,'Visible','off')
2618    [PlotType,PlotParamOut]=plot_field(UvData.Field,handles.axes3,read_GUI(handles.uvmat));
2619    write_plot_param(handles,PlotParamOut) %update the auto plot parameters
2620%     if isfield(Field,'Mesh')&&~isempty(Field.Mesh)
2621%         ObjectData.Mesh=Field.Mesh; % gives an estimated mesh size (useful for mouse action on the plot)
2622%     end
2623   
2624%% 2D or 3D fields are generally projected
[387]2625else
[434]2626    set(handles.Objects,'Visible','on')
2627    set(handles.ListObject_1_title,'Visible','on')
2628    set(handles.ListObject_1,'Visible','on')
2629   
2630    %% Plot the projections on the selected  projection objects
2631    % main projection object (uvmat display)
2632    list_object=get(handles.ListObject_1,'String');
2633    if isequal(list_object,{''})%refresh list of objects if the menu is empty
2634        UvData.Object={[]};
2635        set(handles.ListObject_1,'Value',1)
[387]2636    end
[434]2637    IndexObj(1)=get(handles.ListObject_1,'Value');%selected projection object for main view
2638    if IndexObj(1)> numel(UvData.Object)
2639        IndexObj(1)=1;%select the first object if the selected one does not exist
2640        set(handles.ListObject_1,'Value',1)
[387]2641    end
[434]2642    IndexObj(2)=get(handles.ListObject,'Value');%selected projection object for main view
2643    if isequal(IndexObj(2),IndexObj(1))
2644        IndexObj(2)=[];
2645    end
2646    plot_handles{1}=handles;
2647    if isfield(UvData,'plotaxes')%case of movies
2648        haxes(1)=UvData.plotaxes;
2649    else
2650        haxes(1)=handles.axes3;
2651    end
2652    PlotParam{1}=read_GUI(handles.uvmat);
2653    %default settings if vectors not visible
2654    if ~isfield(PlotParam{1},'Vectors')
2655        PlotParam{1}.Vectors.MaxVec=1;
2656        PlotParam{1}.Vectors.MinVec=0;
2657        PlotParam{1}.Vectors.CheckFixVecColor=1;
2658        PlotParam{1}.Vectors.ColCode1=0.33;
2659        PlotParam{1}.Vectors.ColCode2=0.66;
2660        PlotParam{1}.Vectors.ColorScalar={'ima_cor'};
2661        PlotParam{1}.Vectors.ColorCode= {'rgb'};
2662    end
2663    PosColorbar{1}=UvData.OpenParam.PosColorbar;%prescribe the colorbar position on the uvmat interface
2664   
2665    %% second projection object (view_field display)
2666    if length( IndexObj)>=2
2667        view_field_handle=findobj(allchild(0),'tag','view_field');%handles of the view_field GUI
2668        if ~isempty(view_field_handle)
2669            plot_handles{2}=guidata(view_field_handle);
2670            haxes(2)=plot_handles{2}.axes3;
2671            PlotParam{2}=read_GUI(handles.uvmat);%read plotting parameters on the uvmat interface
2672            PosColorbar{2}='*'; %TODO: deal with colorbar position on view_field
[421]2673        end
[387]2674    end
[434]2675   
2676    %% loop on the projection objects: one or two
2677   
2678    for imap=1:numel(IndexObj)
2679        iobj=IndexObj(imap);
2680        %      if imap==2 || check_proj==0  % field not yet projected) && ~isfield(UvData.Object{iobj},'Type')% case with no projection (only for the first empty object)
2681        % %          [ObjectData,errormsg]=calc_field(UvData.Field.FieldList,UvData.Field);
2682        % %      else
2683        [ObjectData,errormsg]=proj_field(UvData.Field,UvData.Object{iobj});% project field on the object
2684        %      end
2685        if ~isempty(errormsg)
2686            return
[387]2687        end
[434]2688        if testnewseries
2689            PlotParam{imap}.Scalar.CheckBW=[]; %B/W option depends on the input field (image or scalar)
2690            if isfield(ObjectData,'CoordUnit')
2691                PlotParam{imap}.Coordinates.CheckFixAspectRatio=1;% set x and y scaling equal if CoordUnit is defined (common unit for x and y)
2692                PlotParam{imap}.Coordinates.AspectRatio=1; %set aspect ratio to 1
[387]2693            end
[434]2694        end
2695        %use of mask (TODO: check)
2696        if isfield(ObjectData,'NbDim') && isequal(ObjectData.NbDim,2) && isfield(ObjectData,'Mask') && isfield(ObjectData,'A')
2697            flag_mask=double(ObjectData.Mask>200);%=0 for masked regions
2698            AX=ObjectData.AX;%x coordiantes for the scalar field
2699            AY=ObjectData.AY;%y coordinates for the scalar field
2700            MaskX=ObjectData.MaskX;%x coordiantes for the mask
2701            MaskY=ObjectData.MaskY;%y coordiantes for the mask
2702            if ~isequal(MaskX,AX)||~isequal(MaskY,AY)
2703                nxy=size(flag_mask);
2704                sizpx=(ObjectData.MaskX(end)-ObjectData.MaskX(1))/(nxy(2)-1);%size of a mask pixel
2705                sizpy=(ObjectData.MaskY(1)-ObjectData.MaskY(end))/(nxy(1)-1);
2706                x_mask=ObjectData.MaskX(1):sizpx:ObjectData.MaskX(end); % pixel x coordinates for image display
2707                y_mask=ObjectData.MaskY(1):-sizpy:ObjectData.MaskY(end);% pixel x coordinates for image display
2708                %project on the positions of the scalar
2709                npxy=size(ObjectData.A);
2710                dxy(1)=(ObjectData.AY(end)-ObjectData.AY(1))/(npxy(1)-1);%grid mesh in y
2711                dxy(2)=(ObjectData.AX(end)-ObjectData.AX(1))/(npxy(2)-1);%grid mesh in x
2712                xi=ObjectData.AX(1):dxy(2):ObjectData.AX(end);
2713                yi=ObjectData.AY(1):dxy(1):ObjectData.AY(end);
2714                [XI,YI]=meshgrid(xi,yi);% creates the matrix of regular coordinates
2715                flag_mask = interp2(x_mask,y_mask,flag_mask,XI,YI);
2716            end
2717            AClass=class(ObjectData.A);
2718            ObjectData.A=flag_mask.*double(ObjectData.A);
2719            ObjectData.A=feval(AClass,ObjectData.A);
[387]2720            ind_off=[];
[434]2721            if isfield(ObjectData,'ListVarName')
2722                for ilist=1:length(ObjectData.ListVarName)
2723                    if isequal(ObjectData.ListVarName{ilist},'Mask')||isequal(ObjectData.ListVarName{ilist},'MaskX')||isequal(ObjectData.ListVarName{ilist},'MaskY')
2724                        ind_off=[ind_off ilist];
2725                    end
[387]2726                end
[434]2727                ObjectData.ListVarName(ind_off)=[];
2728                VarDimIndex(ind_off)=[];
2729                ind_off=[];
2730                for ilist=1:length(ListDimName)
2731                    if isequal(ListDimName{ilist},'MaskX') || isequal(ListDimName{ilist},'MaskY')
2732                        ind_off=[ind_off ilist];
2733                    end
2734                end
2735                ListDimName(ind_off)=[];
2736                DimValue(ind_off)=[];
[387]2737            end
2738        end
[434]2739        if ~isempty(ObjectData)
2740            PlotType='none'; %default
2741            if imap==2 && isempty(view_field_handle)
2742                view_field(ObjectData)
2743            else
2744                [PlotType,PlotParamOut]=plot_field(ObjectData,haxes(imap),PlotParam{imap},PosColorbar{imap});
2745                write_plot_param(plot_handles{imap},PlotParamOut) %update the auto plot parameters
2746                if isfield(Field,'Mesh')&&~isempty(Field.Mesh)
2747                    ObjectData.Mesh=Field.Mesh; % gives an estimated mesh size (useful for mouse action on the plot)
2748                end
[387]2749            end
[434]2750            if isequal(PlotType,'none')
2751                hget_field=findobj(allchild(0),'name','get_field');
2752                if isempty(hget_field)
[450]2753                    get_field(FileName)% the projected field cannot be automatically plotted: use get_field to specify the variablesdelete(hget_field)
[434]2754                end
2755                errormsg='The field defined by get_field cannot be plotted';
2756                return
[387]2757            end
2758        end
2759    end
[434]2760   
2761    %% update the mask
2762    if isequal(get(handles.CheckMask,'Value'),1)%if the mask option is on
2763        update_mask(handles,num_i1,num_i2);
2764    end
2765   
2766    %% prepare the menus of histograms and plot them (histogram of the whole volume in 3D case)
2767    menu_histo=(UvData.Field.ListVarName)';%list of field variables to be displayed for the menu of histogram display
2768    ind_skip=[];
2769    % nb_histo=1;
2770    Ustring='';
2771    Vstring='';
2772    % suppress coordinates from the histogram menu
2773    for ivar=1:numel(menu_histo)%l loop on field variables:
2774        if isfield(UvData.Field,'VarAttribute') && numel(UvData.Field.VarAttribute)>=ivar && isfield(UvData.Field.VarAttribute{ivar},'Role')
2775            Role=UvData.Field.VarAttribute{ivar}.Role;
2776            switch Role
2777                case {'coord_x','coord_y','coord_z','dimvar'}
2778                    ind_skip=[ind_skip ivar];
2779                case {'vector_x'}
2780                    Ustring=UvData.Field.ListVarName{ivar};
2781                    ind_skip=[ind_skip ivar];
2782                case {'vector_y'}
2783                    Vstring=UvData.Field.ListVarName{ivar};
2784                    ind_skip=[ind_skip ivar];
2785            end
[387]2786        end
[434]2787        DimCell=UvData.Field.VarDimName{ivar};
2788        DimName='';
2789        if ischar(DimCell)
2790            DimName=DimCell;
2791        elseif iscell(DimCell)&& numel(DimCell)==1
2792            DimName=DimCell{1};
2793        end
2794        if strcmp(DimName,menu_histo{ivar})
2795            ind_skip=[ind_skip ivar];
2796        end
[387]2797    end
[434]2798    menu_histo(ind_skip)=[];% remove skipped items
2799    if ~isempty(Ustring)
2800        menu_histo=[{[Ustring ',' Vstring]};menu_histo];% add U, V at the beginning if they exist
[387]2801    end
[434]2802   
2803    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2804    % display menus and plot histograms
2805    test_v=0;
2806    if ~isempty(menu_histo)
2807        set(handles.histo1_menu,'Value',1)
2808        set(handles.histo1_menu,'String',menu_histo)
2809        histo1_menu_Callback(handles.histo1_menu, [], handles)% plot first histogram
[387]2810    end
2811end
2812
[424]2813%------------------------------------------------------------------------
2814function histo1_menu_Callback(hObject, eventdata, handles)
2815%--------------------------------------------
2816%plot first histo
2817%huvmat=get(handles.histo1_menu,'parent');
2818histo_menu=get(handles.histo1_menu,'String');
2819histo_value=get(handles.histo1_menu,'Value');
2820FieldName=histo_menu{histo_value};
2821% update_histo(handles.histo_u,handles.uvmat,FieldName)
2822%
2823% %------------------------------------------------------------------------
2824% function histo2_menu_Callback(hObject, eventdata, handles)
2825% %------------------------------------------------------------------------
2826% %plot second histo
2827% %huvmat=get(handles.histo2_menu,'parent');
2828% histo_menu=get(handles.histo2_menu,'String');
2829% histo_value=get(handles.histo2_menu,'Value');
2830% FieldName=histo_menu{histo_value};
2831% update_histo(handles.histo_v,handles.uvmat,FieldName)
2832%
2833% %------------------------------------------------------------------------
2834% %read the field .Fieldname stored in UvData and plot its histogram
2835% function update_histo(haxes,huvmat,FieldName)
2836%------------------------------------------------------------------------
2837UvData=get(handles.uvmat,'UserData');
2838Field=UvData.Field;
2839r=regexp(FieldName,'(?<var1>.*)(?<sep>,)(?<var2>.*)','names');
2840FieldName_2='';
2841if ~isempty(r)
2842    FieldName=r.var1;
2843    FieldName_2=r.var2;
2844end
2845if ~isfield(UvData.Field,FieldName)
2846    msgbox_uvmat('ERROR',['no field  ' FieldName ' for histogram'])
2847    return
2848end
2849FieldHisto=Field.(FieldName);
2850if isfield(Field,'FF') && ~isempty(Field.FF) && isequal(size(Field.FF),size(FieldHisto))
2851    indsel=find(Field.FF==0);%find values marked as false
2852    if ~isempty(indsel)
2853        FieldHisto=FieldHisto(indsel);
2854        if ~isempty(FieldName_2)
2855            FieldHisto(:,:,2)=Field.(FieldName_2)(indsel);
2856        end
[387]2857    end
2858end
[424]2859if isempty(Field)
2860    msgbox_uvmat('ERROR',['empty field ' FieldName])
2861else
2862    nxy=size(FieldHisto);
2863    Amin=double(min(min(min(FieldHisto))));%min of field value
2864    Amax=double(max(max(max(FieldHisto))));%max of field value
2865    if isequal(Amin,Amax)
2866        cla(handles.histo_u)
2867    else
2868        Histo.ListVarName={FieldName,'histo'};
2869        if isfield(Field,'NbDim') && isequal(Field.NbDim,3)
2870            Histo.VarDimName={FieldName,FieldName}; %dimensions for the histogram
2871        else
2872            if numel(nxy)==2
2873                Histo.VarDimName={FieldName,FieldName}; %dimensions for the histogram
2874            else
2875                Histo.VarDimName={FieldName,{FieldName,'component'}}; %dimensions for the histogram
2876            end
2877        end
2878        %unit
2879        units=[]; %default
2880        for ivar=1:numel(Field.ListVarName)
2881            if strcmp(Field.ListVarName{ivar},FieldName)
2882                if isfield(Field,'VarAttribute') && numel(Field.VarAttribute)>=ivar && isfield(Field.VarAttribute{ivar},'units')
2883                    units=Field.VarAttribute{ivar}.units;
2884                    break
2885                end
2886            end
2887        end
2888        if ~isempty(units)
2889            Histo.VarAttribute{1}.units=units;
2890        end
2891        eval(['Histo.' FieldName '=linspace(Amin,Amax,50);'])%absissa values for histo
2892        if isfield(Field,'NbDim') && isequal(Field.NbDim,3)
2893            C=reshape(double(FieldHisto),1,[]);% reshape in a vector
2894            Histo.histo(:,1)=hist(C, Histo.(FieldName));  %calculate histogram
2895        else
2896            for col=1:size(FieldHisto,3)
2897                B=FieldHisto(:,:,col);
2898                C=reshape(double(B),1,nxy(1)*nxy(2));% reshape in a vector
2899                Histo.histo(:,col)=hist(C, Histo.(FieldName));  %calculate histogram
2900            end
2901        end
2902        plot_field(Histo,handles.histo_u);
[426]2903        hlegend=legend;
2904        if isempty(FieldName_2)
2905        set(hlegend,'String',FieldName)
2906        else
2907            set(hlegend,'String',{FieldName;FieldName_2})
2908        end
2909%         hh=get(handles.histo_u,'children');
2910%         get(hh(1))
2911%         get(hh(2))
[424]2912    end
[387]2913end
2914
2915%-------------------------------------------------------------------
2916% --- translate coordinate to matrix index
2917%-------------------------------------------------------------------
2918function [indx,indy]=pos2ind(x0,rangx0,nxy)
2919indx=1+round((nxy(2)-1)*(x0-rangx0(1))/(rangx0(2)-rangx0(1)));% index x of pixel 
2920indy=1+round((nxy(1)-1)*(y12-rangy0(1))/(rangy0(2)-rangy0(1)));% index y of pixel
2921
[428]2922
[387]2923%-------------------------------------------------------------------
[428]2924% --- Executes on button press in 'CheckZoom'.
2925%-------------------------------------------------------------------
2926function CheckZoom_Callback(hObject, eventdata, handles)
2927
2928if (get(handles.CheckZoom,'Value') == 1);
2929    set(handles.CheckZoom,'BackgroundColor',[1 1 0])
2930    set(handles.CheckFixLimits,'Value',1)% propose by default fixed limits for the plotting axes
2931    set(handles.CheckFixLimits,'BackgroundColor',[1 1 0])
2932else
2933    set(handles.CheckZoom,'BackgroundColor',[0.7 0.7 0.7])
2934end
2935
2936%-------------------------------------------------------------------
[387]2937% --- Executes on button press in 'CheckFixLimits'.
2938%-------------------------------------------------------------------
2939function CheckFixLimits_Callback(hObject, eventdata, handles)
2940test=get(handles.CheckFixLimits,'Value');
2941if test
2942    set(handles.CheckFixLimits,'BackgroundColor',[1 1 0])
2943else
2944    set(handles.CheckFixLimits,'BackgroundColor',[0.7 0.7 0.7])
2945    update_plot(handles);
2946end
2947
2948%-------------------------------------------------------------------
[428]2949% --- Executes on button press in CheckFixAspectRatio.
2950function CheckFixAspectRatio_Callback(hObject, eventdata, handles)
2951%-------------------------------------------------------------------
2952if get(handles.CheckFixAspectRatio,'Value')
2953    set(handles.CheckFixAspectRatio,'BackgroundColor',[1 1 0])
[387]2954    update_plot(handles);
2955else
[428]2956    set(handles.CheckFixAspectRatio,'BackgroundColor',[0.7 0.7 0.7])
[387]2957    update_plot(handles);
2958end
2959
2960%-------------------------------------------------------------------
[428]2961function num_AspectRatio_Callback(hObject, eventdata, handles)
[387]2962%-------------------------------------------------------------------
[428]2963set(handles.CheckFixAspectRatio,'Value',1)% select the fixed aspect ratio button
2964set(handles.CheckFixAspectRatio,'BackgroundColor',[1 1 0])% mark in yellow
2965update_plot(handles);
[387]2966%-------------------------------------------------------------------
2967
[428]2968%-------------------------------------------------------------------
[387]2969
[428]2970
2971
[387]2972%-------------------------------------------------------------------
2973%----Executes on button press in 'record': records the current flags of manual correction.
2974%-------------------------------------------------------------------
2975function record_Callback(hObject, eventdata, handles)
2976% [filebase,num_i1,num_j1,num_i2,num_j2,Ext,NomType,SubDir]=read_input_file(handles);
2977[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
[450]2978FileName=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
2979%FileName=read_file_boxes(handles);
2980[erread,message]=fileattrib(FileName);
[387]2981if ~isempty(message) && ~isequal(message.UserWrite,1)
[450]2982     msgbox_uvmat('ERROR',['no writting access to ' FileName])
[387]2983     return
2984end
2985test_civ2=isequal(get(handles.civ2,'BackgroundColor'),[1 1 0]);
2986test_civ1=isequal(get(handles.VelType,'BackgroundColor'),[1 1 0]);
2987if ~test_civ2 && ~test_civ1
2988    msgbox_uvmat('ERROR','manual correction only possible for CIV1 or CIV2 velocity fields')
2989end
2990if test_civ2
2991    nbname='nb_vectors2';
2992   flagname='vec2_FixFlag';
2993   attrname='fix2';
2994end
2995if test_civ1
2996    nbname='nb_vectors';
2997   flagname='vec_FixFlag';
2998   attrname='fix';
2999end
3000%write fix flags in the netcdf file
3001UvData=get(handles.uvmat,'UserData');
3002hhh=which('netcdf.open');% look for built-in matlab netcdf library
3003if ~isequal(hhh,'')% case of new builtin Matlab netcdf library
[450]3004    nc=netcdf.open(FileName,'NC_WRITE');
[387]3005    netcdf.reDef(nc);
3006    netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),attrname,1);
3007    dimid = netcdf.inqDimID(nc,nbname);
3008    try
3009        varid = netcdf.inqVarID(nc,flagname);% look for already existing fixflag variable
3010    catch
3011        varid=netcdf.defVar(nc,flagname,'double',dimid);%create fixflag variable if it does not exist
3012    end
3013    netcdf.endDef(nc);
3014    netcdf.putVar(nc,varid,UvData.axes3.FF);
3015    netcdf.close(nc); 
3016else %old netcdf library
[450]3017    netcdf_toolbox(FileName,AxeData,attrname,nbname,flagname)
[387]3018end
3019
3020%-------------------------------------------------------------------
3021%----Correct the netcdf file, using toolbox (old versions of Matlab).
3022%-------------------------------------------------------------------
[450]3023function netcdf_toolbox(FileName,AxeData,attrname,nbname,flagname)
3024nc=netcdf(FileName,'write'); %open netcdf file
[387]3025result=redef(nc);
3026eval(['nc.' attrname '=1;']);
3027theDim=nc(nbname) ;% get the number of velocity vectors
3028nb_vectors=size(theDim);
3029var_FixFlag=ncvar(flagname,nc);% var_FixFlag will be written as the netcdf variable vec_FixFlag
3030var_FixFlag(1:nb_vectors)=AxeData.FF;%
3031fin=close(nc);
3032
[428]3033%-------------------------------------------------------------------
[387]3034% --- Executes on button press in SubField
3035function SubField_Callback(hObject, eventdata, handles)
[428]3036%-------------------------------------------------------------------
[387]3037UvData=get(handles.uvmat,'UserData');
3038if get(handles.SubField,'Value')==0% if the subfield button is desactivated   
3039    set(handles.RootPath_1,'String','')
3040    set(handles.RootFile_1,'String','')
3041    set(handles.SubDir_1,'String','');
3042    set(handles.FileIndex_1,'String','');
3043    set(handles.FileExt_1,'String','');
3044    set(handles.RootPath_1,'Visible','off')
3045    set(handles.RootFile_1,'Visible','off')
3046    set(handles.SubDir_1,'Visible','off');
3047    set(handles.NomType_1,'Visible','off');
3048    set(handles.abs_time_1,'Visible','off')
3049    set(handles.FileIndex_1,'Visible','off');
3050    set(handles.FileExt_1,'Visible','off');
3051    set(handles.Fields_1,'Value',1);%set to blank state
3052    set(handles.VelType_1,'Value',1);%set to blank state
[428]3053    set(handles.num_Opacity,'String','')% desactivate opacity setting
[387]3054    if ~strcmp(get(handles.VelType,'Visible'),'on')
3055        set(handles.VelType_1,'Visible','off')
3056    end
3057    if isfield(UvData,'XmlData_1')
3058        UvData=rmfield(UvData,'XmlData_1');
3059    end
3060    set(handles.uvmat,'UserData',UvData);
3061    run0_Callback(hObject, eventdata, handles); %run
3062else
3063    MenuBrowse_1_Callback(hObject, eventdata, handles)
3064end
3065
3066%------------------------------------------------------------------------
3067% --- read the data displayed for the input rootfile windows (new): TODO use read_GUI
3068
3069function [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles)
3070%------------------------------------------------------------------------
3071InputFile=read_GUI(handles.InputFile);
3072RootPath=InputFile.RootPath;
3073SubDir=regexprep(InputFile.SubDir,'/|\','');
3074RootFile=regexprep(InputFile.RootFile,'/|\','');
3075FileIndices=InputFile.FileIndex;
3076FileExt=InputFile.FileExt;
3077
3078
3079%------------------------------------------------------------------------
3080% ---- read the data displayed for the second input rootfile windows
3081function [RootPath_1,SubDir_1,RootFile_1,FileIndex_1,FileExt_1,NomType_1]=read_file_boxes_1(handles)
3082%------------------------------------------------------------------------
3083RootPath_1=get(handles.RootPath_1,'String'); % read the data from the file1_input window
3084if isequal(get(handles.RootPath_1,'Visible'),'off') || isequal(RootPath_1,'"')
3085    RootPath_1=get(handles.RootPath,'String');
3086end;
3087SubDir_1=get(handles.SubDir_1,'String');
3088if isequal(get(handles.SubDir_1,'Visible'),'off')|| isequal(SubDir_1,'"')
3089    SubDir_1=get(handles.SubDir,'String');
3090end
3091SubDir_1=regexprep(SubDir_1,'\<[\\/]|[\\/]\>','');%suppress possible / or \ separator at the beginning or the end of the string
3092RootFile_1=get(handles.RootFile_1,'String');
3093if isequal(get(handles.RootFile_1,'Visible'),'off') || isequal(RootFile_1,'"')
3094    RootFile_1=get(handles.RootFile,'String');
3095end
3096RootFile_1=regexprep(RootFile_1,'\<[\\/]|[\\/]\>','');%suppress possible / or \ separator at the beginning or the end of the string
3097FileIndex_1=get(handles.FileIndex_1,'String');
3098if isequal(get(handles.FileIndex_1,'Visible'),'off')|| isequal(FileIndex_1,'"')
3099    FileIndex_1=get(handles.FileIndex,'String');
3100end
3101FileExt_1=get(handles.FileExt_1,'String');
3102if isequal(get(handles.FileExt_1,'Visible'),'off') || isequal(FileExt_1,'"')
3103    FileExt_1=get(handles.FileExt,'String');%read FileExt by default
3104end
3105NomType_1=get(handles.NomType_1,'String');
3106if isequal(get(handles.NomType_1,'Visible'),'off') || isequal(NomType_1,'"')
3107    NomType_1=get(handles.NomType,'String');%read FileExt by default
3108end
3109%------------------------------------------------------------------------
3110% --- Executes on menu selection Fields
3111function Fields_Callback(hObject, eventdata, handles)
3112%------------------------------------------------------------------------
3113list_fields=get(handles.Fields,'String');% list menu fields
3114index_fields=get(handles.Fields,'Value');% selected string index
3115field= list_fields{index_fields(1)}; % selected string
3116if isequal(field,'get_field...')
3117    set(handles.FixVelType,'visible','off')
3118    set(handles.VelType,'visible','off')
3119    set(handles.VelType_1,'visible','off')
3120    [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
[450]3121    FileName=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
3122    %FileName=read_file_boxes(handles);
[387]3123    hget_field=findobj(allchild(0),'name','get_field');
3124    if ~isempty(hget_field)
3125        delete(hget_field)
3126    end
[450]3127    hget_field=get_field(FileName);
[387]3128    set(hget_field,'Name','get_field')
3129    hhget_field=guidata(hget_field);
3130    set(hhget_field.list_fig,'Value',1)
3131    set(hhget_field.list_fig,'String',{'uvmat'})
3132    set(handles.transform_fct,'Value',1)% no transform by default
3133    set(handles.path_transform,'String','')
3134    return %no action
3135end
3136list_fields=get(handles.Fields_1,'String');% list menu fields
3137index_fields=get(handles.Fields_1,'Value');% selected string index
3138field_1= list_fields{index_fields(1)}; % selected string
3139UvData=get(handles.uvmat,'UserData');
3140
3141%read the rootfile input display
3142[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
3143FileName=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
3144[tild,tild,tild,i1,i2,j1,j2,tild,NomType]=fileparts_uvmat(['xxx' get(handles.FileIndex,'String') FileExt]);
3145if isequal(field,'image')
[494]3146    if  isfield(UvData.Field,'Civ2_ImageA')%get the corresponding input image in the netcdf file
3147        imagename=UvData.Field.Civ2_ImageA;
3148    elseif isfield(UvData.Field,'Civ1_ImageA')%
3149        imagename=UvData.Field.Civ1_ImageA;
3150    else
3151        SubDirBase=regexprep(SubDir,'\..*','');%take the root part of SubDir, before the first dot '.'
3152        imagename=fullfile_uvmat(RootPath,SubDirBase,RootFile,'.png',NomType,i1,[],j1,[]);
3153    end
[387]3154    if ~exist(imagename,'file')
3155        [FileName,PathName] = uigetfile( ...
3156            {'*.png;*.jpg;*.tif;*.avi;*.AVI;*.vol', ' (*.png, .tif, *.avi,*.vol)';
3157            '*.jpg',' jpeg image files'; ...
3158            '*.png','.png image files'; ...
3159            '*.tif','.tif image files'; ...
3160            '*.avi;*.AVI','.avi movie files'; ...
3161            '*.vol','.volume images (png)'; ...
3162            '*.*',  'All Files (*.*)'}, ...
3163            'Pick an image',imagename);   
3164        imagename=[PathName FileName];
3165    end
3166     % display the selected field and related information
[406]3167    display_file_name(handles,imagename)%display the image
[387]3168    return
3169else
3170    ext=get(handles.FileExt,'String');
3171    if ~isequal(ext,'.nc') %find the new NomType if the previous display was not already a netcdf file
3172        [FileName,PathName] = uigetfile( ...
3173            {'*.nc', ' (*.nc)';
3174            '*.nc',' netcdf files'; ...
3175            '*.*',  'All Files (*.*)'}, ...
3176            'Pick a netcdf file',FileBase);
[450]3177        FullFileName=[PathName FileName];
[387]3178        % display the selected field and related information
[450]3179        display_file_name( handles,FullFileName)
[387]3180        return
3181    end
3182end
3183indices=fullfile_uvmat('','','','',NomType,i1,i2,j1,j2);
3184set(handles.FileIndex,'String',indices)
3185% set(handles.NomType,'String',NomType)
3186
3187%common to Fields_1_Callback
3188if isequal(field,'image')||isequal(field_1,'image')
3189    set(handles.TitleNpx,'Visible','on')% visible npx,pxcm... buttons
3190    set(handles.TitleNpy,'Visible','on')
3191    set(handles.num_Npx,'Visible','on')
3192    set(handles.num_Npy,'Visible','on')
3193else
3194    set(handles.TitleNpx,'Visible','off')% visible npx,pxcm... buttons
3195    set(handles.TitleNpy,'Visible','off')
3196    set(handles.num_Npx,'Visible','off')
3197    set(handles.num_Npy,'Visible','off')
3198end
3199if ~(isfield(UvData,'NewSeries')&&isequal(UvData.NewSeries,1))
3200    run0_Callback(hObject, eventdata, handles)
3201end
3202
3203%---------------------------------------------------
3204% --- Executes on menu selection Fields
3205function Fields_1_Callback(hObject, eventdata, handles)
3206%-------------------------------------------------
3207%% read input data
3208check_new=~get(handles.SubField,'Value'); %check_new=1 if a second field was not previously entered
3209UvData=get(handles.uvmat,'UserData');
3210if check_new && isfield(UvData,'XmlData')
3211    UvData.XmlData{2}=UvData.XmlData{1};
3212end
[389]3213if isfield(UvData,'Field_1')
3214    UvData=rmfield(UvData,'Field_1');% remove the stored second field (a new one needs to be read)
3215end
[450]3216UvData.FileName_1='';% desactivate the use of a constant second file
[387]3217list_fields=get(handles.Fields,'String');% list menu fields
[405]3218field= list_fields{get(handles.Fields,'Value')}; % selected string
[387]3219list_fields=get(handles.Fields_1,'String');% list menu fields
[405]3220field_1= list_fields{get(handles.Fields_1,'Value')}; % selected string for the second field
3221if isempty(field_1)%||(numel(UvData.FileType)>=2 && strcmp(UvData.FileType{2},'image'))
[387]3222    set(handles.SubField,'Value',0)
3223    SubField_Callback(hObject, eventdata, handles)
[428]3224    return
[405]3225else
3226    set(handles.SubField,'Value',1)%state that a second field is now entered
[387]3227end
3228
3229%% read the rootfile input display
[405]3230[RootPath_1,SubDir_1,RootFile_1,FileIndex_1,FileExt_1]=read_file_boxes_1(handles);
[450]3231FileName_1=[fullfile(RootPath_1,SubDir_1,RootFile_1) FileIndex_1 FileExt_1];
[387]3232[tild,tild,tild,i1,i2,j1,j2]=fileparts_uvmat(get(handles.FileIndex,'String'));
[405]3233% set(handles.FileIndex_1,'Visible','on')
3234% set(handles.FileExt_1,'Visible','on')
[387]3235switch field_1
3236    case 'get_field...'
3237        set_veltype_display(0) % no veltype display
3238        hget_field=findobj(allchild(0),'name','get_field_1');
3239        if ~isempty(hget_field)
3240            delete(hget_field)
3241        end
[450]3242        hget_field=get_field(FileName_1);
[387]3243        set(hget_field,'name','get_field_1')
3244        hhget_field=guidata(hget_field);
3245        set(hhget_field.list_fig,'Value',1)
3246        set(hhget_field.list_fig,'String',{'uvmat'})
3247        set(handles.transform_fct,'Value',1)% no transform by default
3248        set(handles.path_transform,'String','')
[428]3249        if check_new
3250            UvData.FileType{2}=UvData.FileType{1};
3251            set(handles.FileIndex_1,'String',get(handles.FileIndex,'String'))
3252%             set(handles.FileExt_1,'String',get(handles.FileExt,'String'))
3253              set(handles.uvmat,'UserData',UvData)
3254        end
[387]3255    case 'image'
[494]3256        % get the image name corresponding to the current netcdf name (no unique correspondance)
3257        if  isfield(UvData.Field,'Civ2_ImageA')%get the corresponding input image in the netcdf file
3258            imagename=UvData.Field.Civ2_ImageA;
3259        elseif isfield(UvData.Field,'Civ1_ImageA')%
3260            imagename=UvData.Field.Civ1_ImageA;
3261        else
3262            SubDirBase=regexprep(SubDir_1,'\..*','');%take the root part of SubDir, before the first dot '.'
3263            imagename=fullfile_uvmat(RootPath_1,SubDirBase,RootFile_1,'.png',get(handles.NomType,'String'),i1,[],j1);
3264        end
[405]3265        if ~exist(imagename,'file') % browse for images if it is not found
[387]3266            [FileName,PathName] = uigetfile( ...
3267                {'*.png;*.jpg;*.tif;*.avi;*.AVI;*.vol', ' (*.png, .tif, *.avi,*.vol)';
3268                '*.jpg',' jpeg image files'; ...
3269                '*.png','.png image files'; ...
3270                '*.tif','.tif image files'; ...
3271                '*.avi;*.AVI','.avi movie files'; ...
3272                '*.vol','.volume images (png)'; ...
3273                '*.*',  'All Files (*.*)'}, ...
3274                'Pick an image',imagename);
3275            imagename=[PathName FileName];
3276        end
[405]3277        if ~ischar(imagename)% quit if the browser has  been closed
3278            set(handles.SubField,'Value',0)
3279        else %valid browser input:  display the selected image
3280            set(handles.TitleNpx,'Visible','on')% visible npx,pxcm... buttons
3281            set(handles.TitleNpy,'Visible','on')
3282            set(handles.num_Npx,'Visible','on')
3283            set(handles.num_Npy,'Visible','on')
[406]3284            display_file_name(handles,imagename,2)%display the imag
[405]3285        end
[387]3286    otherwise
3287        if check_new
3288            UvData.FileType{2}=UvData.FileType{1};
3289            set(handles.FileIndex_1,'String',get(handles.FileIndex,'String'))
3290            set(handles.FileExt_1,'String',get(handles.FileExt,'String'))
3291        end
3292        if ~isequal(field,'image')
3293            set(handles.TitleNpx,'Visible','off')% visible npx,pxcm... buttons
3294            set(handles.TitleNpy,'Visible','off')
3295            set(handles.num_Npx,'Visible','off')
3296            set(handles.num_Npy,'Visible','off')
3297        end
3298        set(handles.uvmat,'UserData',UvData)
3299        if ~(isfield(UvData,'NewSeries')&&isequal(UvData.NewSeries,1))
3300            run0_Callback(hObject, eventdata, handles)
3301        end
3302end
3303
3304%------------------------------------------------------------------------
3305% --- set the visibility of relevant velocity type menus:
3306function menu=set_veltype_display(Civ,FileType)
3307%------------------------------------------------------------------------
3308if ~exist('FileType','var')
3309    FileType='civx';
3310end
3311switch FileType
3312    case 'civx'
[389]3313        menu={'civ1';'interp1';'filter1';'civ2';'interp2';'filter2'};
3314        if isequal(Civ,0)
3315            imax=0;
3316        elseif isequal(Civ,1) || isequal(Civ,2)
3317            imax=1;
3318        elseif isequal(Civ,3)
3319            imax=3;
3320        elseif isequal(Civ,4) || isequal(Civ,5)
3321            imax=4;
3322        elseif isequal(Civ,6) %patch2
3323            imax=6;
3324        end
[387]3325    case 'civdata'
[389]3326        menu={'civ1';'filter1';'civ2';'filter2'};
3327        if isequal(Civ,0)
3328            imax=0;
3329        elseif isequal(Civ,1) || isequal(Civ,2)
3330            imax=1;
3331        elseif isequal(Civ,3)
3332            imax=2;
3333        elseif isequal(Civ,4) || isequal(Civ,5)
3334            imax=3;
3335        elseif isequal(Civ,6) %patch2
3336            imax=4;
3337        end
[387]3338end
3339menu=menu(1:imax);
3340
3341%------------------------------------------------------------------------
[402]3342% --- Executes on button press in FixVelType.
3343function FixVelType_Callback(hObject, eventdata, handles)
3344%------------------------------------------------------------------------
[405]3345% refresh the current plot if the fixed  veltype is unselected
3346if ~get(handles.FixVelType,'Value')
[402]3347    run0_Callback(hObject, eventdata, handles)
3348end
3349
3350%------------------------------------------------------------------------
[387]3351% --- Executes on button press in VelType.
3352function VelType_Callback(hObject, eventdata, handles)
3353%------------------------------------------------------------------------
3354set(handles.FixVelType,'Value',1)
3355run0_Callback(hObject, eventdata, handles)
3356
3357%------------------------------------------------------------------------
[402]3358% --- Executes on button press in VelType_1.
[387]3359function VelType_1_Callback(hObject, eventdata, handles)
3360%------------------------------------------------------------------------
3361set(handles.FixVelType,'Value',1)% the velocity type is now imposed by the GUI (not automatic)
[389]3362UvData=get(handles.uvmat,'UserData');
[450]3363%refresh field with a second FileName=first file name
[387]3364set(handles.run0,'BackgroundColor',[1 1 0])%paint the command button in yellow
3365drawnow   
3366InputFile=read_GUI(handles.InputFile);
3367[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
[450]3368FileName=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
[405]3369
[389]3370if isempty(InputFile.VelType_1)
[450]3371        FileName_1='';% we plot the current field without the second field
[387]3372        set(handles.SubField,'Value',0)
3373        SubField_Callback(hObject, eventdata, handles)
3374elseif get(handles.SubField,'Value')% if subfield is already 'on'
3375      [RootPath_1,SubDir_1,RootFile_1,FileIndices_1,FileExt_1]=read_file_boxes_1(handles);
[450]3376     FileName_1=[fullfile(RootPath_1,SubDir_1,RootFile_1) FileIndices_1 FileExt_1];
[387]3377else
[450]3378     FileName_1=FileName;% we compare two fields in the same file by default
[389]3379     UvData.FileType{2}=UvData.FileType{1};
[387]3380     set(handles.SubField,'Value',1)
3381end
[389]3382if isfield(UvData,'Field_1')
3383    UvData=rmfield(UvData,'Field_1');% removes the stored second field if it exists
3384end
[450]3385UvData.FileName_1='';% desactivate the use of a constant second file
[389]3386set(handles.uvmat,'UserData',UvData)
[387]3387num_i1=stra2num(get(handles.i1,'String'));
3388num_i2=stra2num(get(handles.i2,'String'));
3389num_j1=stra2num(get(handles.j1,'String'));
3390num_j2=stra2num(get(handles.j2,'String'));
3391
[450]3392errormsg=refresh_field(handles,FileName,FileName_1,num_i1,num_i2,num_j1,num_j2);
[387]3393
3394if ~isempty(errormsg)
3395    msgbox_uvmat('ERROR',errormsg);
3396else
3397    set(handles.i1,'BackgroundColor',[1 1 1])
3398    set(handles.i2,'BackgroundColor',[1 1 1])
3399    set(handles.j1,'BackgroundColor',[1 1 1])
3400    set(handles.j2,'BackgroundColor',[1 1 1])
3401    set(handles.FileIndex,'BackgroundColor',[1 1 1])
3402    set(handles.FileIndex_1,'BackgroundColor',[1 1 1])
3403end
3404set(handles.run0,'BackgroundColor',[1 0 0])
3405
3406%-----------------------------------------------
3407% --- reset civ buttons
3408function reset_vel_type(handles_civ0,handle1)
3409for ibutton=1:length(handles_civ0)
3410    set(handles_civ0(ibutton),'BackgroundColor',[0.831 0.816 0.784])
3411    set(handles_civ0(ibutton),'Value',0)
3412end
3413if exist('handle1','var')%handles of selected button
3414        set(handle1,'BackgroundColor',[1 1 0]) 
3415end
3416
3417%-------------------------------------------------------
3418% --- Executes on button press in MENUVOLUME.
3419%-------------------------------------------------------
3420function VOLUME_Callback(hObject, eventdata, handles)
3421%errordlg('command VOL not implemented yet')
3422if ishandle(handles.UVMAT_title)
3423    delete(handles.UVMAT_title)
3424end
3425UvData=get(handles.uvmat,'UserData');%read UvData properties stored on the uvmat interface
3426if isequal(get(handles.VOLUME,'Value'),1)
3427    set(handles.CheckZoom,'Value',0)
3428    set(handles.CheckZoom,'BackgroundColor',[0.7 0.7 0.7])
3429    set(handles.edit_vect,'Value',0)
3430    edit_vect_Callback(hObject, eventdata, handles)
3431    set(handles.edit_object,'Value',0)
3432    set(handles.edit_object,'BackgroundColor',[0.7 0.7 0.7])
3433%     set(handles.cal,'Value',0)
3434%     set(handles.cal,'BackgroundColor',[0 1 0])
3435    set(handles.edit_vect,'Value',0)
3436    edit_vect_Callback(hObject, eventdata, handles)
3437    %initiate set_object GUI
3438    data.Name='VOLUME';
3439    if isfield(UvData,'CoordType')
3440        data.CoordType=UvData.CoordType;
3441    end
[404]3442    if isfield(UvData.Field,'Mesh')&~isempty(UvData.Field.Mesh)
3443        data.RangeX=[UvData.Field.XMin UvData.Field.XMax];
3444        data.RangeY=[UvData.Field.YMin UvData.Field.YMax];
3445        data.DX=UvData.Field.Mesh;
3446        data.DY=UvData.Field.Mesh;
[387]3447    elseif isfield(UvData.Field,'AX')&isfield(UvData.Field,'AY')& isfield(UvData.Field,'A')%only image
3448        np=size(UvData.Field.A);
3449        meshx=(UvData.Field.AX(end)-UvData.Field.AX(1))/np(2);
3450        meshy=abs(UvData.Field.AY(end)-UvData.Field.AY(1))/np(1);
3451        data.RangeY=max(meshx,meshy);
3452        data.RangeX=max(meshx,meshy);
3453        data.DX=max(meshx,meshy);
3454    end
3455    data.ParentButton=handles.VOLUME;
3456    PlotHandles=get_plot_handles(handles);%get the handles of the interface elements setting the plotting parameters
3457    [hset_object,UvData.sethandles]=set_object(data,PlotHandles);% call the set_object interface with action on haxes,
3458                                                      % associate the set_object interface handle to the plotting axes
3459    if isfield(UvData.OpenParam,'SetObjectOrigin')                                               
3460    pos_uvmat=get(handles.uvmat,'Position');
3461    pos_set_object(1:2)=UvData.OpenParam.SetObjectOrigin + pos_uvmat(1:2);
3462    pos_set_object(3:4)=UvData.OpenParam.SetObjectSize .* pos_uvmat(3:4); 
3463    set(hset_object,'Position',pos_set_object)
3464    end
3465    UvData.MouseAction='create_object';
3466else
3467    set(handles.VOLUME,'BackgroundColor',[0 1 0])
3468    UvData.MouseAction='none';
3469end
3470set(handles.uvmat,'UserData',UvData)
3471
3472%-------------------------------------------------------
3473function edit_vect_Callback(hObject, eventdata, handles)
3474%-------------------------------------------------------
3475%
3476% UvData=get(handles.uvmat,'UserData');%read UvData properties stored on the uvmat interface
3477if isequal(get(handles.edit_vect,'Value'),1)
3478    test_civ2=isequal(get(handles.civ2,'BackgroundColor'),[1 1 0]);
3479    test_civ1=isequal(get(handles.VelType,'BackgroundColor'),[1 1 0]);
3480    if ~test_civ2 && ~test_civ1
3481        msgbox_uvmat('ERROR','manual correction only possible for CIV1 or CIV2 velocity fields')
3482    end
3483    set(handles.record,'Visible','on')
3484    set(handles.edit_vect,'BackgroundColor',[1 1 0])
3485    set(handles.edit_object,'Value',0)
3486    set(handles.CheckZoom,'Value',0)
3487    set(handles.CheckZoom,'BackgroundColor',[0.7 0.7 0.7])
3488%     set(handles.create,'Value',0)
3489%     set(handles.create,'BackgroundColor',[0 1 0])
3490    set(handles.edit_object,'BackgroundColor',[0.7 0.7 0.7])
3491    set(gcf,'Pointer','arrow')
3492%     UvData.MouseAction='edit_vect';
3493else
3494    set(handles.record,'Visible','off')
3495    set(handles.edit_vect,'BackgroundColor',[0.7 0.7 0.7])
3496%     UvData.MouseAction='none';
3497end
3498% set(handles.uvmat,'UserData',UvData)
3499
3500%----------------------------------------------
3501function save_mask_Callback(hObject, eventdata, handles)
3502%-----------------------------------------------------------------------
3503UvData=get(handles.uvmat,'UserData');
3504
3505flag=1;
3506npx=size(UvData.Field.A,2);
3507npy=size(UvData.Field.A,1);
3508xi=0.5:npx-0.5;
3509yi=0.5:npy-0.5;
3510[Xi,Yi]=meshgrid(xi,yi);
3511if isfield(UvData,'Object')
3512    for iobj=1:length(UvData.Object)
3513        ObjectData=UvData.Object{iobj};
3514        if isfield(ObjectData,'ProjMode') &&(isequal(ObjectData.ProjMode,'mask_inside')||isequal(ObjectData.ProjMode,'mask_outside'));
3515            flagobj=1;
3516            testphys=0; %coordinates in pixels by default
3517            if isfield(ObjectData,'CoordType') && isequal(ObjectData.CoordType,'phys')
3518                if isfield(UvData,'XmlData')&& isfield(UvData.XmlData{1},'GeometryCalib')
3519                    Calib=UvData.XmlData{1}.GeometryCalib;
3520                    testphys=1;
3521                end
3522            end
3523            if isfield(ObjectData,'Coord')& isfield(ObjectData,'Style')
3524                if isequal(ObjectData.Type,'polygon')
3525                    X=ObjectData.Coord(:,1);
3526                    Y=ObjectData.Coord(:,2);
3527                    if testphys
3528                        [X,Y]=px_XYZ(Calib,X,Y,0);% to generalise with 3D cases
3529                    end
3530                    flagobj=~inpolygon(Xi,Yi,X',Y');%=0 inside the polygon, 1 outside                 
3531                elseif isequal(ObjectData.Type,'ellipse')
3532                    if testphys
3533                        %[X,Y]=px_XYZ(Calib,X,Y,0);% TODO:create a polygon boundary and transform to phys
3534                    end
3535                    RangeX=max(ObjectData.RangeX);
3536                    RangeY=max(ObjectData.RangeY);
3537                    X2Max=RangeX*RangeX;
3538                    Y2Max=RangeY*RangeY;
3539                    distX=(Xi-ObjectData.Coord(1,1));
3540                    distY=(Yi-ObjectData.Coord(1,2));
3541                    flagobj=(distX.*distX/X2Max+distY.*distY/Y2Max)>1;
3542                elseif isequal(ObjectData.Type,'rectangle')
3543                    if testphys
3544                        %[X,Y]=px_XYZ(Calib,X,Y,0);% TODO:create a polygon boundary and transform to phys
3545                    end
3546                    distX=abs(Xi-ObjectData.Coord(1,1));
3547                    distY=abs(Yi-ObjectData.Coord(1,2));
3548                    flagobj=distX>max(ObjectData.RangeX) | distY>max(ObjectData.RangeY);
3549                end
3550                if isequal(ObjectData.ProjMode,'mask_outside')
3551                    flagobj=~flagobj;
3552                end
3553                flag=flag & flagobj;
3554            end
3555        end
3556    end
3557end
3558% flag=~flag;
3559%mask name
3560RootPath=get(handles.RootPath,'String');
3561RootFile=get(handles.RootFile,'String');
3562RootFile=regexprep(RootFile,'\<[\\/]|[\\/]\>','');%suppress possible / or \ separator at the beginning or the end of the string
3563filebase=fullfile(RootPath,RootFile);
3564list=get(handles.masklevel,'String');
3565masknumber=num2str(length(list));
3566maskindex=get(handles.masklevel,'Value');
3567mask_name=fullfile_uvmat(RootPath,SubDir,[RootFile '_' masknumber 'mask'],'.png','_1',maskindex);
3568%mask_name=name_generator([filebase '_' masknumber 'mask'],maskindex,1,'.png','_i');
3569imflag=uint8(255*(0.392+0.608*flag));% =100 for flag=0 (vectors not computed when 20<imflag<200)
3570imflag=flipdim(imflag,1);
3571% imflag=uint8(255*flag);% =0 for flag=0 (vectors=0 when 20<imflag<200)
3572msgbox_uvmat('CONFIRMATION',[mask_name ' saved'])
3573imwrite(imflag,mask_name,'BitDepth',8);
3574
3575%display the mask
3576figure;
3577vec=linspace(0,1,256);%define a linear greyscale colormap
3578map=[vec' vec' vec'];
3579colormap(map)
3580
3581image(imflag);
3582
3583%-------------------------------------------------------------------
3584%-------------------------------------------------------------------
3585%  - FUNCTIONS FOR SETTING PLOTTING PARAMETERS
3586
3587%------------------------------------------------------------------
3588%-------------------------------------------------------------
3589% --- Executes on selection change in transform_fct.
3590function transform_fct_Callback(hObject, eventdata, handles)
3591%-------------------------------------------------------------
3592UvData=get(handles.uvmat,'UserData');
3593menu=get(handles.transform_fct,'String');
3594ind_coord=get(handles.transform_fct,'Value');
3595coord_option=menu{ind_coord};
3596list_transform=get(handles.transform_fct,'UserData');
3597ff=functions(list_transform{end}); 
3598if isequal(coord_option,'more...');
3599    coord_fct='';
3600    prompt = {'Enter the name of the transform function'};
3601    dlg_title = 'user defined transform';
3602    num_lines= 1;
3603    [FileName, PathName] = uigetfile( ...
3604       {'*.m', ' (*.m)';
3605        '*.m',  '.m files '; ...
3606        '*.*', 'All Files (*.*)'}, ...
3607        'Pick a file', ff.file);
3608    if isequal(PathName(end),'/')||isequal(PathName(end),'\')
3609        PathName(end)=[];
3610    end
3611    transform_selected =fullfile(PathName,FileName);
3612    if ~exist(transform_selected,'file')
3613           return
3614    end
3615   [ppp,transform,ext_fct]=fileparts(FileName);% removes extension .m
3616   if ~isequal(ext_fct,'.m')
3617        msgbox_uvmat('ERROR','a Matlab function .m must be introduced');
3618        return
3619   end
3620   menu=update_menu(handles.transform_fct,transform);%add the selected fct to the menu
3621   ind_coord=get(handles.transform_fct,'Value');
3622   addpath(PathName)
3623   list_transform{ind_coord}=str2func(transform);% create the function handle corresponding to the newly seleced function
3624   set(handles.transform_fct,'UserData',list_transform)
3625   rmpath(PathName)
3626   % save the new menu in the personal file 'uvmat_perso.mat'
3627   dir_perso=prefdir;%personal Matalb directory
3628   profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
3629   if exist(profil_perso,'file')
3630       nb_builtin=UvData.OpenParam.NbBuiltin;
3631       for ilist=nb_builtin+1:numel(list_transform)
3632           ff=functions(list_transform{ilist});
3633           transform_fct{ilist-nb_builtin}=ff.file;
3634       end
3635        save (profil_perso,'transform_fct','-append'); %store the root name for future opening of uvmat
3636   end   
3637end
3638
[429]3639%% check the current path to the selected function
[387]3640if isa(list_transform{ind_coord},'function_handle')
3641    func=functions(list_transform{ind_coord});
3642    set(handles.path_transform,'String',fileparts(func.file)); %show the path to the senlected function
3643else
3644    set(handles.path_transform,'String','')
3645end
3646
3647set(handles.CheckFixLimits,'Value',0)
3648set(handles.CheckFixLimits,'BackgroundColor',[0.7 0.7 0.7])
3649
[429]3650%% delete drawn objects
[387]3651hother=findobj('Tag','proj_object');%find all the proj objects
3652for iobj=1:length(hother)
3653    delete_object(hother(iobj))
3654end
3655hother=findobj('Tag','DeformPoint');%find all the proj objects
3656for iobj=1:length(hother)
3657    delete_object(hother(iobj))
3658end
3659hh=findobj('Tag','calib_points');
3660if ~isempty(hh)
3661    delete(hh)
3662end
3663hhh=findobj('Tag','calib_marker');
3664if ~isempty(hhh)
3665    delete(hhh)
3666end
3667if isfield(UvData,'Object')
3668     UvData.Object=UvData.Object(1);
3669end
3670set(handles.ListObject,'Value',1)
[429]3671set(handles.ListObject,'String',{'plane'})
3672set(handles.ListObject_1,'Value',1)
3673set(handles.ListObject_1,'String',{'plane'})
[387]3674
3675%delete mask if it is displayed
[411]3676% if isequal(get(handles.CheckMask,'Value'),1)%if the mask option is on
3677%    UvData=rmfield(UvData,'MaskName'); %will impose mask refresh 
3678% end
[387]3679set(handles.uvmat,'UserData',UvData)
3680run0_Callback(hObject, eventdata, handles)
3681
3682
3683
3684%------------------------------------------------
3685%CALLBACKS FOR PLOTTING PARAMETERS
3686%-------------------------------------------------
[405]3687%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3688% Plot coordinates
3689%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[387]3690%------------------------------------------------------------------------
3691function num_MinX_Callback(hObject, eventdata, handles)
3692%------------------------------------------------------------------------
3693set(handles.CheckFixLimits,'Value',1) %suppress auto mode
3694set(handles.CheckFixLimits,'BackgroundColor',[1 1 0])
3695update_plot(handles);
3696
3697%------------------------------------------------------------------------
3698function num_MaxX_Callback(hObject, eventdata, handles)
3699%------------------------------------------------------------------------
3700set(handles.CheckFixLimits,'Value',1) %suppress auto mode
3701set(handles.CheckFixLimits,'BackgroundColor',[1 1 0])
3702update_plot(handles);
3703
3704%------------------------------------------------------------------------
3705function num_MinY_Callback(hObject, eventdata, handles)
3706%------------------------------------------
3707set(handles.CheckFixLimits,'Value',1) %suppress auto mode
3708set(handles.CheckFixLimits,'BackgroundColor',[1 1 0])
3709update_plot(handles);
3710
3711%------------------------------------------------------------------------
3712function num_MaxY_Callback(hObject, eventdata, handles)
3713%------------------------------------------------------------------------
3714set(handles.CheckFixLimits,'Value',1) %suppress auto mode
3715set(handles.CheckFixLimits,'BackgroundColor',[1 1 0])
3716update_plot(handles);
3717
[405]3718%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3719% Scalar or image representation
3720%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[387]3721%------------------------------------------------------------------------
3722function num_MinA_Callback(hObject, eventdata, handles)
3723%------------------------------------------
3724set(handles.CheckFixScalar,'Value',1) %suppress auto mode
3725set(handles.CheckFixScalar,'BackgroundColor',[1 1 0])
3726MinA=str2double(get(handles.num_MinA,'String'));
3727MaxA=str2double(get(handles.num_MaxA,'String'));
3728if MinA>MaxA% switch minA and maxA in case of error
3729    MinA_old=MinA;
3730    MinA=MaxA;
3731    MaxA=MinA_old;
3732    set(handles.num_MinA,'String',num2str(MinA,5));
3733    set(handles.num_MaxA,'String',num2str(MaxA,5));
3734end
3735update_plot(handles);
3736
3737%------------------------------------------------------------------------
3738function num_MaxA_Callback(hObject, eventdata, handles)
3739%------------------------------------------------------------------------
3740set(handles.CheckFixScalar,'Value',1) %suppress auto mode
3741set(handles.CheckFixScalar,'BackgroundColor',[1 1 0])
3742MinA=str2double(get(handles.num_MinA,'String'));
3743MaxA=str2double(get(handles.num_MaxA,'String'));
3744if MinA>MaxA% switch minA and maxA in case of error
3745        MinA_old=MinA;
3746    MinA=MaxA;
3747    MaxA=MinA_old;
3748    set(handles.num_MinA,'String',num2str(MinA,5));
3749    set(handles.num_MaxA,'String',num2str(MaxA,5));
3750end
3751update_plot(handles);
3752
3753%------------------------------------------------------------------------
3754function CheckFixScalar_Callback(hObject, eventdata, handles)
3755%------------------------------------------------------------------------
3756test=get(handles.CheckFixScalar,'Value');
3757if test
3758    set(handles.CheckFixScalar,'BackgroundColor',[1 1 0])
3759else
3760    set(handles.CheckFixScalar,'BackgroundColor',[0.7 0.7 0.7])
3761    update_plot(handles);
3762end
3763
3764%-------------------------------------------------------------------
3765function CheckBW_Callback(hObject, eventdata, handles)
3766%-------------------------------------------------------------------
3767update_plot(handles);
3768
3769%-------------------------------------------------------------------
[428]3770function num_Opacity_Callback(hObject, eventdata, handles)
3771update_plot(handles);
3772%-------------------------------------------------------------------
3773
3774%-------------------------------------------------------------------
[387]3775function ListContour_Callback(hObject, eventdata, handles)
3776%-------------------------------------------------------------------
3777val=get(handles.ListContour,'Value');
3778if val==2
3779    set(handles.interval_txt,'Visible','on')
3780    set(handles.num_IncrA,'Visible','on')
3781else
3782    set(handles.interval_txt,'Visible','off')
3783    set(handles.num_IncrA,'Visible','off')
3784end
3785update_plot(handles);
3786
3787%-------------------------------------------------------------------
3788function num_IncrA_Callback(hObject, eventdata, handles)
3789%-------------------------------------------------------------------
3790update_plot(handles);
3791
[405]3792
3793%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3794% Vector representation
3795%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[387]3796%-------------------------------------------------------------------
3797function CheckHideWarning_Callback(hObject, eventdata, handles)
3798%-------------------------------------------------------------------
3799update_plot(handles);
3800
3801%-------------------------------------------------------------------
3802function CheckHideFalse_Callback(hObject, eventdata, handles)
3803%-------------------------------------------------------------------
3804update_plot(handles);
3805
3806%-------------------------------------------------------------------
3807function num_VecScale_Callback(hObject, eventdata, handles)
3808%-------------------------------------------------------------------
3809set(handles.CheckFixVectors,'Value',1);
3810set(handles.CheckFixVectors,'BackgroundColor',[1 1 0])
3811update_plot(handles);
3812
3813%-------------------------------------------------------------------
3814function CheckFixVectors_Callback(hObject, eventdata, handles)
3815%-------------------------------------------------------------------
3816test=get(handles.CheckFixVectors,'Value');
3817if test
3818    set(handles.CheckFixVectors,'BackgroundColor',[1 1 0])
3819else
3820    update_plot(handles);
3821    %set(handles.num_VecScale,'String',num2str(ScalOut.num_VecScale,3))
3822    set(handles.CheckFixVectors,'BackgroundColor',[0.7 0.7 0.7])
3823end
3824
3825%------------------------------------------------------------------------
3826% --- Executes on selection change in CheckDecimate4 (nb_vec/4).
3827function CheckDecimate4_Callback(hObject, eventdata, handles)
3828%------------------------------------------------------------------------
3829update_plot(handles);
3830
3831%------------------------------------------------------------------------
[405]3832% --- Executes on selection change in ColorCode menu
3833function ColorCode_Callback(hObject, eventdata, handles)
[387]3834%------------------------------------------------------------------------
[405]3835% edit the choice for color code
3836update_color_code_boxes(handles);
3837update_plot(handles);
3838
3839%------------------------------------------------------------------------
3840function update_color_code_boxes(handles)
3841%------------------------------------------------------------------------
3842list_code=get(handles.ColorCode,'String');% list menu fields
3843colcode= list_code{get(handles.ColorCode,'Value')}; % selected field
3844enable_slider='off';%default
3845enable_bounds='off';%default
3846enable_scalar='off';%default
3847switch colcode
3848    case {'rgb','bgr'}
3849        enable_slider='on';
3850        enable_bounds='on';
3851        enable_scalar='on';
3852    case '64 colors'
3853        enable_bounds='on';
3854        enable_scalar='on';
3855end
3856set(handles.Slider1,'Visible',enable_slider)
3857set(handles.Slider2,'Visible', enable_slider)
3858set(handles.num_ColCode1,'Visible',enable_slider)
3859set(handles.num_ColCode2,'Visible',enable_slider)
3860set(handles.TitleColCode1,'Visible',enable_slider)
3861set(handles.TitleColCode2,'Visible',enable_slider)
3862set(handles.CheckFixVecColor,'Visible',enable_bounds)
3863set(handles.num_MinVec,'Visible',enable_bounds)
3864set(handles.num_MaxVec,'Visible',enable_bounds)
3865set(handles.ColorScalar,'Visible',enable_scalar)
[387]3866set_vec_col_bar(handles)
[405]3867
3868%------------------------------------------------------------------
3869% --- Executes on selection change in ColorScalar: choice of the color code.
3870function ColorScalar_Callback(hObject, eventdata, handles)
3871%------------------------------------------------------------------
3872% edit the choice for color code
3873list_scalar=get(handles.ColorScalar,'String');% list menu fields
3874col_scalar= list_scalar{get(handles.ColorScalar,'Value')}; % selected field
3875if isequal(col_scalar,'ima_cor')
3876    set(handles.CheckFixVecColor,'Value',1)%fixed scale by default
3877    ColorCode='rgb';
3878    set(handles.num_MinVec,'String','0')
3879    set(handles.num_MaxVec,'String','1')
3880    set(handles.num_ColCode1,'String','0.333')
3881    set(handles.num_ColCode2,'String','0.666')
3882else
3883    set(handles.CheckFixVecColor,'Value',0)%auto scale between min,max by default
3884    ColorCode='64 colors';
3885end
3886ColorCodeList=get(handles.ColorCode,'String');
3887ichoice=find(strcmp(ColorCode,ColorCodeList),1);
3888set(handles.ColorCode,'Value',ichoice)% set color code in the menu
3889
3890update_color_code_boxes(handles);
3891%replot the current graph
3892run0_Callback(hObject, eventdata, handles)
3893
3894%----------------------------------------------------------------
3895% -- Executes on slider movement to set the color code
3896%
3897function Slider1_Callback(hObject, eventdata, handles)
3898%------------------------------------------------------------------
3899slider1=get(handles.Slider1,'Value');
3900min_val=str2num(get(handles.num_MinVec,'String'));
3901max_val=str2num(get(handles.num_MaxVec,'String'));
3902col=min_val+(max_val-min_val)*slider1;
3903set(handles.num_ColCode1,'String',num2str(col))
3904if(get(handles.Slider2,'Value') < col)%move also the second slider at the same value if needed
3905    set(handles.Slider2,'Value',col)
3906    set(handles.num_ColCode2,'String',num2str(col))
3907end
3908set_vec_col_bar(handles)
[387]3909update_plot(handles);
3910
[405]3911%----------------------------------------------------------------
3912% Executes on slider movement to set the color code
3913%----------------------------------------------------------------
3914function Slider2_Callback(hObject, eventdata, handles)
3915slider2=get(handles.Slider2,'Value');
3916min_val=str2num(get(handles.num_MinVec,'String'));
3917max_val=str2num(get(handles.num_MaxVec,'String'));
3918col=min_val+(max_val-min_val)*slider2;
3919set(handles.num_ColCode2,'String',num2str(col))
3920if(get(handles.Slider1,'Value') > col)%move also the first slider at the same value if needed
3921    set(handles.Slider1,'Value',col)
3922    set(handles.num_ColCode1,'String',num2str(col))
3923end
3924set_vec_col_bar(handles)
3925update_plot(handles);
3926
3927%----------------------------------------------------------------
3928% --- Execute on return carriage on the edit box corresponding to slider 1
3929%----------------------------------------------------------------
3930function num_ColCode1_Callback(hObject, eventdata, handles)
3931set_vec_col_bar(handles)
3932update_plot(handles);
3933
3934%----------------------------------------------------------------
3935% --- Execute on return carriage on the edit box corresponding to slider 2
3936%----------------------------------------------------------------
3937function num_ColCode2_Callback(hObject, eventdata, handles)
3938set_vec_col_bar(handles)
3939update_plot(handles);
[387]3940%------------------------------------------------------------------------
[405]3941%-------------------------------------------------------
[387]3942% --- Executes on button press in CheckFixVecColor.
[405]3943%-------------------------------------------------------
3944function VecColBar_Callback(hObject, eventdata, handles)
3945set_vec_col_bar(handles)
3946
3947%------------------------------------------------------------------------
3948% --- Executes on button press in CheckFixVecColor.
[387]3949function CheckFixVecColor_Callback(hObject, eventdata, handles)
3950%------------------------------------------------------------------------
[405]3951if ~get(handles.CheckFixVecColor,'Value')
[387]3952    update_plot(handles);
3953end
3954
3955%------------------------------------------------------------------------
3956% --- Executes on selection change in num_MaxVec.
3957function num_MinVec_Callback(hObject, eventdata, handles)
3958%------------------------------------------------------------------------
3959max_vec_Callback(hObject, eventdata, handles)
3960
3961%------------------------------------------------------------------------
3962% --- Executes on selection change in num_MaxVec.
3963function num_MaxVec_Callback(hObject, eventdata, handles)
3964%------------------------------------------------------------------------
3965set(handles.CheckFixVecColor,'Value',1)
3966CheckFixVecColor_Callback(hObject, eventdata, handles)
3967min_val=str2num(get(handles.num_MinVec,'String'));
3968max_val=str2num(get(handles.num_MaxVec,'String'));
3969slider1=get(handles.Slider1,'Value');
3970slider2=get(handles.Slider2,'Value');
3971colcode1=min_val+(max_val-min_val)*slider1;
3972colcode2=min_val+(max_val-min_val)*slider2;
3973set(handles.num_ColCode1,'String',num2str(colcode1))
3974set(handles.num_ColCode2,'String',num2str(colcode2))
3975update_plot(handles);
3976
3977%------------------------------------------------------------------------
[405]3978% --- update the display of color code for vectors (on vecColBar)
[387]3979function set_vec_col_bar(handles)
3980%------------------------------------------------------------------------
3981%get the image of the color display button 'VecColBar' in pixels
3982set(handles.VecColBar,'Unit','pixel');
3983pos_vert=get(handles.VecColBar,'Position');
3984set(handles.VecColBar,'Unit','Normalized');
3985width=ceil(pos_vert(3));
3986height=ceil(pos_vert(4));
3987
3988%get slider indications
[405]3989list=get(handles.ColorCode,'String');
3990ichoice=get(handles.ColorCode,'Value');
3991colcode.ColorCode=list{ichoice};
[387]3992colcode.MinVec=str2num(get(handles.num_MinVec,'String'));
3993colcode.MaxVec=str2num(get(handles.num_MaxVec,'String'));
[405]3994test3color=strcmp(colcode.ColorCode,'rgb') || strcmp(colcode.ColorCode,'bgr');
[387]3995if test3color
3996    colcode.ColCode1=str2num(get(handles.num_ColCode1,'String'));
3997    colcode.ColCode2=str2num(get(handles.num_ColCode2,'String'));
3998end
3999vec_C=colcode.MinVec+(colcode.MaxVec-colcode.MinVec)*(0.5:width-0.5)/width;%sample of vec_C values from min to max
4000[colorlist,col_vec]=set_col_vec(colcode,vec_C);
4001oneheight=ones(1,height);
4002A1=colorlist(col_vec,1)*oneheight;
4003A2=colorlist(col_vec,2)*oneheight;
4004A3=colorlist(col_vec,3)*oneheight;
4005A(:,:,1)=A1';
4006A(:,:,2)=A2';
4007A(:,:,3)=A3';
4008set(handles.VecColBar,'Cdata',A)
4009
4010%-------------------------------------------------------------------
4011function update_plot(handles)
4012%-------------------------------------------------------------------
4013UvData=get(handles.uvmat,'UserData');
4014AxeData=UvData.axes3;% retrieve the current plotted data
4015PlotParam=read_GUI(handles.uvmat);
[399]4016[tild,PlotParamOut]= plot_field(AxeData,handles.axes3,PlotParam);
[387]4017write_plot_param(handles,PlotParamOut); %update the auto plot parameters
4018
[402]4019%------------------------------------------------------------------------
4020%------------------------------------------------------------------------
4021%   SELECTION AND EDITION OF PROJECTION OBJECTS
4022%------------------------------------------------------------------------
4023%------------------------------------------------------------------------
[387]4024
[410]4025% --- Executes on selection change in ListObject_1.
4026function ListObject_1_Callback(hObject, eventdata, handles)
[432]4027list_str=get(handles.ListObject,'String');
[410]4028UvData=get(handles.uvmat,'UserData');
4029ObjectData=UvData.Object{get(handles.ListObject_1,'Value')};
4030
4031%% update the projection plot on uvmat
[432]4032ProjData= proj_field(UvData.Field,ObjectData);%project the current input field on object ObjectData
4033plot_field(ProjData,handles.axes3,read_GUI(handles.uvmat));% plot the projected field;
4034%replot all the objects within the new projected field
4035for IndexObj=1:numel(list_str)
4036    IndexObj
4037        hobject=UvData.Object{IndexObj}.DisplayHandle.uvmat
4038        if isempty(hobject) || ~ishandle(hobject)
4039            hobject=handles.axes3
4040        end
4041        if isequal(IndexObj,get(handles.ListObject,'Value'))
4042            objectcolor='m'; %paint in magenta the currently selected object in ListObject
4043        else
4044            objectcolor='b';
4045        end
4046        UvData.Object{IndexObj}.DisplayHandle.uvmat=plot_object(UvData.Object{IndexObj},ObjectData,hobject,objectcolor);%draw the object in uvmat     
4047end
4048set(handles.uvmat,'UserData',UvData)
[410]4049
4050%% display the object parameters if the GUI set_object is already opened
[425]4051if ~get(handles.ViewObject,'Value')
[410]4052    ZBounds=0; % default
4053    if isfield(UvData.Field,'ZMin') && isfield(UvData.Field,'ZMax')
4054        ZBounds(1)=UvData.Field.ZMin; %minimum for the Z slider
4055        ZBounds(2)=UvData.Field.ZMax;%maximum for the Z slider
4056    end
[425]4057    ObjectData.Name=list_str{get(handles.ListObject_1,'Value')};
[410]4058    set_object(ObjectData,[],ZBounds);
[424]4059    set(handles.ViewObject,'Value',1)% show that the selected object in ListObject_1 is currently visualised
[410]4060end
[432]4061
[410]4062%  desactivate the edit object mode
4063set(handles.edit_object,'Value',0)
4064set(handles.edit_object,'BackgroundColor',[0.7,0.7,0.7])
4065
[387]4066%------------------------------------------------------------------------
4067% --- Executes on selection change in ListObject.
4068function ListObject_Callback(hObject, eventdata, handles)
4069%------------------------------------------------------------------------
4070list_str=get(handles.ListObject,'String');
4071IndexObj=get(handles.ListObject,'Value');%present object selection
4072
[410]4073%% The object  is displayed in set_object if this GUI is already opened
[402]4074UvData=get(handles.uvmat,'UserData');
[410]4075ObjectData=UvData.Object{IndexObj};
[402]4076hset_object=findobj(allchild(0),'tag','set_object');
4077if ~isempty(hset_object)
4078    ZBounds=0; % default
4079    if isfield(UvData.Field,'ZMin') && isfield(UvData.Field,'ZMax')
4080        ZBounds(1)=UvData.Field.ZMin; %minimum for the Z slider
4081        ZBounds(2)=UvData.Field.ZMax;%maximum for the Z slider
4082    end
[410]4083    ObjectData.Name=list_str{IndexObj};
[402]4084    set_object(ObjectData,[],ZBounds);
[424]4085    set(handles.ViewField,'Value',1)% show that the selected object in ListObject is currently visualised
[402]4086end
[429]4087
4088%%  desactivate the edit object mode
[402]4089set(handles.edit_object,'Value',0)
4090set(handles.edit_object,'BackgroundColor',[0.7,0.7,0.7])
4091
[429]4092%% update the  plot on view_field if view_field is already openened
4093hview_field=findobj(allchild(0),'tag','view_field');
4094if isempty(hview_field)
4095    hhview_field.axes3=[];
4096else
4097    Data=get(hview_field,'UserData');
4098    hhview_field=guidata(hview_field);
4099    ProjData= proj_field(UvData.Field,ObjectData);%project the current interface field on ObjectData
4100    [PlotType,PlotParam]=plot_field(ProjData,hhview_field.axes3,read_GUI(hview_field));%read plotting parameters on the uvmat interfachhview_fiel
4101    write_plot_param(hhview_field,PlotParam); %update the display of plotting parameters for the current object
4102    haxes=findobj(hview_field,'tag','axes3');
4103    pos=get(hview_field,'Position'); 
4104    if strcmp(get(haxes,'Visible'),'off')%sempty(PlotParam.Coordinates)% case of no plot display (pure text table)
4105        h_TableDisplay=findobj(hview_field,'tag','TableDisplay');
4106        pos_table=get(h_TableDisplay,'Position');
4107        set(hview_field,'Position',[pos(1)+pos(3)-pos_table(3) pos(2)+pos(4)-pos_table(4) pos_table(3) pos_table(4)])
4108        drawnow% needed to change position before the next command
4109        set(hview_field,'UserData',Data);% restore the previously stored GUI position after GUI resizing
4110    else
4111        set(hview_field,'Position',Data.GUISize)% return to the previously stored GUI position and size
[387]4112    end
4113end
4114
[402]4115%% update the color of the graphic object representation: the selected object in magenta, others in blue
[432]4116update_object_color(handles.axes3,hhview_field.axes3,UvData.Object{IndexObj}.DisplayHandle.uvmat)
[387]4117
4118%------------------------------------------------------------------------
[402]4119%--- update the color representation of objects (indicating the selected ones)
4120function update_object_color(axes_uvmat,axes_view_field,DisplayHandle)
[387]4121%------------------------------------------------------------------------
[402]4122if isempty(axes_view_field)% case with no view_field plot
4123hother=[findobj(axes_uvmat,'Tag','proj_object');findobj(axes_uvmat,'Tag','DeformPoint')];%find all the proj object and deform point representations
[387]4124else
[402]4125hother=[findobj(axes_uvmat,'Tag','proj_object') ;findobj(axes_view_field,'Tag','proj_object');... %find all the proj object representations
4126findobj(axes_uvmat,'Tag','DeformPoint'); findobj(axes_view_field,'Tag','DeformPoint')];%find all the deform point representations
[387]4127end
4128for iobj=1:length(hother)
4129    if isequal(get(hother(iobj),'Type'),'rectangle')||isequal(get(hother(iobj),'Type'),'patch')
4130        set(hother(iobj),'EdgeColor','b')
4131        if isequal(get(hother(iobj),'FaceColor'),'m')
4132            set(hother(iobj),'FaceColor','b')
4133        end
4134    elseif isequal(get(hother(iobj),'Type'),'image')
4135        Acolor=get(hother(iobj),'CData');
4136        Acolor(:,:,1)=zeros(size(Acolor,1),size(Acolor,2));
4137        set(hother(iobj),'CData',Acolor);
4138    else
4139        set(hother(iobj),'Color','b')
4140    end
4141    set(hother(iobj),'Selected','off')
4142end
[432]4143if ishandle(DisplayHandle)
[402]4144    linetype=get(DisplayHandle,'Type');
4145    if isequal(linetype,'line')
4146        set(DisplayHandle,'Color','m'); %set the selected object to magenta color
4147    elseif isequal(linetype,'rectangle')
4148        set(DisplayHandle,'EdgeColor','m'); %set the selected object to magenta color
4149    elseif isequal(linetype,'patch')
4150        set(DisplayHandle,'FaceColor','m'); %set the selected object to magenta color
4151    end
4152    SubObjectData=get(DisplayHandle,'UserData');
4153    if isfield(SubObjectData,'SubObject') & ishandle(SubObjectData.SubObject)
4154        for iobj=1:length(SubObjectData.SubObject)
4155            hsub=SubObjectData.SubObject(iobj);
4156            if isequal(get(hsub,'Type'),'rectangle')
4157                set(hsub,'EdgeColor','m'); %set the selected object to magenta color
4158            elseif isequal(get(hsub,'Type'),'image')
4159                Acolor=get(hsub,'CData');
4160                Acolor(:,:,1)=Acolor(:,:,3);
4161                set(hsub,'CData',Acolor);
4162            else
4163                set(hsub,'Color','m')
4164            end
[387]4165        end
4166    end
[402]4167    if isfield(SubObjectData,'DeformPoint') & ishandle(SubObjectData.DeformPoint)
4168        set(SubObjectData.DeformPoint,'Color','m')
4169    end
[387]4170end
[402]4171
[427]4172%-------------------------------------------------------------------
4173% --- Executes on selection change in edit_object.
4174function edit_object_Callback(hObject, eventdata, handles)
4175%-------------------------------------------------------------------
4176UvData=get(handles.uvmat,'UserData');%read UvData properties stored on the uvmat interface
4177hset_object=findobj(allchild(0),'Tag','set_object');
4178if get(handles.edit_object,'Value')
4179    set(handles.edit_object,'BackgroundColor',[1,1,0]) 
4180    %suppress the other options
4181    set(handles.CheckZoom,'Value',0)
4182    CheckZoom_Callback(hObject, eventdata, handles)
4183    hgeometry_calib=findobj(allchild(0),'tag','geometry_calib');
4184    if ishandle(hgeometry_calib)
4185        hhgeometry_calib=guidata(hgeometry_calib);
4186        set(hhgeometry_calib.edit_append,'Value',0)% desactivate mouse action in geometry_calib
4187        set(hhgeometry_calib.edit_append,'BackgroundColor',[0.7 0.7 0.7])
4188    end
4189    set(handles.ViewObject,'value',1)
4190    ViewObject_Callback(hObject, eventdata, handles)
4191else % desctivate object edit mode
4192    set(handles.edit_object,'BackgroundColor',[0.7,0.7,0.7]) 
4193    if ~isempty(hset_object)% open the
4194        hhset_object=guidata(hset_object);
4195        set(hhset_object.PLOT,'enable','off');
4196        set(get(hset_object,'children'),'enable','inactive')
4197    end
4198end
4199
4200
[402]4201%------------------------------------------------------------------------
[424]4202% --- Executes on button press in ViewObject.
4203function ViewObject_Callback(hObject, eventdata, handles)
[410]4204%------------------------------------------------------------------------
[424]4205check_view=get(handles.ViewObject,'Value');
[410]4206
4207if check_view %activate set_object   
[424]4208    IndexObj=get(handles.ListObject,'Value');
4209    list_object=get(handles.ListObject,'String');
[410]4210    UvData=get(handles.uvmat,'UserData');%read UvData properties stored on the uvmat interface
4211    UvData.Object{IndexObj}.Name=list_object{IndexObj};
4212    if numel(UvData.Object)<IndexObj;% error in UvData
4213        msgbox_uvmat('ERROR','invalid object list')
4214        return
4215    end
4216    ZBounds=0; % default
4217    if isfield(UvData.Field,'ZMin') && isfield(UvData.Field,'ZMax')
4218        ZBounds(1)=UvData.Field.ZMin; %minimum for the Z slider
4219        ZBounds(2)=UvData.Field.ZMax;%maximum for the Z slider
4220    end
[424]4221%     set(handles.ListObject_1,'Value',IndexObj);%restore ListObject selection after set_object deletion
[410]4222    data=UvData.Object{IndexObj};
4223    if ~isfield(data,'Type')% default plane
4224        data.Type='plane';
4225    end
4226    if isfield(UvData,'Field')
4227        Field=UvData.Field;
4228        if isfield(UvData.Field,'Mesh')&&~isempty(UvData.Field.Mesh)
4229            data.RangeX=[UvData.Field.XMin UvData.Field.XMax];
4230            if strcmp(data.Type,'line')||strcmp(data.Type,'polyline')
4231                data.RangeY=UvData.Field.Mesh;
4232            else
4233                data.RangeY=[UvData.Field.YMin UvData.Field.YMax];
4234            end
4235            data.DX=UvData.Field.Mesh;
4236            data.DY=UvData.Field.Mesh;
4237        end
4238        if isfield(Field,'NbDim')&& isequal(Field.NbDim,3)
4239            data.Coord=[0 0 0]; %default
4240        end
4241        if isfield(Field,'CoordUnit')
4242            data.CoordUnit=Field.CoordUnit;
4243        end
4244    end
4245    hset_object=set_object(data,[],ZBounds);
4246    hhset_object=guidata(hset_object);
4247    if get(handles.edit_object,'Value')% edit mode
4248        set(hhset_object.PLOT,'Enable','on')
[424]4249        set(get(hset_object,'children'),'enable','on')
[410]4250    else
4251        set(hhset_object.PLOT,'Enable','off')
[427]4252        set(get(hset_object,'children'),'enable','inactive')% deactivate the GUI except SAVE
4253        set(hhset_object.SAVE,'Enable','on')
[410]4254    end
4255else
4256    hset_object=findobj(allchild(0),'tag','set_object');
4257    if ~isempty(hset_object)
4258        delete(hset_object)% delete existing version of set_object
4259    end
4260end
4261 
[424]4262
[410]4263%------------------------------------------------------------------------
[424]4264% --- Executes on button press in ViewField.
4265function ViewField_Callback(hObject, eventdata, handles)
[402]4266%------------------------------------------------------------------------
[424]4267check_view=get(handles.ViewField,'Value');
[387]4268
[410]4269if check_view
4270    IndexObj=get(handles.ListObject,'Value');
4271    UvData=get(handles.uvmat,'UserData');%read UvData properties stored on the uvmat interface
4272    if numel(UvData.Object)<IndexObj(end);% error in UvData
4273        msgbox_uvmat('ERROR','invalid object list')
4274        return
4275    end
4276    ZBounds=0; % default
4277    if isfield(UvData.Field,'ZMin') && isfield(UvData.Field,'ZMax')
4278        ZBounds(1)=UvData.Field.ZMin; %minimum for the Z slider
4279        ZBounds(2)=UvData.Field.ZMax;%maximum for the Z slider
4280    end
4281    set(handles.ListObject,'Value',IndexObj);%restore ListObject selection after set_object deletion
4282    if ~isfield(UvData.Object{IndexObj(1)},'Type')% default plane
4283        UvData.Object{IndexObj(1)}.Type='plane';
4284    end
4285    list_object=get(handles.ListObject,'String');
4286    UvData.Object{IndexObj(end)}.Name=list_object{IndexObj(end)};
4287   
[429]4288    %% show the projection of the selected object on view_field
4289    ProjData= proj_field(UvData.Field,UvData.Object{IndexObj});%project the current field on ObjectData
[402]4290    hview_field=findobj(allchild(0),'tag','view_field');
4291    if isempty(hview_field)
4292        hview_field=view_field;
4293    end
[429]4294    hhview_field=guidata(hview_field);
4295    [PlotType,PlotParam]=plot_field(ProjData,hhview_field.axes3,read_GUI(hview_field));%read plotting parameters on the GUI view_field);
4296    write_plot_param(hhview_field,PlotParam); %update the display of plotting parameters for the current object
4297    haxes=findobj(hview_field,'tag','axes3');
4298    pos=get(hview_field,'Position');
4299    if strcmp(get(haxes,'Visible'),'off')%sempty(PlotParam.Coordinates)% case of no plot display (pure text table)
4300        h_TableDisplay=findobj(hview_field,'tag','TableDisplay');
4301        pos_table=get(h_TableDisplay,'Position');
4302        set(hview_field,'Position',[pos(1)+pos(3)-pos_table(3) pos(2)+pos(4)-pos_table(4) pos_table(3) pos_table(4)])
4303    else
4304        Data=get(hview_field,'UserData');
[432]4305        set(hview_field,'Position',Data.GUISize)% restore the size of view_field for plots
[429]4306    end
[410]4307else
[424]4308    hview_field=findobj(allchild(0),'tag','view_field');
4309    if ~isempty(hview_field)
4310        delete(hview_field)% delete existing version of set_object
[410]4311    end
[402]4312end
4313
[424]4314
[402]4315%------------------------------------------------------------------------
4316% --- Executes on button press in delete_object.
4317function delete_object_Callback(hObject, eventdata, handles)
4318%------------------------------------------------------------------------
4319IndexObj=get(handles.ListObject,'Value');
[410]4320IndexObj_1=get(handles.ListObject_1,'Value');
4321if IndexObj>1 && ~isequal(IndexObj,IndexObj_1)
4322    delete_object(IndexObj)
[402]4323end
4324
4325%------------------------------------------------------------------------
4326%------------------------------------------------------------------------
4327%  II - TOOLS FROM THE UPPER MENU BAR
4328%------------------------------------------------------------------------
4329%------------------------------------------------------------------------
4330
4331%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4332% Export  Menu Callbacks
4333%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4334%------------------------------------------------------------------------
[387]4335% --- Executes on button press in Menu/Export/field in workspace.
4336function MenuExportField_Callback(hObject, eventdata, handles)
[402]4337%------------------------------------------------------------------------
[387]4338global Data_uvmat
4339Data_uvmat=get(handles.uvmat,'UserData');
4340evalin('base','global Data_uvmat')%make CurData global in the workspace
4341display('current field :')
4342evalin('base','Data_uvmat') %display CurData in the workspace
4343commandwindow; %brings the Matlab command window to the front
4344
[402]4345%------------------------------------------------------------------------
[387]4346% --- Executes on button press in Menu/Export/extract figure.
[402]4347function MenuExportFigure_Callback(hObject, eventdata, handles)
4348%------------------------------------------------------------------------
4349% huvmat=get(handles.MenuExport,'parent');
[387]4350hfig=figure;
[402]4351copyobj(handles.axes3,hfig);
[387]4352map=colormap(handles.axes3);
4353colormap(map);%transmit the current colormap to the zoom fig
4354colorbar
4355
[402]4356% %------------------------------------------------------
4357% % --- Executes on button press in Menu/Export/extract figure.
4358% %------------------------------------------------------
4359% function MenuExport_plot_Callback(hObject, eventdata, handles)
4360% huvmat=get(handles.MenuExport_plot,'parent');
4361% UvData=get(huvmat,'UserData');
4362% hfig=figure;
4363% newaxes=copyobj(handles.axes3,hfig);
4364% map=colormap(handles.axes3);
4365% colormap(map);%transmit the current colormap to the zoom fig
4366% colorbar
[387]4367
[402]4368%
4369% % --------------------------------------------------------------------
4370% function Insert_Callback(hObject, eventdata, handles)
4371%
[387]4372
4373%------------------------------------------------------------------------
4374% --------------------------------------------------------------------
4375function MenuExportMovie_Callback(hObject, eventdata, handles)
4376% --------------------------------------------------------------------
4377set(handles.MenuExportMovie,'BusyAction','queue')% activate the button
4378huvmat=get(handles.run0,'parent');
4379UvData=get(huvmat,'UserData');
4380%[xx,xx,FileBase]=read_file_boxes(handles);
4381[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
4382FileBase=fullfile(RootPath,RootFile);
4383 %read the current input file name
4384prompt = {'movie file name';'frames per second';'frame resolution (*[512x384] pixels)';'axis position relative to the frame';'total frame number (starting from the current uvmat display)'};
4385dlg_title = 'select properties of the output avi movie';
4386num_lines= 1;
4387% nbfield_cell=get(handles.last_i,'String');
4388def     = {[FileBase '_out.avi'];'10';'1';'[0.03 0.05 0.95 0.92]';'10'};
4389answer = inputdlg(prompt,dlg_title,num_lines,def,'on');
4390aviname=answer{1};
4391fps=str2double(answer{2});
4392% check for existing file with output name aviname
4393if exist(aviname,'file')
4394    backup=aviname;
4395    testexist=2;
4396    while testexist==2
4397        backup=[backup '~'];
4398        testexist=exist(backup,'file');     
4399    end
4400    [success,message]=copyfile(aviname,backup);%make backup of the existing file
4401    if isequal(success,1)
4402        delete(aviname)%delete existing file
4403    else
4404        msgbox_uvmat('ERROR',message)
4405        return
4406    end
4407end
4408%create avi open
4409aviobj=avifile(aviname,'Compression','None','fps',fps);
4410
4411%display first view for tests
4412newfig=figure;
4413newaxes=copyobj(handles.axes3,newfig);%new plotting axes in the new figure
4414set(newaxes,'Tag','movieaxes')
4415nbpix=[512 384]*str2double(answer{3});
4416set(gcf,'Position',[1 1 nbpix])% resolution XVGA
4417set(newaxes,'Position',eval(answer{4}));
4418map=colormap(handles.axes3);
4419colormap(map);%transmit the current colormap to the zoom fig
4420msgbox_uvmat('INPUT_Y-N',{['adjust figure ' num2str(newfig) ' with its matlab edit menu '] ;...
4421        ['then press OK to get the avi movie as a copy of figure ' num2str(newfig) ' display']});
4422UvData.plotaxes=newaxes;% the axis in the new figure becomes the current main plotting axes
4423set(huvmat,'UserData',UvData);
4424increment=str2num(get(handles.increment_scan,'String')); %get the field increment d
4425set(handles.STOP,'Visible','on')
4426set(handles.speed,'Visible','on')
4427set(handles.speed_txt,'Visible','on')
4428set(handles.Movie,'BusyAction','queue')
4429
4430%imin=str2double(get(handles.i1,'String'));
4431imax=str2double(answer{5});
4432% if isfield(UvData,'Time')
4433htitle=get(newaxes,'Title');
4434xlim=get(newaxes,'XLim');
4435ylim=get(newaxes,'YLim');
4436set(htitle,'Position',[xlim(2)+0.07*(xlim(2)-xlim(1)) ylim(2)-0.05*(ylim(2)-ylim(1)) 0])
4437time_str=get(handles.abs_time,'String');
4438set(htitle,'String',['t=' time_str])
4439set(handles.speed,'Value',1)
4440for i=1:imax
4441    if get(handles.speed,'Value')~=0 && isequal(get(handles.MenuExportMovie,'BusyAction'),'queue') % enable STOP command
4442            runpm(hObject,eventdata,handles,increment)% run plus
4443            drawnow
4444            time_str=get(handles.abs_time,'String');
4445            if ishandle(htitle)
4446             set(htitle,'String',['t=' time_str])
4447            end
4448            mov=getframe(newfig);
4449            aviobj=addframe(aviobj,mov);
4450    end
4451end
4452aviobj=close(aviobj);
4453UvData=rmfield(UvData,'plotaxes');
4454%UvData.Object{1}.plotaxes=handles.axes3;
4455set(huvmat,'UserData',UvData);
4456msgbox_uvmat('CONFIRMATION',{['movie ' aviname ' created '];['with ' num2str(imax) ' frames']})
4457
[402]4458
4459%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4460% Projection Objects Menu Callbacks
4461%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4462
4463% -----------------------------------------------------------------------
4464function Menupoints_Callback(hObject, eventdata, handles)
[387]4465%------------------------------------------------------------------------
[402]4466data.Type='points';
4467data.ProjMode='projection';%default
[410]4468data.ProjModeMenu={};% do not restrict ProjMode menus
[402]4469create_object(data,handles)
4470
4471% -----------------------------------------------------------------------
4472function Menuline_Callback(hObject, eventdata, handles)
4473%------------------------------------------------------------------------
4474data.Type='line';
4475data.ProjMode='projection';%default
[410]4476data.ProjModeMenu={};% do not restrict ProjMode menus
[402]4477create_object(data,handles)
4478
4479%------------------------------------------------------------------------
4480function Menupolyline_Callback(hObject, eventdata, handles)
4481%------------------------------------------------------------------------
4482data.Type='polyline';
4483data.ProjMode='projection';%default
[410]4484data.ProjModeMenu={};% do not restrict ProjMode menus
[402]4485create_object(data,handles)
4486
4487%------------------------------------------------------------------------
4488function Menupolygon_Callback(hObject, eventdata, handles)
4489%------------------------------------------------------------------------
4490data.Type='polygon';
4491data.ProjMode='inside';%default
[410]4492data.ProjModeMenu={};% do not restrict ProjMode menus
[402]4493create_object(data,handles)
4494
4495%------------------------------------------------------------------------
4496function Menurectangle_Callback(hObject, eventdata, handles)
4497%------------------------------------------------------------------------
4498data.Type='rectangle';
4499data.ProjMode='inside';%default
[410]4500data.ProjModeMenu={};% do not restrict ProjMode menus
[402]4501create_object(data,handles)
4502
4503%------------------------------------------------------------------------
4504function Menuellipse_Callback(hObject, eventdata, handles)
4505%------------------------------------------------------------------------
4506data.Type='ellipse';
4507data.ProjMode='inside';%default
[410]4508data.ProjModeMenu={};% do not restrict ProjMode menus
[402]4509create_object(data,handles)
4510
4511%------------------------------------------------------------------------
4512function MenuMaskObject_Callback(hObject, eventdata, handles)
4513%------------------------------------------------------------------------
4514data.Type='polygon';
4515data.TypeMenu={'polygon'};
4516data.ProjMode='mask_inside';%default
4517data.ProjModeMenu={'mask_inside';'mask_outside'};
4518create_object(data,handles)
4519
4520%------------------------------------------------------------------------
4521function Menuplane_Callback(hObject, eventdata, handles)
4522%------------------------------------------------------------------------
4523data.Type='plane';
4524data.ProjMode='projection';%default
[410]4525data.ProjModeMenu={};% do not restrict ProjMode menus
[402]4526create_object(data,handles)
4527
4528%------------------------------------------------------------------------
4529function Menuvolume_Callback(hObject, eventdata, handles)
4530%------------------------------------------------------------------------
4531data.Type='volume';
4532data.ProjMode='interp';%default
[410]4533data.ProjModeMenu={};
[402]4534% set(handles.create,'Visible','on')
4535% set(handles.create,'Value',1)
[410]4536% VOLUME_Callback(hObject,eventdata,handles)data.ProjModeMenu={};
[402]4537create_object(data,handles)
4538
4539%------------------------------------------------------------------------
4540% --- generic function used for the creation of a projection object
4541function create_object(data,handles)
4542%------------------------------------------------------------------------
[410]4543% desactivate geometric calibration if opened
[402]4544hgeometry_calib=findobj(allchild(0),'tag','geometry_calib');
4545if ishandle(hgeometry_calib)
4546    hhgeometry_calib=guidata(hgeometry_calib);
4547    set(hhgeometry_calib.edit_append,'Value',0)% desactivate mouse action in geometry_calib
4548    set(hhgeometry_calib.edit_append,'BackgroundColor',[0.7 0.7 0.7])
4549end
4550set(handles.edit_object,'Value',0); %suppress the object edit mode
4551set(handles.edit_object,'BackgroundColor',[0.7,0.7,0.7]) 
[429]4552ListObject=get(handles.ListObject,'String');
4553if ~strcmp(ListObject{end},'')
4554    ListObject=[ListObject;{''}]; %append a blank to the list (if nort already done) to indicate the creation of a new object
4555    set(handles.ListObject,'String',ListObject)
4556end
4557IndexObj=length(ListObject);
4558set(handles.ListObject,'Value',IndexObj)
[410]4559UvData=get(handles.uvmat,'UserData');
[429]4560UvData.Object{IndexObj}=[]; %create a new empty object
[432]4561UvData.Object{IndexObj}.DisplayHandle.uvmat=handles.axes3; % axes for plot_object
4562UvData.Object{IndexObj}.DisplayHandle.view_field=[]; %no plot handle before plot_field operation
[410]4563data.Name=data.Type;% default name=type
[402]4564data.Coord=[0 0]; %default
4565if isfield(UvData,'Field')
4566    Field=UvData.Field;
[404]4567    if isfield(UvData.Field,'Mesh')&&~isempty(UvData.Field.Mesh)
4568        data.RangeX=[UvData.Field.XMin UvData.Field.XMax];
[410]4569        if strcmp(data.Type,'line')||strcmp(data.Type,'polyline')||strcmp(data.Type,'points')
[406]4570            data.RangeY=UvData.Field.Mesh;
4571        else
4572            data.RangeY=[UvData.Field.YMin UvData.Field.YMax];
4573        end
[404]4574        data.DX=UvData.Field.Mesh;
4575        data.DY=UvData.Field.Mesh;
[402]4576    end
4577    if isfield(Field,'NbDim')&& isequal(Field.NbDim,3)
4578         data.Coord=[0 0 0]; %default
4579    end
4580    if isfield(Field,'CoordUnit')
4581        data.CoordUnit=Field.CoordUnit;
4582    end
4583end
4584if ishandle(handles.UVMAT_title)
4585    delete(handles.UVMAT_title)%delete the initial display of uvmat if no field has been entered
4586end
4587hset_object=set_object(data,handles);% call the set_object interface
4588hhset_object=guidata(hset_object);
[421]4589hchild=get(hset_object,'children');
4590set(hchild,'enable','on')
[402]4591set(handles.uvmat,'UserData',UvData)
[410]4592set(handles.CheckZoom,'Value',0) %desactivate the zoom for object creation by the mouse
[402]4593CheckZoom_Callback(handles.uvmat, [], handles)
4594set(handles.delete_object,'Visible','on')
4595
4596%------------------------------------------------------------------------
4597function MenuBrowseObject_Callback(hObject, eventdata, handles)
4598%------------------------------------------------------------------------
4599%get the object file
4600[FileName, PathName, filterindex] = uigetfile( ...
4601       {'*.xml;*.mat', ' (*.xml,*.mat)';
4602       '*.xml',  '.xml files '; ...
4603        '*.mat',  '.mat matlab files '}, ...
4604        'Pick an xml Object file',get(handles.RootPath,'String'));
4605fileinput=[PathName FileName];%complete file name
4606sizf=size(fileinput);
4607if (~ischar(fileinput)||~isequal(sizf(1),1)),return;end
4608
4609%read the file
[477]4610[data,heading]=xml2struct(fileinput);
4611if ~strcmp(heading,'ProjObject')
4612    msgbox_uvmat('WARNING','The xml file does not have the heading ProjObject for projection objects')
4613end
[427]4614[tild,data.Name]=fileparts(FileName);% object name set as file name
[429]4615ListObject=get(handles.ListObject,'String');
4616if ~strcmp(ListObject{end},'')
4617    ListObject=[ListObject;{''}]; %append a blank to the list (if not already done) to indicate the creation of a new object
4618    set(handles.ListObject,'String',ListObject)
4619end
[445]4620IndexObj=length(ListObject);
4621
[432]4622UvData=get(handles.uvmat,'UserData');
4623UvData.Object{IndexObj}=[]; %create a new empty object
4624UvData.Object{IndexObj}.DisplayHandle.uvmat=[]; %no plot handle before plot_field operation
4625UvData.Object{IndexObj}.DisplayHandle.view_field=[]; %no plot handle before plot_field operation
4626set(handles.uvmat,'UserData',UvData)
[445]4627set(handles.ListObject,'Value',IndexObj)
[427]4628hset_object=set_object(data);% call the set_object interface
4629set(get(hset_object,'children'),'enable','on')% enable edit action on elements on GUI set_object
[402]4630set(handles.edit_object,'Value',0); %suppress the object edit mode
4631set(handles.edit_object,'BackgroundColor',[0.7,0.7,0.7]) 
4632set(handles.delete_object,'Visible','on')
4633
[432]4634
[402]4635%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4636% MenuEdit Callbacks
4637%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4638%------------------------------------------------------------------------
4639function MenuEditObject_Callback(hObject, eventdata, handles)
4640%------------------------------------------------------------------------
4641set(handles.edit_object,'Value',1)
4642edit_Callback(hObject, eventdata, handles)
4643
4644%------------------------------------------------------------------------
4645function MenuEditVectors_Callback(hObject, eventdata, handles)
4646%------------------------------------------------------------------------
4647set(handles.edit_vect,'Visible','on')
4648set(handles.edit_vect,'Value',1)
4649edit_vect_Callback(hObject, eventdata, handles)
4650
4651%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4652% MenuTools Callbacks
4653%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4654%------------------------------------------------------------------------
[387]4655function MenuCalib_Callback(hObject, eventdata, handles)
4656%------------------------------------------------------------------------
4657
4658UvData=get(handles.uvmat,'UserData');%read UvData properties stored on the uvmat interface
4659
4660%suppress competing options
4661set(handles.CheckZoom,'Value',0)
4662set(handles.CheckZoom,'BackgroundColor',[0.7 0.7 0.7])
4663set(handles.ListObject,'Value',1)     
4664% initiate display of GUI geometry_calib
4665data=[]; %default
4666if isfield(UvData,'CoordType')
4667    data.CoordType=UvData.CoordType;
4668end
4669pos=get(handles.uvmat,'Position');
4670pos(1)=pos(1)+pos(3)-0.311+0.04; %0.311= width of the geometry_calib interface (units relative to the srcreen)
4671pos(2)=pos(2)-0.02;
4672[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
4673FileName=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
4674set(handles.view_xml,'Backgroundcolor',[1 1 0])%indicate the reading of the current xml file by geometry_calib
4675if isfield(UvData.OpenParam,'CalOrigin')
4676    pos_uvmat=get(handles.uvmat,'Position');
4677    pos_cal(1)=pos_uvmat(1)+UvData.OpenParam.CalOrigin(1)*pos_uvmat(3);
4678    pos_cal(2)=pos_uvmat(2)+UvData.OpenParam.CalOrigin(2)*pos_uvmat(4);
4679    pos_cal(3:4)=UvData.OpenParam.CalSize .* pos_uvmat(3:4);
4680end
4681geometry_calib(FileName,pos_cal);% call the geometry_calib interface   
4682set(handles.view_xml,'Backgroundcolor',[1 1 1])%indicate the end of reading of the current xml file by geometry_calib
4683set(handles.MenuCalib,'checked','on')% indicate that MenuCalib is activated, test used by mouse action
4684
4685%------------------------------------------------------------------------
4686function MenuMask_Callback(hObject, eventdata, handles)
4687%------------------------------------------------------------------------
4688UvData=get(handles.uvmat,'UserData');%read UvData properties stored on the uvmat interface
4689ListObj=UvData.Object;
4690select=zeros(1,numel(ListObj));
4691for iobj=1:numel(ListObj);
4692    if strcmp(ListObj{iobj}.ProjMode,'mask_inside')||strcmp(ListObj{iobj}.ProjMode,'mask_outside')
4693        select(iobj)=1;
4694    end
4695end
4696val=find(select);
4697if isempty(val)
4698    msgbox_uvmat('ERROR','polygons must be first created by Projection object/mask polygon in the menu bar');
4699    return
4700else
[410]4701%     set(handles.ListObject,'Max',2);%allow multiple selection
[387]4702    set(handles.ListObject,'Value',val);
4703    flag=1;
4704    npx=size(UvData.Field.A,2);
4705    npy=size(UvData.Field.A,1);
4706    xi=0.5:npx-0.5;
4707    yi=0.5:npy-0.5;
4708    [Xi,Yi]=meshgrid(xi,yi);
4709    if isfield(UvData,'Object')
4710        for iobj=1:length(UvData.Object)
4711            ObjectData=UvData.Object{iobj};
4712            if isfield(ObjectData,'ProjMode') &&(isequal(ObjectData.ProjMode,'mask_inside')||isequal(ObjectData.ProjMode,'mask_outside'));
4713                flagobj=1;
4714                testphys=0; %coordinates in pixels by default
4715                if isfield(ObjectData,'CoordUnit') && ~isequal(ObjectData.CoordUnit,'pixel')
4716                    if isfield(UvData,'XmlData')&& isfield(UvData.XmlData{1},'GeometryCalib')
4717                        Calib=UvData.XmlData{1}.GeometryCalib;
4718                        testphys=1;
4719                    end
4720                end
4721                if isfield(ObjectData,'Coord')&& isfield(ObjectData,'Type')
4722                    if isequal(ObjectData.Type,'polygon')
4723                        X=ObjectData.Coord(:,1);
4724                        Y=ObjectData.Coord(:,2);
4725                        if testphys
4726                            [X,Y]=px_XYZ(Calib,X,Y,0);% to generalise with 3D cases
4727                        end
4728                        flagobj=~inpolygon(Xi,Yi,X',Y');%=0 inside the polygon, 1 outside
4729                    elseif isequal(ObjectData.Type,'ellipse')
4730                        if testphys
4731                            %[X,Y]=px_XYZ(Calib,X,Y,0);% TODO:create a polygon boundary and transform to phys
4732                        end
4733                        RangeX=max(ObjectData.RangeX);
4734                        RangeY=max(ObjectData.RangeY);
4735                        X2Max=RangeX*RangeX;
4736                        Y2Max=RangeY*RangeY;
4737                        distX=(Xi-ObjectData.Coord(1,1));
4738                        distY=(Yi-ObjectData.Coord(1,2));
4739                        flagobj=(distX.*distX/X2Max+distY.*distY/Y2Max)>1;
4740                    elseif isequal(ObjectData.Type,'rectangle')
4741                        if testphys
4742                            %[X,Y]=px_XYZ(Calib,X,Y,0);% TODO:create a polygon boundary and transform to phys
4743                        end
4744                        distX=abs(Xi-ObjectData.Coord(1,1));
4745                        distY=abs(Yi-ObjectData.Coord(1,2));
4746                        flagobj=distX>max(ObjectData.RangeX) | distY>max(ObjectData.RangeY);
4747                    end
4748                    if isequal(ObjectData.ProjMode,'mask_outside')
4749                        flagobj=~flagobj;
4750                    end
4751                    flag=flag & flagobj;
4752                end
4753            end
4754        end
4755    end
4756    %mask name
4757    RootPath=get(handles.RootPath,'String');
[444]4758    SubDir=get(handles.SubDir,'String');
[387]4759    RootFile=get(handles.RootFile,'String');
4760    if ~isempty(RootFile)&&(isequal(RootFile(1),'/')|| isequal(RootFile(1),'\'))
4761        RootFile(1)=[];
4762    end
[444]4763   % filebase=fullfile(RootPath,RootFile);
[387]4764    list=get(handles.masklevel,'String');
4765    masknumber=num2str(length(list));
4766    maskindex=get(handles.masklevel,'Value');
[444]4767   % mask_name=fullfile_uvmat(RootPath,'',[RootFile '_' masknumber 'mask'],'.png','_1',maskindex);
4768    mask_name=fullfile_uvmat(RootPath,[SubDir '.mask'],'mask','.png','_1',maskindex);
[387]4769    imflag=uint8(255*(0.392+0.608*flag));% =100 for flag=0 (vectors not computed when 20<imflag<200)
4770    imflag=flipdim(imflag,1);
4771
4772    %display the mask
4773    hfigmask=figure;
4774    set(hfigmask,'Name','mask image')
4775    vec=linspace(0,1,256);%define a linear greyscale colormap
4776    map=[vec' vec' vec'];
4777    colormap(map)
4778    image(imflag);
4779    answer=msgbox_uvmat('INPUT_TXT','mask file name:', mask_name);
4780    if ~strcmp(answer,'Cancel')
4781        mask_dir=fileparts(answer);
4782        if ~exist(mask_dir,'dir')
[444]4783            [xx,msg1]=mkdir(mask_dir);
4784            if ~strcmp(msg1,'')
4785                errormsg=['cannot create ' mask_dir ': ' msg1];%error message for directory creation
4786                return
4787            end
[387]4788        end
4789        imwrite(imflag,answer,'BitDepth',8);
4790    end
4791    set(handles.ListObject,'Value',1)
4792end
4793
4794%------------------------------------------------------------------------
4795%-- open the GUI set_grid.fig to create grid
4796function MenuGrid_Callback(hObject, eventdata, handles)
4797%------------------------------------------------------------------------
4798%suppress the other options if grid is chosen
4799set(handles.edit_vect,'Value',0)
4800edit_vect_Callback(hObject, eventdata, handles)
4801set(handles.edit_object,'BackgroundColor',[0.7 0.7 0.7])
4802set(handles.ListObject,'Value',1)     
4803
4804%prepare display of the set_grid GUI
4805[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
4806FileName=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
4807CoordList=get(handles.transform_fct,'String');
4808val=get(handles.transform_fct,'Value');
4809set_grid(FileName,CoordList{val});% call the set_object interface
4810
[402]4811
[387]4812%------------------------------------------------------------------------
[402]4813function MenuRuler_Callback(hObject, eventdata, handles)
4814%------------------------------------------------------------------------
4815set(handles.CheckZoom,'Value',0)
4816CheckZoom_Callback(handles.uvmat, [], handles)
4817set(handles.MenuRuler,'checked','on')
4818UvData=get(handles.uvmat,'UserData');
4819UvData.MouseAction='ruler';
4820set(handles.uvmat,'UserData',UvData);
4821
4822%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4823% MenuRun Callbacks
4824%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4825
4826%------------------------------------------------------------------------
[387]4827% open the GUI 'series'
4828function MenuSeries_Callback(hObject, eventdata, handles)
4829%------------------------------------------------------------------------
4830series; %first display of the GUI to fill waiting time
4831[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
4832param.FileName=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
4833if isequal(get(handles.SubField,'Value'),1)
4834    [RootPath_1,SubDir_1,RootFile_1,FileIndices_1,FileExt_1]=read_file_boxes_1(handles);
4835    FileName_1=[fullfile(RootPath_1,SubDir_1,RootFile_1) FileIndices_1 FileExt_1];
4836    if ~isequal(FileName_1,param.FileName)
4837        param.FileName_1=FileName_1;
4838    end
4839end
4840param.NomType=get(handles.NomType,'String');
4841param.NomType_1=get(handles.NomType_1,'String');
4842param.CheckFixPair=get(handles.CheckFixPair,'Value');
4843huvmat=get(handles.MenuSeries,'parent');
4844UvData=get(huvmat,'UserData');
4845if isfield(UvData,'XmlData')&& isfield(UvData.XmlData{1},'Time')
4846    param.Time=UvData.XmlData{1}.Time;
4847end
4848if isequal(get(handles.scan_i,'Value'),1)
4849    param.incr_i=str2num(get(handles.increment_scan,'String'));
4850elseif isequal(get(handles.scan_j,'Value'),1)
4851    param.incr_j=str2num(get(handles.increment_scan,'String'));
4852end
4853param.list_fields=get(handles.Fields,'String');% list menu fields
4854param.list_fields(1)=[]; %suppress  'image' option
4855param.index_fields=get(handles.Fields,'Value');% selected string index
4856if param.index_fields>1
4857    param.index_fields=param.index_fields-1;
4858end
4859param.list_fields_1=get(handles.Fields_1,'String');% list menu fields
4860param.list_fields_1(1)=[]; %suppress  'image' option
4861param.index_fields_1=get(handles.Fields_1,'Value')-1;% selected string index
4862if param.index_fields_1>1
4863    param.index_fields_1=param.index_fields_1-1;
4864end
4865param.menu_coord_str=get(handles.transform_fct,'String');
4866param.menu_coord_val=get(handles.transform_fct,'Value');
4867series(param); %run the series interface
4868
4869%------------------------------------------------------------------------
[402]4870% -- open the GUI civ.fig for PIV
[387]4871function MenuPIV_Callback(hObject, eventdata, handles)
4872%------------------------------------------------------------------------
4873 [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
4874 FileName=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
4875civ(FileName);% interface de civ(not in the uvmat file)
4876
[402]4877% --------------------------------------------------------------------
4878function MenuHelp_Callback(hObject, eventdata, handles)
4879% --------------------------------------------------------------------
4880path_to_uvmat=which ('uvmat');% check the path of uvmat
4881pathelp=fileparts(path_to_uvmat);
4882helpfile=fullfile(pathelp,'uvmat_doc','uvmat_doc.html');
4883if isempty(dir(helpfile)), msgbox_uvmat('ERROR','Please put the help file uvmat_doc.html in the sub-directory /uvmat_doc of the UVMAT package')
4884else
4885    addpath (fullfile(pathelp,'uvmat_doc'))
4886    web(helpfile);
[387]4887end
Note: See TracBrowser for help on using the repository browser.