source: trunk/src/uvmat.m @ 681

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

mouse action improved for translations, use of magenta color to indicate that REFRESH is needed

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