source: trunk/src/uvmat.m @ 688

Last change on this file since 688 was 688, checked in by sommeria, 11 years ago

bug correction on xml time reading
some cleaning of the GUI uvmat
improvement of option 'contours' in plot_field

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