source: trunk/src/uvmat.m @ 748

Last change on this file since 748 was 748, checked in by sommeria, 10 years ago

update for 3D plots, panel Coordiantes introduces, while coordiantes now called Axes

File size: 248.1 KB
Line 
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 fieldname (with fieldname
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:(use 'Export/field in workspace' in
31% the menu bar of uvmat to retrieve it)
32%          .OpenParam: structure containing parameters defined when uvmat is opened
33%                       .PosColorbar: position (1x4 vector)of the colorbar (relative to the fig uvmat)
34%                       .PosGeometryCalib: size of set_object
35%                       .NbBuiltin: nbre of functions always displayed in TransformName menu
36%          .ProjObject: cell array of structures representing the current projection objects, as produced by 'set_object.m'={[]} by default
37%          .NewSeries: =0/1 flag telling whether a new field series has been opened
38%          .FileName_1: name of the current second field (used to detect a  constant field during file scanning)
39%          .FileType: current file type, as defined by the fct  get_file_type.m)
40%          .i1_series,.i2_series,.j1_series,.j1_series: series of i1,i2,j1,j2 indices detected in the input dir,set by  the fct find_file_series
41%          .MovieObject: current movie object
42%          .TimeUnit: unit for time
43%          .XmlData: cell array of 1 or 2 structures representing the xml files associated with the input fieldname (containing timing  and geometry calibration)
44%          .Field: cell array of 1 or 2 structures representing the current  input field(s)
45%          .PlotAxes: field structure representing the current field plotted  on the main axes  (used for mouse operations)
46%          .HistoAxes: idem for histogram axes
47
48% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%   DATA FLOW  (for REFRESH_Callback) %%%%%%%%%%%%%%%%%%%%:
49%
50%
51% 1) Input filenames are determined by MenuBrowse (first field), MenuBrowseCampaign
52% (second field), or by the stored file name .FileName_1, or as an input of uvmat.
53% 2) These functions call 'uvmat/display_file_name.m' which detects the file series, and fills the file index boxes
54% 3) Then 'uvmat/update_rootinfo.m' Updates information about a new field series (indices to scan, timing, calibration from an xml file)
55% 4) Then fieldname are opened and visualised by the main sub-function 'uvmat/refresh_field.m'
56% The function first reads the name of the input file(s) (one or two) from the edit boxes  of the GUI
57% It then reads the input file(s) with the function read_field.m and perform the following list of operations:
58%
59%    %%%%%%%%  structure of uvmat/refresh_field.m %%%%%%%%
60%
61%           Main input open       second input open_1       
62%                    |                   | 
63%             read_field.m            read_field.m
64%                    |                   |
65%                 Field{1}            Field{2}               
66%                    |                   |                                 
67%                    --->transform fct<---             transform (e.g. phys.m) and combine input fieldname 
68%                            |                                   
69%                        (tps_coeff_field.m)               calculate tps coefficients (for filter projection or spatial derivatives).
70%                            |
71%                       UvData.Field-------------->histogram
72%               _____________|____________
73%              |                          |                   
74%        proj_field.m               proj_field.m       project the field on the projection objects (use set_field_list.m)           
75%              |                          |
76%         UvData.PlotAxes          ViewData.PlotAxes (on view_field)
77%              |                          |
78%       plot_field.m (uvmat)       plot_field.m (view_field)      plot the projected fieldname
79%
80%
81%%%%%%%%%%%%%%    SCALARS: %%%%%%%%%%%%??%%%
82% scalars are displayed either as an image or countour plot, either as a color of
83% velocity vectors. The scalar values in the first case is represented by
84% UvData.Field.A, and by UvData.Field.C in the second case. The corresponding set of X
85% and Y axes are represented by UvData.Field.AX and UvData.Field.AY, and .X and
86% .Y for C (the same as velocity vectors). If A is a nxxny matrix (scalar
87% on a regtular grid), then .AX andf.AY contains only two elements, represneting the
88% axes of the four image corners. The scalar name is represented by
89% the strings .AName and/or .CName.
90% If the scalar exists in an input open (image or scalar stored under its
91% name in a netcdf open), it is directly read at the level of Field{1}or Field{2}.
92% Else only its name AName is recorded in Field{i}, and its field is then calculated
93%by the fuction calc_scal after the coordinate transform or after projection on an CheckEditObject
94     
95% Properties attached to plotting figures (standard Matlab properties):
96%    'CurrentAxes'= gca or get(gcf,'CurrentAxes');
97%    'CurrentPoint'=get(gcf,'CurrentPoint'): figure axes of the point over which the mouse is positioned
98%    'CurrentCharacter'=get(gcf,'CurrentCharacter'): last character typed  over the figure where the mouse is positioned
99%    'WindowButtonMotionFcn': function permanently called by mouse motion over the figure
100%    'KeyPressFcn': function called by pressing a key on the key board
101%    'WindowButtonDownFcn':  function called by pressing the mouse over the  figure
102%    'WindowButtonUpFcn': function called by releasing  the mouse pressure over the  figure
103
104% Properties attached to plotting axes:
105%    'CurrentPoint'=get(gca,'CurrentPoint'); (standard Matlab) same as for the figure, but position in plot axes.
106%     AxeData:=get(gca,'UserData');
107%     AxeData.Drawing  = create: create a new object
108%                       = deform: modify an existing object by moving its defining create
109%                      = off: no current drawing action
110%                     = translate: translate an existing object
111%                    = calibration: move a calibration point
112%                    = CheckZoom: isolate a subregion for CheckZoom in=1 if an object is being currently drawn, 0 else (set to 0 by releasing mouse button)
113%            .CurrentOrigin: Origin of a curently drawn CheckEditObject
114%            .CurrentLine: currently drawn menuline (A REVOIR)
115%            .CurrentObject: handle of the currently drawn CheckEditObject
116%            .CurrentRectZoom: current rectangle used for CheckZoom
117
118% Properties attached to projection objects (create, menuline, menuplane...):
119%    'Tag'='proj_object': for all projection objects
120%    ObjectData.Type=...: style of projection object:
121%              .ProjMode
122%              .Coordinates: defines the position of the object
123%              .XMin,YMin....
124%              .XMax,YMax....
125%              .DX,DY,DZ
126%              .Phi, .Theta, .Psi : Euler angles
127%              .X,.Y,.U,.V.... : field data projected on the object
128%              .IndexObj: index in the list of UvData.ProjObject
129           %during plotting
130%               .plotaxes: handles of the current axes used to plot the  result of field projection on the object
131%               .plothandle: vector of handle(s) of the object graphic represnetation in all the opened plotting axes
132% To each projection object #iobj, corresponds an axis
133% Object{iobj}.plotaxes and nbobj representation graphs  Object{iobj}.plothandles(:) (where nbobj is the
134% nbre of current objects opened in uvmat. Note that Object{iobj}.plothandles(iobj)=[] : an object is not represented in its own projection field;
135
136%------------------------------------------------------------------------
137%------------------------------------------------------------------------
138%  I - MAIN FUNCTION uvmat
139%------------------------------------------------------------------------
140%------------------------------------------------------------------------
141function varargout = uvmat(varargin)
142
143% Begin initialization code - DO NOT EDIT
144gui_Singleton = 1;
145gui_State = struct('gui_Name',          mfilename, ...
146                   'gui_Singleton',     gui_Singleton, ...
147                   'gui_OpeningFcn',    @uvmat_OpeningFcn, ...
148                   'gui_OutputFcn',     @uvmat_OutputFcn, ...
149                   'gui_LayoutFcn',     [], ...
150                   'gui_Callback',      []);
151if nargin && ischar(varargin{1})&& ~isempty(regexp(varargin{1},'_Callback','once'))
152    gui_State.gui_Callback = str2func(varargin{1});
153end
154
155if nargout
156    varargout{1:nargout} = gui_mainfcn(gui_State, varargin{:});
157else
158    gui_mainfcn(gui_State, varargin{:});
159end
160% End initialization code - DO NOT EDIT
161
162%------------------------------------------------------------------------
163% --- Executes just before the GUI uvmat is made visible.
164function uvmat_OpeningFcn(hObject, eventdata, handles, input )
165%------------------------------------------------------------------------
166
167%% Choose default command menuline output for uvmat (standard GUI)
168handles.output = hObject;
169
170%% Update handles structure (standard GUI)
171guidata(hObject, handles);
172
173%% add the path to uvmat (useful if uvmat has been opened in the working directory and a working directory change occured)
174path_uvmat=fileparts(which('uvmat'));
175
176%% set the position of the GUI, colorbar and ancillary GUIs:
177set(hObject,'Units','pixels')%
178set(0,'Units','pixels');
179ScreenSize=get(0,'ScreenSize');%size of the current screen
180Width=1050;
181Height=700;
182%adjust to screen size (reduced by a min margin)
183RescaleFactor=min((ScreenSize(3)-80)/Width,(ScreenSize(4)-80)/Height);
184if RescaleFactor>1
185    RescaleFactor=RescaleFactor/2+1/2; %reduce the rescale factor to provide an increased margin for a big screen
186end
187Width=Width*RescaleFactor;
188Height=Height*RescaleFactor;
189LeftX=80*RescaleFactor;%position of the left fig side, in pixels (put to the left side, with some margin)
190LowY=round(ScreenSize(4)/2-Height/2); % put at the middle height on the screen
191set(hObject,'Position',[LeftX LowY Width Height])
192UvData.OpenParam.PosColorbar=[0.80 0.02 0.018 0.445];
193AxeData.LimEditBox=1; %initialise AxeData
194set(handles.PlotAxes,'UserData',AxeData)
195% position of table Coord_y
196%set(handles.Coord_y,'Unit','pixel')
197% Pos=get(handles.Coord_y,'Position');
198% set(handles.Coord_y,'Unit','normalized')
199% set(handles.Coord_y,'ColumnWidth',{Pos(3)})
200% set(handles.Coord_y,'ColumnFormat',{'char'})
201% set(handles.Coord_y,'ColumnEditable',false)
202% set(handles.Coord_y,'ColumnName',{''})
203
204%% set functions for the mouse and keyboard
205set(hObject,'WindowKeyPressFcn',{'keyboard_callback',handles})%set keyboard action function
206set(hObject,'WindowButtonMotionFcn',{'mouse_motion',handles})%set mouse action functio
207set(hObject,'WindowButtonDownFcn',{'mouse_down'})%set mouse click action function
208set(hObject,'WindowButtonUpFcn',{'mouse_up',handles})
209set(hObject,'DeleteFcn',{@closefcn})%
210set(hObject,'ResizeFcn',{@ResizeFcn,handles})%
211% set(handles.RootPath,'ButtonDownFcn',{'@mouse_down_control'})%set mouse click action function
212
213%% initialisation
214set(handles.FieldName,'Value',1)
215set(handles.FieldName,'string',{''})
216UvData.ProjObject={[]};
217
218%% TRANSFORM menu: builtin fcts
219transform_menu={'';'sub_field';'phys';'phys_polar'};
220UvData.OpenParam.NbBuiltin=numel(transform_menu); %number of functions
221transform_path=fullfile(path_uvmat,'transform_field');
222path_list=cell(UvData.OpenParam.NbBuiltin,1);
223path_list{1}='';
224for ilist=2:UvData.OpenParam.NbBuiltin
225path_list{ilist}=transform_path; % set transform_path to the path_list
226end
227
228%% load the list of previously browsed files in menus Open, Open_1 and TransformName
229dir_perso=prefdir; % path to the directory .matlab containing the personal data of the current user
230profil_perso=fullfile(dir_perso,'uvmat_perso.mat');% personal data file uvmat_perso.mat' in .matlab
231if exist(profil_perso,'file')% if the file exists
232    h=load (profil_perso); % open the personal file
233    if isfield(h,'MenuFile')% load the saved menu of previously opened files
234        for ifile=1:min(length(h.MenuFile),5)
235            set(handles.(['MenuFile_' num2str(ifile)]),'Label',h.MenuFile{ifile});
236        end
237    end
238    if isfield(h,'MenuCampaign')% load the saved menu of previously opened campaigns
239        for ifile=1:min(length(h.MenuCampaign),5)
240            set(handles.(['MenuCampaign_' num2str(ifile)]),'Label',h.MenuCampaign{ifile});
241        end
242    end
243    if isfield(h,'RootPath')
244        set(handles.RootPath,'UserData',h.RootPath); %store the previous campaign in the UserData of RootPath
245    end
246    if isfield(h,'transform_fct') && iscell(h.transform_fct) % load the menu of transform fct set by user
247        for ilist=1:length(h.transform_fct);
248            if exist(h.transform_fct{ilist},'file')
249                [path,file]=fileparts(h.transform_fct{ilist});
250                transform_menu=[transform_menu; {file}];
251                path_list=[path_list; {path}];
252            end
253        end
254    end
255end
256transform_menu=[transform_menu;{'more...'}];%append the option more.. to the menu
257set(handles.TransformName,'String',transform_menu)% display the menu of transform fcts
258set(handles.TransformName,'UserData',path_list)% store the corresponding list of path in UserData of uicontrol transform_fct
259set(handles.TransformPath,'String','')
260set(handles.TransformPath,'UserData',[])
261
262%% case of an input argument for uvmat
263testinputfield=0;
264inputfile=[];
265Field=[];
266if exist('input','var')
267    if ishandle(handles.UVMAT_title)
268        delete(handles.UVMAT_title)
269    end   
270    if isstruct(input)
271        if isfield(input,'InputFile')
272            inputfile=input.InputFile;
273        end
274        if isfield(input,'TimeIndex')
275            set(handles.i1,num2str(input.TimeIndex))
276        end
277        if isfield(input,'FieldsString')
278            UvData.FieldsString=input.FieldsString;
279        end
280    elseif ischar(input)% file name introduced as input
281           inputfile=input;
282    elseif isnumeric(input)%simple matrix introduced as input
283        sizinput=size(input);
284        if sizinput(1)<=1 || sizinput(2)<=1
285            msgbox_uvmat('ERROR','bad input for uvmat: file name, structure or numerical matrix accepted')
286            return
287        end
288        UvData.Field.ListVarName={'A','coord_y','coord_x'};
289        UvData.Field.VarDimName={{'coord_y','coord_x'},'cord_y','coord_x'};
290        UvData.Field.A=input;
291        UvData.Field.coord_x=[0.5 size(input,2)-0.5];
292        UvData.Field.coord_y=[size(input,1)-0.5 0.5];
293        testinputfield=1;
294    end
295else
296    %% check the path and date of modification of all functions in uvmat
297    path_to_uvmat=which ('uvmat');% check the path detected for source file uvmat
298    [infomsg,date_str,svn_info]=check_files;%check the path of the functions called by uvmat.m   
299    date_str=['last modification: ' date_str];
300    if ishandle(handles.UVMAT_title)
301        set(handles.UVMAT_title,'String',...
302            [{'Copyright  LEGI UMR 5519 /CNRS-UJF-Grenoble INP, 2010'};...
303            {'GNU General Public License'};...
304            {path_to_uvmat};...
305            {date_str};...
306            infomsg]);
307    end
308end
309set(handles.uvmat,'UserData',UvData)
310if ~isempty(inputfile)
311    %%%%% display the input field %%%%%%%
312    display_file_name(handles,inputfile)
313    %%%%%%%
314end
315
316set_vec_col_bar(handles) %update the display of color code for vectors
317
318%------------------------------------------------------------------------
319% --- Outputs from this function are returned to the command menuline.
320function varargout = uvmat_OutputFcn(hObject, eventdata, handles)
321%------------------------------------------------------------------------   
322varargout{1} = handles.output;% the only output argument is the handle to the GUI figure
323
324%------------------------------------------------------------------------
325% --- executed when closing uvmat: delete or desactivate the associated figures if exist
326function closefcn(gcbo,eventdata)
327%------------------------------------------------------------------------
328% delete GUI 'view_field' if detected
329hh=findobj(allchild(0),'tag','view_field');
330if ~isempty(hh)
331    delete(hh)
332end
333% delete GUI 'geometry_calib' if detected
334hh=findobj(allchild(0),'tag','geometry_calib');
335if ~isempty(hh)
336    delete(hh)
337end
338% desable set_object editing action if detected
339hh=findobj(allchild(0),'name','set_object');
340if ~isempty(hh)
341    hhh=findobj(hh,'tag','PLOT');
342    set(hhh,'enable','off')
343end
344%delete the bowser if detected
345hh=findobj(allchild(0),'tag','browser');
346if ~isempty(hh)
347    delete(hh)
348end
349
350%------------------------------------------------------------------------
351%--- activated when resizing the GUI view_field
352 function ResizeFcn(gcbo,eventdata,handles)
353%------------------------------------------------------------------------     
354set(handles.uvmat,'Units','pixels')
355size_fig=get(handles.uvmat,'Position');
356ColumnWidth=max(150,0.18*size_fig(3));
357ColumnWidth=min(ColumnWidth,250); % width of the right side display column, between 150 and 250, depending on the fig width
358
359%% position of panel InputFile
360set(handles.InputFile,'Units','pixels')
361pos_InputFile=get(handles.InputFile,'Position');% [lower x lower y width height] for text_display
362pos_InputFile(1)=0;
363pos_InputFile(2)=size_fig(4)-pos_InputFile(4);             % set frame InputFile to the top of the fig
364pos_InputFile(3)=size_fig(3);
365set(handles.InputFile,'Position',pos_InputFile);% [lower x lower y width height] for text_display
366
367%% reset position of text_display and TableDisplay
368% if strcmp(get(handles.TableDisplay,'Visible'),'off')
369    set(handles.text_display,'Units','pixels')
370    pos_1=get(handles.text_display,'Position');% [lower x lower y width height] for text_display
371        pos_1(3)=1.2*ColumnWidth;
372    pos_1(1)=size_fig(3)-pos_1(3);             % set text display to the right of the fig
373    pos_1(2)=size_fig(4)-pos_InputFile(4)-pos_1(4);             % set text display to the top of the fig
374    set(handles.text_display,'Position',pos_1)
375    % reset position of TableDisplay
376% else
377%     set(handles.TableDisplay,'Units','pixels')
378%     pos_1=get(handles.TableDisplay,'Position');
379%     pos_1(3)=1.2*ColumnWidth;
380%     pos_1(1)=size_fig(3)-pos_1(3);
381%     pos_1(2)=size_fig(4)-pos_InputFile(4)-pos_1(4);
382    set(handles.TableDisplay,'Position',pos_1)
383    % reset position of CheckTable
384    set(handles.CheckTable,'Unit','pixels')
385pos_CheckTable=get(handles.CheckTable,'Position');% [lower x lower y width height] for CheckHold
386pos_CheckTable(1)=pos_1(1)-pos_CheckTable(3);       % set 'CheckHold' to the right of the fig
387pos_CheckTable(2)=pos_InputFile(2)-pos_CheckTable(4);          % set 'CheckHold' to the lower edge of text display
388set(handles.CheckTable,'Position',pos_CheckTable)
389% end
390
391%% reset position of CheckHold
392% pos_CheckHold=get(handles.CheckHold,'Position');% [lower x lower y width height] for CheckHold
393% pos_CheckHold(1)=size_fig(3)-pos_CheckHold(3);       % set 'CheckHold' to the right of the fig
394% pos_CheckHold(2)=pos_1(2)-pos_CheckHold(4);          % set 'CheckHold' to the lower edge of text display
395% set(handles.CheckHold,'Position',pos_CheckHold)
396
397%% reset position of Coordinates panel
398set(handles.Coordinates,'Units','pixels')
399pos_2=get(handles.Coordinates,'Position');% [lower x lower y width height] for frame 'Coordinates'
400pos_2(3)=ColumnWidth;
401pos_2(1)=size_fig(3)-pos_2(3);       % set 'Coordinates' to the right of the fig
402pos_2(2)=pos_1(2)-pos_2(4);          % set 'Coordinates' to the lower edge of text display, allowing a margin for CheckHold
403set(handles.Coordinates,'Position',pos_2)
404
405%% reset position of Axes panel
406set(handles.Axes,'Units','pixels')
407pos_3=get(handles.Axes,'Position');% [lower x lower y width height] for frame 'Coordinates'
408pos_3(3)=ColumnWidth;
409pos_3(1)=size_fig(3)-pos_3(3);       % set 'Coordinates' to the right of the fig
410pos_3(2)=pos_2(2)-pos_3(4);          % set 'Coordinates' to the lower edge of text display, allowing a margin for CheckHold
411set(handles.Axes,'Position',pos_3)
412
413%% reset position of  Scalar
414set(handles.Scalar,'Units','pixels')
415pos_4=get(handles.Scalar,'Position'); % [lower x lower y width height] for frame 'Scalar'
416pos_4(3)=ColumnWidth;
417pos_4(1)=size_fig(3)-pos_4(3);         % set 'Scalar' to the right of the fig
418if strcmp(get(handles.Scalar,'Visible'),'on')
419    pos_4(2)=pos_3(2)-pos_4(4); % set 'Scalar' to the lower edge of frame 'Coordinates' if visible
420else
421    pos_4(2)=pos_3(2);% set 'Scalar' to the lower edge of frame 'text display' if  unvisible
422end
423set(handles.Scalar,'Position',pos_4)
424
425%% reset position of  Vectors
426set(handles.Vectors,'Units','pixels')
427pos_5=get(handles.Vectors,'Position');
428pos_5(3)=ColumnWidth;
429pos_5(1)=size_fig(3)-pos_5(3);
430if strcmp(get(handles.Vectors,'visible'),'on')
431    pos_5(2)=pos_4(2)-pos_5(4);
432else
433    pos_5(2)=pos_4(2);
434end
435set(handles.Vectors,'Position',pos_5)
436
437%% reset position and scale of axis
438pos(1)=0.2*size_fig(3)+35;
439pos(2)=35;
440pos(3)=0.77*size_fig(3)-1.2*ColumnWidth;
441pos(4)=size_fig(4)-60;
442set(handles.PlotAxes,'Units','pixels')
443set(handles.PlotAxes,'Position',pos)
444set(handles.PlotAxes,'Units','normalized')
445
446
447%------------------------------------------------------------------------
448%------------------------------------------------------------------------
449%  II - FUNCTIONS FOR INTRODUCING THE INPUT FILES
450% automatically sets the global properties when the rootfile name is introduced
451% then activate the view-field action if selected
452% it is activated either by clicking on the RootPath window or by the
453% browser
454%------------------------------------------------------------------------
455%------------------------------------------------------------------------
456% --- Executes on the menu Open/Browse...
457% search the files, recognize their type according to their name and fill the rootfile input windows
458function MenuBrowse_Callback(hObject, eventdata, handles)
459[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
460oldfile=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
461if isempty(oldfile) %loads the previously stored file name and set it as default in the file_input box
462    oldfile=get(handles.RootPath,'UserData');
463end
464fileinput=uigetfile_uvmat('pick an input file',oldfile);
465hh=dir(fileinput);
466if numel(hh)>1
467    msgbox_uvmat('ERROR','invalid input, probably a broken link');
468else
469
470    %% display the selected field and related information
471    if ~isempty(fileinput)
472        set(handles.SubField,'Value',0)
473        desable_subfield(handles)
474        display_file_name(handles,fileinput)
475    end
476end
477
478% -----------------------------------------------------------------------
479% --- Open again the file whose name has been recorded in MenuFile_1
480function MenuFile_Callback(hObject, eventdata, handles)
481%------------------------------------------------------------------------
482fileinput=get(hObject,'Label');
483set(handles.SubField,'Value',0)
484desable_subfield(handles)
485errormsg=display_file_name( handles,fileinput);
486if ~isempty(errormsg)
487    set(hObject,'Label','')
488    MenuFile=[{get(handles.MenuFile_1,'Label')};{get(handles.MenuFile_2,'Label')};...
489        {get(handles.MenuFile_3,'Label')};{get(handles.MenuFile_4,'Label')};{get(handles.MenuFile_5,'Label')}];
490    str_find=strcmp(get(hObject,'Label'),MenuFile);
491    MenuFile(str_find)=[];% suppress the input file to the list
492    for ifile=1:numel(MenuFile)
493        set(handles.(['MenuFile_' num2str(ifile)]),'Label',MenuFile{ifile});
494    end
495end
496
497% -----------------------------------------------------------------------
498% --- Executes on the menu Open/Browse campaign...
499% --- search the file inside a campaign, using the GUI browse_data
500% -----------------------------------------------------------------------
501function MenuBrowseCampaign_Callback(hObject, eventdata, handles)
502set(handles.MenuOpenCampaign,'ForegroundColor',[1 1 0])
503drawnow
504RootPath=get(handles.RootPath,'String');
505if isempty(RootPath)
506    RootPath=get(handles.RootPath,'UserData');%use Rootpath recored from the personal file at uvmat opening
507end
508CampaignPath=fileparts(fileparts(RootPath));
509DirFull=uigetfile_uvmat('define this path as the Campaign folder:',CampaignPath,'uigetdir');
510%DirFull = uigetdir(CampaignPath,'Select a Campaign dir, then press OK');
511if isempty(DirFull)
512    return
513end
514OutPut=browse_data(DirFull);% open the GUI browse_data to get select a campaign dir, experiment and device
515if ~isfield(OutPut,'Campaign')
516    return
517end
518fileinput=uigetfile_uvmat('pick an input file',fullfile(OutPut.Campaign,OutPut.Experiment{1},OutPut.DataSeries{1}));
519hh=dir(fileinput);
520if numel(hh)>1
521    msgbox_uvmat('ERROR','invalid input, probably a broken link');
522    return
523end
524
525%
526% DirName=fullfile(OutPut.Campaign,OutPut.Experiment{1},OutPut.DataSeries{1});
527% ListStruct=dir(DirName); %list files and the dir DataSeries
528% % select the first appropriate file in the dir
529% FileName='';
530% for ilist=1:numel(ListStruct)
531%     if ~isequal(ListStruct(ilist).isdir,1)%look for files, not dir
532%         FileName=ListStruct(ilist).name;
533%         FileType=get_file_type(fullfile(DirName,FileName));
534%         switch FileType
535%             case {'image','multimage','civx','civdata','netcdf'}
536%                 break
537%         end
538%     end
539% end
540% if isempty(FileName)
541%     msgbox_uvmat('ERROR',['no appropriate input file in the DataSeries folder ' fullfile(DirName)])
542%     return
543% end
544
545%% update the list of campaigns in the menubar
546MenuCampaign=[{get(handles.MenuCampaign_1,'Label')};{get(handles.MenuCampaign_2,'Label')};...
547    {get(handles.MenuCampaign_3,'Label')};{get(handles.MenuCampaign_4,'Label')};{get(handles.MenuCampaign_5,'Label')}];
548check_dir=isempty(find(strcmp(DirFull,MenuCampaign)));
549if check_dir %insert the new campaign in the list if it is not found
550    MenuCampaign(end)=[]; %suppress the last item
551    MenuCampaign=[{DirFull};MenuCampaign];%insert the new campaign
552    for ilist=1:numel(MenuCampaign)
553        set(handles.(['MenuCampaign_' num2str(ilist)]),'Label',MenuCampaign{ilist})
554    end
555    % save the list for future opening:
556    dir_perso=prefdir;
557    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
558    if exist(profil_perso,'file')
559        save (profil_perso,'MenuCampaign','RootPath','-append'); %store the file names for future opening of uvmat
560    else
561        save (profil_perso,'MenuCampaign','RootPath','-V6'); %store the file names for future opening of uvmat
562    end
563end
564
565%% display the selected field and related information
566%display_file_name( handles,fullfile(DirName,FileName))
567display_file_name( handles,fileinput)
568set(handles.MenuOpenCampaign,'ForegroundColor',[0 0 0])
569
570% -----------------------------------------------------------------------
571% --- Open again as second field the file whose name has been recorded in MenuFile_1
572% -----------------------------------------------------------------------
573function MenuCampaign_Callback(hObject, eventdata, handles)
574
575set(handles.MenuOpenCampaign,'ForegroundColor',[1 1 0])
576OutPut=browse_data(get(hObject,'Label'));% open the GUI browse_data to get select a campaign dir, experiment and device
577if ~isfield(OutPut,'Campaign')
578    return
579end
580DirName=fullfile(OutPut.Campaign,OutPut.Experiment{1},OutPut.DataSeries{1});
581fileinput=uigetfile_uvmat('pick an input file',fullfile(OutPut.Campaign,OutPut.Experiment{1},OutPut.DataSeries{1}));
582hh=dir(fileinput);
583if numel(hh)>1
584    msgbox_uvmat('ERROR','invalid input, probably a broken link');
585    return
586end
587%
588% hdir=dir(DirName); %list files and dirs
589% FileName='';
590% for ilist=1:numel(hdir)
591%     if ~isequal(hdir(ilist).isdir,1)%look for files, not dir
592%         FileName=hdir(ilist).name;
593%         FileType=get_file_type(fullfile(DirName,FileName));
594%         switch FileType
595%             case {'image','multimage','civx','civdata','netcdf'}
596%             break
597%         end
598%     end
599% end
600% if isempty(FileName)
601%     msgbox_uvmat('ERROR','no valid input file in the selected directory')
602% else
603display_file_name(handles,fileinput)
604% end
605set(handles.MenuOpenCampaign,'ForegroundColor',[0 0 0])
606
607%------------------------------------------------------------------------
608% --- Called by action in FileIndex edit box
609function FileIndex_Callback(hObject, eventdata, handles)
610%------------------------------------------------------------------------
611[tild,tild,tild,i1,i2,j1,j2]=fileparts_uvmat(get(handles.FileIndex,'String'));
612set(handles.i1,'String',num2str(i1));
613set(handles.i2,'String',num2str(i2));
614set(handles.j1,'String',num2str(j1));
615set(handles.j2,'String',num2str(j2));
616
617
618%------------------------------------------------------------------------
619% --- Called by action in NomType edit box
620function NomType_Callback(hObject, eventdata, handles)
621%------------------------------------------------------------------------
622i1=str2num(get(handles.i1,'String'));
623i2=str2num(get(handles.i2,'String'));
624j1=str2num(get(handles.j1,'String'));
625j2=str2num(get(handles.j2,'String'));
626FileIndex=fullfile_uvmat('','','','',get(handles.NomType,'String'),i1,i2,j1,j2);
627set(handles.FileIndex,'String',FileIndex)
628% inputfilerefresh the current settings and inputfilerefresh the field view
629RootPath_Callback(hObject,eventdata,handles)
630
631%------------------------------------------------------------------------
632% --- Called by action in NomType edit box
633function NomType_1_Callback(hObject, eventdata, handles)
634%------------------------------------------------------------------------
635i1=str2num(get(handles.i1,'String'));
636i2=str2num(get(handles.i2,'String'));
637j1=str2num(get(handles.j1,'String'));
638j2=str2num(get(handles.j2,'String'));
639FileIndex=fullfile_uvmat('','','','',get(handles.NomType_1,'String'),i1,i2,j1,j2);
640set(handles.FileIndex_1,'String',FileIndex)
641% inputfilerefresh the current settings and inputfilerefresh the field view
642RootPath_1_Callback(hObject,eventdata,handles)
643
644%------------------------------------------------------------------------
645% --- Executes on button press in InputFileREFRESH.
646function InputFileREFRESH_Callback(hObject, eventdata, handles)
647%------------------------------------------------------------------------   
648set(handles.InputFileREFRESH,'BackgroundColor',[1 1 0])% set button color to yellow to indicate that refresh is under action
649set(handles.uvmat,'Pointer','watch') % set the mouse pointer to 'watch'
650drawnow
651% read the current input file name:
652[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
653% if ~exist(fullfile(RootPath,SubDir),'dir')
654%     msgbox_uvmat('ERROR',['directory ' fullfile(RootPath,SubDir) ' does not exist'])
655%     return
656% end
657% detect the file type, get the movie object if relevant, and look for the corresponding file series:
658[RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,tild,FileType,FileInfo,MovieObject]=find_file_series(fullfile(RootPath,SubDir),[RootFile FileIndices FileExt]);
659% initiate the input file series and inputfilerefresh the current field view:
660errormsg=update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,MovieObject,1);
661% inputfilerefresh the second series if selected
662if get(handles.SubField,'Value')
663    [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes_1(handles);
664    if ~exist(fullfile(RootPath,SubDir),'dir')
665        msgbox_uvmat('ERROR',['directory ' fullfile(RootPath,SubDir) ' does not exist'])
666        return
667    end
668    % detect the file type, get the movie object if relevant, and look for the corresponding file series:
669    [RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,tild,FileType,MovieObject]=find_file_series(fullfile(RootPath,SubDir),[RootFile FileIndices FileExt]);
670    % initiate the input file series and inputfilerefresh the current field view:
671    errormsg=update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,MovieObject,2);
672end
673
674if isempty(errormsg)
675% set(handles.InputFileREFRESH,'BackgroundColor',[1 0 0])% set button color to red to indicate that refresh has been updated
676else
677    set(handles.InputFileREFRESH,'BackgroundColor',[1 0 1])% keep button color magenta, input not succesfull
678end
679set(handles.uvmat,'Pointer','arrow')% set back the mouse pointer to arrow
680
681%------------------------------------------------------------------------
682% --- Fills the edit boxes RootPath, RootFile,NomType...from an input file name 'fileinput'
683function errormsg=display_file_name(handles,fileinput,index)
684%------------------------------------------------------------------------
685%% look for the input file existence
686errormsg='';%default
687if ~exist(fileinput,'file')
688    errormsg=['input file ' fileinput  ' does not exist'];
689    msgbox_uvmat('ERROR',errormsg)
690    return
691end
692
693%% define the relevant handles for the first field series (index=1) or the second file series (index=2)
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');
717    set(handles.TimeName_1,'Visible','on')
718    set(handles.TimeValue_1,'Visible','on')
719end
720set(handles.InputFileREFRESH,'BackgroundColor',[1 1 0])% paint REFRESH button to yellow to visualise root file input
721set(handles.uvmat,'Pointer','watch') % set the mouse pointer to 'watch'
722drawnow
723
724%% detect root name, nomenclature and indices in the input file name:
725[FilePath,FileName,FileExt]=fileparts(fileinput);
726% detect the file type, get the movie object if relevant, and look for the corresponding file series:
727% the root name and indices may be corrected by including the first index i1 if a corresponding xml file exists
728[RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,NomType,FileType,FileInfo,MovieObject,i1,i2,j1,j2]=find_file_series(FilePath,[FileName FileExt]);
729
730if strcmp(FileType,'txt')
731    try
732        edit(fileinput)
733    catch ME
734        msgbox_uvmat('ERROR','invalid intput file')
735    end
736    return
737elseif strcmp(FileType,'xml')
738    editxml(fileinput)
739     return
740elseif strcmp(FileType,'figure')
741    open(fileinput)
742     return
743end
744
745%% open the file or fill the GUI uvmat according to the detected file type
746switch FileType
747    case ''
748        msgbox_uvmat('ERROR','invalid input file type')
749    case 'txt'
750        edit(fileinput)
751    case 'figure'                           %display matlab figure
752        hfig=open(fileinput);
753        set(hfig,'WindowButtonMotionFcn','mouse_motion')%set mouse action functio
754        set(hfig,'WindowButtonUpFcn','mouse_up')%set mouse click action function
755        set(hfig,'WindowButtonUpFcn','mouse_down')%set mouse click action function
756    case 'xml'                % edit xml files
757        t=xmltree(fileinput);
758        % the xml file marks a project or project link, open datatree_browser
759        if strcmp(get(t,1,'name'),'Project')&& exist(regexprep(fileinput,'.xml$',''),'dir')
760            datatree_browser(fileinput)
761        else % other xml file, open the xml editor
762            editxml(fileinput);
763        end
764    case 'xls'% Excel file opended by editxml
765        editxml(fileinput);
766    otherwise
767        set(handles_RootPath,'String',RootPath);
768        rootname=fullfile(RootPath,SubDir,RootFile);
769        set(handles_SubDir,'String',['/' SubDir]);
770        set(handles_RootFile,'String',['/' RootFile]); %display the separator
771        indices=fileinput(length(rootname)+1:end);
772        indices(end-length(FileExt)+1:end)=[]; %remove extension
773        set(handles_FileIndex,'String',indices);
774        set(handles_NomType,'String',NomType);
775        set(handles_FileExt,'String',FileExt);
776        if index==1
777            % fill file index counters if the first file series is opened
778            set(handles.i1,'String',num2str(i1));
779            set(handles.i2,'String',num2str(i2));
780            set(handles.j1,'String',num2stra(j1,NomType));
781            set(handles.j2,'String',num2stra(j2,NomType));
782        else %read the current field index to synchronise with the first series
783            i1_s=str2num(get(handles.i1,'String'));
784            i2_0=str2num(get(handles.i2,'String'));
785            if ~isempty(i2_0)
786                i2_s=i2_0;
787            else
788               i2_s=i2;
789            end
790            j1_0=stra2num(get(handles.j1,'String'));
791            if ~isempty(j1_0)
792                j1_s=j1_0;
793            else
794                j1_s=j1;
795            end
796            j2_0=stra2num(get(handles.j2,'String'));
797            if ~isempty(j2_0)
798                j2_s=j2_0;
799            else
800                j2_s=j2;
801            end
802        end
803       
804        % synchronise indices of the second  input file if it exists
805        if get(handles.SubField,'Value')==1% if the subfield button is activated, update the field numbers
806            Input=read_GUI(handles.InputFile);
807            if ~isfield(Input,'RootPath_1')||strcmp(Input.RootPath_1,'"')
808                Input.RootPath_1=Input.RootPath;
809            end
810            if ~isfield(Input,'SubDir_1')||strcmp(Input.SubDir_1,'"')
811                Input.SubDir_1=Input.SubDir;
812            end
813            if ~isfield(Input,'RootFile_1')||strcmp(Input.RootFile_1,'"')
814                Input.RootFile_1=Input.RootFile;
815            end
816            if ~isfield(Input,'FileExt_1')||strcmp(Input.FileExt_1,'"')
817                Input.FileExt_1=Input.FileExt;
818            end
819            if ~isfield(Input,'NomType_1')||strcmp(Input.NomType_1,'"')
820                Input.NomType_1=Input.NomType;
821            end
822            %updtate the indices of the second field series to correspond to the newly opened one
823            FileName_1=fullfile_uvmat(Input.RootPath_1,Input.SubDir_1,Input.RootFile_1,Input.FileExt_1,Input.NomType_1,i1_s,i2_s,j1_s,j2_s);
824            if exist(FileName_1,'file')
825                FileIndex_1=fullfile_uvmat('','','','',Input.NomType_1,i1_s,i2_s,j1_s,j2_s);
826            else
827                FileIndex_1=fullfile_uvmat('','','','',Input.NomType_1,i1,i2,j1,j2);
828                msgbox_uvmat('WARNING','unable to synchronise the indices of the two series')
829            end
830            set(handles.FileIndex_1,'String',FileIndex_1)
831        end
832       
833        %enable other menus
834        set(handles.MenuOpenCampaign,'Enable','on')
835        set(handles.MenuExport,'Enable','on')
836        set(handles.MenuExportFigure,'Enable','on')
837        set(handles.MenuExportMovie,'Enable','on')
838        set(handles.MenuTools,'Enable','on')
839
840        % initiate input file series and inputfilerefresh the current field view:     
841        update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,MovieObject,index);
842
843end
844
845%% update list of recent files in the menubar and save it for future opening
846MenuFile=[{get(handles.MenuFile_1,'Label')};{get(handles.MenuFile_2,'Label')};...
847    {get(handles.MenuFile_3,'Label')};{get(handles.MenuFile_4,'Label')};{get(handles.MenuFile_5,'Label')}];
848str_find=strcmp(fileinput,MenuFile);
849if isempty(find(str_find,1))
850    MenuFile=[{fileinput};MenuFile];%insert the current file if not already in the list
851end
852for ifile=1:min(length(MenuFile),5)
853    set(handles.(['MenuFile_' num2str(ifile)]),'Label',MenuFile{ifile});
854    %set(handles.(['MenuFile_' num2str(ifile) '_1']),'Label',MenuFile{ifile});
855end
856dir_perso=prefdir;
857profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
858if exist(profil_perso,'file')
859    save (profil_perso,'MenuFile','RootPath','-append'); %store the file names for future opening of uvmat
860else
861    save (profil_perso,'MenuFile','RootPath','-V6'); %store the file names for future opening of uvmat
862end
863
864set(handles.InputFileREFRESH,'BackgroundColor',[1 0 0])% paint back button to red to indicate update is finished
865set(handles.uvmat,'Pointer','arrow')% set back the mouse pointer to arrow
866
867
868%------------------------------------------------------------------------
869% --- Update information about a new field series (indices to scan, timing,
870%     calibration from an xml file, then inputfilerefresh current plots
871function errormsg=update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,VideoObject,index)
872%------------------------------------------------------------------------
873errormsg=''; %default error msg
874%% define the relevant handles depending on the index (1=first file series, 2= second file series)
875if ~exist('index','var')
876    index=1;
877end
878if index==1
879    handles_Fields=handles.FieldName;
880elseif index==2
881    handles_Fields=handles.FieldName_1;
882end
883
884set(handles.FieldName,'UserData',[])% reinialize data from uvmat opening
885UvData=get(handles.uvmat,'UserData');%huvmat=handles of the uvmat interface
886UvData.NewSeries=1; %flag for REFRESH: begin a new series
887UvData.FileName_1='';% name of the current second field (used to detect a  constant field during file scanning)
888UvData.FileType{index}=FileType;
889UvData.i1_series{index}=i1_series;
890UvData.i2_series{index}=i2_series;
891UvData.j1_series{index}=j1_series;
892UvData.j2_series{index}=j2_series;
893set(handles.FixVelType,'Value',0); %desactivate fixed veltype
894if index==1
895    [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
896else
897    [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes_1(handles);
898end
899FileName=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
900FileBase=fullfile(RootPath,RootFile);
901if ~exist(FileName,'file')
902    errormsg=['input file ' FileName ' not found'];
903   msgbox_uvmat('ERROR',errormsg);   
904    return
905end
906
907%% read timing and total frame number from the current file (movie files) !! may be overrid by xml file
908TimeUnit='';%default
909TimeName='';%default
910XmlData.Time=[];%default
911imainfo=[];
912ColorType='falsecolor'; %default
913UvData.MovieObject{index}=VideoObject;
914if ~isempty(VideoObject)% case of video data
915    imainfo=get(VideoObject);
916    TimeUnit='s';
917    if isempty(j1_series); %frame index along i
918        XmlData.Time=zeros(imainfo.NumberOfFrames+1,2);
919        XmlData.Time(:,2)=(0:1/imainfo.FrameRate:(imainfo.NumberOfFrames)/imainfo.FrameRate)';
920    else
921        XmlData.Time=[0;ones(size(i1_series,3)-1,1)]*(0:1/imainfo.FrameRate:(imainfo.NumberOfFrames)/imainfo.FrameRate);
922    end
923    %set(handles.Dt_txt,'String',['Dt=' num2str(1000/imainfo.FrameRate) 'ms']);%display the elementary time interval in millisec
924    TimeName='video';
925    ColorType='truecolor';
926elseif ~isempty(FileExt(2:end))&&(~isempty(imformats(FileExt(2:end))) || isequal(FileExt,'.vol'))%&& isequal(NomType,'*')% multi-frame image
927    if ~isequal(SubDir,'')
928        imainfo=imfinfo([fullfile(RootPath,SubDir,RootFile) FileIndices FileExt]);
929    else
930        imainfo=imfinfo([FileBase FileIndices FileExt]);
931    end
932    ColorType=imainfo.ColorType;%='truecolor' for color images
933end
934if isfield(imainfo,'Width') && isfield(imainfo,'Height')
935    if length(imainfo)>1
936        set(handles.num_Npx,'String',num2str(imainfo(1).Width));%fills nbre of pixels x box
937        set(handles.num_Npy,'String',num2str(imainfo(1).Height));%fills nbre of pixels x box
938    else
939        set(handles.num_Npx,'String',num2str(imainfo.Width));%fills nbre of pixels x box
940        set(handles.num_Npy,'String',num2str(imainfo.Height));%fills nbre of pixels x box
941    end
942else
943    set(handles.num_Npx,'String','');%fills nbre of pixels x box
944    set(handles.num_Npy,'String','');%fills nbre of pixels x box
945end
946set(handles.CheckBW,'Value',strcmp(ColorType,'grayscale'))% select handles.CheckBW if grayscale image
947
948%% read parameters (time, geometric calibration..) from a documentation file (.xml advised)
949XmlData.GeometryCalib=[];%default
950XmlFileName=find_imadoc(RootPath,SubDir,RootFile,FileExt);
951[tild,tild,DocExt]=fileparts(XmlFileName);
952warntext='';%default warning message
953NbSlice=1;%default
954ImaDoc_str='';
955if ~isempty(XmlFileName)
956    set(handles.view_xml,'Visible','on')
957    set(handles.view_xml,'BackgroundColor',[1 1 0])% paint  to yellow color to indicate reading of the xml file
958    set(handles.view_xml,'String','view .xml')
959    drawnow
960    [XmlDataRead,warntext]=imadoc2struct(XmlFileName);
961    if ~isempty(warntext)
962        msgbox_uvmat('WARNING',warntext)
963    end
964    if ~isempty(XmlDataRead)
965        ImaDoc_str=['view ' DocExt];  % DocExt= '.xml' or .civ (obsolete case)
966        %XmlData=XmlDataRead;
967        if isfield(XmlDataRead,'TimeUnit')&& ~isempty(XmlDataRead.TimeUnit)
968            TimeUnit=XmlDataRead.TimeUnit;
969        end
970        if isfield(XmlDataRead,'Time')&& ~isempty(XmlDataRead.Time)
971            XmlData.Time=XmlDataRead.Time;
972        end
973        set(handles.view_xml,'BackgroundColor',[1 1 1])% paint back to white
974        drawnow
975        if isfield(XmlDataRead, 'GeometryCalib') && ~isempty(XmlDataRead.GeometryCalib)
976            XmlData.GeometryCalib=XmlDataRead.GeometryCalib;
977            if isfield(XmlData.GeometryCalib,'CheckVolumeScan') && isequal(XmlData.GeometryCalib.CheckVolumeScan,1)
978                set (handles.slices,'String','volume')
979            end
980            % check whether the GUI geometry_calib is opened
981            hgeometry_calib=findobj('tag','geometry_calib');
982            if ~isempty(hgeometry_calib) % check whether the display of the GUI geometry_calib is consistent with the current calib param
983                GUserData=get(hgeometry_calib,'UserData');
984                if ~(isfield(GUserData,'XmlInputFile') && strcmp(GUserData.XmlInputFile,XmlFileName))
985                    answer=msgbox_uvmat('INPUT_Y-N','refresh the display of the GUI geometry_calib with the new input data?');
986                    if strcmp(answer,'Yes')
987                        geometry_calib(XmlFileName);%diplay the new calibration points and parameters in geometry_calib
988                    end
989                end
990            end
991        end
992    end
993end
994if isempty(ImaDoc_str)
995    set(handles.view_xml,'Visible','off') % no .xml (or .civ) file detected
996else
997    set(handles.view_xml,'String',ImaDoc_str)% indicate that a xml file has been detected
998end
999
1000%% Define timing
1001% time not set by the input file: images or civ data: indicate that time is read from the xml file
1002if isfield(XmlData,'Time')&& ~isempty(XmlData.Time) && ...
1003        (strcmp(FileType,'image')|| strcmp(FileType,'multimage'))%||strcmp(FileType,'civdata')||strcmp(FileType,'civx'))
1004    TimeName='xml';
1005elseif strcmp(FileType,'civdata')
1006    TimeName='civdata';
1007elseif strcmp(FileType,'civx')
1008    TimeName='civx';
1009end
1010if index==1
1011    set(handles.TimeName,'String',TimeName)
1012else
1013    set(handles.TimeName_1,'String',TimeName)
1014    set(handles.TimeName_1,'Visible','on')
1015end
1016
1017%% store last index in handles.MaxIndex_i and .MaxIndex_j
1018nbfield=max(max(max(i2_series)));
1019if isempty(nbfield)
1020    nbfield=max(max(max(i1_series)));
1021end
1022nbfield_j=max(max(max(j2_series)));
1023if isempty(nbfield_j)
1024    nbfield_j=max(max(max(j1_series)));
1025end
1026if isfield(XmlData,'Time')&& ~isempty(XmlData.Time)
1027    %transform .Time to a column vector if it is a line vector the nomenclature uses a single index
1028    if isequal(size(XmlData.Time,1),1)
1029        XmlData.Time=(XmlData.Time)';
1030    end
1031end
1032last_i_cell=get(handles.MaxIndex_i,'String');
1033if isempty(nbfield)
1034    last_i_cell{index}='';
1035else
1036    last_i_cell{index}=num2str(nbfield);
1037end
1038set(handles.MaxIndex_i,'String',last_i_cell)
1039last_j_cell=get(handles.MaxIndex_j,'String');
1040if isempty(nbfield_j)
1041     last_j_cell{index}='';
1042else
1043     last_j_cell{index}=num2str(nbfield_j);
1044end
1045set(handles.MaxIndex_j,'String',last_j_cell);
1046
1047%% store geometric calibration in UvData
1048if isfield(XmlData,'GeometryCalib')
1049    GeometryCalib=XmlData.GeometryCalib;
1050    if isempty(GeometryCalib)
1051        set(handles.pxcmx,'String','')
1052        set(handles.pxcmy,'String','')
1053        set(handles.pxcmx,'Visible','off')
1054        set(handles.pxcmy,'Visible','off')
1055        set(handles.TransformName,'Value',1); %  no transform by default
1056    else
1057        set(handles.pxcmx,'Visible','on')
1058        set(handles.pxcmy,'Visible','on')
1059        if (isfield(GeometryCalib,'R')&& ~isequal(GeometryCalib.R(2,1),0) && ~isequal(GeometryCalib.R(1,2),0)) ||...
1060            (isfield(GeometryCalib,'kappa1')&& ~isequal(GeometryCalib.kappa1,0))
1061            set(handles.pxcmx,'String','var')
1062            set(handles.pxcmy,'String','var')
1063        elseif isfield(GeometryCalib,'fx_fy')
1064            pixcmx=GeometryCalib.fx_fy(1);%*GeometryCalib.R(1,1)*GeometryCalib.sx/(GeometryCalib.Tz*GeometryCalib.dpx);
1065            pixcmy=GeometryCalib.fx_fy(2);%*GeometryCalib.R(2,2)/(GeometryCalib.Tz*GeometryCalib.dpy);
1066            set(handles.pxcmx,'String',num2str(pixcmx))
1067            set(handles.pxcmy,'String',num2str(pixcmy))
1068        end
1069        if ~get(handles.CheckFixLimits,'Value')
1070            set(handles.TransformName,'Value',3); % phys transform by default if fixedLimits is off
1071        end
1072        if isfield(GeometryCalib,'SliceCoord')           
1073           siz=size(GeometryCalib.SliceCoord);
1074           if siz(1)>1
1075               NbSlice=siz(1);
1076               set(handles.slices,'Visible','on')
1077               set(handles.slices,'Value',1)
1078           end
1079           if isfield(GeometryCalib,'CheckVolumeScan') && isequal(GeometryCalib.CheckVolumeScan,1)
1080               set(handles.num_NbSlice,'Visible','off')
1081           else
1082               set(handles.num_NbSlice,'Visible','on')
1083               set(handles.num_NbSlice,'String',num2str(NbSlice))
1084           end
1085           slices_Callback([],[], handles)
1086        end           
1087    end
1088end
1089
1090%% update the data attached to the uvmat interface
1091if ~isempty(TimeUnit)
1092    if index==2 && isfield(UvData,'TimeUnit') && ~strcmp(UvData.TimeUnit,TimeUnit)
1093        msgbox_uvmat('WARNING',['time unit for second file series ' TimeUnit ' inconsistent with first series'])
1094    else
1095        UvData.TimeUnit=TimeUnit;
1096    end
1097end
1098UvData.XmlData{index}=XmlData;
1099UvData.NewSeries=1;
1100
1101%display warning message
1102if ~isequal(warntext,'')
1103    msgbox_uvmat('WARNING',warntext);
1104end
1105
1106%% set default options in menu 'FieldName'
1107switch FileType
1108    case {'civx','civdata'}
1109        [FieldList,ColorList]=set_field_list('U','V','C');
1110        set(handles_Fields,'String',[{'image'};FieldList;{'get_field...'}]);%standard menu for civx data
1111        set(handles_Fields,'Value',2) % set menu to 'velocity
1112        if index==1
1113            set(handles.FieldName_1,'Value',1);
1114            set(handles.FieldName_1,'String',[{''};{'image'};FieldList;{'get_field...'}]);%standard menu for civx data reproduced for the second field
1115        end
1116        set(handles.ColorScalar,'Value',1)
1117        set(handles.ColorScalar,'String',ColorList)
1118        set(handles.Vectors,'Visible','on')
1119        %set(handles.Coord_x,'Value',1);
1120        set(handles.Coord_x,'String','X');
1121        set(handles.Coord_y,'String','Y');
1122    case 'netcdf'
1123        set(handles_Fields,'Value',1)
1124        set(handles_Fields,'String',{'get_field...'})
1125        if index==1
1126            FieldName_Callback([],[], handles)
1127        else
1128            FieldName_1_Callback([],[], handles)
1129        end
1130    otherwise
1131        set(handles_Fields,'Value',1) % set menu to 'image'
1132        set(handles_Fields,'String',{'image'})
1133        %set(handles.Coord_x,'Value',1);
1134        set(handles.Coord_x,'String','AX');
1135    set(handles.Coord_y,'String','AY');
1136end
1137set(handles.uvmat,'UserData',UvData)
1138
1139%% set index navigation options
1140scan_option='i';%default
1141state_j='off'; %default
1142if index==2
1143    if get(handles.scan_j,'Value')
1144        scan_option='j'; %keep the scan option for the second file series
1145    end
1146    if strcmp(get(handles.j1,'Visible'),'on')
1147        state_j='on';
1148    end
1149end
1150[ref_j,ref_i]=find(squeeze(i1_series(1,:,:)));
1151if ~isempty(j1_series)
1152        state_j='on';
1153        if index==1
1154            if isequal(ref_i,ref_i(1)*ones(size(ref_j)))% if ref_i is always equal to its first value
1155                scan_option='j'; %scan j indext               
1156            end
1157        end
1158end
1159if isequal(scan_option,'i')
1160    diff_ref_i=diff(ref_i,1);
1161    if isempty(diff_ref_i)
1162        diff_ref_i=1;
1163    end
1164    if isequal (diff_ref_i,diff_ref_i(1)*ones(size(diff_ref_i)))
1165        set(handles.num_IndexIncrement,'String',num2str(diff_ref_i(1)))
1166    end
1167     set(handles.scan_i,'Value',1)
1168     scan_i_Callback([],[], handles);
1169else
1170    diff_ref_j=diff(ref_j);
1171    if isempty(diff_ref_j)
1172        diff_ref_j=1;
1173    end
1174    if isequal (diff_ref_j,diff_ref_j(1)*ones(size(diff_ref_j)))
1175        set(handles.num_IndexIncrement,'String',num2str(diff_ref_j(1)))
1176    end
1177     set(handles.scan_j,'Value',1)
1178     scan_j_Callback([],[], handles);
1179end
1180set(handles.scan_j,'Visible',state_j)
1181set(handles.j1,'Visible',state_j)
1182set(handles.j2,'Visible',state_j)
1183set(handles.MaxIndex_j,'Visible',state_j);
1184set(handles.j_text,'Visible',state_j);
1185if ~isempty(i2_series)||~isempty(j2_series)
1186    set(handles.CheckFixPair,'Visible','on')
1187elseif index==1
1188    set(handles.CheckFixPair,'Visible','off')
1189end
1190
1191%% apply the effect of the transform fct and view the field 
1192transform=get(handles.TransformPath,'UserData');
1193if index==2 && (~isa(transform,'function_handle')||nargin(transform)<3)
1194    set(handles.TransformName,'value',2); % set transform to sub_field if the current fct doe not accept two input fields
1195end
1196set(handles.InputFileREFRESH,'BackgroundColor',[1 0 0])% set button color to red to indicate that refresh has been updated
1197TransformName_Callback([],[],handles)% callback for the selection of transform function, then refresh the current plot
1198mask_test=get(handles.CheckMask,'value');
1199if mask_test
1200    MaskData=get(handles.CheckMask,'UserData');
1201    if isfield(MaskData,'maskhandle') && ishandle(MaskData.maskhandle)
1202          delete(MaskData.maskhandle)    %delete old mask
1203    end
1204    CheckMask_Callback([],[],handles)
1205end
1206
1207%------------------------------------------------------------------------
1208% --- switch file index scanning options scan_i and scan_j in an exclusive way
1209%------------------------------------------------------------------------
1210function scan_i_Callback(hObject, eventdata, handles)
1211
1212if get(handles.scan_i,'Value')==1
1213    set(handles.scan_j,'Value',0)
1214else
1215    set(handles.scan_j,'Value',1)
1216end
1217scan_j_Callback(hObject, eventdata, handles)
1218
1219%------------------------------------------------------------------------
1220% --- switch file index scanning options scan_i and scan_j in an exclusive way
1221%------------------------------------------------------------------------
1222function scan_j_Callback(hObject, eventdata, handles)
1223
1224if get(handles.scan_j,'Value')==1
1225    set(handles.scan_i,'Value',0)
1226else
1227    set(handles.scan_i,'Value',1)
1228    set(handles.CheckFixPair,'Visible','off')
1229end
1230
1231%------------------------------------------------------------------------
1232function i1_Callback(hObject, eventdata, handles)
1233%------------------------------------------------------------------------
1234update_ij(handles,1)
1235
1236%------------------------------------------------------------------------
1237function i2_Callback(hObject, eventdata, handles)
1238%------------------------------------------------------------------------
1239update_ij(handles,2)
1240
1241%------------------------------------------------------------------------
1242function j1_Callback(hObject, eventdata, handles)
1243%------------------------------------------------------------------------
1244update_ij(handles,3)
1245
1246%------------------------------------------------------------------------
1247function j2_Callback(hObject, eventdata, handles)
1248%------------------------------------------------------------------------
1249update_ij(handles,4)
1250
1251%------------------------------------------------------------------------
1252%--- update the index display after action on edit boxes i1, i2, j1 or j2
1253%------------------------------------------------------------------------
1254function update_ij(handles,index_rank)
1255   
1256NomType=get(handles.NomType,'String');
1257indices=get(handles.FileIndex,'String');
1258[tild,tild,tild,i1,i2,j1,j2]=fileparts_uvmat(indices);% the indices for the second series taken from FileIndex
1259switch index_rank
1260    case 1
1261        indices=fullfile_uvmat('','','','',NomType,stra2num(get(handles.i1,'String')),i2,j1,j2);
1262        set(handles.i1,'BackgroundColor',[0.7 0.7 0.7])% mark the edit box in grey, then RUN0 will mark it in white for confirmation
1263    case 2
1264        indices=fullfile_uvmat('','','','',NomType,i1,stra2num(get(handles.i2,'String')),j1,j2);
1265        set(handles.i2,'BackgroundColor',[0.7 0.7 0.7])% mark the edit box in grey, then RUN0 will mark it in white for confirmation
1266    case 3
1267        indices=fullfile_uvmat('','','','',NomType,i1,i2,stra2num(get(handles.j1,'String')),j2);
1268        set(handles.j1,'BackgroundColor',[0.7 0.7 0.7])% mark the edit box in grey, then RUN0 will mark it in white for confirmation
1269    case 4
1270        indices=fullfile_uvmat('','','','',NomType,i1,i2,j1,stra2num(get(handles.j2,'String')));
1271        set(handles.j2,'BackgroundColor',[0.7 0.7 0.7])% mark the edit box in grey, then RUN0 will mark it in white for confirmation
1272end
1273set(handles.FileIndex,'String',indices)
1274set(handles.FileIndex,'BackgroundColor',[0.7 0.7 0.7])% mark the edit box in grey, then RUN0 will mark it in white for confirmation
1275% update the second index if relevant
1276if strcmp(get(handles.FileIndex_1,'Visible'),'on')
1277    NomType_1=get(handles.NomType_1,'String');
1278    indices_1=get(handles.FileIndex_1,'String');
1279    [tild,tild,tild,i1_1,i2_1,j1_1,j2_1]=fileparts_uvmat(indices_1);% the indices for the second series taken from FileIndex_1
1280    switch index_rank
1281        case 1
1282            indices_1=fullfile_uvmat('','','','',NomType_1,stra2num(get(handles.i1,'String')),i2_1,j1_1,j2_1);
1283        case 2
1284            indices_1=fullfile_uvmat('','','','',NomType_1,i1_1,stra2num(get(handles.i2,'String')),j1_1,j2_1);
1285        case 3
1286            indices_1=fullfile_uvmat('','','','',NomType_1,i1_1,i2_1,stra2num(get(handles.j1,'String')),j2_1);
1287        case 4
1288            indices_1=fullfile_uvmat('','','','',NomType_1,i1_1,i2_1,j1_1,stra2num(get(handles.j2,'String')));
1289    end
1290    set(handles.FileIndex_1,'String',indices_1)
1291    set(handles.FileIndex_1,'BackgroundColor',[0.7 0.7 0.7])% mark the edit box in grey, then RUN0 will mark it in white for confirmation
1292end
1293   
1294%------------------------------------------------------------------------
1295
1296%------------------------------------------------------------------------
1297function slices_Callback(hObject, eventdata, handles)
1298%------------------------------------------------------------------------
1299if strcmp(get(handles.slices,'String'),'slices')
1300    if get(handles.slices,'Value')==1
1301        set(handles.num_NbSlice,'Visible','on')
1302        set(handles.z_text,'Visible','on')
1303        set(handles.z_index,'Visible','on')
1304        num_NbSlice_Callback(hObject, eventdata, handles)
1305    else
1306        set(handles.num_NbSlice,'Visible','off')
1307        set(handles.z_text,'Visible','off')
1308        set(handles.z_index,'Visible','off')
1309        set(handles.masklevel,'Value',1)
1310        set(handles.masklevel,'String',{'1'})
1311    end
1312end
1313
1314%------------------------------------------------------------------------
1315function num_NbSlice_Callback(hObject, eventdata, handles)
1316%------------------------------------------------------------------------
1317mode=get(handles.slices,'String');
1318nb_slice_str=get(handles.num_NbSlice,'String');
1319if strcmp(mode,'volume')
1320    z=stra2num(get(handles.j1,'String'));
1321else
1322    num=str2double(get(handles.i1,'String'));
1323    nbslice=str2double(get(handles.num_NbSlice,'String'));
1324    z=mod(num-1,nbslice)+1;
1325end
1326set(handles.z_index,'String',num2str(z))
1327for ilist=1:nbslice
1328    list_index{ilist,1}=num2str(ilist);
1329end   
1330set(handles.masklevel,'String',list_index)
1331set(handles.masklevel,'Value',z)
1332
1333%------------------------------------------------------------------------
1334% --- Executes on button press in view_xml.
1335%------------------------------------------------------------------------
1336function view_xml_Callback(hObject, eventdata, handles)
1337
1338% if TimeName defined, open the xml file corresponding to the first file
1339% series, else open the xml file corresponding to the second series
1340if isempty(get(handles.TimeName,'String'))% open the xml file corresponding to the secodn file series
1341    [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes_1(handles);
1342else
1343   [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
1344end
1345option=get(handles.view_xml,'String');
1346if isequal(option,'view .xml')     
1347    FileXml=fullfile(RootPath,[SubDir '.xml']);
1348    if ~exist(FileXml,'file')% case of civ files , removes the extension for subdir
1349        FileXml=fullfile(RootPath,[regexprep(SubDir,'\..+$','') '.xml']);
1350    end
1351    heditxml=editxml(FileXml);
1352end
1353
1354%------------------------------------------------------------------------
1355% --- Executes on button press in CheckMask.
1356function CheckMask_Callback(hObject, eventdata, handles)
1357%------------------------------------------------------------------------
1358%case of view mask selection
1359if isequal(get(handles.CheckMask,'Value'),1)
1360    [RootPath,SubDir]=read_file_boxes(handles);
1361    MaskSubDir=regexprep(SubDir,'\..*','');%take the root part of SubDir, before the first dot '.'
1362    MaskPath=fullfile(RootPath,[MaskSubDir '.mask']);
1363    mdetect=0;
1364    if exist(MaskPath,'dir')
1365        ListStruct=dir(MaskPath);%look for a mask file
1366        ListCells=struct2cell(ListStruct);% transform dir struct to a cell arrray
1367        check_dir=cell2mat(ListCells(4,:));% =1 for directories, =0 for files
1368        ListFiles=ListCells(1,:);%list of file and dri names
1369        ListFiles=ListFiles(~check_dir);%list of file names (excluding dir)
1370        if ~isempty(ListFiles)
1371            for ifile=1:numel(ListFiles)
1372                [tild,tild,MaskExt]=fileparts(ListFiles{1});
1373                [tild,tild,MaskFile{ifile},i1_series,i2_series,j1_series,j2_series,MaskNomType,MaskFileType]=find_file_series(MaskPath,ListFiles{ifile},0);
1374                if strcmp(MaskFileType,'image') && isempty(i2_series) && isempty(j2_series)
1375                    mdetect=1;
1376                end
1377                if ~strcmp(MaskFile{ifile},MaskFile{1})
1378                    mdetect=0;% cancel detection test in case of multiple masks, use the brower for selection
1379                    break
1380                end
1381            end
1382        end
1383        RootPath=MaskPath;
1384    end
1385    if mdetect==0
1386        MaskFullName=uigetfile_uvmat('pick a mask image file:',RootPath,'image');
1387        if isempty(MaskFullName)
1388            set(handles.CheckMask,'Value',0)
1389        end
1390        [MaskPath,MaskName,MaskExt]=fileparts(MaskFullName);
1391        [tild,tild,MaskFile,i1_series,i2_series,j1_series,j2_series,MaskNomType]=find_file_series(MaskPath,[MaskName MaskExt],0);
1392        if ~(isempty(i2_series) && isempty(j2_series))
1393            MaskNomType='*';
1394        end
1395    end
1396    Mask.Path=MaskPath;
1397    if isempty(MaskFile)
1398        Mask.File='';
1399    elseif ischar(MaskFile)
1400        Mask.File=MaskFile;
1401    else
1402        Mask.File=MaskFile{1};
1403    end
1404    Mask.Ext=MaskExt;
1405    Mask.NomType=MaskNomType;
1406    set(handles.CheckMask,'UserData',Mask);
1407    errormsg=update_mask(handles);
1408else % desactivate mask display
1409    MaskData=get(handles.CheckMask,'UserData');
1410    if isfield(MaskData,'maskhandle') && ishandle(MaskData.maskhandle)
1411        delete(MaskData.maskhandle)
1412    end
1413    set(handles.CheckMask,'UserData',[])
1414    UvData=get(handles.uvmat,'UserData');
1415    if isfield(UvData,'MaskName')
1416        UvData=rmfield(UvData,'MaskName');
1417        set(handles.uvmat,'UserData',UvData)
1418    end
1419    set(handles.CheckMask,'BackgroundColor',[0.7 0.7 0.7])
1420end
1421
1422%------------------------------------------------------------------------
1423function errormsg=update_mask(handles)
1424%------------------------------------------------------------------------
1425errormsg=[];%default
1426Mask=get(handles.CheckMask,'UserData');
1427MaskIndex=1;
1428if strcmp(get(handles.z_index,'Visible'),'on')
1429    MaskIndex=str2num(get(handles.z_index,'String'));
1430end
1431if isfield(Mask,'maskhandle')&& ishandle(Mask.maskhandle)
1432    uistack(Mask.maskhandle,'top');
1433end
1434MaskName=fullfile_uvmat(Mask.Path,'',Mask.File,Mask.Ext,Mask.NomType,MaskIndex);
1435UvData=get(handles.uvmat,'UserData');
1436
1437%% update mask image if the mask is new
1438if ~ (isfield(UvData,'MaskName') && isequal(UvData.MaskName,MaskName))
1439    UvData.MaskName=MaskName; %update the recorded name on UvData
1440    set(handles.uvmat,'UserData',UvData);
1441    if ~exist(MaskName,'file')
1442        if isfield(Mask,'maskhandle')&& ishandle(Mask.maskhandle)
1443            delete(Mask.maskhandle)   
1444        end
1445    else
1446        %read mask image
1447        [MaskField,tild,errormsg] = read_field(MaskName,'image');
1448        if ~isempty(errormsg)
1449            return
1450        end
1451        npxy=size(MaskField.A);
1452        if length(npxy)>2
1453            errormsg=[MaskName ' is not a grey scale image'];
1454            return
1455        elseif ~isa(MaskField.A,'uint8')
1456            errormsg=[MaskName ' is not a 8 bit grey level image'];
1457            return
1458        end
1459        MaskField.ZIndex=MaskIndex;
1460        %px to phys or other transform on field
1461         menu_transform=get(handles.TransformName,'String');
1462        choice_value=get(handles.TransformName,'Value');
1463        transform_name=menu_transform{choice_value};%name of the transform fct  given by the menu 'transform_fct'
1464        transform=get(handles.TransformPath,'UserData');
1465        if  ~isequal(transform_name,'') && ~isequal(transform_name,'px')
1466            if isfield(UvData,'XmlData') && isfield(UvData.XmlData{1},'GeometryCalib')%use geometry calib recorded from the ImaDoc xml file as first priority
1467                Calib=UvData.XmlData{1}.GeometryCalib;
1468                MaskField=transform(MaskField,UvData.XmlData{1});
1469            end
1470        end
1471        flagmask=MaskField.A < 200;
1472       
1473        %make brown color image
1474        imflag(:,:,1)=0.9*flagmask;
1475        imflag(:,:,2)=0.7*flagmask;
1476        imflag(:,:,3)=zeros(size(flagmask));
1477       
1478        %update mask image
1479        hmask=[]; %default
1480        if isfield(Mask,'maskhandle')&& ishandle(Mask.maskhandle)
1481            hmask=Mask.maskhandle;
1482        end
1483        if ~isempty(hmask)
1484            set(hmask,'CData',imflag)   
1485            set(hmask,'AlphaData',flagmask*0.6)
1486            set(hmask,'XData',MaskField.AX);
1487            set(hmask,'YData',MaskField.AY);
1488%             uistack(hmask,'top')
1489        else
1490            axes(handles.PlotAxes)
1491            hold on   
1492            Mask.maskhandle=image(MaskField.AX,MaskField.AY,imflag,'Tag','mask','HitTest','off','AlphaData',0.6*ones(size(flagmask)));
1493            set(handles.CheckMask,'UserData',Mask)
1494        end
1495    end
1496end
1497
1498%------------------------------------------------------------------------
1499%------------------------------------------------------------------------
1500% III - MAIN InputFileREFRESH FUNCTIONS : 'FRAME PLOT'
1501%------------------------------------------------------------------------
1502
1503%------------------------------------------------------------------------
1504% --- Executes on button press in runplus: make one step forward and call
1505% --- InputFileREFRESH. The step forward is along the fieldname series 1 or 2 depending on
1506% --- the scan_i and scan_j check box (exclusive each other)
1507function runplus_Callback(hObject, eventdata, handles)
1508%------------------------------------------------------------------------
1509
1510set(handles.runplus,'BackgroundColor',[1 1 0])%paint the command button in yellow
1511drawnow
1512increment=str2double(get(handles.num_IndexIncrement,'String')); %get the field increment d
1513if isnan(increment)% case of free increment: move to next available field index
1514    increment='+';
1515end
1516errormsg=runpm(hObject,eventdata,handles,increment);
1517if ~isempty(errormsg)
1518    msgbox_uvmat('ERROR',errormsg);
1519end
1520set(handles.runplus,'BackgroundColor',[1 0 0])%paint the command button back to red
1521
1522%------------------------------------------------------------------------
1523% --- Executes on button press in runmin: make one step backward and call
1524% --- InputFileREFRESH. The step backward is along the fieldname series 1 or 2 depending on
1525% --- the scan_i and scan_j check box (exclusive each other)
1526function runmin_Callback(hObject, eventdata, handles)
1527%------------------------------------------------------------------------
1528
1529set(handles.runmin,'BackgroundColor',[1 1 0])%paint the command button in yellow
1530drawnow
1531increment=-str2double(get(handles.num_IndexIncrement,'String')); %get the field increment d
1532if isnan(increment)% case of free increment: move to previous available field index
1533    increment='-';
1534end
1535errormsg=runpm(hObject,eventdata,handles,increment);
1536if ~isempty(errormsg)
1537    msgbox_uvmat('ERROR',errormsg);
1538end
1539set(handles.runmin,'BackgroundColor',[1 0 0])%paint the command button back to red
1540
1541%------------------------------------------------------------------------
1542% -- Executes on button press in Movie: make a series of +> steps
1543function Movie_Callback(hObject, eventdata, handles)
1544%------------------------------------------------------------------------
1545
1546set(handles.Movie,'BackgroundColor',[1 1 0])%paint the command button in yellow
1547drawnow
1548increment=str2double(get(handles.num_IndexIncrement,'String')); %get the field increment d
1549if isnan(increment)% case of free increment: move to next available field index
1550    increment='+';
1551end
1552set(handles.STOP,'Visible','on')
1553set(handles.speed,'Visible','on')
1554set(handles.speed_txt,'Visible','on')
1555set(handles.Movie,'BusyAction','queue')
1556UvData=get(handles.uvmat,'UserData');
1557
1558while get(handles.Movie,'Value')==1 && get(handles.speed,'Value')~=0 && isequal(get(handles.Movie,'BusyAction'),'queue') % enable STOP command
1559        errormsg=runpm(hObject,eventdata,handles,increment);
1560        if ~isempty(errormsg)
1561            set(handles.Movie,'BackgroundColor',[1 0 0])%paint the command buttonback to red
1562            return
1563        end
1564        pause(1.02-get(handles.speed,'Value'))% wait for next image
1565end
1566if isfield(UvData,'aviobj') && ~isempty( UvData.aviobj),
1567    UvData.aviobj=close(UvData.aviobj);
1568   set(handles.uvmat,'UserData',UvData);
1569end
1570set(handles.Movie,'BackgroundColor',[1 0 0])%paint the command buttonback to red
1571
1572%------------------------------------------------------------------------
1573% -- Executes on button press in Movie: make a series of <- steps
1574function MovieBackward_Callback(hObject, eventdata, handles)
1575%------------------------------------------------------------------------
1576set(handles.MovieBackward,'BackgroundColor',[1 1 0])%paint the command button in yellow
1577drawnow
1578increment=-str2double(get(handles.num_IndexIncrement,'String')); %get the field increment d
1579if isnan(increment)% case of free increment: move to next available field index
1580    increment='-';
1581end
1582set(handles.STOP,'Visible','on')
1583set(handles.speed,'Visible','on')
1584set(handles.speed_txt,'Visible','on')
1585set(handles.MovieBackward,'BusyAction','queue')
1586UvData=get(handles.uvmat,'UserData');
1587
1588while get(handles.MovieBackward,'Value')==1 && get(handles.speed,'Value')~=0 && isequal(get(handles.MovieBackward,'BusyAction'),'queue') % enable STOP command
1589        errormsg=runpm(hObject,eventdata,handles,increment);
1590        if ~isempty(errormsg)
1591            set(handles.MovieBackward,'BackgroundColor',[1 0 0])%paint the command buttonback to red
1592            return
1593        end
1594        pause(1.02-get(handles.speed,'Value'))% wait for next image
1595end
1596if isfield(UvData,'aviobj') && ~isempty( UvData.aviobj),
1597    UvData.aviobj=close(UvData.aviobj);
1598   set(handles.uvmat,'UserData',UvData);
1599end
1600set(handles.MovieBackward,'BackgroundColor',[1 0 0])%paint the command buttonback to red
1601
1602%------------------------------------------------------------------------
1603function STOP_Callback(hObject, eventdata, handles)
1604%------------------------------------------------------------------------
1605set(handles.movie_pair,'BusyAction','Cancel')
1606set(handles.movie_pair,'value',0)
1607set(handles.Movie,'BusyAction','Cancel')
1608set(handles.MovieBackward,'BusyAction','Cancel')
1609set(handles.MenuExportMovie,'BusyAction','Cancel')
1610%set(handles.movie_pair,'BackgroundColor',[1 0 0])%paint the command buttonback to red
1611set(handles.Movie,'BackgroundColor',[1 0 0])%paint the command buttonback to red
1612set(handles.MovieBackward,'BackgroundColor',[1 0 0])%paint the command buttonback to red
1613
1614%------------------------------------------------------------------------
1615% --- function activated by runplus and run minus
1616function errormsg=runpm(hObject,eventdata,handles,increment)
1617%------------------------------------------------------------------------
1618errormsg='';%default
1619%% check for movie pair status
1620movie_status=get(handles.movie_pair,'Value');
1621if isequal(movie_status,1)
1622    STOP_Callback(hObject, eventdata, handles)%interrupt movie pair if active
1623end
1624
1625%% read the current input file name(s) and field indices
1626InputFile=read_GUI(handles.InputFile);
1627InputFile.RootFile=regexprep(InputFile.RootFile,'^[\\/]|[\\/]$','');%suppress possible / or \ separator at the beginning or the end of the string
1628InputFile.SubDir=regexprep(InputFile.SubDir,'^[\\/]|[\\/]$','');%suppress possible / or \ separator at the beginning or the end of the string
1629FileExt=InputFile.FileExt;
1630NomType=InputFile.NomType;
1631[tild,tild,tild,i1,i2,j1,j2]=fileparts_uvmat(InputFile.FileIndex);% check back the indices used
1632if isempty(i1)
1633    i1=str2num(get(handles.i1,'String'));%read the field indices (for movie, it is not given by the file name)
1634elseif isempty(j1) && strcmp(get(handles.j1,'Visible'),'on')
1635    j1=str2num(get(handles.j1,'String'));%case of indexed movie
1636end
1637sub_value= get(handles.SubField,'Value');
1638if sub_value % a second input file has been entered
1639    [InputFile.RootPath_1,InputFile.SubDir_1,InputFile.RootFile_1,InputFile.FileIndex_1,InputFile.FileExt_1,InputFile.NomType_1]=read_file_boxes_1(handles);
1640    [tild,tild,tild,i1_1,i2_1,j1_1,j2_1]=fileparts_uvmat(InputFile.FileIndex_1);% the indices for the second series taken from FileIndex_1
1641    if isempty(i1_1)
1642        i1_1=str2num(get(handles.i1,'String'));%read the field indices (for movie, it is not given by the file name)
1643    elseif isempty(j1_1) && strcmp(get(handles.j1,'Visible'),'on')
1644        j1_1=str2num(get(handles.j1,'String'));%case of indexed movie
1645    end
1646else
1647    filename_1=[];
1648end
1649
1650%% increment (or decrement) the field indices and update the input filename(s)
1651if ~isnumeric(increment)% undefined increment value
1652    set(handles.CheckFixPair,'Value',0)
1653end
1654CheckFixPair=get(handles.CheckFixPair,'Value')||(isempty(i2)&&isempty(j2));
1655
1656% the pair i1-i2 or j1-j2 is imposed (check box CheckFixPair selected)
1657if CheckFixPair && isnumeric(increment)
1658    if get(handles.scan_i,'Value')==1% case of scanning along index i
1659        i1=i1+increment;
1660        i2=i2+increment;
1661        if sub_value
1662            i1_1=i1_1+increment;
1663            i2_1=i2_1+increment;
1664        end
1665    else % case of scanning along index j (burst numbers)
1666        j1=j1+increment;
1667        j2=j2+increment;
1668        if sub_value
1669            j1_1=j1_1+increment;
1670            j2_1=j2_1+increment;
1671        end
1672    end
1673   
1674    % the pair i1-i2 or j1-j2 is free (check box CheckFixPair not selected): the list of existing indices recorded in UvData is used
1675else
1676    UvData=get(handles.uvmat,'UserData');
1677    ref_i=i1;
1678    if ~isempty(i2)
1679        ref_i=floor((i1+i2)/2);% current reference index i
1680    end
1681    ref_j=1;
1682    if ~isempty(j1)
1683        ref_j=j1;
1684        if ~isempty(j2)
1685            ref_j=floor((j1+j2)/2);% current reference index j
1686        end
1687    end
1688    if isnumeric(increment)
1689        if get(handles.scan_i,'Value')==1% case of scanning along index i
1690            ref_i=ref_i+increment;% increment the current reference index i
1691        else % case of scanning along index j (burst numbers)
1692            ref_j=ref_j+increment;% increment the current reference index j if scan_j option is used
1693        end
1694    else % free increment
1695       % runaction=get(gcbo,'tag');
1696        if strcmp(increment,'+')% if runplus or movie is activated
1697            step=1;
1698        else
1699            step=-1;
1700        end
1701        if get(handles.scan_i,'Value')==1% case of scanning along index i
1702            ref_i=ref_i+step;
1703            while ref_i>=0  && size(UvData.i1_series{1},3)>=ref_i+1 && UvData.i1_series{1}(1,ref_j+1,ref_i+1)==0
1704                ref_i=ref_i+step;
1705            end
1706        else % case of scanning along index j (burst numbers)
1707            ref_j=ref_j+step;
1708            while ref_j>=0  && size(UvData.i1_series{1},2)>=ref_j+1 && UvData.i1_series{1}(1,ref_j+1,ref_i+1)==0
1709                ref_j=ref_j+step;
1710            end
1711        end
1712    end
1713    if ref_i<0
1714        errormsg='minimum i index reached';
1715    elseif ref_j<0
1716        errormsg='minimum j index reached';
1717    elseif ref_i+1>size(UvData.i1_series{1},3)
1718        errormsg='maximum i index reached (reload the input file to update the index bound)';
1719    elseif ref_j+1>size(UvData.i1_series{1},2)
1720        errormsg='maximum j index reached (reload the input file to update the index bound)';
1721    end
1722    if ~isempty(errormsg),return,end
1723    siz=size(UvData.i1_series{1});
1724    ref_indices=ref_i*siz(1)*siz(2)+ref_j*siz(1)+1:ref_i*siz(1)*siz(2)+(ref_j+1)*siz(1);
1725    i1_subseries=UvData.i1_series{1}(ref_indices);
1726    ref_indices=ref_indices(i1_subseries>0);
1727    if isempty(ref_indices)% case of pairs (free index i)
1728        ref_indices=ref_i*siz(1)*siz(2)+1:(ref_i+1)*siz(1)*siz(2);
1729        i1_subseries=UvData.i1_series{1}(ref_indices);
1730        ref_indices=ref_indices(i1_subseries>0);
1731    end
1732    if isempty(ref_indices),errormsg='no next frame: set num_IndexIncrement =''*'' to reach the next existing file';return
1733    end
1734    i1=UvData.i1_series{1}(ref_indices(end));
1735    if ~isempty(UvData.i2_series{1})
1736        i2=UvData.i2_series{1}(ref_indices(end));
1737    end
1738    if ~isempty(UvData.j1_series{1})
1739        j1=UvData.j1_series{1}(ref_indices(end));
1740    end
1741    if ~isempty(UvData.j2_series{1})
1742        j2=UvData.j2_series{1}(ref_indices(end));
1743    end
1744   
1745    % case of a second file series
1746    if sub_value
1747        ref_i_1=i1_1;
1748        if ~isempty(i2_1)
1749            ref_i_1=floor((i1_1+i2_1)/2);% current reference index i
1750        end
1751        ref_j_1=1;
1752        if ~isempty(j1_1)
1753            ref_j_1=j1_1;
1754            if ~isempty(j2_1)
1755                ref_j_1=floor((j1_1+j2_1)/2);% current reference index j
1756            end
1757        end
1758        if isnumeric(increment)
1759            if get(handles.scan_i,'Value')==1% case of scanning along index i
1760                ref_i_1=ref_i_1+increment;% increment the current reference index i
1761            else % case of scanning along index j (burst numbers)
1762                ref_j_1=ref_j_1+increment;% increment the current reference index j if scan_j option is used
1763            end
1764        else % free increment, synchronise the ref indices with the first series
1765            ref_i_1=ref_i;
1766            ref_j_1=ref_j;
1767        end
1768        if numel(UvData.i1_series)==1
1769            UvData.i1_series{2}=UvData.i1_series{1};
1770            UvData.j1_series{2}=UvData.j1_series{1};
1771            UvData.i2_series{2}=UvData.i2_series{1};
1772            UvData.j2_series{2}=UvData.j2_series{1};
1773        end
1774        if ref_i_1<0
1775            errormsg='minimum i index reached';
1776        elseif ref_j_1<0
1777            errormsg='minimum j index reached';
1778        elseif ref_i_1+1>size(UvData.i1_series{2},3)
1779            errormsg='maximum i index reached for the second series (reload the input file to update the index bound)';
1780        elseif ref_j_1+1>size(UvData.i1_series{2},2)
1781            errormsg='maximum j index reached for the second series(reload the input file to update the index bound)';
1782        end
1783        if ~isempty(errormsg),return,end
1784        siz=size(UvData.i1_series{2});
1785        ref_indices=ref_i_1*siz(1)*siz(2)+ref_j_1*siz(1)+1:ref_i_1*siz(1)*siz(2)+(ref_j_1+1)*siz(1);
1786        i1_subseries=UvData.i1_series{2}(ref_indices);
1787        ref_indices=ref_indices(i1_subseries>0);
1788        if isempty(ref_indices)% case of pairs (free index i)
1789            ref_indices=ref_i_1*siz(1)*siz(2)+1:(ref_i_1+1)*siz(1)*siz(2);
1790            i1_subseries=UvData.i1_series{2}(ref_indices);
1791            ref_indices=ref_indices(i1_subseries>0);
1792        end
1793        i1_1=UvData.i1_series{2}(ref_indices(end));
1794        if ~isempty(UvData.i2_series{2})
1795            i2_1=UvData.i2_series{2}(ref_indices(end));
1796        end
1797        if ~isempty(UvData.j1_series{2})
1798            j1_1=UvData.j1_series{2}(ref_indices(end));
1799        end
1800        if ~isempty(UvData.j2_series{2})
1801            j2_1=UvData.j2_series{1}(ref_indices(end));
1802        end
1803    else% the second series (if needed) is the same file as the first
1804        i1_1=i1;
1805        i2_1=i2;
1806        j1_1=j1;
1807        j2_1=j2;
1808    end
1809end
1810filename=fullfile_uvmat(InputFile.RootPath,InputFile.SubDir,InputFile.RootFile,FileExt,NomType,i1,i2,j1,j2);
1811
1812%% refresh plots
1813if sub_value
1814    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);
1815    errormsg=refresh_field(handles,filename,filename_1,i1,i2,j1,j2,i1_1,i2_1,j1_1,j2_1);
1816else
1817    errormsg=refresh_field(handles,filename,filename_1,i1,i2,j1,j2);
1818end
1819set(handles.InputFileREFRESH,'BackgroundColor',[1 0 0])
1820
1821%% update the index counters if the index move is successfull
1822if isempty(errormsg)
1823    set(handles.i1,'String',num2stra(i1,NomType,1));
1824    if isequal(i2,i1)
1825        set(handles.i2,'String','');
1826    else
1827        set(handles.i2,'String',num2stra(i2,NomType,1));
1828    end
1829    set(handles.j1,'String',num2stra(j1,NomType,2));
1830    if isequal(j2,j1)
1831        set(handles.j2,'String','');
1832    else
1833        set(handles.j2,'String',num2stra(j2,NomType,2));
1834    end
1835    indices=fullfile_uvmat('','','','',NomType,i1,i2,j1,j2);
1836    set(handles.FileIndex,'String',indices);
1837    if ~isempty(filename_1)
1838        indices_1=fullfile_uvmat('','','','',InputFile.NomType_1,i1_1,i2_1,j1_1,j2_1);
1839        set(handles.FileIndex_1,'String',indices_1);
1840    end
1841    if isequal(movie_status,1)
1842        set(handles.movie_pair,'Value',1)
1843        movie_pair_Callback(hObject, eventdata, handles); %reactivate moviepair if it was activated
1844    else
1845        if isempty(i2), set(handles.i2,'String',''); end % suppress the second index display if not used
1846        if isempty(j2), set(handles.j2,'String',''); end
1847    end
1848    set(handles.i1,'BackgroundColor',[1 1 1])
1849    set(handles.i2,'BackgroundColor',[1 1 1])
1850    set(handles.j1,'BackgroundColor',[1 1 1])
1851    set(handles.j2,'BackgroundColor',[1 1 1])
1852    set(handles.FileIndex,'BackgroundColor',[1 1 1])
1853    set(handles.FileIndex_1,'BackgroundColor',[1 1 1])
1854end
1855
1856%------------------------------------------------------------------------
1857% --- Executes on button press in movie_pair: create an alternating movie with two view
1858function movie_pair_Callback(hObject, eventdata, handles)
1859%------------------------------------------------------------------------
1860
1861%% stop movie action if the movie_pair button is off
1862if ~get(handles.movie_pair,'value')
1863    set(handles.movie_pair,'BusyAction','Cancel')%stop movie pair if button is 'off'
1864    set(handles.i2,'String','')
1865    set(handles.j2,'String','')
1866    set(handles.Dt_txt,'String','')
1867    return
1868else
1869    set(handles.movie_pair,'BusyAction','queue')
1870    set(handles.InputFileREFRESH,'BackgroundColor',[1 0 0])
1871end
1872
1873%% initialisation
1874set(handles.movie_pair,'BackgroundColor',[1 1 0])%paint the command button in yellow
1875drawnow
1876list_fields=get(handles.FieldName,'String');% list menu fields
1877index_fields=get(handles.FieldName,'Value');% selected string index
1878FieldName=list_fields{index_fields}; % selected field
1879UvData=get(handles.uvmat,'UserData');
1880if isequal(FieldName,'image')
1881    index=1;
1882    [RootPath,SubDir,RootFile,FileIndices,Ext]=read_file_boxes(handles);
1883    NomType=get(handles.NomType,'String');
1884else
1885    list_fields=get(handles.FieldName_1,'String');% list menu fields
1886    index_fields=get(handles.FieldName_1,'Value');% selected string index
1887    FieldName=list_fields{index_fields}; % selected field
1888    if isequal(FieldName,'image')
1889        index=2;
1890        [RootPath,SubDir,RootFile,FileIndex_1,Ext,NomType]=read_file_boxes_1(handles);% get info from the second input line
1891    else
1892        msgbox_uvmat('ERROR','an image or movie must be first introduced as input')
1893        set(handles.movie_pair,'BackgroundColor',[1 0 0])%paint the command button in red
1894        set(handles.movie_pair,'Value',0)
1895        return
1896    end
1897end
1898num_i1=str2num(get(handles.i1,'String'));
1899num_j1=stra2num(get(handles.j1,'String'));
1900num_i2=str2num(get(handles.i2,'String'));
1901num_j2=stra2num(get(handles.j2,'String'));
1902imaname_1='';
1903if isempty(num_j2)
1904    if isempty(num_i2)
1905        if strcmp(get(handles.j2,'Visible'),'on') %if the j box is visible
1906            imaname_1=fullfile_uvmat(RootPath,SubDir,RootFile,Ext,NomType,num_i1,[],num_j1+1);
1907        end
1908        if exist(imaname_1,'file')
1909            num_j2=num_j1+1;% look by default for the next j index as the second file
1910            set(handles.j2,'String',num2stra(num_j2,NomType));
1911        else
1912            imaname_1=fullfile_uvmat(RootPath,SubDir,RootFile,Ext,NomType,num_i1+1,[],num_j1);
1913            if exist(imaname_1,'file')
1914                num_i2=num_i1+1;
1915                set(handles.i2,'String',num2str(num_i2));
1916            else
1917                msgbox_uvmat('ERROR', 'a second image index i2 or j2 is needed to show the pair as a movie')
1918                set(handles.movie_pair,'BackgroundColor',[1 0 0])%paint the command button in red
1919                set(handles.movie_pair,'Value',0)
1920                return
1921            end
1922        end
1923    else
1924        num_j2=num_j1;%repeat the index i1 by default
1925    end
1926end
1927if isempty(num_i2)
1928    num_i2=num_i1;%repeat the index i1 by default
1929end
1930if isempty(num_j1)
1931    num_j1=1;
1932end
1933if isempty(num_j2)
1934    num_j2=num_j1;%repeat the index i1 by default
1935end
1936imaname_1=fullfile_uvmat(RootPath,SubDir,RootFile,Ext,NomType,num_i2,[],num_j2);
1937if strcmp(NomType,'*')
1938    num_frame=num_i2;
1939else
1940    num_frame=num_j2;
1941end
1942if ~exist(imaname_1,'file')
1943      msgbox_uvmat('ERROR',['second input open (-)  ' imaname_1 ' not found']);
1944      set(handles.movie_pair,'BackgroundColor',[1 0 0])%paint the command button in red
1945       set(handles.movie_pair,'Value',0)
1946      return
1947end
1948
1949%% display time interval for the image pair
1950if isfield(UvData,'XmlData')&&isfield(UvData.XmlData{1},'Time')...
1951        && size(UvData.XmlData{1}.Time,1)>=num_i2+1 && size(UvData.XmlData{1}.Time,2)>=num_j2+1
1952    dt=(UvData.XmlData{1}.Time(num_i2+1,num_j2+1)-UvData.XmlData{1}.Time(num_i1+1,num_j1+1));
1953    if  isfield(UvData,'TimeUnit')
1954        set(handles.Dt_txt,'String',['Dt=' num2str(1000*dt,3) '  m' UvData.TimeUnit] )
1955    else
1956        set(handles.Dt_txt,'String',['Dt=' num2str(1000*dt,3) '  10^(-3)'] )
1957    end
1958else
1959    set(handles.Dt_txt,'String','')
1960end
1961
1962%% get the first image
1963%Field.AName='image';
1964if index==1
1965    Field_a=UvData.Field;% movie on the second field
1966else
1967    Field_a=UvData.Field_1;% movie on the first field
1968end
1969
1970%% read the second image
1971MovieObject=[];
1972if numel(UvData.MovieObject)>=index
1973    MovieObject=UvData.MovieObject{index};
1974end
1975[Field_b,ParamOut,errormsg] = read_field(imaname_1,UvData.FileType{index},MovieObject,num_frame);
1976
1977%px to phys or other transform on field
1978transform=get(handles.TransformPath,'UserData');
1979if  ~isempty(transform)
1980    if isfield(UvData,'XmlData') && numel(UvData.XmlData)>=index %use geometry calib recorded from the ImaDoc xml file as first priority
1981        if index==2
1982        Field_a=transform(Field_a,UvData.XmlData{index});%the first field has been stored without transform
1983        end
1984        if nargin(transform)>=2
1985        Field_b=transform(Field_b,UvData.XmlData{index});
1986        else
1987          Field_b=transform(Field_b);
1988        end
1989    end
1990end
1991
1992% make movie until movie speed is set to 0 or STOP is activated
1993hima=findobj(handles.PlotAxes,'Tag','ima');% %handles.PlotAxes =main plotting window (A GENERALISER)
1994set(handles.STOP,'Visible','on')
1995set(handles.speed,'Visible','on')
1996set(handles.speed_txt,'Visible','on')
1997set(handles.i2,'BackgroundColor',[1 1 1])% mark the edit box in white to indicate its use as input
1998set(handles.j2,'BackgroundColor',[1 1 1])% mark the edit box in white to indicate its use as input
1999set(handles.FileIndex,'BackgroundColor',[1 1 1])% mark the edit box in white to indicate its use as input
2000while get(handles.speed,'Value')~=0 && isequal(get(handles.movie_pair,'BusyAction'),'queue') % enable STOP command
2001    % read and plot the series of images in non erase mode
2002    set(hima,'CData',Field_b.A);
2003    pause(1.02-get(handles.speed,'Value'));% wait for next image
2004    set(hima,'CData',Field_a.A);
2005    pause(1.02-get(handles.speed,'Value'));% wait for next image
2006end
2007set(handles.movie_pair,'BackgroundColor',[1 0 0])%paint the command button in red
2008set(handles.movie_pair,'Value',0)
2009set(handles.Dt_txt,'String','')
2010
2011%------------------------------------------------------------------------
2012% --- Executes on button press in InputFileREFRESH.
2013function REFRESH_Callback(hObject, eventdata, handles)
2014%------------------------------------------------------------------------
2015set(handles.REFRESH,'BackgroundColor',[1 1 0])%paint the command button in yellow
2016drawnow
2017[RootPath,SubDir,RootFile,FileIndex,FileExt]=read_file_boxes(handles);
2018[tild,tild,tild,i1,i2,j1,j2]=fileparts_uvmat(FileIndex);% check back the indices used
2019if isempty(i2), set(handles.i2,'String',''); end % suppress the second index display if not used
2020if isempty(j2), set(handles.j2,'String',''); end
2021filename=[fullfile(RootPath,SubDir,RootFile) FileIndex FileExt];
2022filename_1='';%default
2023FileIndex_1='';
2024if get(handles.SubField,'Value')
2025    [RootPath_1,SubDir_1,RootFile_1,FileIndex_1,FileExt_1]=read_file_boxes_1(handles);
2026    filename_1=[fullfile(RootPath_1,SubDir_1,RootFile_1) FileIndex_1 FileExt_1];
2027end
2028num_i1=stra2num(get(handles.i1,'String'));
2029num_i2=stra2num(get(handles.i2,'String'));
2030num_j1=stra2num(get(handles.j1,'String'));
2031num_j2=stra2num(get(handles.j2,'String'));
2032[tild,tild,tild,i1_1,i2_1,j1_1,j2_1]=fileparts_uvmat(FileIndex_1);% get the indices of the second series from the string FileIndex_1
2033if isempty(j1_1)% case of movies, the index is not given by file index
2034    j1_1=num_j1;
2035end
2036
2037errormsg=refresh_field(handles,filename,filename_1,num_i1,num_i2,num_j1,num_j2,i1_1,i2_1,j1_1,j2_1);
2038
2039if ~isempty(errormsg)
2040      msgbox_uvmat('ERROR',errormsg);
2041      set(handles.InputFileREFRESH,'BackgroundColor',[1 0 1])% keep button color magenta, input not succesfull
2042else
2043    set(handles.i1,'BackgroundColor',[1 1 1])
2044    set(handles.i2,'BackgroundColor',[1 1 1])
2045    set(handles.j1,'BackgroundColor',[1 1 1])
2046    set(handles.j2,'BackgroundColor',[1 1 1])
2047    set(handles.FileIndex,'BackgroundColor',[1 1 1])
2048    set(handles.FileIndex_1,'BackgroundColor',[1 1 1]) 
2049    set(handles.REFRESH,'BackgroundColor',[1 0 0])% set button color to red, update successfull
2050end   
2051
2052%------------------------------------------------------------------------
2053% --- read the input files and inputfilerefresh all the plots, including projection.
2054% OUTPUT:
2055%  errormsg: error message char string  =[] by default
2056% INPUT:
2057% FileName: first input file (=[] in the absence of input file)
2058% FileName_1: second input file (=[] in the asbsence of second input file)
2059% num_i1,num_i2,num_j1,num_j2; frame indices
2060% i1_1,i2_1,j1_1,j2_1: frame indices for the second input file  (needed if FileName_1 is not empty)
2061%------------------------------------------------------------------------
2062function errormsg=refresh_field(handles,FileName,FileName_1,num_i1,num_i2,num_j1,num_j2,i1_1,i2_1,j1_1,j2_1)
2063%------------------------------------------------------------------------
2064
2065%% initialisation
2066pointer=get(handles.uvmat,'Pointer');
2067if strcmp(pointer,'watch')% reinitialise the mouse if stuck to 'watch'
2068    set(handles.CheckZoom,'Value',0)
2069    pointer='arrow';
2070end
2071set(handles.uvmat,'Pointer','watch')
2072drawnow
2073if ~exist('Field','var')
2074    Field={};
2075end
2076UvData=get(handles.uvmat,'UserData');
2077if ishandle(handles.UVMAT_title) %remove title panel on uvmat
2078    delete(handles.UVMAT_title)
2079end
2080
2081%% determine the main input file information for action
2082if ~exist(FileName,'file')
2083    errormsg=['input file ' FileName ' does not exist'];
2084    return
2085end
2086NomType=get(handles.NomType,'String');
2087NomType_1='';
2088if strcmp(get(handles.NomType_1,'Visible'),'on')
2089    NomType_1=get(handles.NomType_1,'String');
2090end
2091%update the z position index
2092mode_slice=get(handles.slices,'String');
2093if strcmp(mode_slice,'volume')
2094    z_index=num_j1;
2095    set(handles.z_index,'String',num2str(z_index))
2096else
2097    nbslice=str2num(get(handles.num_NbSlice,'String'));
2098    z_index=mod(num_i1-1,nbslice)+1;
2099    set(handles.z_index,'String',num2str(z_index))
2100end
2101% inputfilerefresh menu for save_mask if relevant
2102masknumber=get(handles.masklevel,'String');
2103if length(masknumber)>=z_index
2104    set(handles.masklevel,'Value',z_index)
2105end
2106
2107%% test for need of tps
2108check_proj_tps=0;
2109if  (strcmp(UvData.FileType{1},'civdata')||strcmp(UvData.FileType{1},'civx'))
2110    for iobj=1:numel(UvData.ProjObject)
2111        if isfield(UvData.ProjObject{iobj},'ProjMode')&& strcmp(UvData.ProjObject{iobj}.ProjMode,'interp_tps')
2112            check_proj_tps=1;
2113            break
2114        end
2115    end
2116end
2117
2118%% read the first input field
2119ParamIn.ColorVar='';%default variable name for vector color
2120frame_index=1;%default
2121FieldName='';%default
2122VelType='';%default
2123switch UvData.FileType{1}
2124    case {'civx','civdata','netcdf'};
2125        list_fields=get(handles.FieldName,'String');% list menu fields
2126        FieldName= list_fields{get(handles.FieldName,'Value')}; % selected field
2127        if ~strcmp(FieldName,'get_field...')
2128            if get(handles.FixVelType,'Value')
2129                VelTypeList=get(handles.VelType,'String');
2130                VelType=VelTypeList{get(handles.VelType,'Value')};
2131            end
2132        end
2133        % case of input vector field, get the scalar used for vector color
2134        if ~isempty(regexp(FieldName,'^vec('))
2135            list_code=get(handles.ColorCode,'String');% list menu fields
2136            index_code=get(handles.ColorCode,'Value');% selected string index
2137            if  ~strcmp(list_code{index_code},'black') &&  ~strcmp(list_code{index_code},'white')
2138                list_code=get(handles.ColorScalar,'String');% list menu fields
2139                index_code=get(handles.ColorScalar,'Value');% selected string index
2140                ParamIn.ColorVar= list_code{index_code}; % selected field
2141            end
2142        end
2143    case {'video','mmreader'}
2144        ParamIn=UvData.MovieObject{1}; % movie object     
2145        if strcmp(NomType,'*')
2146            frame_index=num_i1;%frame index from a single movies or multimage
2147        else
2148            frame_index=num_j1;% frame index from a set of indexed movies
2149        end
2150    case 'multimage'
2151        if ~strcmp(NomType,'*')
2152            frame_index=num_j1;%frame index for movies or multimage
2153        else
2154            frame_index=num_i1;
2155        end
2156    case 'vol' %TODO: update
2157        if isfield(UvData.XmlData,'Npy') && isfield(UvData.XmlData,'Npx')
2158            ParamIn.Npy=UvData.XmlData.Npy;
2159            ParamIn.Npx=UvData.XmlData.Npx;
2160        else           
2161            errormsg='Npx and Npy need to be defined in the xml file for volume images .vol';
2162            return
2163        end
2164end
2165if isstruct (ParamIn)
2166    ParamIn.FieldName=FieldName;
2167    ParamIn.VelType=VelType;
2168    ParamIn.Coord_x=get(handles.Coord_x,'String');
2169    ParamIn.Coord_y=get(handles.Coord_y,'String');
2170    ParamIn.Coord_z=get(handles.Coord_z,'String');
2171    TimeName=get(handles.TimeName,'String');
2172    r=regexp(TimeName,'^(?<type>(dim:)|(var:))','names');%look for 'var:' or 'dim:' at the beginning of time name
2173    if ~isempty(r)
2174        frame_index=num_i1;%time index chosen by i1
2175        if strcmp(r.type,'dim:')
2176            ParamIn.TimeDimName=TimeName(5:end);
2177        elseif strcmp(r.type,'var:')
2178            ParamIn.TimeVarName=TimeName(5:end);
2179        end
2180    end
2181end
2182% check_tps = 0;         
2183% if strcmp(UvData.FileType{1},'civdata')&&~strcmp(ParamIn.FieldName,'velocity')&&~strcmp(ParamIn.FieldName,'get_field...')
2184%        check_tps=1;%tps needed to get the requested field
2185% end
2186[Field{1},ParamOut,errormsg] = read_field(FileName,UvData.FileType{1},ParamIn,frame_index);
2187if ~isempty(errormsg)
2188    errormsg=['uvmat / refresh_field / read_field( ' FileName ') / ' errormsg];
2189    return
2190end 
2191if isfield(ParamOut,'Npx')&& isfield(ParamOut,'Npy')
2192    set(handles.num_Npx,'String',num2str(ParamOut.Npx));% display image size on the interface
2193    set(handles.num_Npy,'String',num2str(ParamOut.Npy));
2194end
2195Field{1}.ZIndex=z_index; %used for multiplane 3D calibration
2196
2197%% choose and read a second field FileName_1 if defined
2198VelType_1=[];%default
2199FieldName_1=[];
2200ParamIn_1=[];
2201ParamOut_1=[];
2202frame_index_1=1;
2203if ~isempty(FileName_1)
2204    if ~exist(FileName_1,'file')
2205        errormsg=['second file ' FileName_1 ' does not exist'];
2206        return
2207    end
2208    switch UvData.FileType{2}
2209        case {'civx','civdata','netcdf'};
2210            list_fields=get(handles.FieldName_1,'String');% list menu fields
2211            if ischar(list_fields),list_fields={list_fields};end
2212            FieldName_1= list_fields{get(handles.FieldName_1,'Value')}; % selected field
2213            if ~strcmp(FieldName,'get_field...')
2214                if get(handles.FixVelType,'Value')
2215                    VelTypeList=get(handles.VelType_1,'String');
2216                    VelType_1=VelTypeList{get(handles.VelType_1,'Value')};% read the velocity type.
2217                end
2218            end
2219            if strcmp(FieldName_1,'velocity')&& strcmp(get(handles.ColorCode,'Visible'),'on')
2220                list_code=get(handles.ColorCode,'String');% list menu fields
2221                index_code=get(handles.ColorCode,'Value');% selected string index
2222                if  ~strcmp(list_code{index_code},'black') &&  ~strcmp(list_code{index_code},'white')
2223                    list_code=get(handles.ColorScalar,'String');% list menu fields
2224                    index_code=get(handles.ColorScalar,'Value');% selected string index
2225                    ParamIn_1.ColorVar= list_code{index_code}; % selected field for vector color display                 
2226                end
2227            end
2228        case {'video','mmreader'}
2229            ParamIn_1=UvData.MovieObject{2};
2230            if ~strcmp(NomType_1,'*')
2231                frame_index_1=j1_1;%frame index for movies or multimage
2232            else
2233                frame_index_1=i1_1;
2234            end 
2235         case 'multimage'
2236            if strcmp(NomType_1,'*')%frame index for movies or multimage
2237                frame_index_1=i1_1;
2238            else
2239                frame_index_1=j1_1;
2240            end   
2241        case 'vol' %TODO: update
2242            if isfield(UvData.XmlData,'Npy') && isfield(UvData.XmlData,'Npx')
2243                ParamIn_1.Npy=UvData.XmlData.Npy;
2244                ParamIn_1.Npx=UvData.XmlData.Npx;
2245            else
2246                errormsg='Npx and Npy need to be defined in the xml file for volume images .vol';
2247                return
2248            end
2249    end
2250    if isequal(get(handles.NomType_1,'Visible'),'on')
2251        NomType_1=get(handles.NomType_1,'String');
2252    else
2253        NomType_1=get(handles.NomType,'String');
2254    end
2255    test_keepdata_1=0;% test for keeping the previous stored data if the input files are unchanged
2256    if ~isequal(NomType_1,'*')&& isfield(UvData,'FileName_1')
2257           test_keepdata_1= strcmp(FileName_1,UvData.FileName_1) ;
2258    end
2259    if test_keepdata_1
2260        Field{2}=UvData.Field_1;% keep the stored field
2261        ParamOut_1=UvData.ParamOut_1;
2262    else
2263        if isempty(ParamIn_1) || isstruct(ParamIn_1)
2264        ParamIn_1.FieldName=FieldName_1;
2265        ParamIn_1.VelType=VelType_1;
2266        ParamIn_1.Coord_x=get(handles.Coord_x,'String');
2267        ParamIn_1.Coord_y=get(handles.Coord_y,'String');
2268        end 
2269        [Field{2},ParamOut_1,errormsg] = read_field(FileName_1,UvData.FileType{2},ParamIn_1,frame_index_1);
2270        if ~isempty(errormsg)
2271            errormsg=['error in reading ' FieldName_1 ' in ' FileName_1 ': ' errormsg];
2272            return
2273        end
2274        if isstruct(ParamOut_1)&&~strcmp(ParamOut_1.FieldName,'get_field...')&& (strcmp(UvData.FileType{2},'civdata')||strcmp(UvData.FileType{2},'civx'))...
2275                &&~strcmp(ParamOut_1.FieldName,'velocity') && ~strcmp(ParamOut_1.FieldName,'get_field...')
2276            if ~check_proj_tps
2277            end
2278        end
2279    end
2280    Field{2}.ZIndex=z_index;%used for multi-plane 3D calibration
2281end
2282
2283%% update uvmat interface
2284if isfield(ParamOut,'Npx')
2285    set(handles.num_Npx,'String',num2str(ParamOut.Npx));% display image size on the interface
2286    set(handles.num_Npy,'String',num2str(ParamOut.Npy));
2287elseif isfield(ParamOut_1,'Npx')
2288    set(handles.num_Npx,'String',num2str(ParamOut_1.Npx));% display image size on the interface
2289    set(handles.num_Npy,'String',num2str(ParamOut_1.Npy));
2290end
2291
2292%% update the display menu for the first velocity type (first menuline)
2293test_veltype=0;
2294if (strcmp(UvData.FileType{1},'civx')||strcmp(UvData.FileType{1},'civdata'))&& ~strcmp(FieldName,'get_field...')
2295    test_veltype=1;
2296    set(handles.VelType,'Visible','on')
2297    set(handles.VelType_1,'Visible','on')
2298    set(handles.FixVelType,'Visible','on')
2299    menu=set_veltype_display(ParamOut.CivStage,UvData.FileType{1});
2300    index_menu=strcmp(ParamOut.VelType,menu);%look for VelType in  the menu
2301    index_val=find(index_menu,1);
2302    if isempty(index_val)
2303        index_val=1;
2304    end
2305    set(handles.VelType,'Value',index_val)
2306    if ~get(handles.SubField,'value')
2307        set(handles.VelType,'String',menu)
2308        set(handles.VelType_1,'Value',1)
2309        set(handles.VelType_1,'String',[{''};menu])
2310    end
2311else
2312    set(handles.VelType,'Visible','off')
2313end
2314
2315%% update the display menu for the second velocity type (second menuline)
2316test_veltype_1=0;
2317if isempty(FileName_1)
2318elseif ~test_keepdata_1
2319    if (strcmp(UvData.FileType{2},'civx')||strcmp(UvData.FileType{2},'civdata'))&& ~strcmp(FieldName_1,'get_field...')
2320        test_veltype_1=1;
2321        set(handles.VelType_1,'Visible','on')
2322        menu=set_veltype_display(ParamOut_1.CivStage,UvData.FileType{2});
2323        index_menu=strcmp(ParamOut_1.VelType,menu);
2324        set(handles.VelType_1,'Value',1+find(index_menu,1))
2325        set(handles.VelType_1,'String',[{''};menu])
2326    else
2327         set(handles.VelType_1,'Visible','off')
2328    end
2329    % update the second field menu: the same quantity
2330    if isstruct(ParamOut_1)
2331        % display the FieldName menu from the input file and pick the selected one:
2332        FieldList=get(handles.FieldName_1,'String');
2333        field_index=strcmp(ParamOut_1.FieldName,FieldList);
2334        if ~isempty(field_index)
2335            set(handles.FieldName_1,'Value',find(field_index,1))
2336        end
2337    end
2338end
2339if test_veltype||test_veltype_1
2340    set(handles.FixVelType,'Visible','on')
2341else
2342    set(handles.FixVelType,'Visible','off')
2343end
2344   
2345%% introduce w as background image by default for a new series (only for nbdim=2)
2346if ~isfield(UvData,'NewSeries')
2347    UvData.NewSeries=1;
2348end
2349%put W as background image by default if NbDim=2:
2350if  UvData.NewSeries && isequal(get(handles.SubField,'Value'),0) && isfield(Field{1},'W') && ~isempty(Field{1}.W) && ~isequal(Field{1}.NbDim,3);
2351        set(handles.SubField,'Value',1);
2352        set(handles.RootPath_1,'String','"')
2353        set(handles.RootFile_1,'String','"')
2354        set(handles.SubDir_1,'String','"');
2355         indices=fullfile_uvmat('','','','',NomType,num_i1,num_i2,num_j1,num_j2);
2356        set(handles.FileIndex_1,'String',indices)
2357        set(handles.FileExt_1,'String','"');
2358        set(handles.FieldName_1,'Visible','on');
2359        set(handles.FieldName_1,'Visible','on');
2360        set(handles.RootPath_1,'Visible','on')
2361        set(handles.RootFile_1,'Visible','on')
2362        set(handles.SubDir_1,'Visible','on');
2363        set(handles.FileIndex_1,'Visible','on');
2364        set(handles.FileExt_1,'Visible','on');
2365        set(handles.FieldName_1,'Visible','on');
2366        Field{1}.AName='w';
2367end           
2368
2369%% display time value of the current file
2370abstime=[];%default inputs
2371dt=[];
2372TimeUnit='';
2373if isfield(UvData,'TimeUnit')
2374    TimeUnit=UvData.TimeUnit;%retrieve info from update_rootinfo
2375end
2376TimeName=get(handles.TimeName,'String');
2377
2378% time from xml file or video movie
2379if strcmp(TimeName,'xml')||strcmp(TimeName,'video')
2380    if isempty(num_i2)||isnan(num_i2)
2381        num_i2=num_i1;
2382    end
2383    if isempty(num_j1)||isnan(num_j1)
2384        num_j1=1;
2385    end
2386    if isempty(num_j2)||isnan(num_j2)
2387        num_j2=num_j1;
2388    end
2389    siz=size(UvData.XmlData{1}.Time);
2390    if ~isempty(num_i1)&& ~isempty(num_i2) && num_i1>=0 &&siz(1)>=max(num_i1+1,num_i2+1) && siz(2)>=max(num_j1+1,num_j2+1)
2391        abstime=(UvData.XmlData{1}.Time(num_i1+1,num_j1+1)+UvData.XmlData{1}.Time(num_i2+1,num_j2+1))/2;%overset the time read from files
2392        dt=(UvData.XmlData{1}.Time(num_i2+1,num_j2+1)-UvData.XmlData{1}.Time(num_i1+1,num_j1+1));
2393        Field{1}.Dt=dt;
2394        if isfield(UvData.XmlData{1},'TimeUnit')
2395            TimeUnit=UvData.XmlData{1}.TimeUnit;
2396        end
2397    end
2398end
2399
2400% time in the input file, not defined in a xml file or movie
2401if isempty(abstime)
2402    if strcmp(TimeName,'civdata')||strcmp(TimeName,'civx')
2403        abstime=Field{1}.Time;
2404    elseif ~isempty(regexp(TimeName,'^att:', 'once'))
2405        abstime=Field{1}.(TimeName(5:end));%the time is an attribute  selected by get_file
2406        if isfield(Field{1},[TimeName(5:end) 'Unit'])
2407            TimeUnit=Field{1}.([TimeName(5:end) 'Unit']);
2408        else
2409            TimeUnit='';
2410        end
2411    elseif  ~isempty(regexp(TimeName,'^var:'))
2412        abstime=Field{1}.(TimeName(5:end));%the time is a variale selected by get_file
2413        % TODO: look for time unit attribute
2414    elseif ~isempty(regexp(TimeName,'^dim:'))
2415        abstime=str2num(get(handles.i1,'String'));
2416        TimeUnit='index';
2417    end
2418    if isfield(Field{1},'Dt')
2419        dt=Field{1}.Dt;%dt read from the netcdf input file
2420    elseif numel(Field)==2 && isfield(Field{2},'Dt')%dt obtained from the second field if not defined in the first
2421        dt=Field{2}.Dt;%dt read from the netcdf input file
2422    end
2423end
2424set(handles.TimeValue,'String',num2str(abstime))
2425
2426%% display time value of the second current file if relevant
2427abstime_1=[];
2428if ~isempty(FileName_1)
2429    TimeName_1=get(handles.TimeName_1,'String');% indicate whether time is from xml or video
2430    % time from xml file or video movie as a second file series
2431    if strcmp(TimeName_1,'xml')||strcmp(TimeName_1,'video')
2432        if numel(UvData.XmlData)==2
2433            if isempty(i2_1)
2434                i2_1=num_i1;
2435            end
2436            if isempty(j1_1)
2437                j1_1=1;
2438            end
2439            if isempty(j2_1)
2440                j2_1=j1_1;
2441            end
2442            siz=size(UvData.XmlData{2}.Time);
2443            if ~isempty(i1_1) && siz(1)>=max(i1_1+1,i2_1+1) && siz(2)>=max(j1_1+1,j2_1+1)
2444                abstime_1=(UvData.XmlData{2}.Time(i1_1+1,j1_1+1)+UvData.XmlData{2}.Time(i2_1+1,j2_1+1))/2;%overset the time read from files
2445                Field{2}.Dt=(UvData.XmlData{2}.Time(i2_1+1,j2_1+1)-UvData.XmlData{2}.Time(i1_1+1,j1_1+1));
2446            end
2447        end
2448    end
2449   
2450    % get time in the input file of the second series, not defined in a xml file or movie
2451    if isempty(abstime_1) && numel(Field)==2
2452         if strcmp(TimeName_1,'civdata')||strcmp(TimeName_1,'civx')
2453        abstime_1=Field{2}.Time;
2454         elseif  ~isempty(regexp(TimeName_1,'^att:')) ||~isempty(regexp(TimeName_1,'^dim:'))||~isempty(regexp(TimeName_1,'^var:'))
2455        abstime_1=Field{2}.(TimeName_1(5:end));%the time is an attribute or variale selected by get_file
2456         end
2457    end
2458    set(handles.TimeValue_1,'String',num2str(abstime_1,5))
2459end
2460
2461if isempty(dt)||isequal(dt,0)
2462    set(handles.Dt_txt,'String','')
2463else
2464    if  isempty(TimeUnit)
2465        set(handles.Dt_txt,'String',['Dt=' num2str(1000*dt,3) '  10^(-3)'] )
2466    else
2467        set(handles.Dt_txt,'String',['Dt=' num2str(1000*dt,3) '  m' TimeUnit] )
2468    end
2469end
2470
2471%% Time title with unit
2472if isempty(abstime)&&isempty(abstime_1)
2473    Time_title='';
2474else
2475    Time_title='Time';
2476    if ~isempty(TimeUnit)
2477        Time_title=['Time (' TimeUnit ')'];
2478    end
2479end
2480set(handles.Time_title,'String',Time_title)
2481
2482%% store the current open names, fieldname and vel types in uvmat interface
2483UvData.FileName_1=FileName_1;
2484UvData.ParamOut_1=ParamOut_1;
2485if numel(Field)==2
2486    UvData.Field_1=Field{2}; %store the second field for possible use at next RUN
2487end
2488
2489%% apply coordinate transform or other user fct
2490transform=get(handles.TransformPath,'UserData');
2491if isempty(transform)
2492    UvData.Field=Field{1};
2493else
2494    XmlData=[];%default
2495    XmlData_1=[];%default
2496    if isfield(UvData,'XmlData')%use geometry calib recorded from the ImaDoc xml file as first priority
2497        XmlData=UvData.XmlData{1};
2498        if numel(UvData.XmlData)==2
2499            XmlData_1=UvData.XmlData{2};
2500        end
2501    end
2502    switch nargin(transform)
2503        case 4
2504            if length(Field)==2
2505                UvData.Field=transform(Field{1},XmlData,Field{2},XmlData_1);
2506            else
2507                UvData.Field=transform(Field{1},XmlData);
2508            end
2509        case 3
2510            if length(Field)==2
2511                UvData.Field=transform(Field{1},XmlData,Field{2});
2512            else
2513                UvData.Field=transform(Field{1},XmlData);
2514            end
2515        case 2
2516            UvData.Field=transform(Field{1},XmlData);
2517        case 1
2518            UvData.Field=transform(Field{1});
2519    end
2520end
2521
2522%% calculate tps coefficients if needed
2523UvData.Field=tps_coeff_field(UvData.Field,check_proj_tps);
2524
2525%% get bounds and dimensions of the input field
2526UvData.Field=find_field_bounds(UvData.Field);
2527
2528testnewseries=UvData.NewSeries;
2529UvData.NewSeries=0;% put to 0 the test for a new field series (set by RootPath_callback)
2530
2531%% reset the min and max of scalar if only the mask is displayed(TODO: check the need)
2532% if isfield(UvData,'Mask')&& ~isfield(UvData,'A')
2533%     set(handles.num_MinA,'String','0')
2534%     set(handles.num_MaxA,'String','255')
2535% end
2536
2537%% usual 1D (x,y) plots
2538if UvData.Field.NbDim<=1
2539    set(handles.Objects,'Visible','off')
2540    [PlotType,PlotParamOut]=plot_field(UvData.Field,handles.PlotAxes,read_GUI(handles.uvmat));
2541    errormsg=fill_GUI(PlotParamOut,handles.uvmat);
2542    for list={'Scalar','Vectors'}
2543        if ~isfield(PlotParamOut,list{1})
2544            set(handles.(list{1}),'Visible','off')
2545        end
2546    end
2547    set(handles.uvmat,'UserData',UvData)
2548%% 2D or 3D fieldname are generally projected
2549else
2550    set(handles.Objects,'Visible','on')
2551   
2552    %% Plot the projections on the selected  projection objects
2553    %if no projection object exists, create a default one
2554    if isempty(UvData.ProjObject{1})
2555        set(handles.ListObject,'Value',1)
2556        set(handles.ListObject,'String',{'plane'})
2557        UvData.ProjObject{1}.Type='plane';%main plotting plane
2558        UvData.ProjObject{1}.ProjMode='projection';%main plotting plane
2559        UvData.ProjObject{1}.DisplayHandle.uvmat=[]; %plane not visible in uvmat
2560        UvData.ProjObject{1}.DisplayHandle.view_field=[]; %plane not visible in uvmat
2561        set(handles.ListObject_1,'Value',1)
2562        set(handles.ListObject_1,'String',{'plane'})
2563        if UvData.Field.NbDim==3 %3D case
2564%             ZBounds(1)=UvData.Field.ZMin; %minimum for the Z slider
2565%             ZBounds(2)=UvData.Field.ZMax;%maximum for the Z slider
2566            UvData.ProjObject{1}.NbDim=3;%test for 3D objects
2567            UvData.ProjObject{1}.RangeZ=UvData.Field.CoordMesh;%main plotting plane
2568            UvData.ProjObject{1}.Coord(1,3)=(UvData.Field.ZMin+UvData.Field.ZMax)/2;%section at a middle plane chosen
2569            UvData.ProjObject{1}.Angle=[0 0 0];
2570        elseif isfield(UvData,'Z')
2571            %multilevel case (single menuplane in a 3D space)
2572            if isfield(UvData,'CoordType')&& isequal(UvData.CoordType,'phys') && isfield(UvData,'XmlData')
2573                XmlData=UvData.XmlData{1};
2574                if isfield(XmlData,'PlanePos')
2575                    UvData.ProjObject{1}.Coord=XmlData.PlanePos(UvData.ZIndex,:);
2576                end
2577                if isfield(XmlData,'PlaneAngle')
2578                    siz=size(XmlData.PlaneAngle);
2579                    indangle=min(siz(1),UvData.ZIndex);%take first angle if a single angle is defined (translating scanning)
2580                    UvData.ProjObject{1}.PlaneAngle=XmlData.PlaneAngle(indangle,:);
2581                end
2582            elseif isfield(UvData,'ZIndex')
2583                UvData.ProjObject{1}.ZObject=UvData.ZIndex;
2584            end
2585        end
2586    end
2587    IndexObj=get(handles.ListObject_1,'Value');%selected projection object for main view
2588    if IndexObj> numel(UvData.ProjObject)
2589        IndexObj=1;%select the first object if the selected one does not exist
2590        set(handles.ListObject_1,'Value',1)
2591    end
2592    if get(handles.CheckViewField,'Value')
2593        IndexObj_2=get(handles.ListObject,'Value');%selected projection object for view_field
2594        if ~isequal(IndexObj_2,IndexObj(1))
2595            IndexObj(2)=IndexObj_2;
2596        end
2597    end
2598    plot_handles{1}=handles;
2599    if isfield(UvData,'plotaxes')%case of movies
2600        haxes(1)=UvData.plotaxes;
2601    else
2602        haxes(1)=handles.PlotAxes;
2603    end
2604    PlotParam{1}=read_GUI(handles.uvmat);
2605    %default settings if vectors not visible
2606    if ~isfield(PlotParam{1},'Vectors')
2607        PlotParam{1}.Vectors.MaxVec=1;
2608        PlotParam{1}.Vectors.MinVec=0;
2609        PlotParam{1}.Vectors.CheckFixVecColor=1;
2610        PlotParam{1}.Vectors.ColCode1=0.33;
2611        PlotParam{1}.Vectors.ColCode2=0.66;
2612        PlotParam{1}.Vectors.ColorScalar={''};
2613        PlotParam{1}.Vectors.ColorCode= {'rgb'};
2614    end
2615    PosColorbar{1}=UvData.OpenParam.PosColorbar;%prescribe the colorbar position on the uvmat interface
2616   
2617    %% second projection object (view_field display)
2618    if length( IndexObj)==2
2619        view_field_handle=findobj(allchild(0),'tag','view_field');%handles of the view_field GUI
2620        if ~isempty(view_field_handle)
2621            plot_handles{2}=guidata(view_field_handle);
2622            haxes(2)=plot_handles{2}.PlotAxes;
2623            PlotParam{2}=read_GUI(view_field_handle);
2624            PosColorbar{2}='*'; %TODO: deal with colorbar position on view_field
2625        end
2626    end
2627   
2628    %% loop on the projection objects: one or two
2629   
2630    for imap=1:numel(IndexObj)
2631        iobj=IndexObj(imap);
2632        if numel(UvData.ProjObject)<iobj
2633            break
2634        end
2635        if UvData.Field.NbDim==3
2636            UvData.ProjObject{iobj}.NbDim=3;%test for 3D objects
2637            if ~isfield(UvData.ProjObject{iobj},'RangeZ')
2638            UvData.ProjObject{iobj}.RangeZ=UvData.Field.CoordMesh;%main plotting plane
2639            end
2640            if ~(isfield(UvData.ProjObject{iobj},'Coord') && UvData.ProjObject{iobj}.Coord(1,3)<UvData.Field.ZMax && UvData.ProjObject{iobj}.Coord(1,3)>UvData.Field.ZMin)
2641                 UvData.ProjObject{iobj}.Coord(1,3)=(UvData.Field.ZMin+UvData.Field.ZMax)/2;%section at a middle plane chosen
2642            end         
2643        end
2644        [ObjectData,errormsg]=proj_field(UvData.Field,UvData.ProjObject{iobj});% project field on the object
2645        if ~isempty(errormsg)
2646            return
2647        end
2648        if testnewseries
2649            PlotParam{imap}.Scalar.CheckBW=[]; %B/W option depends on the input field (image or scalar)
2650            if isfield(ObjectData,'CoordUnit')
2651                PlotParam{imap}.Axes.CheckFixAspectRatio=1;% set x and y scaling equal if CoordUnit is defined (common unit for x and y)
2652                PlotParam{imap}.Axes.AspectRatio=1; %set aspect ratio to 1
2653            end
2654        end
2655        %use of mask (TODO: check)
2656        if isfield(ObjectData,'NbDim') && isequal(ObjectData.NbDim,2) && isfield(ObjectData,'Mask') && isfield(ObjectData,'A')
2657            flag_mask=double(ObjectData.Mask>200);%=0 for masked regions
2658            AX=ObjectData.AX;%x coordiantes for the scalar field
2659            AY=ObjectData.AY;%y coordinates for the scalar field
2660            MaskX=ObjectData.MaskX;%x coordiantes for the mask
2661            MaskY=ObjectData.MaskY;%y coordiantes for the mask
2662            if ~isequal(MaskX,AX)||~isequal(MaskY,AY)
2663                nxy=size(flag_mask);
2664                sizpx=(ObjectData.MaskX(end)-ObjectData.MaskX(1))/(nxy(2)-1);%size of a mask pixel
2665                sizpy=(ObjectData.MaskY(1)-ObjectData.MaskY(end))/(nxy(1)-1);
2666                x_mask=ObjectData.MaskX(1):sizpx:ObjectData.MaskX(end); % pixel x coordinates for image display
2667                y_mask=ObjectData.MaskY(1):-sizpy:ObjectData.MaskY(end);% pixel x coordinates for image display
2668                %project on the positions of the scalar
2669                npxy=size(ObjectData.A);
2670                dxy(1)=(ObjectData.AY(end)-ObjectData.AY(1))/(npxy(1)-1);%grid mesh in y
2671                dxy(2)=(ObjectData.AX(end)-ObjectData.AX(1))/(npxy(2)-1);%grid mesh in x
2672                xi=ObjectData.AX(1):dxy(2):ObjectData.AX(end);
2673                yi=ObjectData.AY(1):dxy(1):ObjectData.AY(end);
2674                [XI,YI]=meshgrid(xi,yi);% creates the matrix of regular coordinates
2675                flag_mask = interp2(x_mask,y_mask,flag_mask,XI,YI);
2676            end
2677            AClass=class(ObjectData.A);
2678            ObjectData.A=flag_mask.*double(ObjectData.A);
2679            ObjectData.A=feval(AClass,ObjectData.A);
2680        end
2681        if ~isempty(ObjectData)
2682            %PlotType='none'; %default
2683            if imap==2 && isempty(view_field_handle)
2684                view_field(ObjectData)
2685            else
2686              %  ObjectData.VarAttribute{5}.Role='scalar';TODO    CORRECT
2687                [PlotType,PlotParamOut]=plot_field(ObjectData,haxes(imap),PlotParam{imap},PosColorbar{imap});
2688                if imap==1
2689                    errormsg=fill_GUI(PlotParamOut,handles.uvmat);
2690                else
2691                    errormsg=fill_GUI(PlotParamOut,view_field_handle);
2692                end
2693                for list={'Scalar','Vectors'}
2694                    if ~isfield(PlotParamOut,list{1})
2695                        set(plot_handles{imap}.(list{1}),'Visible','off')
2696                    end
2697                end
2698                if isfield(Field,'CoordMesh')&&~isempty(Field.CoordMesh)
2699                    ObjectData.CoordMesh=Field.CoordMesh; % gives an estimated mesh size (useful for mouse action on the plot)
2700                end
2701            end
2702        end
2703    end
2704   
2705    set(handles.uvmat,'UserData',UvData)
2706   
2707    %% update the mask
2708    if isequal(get(handles.CheckMask,'Value'),1)%if the mask option is on
2709        update_mask(handles);
2710    end
2711   
2712    %% prepare the menus of histograms and plot them (histogram of the whole volume in 3D case)
2713    menu_histo=(UvData.Field.ListVarName)';%list of field variables to be displayed for the menu of histogram display
2714    ind_skip=[];
2715    % nb_histo=1;
2716    Ustring='';
2717    Vstring='';
2718    % suppress axes from the histogram menu
2719    for ivar=1:numel(menu_histo)%l loop on field variables:
2720        if isfield(UvData.Field,'VarAttribute') && numel(UvData.Field.VarAttribute)>=ivar && isfield(UvData.Field.VarAttribute{ivar},'Role')
2721            Role=UvData.Field.VarAttribute{ivar}.Role;
2722            switch Role
2723                case {'coord_x','coord_y','coord_z','dimvar'}
2724                    ind_skip=[ind_skip ivar];
2725                case {'vector_x'}
2726                    Ustring=UvData.Field.ListVarName{ivar};
2727                    ind_skip=[ind_skip ivar];
2728                case {'vector_y'}
2729                    Vstring=UvData.Field.ListVarName{ivar};
2730                    ind_skip=[ind_skip ivar];
2731            end
2732        end
2733        DimCell=UvData.Field.VarDimName{ivar};
2734        DimName='';
2735        if ischar(DimCell)
2736            DimName=DimCell;
2737        elseif iscell(DimCell)&& numel(DimCell)==1
2738            DimName=DimCell{1};
2739        end
2740        if strcmp(DimName,menu_histo{ivar})
2741            ind_skip=[ind_skip ivar];
2742        end
2743    end
2744    menu_histo(ind_skip)=[];% remove skipped items
2745    if ~isempty(Ustring)
2746        menu_histo=[{[Ustring ',' Vstring]};menu_histo];% add U, V at the beginning if they exist
2747    end
2748   
2749    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2750    % display menus and plot histograms
2751    test_v=0;
2752    if ~isempty(menu_histo)
2753        set(handles.histo1_menu,'Value',1)
2754        set(handles.histo1_menu,'String',menu_histo)
2755        histo1_menu_Callback(handles.histo1_menu, [], handles)% plot first histogram
2756    end
2757end
2758
2759if UvData.Field.NbDim==3
2760    set(handles.CheckEditObject,'Value',1)
2761    CheckEditObject_Callback(handles.uvmat, [], handles)
2762end   
2763ResizeFcn(handles.uvmat,[],handles)
2764set(handles.uvmat,'Pointer',pointer)
2765
2766%------------------------------------------------------------------------
2767function histo1_menu_Callback(hObject, eventdata, handles)
2768%--------------------------------------------
2769%% get the current field stored in uvmat user data
2770UvData=get(handles.uvmat,'UserData');
2771Field=UvData.Field;
2772
2773%% get from the menu 'histo1_menu' the name(s) of the fields to use
2774histo_menu=get(handles.histo1_menu,'String');
2775histo_value=get(handles.histo1_menu,'Value');
2776FieldName=histo_menu{histo_value};
2777r=regexp(FieldName,'(?<var1>.*)(?<sep>,)(?<var2>.*)','names');
2778FieldName_2='';
2779if ~isempty(r)
2780    FieldName=r.var1;% name of first variable
2781    FieldName_2=r.var2;% name of second variable
2782end
2783if ~isfield(UvData.Field,FieldName)
2784    msgbox_uvmat('ERROR',['no field  ' FieldName ' for histogram'])
2785    return
2786end
2787
2788%% extract the fields to use
2789% eliminate false data if relevant (false flag FF exists)
2790check_false=0;
2791if isfield(Field,'FF') && ~isempty(Field.FF) && isequal(size(Field.FF),size(Field.(FieldName)))
2792    indsel=find(Field.FF==0);%find values marked as false
2793    if ~isempty(indsel)
2794        FieldHisto=Field.(FieldName)(indsel);%field of the first variable (U)
2795        if ~isempty(FieldName_2)
2796            if isfield(Field,'NbDim') && Field.NbDim==3
2797                 FieldHisto(:,:,:,2)=Field.(FieldName_2)(indsel);%field of the second variable (U)
2798            else
2799            FieldHisto(:,:,2)=Field.(FieldName_2)(indsel);%field of the second variable (U)
2800            end
2801        end
2802        check_false=1;
2803    end
2804end
2805% no false data
2806if ~check_false
2807    FieldHisto=Field.(FieldName);%field of the first variable (U)
2808    if ~isempty(FieldName_2)
2809        if isfield(Field,'NbDim') && Field.NbDim==3
2810            FieldHisto(:,:,:,2)=Field.(FieldName_2);%field of the second variable (V)
2811        else
2812            FieldHisto(:,:,2)=Field.(FieldName_2);%field of the second variable (V)
2813        end
2814    end
2815end
2816
2817%% calculate and plot histogram
2818if isempty(Field)
2819    msgbox_uvmat('ERROR',['empty field ' FieldName])
2820else
2821    nxy=size(FieldHisto);
2822    Amin=double(min(min(min(min(FieldHisto)))));%min of field value
2823    Amax=double(max(max(max(max(FieldHisto)))));%max of field value
2824    if isequal(Amin,Amax)
2825        cla(handles.HistoAxes)
2826    else
2827        Histo.ListVarName={FieldName,'histo'};
2828        if isfield(Field,'NbDim') && isequal(Field.NbDim,3)
2829            Histo.VarDimName={FieldName,FieldName}; %dimensions for the histogram
2830        else
2831            if numel(nxy)==2
2832                Histo.VarDimName={FieldName,FieldName}; %dimensions for the histogram
2833            else
2834                Histo.VarDimName={FieldName,{FieldName,'component'}}; %dimensions for the histogram
2835            end
2836        end
2837        %unit
2838        units=[]; %default
2839        for ivar=1:numel(Field.ListVarName)
2840            if strcmp(Field.ListVarName{ivar},FieldName)
2841                if isfield(Field,'VarAttribute') && numel(Field.VarAttribute)>=ivar && isfield(Field.VarAttribute{ivar},'units')
2842                    units=Field.VarAttribute{ivar}.units;
2843                    break
2844                end
2845            end
2846        end
2847        if ~isempty(units)
2848            Histo.VarAttribute{1}.units=units;
2849        end
2850        Histo.(FieldName)=linspace(Amin,Amax,50); %absissa values for histo
2851        if isfield(Field,'NbDim') && isequal(Field.NbDim,3)
2852            C=reshape(double(FieldHisto),1,[]);% reshape in a vector
2853            Histo.histo(:,1)=hist(C, Histo.(FieldName));  %calculate histogram
2854        else
2855            for col=1:size(FieldHisto,3)
2856                B=FieldHisto(:,:,col);
2857                C=reshape(double(B),1,nxy(1)*nxy(2));% reshape in a vector
2858                Histo.histo(:,col)=hist(C, Histo.(FieldName));  %calculate histogram
2859            end
2860        end
2861        plot_field(Histo,handles.HistoAxes);
2862        hlegend=legend;
2863        if isempty(FieldName_2)
2864        set(hlegend,'String',FieldName)
2865        else
2866            set(hlegend,'String',{FieldName;FieldName_2})
2867        end
2868    end
2869end
2870
2871%------------------------------------------------------------------------
2872% --- translate coordinate to matrix index
2873%------------------------------------------------------------------------
2874function [indx,indy]=pos2ind(x0,rangx0,nxy)
2875indx=1+round((nxy(2)-1)*(x0-rangx0(1))/(rangx0(2)-rangx0(1)));% index x of pixel 
2876indy=1+round((nxy(1)-1)*(y12-rangy0(1))/(rangy0(2)-rangy0(1)));% index y of pixel
2877
2878%------------------------------------------------------------------------
2879% --- Executes on button press in 'CheckZoom'.
2880%------------------------------------------------------------------------
2881function CheckZoom_Callback(hObject, eventdata, handles)
2882
2883    if get(handles.CheckZoom,'Value')
2884        set(handles.CheckFixLimits,'Value',1)% propose by default fixed limits for the plotting axes
2885        set(handles.CheckZoomFig,'Value',0)%desactivate zoom fig
2886    end
2887
2888
2889%------------------------------------------------------------------------
2890% --- Executes on button press in CheckZoomFig.
2891%------------------------------------------------------------------------
2892function CheckZoomFig_Callback(hObject, eventdata, handles)
2893
2894if get(handles.CheckZoomFig,'Value')
2895    set(handles.CheckZoom,'value',0)
2896end
2897
2898%------------------------------------------------------------------------
2899% --- Executes on button press in 'CheckFixLimits'.
2900%------------------------------------------------------------------------
2901function CheckFixLimits_Callback(hObject, eventdata, handles)
2902
2903if ~get(handles.CheckFixLimits,'Value')
2904    update_plot(handles)
2905    set(handles.CheckZoom,'Value',0)
2906end
2907
2908%------------------------------------------------------------------------
2909% --- Executes on button press in CheckFixAspectRatio.
2910function CheckFixAspectRatio_Callback(hObject, eventdata, handles)
2911%------------------------------------------------------------------------
2912
2913% if get(handles.CheckFixAspectRatio,'Value')
2914    update_plot(handles);
2915% else
2916%     update_plot(handles);
2917% end
2918
2919%------------------------------------------------------------------------
2920function num_AspectRatio_Callback(hObject, eventdata, handles)
2921%------------------------------------------------------------------------
2922set(handles.CheckFixAspectRatio,'Value',1)% select the fixed aspect ratio button
2923update_plot(handles);
2924
2925%------------------------------------------------------------------------
2926%----Executes on button press in 'record': records the current flags of manual correction.
2927%------------------------------------------------------------------------
2928function record_Callback(hObject, eventdata, handles)
2929
2930[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
2931FileName=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
2932[erread,message]=fileattrib(FileName);
2933if ~isempty(message) && ~isequal(message.UserWrite,1)
2934     msgbox_uvmat('ERROR',['no writting access to ' FileName])
2935     return
2936end
2937MenuVelType=get(handles.VelType,'String');
2938test_civ2=strcmp(MenuVelType{get(handles.VelType,'Value')},'civ2');
2939test_civ1=strcmp(MenuVelType{get(handles.VelType,'Value')},'civ1');
2940if ~test_civ2 && ~test_civ1
2941    msgbox_uvmat('ERROR','manual correction only possible for CIV1 or CIV2 velocity fields')
2942end
2943if test_civ2
2944    nbname='nb_vec_2';
2945   flagname='Civ2_FF';
2946   CivStage=5;
2947end
2948if test_civ1
2949    nbname='nb_vec_1';
2950   flagname='Civ1_FF';
2951    CivStage=2;
2952end
2953%write fix flags in the netcdf file
2954UvData=get(handles.uvmat,'UserData');
2955hhh=which('netcdf.open');% look for built-in matlab netcdf library
2956if ~isequal(hhh,'')% case of  builtin Matlab netcdf library
2957    nc=netcdf.open(FileName,'NC_WRITE');
2958    netcdf.reDef(nc);
2959    netcdf.putAtt(nc,netcdf.getConstant('NC_GLOBAL'),'CivStage',CivStage);
2960    dimid = netcdf.inqDimID(nc,nbname);
2961    try
2962        varid = netcdf.inqVarID(nc,flagname);% look for already existing fixflag variable
2963    catch
2964        varid=netcdf.defVar(nc,flagname,'double',dimid);%create fixflag variable if it does not exist
2965    end
2966    netcdf.endDef(nc);
2967    netcdf.putVar(nc,varid,UvData.PlotAxes.FF);
2968    netcdf.close(nc); 
2969else %old netcdf library
2970    netcdf_toolbox(FileName,AxeData,attrname,nbname,flagname)
2971end
2972
2973%-------------------------------------------------------------------
2974%----Correct the netcdf file, using toolbox (old versions of Matlab).
2975%-------------------------------------------------------------------
2976function netcdf_toolbox(FileName,AxeData,attrname,nbname,flagname)
2977nc=netcdf(FileName,'write'); %open netcdf file
2978result=redef(nc);
2979eval(['nc.' attrname '=1;']);
2980theDim=nc(nbname) ;% get the number of velocity vectors
2981nb_vectors=size(theDim);
2982var_FixFlag=ncvar(flagname,nc);% var_FixFlag will be written as the netcdf variable vec_FixFlag
2983var_FixFlag(1:nb_vectors)=AxeData.FF;%
2984fin=close(nc);
2985
2986%-----------------------------------------------------------------------
2987% --- Executes on button press in SubField
2988%-----------------------------------------------------------------------
2989function SubField_Callback(hObject, eventdata, handles)
2990
2991if get(handles.SubField,'Value')==0% if the subfield button is desactivated 
2992    desable_subfield(handles)
2993    transform_fct_list=get(handles.TransformName,'String');
2994    transform_fct=transform_fct_list(get(handles.TransformName,'Value'));
2995    if strcmp(transform_fct,'sub_field')
2996        set(handles.TransformName,'Value',1)%suppress the sub_field transform
2997        TransformName_Callback(hObject, eventdata, handles);
2998    else
2999        REFRESH_Callback(hObject, eventdata, handles)
3000    end 
3001else
3002    fileinput_1=uigetfile_uvmat('select a second input file:',get(handles.RootPath,'String'));
3003    if isempty(fileinput_1)
3004        set(handles.SubField,'Value',0)
3005    else       
3006        % refresh the current displayed field
3007        display_file_name(handles,fileinput_1,2)
3008       
3009        %update list of recent files in the menubar
3010        MenuFile_1=fileinput_1;
3011        MenuFile_2=get(handles.MenuFile_1,'Label');
3012        MenuFile_3=get(handles.MenuFile_2,'Label');
3013        MenuFile_4=get(handles.MenuFile_3,'Label');
3014        MenuFile_5=get(handles.MenuFile_4,'Label');
3015        set(handles.MenuFile_1,'Label',MenuFile_1)
3016        set(handles.MenuFile_2,'Label',MenuFile_2)
3017        set(handles.MenuFile_3,'Label',MenuFile_3)
3018        set(handles.MenuFile_4,'Label',MenuFile_4)
3019        set(handles.MenuFile_5,'Label',MenuFile_5)
3020    end
3021end
3022
3023%-----------------------------------------------------------------------
3024% --- desactivate display used for a second file series
3025%-----------------------------------------------------------------------
3026function desable_subfield(handles)
3027   
3028set(handles.RootPath_1,'String','')
3029set(handles.RootFile_1,'String','')
3030set(handles.SubDir_1,'String','');
3031set(handles.FileIndex_1,'String','');
3032set(handles.FileExt_1,'String','');
3033set(handles.RootPath_1,'Visible','off')
3034set(handles.RootFile_1,'Visible','off')
3035set(handles.SubDir_1,'Visible','off');
3036set(handles.NomType_1,'Visible','off');
3037set(handles.FileIndex_1,'Visible','off');
3038set(handles.FileExt_1,'Visible','off');
3039set(handles.TimeName_1,'String','');
3040set(handles.TimeName_1,'Visible','off');
3041set(handles.TimeValue_1,'String','');
3042set(handles.TimeValue_1,'Visible','off');
3043set(handles.FieldName_1,'Value',1);%set to blank state
3044set(handles.VelType_1,'Value',1);%set to blank state
3045set(handles.num_Opacity,'String','')% desactivate opacity setting
3046FieldList=get(handles.FieldName,'String');
3047if numel(FieldList)>1   % if a choice of fields exists
3048    set(handles.FieldName_1,'Value',1)% set second field choice to blank
3049    set(handles.FieldName_1,'String',[{''};FieldList])% reproduce the menu FieldName plus a blank option
3050else
3051    set(handles.FieldName_1,'String',{''})% set second field choice to blank
3052end
3053if ~strcmp(get(handles.VelType,'Visible'),'on')
3054    set(handles.VelType_1,'Visible','off')
3055end
3056UvData=get(handles.uvmat,'UserData');
3057if isfield(UvData,'XmlData_1')
3058    UvData=rmfield(UvData,'XmlData_1');
3059end
3060set(handles.uvmat,'UserData',UvData);
3061
3062%------------------------------------------------------------------------
3063% --- read the data displayed for the input rootfile windows (new): TODO use read_GUI
3064%------------------------------------------------------------------------
3065function [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles)
3066
3067InputFile=read_GUI(handles.InputFile);
3068RootPath=InputFile.RootPath;
3069SubDir=regexprep(InputFile.SubDir,'/|\','');
3070RootFile=regexprep(InputFile.RootFile,'/|\','');
3071FileIndices=InputFile.FileIndex;
3072FileExt=InputFile.FileExt;
3073
3074
3075%------------------------------------------------------------------------
3076% ---- read the data displayed for the second input rootfile windows
3077%------------------------------------------------------------------------
3078function [RootPath_1,SubDir_1,RootFile_1,FileIndex_1,FileExt_1,NomType_1]=read_file_boxes_1(handles)
3079
3080RootPath_1=get(handles.RootPath_1,'String'); % read the data from the file1_input window
3081if isequal(get(handles.RootPath_1,'Visible'),'off') || isequal(RootPath_1,'"')
3082    RootPath_1=get(handles.RootPath,'String');
3083end;
3084SubDir_1=get(handles.SubDir_1,'String');
3085if isequal(get(handles.SubDir_1,'Visible'),'off')|| isequal(SubDir_1,'"')
3086    SubDir_1=get(handles.SubDir,'String');
3087end
3088SubDir_1=regexprep(SubDir_1,'\<[\\/]|[\\/]\>','');%suppress possible / or \ separator at the beginning or the end of the string
3089RootFile_1=get(handles.RootFile_1,'String');
3090if isequal(get(handles.RootFile_1,'Visible'),'off') || isequal(RootFile_1,'"')
3091    RootFile_1=get(handles.RootFile,'String');
3092end
3093RootFile_1=regexprep(RootFile_1,'\<[\\/]|[\\/]\>','');%suppress possible / or \ separator at the beginning or the end of the string
3094FileIndex_1=get(handles.FileIndex_1,'String');
3095if isequal(get(handles.FileIndex_1,'Visible'),'off')|| isequal(FileIndex_1,'"')
3096    FileIndex_1=get(handles.FileIndex,'String');
3097end
3098FileExt_1=get(handles.FileExt_1,'String');
3099if isequal(get(handles.FileExt_1,'Visible'),'off') || isequal(FileExt_1,'"')
3100    FileExt_1=get(handles.FileExt,'String');%read FileExt by default
3101end
3102NomType_1=get(handles.NomType_1,'String');
3103if isequal(get(handles.NomType_1,'Visible'),'off') || isequal(NomType_1,'"')
3104    NomType_1=get(handles.NomType,'String');%read FileExt by default
3105end
3106%------------------------------------------------------------------------
3107% --- Executes on menu selection FieldName
3108
3109    function FieldName_Callback(hObject, eventdata, handles)
3110%------------------------------------------------------------------------
3111
3112%% read data from uvmat
3113UvData=get(handles.uvmat,'UserData');
3114list_fields=get(handles.FieldName,'String');% list menu fields
3115index_fields=get(handles.FieldName,'Value');% selected string index
3116field= list_fields{index_fields(1)}; % selected string
3117[RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
3118FileName=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
3119[tild,tild,tild,i1,i2,j1,j2,tild,NomType]=fileparts_uvmat(['xxx' get(handles.FileIndex,'String') FileExt]);
3120
3121switch field 
3122    case 'get_field...'
3123        %% fill the axes and variables from selections in get_field
3124        ParamIn=[];
3125        % in case of civ data, we use the civ choice as default input for the GUI get_field
3126        if strcmp(get(handles.VelType,'Visible'),'on')
3127            ParamIn.SwitchVarIndexTime='attribute';
3128            ListVelType=get(handles.VelType,'String');
3129            VelType=ListVelType{get(handles.VelType,'Value')};
3130            switch VelType
3131                case 'civ1'
3132                    ParamIn.TimeAttrName='Civ1_Time';
3133                    ParamIn.vector_x='Civ1_U';
3134                    ParamIn.vector_y='Civ1_V';
3135                    ParamIn.vec_color='Civ1_C';
3136                case 'filter1'
3137                    ParamIn.TimeAttrName='Civ1_Time';
3138                    ParamIn.vector_x='Civ1_U_smooth';
3139                    ParamIn.vector_y='Civ1_V_smooth';
3140                case 'civ2'
3141                    ParamIn.TimeAttrName='Civ2_Time';
3142                    ParamIn.vector_x='Civ2_U';
3143                    ParamIn.vector_y='Civ2_V';
3144                case 'filter2'
3145                    ParamIn.TimeAttrName='Civ2_Time';
3146                    ParamIn.vector_x='Civ2_U_smooth';
3147                    ParamIn.vector_y='Civ2_V_smooth';
3148                    ParamIn.vec_color='Civ2_C';
3149            end
3150        end
3151       
3152        % VelType menu desactivated
3153        set(handles.FixVelType,'visible','off')
3154        set(handles.VelType,'Visible','off')
3155       
3156        %read selection from get_field
3157        [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes(handles);
3158        FileName=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
3159        GetFieldData=get_field(FileName,ParamIn);% inport field names from the GUI get_field
3160        FieldList={};
3161        VecColorList={''};
3162        ZName='';
3163        switch GetFieldData.FieldOption
3164            case 'vectors'
3165                UName=GetFieldData.PanelVectors.vector_x;
3166                VName=GetFieldData.PanelVectors.vector_y;
3167                YName=GetFieldData.Coordinates.Coord_y;
3168                if isfield(GetFieldData.Coordinates,'Coord_z')
3169                ZName=GetFieldData.Coordinates.Coord_z;
3170                end
3171                CName=GetFieldData.PanelVectors.vec_color;
3172                FieldList={['vec(' UName ',' VName ')'];...
3173                    ['norm(' UName ',' VName ')'];...
3174                    UName;VName};
3175                VecColorList={['norm(' UName ',' VName ')'];...
3176                    UName;VName};
3177                if ~isempty(CName)
3178                    VecColorList=[{CName};VecColorList];
3179                end
3180            case 'scalar'
3181                AName=GetFieldData.PanelScalar.scalar;
3182                YName=GetFieldData.Coordinates.Coord_y;
3183                if isfield(GetFieldData.Coordinates,'Coord_z')
3184                ZName=GetFieldData.Coordinates.Coord_z;
3185                end
3186                FieldList={AName};
3187            case '1D plot'
3188                YName=GetFieldData.PanelOrdinate.ordinate;
3189            case 'civdata...'%reinitiate input, return to automatic civ data reading
3190                display_file_name(handles,FileName,1)
3191        end
3192        % get time as file index, attribute, variable or matrix index
3193        if ~strcmp(GetFieldData.FieldOption,'civdata...')
3194            XName=GetFieldData.Coordinates.Coord_x;
3195            TimeNameStr=GetFieldData.Time.SwitchVarIndexTime;
3196            switch TimeNameStr
3197                case 'file index'
3198                    set(handles.TimeName,'String','');
3199                case 'attribute'
3200                    set(handles.TimeName,'String',['att:' GetFieldData.Time.TimeName]);
3201                case 'variable'
3202                    set(handles.TimeName,'String',['var:' GetFieldData.Time.TimeName])
3203                    set(handles.NomType,'String','*')
3204                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
3205                    set(handles.i1,'String','1')% set counter to 1 (now the time index in the input matrix)
3206                    set(handles.FileIndex,'String','')
3207                    ParamIn.TimeVarName=GetFieldData.Time.TimeName;
3208                case 'matrix index'
3209                    set(handles.TimeName,'String',['dim:' GetFieldData.Time.TimeName]);
3210                    set(handles.NomType,'String','*')
3211                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
3212                    set(handles.i1,'String','1')% set counter to 1 (now the time index in the input matrix)
3213                    set(handles.FileIndex,'String','')
3214                    ParamIn.TimeDimName=GetFieldData.Time.TimeName;
3215            end
3216            set(handles.Coord_x,'String',XName)
3217%             if ischar(YName)
3218%                 YName={YName};
3219%             end
3220            set(handles.Coord_y,'String',YName)
3221            set(handles.Coord_z,'String',ZName)
3222            set(handles.FieldName,'Value',1)
3223            set(handles.FieldName,'String',[FieldList; {'get_field...'}]);
3224            set(handles.ColorScalar,'Value',1)
3225            set(handles.ColorScalar,'String',VecColorList);
3226            UvData.FileType{1}='netcdf';
3227            set(handles.uvmat,'UserData',UvData)
3228            REFRESH_Callback(hObject, eventdata, handles)
3229        end
3230       
3231    case 'image'
3232        %% look for image corresponding to civ data
3233        if  isfield(UvData.Field,'Civ2_ImageA')%get the corresponding input image in the netcdf file
3234            imagename=UvData.Field.Civ2_ImageA;
3235        elseif isfield(UvData.Field,'Civ1_ImageA')%
3236            imagename=UvData.Field.Civ1_ImageA;
3237        else
3238            SubDirBase=regexprep(SubDir,'\..*','');%take the root part of SubDir, before the first dot '.'
3239            imagename=fullfile_uvmat(RootPath,SubDirBase,RootFile,'.png',NomType,i1,[],j1,[]);
3240        end
3241        if ~exist(imagename,'file')
3242            imagename=uigetfile_uvmat('Pick an image file',imagename,'image');
3243            if isempty(imagename)
3244                return
3245            end
3246        end
3247        % display the selected field and related information
3248        display_file_name(handles,imagename)%display the image
3249    otherwise
3250        REFRESH_Callback(hObject, eventdata, handles)
3251end
3252
3253%----------------------------------------------------------------
3254% --- Executes on menu selection FieldName
3255function FieldName_1_Callback(hObject, eventdata, handles)
3256%-------------------------------------------------
3257
3258%%%%%% TODO: modify like FieldName_Callback
3259%% read input data
3260check_new=~get(handles.SubField,'Value'); %check_new=1 if a second field was not previously entered
3261UvData=get(handles.uvmat,'UserData');
3262if check_new && isfield(UvData,'XmlData')
3263    UvData.XmlData{2}=UvData.XmlData{1};
3264end
3265if isfield(UvData,'Field_1')
3266    UvData=rmfield(UvData,'Field_1');% remove the stored second field (a new one needs to be read)
3267end
3268UvData.FileName_1='';% desactivate the use of a constant second file
3269list_fields=get(handles.FieldName,'String');% list menu fields
3270field= list_fields{get(handles.FieldName,'Value')}; % selected string
3271list_fields=get(handles.FieldName_1,'String');% list menu fields
3272field_1= list_fields{get(handles.FieldName_1,'Value')}; % selected string for the second field
3273if isempty(field_1)%||(numel(UvData.FileType)>=2 && strcmp(UvData.FileType{2},'image'))
3274    set(handles.SubField,'Value',0)
3275    SubField_Callback(hObject, eventdata, handles)
3276    return
3277else
3278    set(handles.SubField,'Value',1)%state that a second field is now entered
3279end
3280
3281%% read the rootfile input display
3282[RootPath_1,SubDir_1,RootFile_1,FileIndex_1,FileExt_1]=read_file_boxes_1(handles);
3283FileName_1=[fullfile(RootPath_1,SubDir_1,RootFile_1) FileIndex_1 FileExt_1];
3284[tild,tild,tild,i1,i2,j1,j2]=fileparts_uvmat(get(handles.FileIndex,'String'));
3285switch field_1
3286    case 'get_field...'
3287         %% fill the axes and variables from selections in get_field
3288        ParamIn=[];
3289        % in case of civ data, we use the civ choice as default input for the GUI get_field
3290        if strcmp(get(handles.VelType_1,'Visible'),'on')
3291            ParamIn.SwitchVarIndexTime='attribute';
3292            ListVelType=get(handles.VelType_1,'String');
3293            VelType=ListVelType{get(handles.VelType_1,'Value')};
3294            switch VelType
3295                case 'civ1'
3296                    ParamIn.TimeAttrName='Civ1_Time';
3297                    ParamIn.vector_x='Civ1_U';
3298                    ParamIn.vector_y='Civ1_V';
3299                    ParamIn.vec_color='Civ1_C';
3300                case 'filter1'
3301                    ParamIn.TimeAttrName='Civ1_Time';
3302                    ParamIn.vector_x='Civ1_U_smooth';
3303                    ParamIn.vector_y='Civ1_V_smooth';
3304                case 'civ2'
3305                    ParamIn.TimeAttrName='Civ2_Time';
3306                    ParamIn.vector_x='Civ2_U';
3307                    ParamIn.vector_y='Civ2_V';
3308                case 'filter2'
3309                    ParamIn.TimeAttrName='Civ2_Time';
3310                    ParamIn.vector_x='Civ2_U_smooth';
3311                    ParamIn.vector_y='Civ2_V_smooth';
3312                    ParamIn.vec_color='Civ2_C';
3313            end
3314        end
3315       
3316        % VelType menu desactivated
3317        set(handles.FixVelType,'visible','off')
3318        set(handles.VelType,'Visible','off')
3319       
3320        %read selection from get_field
3321        [RootPath,SubDir,RootFile,FileIndices,FileExt]=read_file_boxes_1(handles);
3322        FileName=[fullfile(RootPath,SubDir,RootFile) FileIndices FileExt];
3323        GetFieldData=get_field(FileName,ParamIn);% inport field names from the GUI get_field
3324        FieldList={};
3325        VecColorList={};
3326        switch GetFieldData.FieldOption
3327            case 'vectors'
3328                UName=GetFieldData.PanelVectors.vector_x;
3329                VName=GetFieldData.PanelVectors.vector_y;
3330                YName=GetFieldData.Coordinates.Coord_y;
3331                CName=GetFieldData.PanelVectors.vec_color;
3332                FieldList={['vec(' UName ',' VName ')'];...
3333                    ['norm(' UName ',' VName ')'];...
3334                    UName;VName};
3335                VecColorList={['norm(' UName ',' VName ')'];...
3336                    UName;VName};
3337                if ~isempty(CName)
3338                    VecColorList=[{CName};VecColorList];
3339                end
3340            case 'scalar'
3341                AName=GetFieldData.PanelScalar.scalar;
3342                YName=GetFieldData.Coordinates.Coord_y;
3343                FieldList={AName};
3344            case '1D plot'
3345                YName=GetFieldData.PanelOrdinate.ordinate;
3346            case 'civdata...'%reinitiate input, return to automatic civ data reading
3347                display_file_name(handles,FileName,1)
3348        end
3349        if ~strcmp(GetFieldData.FieldOption,'civdata...')
3350            XName=GetFieldData.Coordinates.Coord_x;
3351            TimeNameStr=GetFieldData.Time.SwitchVarIndexTime;
3352            switch TimeNameStr
3353                case 'file index'
3354                    set(handles.TimeName_1,'String','');
3355                case 'attribute'
3356                    set(handles.TimeName_1,'String',['att:' GetFieldData.Time.TimeName]);
3357                case 'variable'
3358                    set(handles.TimeName_1,'String',['var:' GetFieldData.Time.TimeName])
3359                    set(handles.NomType_1,'String','*')
3360                    set(handles.RootFile_1,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
3361                    set(handles.FileIndex_1,'String','')
3362                    ParamIn.TimeVarName=GetFieldData.Time.TimeName;
3363                case 'matrix_index'
3364                    set(handles.TimeName_1,'String',['dim:' GetFieldData.Time.TimeName]);
3365                    set(handles.NomType_1,'String','*')
3366                    set(handles.RootFile_1,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
3367                    set(handles.FileIndex_1,'String','')
3368                    ParamIn.TimeDimName_1=GetFieldData.Time.TimeName;
3369            end
3370            set(handles.Coord_x,'String',XName)
3371%             if ischar(YName)
3372%                 YName={YName};
3373%             end
3374            set(handles.Coord_y,'String',YName)
3375            set(handles.FieldName_1,'Value',1)
3376            set(handles.FieldName_1,'String',[FieldList; {'get_field...'}]);
3377            set(handles.ColorScalar,'Value',1)
3378            set(handles.ColorScalar,'String',VecColorList);
3379            UvData.FileType{2}='netcdf';
3380            set(handles.uvmat,'UserData',UvData)
3381            REFRESH_Callback(hObject, eventdata, handles)
3382        end
3383         
3384%         set_veltype_display(0) % no veltype display
3385%         hget_field=findobj(allchild(0),'name','get_field_1');
3386%         if ~isempty(hget_field)
3387%             delete(hget_field)
3388%         end
3389%         hget_field=get_field(FileName_1);
3390%         set(hget_field,'name','get_field_1')
3391%         hhget_field=guidata(hget_field);
3392%         set(hhget_field.list_fig,'Value',1)
3393%         set(hhget_field.list_fig,'String',{'uvmat'})
3394%         if check_new
3395%             UvData.FileType{2}=UvData.FileType{1};
3396%             set(handles.FileIndex_1,'String',get(handles.FileIndex,'String'))
3397%               set(handles.uvmat,'UserData',UvData)
3398%         end
3399    case 'image'
3400        %% look for image corresponding to civ data
3401        imagename='';
3402        if  isfield(UvData.Field,'Civ2_ImageA')%get the corresponding input image in the netcdf file
3403            imagename=UvData.Field.Civ2_ImageA;
3404        elseif isfield(UvData.Field,'Civ1_ImageA')%
3405            imagename=UvData.Field.Civ1_ImageA;
3406        else
3407            SubDirBase=regexprep(SubDir,'\..*','');%take the root part of SubDir, before the first dot '.'
3408            imagename=fullfile_uvmat(RootPath,SubDirBase,RootFile,'.png',NomType,i1,[],j1,[]);
3409        end
3410        if ~exist(imagename,'file')
3411            imagename=uigetfile_uvmat('Pick an image file',imagename,'image');
3412           
3413        end
3414        if isempty(imagename)
3415            set(handles.SubField,'Value',0)
3416            return
3417        else
3418            display_file_name(handles,imagename,2)%display the image as second field
3419        end
3420    otherwise
3421        check_refresh=1;
3422        if check_new% if a second field was not previously entered, we just read another field in the first input file
3423            set(handles.FileIndex_1,'String',get(handles.FileIndex,'String'))
3424            set(handles.FileExt_1,'String',get(handles.FileExt,'String'))
3425           
3426            UvData.FileType{2}=UvData.FileType{1};
3427            UvData.XmlData{2}= UvData.XmlData{1};
3428            transform=get(handles.TransformPath,'UserData');
3429             if (~isa(transform,'function_handle')||nargin(transform)<3)
3430                set(handles.uvmat,'UserData',UvData)
3431                set(handles.TransformName,'value',2); % set transform fct to 'sub_field' if the current fct does not accept two input fields
3432                TransformName_Callback(hObject, eventdata, handles)% activate transform_fct_Callback and refresh current plot
3433                 check_refresh=0;
3434             end             
3435        end
3436        if ~isequal(field,'image')
3437            set(handles.TitleNpxy,'Visible','off')% visible npx,pxcm... buttons
3438            set(handles.num_Npx,'Visible','off')
3439            set(handles.num_Npy,'Visible','off')
3440        end
3441        set(handles.uvmat,'UserData',UvData)
3442 
3443        if check_refresh && ~(isfield(UvData,'NewSeries')&&isequal(UvData.NewSeries,1))
3444            REFRESH_Callback(hObject, eventdata, handles)
3445        end
3446end
3447
3448%------------------------------------------------------------------------
3449% --- set the visibility of relevant velocity type menus:
3450function menu=set_veltype_display(Civ,FileType)
3451%------------------------------------------------------------------------
3452if ~exist('FileType','var')
3453    FileType='civx';
3454end
3455switch FileType
3456    case 'civx'
3457        menu={'civ1';'interp1';'filter1';'civ2';'interp2';'filter2'};
3458        if isequal(Civ,0)
3459            imax=0;
3460        elseif isequal(Civ,1) || isequal(Civ,2)
3461            imax=1;
3462        elseif isequal(Civ,3)
3463            imax=3;
3464        elseif isequal(Civ,4) || isequal(Civ,5)
3465            imax=4;
3466        elseif isequal(Civ,6) %patch2
3467            imax=6;
3468        end
3469    case 'civdata'
3470        menu={'civ1';'filter1';'civ2';'filter2'};
3471        if isequal(Civ,0)
3472            imax=0;
3473        elseif isequal(Civ,1) || isequal(Civ,2)
3474            imax=1;
3475        elseif isequal(Civ,3)
3476            imax=2;
3477        elseif isequal(Civ,4) || isequal(Civ,5)
3478            imax=3;
3479        elseif isequal(Civ,6) %patch2
3480            imax=4;
3481        end
3482end
3483menu=menu(1:imax);
3484
3485%------------------------------------------------------------------------
3486% --- Executes on button press in FixVelType.
3487function FixVelType_Callback(hObject, eventdata, handles)
3488%------------------------------------------------------------------------
3489% inputfilerefresh the current plot if the fixed  veltype is unselected
3490if ~get(handles.FixVelType,'Value')
3491    REFRESH_Callback(hObject, eventdata, handles)
3492end
3493
3494%------------------------------------------------------------------------
3495% --- Executes on button press in VelType.
3496function VelType_Callback(hObject, eventdata, handles)
3497%------------------------------------------------------------------------
3498set(handles.FixVelType,'Value',1)
3499REFRESH_Callback(hObject, eventdata, handles)
3500
3501%------------------------------------------------------------------------
3502% --- Executes on choice selection in VelType_1.
3503function VelType_1_Callback(hObject, eventdata, handles)
3504%------------------------------------------------------------------------
3505set(handles.FixVelType,'Value',1)% the velocity type is now imposed by the GUI (not automatic)
3506UvData=get(handles.uvmat,'UserData');
3507set(handles.InputFileREFRESH,'BackgroundColor',[1 1 0])%paint REFRESH button in yellow to indicate its activation
3508drawnow   
3509InputFile=read_GUI(handles.InputFile);% read the input file parameters
3510[RootPath,SubDir,RootFile,FileIndex,FileExt]=read_file_boxes(handles);
3511[RootPath_1,SubDir_1,RootFile_1,FileIndex_1,FileExt_1]=read_file_boxes_1(handles);
3512FileName=[fullfile(RootPath,SubDir,RootFile) FileIndex FileExt];% name of the first input file
3513
3514check_refresh=0;
3515if isempty(InputFile.VelType_1)
3516        FileName_1='';% we plot the first input field without the second field
3517        set(handles.SubField,'Value',0)
3518        SubField_Callback(hObject, eventdata, handles)% activate SubField_Callback and refresh current plot, removing the second field
3519elseif get(handles.SubField,'Value')% if subfield is already 'on'
3520     FileName_1=[fullfile(RootPath_1,SubDir_1,RootFile_1) FileIndex_1 FileExt_1];% name of the second input file
3521     check_refresh=1;%will refresh the current plot
3522else% we introduce the same file (with a different field) for the second series
3523     FileName_1=FileName;% we compare two fields in the same file
3524     UvData.FileType{2}=UvData.FileType{1};
3525     UvData.XmlData{2}= UvData.XmlData{1};
3526     set(handles.SubField,'Value',1)
3527     transform=get(handles.TransformPath,'UserData');
3528     if (~isa(transform,'function_handle')||nargin(transform)<3)
3529        set(handles.uvmat,'UserData',UvData)
3530        set(handles.TransformName,'value',2); % set transform fct to 'sub_field' if the current fct does not accept two input fields
3531        TransformName_Callback(hObject, eventdata, handles)% activate transform_fct_Callback and refresh current plot
3532     else
3533         check_refresh=1;
3534     end 
3535end
3536
3537% inputfilerefresh the current plot if it has not been done previously
3538if check_refresh
3539    UvData.FileName_1='';% desactivate the use of a constant second file
3540    set(handles.uvmat,'UserData',UvData)
3541    num_i1=stra2num(get(handles.i1,'String'));
3542    num_i2=stra2num(get(handles.i2,'String'));
3543    num_j1=stra2num(get(handles.j1,'String'));
3544    num_j2=stra2num(get(handles.j2,'String'));
3545    [tild,tild,tild,i1_1,i2_1,j1_1,j2_1]=fileparts_uvmat(['xx' FileIndex_1]);
3546    errormsg=refresh_field(handles,FileName,FileName_1,num_i1,num_i2,num_j1,num_j2,i1_1,i2_1,j1_1,j2_1);
3547    if ~isempty(errormsg)
3548        msgbox_uvmat('ERROR',errormsg);
3549    else
3550        set(handles.i1,'BackgroundColor',[1 1 1])
3551        set(handles.i2,'BackgroundColor',[1 1 1])
3552        set(handles.j1,'BackgroundColor',[1 1 1])
3553        set(handles.j2,'BackgroundColor',[1 1 1])
3554        set(handles.FileIndex,'BackgroundColor',[1 1 1])
3555        set(handles.FileIndex_1,'BackgroundColor',[1 1 1])
3556    end
3557    set(handles.InputFileREFRESH,'BackgroundColor',[1 0 0])
3558end
3559
3560
3561%------------------------------------------------------------------------
3562% --- reset civ buttons
3563function reset_vel_type(handles_civ0,handle1)
3564%------------------------------------------------------------------------
3565for ibutton=1:length(handles_civ0)
3566    set(handles_civ0(ibutton),'BackgroundColor',[0.831 0.816 0.784])
3567    set(handles_civ0(ibutton),'Value',0)
3568end
3569if exist('handle1','var')%handles of selected button
3570        set(handle1,'BackgroundColor',[1 1 0]) 
3571end
3572
3573%-----------------------------------------------------------------------
3574% --- Executes on button press in MENUVOLUME.
3575function VOLUME_Callback(hObject, eventdata, handles)
3576%-----------------------------------------------------------------------
3577%errordlg('command VOL not implemented yet')
3578if ishandle(handles.UVMAT_title)
3579    delete(handles.UVMAT_title)
3580end
3581UvData=get(handles.uvmat,'UserData');%read UvData properties stored on the uvmat interface
3582if isequal(get(handles.VOLUME,'Value'),1)
3583    set(handles.CheckZoom,'Value',0)
3584%     set(handles.CheckZoom,'BackgroundColor',[0.7 0.7 0.7])
3585    set(handles.edit_vect,'Value',0)
3586    edit_vect_Callback(hObject, eventdata, handles)
3587    set(handles.CheckEditObject,'Value',0)
3588%     set(handles.CheckEditObject,'BackgroundColor',[0.7 0.7 0.7])
3589%     set(handles.cal,'Value',0)
3590%     set(handles.cal,'BackgroundColor',[0 1 0])
3591    set(handles.edit_vect,'Value',0)
3592    edit_vect_Callback(hObject, eventdata, handles)
3593    %initiate set_object GUI
3594    data.Name='VOLUME';
3595    if isfield(UvData,'CoordType')
3596        data.CoordType=UvData.CoordType;
3597    end
3598    if isfield(UvData.Field,'CoordMesh')&~isempty(UvData.Field.CoordMesh)
3599        data.RangeX=[UvData.Field.XMin UvData.Field.XMax];
3600        data.RangeY=[UvData.Field.YMin UvData.Field.YMax];
3601        data.DX=UvData.Field.CoordMesh;
3602        data.DY=UvData.Field.CoordMesh;
3603    elseif isfield(UvData.Field,'AX')&isfield(UvData.Field,'AY')& isfield(UvData.Field,'A')%only image
3604        np=size(UvData.Field.A);
3605        meshx=(UvData.Field.AX(end)-UvData.Field.AX(1))/np(2);
3606        meshy=abs(UvData.Field.AY(end)-UvData.Field.AY(1))/np(1);
3607        data.RangeY=max(meshx,meshy);
3608        data.RangeX=max(meshx,meshy);
3609        data.DX=max(meshx,meshy);
3610    end
3611    data.ParentButton=handles.VOLUME;
3612    PlotHandles=get_plot_handles(handles);%get the handles of the interface elements setting the plotting parameters
3613    [hset_object,UvData.sethandles]=set_object(data,PlotHandles);% call the set_object interface with action on haxes,
3614                                                      % associate the set_object interface handle to the plotting axes
3615    set(hset_object,'name','set_object')
3616    UvData.MouseAction='create_object';
3617else
3618    set(handles.VOLUME,'BackgroundColor',[0 1 0])
3619end
3620set(handles.uvmat,'UserData',UvData)
3621
3622%-------------------------------------------------------
3623function edit_vect_Callback(hObject, eventdata, handles)
3624%-------------------------------------------------------
3625%
3626if isequal(get(handles.edit_vect,'Value'),1)
3627    VelTypeMenu=get(handles.VelType,'String');
3628    VelType=VelTypeMenu{get(handles.VelType,'Value')};
3629    if ~strcmp(VelType,'civ2') && ~strcmp(VelType,'civ1')
3630        msgbox_uvmat('ERROR','manual correction only possible for CIV1 or CIV2 velocity fields')
3631    end
3632    set(handles.record,'Visible','on')
3633    set(handles.edit_vect,'BackgroundColor',[1 1 0])
3634    set(handles.CheckEditObject,'Value',0)
3635    set(handles.CheckZoom,'Value',0)
3636    set(gcf,'Pointer','arrow')
3637else
3638    set(handles.record,'Visible','off')
3639    set(handles.edit_vect,'BackgroundColor',[0.7 0.7 0.7])
3640end
3641
3642%----------------------------------------------
3643function save_mask_Callback(hObject, eventdata, handles)
3644%-----------------------------------------------------------------------
3645UvData=get(handles.uvmat,'UserData');
3646
3647flag=1;
3648npx=size(UvData.Field.A,2);
3649npy=size(UvData.Field.A,1);
3650xi=0.5:npx-0.5;
3651yi=0.5:npy-0.5;
3652[Xi,Yi]=meshgrid(xi,yi);
3653if isfield(UvData,'ProjObject')
3654    for iobj=1:length(UvData.ProjObject)
3655        ObjectData=UvData.ProjObject{iobj};
3656        if isfield(ObjectData,'ProjMode') &&(isequal(ObjectData.ProjMode,'mask_inside')||isequal(ObjectData.ProjMode,'mask_outside'));
3657            flagobj=1;
3658            testphys=0; %coordinates in pixels by default
3659            if isfield(ObjectData,'CoordType') && isequal(ObjectData.CoordType,'phys')
3660                if isfield(UvData,'XmlData')&& isfield(UvData.XmlData{1},'GeometryCalib')
3661                    Calib=UvData.XmlData{1}.GeometryCalib;
3662                    testphys=1;
3663                end
3664            end
3665            if isfield(ObjectData,'Coord')& isfield(ObjectData,'Style')
3666                if isequal(ObjectData.Type,'polygon')
3667                    X=ObjectData.Coord(:,1);
3668                    Y=ObjectData.Coord(:,2);
3669                    if testphys
3670                        [X,Y]=px_XYZ(Calib,X,Y,0);% to generalise with 3D cases
3671                    end
3672                    flagobj=~inpolygon(Xi,Yi,X',Y');%=0 inside the polygon, 1 outside                 
3673                elseif isequal(ObjectData.Type,'ellipse')
3674                    if testphys
3675                        %[X,Y]=px_XYZ(Calib,X,Y,0);% TODO:create a polygon boundary and transform to phys
3676                    end
3677                    RangeX=max(ObjectData.RangeX);
3678                    RangeY=max(ObjectData.RangeY);
3679                    X2Max=RangeX*RangeX;
3680                    Y2Max=RangeY*RangeY;
3681                    distX=(Xi-ObjectData.Coord(1,1));
3682                    distY=(Yi-ObjectData.Coord(1,2));
3683                    flagobj=(distX.*distX/X2Max+distY.*distY/Y2Max)>1;
3684                elseif isequal(ObjectData.Type,'rectangle')
3685                    if testphys
3686                        %[X,Y]=px_XYZ(Calib,X,Y,0);% TODO:create a polygon boundary and transform to phys
3687                    end
3688                    distX=abs(Xi-ObjectData.Coord(1,1));
3689                    distY=abs(Yi-ObjectData.Coord(1,2));
3690                    flagobj=distX>max(ObjectData.RangeX) | distY>max(ObjectData.RangeY);
3691                end
3692                if isequal(ObjectData.ProjMode,'mask_outside')
3693                    flagobj=~flagobj;
3694                end
3695                flag=flag & flagobj;
3696            end
3697        end
3698    end
3699end
3700% flag=~flag;
3701%mask name
3702RootPath=get(handles.RootPath,'String');
3703RootFile=get(handles.RootFile,'String');
3704RootFile=regexprep(RootFile,'\<[\\/]|[\\/]\>','');%suppress possible / or \ separator at the beginning or the end of the string
3705filebase=fullfile(RootPath,RootFile);
3706list=get(handles.masklevel,'String');
3707masknumber=num2str(length(list));
3708maskindex=get(handles.masklevel,'Value');
3709mask_name=fullfile_uvmat(RootPath,SubDir,[RootFile '_' masknumber 'mask'],'.png','_1',maskindex);
3710%mask_name=name_generator([filebase '_' masknumber 'mask'],maskindex,1,'.png','_i');
3711imflag=uint8(255*(0.392+0.608*flag));% =100 for flag=0 (vectors not computed when 20<imflag<200)
3712imflag=flipdim(imflag,1);
3713% imflag=uint8(255*flag);% =0 for flag=0 (vectors=0 when 20<imflag<200)
3714msgbox_uvmat('CONFIRMATION',[mask_name ' saved'])
3715imwrite(imflag,mask_name,'BitDepth',8);
3716
3717%display the mask
3718figure;
3719vec=linspace(0,1,256);%define a linear greyscale colormap
3720map=[vec' vec' vec'];
3721colormap(map)
3722
3723image(imflag);
3724
3725%------------------------------------------------------------------------
3726%------------------------------------------------------------------------
3727%  - FUNCTIONS FOR SETTING PLOTTING PARAMETERS
3728
3729%------------------------------------------------------------------------
3730%------------------------------------------------------------------------
3731% --- Executes on selection change in TransformName.
3732
3733function TransformName_Callback(hObject, eventdata, handles)
3734%------------------------------------------------------------------------
3735set(handles.TransformName,'backgroundColor',[1 1 0])% indicate activation  of the menu
3736drawnow
3737UvData=get(handles.uvmat,'UserData');
3738menu=get(handles.TransformName,'String');%refresh
3739ichoice=get(handles.TransformName,'Value');%item number in the menu
3740transform_name=menu{ichoice};% choice of the transform fct
3741list_path=get(handles.TransformName,'UserData');
3742
3743%% handles  visibility of the path to the transform function
3744if isempty(transform_name)
3745    set(handles.TransformPath,'Visible','off')
3746else
3747    set(handles.TransformPath,'Visible','on')
3748end
3749
3750%% add a new item to the menu if the option 'more...' has been selected
3751prev_path=fullfile(get(handles.TransformPath,'String'));
3752if ~exist(prev_path,'dir')
3753    prev_path=fullfile(fileparts(which('uvmat')),'transform_field');
3754end
3755if strcmp(transform_name,'more...');
3756    transform_fct_chosen=uigetfile_uvmat('Pick the transform function',prev_path,'.m');
3757    if ~isempty(transform_fct_chosen)
3758        [PathName,transform_name]=fileparts(transform_fct_chosen);
3759        ichoice=find(strcmp(transform_name,menu),1);%look for the selected fct in the existing menu
3760        if isempty(ichoice)% if the item is not found, add it to the menu (before 'more...' and select it)
3761            menu=[menu(1:end-1);{transform_name};{'more...'}];
3762            ichoice=numel(menu)-1;
3763        end
3764        list_path{ichoice}=PathName;%update the list fo fct paths
3765        set(handles.TransformName,'String',menu)
3766        set(handles.TransformName,'Value',ichoice)
3767       
3768        % save the new menu in the personal file 'uvmat_perso.mat'
3769        dir_perso=prefdir;%personal Matalb directory
3770        profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
3771        if exist(profil_perso,'file')
3772            nb_builtin=UvData.OpenParam.NbBuiltin;% number of 'builtin' (basic) transform fcts in uvmat
3773            if nb_builtin<numel(list_path)
3774                for ilist=nb_builtin+1:numel(list_path)
3775                    transform_fct{ilist-nb_builtin}=[fullfile(list_path{ilist},menu{ilist}) '.m'];
3776                end
3777                save (profil_perso,'transform_fct','-append'); %store the root name for future opening of uvmat
3778            end
3779        end
3780    end
3781end
3782
3783%% create the function handle of the selected fct
3784if isempty(list_path{ichoice})% case of no selected fct
3785    transform_handle=[];
3786else
3787    if ~exist(list_path{ichoice},'dir')
3788        msgbox_uvmat('ERROR','invalid fct path: select the transform fct again with the option more...')
3789        return
3790    end
3791    current_dir=pwd;%current working dir
3792    cd(list_path{ichoice})
3793    transform_handle=str2func(transform_name);
3794    cd(current_dir)
3795end
3796set(handles.TransformPath,'String',list_path{ichoice})
3797set(handles.TransformPath,'UserData',transform_handle)
3798set(handles.TransformName,'UserData',list_path)
3799
3800%% update the ToolTip string of the menu TransformName with the first line of the selected fct file
3801if isempty(list_path{ichoice})% case of no selected fct
3802    set(handles.TransformName,'ToolTipString','transform_fct:choose a transform function')
3803else
3804    try
3805        [fid,errormsg] =fopen([fullfile(list_path{ichoice},transform_name) '.m']);
3806        InputText=textscan(fid,'%s',1,'delimiter','\n');
3807        fclose(fid);
3808        set(handles.TransformName,'ToolTipString',['transform_fct: ' InputText{1}{1}])% put the first line of the selected function as tooltip help
3809    end
3810end
3811
3812%% adapt the GUI to the input/output conditions of the selected transform fct
3813CoordUnit='';
3814CoordUnitPrev='';
3815if isfield(UvData,'Field')&&isfield(UvData.Field,'CoordUnit')
3816    CoordUnitPrev=UvData.Field.CoordUnit;
3817end
3818if ~isempty(list_path{ichoice})
3819    if nargin(transform_handle)>1 && isfield(UvData,'XmlData')&&~isempty(UvData.XmlData)
3820        DataOut=feval(transform_handle,'*',UvData.XmlData{1});% execute the transform fct to get the required conditions
3821        if isfield(DataOut,'CoordUnit')% set the requested coord unit (info used to possibly delete the current projection objects)
3822            CoordUnit=DataOut.CoordUnit;
3823        end
3824        if isfield(DataOut,'InputFieldType')% to be used to impose a type of input file (eg. for image transform)
3825            UvData.InputFieldType=DataOut.InputFieldType;
3826        end
3827        if isfield(DataOut,'TransformInput')%  used to add transform parameters at selection of the transform fct
3828            UvData.XmlData{1}.TransformInput=DataOut.TransformInput;
3829        end
3830    end
3831end
3832
3833%% delete drawn objects if the output CooordUnit is different from the previous one
3834if  ~strcmp(CoordUnit,CoordUnitPrev)
3835    set(handles.CheckFixLimits,'Value',0)
3836    hother=findobj('Tag','proj_object');%find all the proj objects
3837    for iobj=1:length(hother)
3838        delete_object(hother(iobj))
3839    end
3840    hother=findobj('Tag','DeformPoint');%find all the proj objects
3841    for iobj=1:length(hother)
3842        delete_object(hother(iobj))
3843    end
3844    hh=findobj('Tag','calib_points');
3845    if ~isempty(hh)
3846        delete(hh)
3847    end
3848    hhh=findobj('Tag','calib_marker');
3849    if ~isempty(hhh)
3850        delete(hhh)
3851    end
3852    set(handles.ListObject,'Value',1)
3853    set(handles.ListObject,'String',{''})
3854    set(handles.ListObject_1,'Value',1)
3855    set(handles.ListObject_1,'String',{''})
3856    set(handles.CheckViewObject,'value',0)
3857    CheckViewObject_Callback(hObject, eventdata, handles)
3858    set(handles.CheckViewField,'value',0)
3859    CheckViewField_Callback(hObject, eventdata, handles)
3860    set(handles.CheckEditObject,'Value',0)
3861    CheckEditObject_Callback(hObject, eventdata, handles)
3862    UvData.ProjObject={[]};
3863end
3864set(handles.uvmat,'UserData',UvData)
3865set(handles.TransformName,'backgroundColor',[1 1 1])% indicate desactivation  of the menu
3866drawnow
3867
3868%% inputfilerefresh the current plot
3869if isempty(list_path{ichoice}) || nargin(transform_handle)<3
3870    set(handles.SubField,'Value',0)
3871    SubField_Callback(hObject, eventdata, handles)
3872else
3873    REFRESH_Callback(hObject, eventdata, handles)
3874end
3875
3876%------------------------------------------------
3877%CALLBACKS FOR PLOTTING PARAMETERS
3878%-------------------------------------------------
3879%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3880% Plot axes
3881%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3882%------------------------------------------------------------------------
3883function num_MinX_Callback(hObject, eventdata, handles)
3884%------------------------------------------------------------------------
3885set(handles.CheckFixLimits,'Value',1) %suppress auto mode
3886% set(handles.CheckFixLimits,'BackgroundColor',[1 1 0])
3887update_plot(handles);
3888
3889%------------------------------------------------------------------------
3890function num_MaxX_Callback(hObject, eventdata, handles)
3891%------------------------------------------------------------------------
3892set(handles.CheckFixLimits,'Value',1) %suppress auto mode
3893% set(handles.CheckFixLimits,'BackgroundColor',[1 1 0])
3894update_plot(handles);
3895
3896%------------------------------------------------------------------------
3897function num_MinY_Callback(hObject, eventdata, handles)
3898%------------------------------------------
3899set(handles.CheckFixLimits,'Value',1) %suppress auto mode
3900% set(handles.CheckFixLimits,'BackgroundColor',[1 1 0])
3901update_plot(handles);
3902
3903%------------------------------------------------------------------------
3904function num_MaxY_Callback(hObject, eventdata, handles)
3905%------------------------------------------------------------------------
3906set(handles.CheckFixLimits,'Value',1) %suppress auto mode
3907% set(handles.CheckFixLimits,'BackgroundColor',[1 1 0])
3908update_plot(handles);
3909
3910%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3911% Scalar or image representation
3912%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3913%------------------------------------------------------------------------
3914function num_MinA_Callback(hObject, eventdata, handles)
3915%------------------------------------------
3916set(handles.CheckFixScalar,'Value',1) %suppress auto mode
3917% set(handles.CheckFixScalar,'BackgroundColor',[1 1 0])
3918MinA=str2double(get(handles.num_MinA,'String'));
3919MaxA=str2double(get(handles.num_MaxA,'String'));
3920if MinA>MaxA% switch minA and maxA in case of error
3921    MinA_old=MinA;
3922    MinA=MaxA;
3923    MaxA=MinA_old;
3924    set(handles.num_MinA,'String',num2str(MinA,5));
3925    set(handles.num_MaxA,'String',num2str(MaxA,5));
3926end
3927update_plot(handles);
3928
3929%------------------------------------------------------------------------
3930function num_MaxA_Callback(hObject, eventdata, handles)
3931%------------------------------------------------------------------------
3932set(handles.CheckFixScalar,'Value',1) %suppress auto mode
3933% set(handles.CheckFixScalar,'BackgroundColor',[1 1 0])
3934MinA=str2double(get(handles.num_MinA,'String'));
3935MaxA=str2double(get(handles.num_MaxA,'String'));
3936if MinA>MaxA% switch minA and maxA in case of error
3937        MinA_old=MinA;
3938    MinA=MaxA;
3939    MaxA=MinA_old;
3940    set(handles.num_MinA,'String',num2str(MinA,5));
3941    set(handles.num_MaxA,'String',num2str(MaxA,5));
3942end
3943update_plot(handles);
3944
3945%------------------------------------------------------------------------
3946function CheckFixScalar_Callback(hObject, eventdata, handles)
3947%------------------------------------------------------------------------
3948test=get(handles.CheckFixScalar,'Value');
3949if test
3950%     set(handles.CheckFixScalar,'BackgroundColor',[1 1 0])
3951else
3952%     set(handles.CheckFixScalar,'BackgroundColor',[0.7 0.7 0.7])
3953    update_plot(handles);
3954end
3955
3956%-------------------------------------------------------------------
3957function CheckBW_Callback(hObject, eventdata, handles)
3958%-------------------------------------------------------------------
3959update_plot(handles);
3960
3961%-------------------------------------------------------------------
3962function num_Opacity_Callback(hObject, eventdata, handles)
3963update_plot(handles);
3964%-------------------------------------------------------------------
3965
3966%-------------------------------------------------------------------
3967function ListContour_Callback(hObject, eventdata, handles)
3968%-------------------------------------------------------------------
3969val=get(handles.ListContour,'Value');
3970if val==2% option 'contours'
3971    set(handles.interval_txt,'Visible','on')
3972    set(handles.num_IncrA,'Visible','on')
3973    set(handles.num_IncrA,'String','')% refresh contour interval
3974%     set(handles.opacity_txt,'Visible','off')
3975%     set(handles.num_Opacity,'Visible','off')
3976else % option 'image'
3977    set(handles.interval_txt,'Visible','off')
3978    set(handles.num_IncrA,'Visible','off')
3979%     set(handles.opacity_txt,'Visible','on')
3980%     set(handles.num_Opacity,'Visible','on')
3981end
3982update_plot(handles);
3983
3984%-------------------------------------------------------------------
3985function num_IncrA_Callback(hObject, eventdata, handles)
3986%-------------------------------------------------------------------
3987update_plot(handles);
3988
3989
3990%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3991% Vector representation
3992%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3993%-------------------------------------------------------------------
3994function CheckHideWarning_Callback(hObject, eventdata, handles)
3995%-------------------------------------------------------------------
3996update_plot(handles);
3997
3998%-------------------------------------------------------------------
3999function CheckHideFalse_Callback(hObject, eventdata, handles)
4000%-------------------------------------------------------------------
4001update_plot(handles);
4002
4003%-------------------------------------------------------------------
4004function num_VecScale_Callback(hObject, eventdata, handles)
4005%-------------------------------------------------------------------
4006set(handles.CheckFixVectors,'Value',1);
4007set(handles.CheckFixVectors,'BackgroundColor',[1 1 0])
4008update_plot(handles);
4009
4010%-------------------------------------------------------------------
4011function CheckFixVectors_Callback(hObject, eventdata, handles)
4012%-------------------------------------------------------------------
4013if ~get(handles.CheckFixVectors,'Value')
4014    update_plot(handles);
4015end
4016
4017%------------------------------------------------------------------------
4018% --- Executes on selection change in CheckDecimate4 (nb_vec/4).
4019%------------------------------------------------------------------------
4020function CheckDecimate4_Callback(hObject, eventdata, handles)
4021
4022if isequal(get(handles.CheckDecimate4,'Value'),1)
4023    set(handles.CheckDecimate16,'Value',0)
4024end
4025update_plot(handles);
4026
4027%------------------------------------------------------------------------
4028% --- Executes on selection change in CheckDecimate16 (nb_vec/16).
4029%------------------------------------------------------------------------
4030function CheckDecimate16_Callback(hObject, eventdata, handles)
4031
4032if isequal(get(handles.CheckDecimate16,'Value'),1)
4033    set(handles.CheckDecimate4,'Value',0)
4034end
4035update_plot(handles);
4036
4037%------------------------------------------------------------------------
4038% --- Executes on selection change in ColorCode menu
4039function ColorCode_Callback(hObject, eventdata, handles)
4040%------------------------------------------------------------------------
4041% edit the choice for color code
4042update_color_code_boxes(handles);
4043update_plot(handles);
4044
4045%------------------------------------------------------------------------
4046function update_color_code_boxes(handles)
4047%------------------------------------------------------------------------
4048list_code=get(handles.ColorCode,'String');% list menu fields
4049colcode= list_code{get(handles.ColorCode,'Value')}; % selected field
4050enable_slider='off';%default
4051enable_bounds='off';%default
4052enable_scalar='off';%default
4053switch colcode
4054    case {'rgb','bgr'}
4055        enable_slider='on';
4056        enable_bounds='on';
4057        enable_scalar='on';
4058    case '64 colors'
4059        enable_bounds='on';
4060        enable_scalar='on';
4061end
4062set(handles.Slider1,'Visible',enable_slider)
4063set(handles.Slider2,'Visible', enable_slider)
4064set(handles.num_ColCode1,'Visible',enable_slider)
4065set(handles.num_ColCode2,'Visible',enable_slider)
4066set(handles.TitleColCode1,'Visible',enable_slider)
4067set(handles.TitleColCode2,'Visible',enable_slider)
4068set(handles.CheckFixVecColor,'Visible',enable_bounds)
4069set(handles.num_MinVec,'Visible',enable_bounds)
4070set(handles.num_MaxVec,'Visible',enable_bounds)
4071set(handles.ColorScalar,'Visible',enable_scalar)
4072set_vec_col_bar(handles)
4073
4074%------------------------------------------------------------------
4075% --- Executes on selection change in ColorScalar: choice of the color code.
4076function ColorScalar_Callback(hObject, eventdata, handles)
4077%------------------------------------------------------------------
4078% edit the choice for color code
4079list_scalar=get(handles.ColorScalar,'String');% list menu fields
4080col_scalar= list_scalar{get(handles.ColorScalar,'Value')}; % selected field
4081if isequal(col_scalar,'ima_cor')
4082    set(handles.CheckFixVecColor,'Value',1)%fixed scale by default
4083    ColorCode='rgb';
4084    set(handles.num_MinVec,'String','0')
4085    set(handles.num_MaxVec,'String','1')
4086    set(handles.num_ColCode1,'String','0.333')
4087    set(handles.num_ColCode2,'String','0.666')
4088else
4089    set(handles.CheckFixVecColor,'Value',0)%auto scale between min,max by default
4090    ColorCode='64 colors';
4091end
4092ColorCodeList=get(handles.ColorCode,'String');
4093ichoice=find(strcmp(ColorCode,ColorCodeList),1);
4094set(handles.ColorCode,'Value',ichoice)% set color code in the menu
4095
4096update_color_code_boxes(handles);
4097%replot the current graph
4098REFRESH_Callback(hObject, eventdata, handles)
4099
4100%----------------------------------------------------------------
4101% -- Executes on slider movement to set the color code
4102%
4103function Slider1_Callback(hObject, eventdata, handles)
4104%------------------------------------------------------------------
4105slider1=get(handles.Slider1,'Value');
4106min_val=str2num(get(handles.num_MinVec,'String'));
4107max_val=str2num(get(handles.num_MaxVec,'String'));
4108col=min_val+(max_val-min_val)*slider1;
4109set(handles.num_ColCode1,'String',num2str(col))
4110if(get(handles.Slider2,'Value') < col)%move also the second slider at the same value if needed
4111    set(handles.Slider2,'Value',col)
4112    set(handles.num_ColCode2,'String',num2str(col))
4113end
4114set_vec_col_bar(handles)
4115update_plot(handles);
4116
4117%----------------------------------------------------------------
4118% Executes on slider movement to set the color code
4119%----------------------------------------------------------------
4120function Slider2_Callback(hObject, eventdata, handles)
4121slider2=get(handles.Slider2,'Value');
4122min_val=str2num(get(handles.num_MinVec,'String'));
4123max_val=str2num(get(handles.num_MaxVec,'String'));
4124col=min_val+(max_val-min_val)*slider2;
4125set(handles.num_ColCode2,'String',num2str(col))
4126if(get(handles.Slider1,'Value') > col)%move also the first slider at the same value if needed
4127    set(handles.Slider1,'Value',col)
4128    set(handles.num_ColCode1,'String',num2str(col))
4129end
4130set_vec_col_bar(handles)
4131update_plot(handles);
4132
4133%----------------------------------------------------------------
4134% --- Execute on return carriage on the edit box corresponding to slider 1
4135%----------------------------------------------------------------
4136function num_ColCode1_Callback(hObject, eventdata, handles)
4137set_vec_col_bar(handles)
4138update_plot(handles);
4139
4140%----------------------------------------------------------------
4141% --- Execute on return carriage on the edit box corresponding to slider 2
4142%----------------------------------------------------------------
4143function num_ColCode2_Callback(hObject, eventdata, handles)
4144set_vec_col_bar(handles)
4145update_plot(handles);
4146%------------------------------------------------------------------------
4147%-------------------------------------------------------
4148% --- Executes on button press in CheckFixVecColor.
4149%-------------------------------------------------------
4150function VecColBar_Callback(hObject, eventdata, handles)
4151set_vec_col_bar(handles)
4152
4153%------------------------------------------------------------------------
4154% --- Executes on button press in CheckFixVecColor.
4155function CheckFixVecColor_Callback(hObject, eventdata, handles)
4156%------------------------------------------------------------------------
4157if ~get(handles.CheckFixVecColor,'Value')
4158    update_plot(handles);
4159end
4160
4161%------------------------------------------------------------------------
4162% --- Executes on selection change in num_MaxVec.
4163function num_MinVec_Callback(hObject, eventdata, handles)
4164%------------------------------------------------------------------------
4165num_MaxVec_Callback(hObject, eventdata, handles)
4166
4167%------------------------------------------------------------------------
4168% --- Executes on selection change in num_MaxVec.
4169function num_MaxVec_Callback(hObject, eventdata, handles)
4170%------------------------------------------------------------------------
4171set(handles.CheckFixVecColor,'Value',1)
4172CheckFixVecColor_Callback(hObject, eventdata, handles)
4173min_val=str2num(get(handles.num_MinVec,'String'));
4174max_val=str2num(get(handles.num_MaxVec,'String'));
4175slider1=get(handles.Slider1,'Value');
4176slider2=get(handles.Slider2,'Value');
4177colcode1=min_val+(max_val-min_val)*slider1;
4178colcode2=min_val+(max_val-min_val)*slider2;
4179set(handles.num_ColCode1,'String',num2str(colcode1))
4180set(handles.num_ColCode2,'String',num2str(colcode2))
4181update_plot(handles);
4182
4183%------------------------------------------------------------------------
4184% --- update the display of color code for vectors (on vecColBar)
4185function set_vec_col_bar(handles)
4186%------------------------------------------------------------------------
4187%get the image of the color display button 'VecColBar' in pixels
4188set(handles.VecColBar,'Unit','pixel');
4189pos_vert=get(handles.VecColBar,'Position');
4190set(handles.VecColBar,'Unit','Normalized');
4191width=ceil(pos_vert(3));
4192height=ceil(pos_vert(4));
4193
4194%get slider indications
4195list=get(handles.ColorCode,'String');
4196ichoice=get(handles.ColorCode,'Value');
4197colcode.ColorCode=list{ichoice};
4198colcode.MinVec=str2num(get(handles.num_MinVec,'String'));
4199colcode.MaxVec=str2num(get(handles.num_MaxVec,'String'));
4200test3color=strcmp(colcode.ColorCode,'rgb') || strcmp(colcode.ColorCode,'bgr');
4201if test3color
4202    colcode.ColCode1=str2num(get(handles.num_ColCode1,'String'));
4203    colcode.ColCode2=str2num(get(handles.num_ColCode2,'String'));
4204end
4205vec_C=colcode.MinVec+(colcode.MaxVec-colcode.MinVec)*(0.5:width-0.5)/width;%sample of vec_C values from min to max
4206[colorlist,col_vec]=set_col_vec(colcode,vec_C);
4207oneheight=ones(1,height);
4208A1=colorlist(col_vec,1)*oneheight;
4209A2=colorlist(col_vec,2)*oneheight;
4210A3=colorlist(col_vec,3)*oneheight;
4211A(:,:,1)=A1';
4212A(:,:,2)=A2';
4213A(:,:,3)=A3';
4214set(handles.VecColBar,'Cdata',A)
4215
4216%-------------------------------------------------------------------
4217function update_plot(handles)
4218%-------------------------------------------------------------------
4219set(handles.REFRESH,'BackgroundColor',[1 1 0]);% display plot activity by yellow color
4220drawnow
4221UvData=get(handles.uvmat,'UserData');
4222AxeData=UvData.PlotAxes;% retrieve the current plotted data
4223PlotParam=read_GUI(handles.uvmat);
4224[tild,PlotParamOut]= plot_field(AxeData,handles.PlotAxes,PlotParam);
4225errormsg=fill_GUI(PlotParamOut,handles.uvmat);
4226if ~isempty(errormsg)
4227    msgbox_uvmat('ERROR',errormsg)
4228    return
4229end
4230set(handles.REFRESH,'BackgroundColor',[1 0 0]);
4231
4232%------------------------------------------------------------------------
4233%------------------------------------------------------------------------
4234%   SELECTION AND EDITION OF PROJECTION OBJECTS
4235%------------------------------------------------------------------------
4236%------------------------------------------------------------------------
4237
4238% --- Executes on selection change in ListObject_1.
4239function ListObject_1_Callback(hObject, eventdata, handles)
4240list_str=get(handles.ListObject,'String');
4241UvData=get(handles.uvmat,'UserData');
4242ObjectData=UvData.ProjObject{get(handles.ListObject_1,'Value')};
4243
4244%% update the projection plot on uvmat
4245ProjData= proj_field(UvData.Field,ObjectData);%project the current input field on object ObjectData
4246plot_field(ProjData,handles.PlotAxes,read_GUI(handles.uvmat));% plot the projected field;
4247%replot all the objects within the new projected field
4248for IndexObj=1:numel(list_str)
4249        hobject=UvData.ProjObject{IndexObj}.DisplayHandle.uvmat;
4250        if isempty(hobject) || ~ishandle(hobject)
4251            hobject=handles.PlotAxes;
4252        end
4253        if isequal(IndexObj,get(handles.ListObject,'Value'))
4254            objectcolor='m'; %paint in magenta the currently selected object in ListObject
4255        else
4256            objectcolor='b';
4257        end
4258        UvData.ProjObject{IndexObj}.DisplayHandle.uvmat=plot_object(UvData.ProjObject{IndexObj},ObjectData,hobject,objectcolor);%draw the object in uvmat     
4259end
4260set(handles.uvmat,'UserData',UvData)
4261
4262%% display the object parameters if the GUI set_object is already opened
4263if ~get(handles.CheckViewObject,'Value')
4264    ZBounds=0; % default
4265    if isfield(UvData.Field,'ZMin') && isfield(UvData.Field,'ZMax')
4266        ZBounds(1)=UvData.Field.ZMin; %minimum for the Z slider
4267        ZBounds(2)=UvData.Field.ZMax;%maximum for the Z slider
4268    end
4269    ObjectData.Name=list_str{get(handles.ListObject_1,'Value')};
4270    hset_object=set_object(ObjectData,[],ZBounds);
4271    set(hset_object,'name','set_object')
4272    set(handles.CheckViewObject,'Value',1)% show that the selected object in ListObject_1 is currently visualised
4273end
4274
4275%  desactivate the edit object mode
4276set(handles.CheckEditObject,'Value',0)
4277% set(handles.CheckEditObject,'BackgroundColor',[0.7,0.7,0.7])
4278
4279%------------------------------------------------------------------------
4280% --- Executes on selection change in ListObject.
4281function ListObject_Callback(hObject, eventdata, handles)
4282%------------------------------------------------------------------------
4283list_str=get(handles.ListObject,'String');
4284IndexObj=get(handles.ListObject,'Value');%present object selection
4285UvData=get(handles.uvmat,'UserData');
4286if numel(UvData.ProjObject)<IndexObj
4287    return
4288end
4289ObjectData=UvData.ProjObject{IndexObj};
4290    ZBounds=0; % default
4291    if isfield(UvData.Field,'ZMin') && isfield(UvData.Field,'ZMax')
4292        ZBounds(1)=UvData.Field.ZMin; %minimum for the Z slider
4293        ZBounds(2)=UvData.Field.ZMax;%maximum for the Z slider
4294    end
4295
4296%% show object features if view_object isselected
4297if get(handles.CheckViewObject,'value')
4298    hset_object=set_object(ObjectData,[],ZBounds);
4299    set(hset_object,'name','set_object')
4300end
4301
4302%%  desactivate the edit object mode for security
4303set(handles.CheckEditObject,'Value',0)
4304
4305%% update the  plot on view_field if view_field is already openened
4306hview_field=findobj(allchild(0),'tag','view_field');
4307if isempty(hview_field)
4308    hhview_field.PlotAxes=[];
4309else
4310    Data=get(hview_field,'UserData');
4311    hhview_field=guidata(hview_field);
4312    ProjData= proj_field(UvData.Field,ObjectData);%project the current interface field on ObjectData
4313    [PlotType,PlotParam]=plot_field(ProjData,hhview_field.PlotAxes,read_GUI(hview_field));%read plotting parameters on the uvmat interface
4314    haxes=findobj(hview_field,'tag','axes3');
4315    pos=get(hview_field,'Position'); 
4316    if strcmp(get(haxes,'Visible'),'off')%sempty(PlotParam.Axes)% case of no plot display (pure text table)
4317        h_TableDisplay=findobj(hview_field,'tag','TableDisplay');
4318        pos_table=get(h_TableDisplay,'Position');
4319        set(hview_field,'Position',[pos(1)+pos(3)-pos_table(3) pos(2)+pos(4)-pos_table(4) pos_table(3) pos_table(4)])
4320        drawnow% needed to change position before the next command
4321        set(hview_field,'UserData',Data);% restore the previously stored GUI position after GUI resizing
4322    else
4323%         set(hview_field,'Position',Data.GUISize)% return to the previously stored GUI position and size
4324    end
4325end
4326
4327%% update the color of the graphic object representation: the selected object in magenta, others in blue
4328update_object_color(handles.PlotAxes,hhview_field.PlotAxes,UvData.ProjObject{IndexObj}.DisplayHandle.uvmat)
4329
4330%------------------------------------------------------------------------
4331%--- update the color representation of objects (indicating the selected ones)
4332function update_object_color(axes_uvmat,axes_view_field,DisplayHandle)
4333%------------------------------------------------------------------------
4334if isempty(axes_view_field)% case with no view_field plot
4335hother=[findobj(axes_uvmat,'Tag','proj_object');findobj(axes_uvmat,'Tag','DeformPoint')];%find all the proj object and deform point representations
4336else
4337hother=[findobj(axes_uvmat,'Tag','proj_object') ;findobj(axes_view_field,'Tag','proj_object');... %find all the proj object representations
4338findobj(axes_uvmat,'Tag','DeformPoint'); findobj(axes_view_field,'Tag','DeformPoint')];%find all the deform point representations
4339end
4340for iobj=1:length(hother)
4341    if isequal(get(hother(iobj),'Type'),'rectangle')||isequal(get(hother(iobj),'Type'),'patch')
4342        set(hother(iobj),'EdgeColor','b')
4343        if isequal(get(hother(iobj),'FaceColor'),'m')
4344            set(hother(iobj),'FaceColor','b')
4345        end
4346    elseif isequal(get(hother(iobj),'Type'),'image')
4347        Acolor=get(hother(iobj),'CData');
4348        Acolor(:,:,1)=zeros(size(Acolor,1),size(Acolor,2));
4349        set(hother(iobj),'CData',Acolor);
4350    else
4351        set(hother(iobj),'Color','b')
4352    end
4353    set(hother(iobj),'Selected','off')
4354end
4355if ishandle(DisplayHandle)
4356    linetype=get(DisplayHandle,'Type');
4357    if isequal(linetype,'line')
4358        set(DisplayHandle,'Color','m'); %set the selected object to magenta color
4359    elseif isequal(linetype,'rectangle')
4360        set(DisplayHandle,'EdgeColor','m'); %set the selected object to magenta color
4361    elseif isequal(linetype,'patch')
4362        set(DisplayHandle,'FaceColor','m'); %set the selected object to magenta color
4363    end
4364    SubObjectData=get(DisplayHandle,'UserData');
4365    if isfield(SubObjectData,'SubObject') & ishandle(SubObjectData.SubObject)
4366        for iobj=1:length(SubObjectData.SubObject)
4367            hsub=SubObjectData.SubObject(iobj);
4368            if isequal(get(hsub,'Type'),'rectangle')
4369                set(hsub,'EdgeColor','m'); %set the selected object to magenta color
4370            elseif isequal(get(hsub,'Type'),'image')
4371                Acolor=get(hsub,'CData');
4372                Acolor(:,:,1)=Acolor(:,:,3);
4373                set(hsub,'CData',Acolor);
4374            else
4375                set(hsub,'Color','m')
4376            end
4377        end
4378    end
4379    if isfield(SubObjectData,'DeformPoint') & ishandle(SubObjectData.DeformPoint)
4380        set(SubObjectData.DeformPoint,'Color','m')
4381    end
4382end
4383
4384%-------------------------------------------------------------------
4385% --- Executes on selection change in CheckEditObject.
4386function CheckEditObject_Callback(hObject, eventdata, handles)
4387%-------------------------------------------------------------------
4388hset_object=findobj(allchild(0),'Tag','set_object');
4389if get(handles.CheckEditObject,'Value')
4390    %suppress the other options
4391    set(handles.MenuObject,'checked','off')
4392    set(handles.CheckZoom,'Value',0)
4393    CheckZoom_Callback(hObject, eventdata, handles)
4394    hgeometry_calib=findobj(allchild(0),'tag','geometry_calib');
4395    if ishandle(hgeometry_calib)
4396        hhgeometry_calib=guidata(hgeometry_calib);
4397        set(hhgeometry_calib.CheckEnableMouse,'Value',0)% desactivate mouse action in geometry_calib
4398        set(hhgeometry_calib.CheckEnableMouse,'BackgroundColor',[0.7 0.7 0.7])
4399    end
4400    set(handles.CheckViewObject,'value',1)
4401    CheckViewObject_Callback(hObject, eventdata, handles)
4402else % desactivate object edit mode
4403    if ~isempty(hset_object)% open the
4404        set(get(hset_object,'children'),'Enable','off')
4405        hSAVE=findobj(hset_object,'Tag','SAVE');
4406        set(hSAVE,'Enable','on')
4407    end
4408end
4409
4410
4411%------------------------------------------------------------------------
4412% --- Executes on button press in CheckViewObject.
4413function CheckViewObject_Callback(hObject, eventdata, handles)
4414%------------------------------------------------------------------------
4415check_view=get(handles.CheckViewObject,'Value');
4416
4417if check_view %activate set_object   
4418    IndexObj=get(handles.ListObject,'Value');
4419    list_object=get(handles.ListObject,'String');
4420    UvData=get(handles.uvmat,'UserData');%read UvData properties stored on the uvmat interface
4421    UvData.ProjObject{IndexObj}.Name=list_object{IndexObj};
4422    if numel(UvData.ProjObject)<IndexObj;% error in UvData
4423        msgbox_uvmat('ERROR','invalid object list')
4424        return
4425    end
4426    ZBounds=0; % default
4427    if isfield(UvData.Field,'ZMin') && isfield(UvData.Field,'ZMax')
4428        ZBounds(1)=UvData.Field.ZMin; %minimum for the Z slider
4429        ZBounds(2)=UvData.Field.ZMax;%maximum for the Z slider
4430    end
4431    data=UvData.ProjObject{IndexObj};
4432    if ~isfield(data,'Type')% default plane
4433        data.Type='plane';
4434    end
4435    hset_object=set_object(data,[],ZBounds);
4436    set(hset_object,'name','set_object')
4437    hhset_object=guidata(hset_object);
4438    if get(handles.CheckEditObject,'Value')% edit mode
4439        set(get(hset_object,'children'),'Enable','on')
4440    else
4441        set(get(hset_object,'children'),'Enable','off')% deactivate the GUI except SAVE
4442        set(hhset_object.SAVE,'Enable','on')
4443    end
4444else
4445    hset_object=findobj(allchild(0),'tag','set_object');
4446    if ~isempty(hset_object)
4447        delete(hset_object)% delete existing version of set_object
4448    end
4449end
4450 
4451
4452%------------------------------------------------------------------------
4453% --- Executes on button press in CheckViewField.
4454function CheckViewField_Callback(hObject, eventdata, handles)
4455%------------------------------------------------------------------------
4456check_view=get(handles.CheckViewField,'Value');
4457
4458if check_view
4459    IndexObj=get(handles.ListObject,'Value');
4460    UvData=get(handles.uvmat,'UserData');%read UvData properties stored on the uvmat interface
4461    if numel(UvData.ProjObject)<IndexObj(end);% error in UvData
4462        msgbox_uvmat('ERROR','invalid object list')
4463        return
4464    end
4465    ZBounds=0; % default
4466    if isfield(UvData.Field,'ZMin') && isfield(UvData.Field,'ZMax')
4467        ZBounds(1)=UvData.Field.ZMin; %minimum for the Z slider
4468        ZBounds(2)=UvData.Field.ZMax;%maximum for the Z slider
4469    end
4470    set(handles.ListObject,'Value',IndexObj);%restore ListObject selection after set_object deletion
4471    if ~isfield(UvData.ProjObject{IndexObj(1)},'Type')% default plane
4472        UvData.ProjObject{IndexObj(1)}.Type='plane';
4473    end
4474    list_object=get(handles.ListObject,'String');
4475    UvData.ProjObject{IndexObj(end)}.Name=list_object{IndexObj(end)};
4476   
4477    %% show the projection of the selected object on view_field
4478    ProjData= proj_field(UvData.Field,UvData.ProjObject{IndexObj});%project the current field on ObjectData
4479    hview_field=findobj(allchild(0),'tag','view_field');
4480    if isempty(hview_field)
4481        hview_field=view_field;
4482    end
4483    hhview_field=guidata(hview_field);
4484    [PlotType,PlotParam]=plot_field(ProjData,hhview_field.PlotAxes,read_GUI(hview_field));%read plotting parameters on the GUI view_field);
4485    errormsg=fill_GUI(PlotParam,hview_field);
4486    for list={'Scalar','Vectors'}
4487        if ~isfield(PlotParam,list{1})
4488            set(hhview_field.(list{1}),'Visible','off')
4489        end
4490    end
4491    haxes=findobj(hview_field,'tag','axes3');
4492    pos=get(hview_field,'Position');
4493    if strcmp(get(haxes,'Visible'),'off')%sempty(PlotParam.Axes)% case of no plot display (pure text table)
4494        h_TableDisplay=findobj(hview_field,'tag','TableDisplay');
4495        pos_table=get(h_TableDisplay,'Position');
4496        set(hview_field,'Position',[pos(1)+pos(3)-pos_table(3) pos(2)+pos(4)-pos_table(4) pos_table(3) pos_table(4)])
4497    else
4498        Data=get(hview_field,'UserData');
4499    end
4500else
4501    hview_field=findobj(allchild(0),'tag','view_field');
4502    if ~isempty(hview_field)
4503        delete(hview_field)% delete existing version of set_object
4504    end
4505end
4506
4507
4508%------------------------------------------------------------------------
4509% --- Executes on button press in DeleteObject.
4510%------------------------------------------------------------------------
4511function DeleteObject_Callback(hObject, eventdata, handles)
4512
4513IndexObj=get(handles.ListObject,'Value');%projection object selected for view_field
4514IndexObj_1=get(handles.ListObject_1,'Value');%projection object selected for uvmat plot
4515if IndexObj>1 && ~isequal(IndexObj,IndexObj_1) % do not delete the object used for the uvmat plot
4516    delete_object(IndexObj)
4517end
4518
4519%'DeleteObject': delete a projection object, defined by its index in the Uvmat list or by its graphic handle
4520%------------------------------------------------------------------------
4521% function DeleteObject(hObject)
4522%
4523% INPUT:
4524% hObject: object index (if integer) or handle of the graphic object. If
4525%          hObject is a subobject, the parent object is detected and deleted.
4526
4527function delete_object(IndexObj)
4528
4529huvmat=findobj('tag','uvmat');%handles of the uvmat interface
4530UvData=get(huvmat,'UserData');
4531hlist_object=findobj(huvmat,'Tag','ListObject');%handles of the object list in the uvmat interface
4532list_str=get(hlist_object,'String');%objet list
4533if  ~isempty(UvData) && isfield(UvData, 'ProjObject') && length(UvData.ProjObject)>=IndexObj
4534    if isfield(UvData.ProjObject{IndexObj},'DisplayHandle') && isfield(UvData.ProjObject{IndexObj}.DisplayHandle,'uvmat')
4535        hdisplay=UvData.ProjObject{IndexObj}.DisplayHandle.uvmat;%handle of the object graphic representation in uvmat
4536        for iview=1:length(hdisplay)
4537            if ishandle(hdisplay(iview)) && ~isequal(hdisplay(iview),0)
4538                ObjectData=get(hdisplay(iview),'UserData');
4539                if isfield(ObjectData,'SubObject') && ~isempty(ObjectData.SubObject)
4540                    delete(ObjectData.SubObject(ishandle(ObjectData.SubObject)));% delete the graphic 'sub-objects (e.g. projection bounds)
4541                end
4542                if isfield(ObjectData,'DeformPoint')&& ~isempty(ObjectData.DeformPoint)
4543                    delete(ObjectData.DeformPoint(ishandle(ObjectData.DeformPoint)));% delete the graphic deformation points
4544                    delete(hdisplay(iview))% delete the main graphic representation of the object
4545                end
4546            end
4547            ishandle(hdisplay(iview))
4548        end
4549        for iobj=IndexObj+1:length(UvData.ProjObject)
4550            hdisplay=UvData.ProjObject{iobj}.DisplayHandle.uvmat;
4551            for iview=1:length(hdisplay)
4552                if ishandle(hdisplay(iview)) && ~isequal(hdisplay(iview),0)
4553                    PlotData=get(hdisplay(iview),'UserData');
4554                    PlotData.IndexObj=iobj-1;
4555                    set(hdisplay(iview),'UserData',PlotData);
4556                end
4557            end
4558        end
4559    end
4560    UvData.ProjObject(IndexObj)=[];
4561end
4562if numel(list_str)>=IndexObj
4563    list_str(IndexObj)=[];
4564end
4565set(huvmat,'UserData',UvData);
4566set(hlist_object,'String',list_str)
4567set(hlist_object,'Value',length(list_str))
4568hlist_object_1=findobj(huvmat,'Tag','ListObject_1');%handles of the first object list in the uvmat interface
4569old_index=get(hlist_object_1,'Value');
4570set(hlist_object_1,'String',list_str)
4571if IndexObj<=old_index
4572    set(hlist_object_1,'Value',old_index-1)
4573end
4574
4575%------------------------------------------------------------------------
4576%------------------------------------------------------------------------
4577%  II - TOOLS FROM THE UPPER MENU BAR
4578%------------------------------------------------------------------------
4579%------------------------------------------------------------------------
4580
4581%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4582% Export  Menu Callbacks
4583%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4584%------------------------------------------------------------------------
4585% --- Executes on button press in Menu/Export/field in workspace.
4586function MenuExportField_Callback(hObject, eventdata, handles)
4587%------------------------------------------------------------------------
4588global Data_uvmat
4589Data_uvmat=get(handles.uvmat,'UserData');
4590evalin('base','global Data_uvmat')%make CurData global in the workspace
4591display('current field :')
4592evalin('base','Data_uvmat') %display CurData in the workspace
4593commandwindow; %brings the Matlab command window to the front
4594
4595%------------------------------------------------------------------------
4596% --- Executes on button press in Menu/Export/extract figure.
4597function MenuExportFigure_Callback(hObject, eventdata, handles)
4598%------------------------------------------------------------------------
4599hfig=figure;
4600copyobj(handles.PlotAxes,hfig);
4601h=findobj(handles.PlotAxes,'tag','ima'); %look for image in the plot
4602if ~isempty(h)
4603    map=colormap(handles.PlotAxes);
4604    colormap(map);%transmit the current colormap to the zoom fig
4605    colorbar
4606end
4607
4608% --------------------------------------------------------------------
4609function MenuExportAxis_Callback(hObject, eventdata, handles)
4610ListFig=findobj(allchild(0),'Type','figure');
4611nb_option=0;
4612menu={};
4613for ilist=1:numel(ListFig)
4614    FigName=get(ListFig(ilist),'name');
4615    if isempty(FigName)
4616        FigName=['figure ' num2str(ListFig(ilist))];
4617    end
4618    if ~strcmp(FigName,'uvmat')
4619        ListAxes=findobj(ListFig(ilist),'Type','axes');
4620        ListTags=get(ListAxes,'Tag');
4621        if ~isempty(ListTags) && ~isempty(find(~strcmp('Colorbar',ListTags), 1))
4622            ListAxes=ListAxes(~strcmp('Colorbar',ListTags));
4623            if numel(ListAxes)==1
4624                nb_option=nb_option+1;
4625                menu{nb_option}=FigName ;
4626                AxesHandle(nb_option)=ListAxes;
4627            else
4628                nb_axis=0;
4629                for iaxes=1:numel(ListAxes)
4630                    nb_axis=nb_axis+1;
4631                    nb_option=nb_option+1;
4632                    menu{nb_option}=[FigName '_' num2str(nb_axis)];
4633                    AxesHandle(nb_option)=ListAxes(nb_axis);
4634                end
4635            end
4636        end
4637    end
4638end
4639if isempty(menu)
4640    answer=msgbox_uvmat('INPUT_Y-N','no existing plotting axes available, create new figure?');
4641    if strcmp(answer,'Yes')
4642        hfig=figure;
4643        copyobj(handles.PlotAxes,hfig);
4644    else
4645        return
4646    end
4647    map=colormap(handles.PlotAxes);
4648    colormap(map);%transmit the current colormap to the zoom fig
4649    colorbar
4650else
4651    answer=msgbox_uvmat('INPUT_MENU','select a figure/axis on which the current uvmat plot will be exported',menu);
4652    if isempty(answer)
4653        return
4654    else
4655        axes(AxesHandle(answer))
4656        hold on
4657        hchild=get(handles.PlotAxes,'children');
4658        copyobj(hchild,gca);
4659    end
4660end
4661
4662
4663%------------------------------------------------------------------------
4664% --------------------------------------------------------------------
4665function MenuExportMovie_Callback(hObject, eventdata, handles)
4666% --------------------------------------------------------------------
4667set(handles.MenuExportMovie,'BusyAction','queue')% activate the button
4668huvmat=get(handles.InputFileREFRESH,'parent');
4669UvData=get(huvmat,'UserData');
4670%[xx,xx,FileBase]=read_file_boxes(handles);
4671[RootPath,SubDir,RootFile,FileIndex,FileExt]=read_file_boxes(handles);
4672FileBase=fullfile(RootPath,RootFile);
4673 %read the current input file name
4674prompt = {'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)'};
4675dlg_title = 'select properties of the output avi movie';
4676num_lines= 1;
4677def     = {[FileBase '_out.avi'];'10';'1';'[0.03 0.05 0.95 0.92]';'10'};
4678answer = inputdlg(prompt,dlg_title,num_lines,def,'on');
4679aviname=answer{1};
4680fps=str2double(answer{2});
4681% check for existing file with output name aviname
4682if exist(aviname,'file')
4683    backup=aviname;
4684    testexist=2;
4685    while testexist==2
4686        backup=[backup '~'];
4687        testexist=exist(backup,'file');     
4688    end
4689    [success,message]=copyfile(aviname,backup);%make backup of the existing file
4690    if isequal(success,1)
4691        delete(aviname)%delete existing file
4692    else
4693        msgbox_uvmat('ERROR',message)
4694        return
4695    end
4696end
4697%create avi open
4698aviobj=avifile(aviname,'Compression','None','fps',fps);
4699
4700%display first view for tests
4701newfig=figure;
4702newaxes=copyobj(handles.PlotAxes,newfig);%new plotting axes in the new figure
4703set(newaxes,'Tag','movieaxes')
4704nbpix=[512 384]*str2double(answer{3});
4705set(gcf,'Position',[1 1 nbpix])% resolution XVGA
4706set(newaxes,'Position',eval(answer{4}));
4707map=colormap(handles.PlotAxes);
4708colormap(map);%transmit the current colormap to the zoom fig
4709msgbox_uvmat('INPUT_Y-N',{['adjust figure ' num2str(newfig) ' with its matlab edit menu '] ;...
4710        ['then press OK to get the avi movie as a copy of figure ' num2str(newfig) ' display']});
4711UvData.plotaxes=newaxes;% the axis in the new figure becomes the current main plotting axes
4712set(huvmat,'UserData',UvData);
4713increment=str2num(get(handles.num_IndexIncrement,'String')); %get the field increment d
4714set(handles.STOP,'Visible','on')
4715set(handles.speed,'Visible','on')
4716set(handles.speed_txt,'Visible','on')
4717set(handles.Movie,'BusyAction','queue')
4718
4719%imin=str2double(get(handles.i1,'String'));
4720imax=str2double(answer{5});
4721% if isfield(UvData,'Time')
4722htitle=get(newaxes,'Title');
4723xlim=get(newaxes,'XLim');
4724ylim=get(newaxes,'YLim');
4725set(htitle,'Position',[xlim(2)+0.07*(xlim(2)-xlim(1)) ylim(2)-0.05*(ylim(2)-ylim(1)) 0])
4726time_str=get(handles.TimeValue,'String');
4727set(htitle,'String',['t=' time_str])
4728set(handles.speed,'Value',1)
4729for i=1:imax
4730    if get(handles.speed,'Value')~=0 && isequal(get(handles.MenuExportMovie,'BusyAction'),'queue') % enable STOP command
4731            runpm(hObject,eventdata,handles,increment)% run plus
4732            drawnow
4733            time_str=get(handles.TimeValue,'String');
4734            if ishandle(htitle)
4735             set(htitle,'String',['t=' time_str])
4736            end
4737            mov=getframe(newfig);
4738            aviobj=addframe(aviobj,mov);
4739    end
4740end
4741aviobj=close(aviobj);
4742UvData=rmfield(UvData,'plotaxes');
4743set(huvmat,'UserData',UvData);
4744msgbox_uvmat('CONFIRMATION',{['movie ' aviname ' created '];['with ' num2str(imax) ' frames']})
4745
4746
4747%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4748% Projection Objects Menu Callbacks
4749%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4750
4751% -----------------------------------------------------------------------
4752function Menupoints_Callback(hObject, eventdata, handles)
4753%------------------------------------------------------------------------
4754data.Type='points';
4755data.ProjMode='projection';%default
4756data.ProjModeMenu={};% do not restrict ProjMode menus
4757create_object(data,handles)
4758
4759% -----------------------------------------------------------------------
4760% --- Callback of the Menu command line
4761%------------------------------------------------------------------------
4762function Menuline_Callback(hObject, eventdata, handles)
4763%------------------------------------------------------------------------
4764data.Type='line';
4765data.ProjMode='projection';%default
4766data.ProjModeMenu={};% do not restrict ProjMode menus
4767create_object(data,handles)
4768
4769% -----------------------------------------------------------------------
4770% --- Callback of the Menu command line_x
4771%------------------------------------------------------------------------
4772function Menuline_x_Callback(hObject, eventdata, handles)
4773
4774data.Type='line_x';
4775data.ProjMode='projection';%default
4776data.ProjModeMenu={};% do not restrict ProjMode menus
4777create_object(data,handles)
4778
4779% -----------------------------------------------------------------------
4780% --- Callback of the Menu command line_y
4781% -----------------------------------------------------------------------
4782function Menuline_y_Callback(hObject, eventdata, handles)
4783
4784data.Type='line_y';
4785data.ProjMode='projection';%default
4786data.ProjModeMenu={};% do not restrict ProjMode menus
4787create_object(data,handles)
4788
4789%------------------------------------------------------------------------
4790function Menupolyline_Callback(hObject, eventdata, handles)
4791%------------------------------------------------------------------------
4792data.Type='polyline';
4793data.ProjMode='projection';%default
4794data.ProjModeMenu={};% do not restrict ProjMode menus
4795create_object(data,handles)
4796
4797%------------------------------------------------------------------------
4798function Menupolygon_Callback(hObject, eventdata, handles)
4799%------------------------------------------------------------------------
4800data.Type='polygon';
4801data.ProjMode='inside';%default
4802data.ProjModeMenu={};% do not restrict ProjMode menus
4803create_object(data,handles)
4804
4805%------------------------------------------------------------------------
4806function Menurectangle_Callback(hObject, eventdata, handles)
4807%------------------------------------------------------------------------
4808data.Type='rectangle';
4809data.ProjMode='inside';%default
4810data.ProjModeMenu={};% do not restrict ProjMode menus
4811create_object(data,handles)
4812
4813%------------------------------------------------------------------------
4814function Menuellipse_Callback(hObject, eventdata, handles)
4815%------------------------------------------------------------------------
4816data.Type='ellipse';
4817data.ProjMode='inside';%default
4818data.ProjModeMenu={};% do not restrict ProjMode menus
4819create_object(data,handles)
4820
4821%------------------------------------------------------------------------
4822function MenuMaskObject_Callback(hObject, eventdata, handles)
4823%------------------------------------------------------------------------
4824data.Type='polygon';
4825data.TypeMenu={'polygon'};
4826data.ProjMode='mask_inside';%default
4827data.ProjModeMenu={'mask_inside';'mask_outside'};
4828create_object(data,handles)
4829
4830%------------------------------------------------------------------------
4831function Menuplane_Callback(hObject, eventdata, handles)
4832%------------------------------------------------------------------------
4833data.Type='plane';
4834data.ProjMode='projection';%default
4835data.ProjModeMenu={};% do not restrict ProjMode menus
4836create_object(data,handles)
4837
4838%------------------------------------------------------------------------
4839function Menuvolume_Callback(hObject, eventdata, handles)
4840%------------------------------------------------------------------------
4841data.Type='volume';
4842data.ProjMode='interp_lin';%default
4843data.ProjModeMenu={};
4844% set(handles.create,'Visible','on')
4845% set(handles.create,'Value',1)
4846% VOLUME_Callback(hObject,eventdata,handles)data.ProjModeMenu={};
4847create_object(data,handles)
4848
4849%------------------------------------------------------------------------
4850% --- generic function used for the creation of a projection object
4851function create_object(data,handles)
4852%------------------------------------------------------------------------
4853%% desactivate concurrent tools
4854set(handles.MenuRuler,'checked','off')%desactivate ruler
4855hgeometry_calib=findobj(allchild(0),'tag','geometry_calib');% search the GUI geometric calibration
4856if ishandle(hgeometry_calib)
4857    hhgeometry_calib=guidata(hgeometry_calib);
4858    set(hhgeometry_calib.CheckEnableMouse,'Value',0)% desactivate mouse action in geometry_calib
4859    set(hhgeometry_calib.CheckEnableMouse,'BackgroundColor',[0.7 0.7 0.7])
4860end
4861set(handles.CheckEditObject,'Value',0)  %desactivate the object edit mode
4862CheckEditObject_Callback([],[],handles)
4863set(handles.CheckViewObject,'Value',0) % desactivate view_object (new object created)
4864set(handles.CheckZoomFig,'Value',0) %desactivate zoom sub fig
4865set(handles.CheckZoom,'Value',0)    %desactivate the zoom action
4866set(handles.MenuObject,'checked','on')% indicate object creation for mouse pointer display
4867if ishandle(handles.UVMAT_title)
4868    delete(handles.UVMAT_title)     %delete the initial display of uvmat if no field has been entered yet
4869end
4870
4871%% initiate the new projection object
4872UvData=get(handles.uvmat,'UserData');
4873data.Name=data.Type;% default name=type
4874data.Coord=[0 0]; %default
4875check_plot=0;
4876if isfield(UvData,'Field')
4877    Field=UvData.Field;
4878    if isfield(Field,'NbDim')&& isequal(Field.NbDim,3)
4879         data.Coord=[0 0 0]; %default
4880    end
4881    if isfield(Field,'CoordUnit')
4882        data.CoordUnit=Field.CoordUnit;
4883    end
4884    if isfield(UvData.Field,'CoordMesh')&&~isempty(UvData.Field.CoordMesh)
4885        data.RangeX=[UvData.Field.XMin UvData.Field.XMax];
4886        switch data.Type
4887            case {'line','polyline','points'}
4888                data.RangeY=UvData.Field.CoordMesh;
4889            case 'line_x'
4890                check_plot=1; %plot the line directly when set_object is opened
4891                data.Type='line';
4892                data.RangeX=UvData.Field.XMin ;
4893                data.RangeY=UvData.Field.CoordMesh;
4894                data.Coord=[UvData.Field.XMin (UvData.Field.YMin +UvData.Field.YMax)/2;...
4895                           UvData.Field.XMax (UvData.Field.YMin +UvData.Field.YMax)/2];% put line at the middle of the y axis
4896            case 'line_y'
4897                check_plot=1; %plot the line directly when set_object is opened
4898                data.Type='line';
4899                data.RangeX=UvData.Field.YMin ;
4900                data.RangeY=UvData.Field.CoordMesh;
4901                data.Coord=[(UvData.Field.XMin+UvData.Field.XMax)/2 UvData.Field.YMin;...
4902                            (UvData.Field.XMin +UvData.Field.XMax)/2 UvData.Field.YMax];% put line at the middle of the y axis
4903            case {'rectangle','ellipse'}
4904                data.RangeY=[UvData.Field.YMin UvData.Field.YMax];
4905                data.RangeX=UvData.Field.CoordMesh;
4906                data.RangeY=UvData.Field.CoordMesh;
4907            otherwise
4908                data.RangeY=[UvData.Field.YMin UvData.Field.YMax];
4909        end
4910        data.DX=UvData.Field.CoordMesh;
4911        data.DY=UvData.Field.CoordMesh;
4912    end
4913end
4914
4915hset_object=set_object(data,handles);% call the GUI set_object
4916hchild=get(hset_object,'children');
4917set(hchild,'enable','on')
4918set(handles.DeleteObject,'Visible','on')% make the object delete button visible
4919if check_plot
4920    hhset_object=guidata(hset_object);
4921    set_object('REFRESH_Callback',1,[],hhset_object);% call the GUI set_object
4922end
4923set(handles.CheckViewField,'Visible','on')
4924set(handles.DeleteObject,'Visible','on')
4925set(handles.ListObject_1,'Visible','on')
4926set(handles.ListObject_1_title,'Visible','on')
4927
4928%------------------------------------------------------------------------
4929function MenuBrowseObject_Callback(hObject, eventdata, handles)
4930%------------------------------------------------------------------------
4931%get the object file
4932fileinput=uigetfile_uvmat('pick an xml object file:',get(handles.RootPath,'String'),'.xml');
4933if ~isempty(fileinput)
4934    %read the file
4935    [data,heading]=xml2struct(fileinput);
4936    if ~strcmp(heading,'ProjObject')
4937        msgbox_uvmat('WARNING','The xml file does not have the heading ProjObject for projection objects')
4938    end
4939    ListObject=get(handles.ListObject,'String');
4940    ListObject=[ListObject;{data.Name}];
4941    IndexObj=length(ListObject);
4942    UvData=get(handles.uvmat,'UserData');
4943    UvData.ProjObject{IndexObj}=[]; %create a new empty object
4944    UvData.ProjObject{IndexObj}.DisplayHandle.uvmat=[]; %no plot handle before plot_field operation
4945    UvData.ProjObject{IndexObj}.DisplayHandle.view_field=[]; %no plot handle before plot_field operation
4946    set(handles.uvmat,'UserData',UvData)
4947    set(handles.CheckViewObject,'Value',1)
4948    set(handles.CheckViewField,'Value',1)
4949    hset_object=set_object(data);% call the set_object interface
4950    hhset_object=guidata(hset_object);
4951    set_object('REFRESH_Callback',hObject,eventdata,hhset_object);% plot projection
4952    set(handles.CheckEditObject,'Value',0); %suppress the object edit mode
4953    CheckEditObject_Callback([],[],handles)
4954    set(handles.DeleteObject,'Visible','on')
4955end
4956
4957%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4958% MenuTools Callbacks
4959%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4960%------------------------------------------------------------------------
4961function MenuCalib_Callback(hObject, eventdata, handles)
4962%------------------------------------------------------------------------
4963%% suppress the second field if exists
4964if get(handles.SubField,'Value')
4965    set(handles.SubField,'Value',0)
4966    SubField_Callback(hObject, eventdata, handles)
4967end
4968UvData=get(handles.uvmat,'UserData');%read UvData properties stored on the uvmat interface
4969
4970%% suppress competing tools
4971set(handles.MenuRuler,'checked','off')%desactivate ruler
4972set(handles.CheckZoom,'Value',0)
4973set(handles.CheckZoom,'BackgroundColor',[0.7 0.7 0.7])
4974set(handles.ListObject,'Value',1)
4975
4976%% initiate display of the GUI geometry_calib
4977data=[]; %default
4978if isfield(UvData,'CoordType')
4979    data.CoordType=UvData.CoordType;
4980end
4981[RootPath,SubDir,RootFile,FileIndex,FileExt]=read_file_boxes(handles);
4982FileName=[fullfile(RootPath,SubDir,RootFile) FileIndex FileExt];
4983set(handles.view_xml,'BackgroundColor',[1 1 0])%indicate the reading of the current xml file by geometry_calib
4984geometry_calib(FileName);% call the geometry_calib interface   
4985set(handles.view_xml,'BackgroundColor',[1 1 1])%indicate the end of reading of the current xml file by geometry_calib
4986set(handles.MenuCalib,'checked','on')% indicate that MenuCalib is activated, test used by mouse action
4987
4988
4989% --------------------------------------------------------------------
4990% --- set the slice plane ro the set of slice planes when volume scan is used
4991function MenuSetSlice_Callback(hObject, eventdata, handles)
4992% --------------------------------------------------------------------
4993%% suppress the second input field if exists
4994if get(handles.SubField,'Value')
4995    set(handles.SubField,'Value',0)
4996    SubField_Callback(hObject, eventdata, handles)
4997end
4998
4999UvData=get(handles.uvmat,'UserData');%read UvData properties stored on the uvmat interface
5000check=0;
5001if isfield(UvData,'XmlData')&&isfield(UvData.XmlData{1},'GeometryCalib')&& isfield(UvData.XmlData{1}.GeometryCalib,'SliceCoord')
5002    GeometryCalib=UvData.XmlData{1}.GeometryCalib;
5003else
5004    msgbox_uvmat('ERROR','3D geometric calibration needed before defining slices')
5005    return
5006end   
5007SliceCoord=GeometryCalib.SliceCoord;
5008InterfaceCoord=min(SliceCoord(:,3));
5009if isfield(GeometryCalib,'InterfaceCoord')
5010    InterfaceCoord=GeometryCalib.InterfaceCoord(1,3);
5011end
5012NbSlice=size(SliceCoord,1);
5013CheckVolumeScan=0;
5014if isfield(GeometryCalib,'CheckVolumeScan')
5015    CheckVolumeScan=GeometryCalib.CheckVolumeScan;
5016end     
5017RefractionIndex=1.33;
5018if isfield(GeometryCalib,'RefractionIndex')
5019    RefractionIndex=GeometryCalib.RefractionIndex;
5020end     
5021SliceAngle=[0 0 0];
5022if isfield(GeometryCalib,'SliceAngle')
5023    SliceAngle=GeometryCalib.SliceAngle;
5024end
5025
5026%% create the GUI set_slice
5027set(0,'Unit','points')
5028ScreenSize=get(0,'ScreenSize');% get the size of the screen, to put the fig on the upper right
5029Width=350;% fig width in points (1/72 inch)
5030Height=min(0.8*ScreenSize(4),300);
5031Left=ScreenSize(3)- Width-40; %right edge close to the right, with margin=40
5032Bottom=ScreenSize(4)-Height-40; %put fig at top right
5033hfig=findobj(allchild(0),'Tag','set_slice');
5034if ~isempty(hfig),delete(hfig), end; %delete existing version of the GUI
5035hfig=figure('name','set_slices','tag','set_slice','MenuBar','none','NumberTitle','off','Unit','points','Position',[Left,Bottom,Width,Height],'UserData',GeometryCalib);
5036BackgroundColor=get(hfig,'Color');
5037hh=0.14; % box height (relative)
5038ii=0.01; % gap between uicontrols
5039
5040ww=(1-5*ii)/4; % box width (relative)
5041% first raw of the GUI
5042uicontrol('Style','text','Units','normalized', 'Position', [2*ii+ww 0.95-ii-0.25*hh ww hh/2],'BackgroundColor',BackgroundColor,...
5043    'String','first','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','center');%title
5044uicontrol('Style','text','Units','normalized', 'Position', [3*ii+2*ww 0.95-ii-0.25*hh ww hh/2],'BackgroundColor',BackgroundColor,...
5045    'String','last','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','center');%title
5046uicontrol('Style','text','Units','normalized', 'Position', [4*ii+3*ww 0.95-ii-0.25*hh ww hh/2],'BackgroundColor',BackgroundColor,...
5047    'String','surface','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','center');%title
5048%  raw 2 of the GUI
5049uicontrol('Style','text','Units','normalized', 'Position', [ii 0.95-2*ii-0.75*hh ww hh/2],'BackgroundColor',BackgroundColor,...
5050    'String','Z','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','right');%title
5051uicontrol('Style','edit','Units','normalized', 'Position', [2*ii+ww 0.95-2*ii-hh ww hh],'tag','num_Z_1','BackgroundColor',[1 1 1],...
5052    'String',num2str(SliceCoord(1,3)),'FontUnits','points','FontSize',12,'FontWeight','bold','TooltipString','''num_Z_1'': z position of first slice');%edit box
5053uicontrol('Style','edit','Units','normalized', 'Position', [3*ii+2*ww 0.95-2*ii-hh ww hh],'tag','num_Z_2','BackgroundColor',[1 1 1],...
5054    'String',num2str(SliceCoord(end,3)),'FontUnits','points','FontSize',12,'FontWeight','bold','TooltipString','''num_Z_2'': z position of last slice');%edit box
5055uicontrol('Style','edit','Units','normalized', 'Position', [4*ii+3*ww 0.95-2*ii-hh ww hh],'tag','num_H','BackgroundColor',[1 1 1],...
5056    'String',num2str(InterfaceCoord),'FontUnits','points','FontSize',12,'FontWeight','bold','TooltipString','''num_H'': z position of the water surface (=Z_1 in air)');%edit box
5057%  raw 3 of the GUI
5058uicontrol('Style','text','Units','normalized', 'Position', [2*ii+ww 0.95-3*ii-1.75*hh 2*ww hh/2],'BackgroundColor',BackgroundColor,'Tag','Refraction_title',...
5059    'String','refraction index','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','right');%title
5060uicontrol('Style','edit','Units','normalized', 'Position', [4*ii+3*ww 0.95-3*ii-2*hh ww hh],'tag','num_RefractionIndex','BackgroundColor',[1 1 1],...
5061    'String',num2str(RefractionIndex),'FontUnits','points','FontSize',12,'FontWeight','bold','TooltipString','''num_RefractionIndex'': refraction index of water');
5062%  raw 4 of the GUI
5063uicontrol('Style','text','Units','normalized', 'Position', [ii 0.95-4*ii-3.25*hh ww hh],'BackgroundColor',BackgroundColor,'Tag','NbSlice_title',...
5064    'String','NbSlice','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','right');%title
5065uicontrol('Style','edit','Units','normalized', 'Position', [2*ii+ww 0.95-4*ii-3*hh ww hh],'tag','num_NbSlice','BackgroundColor',[1 1 1],...
5066    'String',num2str(NbSlice),'FontUnits','points','FontSize',12,'FontWeight','bold','TooltipString','''num_NbSlice'':number of slices');%edit box
5067uicontrol('Style','checkbox','Units','normalized', 'Position', [3*ii+2*ww 0.95-4*ii-3*hh 2*ww hh],'tag','CheckVolumeScan','BackgroundColor',BackgroundColor,...
5068    'String','volume scan','Value',CheckVolumeScan,'FontUnits','points','FontSize',12,'FontWeight','bold','TooltipString','''CheckVolumeScan'':=1 for volume scan (z varies with j index)');
5069%  raw 5 of the GUI
5070uicontrol('Style','text','Units','normalized', 'Position', [2*ii+2*ww 0.95-5*ii-4.2*hh ww hh/2],'BackgroundColor',BackgroundColor,'Tag','Angle_title_1',...
5071    'String','x axis','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','center');%title
5072uicontrol('Style','text','Units','normalized', 'Position', [3*ii+3*ww 0.95-5*ii-4.2*hh ww hh/2],'BackgroundColor',BackgroundColor,'Tag','Angle_title_2',...
5073    'String','y axis','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','center');%title
5074%  raw 6 of the GUI
5075uicontrol('Style','text','Units','normalized', 'Position', [ii 0.95-5*ii-4.75*hh 2*ww hh/2],'BackgroundColor',BackgroundColor,'Tag','NbSlice_title',...
5076    'String','tilt angle','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','right');%title
5077uicontrol('Style','edit','Units','normalized', 'Position', [3*ii+2*ww 0.95-5*ii-5*hh ww hh],'tag','num_SliceAngle_1','BackgroundColor',[1 1 1],...
5078    'String',num2str(SliceAngle(1)),'FontUnits','points','FontSize',12,'FontWeight','bold','TooltipString','''num_SliceAngle_1'':slice angle of inclination around the x axis');%edit box
5079uicontrol('Style','edit','Units','normalized', 'Position', [4*ii+3*ww 0.95-5*ii-5*hh ww hh],'tag','num_SliceAngle_2','BackgroundColor',[1 1 1],...
5080    'String',num2str(SliceAngle(2)),'FontUnits','points','FontSize',12,'FontWeight','bold','TooltipString','''num_SliceAngle_1'':slice angle of inclination around the y axis');%edit box
5081%  raw 7 of the GUI: pushbuttons
5082wwp=(1-4*ii)/3; %width of the push buttons
5083uicontrol('Style','pushbutton','Units','normalized', 'Position', [ii ii wwp hh],'BackgroundColor',[1 0 0],'String','APPLY','Callback',@(hObject,eventdata)set_slice_APPLY_Callback(hObject,eventdata),...
5084    'FontWeight','bold','FontUnits','points','FontSize',12,'TooltipString','''APPLY'': apply the output to the current field series in uvmat');
5085uicontrol('Style','pushbutton','Units','normalized', 'Position', [2*ii+wwp ii wwp hh],'BackgroundColor',[1 0 0],'String','REPLICATE','Callback',@(hObject,eventdata)set_slice_REPLICATE_Callback(hObject,eventdata),...
5086    'FontWeight','bold','FontUnits','points','FontSize',12,'TooltipString','''REPLICATE'': replicate the output for a series of experiments');
5087uicontrol('Style','pushbutton','Units','normalized', 'Position', [3*ii+2*wwp ii wwp hh],'Callback',@(hObject,eventdata)set_slice_Cancel_Callback(hObject,eventdata),...
5088    'String','Cancel','FontWeight','bold','FontUnits','points','FontSize',12,'TooltipString','''Cancel'': quit GUI without action');
5089drawnow
5090
5091%------------------------------------------------------------------------
5092% function called by pressing APPLY in the GUI  set_slices
5093function set_slice_APPLY_Callback(hObject,eventdata)
5094%------------------------------------------------------------------------   
5095
5096%% get the uvmat GUI data and read the current xml file
5097huvmat=findobj(allchild(0),'Tag','uvmat');
5098hhuvmat=guidata(huvmat);
5099[RootPath,SubDir,RootFile,FileIndex,FileExt]=read_file_boxes(hhuvmat);
5100FileName=[fullfile(RootPath,SubDir,RootFile) FileIndex FileExt];%name of the xml file for calibration
5101[RootPath,SubDir,RootFile,tild,tild,tild,tild,FileExt]=fileparts_uvmat(FileName);
5102XmlFile=find_imadoc(RootPath,SubDir,RootFile,FileExt);
5103[s,errormsg]=imadoc2struct(XmlFile,'GeometryCalib');
5104if~isempty(errormsg)
5105    msgbox_uvmat('ERROR',errormsg)
5106    return
5107end
5108GeometryCalib=s.GeometryCalib;
5109
5110%% read the content of the GUI set_slice
5111SliceData=read_GUI(get(hObject,'parent'));
5112GeometryCalib.NbSlice=SliceData.NbSlice;
5113GeometryCalib.CheckVolumeScan=SliceData.CheckVolumeScan;
5114Z_plane=linspace(SliceData.Z(1),SliceData.Z(2),SliceData.NbSlice);
5115GeometryCalib.SliceCoord=Z_plane'*[0 0 1];
5116GeometryCalib.SliceAngle=zeros(GeometryCalib.NbSlice,3);
5117GeometryCalib.SliceAngle(:,1)=SliceData.SliceAngle(1)*ones(GeometryCalib.NbSlice,1);%rotation around x axis (to generalise)
5118GeometryCalib.SliceAngle(:,2)=SliceData.SliceAngle(2)*ones(GeometryCalib.NbSlice,1);%rotation around y axis (to generalise)
5119GeometryCalib.SliceAngle(:,3)=0;
5120GeometryCalib.InterfaceCoord=[0 0 SliceData.H];
5121GeometryCalib.RefractionIndex=SliceData.RefractionIndex;
5122
5123%% store the result in the xml file used for calibration
5124errormsg=update_imadoc(GeometryCalib,XmlFile,'GeometryCalib');% introduce the calibration data in the xml file
5125if strcmp(errormsg,'')
5126    msgbox_uvmat('CONFIRMATION',['slice positions saved in ' XmlFile]);
5127else
5128    msgbox_uvmat('ERROR',errormsg);
5129end
5130
5131%% display image with new calibration in the currently opened uvmat interface
5132set(hhuvmat.CheckFixLimits,'Value',0)% put FixedLimits option to 'off' to plot the whole image
5133uvmat('InputFileREFRESH_Callback',huvmat,[],hhuvmat); %file input with xml reading  in uvmat, show the image in phys coordinates
5134
5135%------------------------------------------------------------------------
5136% function called by pressing REPLICATE in the GUI  set_slices
5137function set_slice_REPLICATE_Callback(hObject,eventdata)
5138%------------------------------------------------------------------------
5139
5140%% read the GUI set_slice
5141SliceData=read_GUI(get(hObject,'parent'));
5142
5143%% get info on the GUI uvmat
5144huvmat=findobj(allchild(0),'Tag','uvmat');
5145hhuvmat=guidata(huvmat);
5146[RootPath,SubDir,RootFile,FileIndex,FileExt]=read_file_boxes(hhuvmat);
5147
5148%% open the GUI browse_data
5149answer=msgbox_uvmat('INPUT_TXT','Campaign to calibrate with slice position?',fileparts(RootPath));
5150if strcmp(answer,'Cancel')
5151    return
5152end
5153OutPut=browse_data(answer);
5154nbcalib=0;
5155for ilist=1:numel(OutPut.Experiment)
5156    SubDirBase=regexprep(OutPut.DataSeries{1},'\..+$','');
5157    XmlFile=fullfile(OutPut.Campaign,OutPut.Experiment{ilist},[SubDirBase '.xml']);
5158   
5159    % read the current xml file
5160    [s,errormsg]=imadoc2struct(XmlFile,'GeometryCalib');
5161    if ~isempty(errormsg)
5162        msgbox_uvmat('ERROR',['error in reading ' XmlFile ': ' errormsg])
5163        return
5164    end
5165    GeometryCalib=s.GeometryCalib;
5166    GeometryCalib.NbSlice=SliceData.NbSlice;
5167    GeometryCalib.VolumeScan=SliceData.CheckVolumeScan;
5168    Z_plane=linspace(SliceData.Z(1),SliceData.Z(2),SliceData.NbSlice);
5169    GeometryCalib.SliceCoord=Z_plane'*[0 0 1];
5170    GeometryCalib.SliceAngle=zeros(GeometryCalib.NbSlice,3);
5171    GeometryCalib.SliceAngle(:,1)=SliceData.SliceAngle(1)*ones(GeometryCalib.NbSlice,1);%rotation around x axis (to generalise)
5172    GeometryCalib.SliceAngle(:,2)=SliceData.SliceAngle(2)*ones(GeometryCalib.NbSlice,1);%rotation around y axis (to generalise)
5173    GeometryCalib.SliceAngle(:,3)=0;
5174    GeometryCalib.InterfaceCoord=[0 0 SliceData.H];
5175    GeometryCalib.RefractionIndex=SliceData.RefractionIndex;
5176   
5177    % update the current xml file
5178    errormsg=update_imadoc(GeometryCalib,XmlFile,'GeometryCalib');% introduce the calibration data in the xml file
5179    if ~strcmp(errormsg,'')
5180        msgbox_uvmat('ERROR',errormsg);
5181    else
5182        display([XmlFile ' updated with slice positions'])
5183        nbcalib=nbcalib+1;
5184    end
5185end
5186msgbox_uvmat('CONFIMATION',[SubDirBase ' calibrated with slice positions for ' num2str(nbcalib) ' experiments']);
5187
5188%------------------------------------------------------------------------
5189% function called by pressing Cancel in the GUI  set_slices
5190function set_slice_Cancel_Callback(hObject,eventdata)
5191%------------------------------------------------------------------------
5192hfig=get(hObject,'parent');
5193delete(hfig)
5194
5195%-----------------------------------------------------------------------
5196function MenuLIFCalib_Callback(hObject, eventdata, handles)
5197%------------------------------------------------------------------------
5198%% read UvData properties stored on the uvmat interface
5199UvData=get(handles.uvmat,'UserData');
5200if isfield(UvData,'XmlData')&& isfield(UvData.XmlData{1},'GeometryCalib')
5201    XmlData=UvData.XmlData{1};
5202else
5203    msgbox_uvmat('ERROR','geometric calibration needed: use Tools/geometric calibration in the menu bar');
5204    return
5205end
5206
5207%% read lines currently drawn
5208ListObj=UvData.ProjObject;
5209select=zeros(1,numel(ListObj));
5210for iobj=1:numel(ListObj);
5211    if isfield(ListObj{iobj},'Type') && strcmp(ListObj{iobj}.Type,'line')
5212        select(iobj)=1;
5213    end
5214end
5215val=find(select);
5216if numel(val)<2
5217    msgbox_uvmat('ERROR','light rays must be defined by at least two lines created by Projection object/line in the menu bar');
5218    return
5219else
5220    set(handles.ListObject,'Value',val);% show the selected lines on the list
5221    ObjectData=UvData.ProjObject(val);
5222    for iobj=1:length(ObjectData)
5223            xA(iobj)=ObjectData{iobj}.Coord(1,1);
5224            yA(iobj)=ObjectData{iobj}.Coord(1,2);
5225            xB(iobj)=ObjectData{iobj}.Coord(2,1);
5226            yB(iobj)=ObjectData{iobj}.Coord(2,2);
5227    end
5228end
5229
5230%% find the origin as intersection of the two first lines (see http://www.ahristov.com/tutorial/geometry-games/intersection-lines.html )
5231x1=xA(1);x2=xB(1);
5232x3=xA(2);x4=xB(2);
5233y1=yA(1);y2=yB(1);
5234y3=yA(2);y4=yB(2);
5235D = (x1-x2)*(y3-y4) -(y1-y2)*(x3-x4);
5236if D==0
5237    msgbox_uvmat('ERROR','the two lines are parallel');
5238    return
5239end
5240x0=((x3-x4)*(x1*y2-y1*x2)-(x1-x2)*(x3*y4-y3*x4))/D;
5241y0=((y3-y4)*(x1*y2-y1*x2)-(y1-y2)*(x3*y4-y3*x4))/D;
5242XmlData.Illumination.Origin=[x0 y0];
5243XmlData.PolarCentre=[x0 y0];
5244
5245%% display the current image in polar axes with origin at the  illumination source
5246currentdir=pwd; 
5247uvmatpath=fileparts(which('uvmat'));
5248cd(fullfile(uvmatpath,'transform_field'));
5249phys_polar=str2func('phys_polar');
5250cd(currentdir)
5251DataOut=phys_polar(UvData.Field,XmlData);
5252view_field(DataOut);
5253
5254%% use the third line for reference luminosity
5255if numel(val)==3
5256    x_ref=linspace(ObjectData{3}.Coord(1,1),ObjectData{3}.Coord(2,1),10);
5257    y_ref=linspace(ObjectData{3}.Coord(1,2),ObjectData{3}.Coord(2,2),10);
5258    x_ref=x_ref-x0;
5259    y_ref=y_ref-y0;
5260    [theta_ref,r_ref] = cart2pol(x_ref,y_ref);%theta_ref  and r_ref are the polar coordinates of the points on the line
5261    theta_ref=theta_ref*180/pi;
5262    figure
5263    plot(theta_ref,r_ref)
5264    azimuth_ima=linspace(DataOut.AY(1),DataOut.AY(2),size(DataOut.A,1));%profile of x index on the transformed image
5265    dist_source = interp1(theta_ref,r_ref,azimuth_ima);
5266    dist_source_pixel=round(size(DataOut.A,2)*(dist_source-DataOut.AX(1))/(DataOut.AX(2)-DataOut.AX(1)));
5267    line_nan= isnan(dist_source_pixel);
5268    dist_source_pixel(line_nan)=1;
5269    width=20; %number of pixels used for reference
5270    DataOut.A=double(DataOut.A);
5271    Anorm=zeros(size(DataOut.A));
5272    Aval=mean(mean(DataOut.A));
5273    for iline=1:size(DataOut.A,1)
5274        lum(iline)=mean(DataOut.A(iline,dist_source_pixel(iline):dist_source_pixel(iline)+width));
5275        Anorm(iline,:)=uint16(Aval*DataOut.A(iline,:)/lum(iline));
5276    end
5277    lum(line_nan)=NaN;
5278    figure
5279    plot(1:size(DataOut.A,1),lum)
5280end
5281ImaName=regexprep([get(handles.RootFile,'String') get(handles.FileIndex,'String')],'//','');
5282NewImageName=fullfile(get(handles.RootPath,'String'),'polar',[ImaName get(handles.FileExt,'String')]);
5283imwrite(Anorm,NewImageName,'BitDepth',16)
5284
5285%% record the origin in the xml file
5286XmlFileName=find_imadoc(get(handles.RootPath,'String'),get(handles.SubDir,'String'),get(handles.RootFile,'String'),get(handles.FileExt,'String'));
5287answer=msgbox_uvmat('INPUT_Y-N','save the illumination origin in the current xml file?');
5288if strcmp(answer,'Yes')
5289    t=xmltree(XmlFileName); %read the file
5290    title=get(t,1,'name');
5291    if ~strcmp(title,'ImaDoc')
5292        msgbox_uvmat('ERROR','wrong xml file');
5293        return
5294    end
5295    % backup the output file if it already exist, and read it
5296    backupfile=XmlFileName;
5297    testexist=2;
5298    while testexist==2
5299        backupfile=[backupfile '~'];
5300        testexist=exist(backupfile,'file');
5301    end
5302    [success,message]=copyfile(XmlFileName,backupfile);%make backup
5303    if success~=1
5304        errormsg=['errror in xml file backup: ' message];
5305        return
5306    end
5307    uid_illumination=find(t,'ImaDoc/Illumination');
5308    if isempty(uid_illumination)  %if GeometryCalib does not already exists, create it
5309        [t,uid_illumination]=add(t,1,'element','Illumination');
5310    end
5311    uid_origin=find(t,'ImaDoc/Illumination/Origin');
5312    if ~isempty(uid_origin)  %if GeometryCalib does not already exists, create it
5313         t=delete(t,uid_origin);
5314    end
5315    % save the illumination origin
5316    t=struct2xml(XmlData.Illumination,t,uid_illumination);
5317    save(t,XmlFileName);
5318end
5319   
5320
5321
5322%------------------------------------------------------------------------
5323function MenuMask_Callback(hObject, eventdata, handles)
5324%------------------------------------------------------------------------
5325UvData=get(handles.uvmat,'UserData');%read UvData properties stored on the uvmat interface
5326ListObj=UvData.ProjObject;
5327select=zeros(1,numel(ListObj));
5328for iobj=1:numel(ListObj);
5329    if strcmp(ListObj{iobj}.ProjMode,'mask_inside')||strcmp(ListObj{iobj}.ProjMode,'mask_outside')
5330        select(iobj)=1;
5331    end
5332end
5333val=find(select);
5334if isempty(val)
5335    msgbox_uvmat('ERROR','polygons must be first created by Projection object/mask polygon in the menu bar');
5336    return
5337else
5338    set(handles.ListObject,'Value',val);
5339    flag=1;
5340    if ~isfield(UvData.Field,'A')
5341            msgbox_uvmat('ERROR','an image needs to be opened to set the mask size');
5342    return
5343    end
5344    npx=size(UvData.Field.A,2);
5345    npy=size(UvData.Field.A,1);
5346    xi=0.5:npx-0.5;
5347    yi=0.5:npy-0.5;
5348    [Xi,Yi]=meshgrid(xi,yi);
5349        for iobj=1:length(UvData.ProjObject)
5350            ObjectData=UvData.ProjObject{iobj};
5351            if isfield(ObjectData,'ProjMode') &&(isequal(ObjectData.ProjMode,'mask_inside')||isequal(ObjectData.ProjMode,'mask_outside'));
5352                flagobj=1;
5353                testphys=0; %coordinates in pixels by default
5354                if isfield(ObjectData,'CoordUnit') && ~isequal(ObjectData.CoordUnit,'pixel')
5355                    if isfield(UvData,'XmlData')&& isfield(UvData.XmlData{1},'GeometryCalib')
5356                        Calib=UvData.XmlData{1}.GeometryCalib;
5357                        testphys=1;
5358                    end
5359                end
5360                if isfield(ObjectData,'Coord')&& isfield(ObjectData,'Type')
5361                    if isequal(ObjectData.Type,'polygon')
5362                        X=ObjectData.Coord(:,1);
5363                        Y=ObjectData.Coord(:,2);
5364                        if testphys
5365                            pos=[X Y zeros(size(X))];
5366                            if isfield(Calib,'SliceCoord') && length(Calib.SliceCoord)>=3
5367                                if isfield(Calib,'SliceAngle')&&~isequal(Calib.SliceAngle,[0 0 0])
5368                                    om=norm(Calib.SliceAngle);%norm of rotation angle in radians
5369                                    OmAxis=Calib.SliceAngle/om; %unit vector marking the rotation axis
5370                                    cos_om=cos(pi*om/180);
5371                                    sin_om=sin(pi*om/180);
5372                                    pos=cos_om*pos+sin_om*cross(OmAxis,pos)+(1-cos_om)*(OmAxis*pos')*OmAxis;
5373                                end
5374                                pos(:,1)=pos(:,1)+Calib.SliceCoord(1);
5375                                pos(:,2)=pos(:,2)+Calib.SliceCoord(2);
5376                                pos(:,3)=pos(:,3)+Calib.SliceCoord(3);
5377                            end                           
5378                            [X,Y]=px_XYZ(Calib,pos(:,1),pos(:,2),pos(:,3));
5379                        end
5380                        flagobj=~inpolygon(Xi,Yi,X',Y');%=0 inside the polygon, 1 outside
5381                    elseif isequal(ObjectData.Type,'ellipse')
5382                        if testphys
5383                            %[X,Y]=px_XYZ(Calib,X,Y,0);% TODO:create a polygon boundary and transform to phys
5384                        end
5385                        RangeX=max(ObjectData.RangeX);
5386                        RangeY=max(ObjectData.RangeY);
5387                        X2Max=RangeX*RangeX;
5388                        Y2Max=RangeY*RangeY;
5389                        distX=(Xi-ObjectData.Coord(1,1));
5390                        distY=(Yi-ObjectData.Coord(1,2));
5391                        flagobj=(distX.*distX/X2Max+distY.*distY/Y2Max)>1;
5392                    elseif isequal(ObjectData.Type,'rectangle')
5393                        if testphys
5394                            %[X,Y]=px_XYZ(Calib,X,Y,0);% TODO:create a polygon boundary and transform to phys
5395                        end
5396                        distX=abs(Xi-ObjectData.Coord(1,1));
5397                        distY=abs(Yi-ObjectData.Coord(1,2));
5398                        flagobj=distX>max(ObjectData.RangeX) | distY>max(ObjectData.RangeY);
5399                    end
5400                    if isequal(ObjectData.ProjMode,'mask_outside')
5401                        flagobj=~flagobj;
5402                    end
5403                    flag=flag & flagobj;
5404                end
5405            end
5406        end
5407    %mask name
5408    RootPath=get(handles.RootPath,'String');
5409    SubDir=get(handles.SubDir,'String');
5410    RootFile=get(handles.RootFile,'String');
5411    if ~isempty(RootFile)&&(isequal(RootFile(1),'/')|| isequal(RootFile(1),'\'))
5412        RootFile(1)=[];
5413    end
5414    list=get(handles.masklevel,'String');
5415    masknumber=num2str(length(list));
5416    maskindex=get(handles.masklevel,'Value');
5417    mask_name=fullfile_uvmat(RootPath,[SubDir '.mask'],'mask','.png','_1',maskindex);
5418    imflag=uint8(255*(0.392+0.608*flag));% =100 for flag=0 (vectors not computed when 20<imflag<200)
5419    imflag=flipdim(imflag,1);
5420
5421    %display the mask
5422    hfigmask=figure;
5423    set(hfigmask,'Name','mask image')
5424    vec=linspace(0,1,256);%define a linear greyscale colormap
5425    map=[vec' vec' vec'];
5426    colormap(map)
5427    image(imflag);
5428    answer=msgbox_uvmat('INPUT_TXT','mask file name:', mask_name);
5429    if ~strcmp(answer,'Cancel')
5430        mask_dir=fileparts(answer);
5431        if ~exist(mask_dir,'dir')
5432            [xx,msg1]=mkdir(mask_dir);
5433            if ~strcmp(msg1,'')
5434                errormsg=['cannot create ' mask_dir ': ' msg1];%error message for directory creation
5435                return
5436            end
5437        end
5438        imwrite(imflag,answer,'BitDepth',8);
5439    end
5440    set(handles.ListObject,'Value',1)
5441end
5442
5443%------------------------------------------------------------------------
5444%-- open the GUI set_grid.fig to create grid
5445function MenuGrid_Callback(hObject, eventdata, handles)
5446%------------------------------------------------------------------------
5447%suppress the other options if grid is chosen
5448set(handles.edit_vect,'Value',0)
5449edit_vect_Callback(hObject, eventdata, handles)
5450set(handles.ListObject,'Value',1)     
5451
5452%prepare display of the set_grid GUI
5453[RootPath,SubDir,RootFile,FileIndex,FileExt]=read_file_boxes(handles);
5454FileName=[fullfile(RootPath,SubDir,RootFile) FileIndex FileExt];
5455UvData=get(handles.uvmat,'UserData');
5456% CoordList=get(handles.TransformName,'String');
5457% val=get(handles.TransformName,'Value');
5458set_grid(FileName,UvData.Field);% call the set_object interface
5459
5460
5461%------------------------------------------------------------------------
5462function MenuRuler_Callback(hObject, eventdata, handles)
5463%------------------------------------------------------------------------
5464if strcmp(get(handles.MenuRuler,'checked'),'on')
5465    set(handles.MenuRuler,'checked','off')%desactivate if activated
5466else
5467    set(handles.MenuRuler,'checked','on')%activate if selected
5468    set(handles.CheckZoom,'Value',0)
5469    CheckZoom_Callback(handles.uvmat, [], handles)
5470    UvData=get(handles.uvmat,'UserData');
5471    UvData.MouseAction='ruler';
5472    set(handles.uvmat,'UserData',UvData);
5473end
5474
5475%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5476% MenuRun Callbacks
5477%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5478
5479%------------------------------------------------------------------------
5480% open the GUI 'series'
5481function MenuSeries_Callback(hObject, eventdata, handles)
5482%------------------------------------------------------------------------
5483Param=read_param(handles);
5484series(Param); %run the series interface
5485
5486% --------------------------------------------------------------------
5487function MenuPIV_Callback(hObject, eventdata, handles)
5488    Param=read_param(handles);
5489%     Param.ActionName='civ_series';
5490hseries=series(Param);
5491hhseries=guidata(hseries);
5492ActionMenu=get(hhseries.ActionName,'String');
5493index_action=find(strcmp('civ_series',ActionMenu));
5494set(hhseries.ActionName,'Value',index_action);
5495series('ActionName_Callback',hObject,eventdata,hhseries); %file input with xml reading  in uvmat, show the image in phys coordinates
5496
5497
5498%------------------------------------------------------------------------
5499% -- open the GUI civ.fig for PIV
5500function MenuCIVx_Callback(hObject, eventdata, handles)
5501%------------------------------------------------------------------------
5502 [RootPath,SubDir,RootFile,FileIndex,FileExt]=read_file_boxes(handles);
5503 FileName=[fullfile(RootPath,SubDir,RootFile) FileIndex FileExt];
5504civ(FileName);% interface de civ(not in the uvmat file)
5505
5506function Param=read_param(handles)
5507   
5508[RootPath,SubDir,RootFile,FileIndex,FileExt]=read_file_boxes(handles);
5509Param.FileName=[fullfile(RootPath,SubDir,RootFile) FileIndex FileExt];%first input file name
5510if isequal(get(handles.SubField,'Value'),1)
5511    [RootPath_1,SubDir_1,RootFile_1,FileIndex_1,FileExt_1]=read_file_boxes_1(handles);
5512    FileName_1=[fullfile(RootPath_1,SubDir_1,RootFile_1) FileIndex_1 FileExt_1];
5513    if ~isequal(FileName_1,Param.FileName)
5514        Param.FileName_1=FileName_1;%second input file name if relevant
5515    end
5516end
5517Param.NomType=get(handles.NomType,'String');
5518Param.NomType_1=get(handles.NomType_1,'String');
5519Param.CheckFixPair=get(handles.CheckFixPair,'Value');
5520UvData=get(handles.uvmat,'UserData');
5521if isfield(UvData,'XmlData')&& isfield(UvData.XmlData{1},'Time')
5522    Param.Time=UvData.XmlData{1}.Time;
5523end
5524if isequal(get(handles.scan_i,'Value'),1)
5525    Param.incr_i=str2num(get(handles.num_IndexIncrement,'String'));
5526elseif isequal(get(handles.scan_j,'Value'),1)
5527    Param.incr_j=str2num(get(handles.num_IndexIncrement,'String'));
5528end
5529
5530%% transfer fields and coordinate names
5531Param.list_fields=get(handles.FieldName,'String');% list menu fields
5532FieldName=Param.list_fields{get(handles.FieldName,'Value')};
5533ind_image=find(strcmp('image',Param.list_fields));
5534if ~isempty(ind_image) && numel(Param.list_fields)>1
5535    Param.list_fields(ind_image)=[]; %suppress  'image' option
5536end
5537Param.index_fields=find(strcmp(FieldName,Param.list_fields));% selected string index
5538Param.list_fields_1=get(handles.FieldName_1,'String');% list menu fields
5539if ischar(Param.list_fields_1),Param.list_fields_1={Param.list_fields_1};end
5540FieldName_1=Param.list_fields_1{get(handles.FieldName_1,'Value')};
5541ind_image=find(strcmp('image',Param.list_fields_1));
5542if ~isempty(ind_image) && numel(Param.list_fields_1)>1
5543    Param.list_fields_1(ind_image)=[]; %suppress  'image' option
5544end
5545Param.index_fields_1=find(strcmp(FieldName_1,Param.list_fields_1));% selected string index
5546TransformList=get(handles.TransformName,'String');
5547Param.TransformName=TransformList{get(handles.TransformName,'Value')};
5548Param.Coord_x_str=get(handles.Coord_x,'String');
5549%Param.Coord_x_val=get(handles.Coord_x,'Value');
5550Param.Coord_y_str=get(handles.Coord_y,'String');
5551
5552% --------------------------------------------------------------------
5553function MenuHelp_Callback(hObject, eventdata, handles)
5554% --------------------------------------------------------------------
5555web('http://servforge.legi.grenoble-inp.fr/projects/soft-uvmat/wiki/UvmatHelp')
5556
5557% path_to_uvmat=which ('uvmat');% check the path of uvmat
5558% pathelp=fileparts(path_to_uvmat);
5559% helpfile=fullfile(pathelp,'uvmat_doc','uvmat_doc.html');
5560% if isempty(dir(helpfile)), msgbox_uvmat('ERROR','Please put the help file uvmat_doc.html in the sub-directory /uvmat_doc of the UVMAT package')
5561% else
5562%     addpath (fullfile(pathelp,'uvmat_doc'))
5563%     web(helpfile);
5564% end
5565
5566
5567
5568%TODO: use to modify fill_GUI
5569%'write_plot_param': update the plotting parameters on the uvmat or view_field interface after a plotting operation
5570function write_plot_param(handles,PlotParam)
5571%% axes
5572if isempty(PlotParam.Axes)
5573    set(handles.Axes,'Visible','off')
5574    set(handles.PlotAxes,'Visible','off')
5575    set(handles.text_display,'Visible','off')
5576    set(handles.TableDisplay,'Visible','on')
5577else
5578    set(handles.Axes,'Visible','on')
5579    set(handles.PlotAxes,'Visible','on')
5580    set(handles.text_display,'Visible','on')
5581    if isfield(handles,'TableDisplay')
5582    set(handles.TableDisplay,'Visible','off')
5583    end
5584    Coordinates=PlotParam.Axes;
5585    if isfield(Coordinates,'CheckFixAspectRatio')
5586        if Coordinates.CheckFixAspectRatio
5587            set(handles.CheckFixAspectRatio,'Value',1)
5588        else
5589            set(handles.CheckFixAspectRatio,'Value',0)
5590 
5591        end
5592    end
5593    if isfield(Coordinates,'AspectRatio')
5594        set(handles.num_AspectRatio,'String',num2str(Coordinates.AspectRatio))
5595    end
5596    if isfield(Coordinates,'MinX')
5597        set(handles.num_MinX,'String',num2str(Coordinates.MinX,4));
5598        set(handles.num_MaxX,'String',num2str(Coordinates.MaxX,4));
5599        set(handles.num_MinY,'String',num2str(Coordinates.MinY,4));
5600        set(handles.num_MaxY,'String',num2str(Coordinates.MaxY,4));
5601    else
5602        set(handles.num_MinX,'String','');
5603        set(handles.num_MaxX,'String','');
5604        set(handles.num_MinY,'String','');
5605        set(handles.num_MaxY,'String','');
5606    end
5607end
5608
5609%% scalar or image parameters
5610if isfield(PlotParam,'Scalar')
5611    set(handles.Scalar,'Visible','on')
5612    if isfield(PlotParam.Scalar,'MaxA')
5613        set(handles.num_MaxA,'String',num2str(PlotParam.Scalar.MaxA,3));
5614    end
5615    if isfield(PlotParam.Scalar,'MinA')
5616        set(handles.num_MinA,'String',num2str(PlotParam.Scalar.MinA,3));
5617    end   
5618    if isfield(PlotParam.Scalar,'IncrA')
5619        set(handles.num_IncrA,'String',num2str(PlotParam.Scalar.IncrA,3))
5620    end
5621    set(handles.CheckBW,'Value',PlotParam.Scalar.CheckBW)
5622    if isfield(PlotParam.Scalar,'Opacity')&&isfield(handles,'num_Opacity')
5623        set(handles.num_Opacity,'String',num2str(PlotParam.Scalar.Opacity))
5624    end
5625else
5626    set(handles.Scalar,'Visible','off')
5627end
5628
5629%% parameter for vector field
5630if isfield(PlotParam,'Vectors')
5631    set(handles.Vectors,'Visible','on')
5632    if isfield(PlotParam.Vectors,'VecScale')
5633        set(handles.num_VecScale,'String',num2str(PlotParam.Vectors.VecScale,3))
5634    end
5635    if isfield(PlotParam.Vectors,'MinC')&& isfield(PlotParam.Vectors,'MaxC')
5636        MinC=PlotParam.Vectors.MinC;
5637        MaxC=PlotParam.Vectors.MaxC;
5638        set(handles.num_MinVec,'String', num2str(MinC,3));
5639        set(handles.num_MaxVec,'String',num2str(MaxC,3));
5640        list=get(handles.ColorCode,'String');
5641        ichoice=get(handles.ColorCode,'Value');
5642        color_option=list{ichoice};
5643        test3color=strcmp(color_option,'rgb')||strcmp(color_option,'bgr');
5644        if test3color% need to update color thresholds
5645            set(handles.num_ColCode1,'Visible','on')
5646            set(handles.num_ColCode2,'Visible','on')
5647            set(handles.Slider1,'Visible','on')
5648            set(handles.Slider2,'Visible','on')
5649            set(handles.num_ColCode1,'String',num2str(PlotParam.Vectors.ColCode1,3))
5650            set(handles.num_ColCode2,'String',num2str(PlotParam.Vectors.ColCode2,3))
5651            set(handles.Slider1,'Value',(PlotParam.Vectors.ColCode1-MinC)/(MaxC-MinC))
5652            set(handles.Slider2,'Value',(PlotParam.Vectors.ColCode2-MinC)/(MaxC-MinC))
5653        else
5654            set(handles.num_ColCode1,'Visible','off')
5655            set(handles.num_ColCode2,'Visible','off')
5656            set(handles.Slider1,'Visible','off')
5657            set(handles.Slider2,'Visible','off')
5658        end
5659    end
5660else
5661    set(handles.Vectors,'Visible','off')
5662    if isfield(handles,'edit_vect')
5663        set(handles.edit_vect,'Visible','off')
5664        set(handles.record,'Visible','off')
5665    end
5666end
5667
5668% --------------------------------------------------------------------
5669% --- Executes on button press in CheckTable.
5670% --------------------------------------------------------------------
5671function CheckTable_Callback(hObject, eventdata, handles)
5672if get(handles.CheckTable,'Value')
5673    set(handles.TableDisplay,'Visible','on')
5674else
5675    set(handles.TableDisplay,'Visible','off')
5676end
5677
5678
5679% --- Executes on selection change in SwitchCoordIndex.
5680function SwitchCoordIndex_Callback(hObject, eventdata, handles)
5681% hObject    handle to SwitchCoordIndex (see GCBO)
5682% eventdata  reserved - to be defined in a future version of MATLAB
5683% handles    structure with handles and user data (see GUIDATA)
5684
5685% Hints: contents = cellstr(get(hObject,'String')) returns SwitchCoordIndex contents as cell array
5686%        contents{get(hObject,'Value')} returns selected item from SwitchCoordIndex
Note: See TracBrowser for help on using the repository browser.