source: trunk/src/series.m @ 494

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

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

File size: 92.8 KB
Line 
1%'series': master function associated to the GUI series.m for analysis field series 
2%------------------------------------------------------------------------
3% function varargout = series(varargin)
4% associated with the GUI series.fig
5%
6%INPUT
7% param: structure with input parameters (link with the GUI uvmat)
8%      .menu_coord_str: string for the TransformName (menu for coordinate transforms)
9%      .menu_coord_val: value for TransformName (menu for coordinate transforms)
10%      .FileName: input file name
11%      .FileName_1: second input file name
12%      .list_field: menu of input fields
13%      .index_fields: chosen index
14%      .civ1=0 or 1, .interp1,  ... : input civ field type
15%
16%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
17%  Copyright Joel Sommeria, 2008, LEGI / CNRS-UJF-INPG, sommeria@coriolis-legi.org.
18%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
19%     This file is part of the toolbox UVMAT.
20%
21%     UVMAT is free software; you can redistribute it and/or modify
22%     it under the terms of the GNU General Public License as published by
23%     the Free Software Foundation; either version 2 of the License, or
24%     (at your option) any later version.
25%
26%     UVMAT is distributed in the hope that it will be useful,
27%     but WITHOUT ANY WARRANTY; without even the implied warranty of
28%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29%     GNU General Public License (file UVMAT/COPYING.txt) for more details.
30%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
31
32%------------------------------------------------------------------------
33%------------------------------------------------------------------------
34%  I - MAIN FUNCTION series
35%------------------------------------------------------------------------
36%------------------------------------------------------------------------
37function varargout = series(varargin)
38
39% Begin initialization code - DO NOT EDIT
40gui_Singleton = 1;
41gui_State = struct('gui_Name',       mfilename, ...
42                   'gui_Singleton',  gui_Singleton, ...
43                   'gui_OpeningFcn', @series_OpeningFcn, ...
44                   'gui_OutputFcn',  @series_OutputFcn, ...
45                   'gui_LayoutFcn',  [] , ...
46                   'gui_Callback',   []);
47if nargin && ischar(varargin{1})
48    gui_State.gui_Callback = str2func(varargin{1});
49end
50
51if nargout
52    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
53else
54    gui_mainfcn(gui_State, varargin{:});
55end
56% End initialization code - DO NOT EDIT
57
58%--------------------------------------------------------------------------
59% --- Executes just before series is made visible.
60%--------------------------------------------------------------------------
61function series_OpeningFcn(hObject, eventdata, handles,param)
62global nb_builtin_ACTION nb_builtin_transform
63% Choose default command line output for series
64handles.output = hObject;
65% Update handles structure
66guidata(hObject, handles);
67%default initial parameters
68drawnow
69set(hObject,'Units','pixels')
70set(handles.PairString,'ColumnEditable',logical(0))
71set(handles.PairString,'ColumnFormat',{'char'})
72set(handles.PairString,'ColumnWidth',{60})
73set(handles.PairString,'Data',{''})
74set(hObject,'WindowButtonDownFcn',{'mouse_down'})%allows mouse action with right button (zoom for uicontrol display)
75dir_perso=prefdir;
76test_profil_perso=0;
77profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
78if exist(profil_perso,'file')
79     h=load (profil_perso);
80     if isfield(h,'MenuFile')
81          for ifile=1:min(length(h.MenuFile),5)
82              eval(['set(handles.MenuFile_' num2str(ifile) ',''Label'',h.MenuFile{ifile});'])
83          end
84     end
85     test_profil_perso=1;
86end
87
88%check default input data
89if ~exist('param','var')
90    param=[]; %default
91end
92
93%% file name and browser initialisation
94if isfield(param,'menu_coord_str')
95    set(handles.TransformName,'String',param.menu_coord_str)
96end
97if isfield(param,'menu_coord_val')
98    set(handles.TransformName,'Value',param.menu_coord_val);
99else
100     set(handles.TransformName,'Value',1);%default
101end
102if isfield(param,'FileName')
103    InputTable={'','','','',''};
104    set(handles.InputTable,'Data',InputTable)
105    if isfield(param,'FileName_1')
106        display_file_name(handles,param.FileName_1,0)
107        display_file_name(handles,param.FileName,1)
108    else
109        display_file_name(handles,param.FileName,0)
110    end
111end 
112
113%% fields input initialisation
114if isfield(param,'list_fields')&& isfield(param,'index_fields') &&~isempty(param.list_fields) &&~isempty(param.index_fields)
115    set(handles.FieldName,'String',param.list_fields);% list menu fields
116    set(handles.FieldName,'Value',param.index_fields);% selected string index
117%     FieldCell{1}=param.list_fields{param.index_fields};
118end
119
120%loads the information stored in prefdir to initiate  the list of ActionName functions
121fct_menu={'check_data_files';'aver_stat';'time_series';'merge_proj';'clean_civ_cmx'};
122transform_menu={'';'phys';'px';'phys_polar'};
123nb_builtin_ACTION=numel(fct_menu); %number of functions
124nb_transform=numel(transform_menu);
125[path_series,name,ext]=fileparts(which('series'));
126path_series=fullfile(path_series,'series');%path of the function 'series'
127addpath (path_series) ; %add the path to UVMAT, (useful in case of change of working directory after civ has been s opened in the working directory)
128path_transform=fullfile(path_series,'transform_field');%path to the field transform functions
129for ilist=1:length(fct_menu)
130    fct_path{ilist,1}=path_series;%paths of the fuctions buil-in in 'series.m'
131end
132
133%% TRANSFORM menu: loads the information stored in prefdir to initiate  the list of field transform functions
134menu_str={'';'phys';'px';'phys_polar'};
135nb_builtin_transform=numel(menu_str); %number of functions
136[path_uvmat,name,ext]=fileparts(which('uvmat'));
137addpath(fullfile(path_uvmat,'transform_field'))
138fct_handle{1,1}=[];
139testexist(1)=1;
140for ilist=2:length(menu_str)
141    if exist(menu_str{ilist},'file')
142        fct_handle{ilist,1}=str2func(menu_str{ilist});
143        testexist(ilist)=1;
144    else
145        testexist(ilist)=0;
146    end
147end
148rmpath(fullfile(path_uvmat,'transform_field'))
149
150%% read the list of functions stored in the personal file 'uvmat_perso.mat' in prefdir
151if test_profil_perso
152    if isfield(h,'series_fct') && iscell(h.series_fct)
153         for ilist=1:length(h.series_fct)
154             [path,file]=fileparts(h.series_fct{ilist});
155             fct_path=[fct_path; {path}];%concatene the list of paths
156             fct_menu=[fct_menu; {file}];
157         end
158    end
159    if isfield(h,'transform_fct') && iscell(h.transform_fct)
160        for ilist=1:length(h.transform_fct);
161             [path,file]=fileparts(h.transform_fct{ilist});
162             addpath(path)
163             if exist(file,'file')
164                h_func=str2func(file);
165                testexist=[testexist 1];
166             else
167                h_func=[];
168                testexist=[testexist 0];
169             end
170             fct_handle=[fct_handle; {h_func}];%concatene the list of paths
171             rmpath(path)
172             menu_str=[menu_str; {file}];
173        end
174    end
175end
176fct_menu=[fct_menu;{'more...'}];
177set(handles.ActionName,'String',fct_menu)
178set(handles.ActionName,'UserData',fct_path)% store the list of path in UserData of ACTION
179menu_str=menu_str(find(testexist));
180fct_handle=fct_handle(find(testexist));
181menu_str=[menu_str;{'more...'}];
182set(handles.TransformName,'String',menu_str)
183set(handles.TransformName,'UserData',fct_handle)% store the list of path in UserData of ACTION
184
185%% Adjust the GUI according to the binaries available in PARAM.xml
186path_uvmat=fileparts(which('uvmat')); %path to civ
187addpath (path_uvmat) ; %add the path to civ, (useful in case of change of working directory after civ has been s opened in the working directory)
188errormsg=[];%default error message
189xmlfile='PARAM.xml';
190if exist(xmlfile,'file')
191    try
192        t=xmltree(xmlfile);
193        sparam=convert(t);
194    catch ME
195        errormsg={' Unable to read the file PARAM.xml defining the civx binaries:';ME.message};
196    end
197else
198    errormsg=[xmlfile ' not found: path to civx binaries undefined'];
199end
200if ~isempty(errormsg)
201    msgbox_uvmat('WARNING',errormsg);
202end
203test_batch=0;%default: ,no batch mode available
204if isfield(sparam,'BatchParam') && isfield(sparam.BatchParam,'BatchMode')
205    test_batch=strcmp(sparam.BatchParam.BatchMode,'sge'); %sge is currently the only implemented batch mod
206end
207RUNVal=get(handles.RunMode,'Value');
208if test_batch==0
209   if RUNVal>2
210       set(handles.RunMode,'Value',1)
211   end
212   set(handles.RunMode,'String',{'local';'background'})
213else
214    set(handles.RunMode,'String',{'local';'background';'cluster'})
215end
216% if isfield(sparam.RunParam,'CivBin')
217%     if ~exist(sparam.RunParam.CivBin,'file')
218%         sparam.RunParam.CivBin=fullfile(path_uvmat,sparam.RunParam.CivBin);
219%     end
220% else
221%     sparam.RunParam.CivBin='';
222% end
223% display the GUI for the default actionname 'check_data_files'
224% ActionName_Callback(hObject, eventdata, handles)
225
226%------------------------------------------------------------------------
227% --- Outputs from this function are returned to the command line.
228function varargout = series_OutputFcn(hObject, eventdata, handles)
229%------------------------------------------------------------------------
230% varargout  cell array for returning output args (see VARARGOUT);
231% hObject    handle to figure
232% eventdata  reserved - to be defined in a future version of MATLAB
233% handles    structure with handles and user data (see GUIDATA)
234% Get default command line output from handles structure
235varargout{1} = handles.output;
236
237%------------------------------------------------------------------------
238%------------------------------------------------------------------------
239%  II - FUNCTIONS FOR INTRODUCING THE INPUT FILES
240% automatically sets the global properties when the rootfile name is introduced
241% then activate the view-field actionname if selected
242% it is activated either by clicking on the RootPath window or by the
243% browser
244%------------------------------------------------------------------------
245%------------------------------------------------------------------------
246function MenuBrowse_Callback(hObject, eventdata, handles)
247%------------------------------------------------------------------------   
248InputTable=get(handles.InputTable,'Data');
249if isempty(InputTable)
250    RootPathCell={};
251else
252    RootPathCell=InputTable(:,1);
253end
254oldfile=''; %default
255if isempty(RootPathCell)||isequal(RootPathCell,{''})%loads the previously stored file name and set it as default in the file_input box
256     dir_perso=prefdir;
257     profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
258     if exist(profil_perso,'file')
259          h=load (profil_perso);
260         if isfield(h,'filebase')&&ischar(h.filebase)
261                 oldfile=h.filebase;
262         end
263         if isfield(h,'RootPath')&&ischar(h.RootPath)
264                 oldfile=h.RootPath;
265         end
266     end
267else
268     SubDirCell=InputTable(:,2);
269    RootFileCell=InputTable(:,3);
270     oldfile=fullfile(RootPathCell{1},SubDirCell{1},RootFileCell{1});
271 end
272[FileName, PathName, filterindex] = uigetfile( ...
273       {'*.xml;*.xls;*.png;*.tif;*.avi;*.AVI;*.nc', ' (*.xml,*.xls, *.png,*.tif, *.avi,*.nc)';
274       '*.xml',  '.xml files '; ...
275        '*.xls',  '.xls files '; ...
276        '*.png','.png image files'; ...
277        '*.tif','.tif image files'; ...
278        '*.avi;*.AVI','.avi movie files'; ...
279        '*.nc','.netcdf files'; ...
280        '*.*',  'All Files (*.*)'}, ...
281        'Pick a file',oldfile);
282fileinput=[PathName FileName];%complete file name
283if isempty(fileinput),return;end %abandon if no file is introduced by the browser
284[path,name,ext]=fileparts(fileinput);
285if isequal(ext,'.xml')
286    [Param,Heading]=xml2struct(fileinput);
287    if ~strcmp(Heading,'Series')
288        msg_box_uvmat('ERROR','xml file heading is not <Series>')
289    else
290        fill_GUI(Param,handles);%fill the GUI with the parameters retrieved from the xml file
291        if isfield(Param,'CheckObject')&& Param.CheckObject
292            set_object(Param.ProjObject)
293        end
294        set(handles.REFRESH,'UserData',[1:size(Param.InputTable,1)])
295        REFRESH_Callback([],[], handles)
296        return
297    end
298elseif isequal(ext,'.xls')
299    msg_box_uvmat('ERROR','input file type not implemented')%A Faire: ouvrir le fichier pour naviguer
300else
301    display_file_name(handles,fileinput,0)
302end
303
304% --------------------------------------------------------------------
305function MenuFile_1_Callback(hObject, eventdata, handles)
306fileinput=get(handles.MenuFile_1,'Label');
307display_file_name(handles,fileinput,0)
308
309% --------------------------------------------------------------------
310function MenuFile_2_Callback(hObject, eventdata, handles)
311fileinput=get(handles.MenuFile_2,'Label');
312display_file_name(handles,fileinput,0)
313
314% --------------------------------------------------------------------
315function MenuFile_3_Callback(hObject, eventdata, handles)
316fileinput=get(handles.MenuFile_3,'Label');
317display_file_name( handles,fileinput,0)
318
319% --------------------------------------------------------------------
320function MenuFile_4_Callback(hObject, eventdata, handles)
321fileinput=get(handles.MenuFile_4,'Label');
322display_file_name(handles,fileinput,0)
323
324% --------------------------------------------------------------------
325function MenuFile_5_Callback(hObject, eventdata, handles)
326fileinput=get(handles.MenuFile_5,'Label');
327display_file_name(handles,fileinput,0)
328
329% --------------------------------------------------------------------
330function MenuBrowse_insert_Callback(hObject, eventdata, handles)
331InputTable=get(handles.InputTable,'Data');
332RootPathCell=InputTable(:,1);
333SubDirCell=InputTable(:,3);
334RootFileCell=InputTable(:,2);
335oldfile=''; %default
336if isempty(RootPathCell)||isequal(RootPathCell,{''})%loads the previously stored file name and set it as default in the file_input box
337     dir_perso=prefdir;
338     profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
339     if exist(profil_perso,'file')
340          h=load (profil_perso);
341         if isfield(h,'filebase')&ischar(h.filebase)
342                 oldfile=h.filebase;
343         end
344         if isfield(h,'RootPath')&ischar(h.RootPath)
345                 oldfile=h.RootPath;
346         end
347     end
348 else
349     oldfile=fullfile(RootPathCell{1},RootFileCell{1});
350 end
351[FileName, PathName, filterindex] = uigetfile( ...
352       {'*.xml;*.xls;*.png;*.avi;*.AVI;*.nc', ' (*.xml,*.xls, *.png, *.avi,*.nc)';
353       '*.xml',  '.xml files '; ...
354        '*.xls',  '.xls files '; ...
355        '*.png','.png image files'; ...
356        '*.avi;*.AVI','.avi movie files'; ...
357        '*.nc','.netcdf files'; ...
358        '*.*',  'All Files (*.*)'}, ...
359        'Pick a file',oldfile);
360fileinput=[PathName FileName];%complete file name
361sizf=size(fileinput);
362if (~ischar(fileinput)|~isequal(sizf(1),1)),return;end
363[path,name,ext]=fileparts(fileinput);
364if isequal(ext,'.xml')
365    msgbox_uvmat('ERROR','input file type not implemented')%A Faire: ouvrir le fichier pour naviguer
366elseif isequal(ext,'.xls')
367    msgbox_uvmat('ERROR','input file type not implemented')%A Faire: ouvrir le fichier pour naviguer
368else
369    display_file_name(handles,fileinput,'append')
370end
371
372% --------------------------------------------------------------------
373function MenuFile_insert_1_Callback(hObject, eventdata, handles)
374% --------------------------------------------------------------------   
375fileinput=get(handles.MenuFile_insert_1,'Label');
376display_file_name(handles,fileinput,'append')
377
378% --------------------------------------------------------------------
379function MenuFile_insert_2_Callback(hObject, eventdata, handles)
380% --------------------------------------------------------------------   
381fileinput=get(handles.MenuFile_insert_2,'Label');
382display_file_name(handles,fileinput,'append')
383
384% --------------------------------------------------------------------
385function MenuFile_insert_3_Callback(hObject, eventdata, handles)
386% --------------------------------------------------------------------   
387fileinput=get(handles.MenuFile_insert_3,'Label');
388display_file_name( handles,fileinput,'append')
389
390% --------------------------------------------------------------------
391function MenuFile_insert_4_Callback(hObject, eventdata, handles)
392% --------------------------------------------------------------------   
393fileinput=get(handles.MenuFile_insert_4,'Label');
394display_file_name( handles,fileinput,'append')
395
396% --------------------------------------------------------------------
397function MenuFile_insert_5_Callback(hObject, eventdata, handles)
398% --------------------------------------------------------------------   
399fileinput=get(handles.MenuFile_insert_5,'Label');
400display_file_name(handles,fileinput,'append')
401
402%------------------------------------------------------------------------
403% --- Executes when entered data in editable cell(s) in InputTable.
404function InputTable_CellEditCallback(hObject, eventdata, handles)
405%------------------------------------------------------------------------
406set(handles.REFRESH,'Visible','on')
407iview=eventdata.Indices(1);
408view_set=get(handles.REFRESH,'UserData');
409if isempty(find(view_set==iview))
410    set(handles.REFRESH,'UserData',[view_set iview])
411end
412%% enable other menus and uicontrols
413set(handles.MenuOpen_insert,'Enable','on')
414set(handles.MenuFile_insert_1,'Enable','on')
415set(handles.MenuFile_insert_2,'Enable','on')
416set(handles.MenuFile_insert_3,'Enable','on')
417set(handles.MenuFile_insert_4,'Enable','on')
418set(handles.MenuFile_insert_5,'Enable','on')
419set(handles.RUN, 'Enable','On')
420set(handles.RUN,'BackgroundColor',[1 0 0])% set RUN button to red
421
422%update the output dir
423% SubDir=sort(InputTable(:,2)); %set of subdirectories sorted in alphabetical order
424% SubDirOut=SubDir{1};
425% if numel(SubDir)>1
426%     for ilist=2:numel(SubDir)
427%         SubDirOut=[SubDirOut '-' SubDir{ilist}];
428%     end
429% end
430% set(handles.OutputSubDir,'String',SubDirOut)
431
432%------------------------------------------------------------------------
433% --- Executes on button press in REFRESH.
434function REFRESH_Callback(hObject, eventdata, handles)
435%------------------------------------------------------------------------
436InputTable=get(handles.InputTable,'Data');
437view_set=get(handles.REFRESH,'UserData');
438set(handles.REFRESH,'BackgroundColor',[0.7 0.7 0.7])% set REFRESH  button to grey color
439drawnow
440for iview=view_set
441    RootPath=fullfile(InputTable{iview,1},InputTable{iview,2});
442    if ~exist(RootPath,'dir')
443        i1_series=[];
444        RootPath=fileparts(RootPath); %will try the upped forldr
445    else
446        [RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,tild,FileType,MovieObject]=...
447            find_file_series(fullfile(InputTable{iview,1},InputTable{iview,2}),[InputTable{iview,3} InputTable{iview,4} InputTable{iview,5}]);
448    end
449    if isempty(i1_series)
450        [FileName, PathName, filterindex] = uigetfile( ...
451            {'*.xml;*.xls;*.png;*.tif;*.avi;*.AVI;*.nc', ' (*.xml,*.xls, *.png,*.tif, *.avi,*.nc)';
452            '*.xml',  '.xml files '; ...
453            '*.xls',  '.xls files '; ...
454            '*.png','.png image files'; ...
455            '*.tif','.tif image files'; ...
456            '*.avi;*.AVI','.avi movie files'; ...
457            '*.nc','.netcdf files'; ...
458            '*.*',  'All Files (*.*)'}, ...
459            ['unvalid entry at line ' num2str(iview) ', pick a file'],RootPath);
460        fileinput=[PathName FileName];%complete file name
461        if isempty(fileinput),return;end %abandon if the operation has been cancelled: no input from browser
462        [path,name,ext]=fileparts(fileinput);
463        display_file_name(handles,fileinput,iview)
464    else
465        update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,MovieObject,iview)
466    end
467end
468set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to grey color
469set(handles.REFRESH,'Visible','off')
470set(handles.REFRESH,'UserData',[])
471
472%------------------------------------------------------------------------
473% --- Function called when a new file is opened, either by series_OpeningFcn or by the browser
474function display_file_name(handles,fileinput,iview)
475%------------------------------------------------------------------------ 
476%
477% INPUT:
478% handles: handles of elements in the GUI
479% fielinput: input file name, including path
480% append =0 (refresh the Input table with the new file), ='append' append a new line in the table
481
482%% get the input root name, indices, file extension and nomenclature NomType
483if ~exist(fileinput,'file')
484    msgbox_uvmat('ERROR',['input file ' fileinput  ' does not exist'])
485    return
486end
487
488%% enable other menus and uicontrols
489set(handles.MenuOpen_insert,'Enable','on')
490set(handles.MenuFile_insert_1,'Enable','on')
491set(handles.MenuFile_insert_2,'Enable','on')
492set(handles.MenuFile_insert_3,'Enable','on')
493set(handles.MenuFile_insert_4,'Enable','on')
494set(handles.MenuFile_insert_5,'Enable','on')
495set(handles.RUN, 'Enable','On')
496set(handles.RUN,'BackgroundColor',[1 0 0])% set RUN button to red
497set(handles.InputTable,'BackgroundColor',[1 1 0]) % set RootPath edit box  to yellow
498drawnow
499
500%% detect root name, nomenclature and indices in the input file name:
501[FilePath,FileName,FileExt]=fileparts(fileinput);
502% detect the file type, get the movie object if relevant, and look for the corresponding file series:
503% the root name and indices may be corrected by including the first index i1 if a corresponding xml file exists
504[RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,NomType,FileType,MovieObject,i1,i2,j1,j2]=find_file_series(FilePath,[FileName FileExt]);
505if isempty(RootFile)&&isempty(i1_series)
506    errormsg='no input file in the series';
507    return
508end
509
510%% fill the list of file series
511InputTable=get(handles.InputTable,'Data');
512if strcmp(iview,'append') % display the input data as a new line in the table
513     iview=size(InputTable,1);
514     InputTable(iview+1,:)={'','','','',''};
515     InputTable(iview,:)=[{RootPath},{SubDir},{RootFile},{NomType},{FileExt}];
516elseif iview==0 % or re-initialise the list of  input  file series
517    iview=1;
518    InputTable=[{'','','','',''};{'','','','',''}];
519     InputTable(iview,:)=[{RootPath},{SubDir},{RootFile},{NomType},{FileExt}];
520    set(handles.TimeTable,'Data',[{[]},{[]},{[]},{[]}])
521    set(handles.MinIndex,'Data',[{[]},{[]}])
522    set(handles.MaxIndex,'Data',[{[]},{[]}])
523    set(handles.ListView,'Value',1)
524    set(handles.ListView,'String',{'1'})
525end
526nbview=size(InputTable,1);
527set(handles.ListView,'String',mat2cell((1:nbview)',ones(nbview,1)))
528set(handles.ListView,'Value',iview)
529set(handles.InputTable,'Data',InputTable)
530
531%% determine the selected reference field indices for pair display
532ref_i=1; %default ref_i is a reference frame index used to find existing pairs from PIV
533if ~isempty(i1)
534    ref_i=i1;
535    if ~isempty(i2)
536        ref_i=floor((ref_i+i2)/2);% reference image number corresponding to the file
537    end
538end
539set(handles.num_ref_i,'String',num2str(ref_i));
540ref_j=1; %default  ref_j is a reference frame index used to find existing pairs from PIV
541if ~isempty(j1)
542    ref_j=j1;
543    if ~isempty(j2)
544        ref_j=floor((j1+j2)/2);
545    end         
546end
547set(handles.num_ref_j,'String',num2str(ref_j));
548
549%% update the list of recent files in the menubar and save it for future opening
550MenuFile=[{get(handles.MenuFile_1,'Label')};{get(handles.MenuFile_2,'Label')};...
551    {get(handles.MenuFile_3,'Label')};{get(handles.MenuFile_4,'Label')};{get(handles.MenuFile_5,'Label')}];
552str_find=strcmp(fileinput,MenuFile);
553if isempty(find(str_find,1))
554    MenuFile=[{fileinput};MenuFile];%insert the current file if not already in the list
555end
556for ifile=1:min(length(MenuFile),5)
557    eval(['set(handles.MenuFile_' num2str(ifile) ',''Label'',MenuFile{ifile});'])
558    eval(['set(handles.MenuFile_insert_' num2str(ifile) ',''Label'',MenuFile{ifile});'])
559end
560dir_perso=prefdir;
561profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
562if exist(profil_perso,'file')
563    save (profil_perso,'MenuFile','-append'); %store the file names for future opening of uvmat
564else
565    save (profil_perso,'MenuFile','-V6'); %store the file names for future opening of uvmat
566end
567
568set(handles.InputTable,'BackgroundColor',[1 1 1])
569
570%% initiate input file series and refresh the current field view:     
571update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,MovieObject,iview);
572
573%------------------------------------------------------------------------
574% --- Update information about a new field series (indices to scan, timing,
575%     calibration from an xml file
576function update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,VideoObject,iview)
577%------------------------------------------------------------------------
578%% update the output dir
579InputTable=get(handles.InputTable,'Data');
580SubDir=sort(InputTable(1:end-1,2)); %set of subdirectories sorted in alphabetical order
581SubDirOut=SubDir{1};
582if numel(SubDir)>1
583    for ilist=2:numel(SubDir)
584        SubDirOut=[SubDirOut '-' SubDir{ilist}];
585    end
586end
587set(handles.OutputSubDir,'String',SubDirOut)
588
589%% display the min and max indices for all the file series
590i_sum=sum(sum(i1_series,2),3);%sum of i1_series on the last index
591MaxIndex_i=max(find(i_sum>0))-1;% max ref index i
592MinIndex_i=min(find(i_sum>0))-1;% min ref index i
593i2_min=[];
594if ~isempty(i2_series)
595    i2_min=i2_series(1,2);
596end
597j1_min=[];
598if ~isempty(j1_series)
599    j1_min=j1_series(1,2);
600end
601j2_min=[];
602if ~isempty(j2_series)
603    j2_min=j2_series(1,2);
604end
605if isequal(MinIndex_i,1) &&...
606        exist (fullfile_uvmat(InputTable{iview,1},InputTable{iview,2},InputTable{iview,3},InputTable{iview,5},InputTable{iview,4},0,i2_min, j1_min,j2_min),'file')
607    MinIndex_i=0;
608end
609j_sum=sum(sum(j1_series,1),3);
610MaxIndex_j=max(find(j_sum>0))-1;
611MinIndex_j=min(find(j_sum>0))-1;
612MinIndex=get(handles.MinIndex,'Data');%retrieve the min indices in the table MinIndex
613MaxIndex=get(handles.MaxIndex,'Data');%retrieve the max indices in the table MaxIndex
614MinIndex{iview,1}=MinIndex_i;
615MinIndex{iview,2}=MinIndex_j;
616MaxIndex{iview,1}=MaxIndex_i;
617MaxIndex{iview,2}=MaxIndex_j;
618
619set(handles.MinIndex,'Data',MinIndex)%display the min indices in the table MinIndex
620set(handles.MaxIndex,'Data',MaxIndex)%display the max indices in the table MaxIndex
621
622%% adjust the first and last indices if requested by the bounds
623first_i=str2num(get(handles.num_first_i,'String'));
624ref_i=str2num(get(handles.num_ref_i,'String'));
625ref_j=str2num(get(handles.num_ref_j,'String'));
626if isempty(first_i)
627    first_i=ref_i;
628elseif first_i < MinIndex_i
629    first_i=MinIndex_i;
630end
631first_j=str2num(get(handles.num_first_j,'String'));
632if isempty(first_j)
633    first_j=ref_j;
634elseif first_j<MinIndex_j
635    first_j=MinIndex_j;
636end
637last_i=str2num(get(handles.num_last_i,'String'));
638if isempty(last_i)
639    last_i=ref_i;
640elseif last_i > MaxIndex_i
641    last_i=MaxIndex_i;
642end
643last_j=str2num(get(handles.num_first_j,'String'));
644if isempty(last_j)
645    last_j=ref_j;
646elseif last_j>MaxIndex_j
647    last_j=MaxIndex_j;
648end
649set(handles.num_first_i,'String',num2str(first_i));
650set(handles.num_first_j,'String',num2str(first_j));
651set(handles.num_last_i,'String',num2str(last_i));
652set(handles.num_last_j,'String',num2str(last_j));
653
654%% read timing and total frame number from the current file (movie files) !! may be overrid by xml file
655InputTable=get(handles.InputTable,'Data');
656FileBase=fullfile(InputTable{iview,1},InputTable{iview,3});
657time=[];%default
658% case of movies
659if strcmp(InputTable{iview,4},'*')
660    if ~isempty(VideoObject)
661        imainfo=get(VideoObject);
662        time=(0:1/imainfo.FrameRate:(imainfo.NumberOfFrames-1)/imainfo.FrameRate)';
663        set(handles.Dt_txt,'String',['Dt=' num2str(1000/imainfo.FrameRate) 'ms']);%display the elementary time interval in millisec
664        ColorType='truecolor';
665    elseif ~isempty(imformats(regexprep(InputTable{iview,5},'^.',''))) || isequal(InputTable{iview,5},'.vol')%&& isequal(NomType,'*')% multi-frame image
666        if ~isempty(InputTable{iview,2})
667            imainfo=imfinfo(fullfile(InputTable{iview,1},InputTable{iview,2},[InputTable{iview,3} InputTable{iview,5}]));
668        else
669            imainfo=imfinfo([FileBase InputTable{iview,5}]);
670        end
671        ColorType=imainfo.ColorType;%='truecolor' for color images
672        if length(imainfo) >1 %case of image with multiple frames
673            nbfield=length(imainfo);
674            nbfield_j=1;
675        end
676    end
677end
678
679%%  read image documentation file  if found%%%%%%%%%%%%%%%%%%%%%%%%%%%
680ext_imadoc='';
681if exist([FileBase '.xml'],'file')
682    ext_imadoc='.xml';
683elseif exist([FileBase '.civ'],'file')
684    ext_imadoc='.civ';
685end
686%read the ImaDoc file
687XmlData=[];
688NbSlice_calib={};
689if isequal(ext_imadoc,'.xml')
690        [XmlData,warntext]=imadoc2struct([FileBase '.xml']);
691        if isfield(XmlData,'Heading') && isfield(XmlData.Heading,'ImageName') && ischar(XmlData.Heading.ImageName)
692            [PP,FF,ext_ima_read]=fileparts(XmlData.Heading.ImageName);
693        end
694        if isfield(XmlData,'Time')
695            time=XmlData.Time;
696        end
697        if isfield(XmlData,'Camera')
698            if isfield(XmlData.Camera,'NbSlice')&& ~isempty(XmlData.Camera.NbSlice)
699                NbSlice_calib{iview}=XmlData.Camera.NbSlice;% Nbre of slices for Zindex in phys transform
700                if ~isequal(NbSlice_calib{iview},NbSlice_calib{1})
701                    msgbox_uvmat('WARNING','inconsistent number of Z indices for the two field series');
702                end
703            end
704            if isfield(XmlData.Camera,'TimeUnit')&& ~isempty(XmlData.Camera.TimeUnit)
705                TimeUnit=XmlData.Camera.TimeUnit;
706            end
707        end
708        if ~isempty(warntext)
709            msgbox_uvmat('WARNING',warntext)
710        end 
711elseif isequal(ext_imadoc,'.civ')
712    [error,XmlData.Time,TimeUnit,mode,npx,npy,pxcmx,pxcmy]=read_imatext([FileBase '.civ']);
713    time=XmlData.Time;
714    if error==2, warntext=['no file ' FileBase '.civ'];
715    elseif error==1, warntext='inconsistent number of fields in the .civ file';
716    end 
717end
718
719%% update time table
720if ~isempty(time)
721TimeTable=get(handles.TimeTable,'Data');
722first_i=str2num(get(handles.num_first_i,'String'));
723last_i=str2num(get(handles.num_last_i,'String'));
724first_j=str2num(get(handles.num_first_j,'String'));
725last_j=str2num(get(handles.num_last_j,'String'));
726MinIndexTable=get(handles.MinIndex,'Data');
727MinIndex_i=MinIndexTable{iview,1};
728MinIndex_j=MinIndexTable{iview,2};
729MaxIndexTable=get(handles.MaxIndex,'Data');
730MaxIndex_i=MaxIndexTable{iview,1};
731MaxIndex_j=MaxIndexTable{iview,2};
732if isempty(MinIndex_j)
733    if MinIndex_i>0
734    TimeTable{iview,1}=time(MinIndex_i);
735    end
736    TimeTable{iview,2}=time(first_i);
737    TimeTable{iview,3}=time(last_i);
738    TimeTable{iview,4}=time(MaxIndex_i);
739elseif ~isempty(time)
740    if MinIndex_i>0
741    TimeTable{iview,1}=time(MinIndex_i,MinIndex_j);
742    end
743    TimeTable{iview,2}=time(first_i,first_j);
744    TimeTable{iview,3}=time(last_i,last_j);
745    TimeTable{iview,4}=time(MaxIndex_i,MaxIndex_j);
746end
747set(handles.TimeTable,'Data',TimeTable)
748end
749
750%% number of slices
751NbSlice=1;%default
752if isfield(XmlData,'GeometryCalib') && isfield(XmlData.GeometryCalib,'SliceCoord')
753    siz=size(XmlData.GeometryCalib.SliceCoord);
754    if siz(1)>1
755        NbSlice=siz(1);
756    end
757end
758set(handles.num_NbSlice,'String',num2str(NbSlice))
759   
760%% update pair menus
761set(handles.Pairs,'Visible','on')
762set(handles.PairString,'Visible','on')
763ListView=get(handles.ListView,'String');
764ListView{iview}=num2str(iview);
765set(handles.ListView,'String',ListView);
766set(handles.ListView,'Value',iview)
767update_mode(handles,i1_series,i2_series,j1_series,j2_series,time)
768
769%% update the series info in 'UserData'
770SeriesData=get(handles.series,'UserData');
771SeriesData.i1_series{iview}=i1_series;
772SeriesData.i2_series{iview}=i2_series;
773SeriesData.j1_series{iview}=j1_series;
774SeriesData.j2_series{iview}=j2_series;
775SeriesData.FileType{iview}=FileType;
776SeriesData.Time{iview}=time;
777set(handles.series,'UserData',SeriesData)
778
779%% enable j index visibility
780state='off';
781check_jindex=~cellfun(@isempty,SeriesData.j1_series); %look for non empty j indices
782if isempty(find(check_jindex))
783    enable_j(handles,'off') % no j index needed
784else
785    enable_j(handles,'on')
786end
787
788%% display the set of existing files as an image
789set(handles.FileStatus,'Units','pixels')
790Position=get(handles.FileStatus,'Position');
791set(handles.FileStatus,'Units','normalized')
792xI=0.5:Position(3)-0.5;
793nbview=numel(SeriesData.i1_series);
794for iview=1:nbview
795    index_min(iview)=min(find(SeriesData.i1_series{iview}(2:end,2:end,1)>0));
796    index_max(iview)=max(find(SeriesData.i1_series{iview}(2:end,2:end,1)>0));
797end
798index_min=min(index_min);
799index_max=max(index_max);
800range_index=index_max-index_min+1;
801scale_y=Position(4)/nbview;
802scale_x=Position(3)/range_index;
803x=(0.5:range_index-0.5)*Position(3)/range_index;
804% y=(0.5:nbview-0.5)*Position(4)/nbview;
805range_y=max(1,floor(Position(4)/nbview));
806CData=zeros(nbview*range_y,Position(3));
807for iview=1:nbview
808    ind_y=1+(iview-1)*range_y:iview*range_y;
809    LineData=zeros(1,range_index);
810    x_index=find(SeriesData.i1_series{iview}(2:end,2:end,1)>0)-index_min+1;
811    LineData(x_index)=1;
812    LineData=interp1(x,LineData,xI,'nearest');
813    CData(ind_y,:)=ones(size(ind_y'))*LineData;
814end
815CData=cat(3,zeros(size(CData)),CData,zeros(size(CData)));
816set(handles.FileStatus,'CData',CData);
817
818%
819%
820% xima=0.5:pos(3)-0.5;% pixel positions on the image representing the existing file indices
821% yima=0.5:pos(4)-0.5;
822% [XIma,YIma]=meshgrid(xima,yima);
823% nb_i=size(i1_series,1);
824% nb_j=size(i1_series,2);
825% ind_i=(0.5:nb_i-0.5)*pos(3)/nb_i;
826% ind_j=(0.5:nb_j-0.5)*pos(4)/nb_j;
827% [Ind_i,Ind_j]=meshgrid(ind_i,ind_j);
828% CData=zeros([size(XIma) 3]);%black color
829% file_ima=double((i1_series(:,:,1)>0)');
830% if numel(file_ima)>=2
831% if size(file_ima,1)==1
832%     CLine=interp1(ind_i,file_ima,xima,'nearest');
833%     CData(:,:,2)=ones(size(yima'))*CLine;
834% else
835%     CData(:,:,2)=interp2(Ind_i,Ind_j,file_ima,XIma,YIma,'nearest');
836% end
837% set(handles.FileStatus,'CData',CData)
838% end
839% set(handles.FileStatus,'Units','normalized')
840
841
842%% enable field and veltype menus, in accordance with the current action
843ActionName_Callback([],[], handles)
844
845%% check for pair display
846check_pairs=0;
847for iview=1:numel(SeriesData.i2_series)
848    if ~isempty(SeriesData.i2_series{iview})||~isempty(SeriesData.j2_series{iview})
849        check_pairs=1;
850    end
851end
852if check_pairs
853    set(handles.Pairs,'Visible','on')
854    set(handles.PairString,'Visible','on')
855else
856    set(handles.Pairs,'Visible','off')
857    set(handles.PairString,'Visible','off')
858end
859
860%% set length of waitbar
861displ_time(handles)
862
863
864% %% set default options in menu 'Fields'%% TODO: check VelType
865% if ~testima
866%     testcivx=0;
867%     if isfield(UvData,'FieldsString') && isequal(UvData.FieldsString,{'get_field...'})% field menu defined as input (from get_field)
868%         set(handles_Fields,'Value',1)
869%         set(handles_Fields,'String',{'get_field...'})
870%         UvData=rmfield(UvData,'FieldsString');
871%     else
872%         Data=nc2struct(FileName,'ListGlobalAttribute','Conventions','absolut_time_T0','civ');
873%         if strcmp(Data.Conventions,'uvmat/civdata') ||( ~isempty(Data.absolut_time_T0)&& ~isequal(Data.civ,0))%if the new input is Civx
874%             FieldList=calc_field;
875%             set(handles_Fields,'String',[{'image'};FieldList;{'get_field...'}]);%standard menu for civx data
876%             set(handles_Fields,'Value',2) % set menu to 'velocity'
877%             col_vec=FieldList;
878%             col_vec(1)=[];%remove 'velocity' option for vector color (must be a scalar)
879%             testcivx=1;
880%         end
881%         if ~testcivx
882%             set(handles_Fields,'Value',1) % set menu to 'get_field...
883%             set(handles_Fields,'String',{'get_field...'})
884%             col_vec={'get_field...'};
885%         end
886%         set(handles.ColorScalar,'String',col_vec)
887%     end
888% end
889% set(handles.uvmat,'UserData',UvData)
890%
891% %% set index navigation options and refresh plots
892% scan_option='i';%default
893% state_j='off'; %default
894% if index==2
895%     if get(handles.scan_j,'Value')
896%         scan_option='j'; %keep the scan option for the second fiel series
897%     end
898%     if strcmp(get(handles.j1,'Visible'),'on')
899%         state_j='on';
900%     end
901% end
902% if ~isempty(j1_series)
903%         state_j='on';
904%         if isequal(nbfield,1) &&index==1
905%             scan_option='j'; %scan j index by default if nbfield=1               
906%         end
907% end
908% if isequal(scan_option,'i')
909%      set(handles.scan_i,'Value',1)
910%      scan_i_Callback([],[], handles);
911% else
912%      set(handles.scan_j,'Value',1)
913%      scan_j_Callback([],[], handles);
914% end
915% set(handles.scan_j,'Visible',state_j)
916% set(handles.j1,'Visible',state_j)
917% set(handles.j2,'Visible',state_j)
918% set(handles.last_j,'Visible',state_j);
919% set(handles.frame_j,'Visible',state_j);
920% set(handles.j_text,'Visible',state_j);
921% if ~isempty(i2_series)||~isempty(j2_series)
922%     set(handles.CheckFixPair,'Visible','on')
923% elseif index==1
924%     set(handles.CheckFixPair,'Visible','off')
925% end
926%
927%
928% mode_Callback(hObject, eventdata, handles)
929%
930% set(handles.REFRESH,'BackgroundColor',[0.7 0.7 0.7])
931% InputTable=get(handles.InputTable,'Data');
932% check_lines=get(handles.REFRESH,'UserData');
933%
934% %% check the indices and FileTypes for each series (limited to the new ones to save time)
935% for ind_list=1:length(check_lines)
936%     if  check_lines(ind_list)
937%         InputLine=InputTable(ind_list,:);
938%         detect_idem=strcmp('"',InputLine);% look for '" (repeat of previous data)
939%         detect_idem=detect_idem(detect_idem>0);
940%         if ~isempty (detect_idem)
941%             InputLine(detect_idem)=InputTable(ind_list-1,detect_idem);
942%             set(handles.InputTable,'Data',InputTable)
943%         end
944%         fileinput=fullfile_uvmat(InputLine{1},InputLine{2},InputLine{3},InputLine{5},InputLine{4},1,2,1,2);
945%         %fileinput=name_generator(fullfile(InputLine{1},InputLine{3}),1,1,InputLine{5},InputLine{4},1,2,2,InputLine{2})
946%         %update file series defined by the selected line
947%         [InputTable{ind_list,3},InputTable{(ind_list),4},errormsg]=update_indices(handles,fileinput,ind_list);
948%         if ~isempty(errormsg)
949%                 msgbox_uvmat('ERROR',errormsg)
950%                 return
951%         end
952%     end
953% end
954% set(handles.InputTable,'Data',InputTable)
955% SeriesData=get(handles.series,'UserData');
956%
957% state_j='off';
958% state_Pairs='off';
959% state_InputFields='off';
960% val=get(handles.ListView,'Value');
961% ListViewString={''};
962% if ~isempty(SeriesData)
963% %     ListViewString={};
964%     for iview=1:size(InputTable,1)
965%         if ~isempty(SeriesData.j1_series{iview})
966%             state_j='on';
967%         end
968%         if ~isempty(SeriesData.i2_series{iview})||~isempty(SeriesData.j2_series{iview})
969%             state_Pairs='on';
970%             ListViewString{iview}=num2str(iview);
971%             if check_lines(iview)
972%                 val=iview;%select the last pair if it is a new entry
973%             end
974%         end
975%         if strcmp(SeriesData.FileType{iview},'civx')||strcmp(SeriesData.FileType{iview},'civdata')
976%             state_InputFields='on';
977%         end
978%     end
979% end
980% set(handles.ListView,'Value',val)
981% set(handles.ListView,'String',ListViewString)
982% if strcmp(state_Pairs,'on')
983%     ListView_Callback(hObject,eventdata,handles)
984% end
985% set(handles.PairString,'Visible',state_Pairs)
986% enable_j(handles,state_j)
987
988%------------------------------------------------------------------------
989function num_first_i_Callback(hObject, eventdata, handles)
990%------------------------------------------------------------------------
991num_last_i_Callback(hObject, eventdata, handles)
992
993%------------------------------------------------------------------------
994function num_last_i_Callback(hObject, eventdata, handles)
995%------------------------------------------------------------------------
996SeriesData=get(handles.series,'UserData');
997if ~isfield(SeriesData,'Time')
998    SeriesData.Time{1}=[];
999end
1000displ_time(handles);
1001
1002%------------------------------------------------------------------------
1003function num_first_j_Callback(hObject, eventdata, handles)
1004%------------------------------------------------------------------------
1005 num_last_j_Callback(hObject, eventdata, handles)
1006
1007%------------------------------------------------------------------------
1008function num_last_j_Callback(hObject, eventdata, handles)
1009%------------------------------------------------------------------------
1010first_j=str2num(get(handles.num_first_j,'String'));
1011last_j=str2num(get(handles.num_last_j,'String'));
1012ref_j=ceil((first_j+last_j)/2);
1013set(handles.num_ref_j,'String', num2str(ref_j))
1014num_ref_j_Callback(hObject, eventdata, handles)
1015SeriesData=get(handles.series,'UserData');
1016if ~isfield(SeriesData,'Time')
1017    SeriesData.Time{1}=[];
1018end
1019displ_time(handles);
1020
1021
1022%------------------------------------------------------------------------
1023% ---- find the times corresponding to the first and last indices of a series
1024function displ_time(handles)
1025%------------------------------------------------------------------------
1026SeriesData=get(handles.series,'UserData');%
1027ref_i=[str2num(get(handles.num_first_i,'String')) str2num(get(handles.num_last_i,'String'))];
1028ref_j=[str2num(get(handles.num_first_j,'String')) str2num(get(handles.num_last_j,'String'))];
1029TimeTable=get(handles.TimeTable,'Data');
1030Pairs=get(handles.PairString,'Data');
1031for iview=1:size(TimeTable,1)
1032    if size(SeriesData.Time,1)<iview
1033        break
1034    end
1035    i1=ref_i;
1036    j1=ref_j;
1037    i2=ref_i;
1038    j2=ref_j;
1039    % case of pairs
1040    if ~isempty(Pairs{iview,1})
1041        r=regexp(Pairs{iview,1},'(?<mode>(Di=)|(Dj=)) -*(?<num1>\d+)\|(?<num2>\d+)','names');
1042        if isempty(r)
1043            r=regexp(Pairs{iview,1},'(?<num1>\d+)(?<mode>-)(?<num2>\d+)','names');
1044        end
1045        switch r.mode
1046            case 'Di='  %  case 'series(Di)')
1047                i1=ref_i-str2num(r.num1);
1048                i2=ref_i+str2num(r.num2);
1049            case 'Dj='  %  case 'series(Dj)'
1050                j1=ref_j-str2num(r.num1);
1051                j2=ref_j+str2num(r.num2);
1052            case '-'  % case 'bursts'
1053                j1=str2num(r.num1)*ones(size(ref_i));
1054                j2=str2num(r.num2)*ones(size(ref_i));
1055        end
1056    end
1057    TimeTable{iview,2}=[];
1058    TimeTable{iview,3}=[];
1059    if size(SeriesData.Time{iview},1)>=i2(2)&&size(SeriesData.Time{iview},1)>=j2(2)
1060        if isempty(ref_j)
1061            time_first=(SeriesData.Time{iview}(i1(1))+SeriesData.Time{iview}(i2(1)))/2;
1062            time_last=(SeriesData.Time{iview}(i1(2))+SeriesData.Time{iview}(i2(2)))/2;
1063        else
1064            time_first=(SeriesData.Time{iview}(i1(1),j1(1))+SeriesData.Time{iview}(i2(1),j2(1)))/2;
1065            time_last=(SeriesData.Time{iview}(i1(2),j1(2))+SeriesData.Time{iview}(i2(2),j2(2)))/2;
1066        end
1067        TimeTable{iview,2}=time_first; %TODO: take into account pairs
1068        TimeTable{iview,3}=time_last; %TODO: take into account pairs
1069    end
1070end
1071set(handles.TimeTable,'Data',TimeTable)
1072
1073%% set the waitbar position with respect to the min and max in the series
1074% for iview=1:numel(SeriesData.i1_series)
1075% [tild,index_min(iview)]=min(SeriesData.i1_series{iview}(SeriesData.i1_series{iview}>0));
1076% [tild,index_max(iview)]=max(SeriesData.i1_series{iview}(SeriesData.i1_series{iview}>0));
1077% end
1078for iview=1:numel(SeriesData.i1_series)
1079    index_min(iview)=min(find(SeriesData.i1_series{iview}(2:end,2:end,1)>0));
1080    index_max(iview)=max(find(SeriesData.i1_series{iview}(2:end,2:end,1)>0));
1081end
1082[index_min,iview_min]=min(index_min);
1083[index_max,iview_max]=min(index_max);
1084index_first=(ref_i(1)-1)*(size(SeriesData.i1_series{iview_min},2)-1)+ref_j(1);
1085index_last=(ref_i(2)-1)*(size(SeriesData.i1_series{iview_max},2)-1)+ref_j(2);
1086range=index_max-index_min+1;
1087coeff_min=(index_first-index_min)/range;
1088coeff_max=(index_last-index_min+1)/range;
1089Position=get(handles.Waitbar,'Position');
1090Position_status=get(handles.FileStatus,'Position');
1091Position(1)=coeff_min*Position_status(3)+Position_status(1);
1092Position(3)=Position_status(3)*(coeff_max-coeff_min);
1093set(handles.Waitbar,'Position',Position)
1094update_waitbar(handles.Waitbar,0)
1095
1096%------------------------------------------------------------------------
1097% --- Executes when selected cell(s) is changed in PairString.
1098function PairString_CellSelectionCallback(hObject, eventdata, handles)
1099%------------------------------------------------------------------------   
1100set(handles.ListView,'Value',eventdata.Indices(1))% detect the selected raw index
1101ListView_Callback ([],[],handles) % update the list of available pairs
1102
1103%------------------------------------------------------------------------
1104%------------------------------------------------------------------------
1105%  III - FUNCTIONS ASSOCIATED TO THE FRAME SET PAIRS
1106%------------------------------------------------------------------------
1107%------------------------------------------------------------------------
1108% --- Executes on selection change in ListView.
1109function ListView_Callback(hObject, eventdata, handles)
1110%------------------------------------------------------------------------   
1111SeriesData=get(handles.series,'UserData');
1112i2_series=[];
1113j2_series=[];
1114iview=get(handles.ListView,'Value');
1115if ~isempty(SeriesData.i2_series{iview})
1116    i2_series=SeriesData.i2_series{iview};
1117end
1118if ~isempty(SeriesData.j2_series{iview})
1119    j2_series=SeriesData.j2_series{iview};
1120end
1121update_mode(handles,SeriesData.i1_series{iview},SeriesData.i2_series{iview},...
1122    SeriesData.j1_series{iview},SeriesData.j2_series{iview},SeriesData.Time{iview})
1123
1124%------------------------------------------------------------------------
1125% --- Executes on button press in mode.
1126function mode_Callback(hObject, eventdata, handles)
1127%------------------------------------------------------------------------       
1128SeriesData=get(handles.series,'UserData');
1129iview=get(handles.ListView,'Value');
1130mode_list=get(handles.mode,'String');
1131mode=mode_list{get(handles.mode,'Value')};
1132if isequal(mode,'bursts')
1133    enable_i(handles,'On')
1134    enable_j(handles,'Off') %do not display j index scanning in burst mode (j is fixed by the burst choice)
1135else
1136    enable_i(handles,'On')
1137    enable_j(handles,'Off')
1138end
1139fill_ListPair(handles,SeriesData.i1_series{iview},SeriesData.i2_series{iview},...
1140    SeriesData.j1_series{iview},SeriesData.j2_series{iview},SeriesData.Time{iview})
1141ListPairs_Callback([],[],handles)
1142
1143%-------------------------------------------------------------
1144% --- Executes on selection in ListPairs.
1145function ListPairs_Callback(hObject,eventdata,handles)
1146%------------------------------------------------------------
1147list_pair=get(handles.ListPairs,'String');%get the menu of image pairs
1148if isempty(list_pair)
1149    string='';
1150else
1151    string=list_pair{get(handles.ListPairs,'Value')};
1152    string=regexprep(string,',.*','');%removes time indication (after ',')
1153end
1154PairString=get(handles.PairString,'Data');
1155iview=get(handles.ListView,'Value');
1156PairString{iview,1}=string;
1157% report the selected pair string to the table PairString
1158set(handles.PairString,'Data',PairString)
1159
1160%------------------------------------------------------------------------
1161function num_ref_i_Callback(hObject, eventdata, handles)
1162%------------------------------------------------------------------------
1163mode_list=get(handles.mode,'String');
1164mode=mode_list{get(handles.mode,'Value')};
1165SeriesData=get(handles.series,'UserData');
1166iview=get(handles.ListView,'Value');
1167fill_ListPair(handles,SeriesData.i1_series{iview},SeriesData.i2_series{iview},...
1168    SeriesData.j1_series{iview},SeriesData.j2_series{iview},SeriesData.Time{iview});% update the menu of pairs depending on the available netcdf files
1169ListPairs_Callback([],[],handles)
1170
1171%------------------------------------------------------------------------
1172function num_ref_j_Callback(hObject, eventdata, handles)
1173%------------------------------------------------------------------------
1174num_ref_i_Callback(hObject, eventdata, handles)
1175
1176%------------------------------------------------------------------------
1177function update_mode(handles,i1_series,i2_series,j1_series,j2_series,time)
1178%------------------------------------------------------------------------   
1179check_burst=0;
1180if isempty(j2_series)% no pair menu to display
1181    if isempty(i2_series)
1182        set(handles.mode,'String',{''})
1183    else
1184        set(handles.mode,'Value',1)
1185        set(handles.mode,'String',{'series(Di)'})
1186    end
1187else
1188    nbfield=size(j2_series,1);
1189    nbfield2=size(j2_series,2);
1190    set(handles.mode,'String',{'bursts';'series(Dj)'})
1191    if nbfield2>10 || nbfield==1
1192        set(handles.mode,'Value',2);%set mode to series(Dj) if more than 10 j values
1193    else
1194        set(handles.mode,'Value',1);
1195        check_burst=1;
1196    end
1197end
1198if check_burst
1199    enable_i(handles,'On')
1200    enable_j(handles,'Off') %do not display j index scanning in burst mode (j is fixed by the burst choice)
1201else
1202    enable_i(handles,'On')
1203    if isempty(j1_series)
1204         enable_j(handles,'Off')
1205    else
1206        enable_j(handles,'On')
1207    end
1208end
1209fill_ListPair(handles,i1_series,i2_series,j1_series,j2_series,time)
1210ListPairs_Callback([],[],handles)
1211
1212%--------------------------------------------------------------
1213% determine the menu for civ1 pairstring depending on existing netcdf files
1214% with the reference indices num_ref_i and num_ref_j
1215%----------------------------------------------------------------
1216function fill_ListPair(handles,i1_series,i2_series,j1_series,j2_series,time)
1217
1218mode_list=get(handles.mode,'String');
1219mode=mode_list{get(handles.mode,'Value')};
1220ref_i=str2num(get(handles.num_ref_i,'String'));
1221if isempty(ref_i)
1222    ref_i=1;
1223end
1224if strcmp(get(handles.num_ref_j,'Visible'),'on')
1225    ref_j=str2num(get(handles.num_ref_j,'String'));
1226    if isempty(ref_j)
1227        ref_j=1;
1228    end
1229else
1230    ref_j=1;
1231end
1232TimeUnit=get(handles.TimeUnit,'String');
1233if length(TimeUnit)>=1
1234    dtunit=['m' TimeUnit];
1235else
1236    dtunit='e-03';
1237end
1238
1239displ_pair={};
1240if strcmp(mode,'series(Di)')
1241    if isempty(i2_series)
1242        msgbox_uvmat('ERROR','no i1-i2 pair available')
1243        return
1244    end
1245    diff_i=i2_series-i1_series;
1246    min_diff=min(diff_i(diff_i>0));
1247    max_diff=max(diff_i(diff_i>0));
1248    for ipair=min_diff:max_diff
1249        if numel(diff_i(diff_i==ipair))>0
1250            pair_string=['Di= ' num2str(-floor(ipair/2)) '|' num2str(ceil(ipair/2)) ];
1251            if ~isempty(time)
1252                if ref_i<=floor(ipair/2)
1253                    ref_i=floor(ipair/2)+1;% shift ref_i to get the first pair
1254                end
1255                Dt=time(ref_i+ceil(ipair/2),ref_j)-time(ref_i-floor(ipair/2),ref_j);
1256                pair_string=[pair_string ', Dt=' num2str(Dt) ' ' dtunit];
1257            end
1258            displ_pair=[displ_pair;{pair_string}];
1259        end
1260    end
1261    if ~isempty(displ_pair)
1262        displ_pair=[displ_pair;{'Di=*|*'}];
1263    end
1264elseif strcmp(mode,'series(Dj)')
1265    if isempty(j2_series)
1266        msgbox_uvmat('ERROR','no j1-j2 pair available')
1267        return
1268    end
1269    diff_j=j2_series-j1_series;
1270    min_diff=min(diff_j(diff_j>0));
1271    max_diff=max(diff_j(diff_j>0));
1272    for ipair=min_diff:max_diff
1273        if numel(diff_j(diff_j==ipair))>0
1274            pair_string=['Dj= ' num2str(-floor(ipair/2)) '|' num2str(ceil(ipair/2)) ];
1275            if ~isempty(time)
1276                if ref_j<=floor(ipair/2)
1277                    ref_j=floor(ipair/2)+1;% shift ref_i to get the first pair
1278                end
1279                Dt=time(ref_i,ref_j+ceil(ipair/2))-time(ref_i,ref_j-floor(ipair/2));
1280                pair_string=[pair_string ', Dt=' num2str(Dt) ' ' dtunit];
1281            end
1282            displ_pair=[displ_pair;{pair_string}];
1283        end
1284    end
1285    if ~isempty(displ_pair)
1286        displ_pair=[displ_pair;{'Dj=*|*'}];
1287    end
1288elseif strcmp(mode,'bursts')
1289    if isempty(j2_series)
1290        msgbox_uvmat('ERROR','no j1-j2 pair available')
1291        return
1292    end
1293    diff_j=j2_series-j1_series;
1294    min_j1=min(j1_series(j1_series>0));
1295    max_j1=max(j1_series(j1_series>0));
1296    min_j2=min(j2_series(j2_series>0));
1297    max_j2=max(j2_series(j2_series>0));
1298    for pair1=min_j1:min(max_j1,min_j1+20)
1299        for pair2=min_j2:min(max_j2,min_j2+20)
1300        if numel(j1_series(j1_series==pair1))>0 && numel(j2_series(j2_series==pair2))>0
1301            displ_pair=[displ_pair;{['j= ' num2str(pair1) '-' num2str(pair2)]}];
1302        end
1303        end
1304    end
1305    if ~isempty(displ_pair)
1306        displ_pair=[displ_pair;{'j=*-*'}];
1307    end
1308end
1309set(handles.num_ref_i,'String',num2str(ref_i)) % update ref_i and ref_j
1310set(handles.num_ref_j,'String',num2str(ref_j))
1311
1312%% display list of pairstring
1313displ_pair_list=get(handles.ListPairs,'String');
1314NewVal=[];
1315if ~isempty(displ_pair_list)
1316Val=get(handles.ListPairs,'Value');
1317NewVal=find(strcmp(displ_pair_list{Val},displ_pair),1);% look at the previous display in the new menu displ_pï¿œir
1318end
1319if ~isempty(NewVal)
1320    set(handles.ListPairs,'Value',NewVal)
1321else
1322    set(handles.ListPairs,'Value',1)
1323end
1324set(handles.ListPairs,'String',displ_pair)
1325
1326%-------------------------------------
1327function enable_i(handles,state)
1328set(handles.i_txt,'Visible',state)
1329set(handles.num_first_i,'Visible',state)
1330set(handles.num_last_i,'Visible',state)
1331set(handles.num_incr_i,'Visible',state)
1332% set(handles.num_MaxIndex_i,'Visible',state)
1333set(handles.num_ref_i,'Visible',state)
1334set(handles.ref_i_text,'Visible',state)
1335
1336%-----------------------------------
1337function enable_j(handles,state)
1338set(handles.j_txt,'Visible',state)
1339% set(handles.num_MinIndex_j,'Visible',state)
1340set(handles.num_first_j,'Visible',state)
1341set(handles.num_last_j,'Visible',state)
1342set(handles.num_incr_j,'Visible',state)
1343% set(handles.num_MaxIndex_j,'Visible',state)
1344set(handles.num_ref_j,'Visible',state)
1345set(handles.ref_j_text,'Visible',state)
1346
1347%-----------------------------------
1348% function view_FieldMenu(handles,state)
1349% % set(handles.FieldName,'Visible',state)
1350% % set(handles.Field_text,'Visible',state)
1351% set(handles.InputFields,'Visible',state)
1352
1353% %-----------------------------------
1354% function view_FieldMenu_1(handles,state)
1355% set(handles.FieldName_1,'Visible',state)
1356% set(handles.Field_text_1,'Visible',state)
1357
1358
1359%%%%%%%%%%%%%%%%%%%%
1360%%  MAIN ActionName FUNCTIONS
1361%%%%%%%%%%%%%%%%%%%%
1362%------------------------------------------------------------------------
1363% --- Executes on button press in RUN.
1364function RUN_Callback(hObject, eventdata, handles)
1365%------------------------------------------------------------------------
1366set(handles.RUN,'BusyAction','queue');
1367set(0,'CurrentFigure',handles.series)
1368set(handles.RUN, 'Enable','Off')
1369set(handles.RUN,'BackgroundColor',[0.831 0.816 0.784])
1370drawnow
1371[h_fun,Series,filexml,errormsg]=prepare_jobs(handles);
1372if ~isempty(errormsg)
1373    msgbox_uvmat('ERROR',errormsg)
1374    return
1375end
1376RunModeList=get(handles.RunMode,'String');
1377RunMode=RunModeList{get(handles.RunMode,'Value')};
1378
1379switch RunMode
1380    case 'local'
1381        Series=h_fun(Series);
1382        if ~isempty(filexml)
1383            t=struct2xml(Series);
1384            t=set(t,1,'name','Series');
1385            save(t,filexml);
1386        end
1387    case 'background'
1388        if isempty(filexml)
1389            Series=h_fun(Series);% no background in the absence of output file
1390        else
1391            % update the xml file after interactive input with the function
1392            Series.Specific='?';
1393            Series=h_fun(Series);
1394            t=struct2xml(Series);
1395            t=set(t,1,'name','Series');
1396            save(t,filexml);
1397            path_uvmat=fileparts(which('uvmat'));
1398           
1399            filename_bat=regexprep(filexml,'.xml$','.bat');
1400            [fid,message]=fopen(filename_bat,'w');
1401            if isequal(fid,-1)
1402                msgbox_uvmat('ERROR', ['creation of .bat file: ' message]);
1403                return
1404            end
1405            path_fct=get(handles.ActionPath,'String');
1406            filelog=regexprep(filexml,'.xml$','.log');
1407            text_matlabscript=[...
1408                '#!/bin/bash \n'...
1409                '. /etc/sysprofile \n'...
1410                'matlab -nodisplay -nosplash -nojvm -logfile ''' filelog ''' <<END_MATLAB \n'...
1411                'addpath(''' path_uvmat '''); \n'...
1412                'addpath(''' Series.Action.ActionPath '''); \n'...
1413                '' Series.Action.ActionName  '( ''' filexml '''); \n'...
1414                'exit \n'...
1415                'END_MATLAB \n'];
1416            fprintf(fid,text_matlabscript);
1417            fclose(fid);
1418            if isunix
1419                system(['chmod +x ' filename_bat]);% set the file to executable
1420                system(['. ' filename_bat ' &']);%execute fct
1421            else
1422                system(filename_bat);
1423            end
1424        end
1425        update_waitbar(handles.Waitbar,1); % put the waitbar to end position to indicate lounching is finished
1426end
1427
1428set(handles.RUN, 'Enable','On')
1429set(handles.RUN,'BackgroundColor',[1 0 0])
1430
1431%------------------------------------------------------------------------
1432function STOP_Callback(hObject, eventdata, handles)
1433%------------------------------------------------------------------------
1434set(handles.RUN, 'BusyAction','cancel')
1435set(handles.RUN,'BackgroundColor',[1 0 0])
1436set(handles.RUN,'enable','on')
1437% set(handles.BATCH,'BackgroundColor',[1 0 0])
1438% set(handles.BATCH,'enable','on')
1439
1440%------------------------------------------------------------------------
1441% --- Executes on button press in BATCH.
1442function BATCH_Callback(hObject, eventdata, handles)
1443%------------------------------------------------------------------------   
1444
1445
1446% %------------------------------------------------------------------------
1447% % --- Executes on button press in BIN.
1448% function BIN_Callback(hObject, eventdata, handles)
1449% %------------------------------------------------------------------------
1450%     cmd=['#!/bin/bash \n '...
1451%         '#$ -cwd \n '...
1452%         'hostname && date \n '...
1453%         'umask 002 \n'...
1454%         Param.xml.CivmBin ' ' Param.xml.RunTime ' ' filename_xml ' ' OutputFile '.nc'];
1455%     
1456%------------------------------------------------------------------------
1457% --- Main launch command, called by RUN and BATCH
1458function [h_fun,Series,filexml,errormsg]=prepare_jobs(handles,run)
1459%INPUT:
1460% handles: handles of graphic objects on the GUI series
1461% run=0, just to display parameters for MenuExport/GUI config
1462% run=1 (default) prepare the computation
1463
1464%------------------------------------------------------------------------
1465h_fun=[];
1466filexml='';
1467errormsg='';
1468if ~exist('run','var')
1469    run=1;
1470end
1471%% Read parameters from series
1472Series=read_GUI(handles.series);
1473if isfield(Series,'Pairs')
1474Series=rmfield(Series,'Pairs'); %info Pairs not needed for output
1475end
1476
1477%% read index ranges
1478first_i=1;
1479last_i=1;
1480incr_i=1;
1481first_j=1;
1482last_j=1;
1483incr_j=1;
1484if isfield(Series.IndexRange,'first_i')
1485    first_i=Series.IndexRange.first_i;
1486    incr_i=Series.IndexRange.incr_i;
1487    last_i=Series.IndexRange.last_i;
1488end
1489if isfield(Series.IndexRange,'first_j')
1490    first_j=Series.IndexRange.first_j;
1491    incr_j=Series.IndexRange.incr_j;
1492    last_j=Series.IndexRange.last_j;
1493end
1494
1495%% read input file parameters and set menus
1496menu_coord_state=get(handles.TransformName,'Visible');
1497if isequal(menu_coord_state,'on')
1498    menu_index=get(handles.TransformName,'Value');
1499    transform_list=get(handles.TransformName,'UserData');
1500    Series.FieldTransform.TransformHandle=transform_list{menu_index};% transform function handles
1501end
1502
1503if last_i < first_i | last_j < first_j , msgbox_uvmat('ERROR','last field number must be larger than the first one'),...
1504    set(handles.RUN, 'Enable','On'), set(handles.RUN,'BackgroundColor',[1 0 0]),return,end;
1505
1506%% projection object
1507if isfield(Series,'CheckObject')
1508    if Series.CheckObject
1509        hset_object=findobj(allchild(0),'tag','set_object');
1510        Series.ProjObject=read_GUI(hset_object);
1511        CheckObject_Callback([], [], handles)
1512    end
1513else
1514    Series.CheckObject=0;
1515end
1516
1517%% get_field GUI
1518if isfield(Series,'InputFields')&&isfield(Series.InputFields,'Field')
1519    if strcmp(Series.InputFields.Field,'get_field...')
1520        hget_field=findobj(allchild(0),'name','get_field');
1521        Series.GetField=read_GUI(hget_field);
1522    end
1523end
1524
1525if ~run
1526    return
1527end
1528
1529%% defining the ActionName function handle
1530list_action=get(handles.ActionName,'String');% list menu action
1531index=get(handles.ActionName,'Value');
1532action= list_action{index}; % selected string
1533%Series.Action=action;%name of the processing programme
1534Series.hseries=handles.series; % handles to the series GUI
1535path_series=which('series');
1536list_path=get(handles.ActionName,'UserData');
1537fct_path=list_path{index}; %path stored for the function ACTION
1538if ~isequal(fct_path,path_series)
1539    eval(['spath=which(''' action ''');']) %spath = current path of the selected function ACTION
1540    if ~exist(fct_path,'dir')
1541        errormsg=['The prescribed function path ' fct_path ' does not exist'];
1542        return
1543    end
1544    if ~isequal(spath,fct_path)
1545        addpath(fct_path)% add the prescribed path if not the current one
1546    end
1547end
1548eval(['h_fun=@' action ';'])%create a function handle for ACTION
1549if ~isequal(fct_path,path_series)
1550        rmpath(fct_path)% add the prescribed path if not the current one   
1551end
1552
1553%% create the output data directory and write in it the xml file from the GUI config
1554%determine the root file corresponding to the first sub dir
1555if isfield(Series,'OutputSubDir')
1556    SubDirOut=[Series.OutputSubDir Series.OutputDirExt];
1557    SubDirOutNew=SubDirOut;
1558    iview=1;
1559    SeriesData=get(handles.series,'UserData');
1560    if size(Series.InputTable,1)>1 && isfield(SeriesData,'AllowInputSort') && isfield(SeriesData.AllowInputSort)
1561        [tild,iview]=sort(Series.InputTable(:,2)); %subdirectories sorted in alphabetical order
1562        Series.InputTable=Series.InputTable(iview,:);
1563    end
1564    detect=exist(fullfile(Series.InputTable{1,1},SubDirOutNew),'dir');% test if  the dir  already exist
1565    check_create=1; %need to create the result directory by default
1566    while detect
1567        answer=msgbox_uvmat('INPUT_Y-N',['use existing ouput directory: ' fullfile(Series.InputTable{1,1},SubDirOutNew) ', possibly delete previous data']);
1568        if isequal(answer,'Yes')
1569            detect=0;
1570            check_create=0;
1571        else
1572            r=regexp(SubDirOutNew,'(?<root>.*\D)(?<num1>\d+)$','names');%detect whether name ends by a number
1573            if isempty(r)
1574                r(1).root=[SubDirOutNew '_'];
1575                r(1).num1='0';
1576            end
1577            SubDirOutNew=[r(1).root num2str(str2num(r(1).num1)+1)];%increment the index by 1 or put 1
1578            detect=exist(fullfile(Series.InputTable{1,1},SubDirOutNew),'dir');% test if  the dir  already exists   
1579            check_create=1;
1580        end
1581    end
1582    Series.OutputDirExt=regexprep(SubDirOutNew,Series.OutputSubDir,'');
1583 %   Series.OutputSubDir=SubDirOutNew;
1584 %   Series.OutputDir=fullfile(Series.InputTable{1,1},Series.OutputSubDir);%directory set for output results
1585    Series.OutputRootFile=Series.InputTable{1,3};% the first sorted RootFile taken for output
1586    set(handles.OutputDirExt,'String',Series.OutputDirExt)
1587    % create output directory
1588    OutputDir=fullfile(Series.InputTable{1,1},[Series.OutputSubDir Series.OutputDirExt]);
1589    if check_create
1590        [tild,msg1]=mkdir(OutputDir);
1591        if ~strcmp(msg1,'')
1592            errormsg=['cannot create ' OutputDir ': ' msg1];%error message for directory creation
1593            return
1594        end
1595    end
1596    filexml=fullfile(OutputDir,[Series.InputTable{1,3} '.xml']);% name of the parameter xml file set in this directory
1597end
1598%removes redondant information
1599Series.IndexRange=rmfield(Series.IndexRange,'TimeTable');
1600Series.IndexRange=rmfield(Series.IndexRange,'MinIndex');
1601Series.IndexRange=rmfield(Series.IndexRange,'MaxIndex');
1602%removes empty lines of InputTable
1603empty_line=zeros(size(Series.InputTable,1),1);
1604for iline=1:size(Series.InputTable,1)
1605    empty_line(iline)=isequal(Series.InputTable(iline,1:3),{'','',''});
1606end
1607Series.InputTable(find(empty_line),:)=[];
1608
1609%------------------------------------------------------------------------
1610% --- Executes on selection change in ActionName.
1611function ActionName_Callback(hObject, eventdata, handles)
1612%------------------------------------------------------------------------
1613global nb_builtin_ACTION
1614list_ACTION=get(handles.ActionName,'String');% list menu fields
1615index_ACTION=get(handles.ActionName,'Value');% selected string index
1616ACTION= list_ACTION{index_ACTION}; % selected function name
1617path_series=which('series');%path to series.m
1618list_path=get(handles.ActionName,'UserData');%list of recorded paths to functions of the list ACTION
1619default_file=fullfile(list_path{end},ACTION);
1620% add a new function to the menu if the selected item is 'more...'
1621if isequal(ACTION,'more...')
1622    pathfct=fileparts(path_series);
1623    [FileName, PathName, filterindex] = uigetfile( ...
1624       {'*.m', ' (*.m)';
1625        '*.m',  '.m files '; ...
1626        '*.*', 'All Files (*.*)'}, ...
1627        'Pick a file',default_file);
1628    if length(FileName)<2
1629        return
1630    end
1631    [pp,ACTION,ext_fct]=fileparts(FileName);%(end-1:end);
1632    if ~isequal(ext_fct,'.m')
1633        msgbox_uvmat('ERROR','a Matlab function .m must be introduced');
1634        return
1635    end
1636   
1637   % insert the choice in the actionname menu
1638   menu_str=update_menu(handles.ActionName,ACTION);%new action menu in which the new item has been appended if needed
1639   index_ACTION=get(handles.ActionName,'Value');% currently selected index in the list
1640   list_path{index_ACTION}=PathName;
1641   if length(menu_str)>nb_builtin_ACTION+5; %nb_builtin=nbre of functions always remaining in the initial menu
1642       nbremove=length(menu_str)-nb_builtin_ACTION-5;
1643       menu_str(nb_builtin_ACTION+1:end-5)=[];
1644       list_path(nb_builtin_ACTION+1:end-4)=[];
1645       index_ACTION=index_ACTION-nbremove;
1646       set(handles.ActionName,'Value',index_ACTION)
1647       set(handles.ActionName,'String',menu_str)
1648   end
1649   list_path{index_ACTION}=PathName;
1650   set(handles.ActionName,'UserData',list_path);
1651   set(handles.ActionPath,'enable','inactive')% indicate that the current path is accessible (not 'off')
1652   
1653   %record the current menu in personal file profil_perso
1654   dir_perso=prefdir;
1655   profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
1656   for ilist=nb_builtin_ACTION+1:length(menu_str)-1
1657       series_fct{ilist-nb_builtin_ACTION}=fullfile(list_path{ilist},[menu_str{ilist} '.m']);     
1658   end
1659   if nb_builtin_ACTION+1<=length(menu_str)-1
1660       if exist(profil_perso,'file')% && nb_builtin_ACTION+1>=length(menu_str)-1
1661           save(profil_perso,'series_fct','-append')
1662       else
1663           txt=ver('MATLAB');
1664           Release=txt.Release;
1665           relnumb=str2num(Release(3:4));
1666           if relnumb >= 14%recent relaese of Matlab
1667               save(profil_perso,'series_fct','-V6')
1668           else
1669               save(profil_perso, 'series_fct')
1670           end
1671       end
1672   end
1673end
1674
1675%check the current ActionPath to the selected function
1676PathName=list_path{index_ACTION};%current recorded path
1677set(handles.ActionPath,'String',PathName); %show the path to the senlected function
1678
1679%reinitialise the waitbar
1680update_waitbar(handles.Waitbar,0)
1681
1682%default setting for the visibility of the GUI elements
1683set(handles.num_NbSlice,'Visible','off')
1684set(handles.NbSlice_title,'Visible','off')
1685set(handles.VelType,'Visible','off');
1686set(handles.VelType_text,'Visible','off');
1687set(handles.VelType_1,'Visible','off');
1688set(handles.VelType_text_1,'Visible','off');
1689set(handles.InputFields,'Visible','off')
1690set(handles.FieldName_1,'Visible','off')
1691%view_FieldMenu_1(handles,'off')
1692set(handles.FieldTransform,'Visible','off')
1693set(handles.CheckObject,'Visible','off');
1694set(handles.ProjObject,'Visible','off');
1695set(handles.CheckMask,'Visible','off')
1696set(handles.Mask,'Visible','off')
1697set(handles.OutputDirExt,'Visible','off')
1698set(handles.OutputSubDir,'Visible','off')
1699set(handles.OutputDir_title,'Visible','off')
1700%set the displayed GUI item needed for input parameters
1701if ~isequal(path_series,PathName)
1702    addpath(PathName)
1703end
1704eval(['h_function=@' ACTION ';']);
1705try
1706    [fid,errormsg] =fopen([ACTION '.m']);
1707    InputText=textscan(fid,'%s',1,'delimiter','\n');
1708    fclose(fid)
1709    set(handles.ActionName,'ToolTipString',InputText{1}{1})% put the first line of the selected function as tooltip help
1710end
1711if ~isequal(path_series,PathName)
1712    rmpath(PathName)
1713end
1714varargout=h_function();
1715Param_list={};
1716
1717InputTable=get(handles.InputTable,'Data');
1718nbview=size(InputTable,1);
1719SeriesData=get(handles.series,'UserData');
1720nb_civ=numel(find(strcmp('civx',SeriesData.FileType)|strcmp('civdata',SeriesData.FileType)));
1721nb_netcdf=numel(find(strcmp('netcdf',SeriesData.FileType)));
1722for ilist=1:length(varargout)-1
1723    switch varargout{ilist}
1724        case 'AllowInputSort'
1725            if isequal(lower(varargout{ilist+1}),'on')% sort the input table by alphabetical order of the SubDir
1726                SeriesData.AllowInputSort=1;
1727                set(handles.series,'UserData',SeriesData)
1728            end                     
1729        case 'WholeIndexRange'
1730            if isequal(lower(varargout{ilist+1}),'on')% set by default the input index range from min to max
1731                MinIndex=get(handles.MinIndex,'Data');
1732                MaxIndex=get(handles.MaxIndex,'Data');
1733                if ~isempty(MinIndex)
1734                    set(handles.num_first_i,'String',num2str(MinIndex{1}))
1735                    set(handles.num_last_i,'String',num2str(MaxIndex{1}))
1736                    set(handles.num_incr_i,'String','1')
1737                    if size(MinIndex,2)>=2
1738                        set(handles.num_first_j,'String',num2str(MinIndex{1,2}))
1739                        set(handles.num_last_j,'String',num2str(MaxIndex{1,2}))
1740                        set(handles.num_incr_j,'String','1')
1741                    end
1742                end
1743            end           
1744        case 'NbSlice'   %hidden by default
1745            if isequal(lower(varargout{ilist+1}),'on')
1746                set(handles.num_NbSlice,'Visible','on')
1747                set(handles.NbSlice_title,'Visible','on')
1748            end
1749        case 'VelType'   %hidden by default
1750             if isequal(lower(varargout{ilist+1}),'one') || isequal(lower(varargout{ilist+1}),'two')
1751                if nb_civ>=1
1752                    set(handles.VelType,'Visible','on')
1753                    set(handles.VelType_text,'Visible','on');
1754                end
1755             end
1756            if isequal(lower(varargout{ilist+1}),'two')
1757                if nb_civ>=2
1758                    set(handles.VelType_1,'Visible','on')
1759                    set(handles.VelType_text_1,'Visible','on');
1760                end
1761            end
1762        case 'FieldName'   %hidden by default
1763            if isequal(lower(varargout{ilist+1}),'one')||isequal(lower(varargout{ilist+1}),'two')
1764                if (nb_civ+nb_netcdf)>=1
1765                 set(handles.FieldName,'Visible','on') % test for MenuBorser
1766                 set(handles.InputFields,'Visible','on')
1767                end
1768            end
1769            if isequal(lower(varargout{ilist+1}),'two')
1770                if (nb_civ+nb_netcdf)>=1
1771                set(handles.FieldName_1,'Visible','on')
1772                end
1773            end
1774        case 'FieldTransform'   %hidden by default
1775            if isequal(lower(varargout{ilist+1}),'on')
1776                set(handles.TransformName,'Enable','on')
1777                set(handles.FieldTransform,'Visible','on')
1778                TransformName_Callback([],[], handles)
1779            end
1780        case 'ProjObject'   %hidden by default
1781            if isequal(lower(varargout{ilist+1}),'on')   
1782                set(handles.CheckObject,'Visible','on')
1783                set(handles.ProjObject,'Visible','on')
1784            end
1785        case 'Mask'   %hidden by default
1786            if isequal(lower(varargout{ilist+1}),'on')   
1787                set(handles.Mask,'Visible','on')
1788                 set(handles.CheckMask,'Visible','on');
1789            end 
1790        case 'OutputDirExt'
1791            if ~isempty(varargout{ilist+1})
1792            set(handles.OutputDirExt,'String',varargout{ilist+1})
1793            set(handles.OutputDirExt,'Visible','on')
1794            set(handles.OutputSubDir,'Visible','on')
1795            set(handles.OutputDir_title,'Visible','on') 
1796            end
1797    end
1798end
1799if ~isempty(Param_list)
1800    set(handles.ParamKey,'String',Param_list)
1801    set(handles.ParamVal,'Visible','on')
1802end
1803
1804%------------------------------------------------------------------------
1805% --- Executes on selection change in FieldName.
1806function FieldName_Callback(hObject, eventdata, handles)
1807%------------------------------------------------------------------------
1808field_str=get(handles.FieldName,'String');
1809field_index=get(handles.FieldName,'Value');
1810field=field_str{field_index(1)};
1811if isequal(field,'get_field...')   
1812     hget_field=findobj(allchild(0),'name','get_field');
1813     if ~isempty(hget_field)
1814         delete(hget_field)%delete opened versions of get_field
1815     end
1816     filecell=get_file_series(read_GUI(handles.series));
1817     if exist(filecell{1,1},'file')
1818        get_field(filecell{1,1})
1819     end
1820elseif isequal(field,'more...')
1821    str=calc_field;
1822    [ind_answer,v] = listdlg('PromptString','Select a file:',...
1823                'SelectionMode','single',...
1824                'ListString',str);
1825       % edit the choice in the fields and actionname menu
1826     scalar=cell2mat(str(ind_answer));
1827     update_menu(handles.FieldName,scalar)
1828end
1829
1830%------------------------------------------------------------------------
1831% --- Executes on selection change in FieldName_1.
1832function FieldName_1_Callback(hObject, eventdata, handles)
1833%------------------------------------------------------------------------
1834field_str=get(handles.FieldName_1,'String');
1835field_index=get(handles.FieldName_1,'Value');
1836field=field_str{field_index};
1837if isequal(field,'get_field...')   
1838     hget_field=findobj(allchild(0),'name','get_field_1');
1839     if ~isempty(hget_field)
1840         delete(hget_field)
1841     end
1842     SeriesData=get(handles.series,'UserData');
1843     filename=SeriesData.CurrentInputFile_1;
1844     if exist(filename,'file')
1845        hget_field=get_field(filename);
1846        set(hget_field,'name','get_field_1')
1847     end
1848elseif isequal(field,'more...')
1849    str=calc_field;
1850    [ind_answer,v] = listdlg('PromptString','Select a file:',...
1851                'SelectionMode','single',...
1852                'ListString',str);
1853       % edit the choice in the fields and actionname menu
1854     scalar=cell2mat(str(ind_answer));
1855     update_menu(handles.FieldName_1,scalar)
1856end   
1857
1858
1859%%%%%%%%%%%%%
1860function [ind_remove]=find_pairs(dirpair,ind_i,last_i)
1861indsel=ind_i;
1862indiff=diff(ind_i); %test index increment to detect multiplets (several pairs with the same index ind_i) and holes in the series
1863indiff=[1 indiff last_i-ind_i(end)+1];%for testing gaps with the imposed bounds
1864if ~isempty(indiff)
1865    indiff2=diff(indiff);
1866    indiffp=[indiff2 1];
1867    indiffm=[1 indiff2];
1868    ind_multi_m=find((indiff==0)&(indiffm<0))-1;%indices of first members of multiplets
1869    ind_multi_p=find((indiff==0)&(indiffp>0));%indices of last members of multiplets
1870    %for each multiplet, select the most recent file
1871    ind_remove=[];
1872    for i=1:length(ind_multi_m)
1873        ind_pairs=ind_multi_m(i):ind_multi_p(i);
1874        for imulti=1:length(ind_pairs)
1875            datepair(imulti)=datenum(dirpair(ind_pairs(imulti)).date);%dates of creation
1876        end
1877        [datenew,indsort2]=sort(datepair); %sort the multiplet by creation date
1878        ind_s=indsort2(1:end-1);%
1879        ind_remove=[ind_remove ind_pairs(ind_s)];%remove these indices, leave the last one
1880    end
1881end
1882
1883%------------------------------------------------------------------------
1884% --- determine the list of index pairstring of processing file
1885function [num_i1,num_i2,num_j1,num_j2,num_i_out,num_j_out]=find_file_indices(num_i,num_j,ind_shift,NomType,mode)
1886%------------------------------------------------------------------------
1887num_i1=num_i;% set of first image numbers by default
1888num_i2=num_i;
1889num_j1=num_j;
1890num_j2=num_j;
1891num_i_out=num_i;
1892num_j_out=num_j;
1893% if isequal (NomType,'_1-2_1') || isequal (NomType,'_1-2')
1894if isequal(mode,'series(Di)')
1895    num_i1_line=num_i+ind_shift(3);% set of first image numbers
1896    num_i2_line=num_i+ind_shift(4);
1897    % adjust the first and last field number
1898        indsel=find(num_i1_line >= 1);
1899    num_i_out=num_i(indsel);
1900    num_i1_line=num_i1_line(indsel);
1901    num_i2_line=num_i2_line(indsel);
1902    num_j1=meshgrid(num_j,ones(size(num_i1_line)));
1903    num_j2=meshgrid(num_j,ones(size(num_i1_line)));
1904    [xx,num_i1]=meshgrid(num_j,num_i1_line);
1905    [xx,num_i2]=meshgrid(num_j,num_i2_line);
1906elseif isequal (mode,'series(Dj)')||isequal (mode,'bursts')
1907    if isequal(mode,'bursts') %case of bursts (png_old or png_2D)
1908        num_j1=ind_shift(1)*ones(size(num_i));
1909        num_j2=ind_shift(2)*ones(size(num_i));
1910    else
1911        num_j1_col=num_j+ind_shift(1);% set of first image numbers
1912        num_j2_col=num_j+ind_shift(2);
1913        % adjust the first field number
1914        indsel=find((num_j1_col >= 1));   
1915        num_j_out=num_j(indsel);
1916        num_j1_col=num_j1_col(indsel);
1917        num_j2_col=num_j2_col(indsel);
1918        [num_i1,num_j1]=meshgrid(num_i,num_j1_col);
1919        [num_i2,num_j2]=meshgrid(num_i,num_j2_col);
1920    end   
1921end
1922
1923%------------------------------------------------------------------------
1924% --- Executes on button press in CheckObject.
1925function CheckObject_Callback(hObject, eventdata, handles)
1926%------------------------------------------------------------------------
1927% SeriesData=get(handles.series,'UserData');
1928value=get(handles.CheckObject,'Value');
1929if value
1930     set(handles.CheckObject,'BackgroundColor',[1 1 0])%put unactivated buttons to yellow
1931     hset_object=findobj(allchild(0),'tag','set_object');%find the set_object interface handle
1932     if ishandle(hset_object)
1933         uistack(hset_object,'top')% show the GUI set_object if opened
1934     else
1935         %get the object file
1936         InputTable=get(handles.InputTable,'Data');
1937         defaultname=InputTable{1,1};
1938         if isempty(defaultname)
1939            defaultname={''};
1940         end
1941        [FileName, PathName, filterindex] = uigetfile( ...
1942       {'*.xml;*.mat', ' (*.xml,*.mat)';
1943       '*.xml',  '.xml files '; ...
1944        '*.mat',  '.mat matlab files '}, ...
1945        'Pick an xml object file (or use uvmat to create it)',defaultname);
1946        fileinput=[PathName FileName];%complete file name
1947        sizf=size(fileinput);
1948        if (~ischar(fileinput)||~isequal(sizf(1),1)),return;end
1949        %read the file
1950        data=xml2struct(fileinput);
1951        if ~isfield(data,'Type')
1952             msgbox_uvmat('ERROR',[fileinput ' is not an object xml file'])
1953             return
1954        end
1955        if ~isfield(data,'ProjMode')
1956             data.ProjMode='none';
1957        end
1958        hset_object=set_object(data);% call the set_object interface
1959     end
1960     Object=read_GUI(hset_object);
1961     set(handles.ProjObject,'String',Object.Name);%display the object name
1962else
1963    set(handles.CheckObject,'BackgroundColor',[0.7 0.7 0.7])%put activated buttons to green
1964end
1965%set(handles.series,'UserData',SeriesData)
1966
1967%--------------------------------------------------------------
1968function CheckMask_Callback(hObject, eventdata, handles)
1969value=get(handles.CheckMask,'Value');
1970if value
1971    msgbox_uvmat('ERROR','not implemented yet')
1972end
1973%--------------------------------------------------------------
1974
1975%-------------------------------------------------------------------
1976%'uv_ncbrowser': interactively calls the netcdf file browser 'get_field.m'
1977function ncbrowser_uvmat(hObject, eventdata)
1978%-------------------------------------------------------------------
1979     bla=get(gcbo,'String');
1980     ind=get(gcbo,'Value');
1981     filename=cell2mat(bla(ind));
1982      blank=find(filename==' ');
1983      filename=filename(1:blank-1);
1984     get_field(filename)
1985
1986% ------------------------------------------------------------------
1987function MenuHelp_Callback(hObject, eventdata, handles)
1988%-------------------------------------------------------------------
1989path_to_uvmat=which ('uvmat');% check the path of uvmat
1990pathelp=fileparts(path_to_uvmat);
1991helpfile=fullfile(pathelp,'uvmat_doc','uvmat_doc.html');
1992if isempty(dir(helpfile)), msgbox_uvmat('ERROR','Please put the help file uvmat_doc.html in the sub-directory /uvmat_doc of the UVMAT package')
1993else
1994    addpath (fullfile(pathelp,'uvmat_doc'))
1995    web([helpfile '#series'])
1996end
1997
1998%-------------------------------------------------------------------
1999% --- Executes on selection change in TransformName.
2000function TransformName_Callback(hObject, eventdata, handles)
2001%-------------------------------------------------------------------
2002global nb_transform
2003
2004menu=get(handles.TransformName,'String');
2005ind_coord=get(handles.TransformName,'Value');
2006coord_option=menu{ind_coord};
2007list_transform=get(handles.TransformName,'UserData');
2008ff=functions(list_transform{end});
2009if isequal(coord_option,'more...');
2010    coord_fct='';
2011    prompt = {'Enter the name of the transform function'};
2012    dlg_title = 'user defined transform';
2013    num_lines= 1;
2014    [FileName, PathName, filterindex] = uigetfile( ...
2015       {'*.m', ' (*.m)';
2016        '*.m',  '.m files '; ...
2017        '*.*', 'All Files (*.*)'}, ...
2018        'Pick a file', ff.file);
2019    if isequal(PathName(end),'/')||isequal(PathName(end),'\')
2020        PathName(end)=[];
2021    end
2022    transform_selected =fullfile(PathName,FileName);
2023    if ~exist(transform_selected,'file')
2024          return
2025    end
2026    [ppp,transform,xt_fct]=fileparts(FileName);% removes extension .m
2027    if ~isequal(ext_fct,'.m')
2028        msgbox_uvmat('ERROR','a Matlab function .m must be introduced');
2029        return
2030    end
2031   menu=update_menu(handles.TransformName,transform);%add the selected fct to the menu
2032   ind_coord=get(handles.TransformName,'Value');
2033   addpath(PathName)
2034   list_transform{ind_coord}=str2func(transform);% create the function handle corresponding to the newly seleced function
2035   set(handles.TransformName,'UserData',list_transform)
2036   rmpath(PathName)
2037   % save the new menu in the personal file 'uvmat_perso.mat'
2038   dir_perso=prefdir;%personal Matalb directory
2039   profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
2040   if exist(profil_perso,'file')
2041       for ilist=nb_transform+1:numel(list_transform)
2042           ff=functions(list_transform{ilist});
2043           transform_fct{ilist-nb_transform}=ff.file;
2044       end
2045        save (profil_perso,'transform_fct','-append'); %store the root name for future opening of uvmat
2046   end
2047end
2048
2049%check the current ActionPath to the selected function
2050if ~isempty(list_transform{ind_coord})
2051    func=functions(list_transform{ind_coord});
2052    set(handles.TransformPath,'String',fileparts(func.file)); %show the path to the senlected function
2053else
2054    set(handles.TransformPath,'String',''); %show the path to the senlected function
2055end
2056
2057% %------------------------------------------------------------------------
2058% % --- Executes on button press in REFRESH.
2059%     function REFRESH_INDICES_Callback(hObject, eventdata, handles)
2060% %------------------------------------------------------------------------       
2061% % hObject    handle to REFRESH (see GCBO)
2062% % eventdata  reserved - to be defined in a future version of MATLAB
2063% % handles    structure with handles and user data (see GUIDATA)
2064% set(handles.REFRESH,'BackgroundColor',[0.7 0.7 0.7])
2065% InputTable=get(handles.InputTable,'Data');
2066% check_lines=get(handles.REFRESH,'UserData');
2067%
2068% %% check the indices and FileTypes for each series (limited to the new ones to save time)
2069% for ind_list=1:length(check_lines)
2070%     if  check_lines(ind_list)
2071%         InputLine=InputTable(ind_list,:);
2072%         detect_idem=strcmp('"',InputLine);% look for '" (repeat of previous data)
2073%         detect_idem=detect_idem(detect_idem>0);
2074%         if ~isempty (detect_idem)
2075%             InputLine(detect_idem)=InputTable(ind_list-1,detect_idem);
2076%             set(handles.InputTable,'Data',InputTable)
2077%         end
2078%         fileinput=fullfile_uvmat(InputLine{1},InputLine{2},InputLine{3},InputLine{5},InputLine{4},1,2,1,2);
2079%         %fileinput=name_generator(fullfile(InputLine{1},InputLine{3}),1,1,InputLine{5},InputLine{4},1,2,2,InputLine{2})
2080%         %update file series defined by the selected line
2081%         [InputTable{ind_list,3},InputTable{(ind_list),4},errormsg]=update_indices(handles,fileinput,ind_list);
2082%         if ~isempty(errormsg)
2083%                 msgbox_uvmat('ERROR',errormsg)
2084%                 return
2085%         end
2086%     end
2087% end
2088% set(handles.InputTable,'Data',InputTable)
2089% SeriesData=get(handles.series,'UserData');
2090%
2091% state_j='off';
2092% state_Pairs='off';
2093% state_InputFields='off';
2094% val=get(handles.ListView,'Value');
2095% ListViewString={''};
2096% if ~isempty(SeriesData)
2097% %     ListViewString={};
2098%     for iview=1:size(InputTable,1)
2099%         if ~isempty(SeriesData.j1_series{iview})
2100%             state_j='on';
2101%         end
2102%         if ~isempty(SeriesData.i2_series{iview})||~isempty(SeriesData.j2_series{iview})
2103%             state_Pairs='on';
2104%             ListViewString{iview}=num2str(iview);
2105%             if check_lines(iview)
2106%                 val=iview;%select the last pair if it is a new entry
2107%             end
2108%         end
2109%         if strcmp(SeriesData.FileType{iview},'civx')||strcmp(SeriesData.FileType{iview},'civdata')
2110%             state_InputFields='on';
2111%         end
2112%     end
2113% end
2114% set(handles.ListView,'Value',val)
2115% set(handles.ListView,'String',ListViewString)
2116% if strcmp(state_Pairs,'on')
2117%     ListView_Callback(hObject,eventdata,handles)
2118% end
2119% set(handles.PairString,'Visible',state_Pairs)
2120% enable_j(handles,state_j)
2121% set(handles.REFRESH,'BackgroundColor',[1 0 0])
2122% set(handles.REFRESH,'visible','off')
2123
2124% -----------------------------------------------------------------------
2125% --- Update min and max indices of a file series by scanning with find_file_series
2126% --- which also changes the root file and NomType in case of movie. Also adjust the string representation of indices (e.g;
2127% --- 1 or 001 by the function find_file_series
2128% --- This function also dispaly the set of availbale files in the series
2129% --- and the menus appropriate to the file type as well as timing possibly set
2130% --- by an xml image documentation file
2131function [RootFile,NomType,errormsg]=update_indices(handles,fileinput,iview)
2132% -----------------------------------------------------------------------
2133%% look for min and max indices existing in the file series and update SeriesData
2134errormsg='';
2135[FilePath,FileName,FileExt]=fileparts(fileinput);
2136% detect the file type, get the movie object if relevant, and look for the corresponding file series:
2137% the root name and indices may be corrected by including the first index i1 if a corresponding xml file exists
2138[RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,NomType,FileType,Object,i1,i2,j1,j2]=find_file_series(FilePath,[FileName FileExt]);
2139if isempty(RootFile)&&isempty(i1_series)
2140    errormsg='no input file in the series';
2141    return
2142end
2143
2144%% adjust the min and max indices common to all the file series
2145MinIndex=get(handles.MinIndex,'Data');
2146MaxIndex=get(handles.MaxIndex,'Data');
2147MinIndex_i=min(i1_series(i1_series>0));
2148if ~isempty(i2_series)
2149    MaxIndex_i=max(i2_series(i2_series>0));
2150else
2151    MaxIndex_i=max(i1_series(i1_series>0));
2152end
2153MinIndex_j=min(j1_series(j1_series>0));
2154if ~isempty(j2_series)
2155    MaxIndex_j=max(j2_series(j2_series>0));
2156else
2157    MaxIndex_j=max(j1_series(j1_series>0));
2158end
2159MinIndex{iview,1}=MinIndex_i;
2160MinIndex{iview,2}=MinIndex_j;
2161MaxIndex{iview,1}=MaxIndex_i;
2162MaxIndex{iview,2}=MaxIndex_j;
2163set(handles.MinIndex,'Data',MinIndex)
2164set(handles.MaxIndex,'Data',MaxIndex)
2165SeriesData=get(handles.series,'UserData');
2166SeriesData.i1_series{iview}=i1_series;
2167SeriesData.i2_series{iview}=i2_series;
2168SeriesData.j1_series{iview}=j1_series;
2169SeriesData.j2_series{iview}=j2_series;
2170SeriesData.FileType{iview}=FileType;
2171
2172%% display the set of existing files as an image
2173set(handles.Waitbar,'Units','pixels')
2174pos=get(handles.Waitbar,'Position');
2175xima=0.5:pos(3)-0.5;% pixel positions on the image representing the existing file indices
2176yima=0.5:pos(4)-0.5;
2177[XIma,YIma]=meshgrid(xima,yima);
2178nb_i=size(i1_series,1);
2179nb_j=size(i1_series,2);
2180ind_i=(0.5:nb_i-0.5)*pos(3)/nb_i;
2181ind_j=(0.5:nb_j-0.5)*pos(4)/nb_j;
2182[Ind_i,Ind_j]=meshgrid(ind_i,ind_j);
2183CData=zeros([size(XIma) 3]);
2184file_ima=double((i1_series(:,:,1)>0)');
2185if numel(file_ima)>=2
2186if size(file_ima,1)==1
2187    CLine=interp1(ind_i,file_ima,xima,'nearest');
2188    CData(:,:,2)=ones(size(yima'))*CLine;
2189else
2190    CData(:,:,2)=interp2(Ind_i,Ind_j,file_ima,XIma,YIma,'nearest');
2191end
2192set(handles.Waitbar,'CData',CData)
2193end
2194set(handles.Waitbar,'Units','normalized')
2195
2196%% enable field and veltype menus
2197% testfield=isequal(get(handles.FieldName,'enable'),'on');
2198% testfield_1=isequal(get(handles.FieldName_1,'enable'),'on');
2199% testveltype=isequal(get(handles.VelType,'enable'),'on');
2200% testveltype_1=isequal(get(handles.VelType_1,'enable'),'on');
2201% testtransform=isequal(get(handles.TransformName,'Enable'),'on');
2202% testnc=0;
2203% testnc_1=0;
2204% testcivx=0;
2205% testcivx_1=0;
2206% testima=0; %test for image input
2207% if isequal(lower(FileExt),'.avi') %.avi file
2208%     testima=1;
2209% elseif ~isempty(imformats(FileExt(2:end)))
2210%     testima=1;
2211% elseif isequal(FileExt,'.vol')
2212%      testima=1;
2213% end
2214%TODO: update
2215% if length(FileExtCell)==1 || length(FileExtCell)>2
2216%     for iview=1:length(FileExtCell)
2217%         if isequal(FileExtCell{iview},'.nc')
2218%             testnc=1;
2219%         end
2220%         if isequal(FileTypeCell{iview},'civx')
2221%             testcivx=1;
2222%         end
2223%     end
2224% elseif length(FileExtCell)==2
2225%     testnc=isequal(FileExtCell{1},'.nc');
2226%     testnc_1=isequal(FileExtCell{2},'.nc');
2227%     testcivx=isequal(FileTypeCell{1},'civx');
2228%     testcivx_1=isequal(FileTypeCell{2},'civx');
2229% end
2230switch FileType
2231    case {'civx','civdata'}
2232    %view_FieldMenu(handles,'on')
2233    menustr=get(handles.FieldName,'String');
2234    if isequal(menustr,{'get_field...'})
2235        set(handles.FieldName,'String',{'get_field...';'velocity';'vort';'div';'more...'})
2236    end
2237    set(handles.VelType,'Visible','on')
2238    set(handles.FieldTransform,'Visible','on')
2239    %      view_TRANSFORM(handles,'on')
2240    %     TODO: second menu
2241    %           view_FieldMenu_1(handles,'on')
2242    %     if testcivx_1
2243    %         menustr=get(handles.FieldName_1,'String');
2244    %         if isequal(menustr,{'get_field...'})
2245    %             set(handles.FieldName_1,'String',{'get_field...';'velocity';'vort';'div';'more...'})
2246    %         end
2247    %     else
2248    %         set(handles.FieldName_1,'Value',1)
2249    %         set(handles.FieldName_1,'String',{'get_field...'})
2250    %     set(handles.VelType_1,'Visible','on')
2251    %     set(handles.VelType_text_1,'Visible','on');
2252    %     end
2253    %     view_FieldMenu_1(handles,'off')
2254    case 'netcdf'
2255  %  view_FieldMenu(handles,'on')
2256    set(handles.FieldName,'Value',1)
2257    set(handles.FieldName,'String',{'get_field...'})
2258    set(handles.FieldTransform,'Visible','off')
2259    %     view_TRANSFORM(handles,'off')
2260    case {'image','multimage','video'}
2261%    view_FieldMenu(handles,'off')
2262 %   view_FieldMenu_1(handles,'off')
2263    set(handles.VelType,'Visible','off')
2264    set(handles.VelType_text,'Visible','off');
2265end
2266
2267
2268%TODO:update
2269% if ~isequal(FileExt,'.nc') && ~isequal(FileExt,'.cdf') && ~testima
2270%     msgbox_uvmat('ERROR',['invalid input file extension ' FileExt])
2271%     return
2272% end 
2273
2274%%  read image documentation file  if found%%%%%%%%%%%%%%%%%%%%%%%%%%%
2275ext_imadoc='';
2276FileBase=fullfile(RootPath,RootFile);
2277if isequal(FileExt,'.xml')||isequal(FileExt,'.civ')
2278    ext_imadoc=FileExt;
2279elseif exist([FileBase '.xml'],'file')
2280    ext_imadoc='.xml';
2281elseif exist([FileBase '.civ'],'file')
2282    ext_imadoc='.civ';
2283end
2284%read the ImaDoc file
2285XmlData=[];
2286NbSlice_calib={};
2287if isequal(ext_imadoc,'.xml')
2288        [XmlData,warntext]=imadoc2struct([FileBase '.xml']);
2289        if isfield(XmlData,'Heading') && isfield(XmlData.Heading,'ImageName') && ischar(XmlData.Heading.ImageName)
2290            [PP,FF,ext_ima_read]=fileparts(XmlData.Heading.ImageName);
2291        end
2292        if isfield(XmlData,'Time')
2293            time{iview}=XmlData.Time;
2294        end
2295        if isfield(XmlData,'Camera')
2296            if isfield(XmlData.Camera,'NbSlice')&& ~isempty(XmlData.Camera.NbSlice)
2297                NbSlice_calib{iview}=XmlData.Camera.NbSlice;% Nbre of slices for Zindex in phys transform
2298                if ~isequal(NbSlice_calib{iview},NbSlice_calib{1})
2299                    msgbox_uvmat('WARNING','inconsistent number of Z indices for the two field series');
2300                end
2301            end
2302            if isfield(XmlData.Camera,'TimeUnit')&& ~isempty(XmlData.Camera.TimeUnit)
2303                TimeUnit=XmlData.Camera.TimeUnit;
2304            end
2305        end
2306        if ~isempty(warntext)
2307            msgbox_uvmat('WARNING',warntext)
2308        end 
2309elseif isequal(ext_imadoc,'.civ')
2310    [error,XmlData.Time,TimeUnit,mode,npx,npy,pxcmx,pxcmy]=read_imatext([FileBase '.civ']);
2311    time{iview}=XmlData.Time;
2312    if error==2, warntext=['no file ' FileBase '.civ'];
2313    elseif error==1, warntext='inconsistent number of fields in the .civ file';
2314    end 
2315end
2316
2317%% update time table
2318TimeTable=get(handles.TimeTable,'Data');
2319TimeTable{iview,1}=time(MinIndex_i,MinIndex_j);
2320TimeTable{iview,4}=time(MaxIndex_i,MaxIndex_j);
2321set(handles.TimeTable,'Data',TimeTable)
2322
2323%% number of slices
2324if isfield(XmlData,'GeometryCalib') && isfield(XmlData.GeometryCalib,'SliceCoord')
2325       siz=size(XmlData.GeometryCalib.SliceCoord);
2326       if siz(1)>1
2327           NbSlice=siz(1);
2328       else
2329           NbSlice=1;
2330       end
2331       set(handles.num_NbSlice,'String',num2str(NbSlice))
2332end
2333% set(handles.mode,'Visible','off') % do not show index pairstring by default
2334set(handles.PairString,'Visible','off')
2335% set(handles.num_ref_i,'Visible','off')
2336% set(handles.ref_i_text,'Visible','off')
2337testpair=0;
2338%set the menus of image pairstring and default selection for series
2339%list pairstring if relevant
2340% Val=get(handles.NomType,'Value');
2341% synchronise_view(handles,Val)
2342
2343% if ~isfield(SeriesData,'j1_series')||isempty(SeriesData.j1_series{index})
2344%     state_j='off'; %no need for j index
2345% else
2346%     state_j='on'; %case of j index
2347% end
2348% show index pairstring if files exist
2349set(handles.series,'UserData',SeriesData)
2350
2351
2352% --------------------------------------------------------------------
2353function MenuExportConfig_Callback(hObject, eventdata, handles)
2354global Series
2355[tild,Series,errormsg]=prepare_jobs(handles,0);
2356% Series=read_GUI(handles.series);
2357
2358evalin('base','global Series')%make CurData global in the workspace
2359display('current series config :')
2360evalin('base','Series') %display CurData in the workspace
2361commandwindow; %brings the Matlab command window to the front
2362
2363
2364% --- Executes on selection change in RunMode.
2365function RunMode_Callback(hObject, eventdata, handles)
Note: See TracBrowser for help on using the repository browser.