source: trunk/src/uvmat.m @ 809

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