source: trunk/src/series.m @ 715

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

improvements in 'series'

File size: 124.2 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)
62
63% Choose default command line output for series
64handles.output = hObject;
65% Update handles structure
66guidata(hObject, handles);
67
68%% initial settings
69% position and  size of the GUI at opening
70set(0,'Unit','points')
71ScreenSize=get(0,'ScreenSize');%size of the current screen, in points (1/72 inch)
72Width=900;% prefered width of the GUI in points (1/72 inch)
73Height=624;% prefered height of the GUI in points (1/72 inch)
74%adjust to screen size (reduced by a min margin)
75RescaleFactor=min((ScreenSize(3)-80)/Width,(ScreenSize(4)-80)/Height);
76if RescaleFactor>1
77    RescaleFactor=min(RescaleFactor,1);
78end
79Width=Width*RescaleFactor;
80Height=Height*RescaleFactor;
81LeftX=80*RescaleFactor;%position of the left fig side, in pixels (put to the left side, with some margin)
82LowY=round(ScreenSize(4)/2-Height/2); % put at the middle height on the screen
83set(hObject,'Units','points')
84set(hObject,'Position',[LeftX LowY Width Height])% position and size of the GUI at opening
85
86% settings of table MinIndex_j
87set(handles.MinIndex_i,'ColumnFormat',{'numeric'})
88set(handles.MinIndex_i,'ColumnEditable',false)
89set(handles.MinIndex_i,'ColumnName',{'i min'})
90set(handles.MinIndex_i,'Data',[])% initiate Data to double (not cell)
91
92% settings of table MinIndex_j
93set(handles.MinIndex_j,'ColumnFormat',{'numeric'})
94set(handles.MinIndex_j,'ColumnEditable',false)
95set(handles.MinIndex_j,'ColumnName',{'j min'})
96set(handles.MinIndex_j,'Data',[])% initiate Data to double (not cell)
97
98% settings of table MaxIndex_i
99set(handles.MaxIndex_i,'ColumnFormat',{'numeric'})
100set(handles.MaxIndex_i,'ColumnEditable',false)
101set(handles.MaxIndex_i,'ColumnName',{'i max'})
102set(handles.MaxIndex_i,'Data',[])% initiate Data to double (not cell)
103
104% settings of table MaxIndex_j
105set(handles.MaxIndex_j,'ColumnFormat',{'numeric'})
106set(handles.MaxIndex_j,'ColumnEditable',false)
107set(handles.MaxIndex_j,'ColumnName',{'j max'})
108set(handles.MaxIndex_j,'Data',[])% initiate Data to double (not cell)
109
110% settings of table PairString
111set(handles.PairString,'ColumnName',{'pairs'})
112set(handles.PairString,'ColumnEditable',false)
113set(handles.PairString,'ColumnFormat',{'char'})
114set(handles.PairString,'Data',{''})
115
116% settings of table MaskTable
117set(handles.MaskTable,'ColumnName',{'mask name'})
118set(handles.PairString,'ColumnEditable',false)
119set(handles.PairString,'ColumnFormat',{'char'})
120set(handles.PairString,'Data',{''})
121
122series_ResizeFcn(hObject, eventdata, handles)%resize table according to series GUI size
123set(hObject,'WindowButtonDownFcn',{'mouse_down'})%allows mouse action with right button (zoom for uicontrol display)
124set(handles.InputTable,'KeyPressFcn',{@key_press_fcn,handles})%set keyboard action function (allow action on uvmat when set_object is in front)
125set(hObject,'DeleteFcn',{@closefcn})%
126
127% check default input data
128if ~exist('Param','var')
129    Param=[]; %default
130end
131
132%% list of builtin functions in the mebu ActionName
133ActionList={'check_data_files';'aver_stat';'time_series';'civ_series';'merge_proj'};% WARNING: fits with nb_builtin_ACTION=4 in ActionName_callback
134NbBuiltinAction=numel(ActionList);
135[path_series,name,ext]=fileparts(which('series'));% path to the GUI series
136path_series_fct=fullfile(path_series,'series');%path of the functions in subdirectroy 'series'
137ActionExtList={'.m';'.sh'};% default choice of extensions (Matlab fct .m or compiled version .sh
138ActionPathList=cell(NbBuiltinAction,numel(ActionExtList));%initiate the cell matrix of Action fct paths
139ActionPathList(:)={path_series_fct}; %set the default path to series fcts to all list members
140RunModeList={'local';'background'};% default choice of extensions (Matlab fct .m or compiled version .sh)
141[s,w]=system('oarstat');% look for cluster system 'oar'
142if isequal(s,0)
143    RunModeList=[RunModeList;{'cluster_oar'}];
144end
145[s,w]=system('qstat');% look for cluster system 'sge'
146if isequal(s,0)
147    RunModeList=[RunModeList;{'cluster_sge'}];
148end
149set(handles.RunMode,'String',RunModeList)
150
151%% list of builtin transform functions in the mebu TransformName
152TransformList={'';'sub_field';'phys';'phys_polar'};% WARNING: must fit with the corresponding menu in uvmat and nb_builtin_transform=4 in  TransformName_callback
153NbBuiltinTransform=numel(TransformList);
154path_transform_fct=fullfile(path_series,'transform_field');
155TransformPathList=cell(NbBuiltinTransform,1);%initiate the cell matrix of Action fct paths
156TransformPathList(:)={path_transform_fct}; %set the default path to series fcts to all list members
157
158%% get the user defined functions stored in the personal file uvmat_perso.mat
159dir_perso=prefdir;
160profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
161if exist(profil_perso,'file')
162    h=load (profil_perso);
163    %get the list of previous input files in the upper bar menu Open
164    if isfield(h,'MenuFile')
165        for ifile=1:min(length(h.MenuFile),5)
166            set(handles.(['MenuFile_' num2str(ifile)]),'Label',h.MenuFile{ifile});
167            set(handles.(['MenuFile_' num2str(ifile+5)]),'Label',h.MenuFile{ifile});
168        end
169    end
170    %get the list of previous camapigns in the upper bar menu Open campaign
171    if isfield(h,'MenuCampaign')
172        for ifile=1:min(length(h.MenuCampaign),5)
173            set(handles.(['MenuCampaign_' num2str(ifile)]),'Label',h.MenuCampaign{ifile});
174        end
175    end
176    %get the menu of actions
177    if isfield(h,'ActionExtListUser') && iscell(h.ActionExtListUser)
178        ActionExtList=[ActionExtList; h.ActionExtListUser];
179    end
180    if isfield(h,'ActionListUser') && iscell(h.ActionListUser) && isfield(h,'ActionPathListUser') && iscell(h.ActionPathListUser)
181        ActionList=[ActionList;h.ActionListUser];
182        ActionPathList=[ActionPathList;h.ActionPathListUser];
183    end
184    %get the menu of transform fct
185    if isfield(h,'TransformListUser') && iscell(h.TransformListUser) && isfield(h,'TransformPathListUser') && iscell(h.TransformPathListUser)
186        TransformList=[TransformList;h.TransformListUser];
187        TransformPathList=[TransformPathList;h.TransformPathListUser];
188    end
189end
190
191%% selection of the input Action fct
192ActionCheckExist=true(size(ActionList));%initiate the check of the path to the listed action fct
193for ilist=NbBuiltinAction+1:numel(ActionList)%check  the validity of the path of the user defined Action fct
194    ActionCheckExist(ilist)=exist(fullfile(ActionPathList{ilist},[ActionList{ilist} '.m']),'file');
195end
196ActionPathList=ActionPathList(ActionCheckExist,:);% suppress the menu options which are not valid anymore
197ActionList=ActionList(ActionCheckExist);
198set(handles.ActionName,'String',[ActionList;{'more...'}])
199set(handles.ActionName,'UserData',ActionPathList)
200ActionIndex=[];
201if isfield(Param,'ActionName')% copy the selected menu index transferred in Param from uvmat
202    ActionIndex=find(strcmp(Param.ActionName,ActionList),1);
203end
204if isempty(ActionIndex)
205    ActionIndex=1;
206end
207set(handles.ActionName,'Value',ActionIndex)
208set(handles.ActionPath,'String',ActionPathList{ActionIndex})
209set(handles.ActionExt,'Value',1)
210set(handles.ActionExt,'String',ActionExtList)
211
212%% selection of the input transform fct
213TransformCheckExist=true(size(TransformList));
214for ilist=NbBuiltinTransform+1:numel(TransformList)
215    TransformCheckExist(ilist)=exist(fullfile(TransformPathList{ilist},[TransformList{ilist} '.m']),'file');
216end
217TransformPathList=TransformPathList(TransformCheckExist);
218TransformList=TransformList(TransformCheckExist);
219set(handles.TransformName,'String',[TransformList;{'more...'}])
220set(handles.TransformName,'UserData',TransformPathList)
221TransformIndex=[];
222if isfield(Param,'TransformName')% copy the selected menu index transferred in Param from uvmat
223    TransformIndex=find(strcmp(Param.TransformName,TransformList),1);
224end
225if isempty(TransformIndex)
226    TransformIndex=1;
227end
228set(handles.TransformName,'Value',TransformIndex)
229set(handles.TransformPath,'String',TransformPathList{TransformIndex})
230   
231%% fields input initialisation
232if isfield(Param,'list_fields')&& isfield(Param,'index_fields') &&~isempty(Param.list_fields) &&~isempty(Param.index_fields)
233    set(handles.FieldName,'String',Param.list_fields);% list menu fields
234    set(handles.FieldName,'Value',Param.index_fields);% selected string index
235end
236if isfield(Param,'Coord_x_str')&& isfield(Param,'Coord_x_val')
237        set(handles.Coord_x,'String',Param.Coord_x_str);% list menu fields
238    set(handles.Coord_x,'Value',Param.Coord_x_val);% selected string index
239end
240if isfield(Param,'Coord_y_str')&& isfield(Param,'Coord_y_val')
241        set(handles.Coord_y,'String',Param.Coord_y_str);% list menu fields
242    set(handles.Coord_y,'Value',Param.Coord_y_val);% selected string index
243end
244
245%% introduce the input file name(s) if defined from input Param
246if isfield(Param,'FileName')&&~isempty(Param.FileName)
247    %InputTable={'','','','',''}; % refresh the file input table
248    InputTable={}
249    set(handles.InputTable,'Data',InputTable)
250    if isfield(Param,'FileName_1')
251        display_file_name(handles,Param.FileName,'one')%refresh the input table
252        display_file_name(handles,Param.FileName_1,1)
253    else
254        display_file_name(handles,Param.FileName,'one')%refresh the input table
255    end
256end 
257if isfield(Param,'incr_i')
258    set(handles.num_incr_i,'String',num2str(Param.incr_i))
259end
260if isfield(Param,'incr_j')
261    set(handles.num_incr_j,'String',num2str(Param.incr_j))
262end
263
264
265%------------------------------------------------------------------------
266% --- Outputs from this function are returned to the command line.
267function varargout = series_OutputFcn(hObject, eventdata, handles)
268%------------------------------------------------------------------------
269varargout{1} = handles.output;
270
271%------------------------------------------------------------------------
272% --- executed when closing uvmat: delete or desactivate the associated figures if exist
273function closefcn(gcbo,eventdata)
274%------------------------------------------------------------------------
275
276% delete set_object_series if detected
277hh=findobj(allchild(0),'name','view_object_series');
278if ~isempty(hh)
279    delete(hh)
280end
281hh=findobj(allchild(0),'name','edit_object_series');
282if ~isempty(hh)
283    delete(hh)
284end
285
286%delete the bowser if detected
287hh=findobj(allchild(0),'tag','browser');
288if ~isempty(hh)
289    delete(hh)
290end
291
292
293%------------------------------------------------------------------------
294%------------------------------------------------------------------------
295%  II - FUNCTIONS FOR INTRODUCING THE INPUT FILES
296% automatically sets the global properties when the rootfile name is introduced
297% then activate the view-field actionname if selected
298% it is activated either by clicking on the RootPath window or by the
299% browser
300%------------------------------------------------------------------------
301%------------------------------------------------------------------------
302% --- fct activated by the browser under 'Open'
303%------------------------------------------------------------------------ 
304function MenuBrowse_Callback(hObject, eventdata, handles)
305%% look for the previously opened file 'oldfile'
306InputTable=get(handles.InputTable,'Data');
307oldfile=InputTable{1,1};
308if isempty(oldfile)
309    % use a file name stored in prefdir
310    dir_perso=prefdir;
311    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
312    if exist(profil_perso,'file')
313        h=load (profil_perso);
314        if isfield(h,'RootPath') && ischar(h.RootPath)
315            oldfile=h.RootPath;
316        end
317    end
318end
319%% launch the browser
320fileinput=uigetfile_uvmat('pick a file to append in the input table',oldfile);
321if ~isempty(fileinput)
322      display_file_name(handles,fileinput,'one')
323end
324
325% --------------------------------------------------------------------
326function MenuBrowseAppend_Callback(hObject, eventdata, handles)
327
328%% look for the previously opened file 'oldfile'
329InputTable=get(handles.InputTable,'Data');
330RootPathCell=InputTable(:,1);
331if isempty(RootPathCell{1})% no input file in the table
332     MenuBrowse_Callback(hObject, eventdata, handles)%refresh the input table, not append
333     return
334end
335SubDirCell=InputTable(:,2);
336oldfile=fullfile(RootPathCell{1},SubDirCell{1});
337
338%% use a file name stored in prefdir
339dir_perso=prefdir;
340profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
341if exist(profil_perso,'file')
342    h=load (profil_perso);
343    if isfield(h,'RootPath') && ischar(h.RootPath)
344        oldfile=h.RootPath;
345    end
346end
347
348%% launch the browser
349fileinput=uigetfile_uvmat('pick a file to append in the input table',oldfile);
350if ~isempty(fileinput)
351        display_file_name(handles,fileinput,'append')
352end
353
354%------------------------------------------------------------------------
355% --- fct activated by selecting a previous file under the menu Open
356%------------------------------------------------------------------------
357function MenuFile_Callback(hObject, eventdata, handles)
358
359errormsg=display_file_name(handles,get(hObject,'Label'),'one');
360if ~isempty(errormsg)
361    set(hObject,'Label','')
362    MenuFile=[{get(handles.MenuFile_1,'Label')};{get(handles.MenuFile_2,'Label')};...
363        {get(handles.MenuFile_3,'Label')};{get(handles.MenuFile_4,'Label')};{get(handles.MenuFile_5,'Label')}];
364    str_find=strcmp(get(hObject,'Label'),MenuFile);
365    MenuFile(str_find)=[];% suppress the input file to the list
366    for ifile=1:numel(MenuFile)
367        set(handles.(['MenuFile_' num2str(ifile)]),'Label',MenuFile{ifile});
368    end
369end
370
371%------------------------------------------------------------------------
372% --- fct activated by selecting a previous file under the menu Open/append
373%------------------------------------------------------------------------
374function MenuFile_append_Callback(hObject, eventdata, handles)
375
376InputTable=get(handles.InputTable,'Data');
377if isempty(InputTable{1,1})% no input file in the table
378    display_file_name(handles,get(hObject,'Label'),'one') %refresh the input table, not append
379else
380    display_file_name(handles,get(hObject,'Label'),'append')% append the selected file to the current list of InputTable
381end
382
383%------------------------------------------------------------------------
384% --- fct activated by the browser under 'Open campaign'
385%------------------------------------------------------------------------
386function MenuBrowseCampaign_Callback(hObject, eventdata, handles)
387
388set(handles.MenuOpenCampaign,'ForegroundColor',[1 1 0])
389drawnow
390InputTable=get(handles.InputTable,'Data');
391RootPath=InputTable{1,1};
392CampaignPath=fileparts(fileparts(RootPath));
393DirFull=uigetfile_uvmat('define this path as the Campaign folder:',CampaignPath,'uigetdir');
394if ~ischar(DirFull)|| ~exist(DirFull,'dir')
395    return
396end
397OutPut=browse_data(DirFull);% open the GUI browse_data to get select a campaign dir, experiment and device
398if ~isfield(OutPut,'Campaign')
399    return
400end
401DirName=fullfile(OutPut.Campaign,OutPut.Experiment{1},OutPut.DataSeries{1});
402ListStruct=dir(DirName); %list files and the dir DataSeries
403% select the first appropriate file in the dir
404FileName='';
405for ilist=1:numel(ListStruct)
406    if ~isequal(ListStruct(ilist).isdir,1)%look for files, not dir
407        FileName=ListStruct(ilist).name;
408        FileType=get_file_type(fullfile(DirName,FileName));
409        switch FileType
410            case {'image','multimage','civx','civdata','netcdf'}
411                break
412        end
413    end
414end
415if isempty(FileName)
416    msgbox_uvmat('ERROR',['no appropriate input file in the DataSeries folder ' fullfile(DirName)])
417    return
418end
419
420%% update the list of campaigns in the menubar
421MenuCampaign=[{get(handles.MenuCampaign_1,'Label')};{get(handles.MenuCampaign_2,'Label')};...
422    {get(handles.MenuCampaign_3,'Label')};{get(handles.MenuCampaign_4,'Label')};{get(handles.MenuCampaign_5,'Label')}];
423check_dir=isempty(find(strcmp(DirFull,MenuCampaign)));
424if check_dir %insert the new campaign in the list if it is not found
425    MenuCampaign(end)=[]; %suppress the last item
426    MenuCampaign=[{DirFull};MenuCampaign];%insert the new campaign
427    for ilist=1:numel(MenuCampaign)
428        set(handles.(['MenuCampaign_' num2str(ilist)]),'Label',MenuCampaign{ilist})
429    end
430    % save the list for future opening:
431    dir_perso=prefdir;
432    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
433    if exist(profil_perso,'file')
434        save (profil_perso,'MenuCampaign','RootPath','-append'); %store the file names for future opening of uvmat
435    else
436        save (profil_perso,'MenuCampaign','RootPath','-V6'); %store the file names for future opening of uvmat
437    end
438end
439
440%% display the selected field and related information
441if get(handles.CheckAppend,'Value')
442    display_file_name(handles,fullfile(DirName,FileName),'append')
443else
444    display_file_name(handles,fullfile(DirName,FileName),'one')
445end
446set(handles.MenuOpenCampaign,'ForegroundColor',[0 0 0])
447
448% --------------------------------------------------------------------
449function MenuCampaign_Callback(hObject, eventdata, handles)
450% --------------------------------------------------------------------
451set(handles.MenuOpenCampaign,'ForegroundColor',[1 1 0])
452OutPut=browse_data(get(hObject,'Label'));% open the GUI browse_data to get select a campaign dir, experiment and device
453if ~isfield(OutPut,'Campaign')
454    return
455end
456DirName=fullfile(OutPut.Campaign,OutPut.Experiment{1},OutPut.DataSeries{1});
457hdir=dir(DirName); %list files and dirs
458for ilist=1:numel(hdir)
459    if ~isequal(hdir(ilist).isdir,1)%look for files, not dir
460        FileName=hdir(ilist).name;
461        FileType=get_file_type(fullfile(DirName,FileName));
462        switch FileType
463            case {'image','multimage','civx','civdata','netcdf'}
464            break
465        end
466    end
467end
468if get(handles.CheckAppend,'Value')
469    display_file_name(handles,fullfile(DirName,FileName),'append')
470else
471    display_file_name(handles,fullfile(DirName,FileName),'one')
472end
473set(handles.MenuOpenCampaign,'ForegroundColor',[0 0 0])
474
475
476
477%------------------------------------------------------------------------
478% --- Executes when entered data in editable cell(s) in InputTable.
479function InputTable_CellEditCallback(hObject, eventdata, handles)
480%------------------------------------------------------------------------
481set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH button to magenta color to indicate that input refresh is needed
482% set(handles.REFRESH_title,'Visible','on')
483iview=eventdata.Indices(1);
484view_set=get(handles.REFRESH,'UserData');
485if isempty(find(view_set==iview))
486    set(handles.REFRESH,'UserData',[view_set iview])
487end
488%% enable other menus and uicontrols
489set(handles.MenuOpenCampaign,'Enable','on')
490set(handles.MenuCampaign_1,'Enable','on')
491set(handles.MenuCampaign_2,'Enable','on')
492set(handles.MenuCampaign_3,'Enable','on')
493set(handles.MenuCampaign_4,'Enable','on')
494set(handles.MenuCampaign_5,'Enable','on')
495set(handles.RUN, 'Enable','On')
496set(handles.RUN,'BackgroundColor',[1 0 0])% set RUN button to red
497
498%------------------------------------------------------------------------
499% --- 'key_press_fcn:' function activated when a key is pressed on the keyboard
500%------------------------------------------------------------------------
501function key_press_fcn(hObject,eventdata,handles)
502
503xx=double(get(handles.series,'CurrentCharacter')); %get the keyboard character
504if ismember(xx,[8 127 31])%backspace or delete, or downward
505    InputTable=get(handles.InputTable,'Data');
506    iline=get(handles.InputTable,'UserData');
507            if isequal(xx, 31)
508                if isequal(iline,size(InputTable,1))% arrow downward
509                InputTable=[InputTable;cell(1,size(InputTable,2))];
510                end
511            else
512    InputTable(iline,:)=[];% suppress the current line
513            end
514    set(handles.InputTable,'Data',InputTable);
515end
516
517
518%------------------------------------------------------------------------
519% --- Executes on button press in REFRESH.
520function REFRESH_Callback(hObject, eventdata, handles)
521%------------------------------------------------------------------------
522InputTable=get(handles.InputTable,'Data');
523set(handles.series,'Pointer','watch') % set the mouse pointer to 'watch'
524set(handles.REFRESH,'BackgroundColor',[1 1 0])% set REFRESH  button to yellow color (indicate activation)
525drawnow
526empty_line=false(size(InputTable,1),1);
527for iline=1:size(InputTable,1)
528    empty_line(iline)= isempty(cell2mat(InputTable(iline,1:3)));
529end
530InputTable(empty_line,:)=[];%remove empty lines
531set(handles.InputTable,'Data',InputTable)
532for iview=1:size(InputTable,1)
533    RootPath=fullfile(InputTable{iview,1},InputTable{iview,2});
534    if ~exist(RootPath,'dir')
535        i1_series=[];
536        RootPath=fileparts(RootPath); %will try the upper folder
537    else %scan the input folder
538        [RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,tild,FileType,FileInfo,MovieObject]=...
539            find_file_series(fullfile(InputTable{iview,1},InputTable{iview,2}),[InputTable{iview,3} InputTable{iview,4} InputTable{iview,5}]);
540    end
541    % if no file is found, open a browser
542    if isempty(i1_series)
543        fileinput=uigetfile_uvmat(['wrong input at line ' num2str(iview) ':pick a new input file'],RootPath);
544        if isempty(fileinput)
545            set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  back to red color
546            return
547        else
548            display_file_name(handles,fileinput,iview)
549        end
550    else
551       update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,FileInfo,MovieObject,iview)
552    end
553end
554set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (indicate activation finished)
555set(handles.series,'Pointer','arrow') % set the mouse pointer to 'watch'
556
557%------------------------------------------------------------------------
558% --- Function called when a new file is opened, either by series_OpeningFcn or by the browser
559function errormsg=display_file_name(handles,fileinput,iview)
560%------------------------------------------------------------------------ 
561%
562% INPUT:
563% handles: handles of elements in the GUI
564% fileinput: input file name, including path
565% iview: line index in the input table
566%       or 'one': refresh the list
567%         'append': add a new line to the input table
568set(handles.REFRESH,'BackgroundColor',[1 1 0])% set REFRESH  button to yellow color (indicate activation)
569drawnow
570errormsg='';%default
571%% get the input root name, indices, file extension and nomenclature NomType
572if ~exist(fileinput,'file')
573    errormsg=['input file ' fileinput  ' does not exist'];
574    msgbox_uvmat('ERROR',errormsg)
575    set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (end of activation)
576    return
577end
578
579%% detect root name, nomenclature and indices in the input file name:
580[FilePath,FileName,FileExt]=fileparts(fileinput);
581% detect the file type, get the movie object if relevant, and look for the corresponding file series:
582% the root name and indices may be corrected by including the first index i1 if a corresponding xml file exists
583[RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,NomType,FileType,FileInfo,MovieObject,i1,i2,j1,j2]=find_file_series(FilePath,[FileName FileExt]);
584if isempty(RootFile)&&isempty(i1_series)
585    errormsg='no input file in the series';
586    msgbox_uvmat('ERROR',errormsg)
587    set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (end of activation)
588    return
589end
590if strcmp(FileType,'txt')
591    edit(fileinput)
592    set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (end of activation)
593    return
594elseif strcmp(FileType,'xml')
595    editxml(fileinput)
596    set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (end of activation)
597     return
598elseif strcmp(FileType,'figure')
599    open(fileinput)
600    set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (end of activation)
601     return
602end
603
604%% enable other menus and uicontrols
605set(handles.MenuOpenCampaign,'Enable','on')
606set(handles.MenuCampaign_1,'Enable','on')
607set(handles.MenuCampaign_2,'Enable','on')
608set(handles.MenuCampaign_3,'Enable','on')
609set(handles.MenuCampaign_4,'Enable','on')
610set(handles.MenuCampaign_5,'Enable','on')
611set(handles.RUN, 'Enable','On')
612set(handles.RUN,'BackgroundColor',[1 0 0])% set RUN button to red
613set(handles.InputTable,'BackgroundColor',[1 1 0]) % set RootPath edit box  to yellow
614drawnow
615
616
617
618%% fill the list of file series
619InputTable=get(handles.InputTable,'Data');
620SeriesData=get(handles.series,'UserData');
621if strcmp(iview,'append') % display the input data as a new line in the table
622    iview=size(InputTable,1)+1;% the next line in InputTable becomes the current line
623    %InputTable(iview+1,:)={'','','','',''};
624    InputTable(iview,:)=[{RootPath},{SubDir},{RootFile},{NomType},{FileExt}];
625elseif strcmp(iview,'one') % refresh the list of  input  file series
626    iview=1; %the first line in InputTable becomes the current line
627    InputTable={'','','','',''};
628    %InputTable=[{'','','','',''};{'','','','',''}];
629    InputTable(iview,:)=[{RootPath},{SubDir},{RootFile},{NomType},{FileExt}];
630    set(handles.TimeTable,'Data',[{[]},{[]},{[]},{[]}])
631    set(handles.MinIndex_i,'Data',[])
632    set(handles.MaxIndex_i,'Data',[])
633    set(handles.MinIndex_j,'Data',[])
634    set(handles.MaxIndex_j,'Data',[])
635    set(handles.ListView,'Value',1)
636    set(handles.ListView,'String',{'1'})
637    set(handles.PairString,'Data',{''})
638    SeriesData.i1_series={};
639    SeriesData.i2_series={};
640    SeriesData.j1_series={};
641    SeriesData.j2_series={};
642    SeriesData.FileType={};
643    SeriesData.FileInfo={};
644    SeriesData.Time={};
645end
646%nbview=size(InputTable,1)-1;% rmq: the last line is set blank to allow manual addition of a line
647nbview=size(InputTable,1);
648set(handles.ListView,'String',mat2cell((1:nbview)',ones(nbview,1)))
649set(handles.ListView,'Value',iview)
650set(handles.InputTable,'Data',InputTable)
651
652%% determine the selected reference field indices for pair display
653if isempty(i1)
654    i1=1;
655end
656if isempty(i2)
657    i2=i1;
658end
659ref_i=floor((i1+i2)/2);% reference image number corresponding to the file
660set(handles.num_ref_i,'String',num2str(ref_i));
661% set(handles.num_ref_i,'UserData',[i1 i2])%store the indices for future opening
662if isempty(j1)
663    j1=1;
664end
665if isempty(j2)
666    j2=j1;
667end
668ref_j=floor((j1+j2)/2);% reference image number corresponding to the file
669set(handles.num_ref_j,'String',num2str(ref_j));
670
671%% update first and last indices if they do not exist
672Param=read_GUI(handles.series);
673first_j=[];
674if isfield(Param.IndexRange,'first_j'); first_j=Param.IndexRange.first_j; end
675last_j=[];
676if isfield(Param.IndexRange,'last_j'); last_j=Param.IndexRange.last_j; end
677PairString='';
678if isfield(Param.IndexRange,'PairString'); PairString=Param.IndexRange.PairString; end
679[i1,i2,j1,j2] = get_file_index(Param.IndexRange.first_i,first_j,PairString);
680FirstFileName=fullfile_uvmat(Param.InputTable{1,1},Param.InputTable{1,2},Param.InputTable{1,3},...
681    Param.InputTable{1,5},Param.InputTable{1,4},i1,i2,j1,j2);
682if ~exist(FirstFileName,'file')
683    set(handles.num_first_i,'String',num2str(ref_i))
684    set(handles.num_first_j,'String',num2str(ref_j))
685end
686[i1,i2,j1,j2] = get_file_index(Param.IndexRange.last_i,last_j,PairString);
687LastFileName=fullfile_uvmat(Param.InputTable{1,1},Param.InputTable{1,2},Param.InputTable{1,3},...
688    Param.InputTable{1,5},Param.InputTable{1,4},i1,i2,j1,j2);
689if ~exist(LastFileName,'file')
690    set(handles.num_last_i,'String',num2str(ref_i))
691    set(handles.num_last_j,'String',num2str(ref_j))
692end
693
694%% update the list of recent files in the menubar and save it for future opening
695MenuFile=[{get(handles.MenuFile_1,'Label')};{get(handles.MenuFile_2,'Label')};...
696    {get(handles.MenuFile_3,'Label')};{get(handles.MenuFile_4,'Label')};{get(handles.MenuFile_5,'Label')}];
697str_find=strcmp(fileinput,MenuFile);
698if isempty(find(str_find,1))
699    MenuFile=[{fileinput};MenuFile];%insert the current file if not already in the list
700end
701for ifile=1:min(length(MenuFile),5)
702    eval(['set(handles.MenuFile_' num2str(ifile) ',''Label'',MenuFile{ifile});'])
703end
704dir_perso=prefdir;
705profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
706if exist(profil_perso,'file')
707    save (profil_perso,'MenuFile','-append'); %store the file names for future opening of uvmat
708else
709    save (profil_perso,'MenuFile','-V6'); %store the file names for future opening of uvmat
710end
711% save the opened file to initiate future opening
712SeriesData.RefFile{iview}=fileinput;% reference opening file for line iview
713SeriesData.Ref_i1=i1;
714SeriesData.Ref_i2=i2;
715SeriesData.Ref_j1=j1;
716SeriesData.Ref_j2=j2;
717set(handles.series,'UserData',SeriesData)
718
719set(handles.InputTable,'BackgroundColor',[1 1 1])
720
721%% initiate input file series and refresh the current field view:     
722update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,FileInfo,MovieObject,iview);
723set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (end of activation)
724
725%------------------------------------------------------------------------
726% --- Update information about a new field series (indices to scan, timing,
727%     calibration from an xml file
728function update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,FileInfo,VideoObject,iview)
729%------------------------------------------------------------------------
730InputTable=get(handles.InputTable,'Data');
731
732%% display the min and max indices for the whole file series
733if size(i1_series,2)==2 && min(min(i1_series(:,1,:)))==0
734    MinIndex_j=1;% index j set to 1 by default
735    MaxIndex_j=1;
736    MinIndex_i=find(i1_series(1,2,:), 1 )-1;% min ref index i detected in the series (corresponding to the first non-zero value of i1_series, except for zero index)
737    MaxIndex_i=find(i1_series(1,2,:),1,'last' )-1;%max ref index i detected in the series (corresponding to the last non-zero value of i1_series)
738else
739    ref_i=squeeze(max(i1_series(1,:,:),[],2));% select ref_j index for each ref_i
740    ref_j=squeeze(max(j1_series(1,:,:),[],3));% select ref_i index for each ref_j
741     MinIndex_i=min(find(ref_i))-1;
742     MaxIndex_i=max(find(ref_i))-1;
743     MaxIndex_j=max(find(ref_j))-1;
744     MinIndex_j=min(find(ref_j))-1;
745    diff_j_max=diff(ref_j);
746    diff_i_max=diff(ref_i);
747    if ~isempty(diff_i_max) && isequal (diff_i_max,diff_i_max(1)*ones(size(diff_i_max)))
748        set(handles.num_incr_i,'String',num2str(diff_i_max(1)))% detect an increment to dispaly by default
749    end
750    if isequal (diff_j_max,diff_j_max(1)*ones(size(diff_j_max)))
751        set(handles.num_incr_j,'String',num2str(diff_j_max(1)))
752    end
753end
754if isequal(MinIndex_i,-1)
755    MinIndex_i=0;
756end
757if isequal(MinIndex_j,-1)
758    MinIndex_j=0;
759end
760MinIndex_i_table=get(handles.MinIndex_i,'Data');%retrieve the min indices in the table MinIndex
761MinIndex_j_table=get(handles.MinIndex_j,'Data');%retrieve the min indices in the table MinIndex
762MaxIndex_i_table=get(handles.MaxIndex_i,'Data');%retrieve the min indices in the table MinIndex
763MaxIndex_j_table=get(handles.MaxIndex_j,'Data');%retrieve the min indices in the table MinIndex
764MinIndex_i_table(iview,1)=MinIndex_i;
765MinIndex_j_table(iview,1)=MinIndex_j;
766MaxIndex_i_table(iview,1)=MaxIndex_i;
767MaxIndex_j_table(iview,1)=MaxIndex_j;
768set(handles.MinIndex_i,'Data',MinIndex_i_table)%display the min indices in the table MinIndex
769set(handles.MinIndex_j,'Data',MinIndex_j_table)%display the max indices in the table MaxIndex
770set(handles.MaxIndex_i,'Data',MaxIndex_i_table)%display the min indices in the table MinIndex
771set(handles.MaxIndex_j,'Data',MaxIndex_j_table)%display the max indices in the table MaxIndex
772
773%% adjust the first and last indices for the selected series, only if requested by the bounds
774% i index, compare input to min index i
775first_i=str2num(get(handles.num_first_i,'String'));%retrieve previous first i
776ref_i=str2num(get(handles.num_ref_i,'String'));%index i given by the input field
777if isempty(first_i)
778    first_i=ref_i;% first_i updated by the input value
779elseif first_i < MinIndex_i
780    first_i=MinIndex_i; % first_i set to the min i index (restricted by oter input lines)
781elseif first_i >MaxIndex_i
782    first_i=MaxIndex_i;% first_i set to the max i index (restricted by oter input lines)
783end
784% j index,  compare input to min index j
785first_j=str2num(get(handles.num_first_j,'String'));
786ref_j=str2num(get(handles.num_ref_j,'String'));%index j given by the input field
787if isempty(first_j)
788    first_j=ref_j;% first_j updated by the input value
789elseif first_j<MinIndex_j
790    first_j=MinIndex_j; % first_j set to the min j index (restricted by oter input lines)
791elseif first_j >MaxIndex_j
792    first_j=MaxIndex_j; % first_j set to the max j index (restricted by oter input lines)
793end
794% i index, compare input to max index i
795last_i=str2num(get(handles.num_last_i,'String'));
796if isempty(last_i)
797    last_i=ref_i;
798elseif last_i > MaxIndex_i
799    last_i=MaxIndex_i;
800elseif last_i<first_i
801    last_i=first_i;
802end
803% j index, compare input to max index j
804last_j=str2num(get(handles.num_last_j,'String'));
805if isempty(last_j)
806    last_j=ref_j;
807elseif last_j>MaxIndex_j
808    last_j=MaxIndex_j;
809elseif last_j<first_j
810    last_j=first_j;
811end
812set(handles.num_first_i,'String',num2str(first_i));
813set(handles.num_first_j,'String',num2str(first_j));
814set(handles.num_last_i,'String',num2str(last_i));
815set(handles.num_last_j,'String',num2str(last_j));
816
817%% number of slices set by default
818NbSlice=1;%default
819% read  value set by the first series for the checkappend mode (iwiew >1)
820if iview>1 && strcmp(get(handles.num_NbSlice,'Visible'),'on')
821    NbSlice=str2num(get(handles.num_NbSlice,'String'));
822end
823
824%% default time unit
825TimeUnit='';
826% read  value set by the first series for the checkappend mode (iwiew >1)
827if iview>1
828    TimeUnit=get(handles.TimeUnit,'String');
829end
830TimeSource='';
831Time=[];%default
832
833%%  read image documentation file if found
834XmlData=[];
835check_calib=0;
836XmlFileName=find_imadoc(InputTable{iview,1},InputTable{iview,2},InputTable{iview,3},InputTable{iview,5});
837if ~isempty(XmlFileName)
838    [XmlData,errormsg]=imadoc2struct(XmlFileName);
839    if ~isempty(errormsg)
840         msgbox_uvmat('WARNING',['error in reading ' XmlFileName ': ' errormsg]);
841    end
842    % read time if available
843    if isfield(XmlData,'Time')
844        Time=XmlData.Time;
845        TimeSource='xml';
846    end
847    if isfield(XmlData,'Camera')
848        if isfield(XmlData.Camera,'NbSlice')&& ~isempty(XmlData.Camera.NbSlice)
849            if iview>1 && ~isempty(NbSlice) && ~strcmp(NbSlice,XmlData.Camera.NbSlice)
850                msgbox_uvmat('WARNING','inconsistent number of slices with the first field series');
851            end
852            NbSlice=XmlData.Camera.NbSlice;% Nbre of slices from camera
853        end
854        if isfield(XmlData.Camera,'TimeUnit')&& ~isempty(XmlData.Camera.TimeUnit)
855            if iview>1 && ~isempty(TimeUnit) && ~strcmp(TimeUnit,XmlData.Camera.TimeUnit)
856                msgbox_uvmat('WARNING','inconsistent time unit with the first field series');
857            end
858            TimeUnit=XmlData.Camera.TimeUnit;
859        end
860    end
861    % number of slices
862    if isfield(XmlData,'GeometryCalib')
863        check_calib=1;
864        if isfield(XmlData.GeometryCalib,'SliceCoord')
865            siz=size(XmlData.GeometryCalib.SliceCoord);
866            if siz(1)>1
867                if iview>1 && ~isempty(NbSlice) && ~strcmp(NbSlice,siz(1))
868                    msgbox_uvmat('WARNING','inconsistent number of Z indices with the first field series');
869                end
870                NbSlice=siz(1);
871            end
872        end
873    end
874    set(handles.num_NbSlice,'String',num2str(NbSlice))
875end
876
877%% read timing and total frame number from the current file (movie files) if not already set by the xml file (prioritary)
878InputTable=get(handles.InputTable,'Data');
879
880% case of movies
881if isempty(Time)
882    if ~isempty(VideoObject)
883        imainfo=get(VideoObject);
884        if isempty(j1_series); %frame index along i
885            Time=zeros(imainfo.NumberOfFrames+1,2);
886            Time(:,2)=(0:1/imainfo.FrameRate:(imainfo.NumberOfFrames)/imainfo.FrameRate)';
887        else
888            Time=[0;ones(size(i1_series,3)-1,1)]*(0:1/imainfo.FrameRate:(imainfo.NumberOfFrames)/imainfo.FrameRate);
889        end
890        TimeSource='video';
891    end
892end
893
894%% update time table
895if ~isempty(Time)
896    TimeTable=get(handles.TimeTable,'Data');
897    TimeTable{iview,1}=Time(MinIndex_i+1,MinIndex_j+1);
898    if size(Time)>=[first_i+1 first_j+1]
899        TimeTable{iview,2}=Time(first_i+1,first_j+1);
900    end
901    if size(Time)>=[last_i+1 last_j+1]
902        TimeTable{iview,3}=Time(last_i+1,last_j+1);
903    end
904    if size(Time)>=[MaxIndex_i+1 MaxIndex_j+1];
905        TimeTable{iview,4}=Time(MaxIndex_i+1,MaxIndex_j+1);
906    end
907    set(handles.TimeTable,'Data',TimeTable)
908end
909
910%% update the series info in 'UserData'
911SeriesData=get(handles.series,'UserData');
912SeriesData.i1_series{iview}=i1_series;
913SeriesData.i2_series{iview}=i2_series;
914SeriesData.j1_series{iview}=j1_series;
915SeriesData.j2_series{iview}=j2_series;
916SeriesData.FileType{iview}=FileType;
917SeriesData.FileInfo{iview}=FileInfo;
918SeriesData.Time{iview}=Time;
919if ~isempty(TimeSource)
920    SeriesData.TimeSource=TimeSource;
921end
922% if ~isempty(TimeUnit)
923%     SeriesData.TimeUnit=TimeUnit;
924% end
925if check_calib
926    SeriesData.GeometryCalib{iview}=XmlData.GeometryCalib;
927end
928set(handles.series,'UserData',SeriesData)
929
930%% update pair menus
931ListView=get(handles.ListView,'String');
932ListView{iview}=num2str(iview);
933set(handles.ListView,'String',ListView);
934set(handles.ListView,'Value',iview)
935update_mode(handles,i1_series,i2_series,j1_series,j2_series,Time)
936
937%% enable j index visibility
938%check_jindex=~isempty(find(~cellfun(@isempty,SeriesData.j1_series))); %look for non empty j indices
939status_j='on';%default
940if isempty(find(~cellfun(@isempty,SeriesData.j1_series), 1)); % case of empty j indices
941    status_j='off'; % no j index needed
942elseif strcmp(get(handles.PairString,'Visible'),'on')
943        PairString=get(handles.PairString,'Data');       
944        check_burst=cellfun(@isempty,regexp(PairString,'^j'));%=0 for burst case, 1 otherwise
945 %   check_nopair=cellfun(@isempty,PairString);
946    if isempty(find(check_burst, 1))% if all pair string begins by j (burst)
947        status_j='off'; % no j index needed for bust case
948    end
949end
950enable_j(handles,status_j) % no j index needed
951
952%% display the set of existing files as an image
953set(handles.FileStatus,'Units','pixels')
954Position=get(handles.FileStatus,'Position');
955set(handles.FileStatus,'Units','normalized')
956xI=0.5:Position(3)-0.5;
957nbview=numel(SeriesData.i1_series);
958j_max=cell(1,nbview);
959MaxIndex_i=ones(1,nbview);%default
960MinIndex_i=ones(1,nbview);%default
961for iview=1:nbview
962    pair_max=squeeze(max(SeriesData.i1_series{iview},[],1)); %max on pair index
963    j_max{iview}=max(pair_max,[],1);%max on j index
964    MaxIndex_i(iview)=max(find(j_max{iview}))-1;% max ref index i
965    MinIndex_i(iview)=min(find(j_max{iview}))-1;% min ref index i
966%     pair_max{iview}=squeezSeriesData.i1_series{iview},[],1)); %max on pair index
967%     if (strcmp(get(handles.num_first_j,'Visible'),'off')&& size(pair_max{iview},2)~=1)
968%         pair_max{iview}=squeeze(max(pair_max{iview},[],1)); % consider only the i index
969%     end
970end
971MinIndex_i=min(MinIndex_i);
972MaxIndex_i=max(MaxIndex_i);
973range_index=MaxIndex_i-MinIndex_i+1;
974% scale_y=Position(4)/nbview;
975% scale_x=Position(3)/range_index;
976%x=(0.5:range_index-0.5)*Position(3)/range_index;% set of abscissa representing the whole i index range
977% y=(0.5:nbview-0.5)*Position(4)/nbview;
978range_y=max(1,floor(Position(4)/nbview));
979npx=floor(Position(3));
980file_indices=MinIndex_i+floor(((0.5:npx-0.5)/npx)*range_index)+1;
981CData=zeros(nbview*range_y,npx);% initiate the image representing the existing files
982for iview=1:nbview
983    ind_y=1+(iview-1)*range_y:iview*range_y;
984    LineData=zeros(size(file_indices));
985    file_select=file_indices(file_indices<=numel(j_max{iview}));
986    ind_select=find(file_indices<=numel(j_max{iview}));
987    LineData(ind_select)=j_max{iview}(file_select)~=0;
988    CData(ind_y,:)=ones(size(ind_y'))*LineData;
989end
990CData=cat(3,zeros(size(CData)),CData,zeros(size(CData)));%make color images r=0,g,b=0
991set(handles.FileStatus,'CData',CData);
992
993%% check for pair display
994check_pairs=0;
995for iview=1:numel(SeriesData.i2_series)
996    if ~isempty(SeriesData.i2_series{iview})||~isempty(SeriesData.j2_series{iview})
997        check_pairs=1;
998    end
999end
1000if check_pairs
1001    set(handles.Pairs,'Visible','on')
1002    set(handles.PairString,'Visible','on')
1003else
1004    set(handles.Pairs,'Visible','off')
1005    set(handles.PairString,'Visible','off')
1006end
1007
1008
1009%% enable field and veltype menus, in accordance with the current action
1010ActionName_Callback([],[], handles)
1011
1012%% set length of waitbar
1013displ_time(handles)
1014
1015%% set default options in menu 'Fields'
1016switch FileType
1017    case {'civx','civdata'}
1018        [FieldList,ColorList]=set_field_list('U','V','C');
1019        set(handles.FieldName,'String',[{'image'};FieldList;{'get_field...'}]);%standard menu for civx data
1020        set(handles.FieldName,'Value',2) % set menu to 'velocity
1021        set(handles.Coord_x,'Value',1);
1022        set(handles.Coord_x,'String',{'X'});
1023        set(handles.Coord_y,'Value',1);
1024        set(handles.Coord_y,'String',{'Y'});
1025    case 'netcdf'
1026        set(handles.FieldName,'Value',1)
1027        set(handles.FieldName,'String',{'get_field...'})
1028        if isempty(i2_series)
1029            i2=[];
1030        else
1031            i2=i2_series(1,ref_j+1,ref_i+1);
1032        end
1033        if isempty(j1_series)
1034            j1=[];j2=[];
1035        else
1036            j1=j1_series(1,ref_j+1,ref_i+1);
1037            if isempty(j2_series)
1038                j2=[];
1039            else
1040                j2=j2_series(1,ref_j+1,ref_i+1);
1041            end
1042        end
1043                FieldName_Callback([], [], handles)
1044       % FileName=fullfile_uvmat(InputTable{iview,1},InputTable{iview,2},InputTable{iview,3},InputTable{iview,5},InputTable{iview,4},i1_series(1,ref_j+1,ref_i+1),i2,j1,j2);
1045%         hget_field=get_field(FileName);
1046%         hhget_field=guidata(hget_field);
1047%         get_field('RUN_Callback',hhget_field.RUN,[],hhget_field);
1048    otherwise
1049        set(handles.FieldName,'Value',1) % set menu to 'image'
1050        set(handles.FieldName,'String',{'image'})
1051        set(handles.Coord_x,'Value',1);
1052        set(handles.Coord_x,'String',{'AX'});
1053        set(handles.Coord_y,'Value',1);
1054        set(handles.Coord_y,'String',{'AY'});
1055end
1056
1057%------------------------------------------------------------------------
1058function num_first_i_Callback(hObject, eventdata, handles)
1059%------------------------------------------------------------------------
1060num_last_i_Callback(hObject, eventdata, handles)
1061
1062%------------------------------------------------------------------------
1063function num_last_i_Callback(hObject, eventdata, handles)
1064%------------------------------------------------------------------------
1065SeriesData=get(handles.series,'UserData');
1066if ~isfield(SeriesData,'Time')
1067    SeriesData.Time{1}=[];
1068end
1069displ_time(handles);
1070
1071%------------------------------------------------------------------------
1072function num_first_j_Callback(hObject, eventdata, handles)
1073%------------------------------------------------------------------------
1074 num_last_j_Callback(hObject, eventdata, handles)
1075
1076%------------------------------------------------------------------------
1077function num_last_j_Callback(hObject, eventdata, handles)
1078%------------------------------------------------------------------------
1079first_j=str2num(get(handles.num_first_j,'String'));
1080last_j=str2num(get(handles.num_last_j,'String'));
1081ref_j=ceil((first_j+last_j)/2);
1082set(handles.num_ref_j,'String', num2str(ref_j))
1083num_ref_j_Callback(hObject, eventdata, handles)
1084SeriesData=get(handles.series,'UserData');
1085if ~isfield(SeriesData,'Time')
1086    SeriesData.Time{1}=[];
1087end
1088displ_time(handles);
1089
1090
1091%------------------------------------------------------------------------
1092% ---- find the times corresponding to the first and last indices of a series
1093function displ_time(handles)
1094%------------------------------------------------------------------------
1095SeriesData=get(handles.series,'UserData');%
1096PairString=get(handles.PairString,'Data');
1097ref_i_1=str2num(get(handles.num_first_i,'String'));%first reference index
1098ref_i_2=str2num(get(handles.num_last_i,'String'));%last reference index
1099ref_j_1=[];ref_j_2=[];
1100if strcmp(get(handles.num_first_j,'Visible'),'on')
1101ref_j_1=str2num(get(handles.num_first_j,'String'));
1102ref_j_2=str2num(get(handles.num_last_j,'String'));
1103end
1104[i1_1,i2_1,j1_1,j2_1] = get_file_index(ref_i_1,ref_j_1,PairString);
1105[i1_2,i2_2,j1_2,j2_2] = get_file_index(ref_i_2,ref_j_2,PairString);
1106TimeTable=get(handles.TimeTable,'Data');
1107
1108%Pairs=get(handles.PairString,'Data');
1109for iview=1:size(TimeTable,1)
1110    if size(SeriesData.Time,1)<iview
1111        break
1112    end
1113    TimeTable{iview,2}=[];
1114    TimeTable{iview,3}=[];
1115    if size(SeriesData.Time{iview},1)>=i2_2+1 && (isempty(ref_j_1)||size(SeriesData.Time{iview},2)>=j2_2+1)
1116        if isempty(ref_j_1)
1117            time_first=(SeriesData.Time{iview}(i1_1+1,2)+SeriesData.Time{iview}(i2_1+1,2))/2;
1118            time_last=(SeriesData.Time{iview}(i1_2+1,2)+SeriesData.Time{iview}(i2_2+1,2))/2;
1119        else
1120            time_first=(SeriesData.Time{iview}(i1_1+1,j1_1+1)+SeriesData.Time{iview}(i2_1+1,j2_1+1))/2;
1121            time_last=(SeriesData.Time{iview}(i1_2+1,j1_2+1)+SeriesData.Time{iview}(i2_2+1,j2_1+1))/2;
1122        end
1123        TimeTable{iview,2}=time_first; %TODO: take into account pairs
1124        TimeTable{iview,3}=time_last; %TODO: take into account pairs
1125    end
1126end
1127set(handles.TimeTable,'Data',TimeTable)
1128
1129%% set the waitbar position with respect to the min and max in the series
1130MinIndex_i=min(get(handles.MinIndex_i,'Data'));
1131MaxIndex_i=max(get(handles.MaxIndex_i,'Data'));
1132pos_first=(ref_i_1-MinIndex_i)/(MaxIndex_i-MinIndex_i+1);
1133pos_last=(ref_i_2-MinIndex_i+1)/(MaxIndex_i-MinIndex_i+1);
1134Position=get(handles.Waitbar,'Position');% position of the waitbar:= [ x,y, width, height]
1135Position_status=get(handles.FileStatus,'Position');
1136Position(1)=Position_status(1)+Position_status(3)*pos_first;
1137Position(3)=Position_status(3)*(pos_last-pos_first);
1138set(handles.Waitbar,'Position',Position)
1139update_waitbar(handles.Waitbar,0)
1140
1141%------------------------------------------------------------------------
1142% --- Executes when selected cell(s) is changed in PairString.
1143function PairString_CellSelectionCallback(hObject, eventdata, handles)
1144%------------------------------------------------------------------------   
1145if numel(eventdata.Indices)>=1
1146set(handles.ListView,'Value',eventdata.Indices(1))% detect the selected raw index
1147ListView_Callback ([],[],handles) % update the list of available pairs
1148end
1149
1150%------------------------------------------------------------------------
1151%------------------------------------------------------------------------
1152%  III - FUNCTIONS ASSOCIATED TO THE FRAME SET PAIRS
1153%------------------------------------------------------------------------
1154%------------------------------------------------------------------------
1155% --- Executes on selection change in ListView.
1156function ListView_Callback(hObject, eventdata, handles)
1157%------------------------------------------------------------------------   
1158SeriesData=get(handles.series,'UserData');
1159i2_series=[];
1160j2_series=[];
1161iview=get(handles.ListView,'Value');
1162if ~isempty(SeriesData.i2_series{iview})
1163    i2_series=SeriesData.i2_series{iview};
1164end
1165if ~isempty(SeriesData.j2_series{iview})
1166    j2_series=SeriesData.j2_series{iview};
1167end
1168update_mode(handles,SeriesData.i1_series{iview},SeriesData.i2_series{iview},...
1169    SeriesData.j1_series{iview},SeriesData.j2_series{iview},SeriesData.Time{iview})
1170
1171%------------------------------------------------------------------------
1172% --- Executes on button press in mode.
1173function mode_Callback(hObject, eventdata, handles)
1174%------------------------------------------------------------------------       
1175SeriesData=get(handles.series,'UserData');
1176iview=get(handles.ListView,'Value');
1177mode_list=get(handles.mode,'String');
1178mode=mode_list{get(handles.mode,'Value')};
1179if isequal(mode,'bursts')
1180    enable_i(handles,'On')
1181    enable_j(handles,'Off') %do not display j index scanning in burst mode (j is fixed by the burst choice)
1182else
1183    enable_i(handles,'On')
1184    enable_j(handles,'Off')
1185end
1186fill_ListPair(handles,SeriesData.i1_series{iview},SeriesData.i2_series{iview},...
1187    SeriesData.j1_series{iview},SeriesData.j2_series{iview},SeriesData.Time{iview})
1188ListPairs_Callback([],[],handles)
1189
1190%-------------------------------------------------------------
1191% --- Executes on selection in ListPairs.
1192function ListPairs_Callback(hObject,eventdata,handles)
1193%------------------------------------------------------------
1194list_pair=get(handles.ListPairs,'String');%get the menu of image pairs
1195if isempty(list_pair)
1196    string='';
1197else
1198    string=list_pair{get(handles.ListPairs,'Value')};
1199    string=regexprep(string,',.*','');%removes time indication (after ',')
1200end
1201PairString=get(handles.PairString,'Data');
1202iview=get(handles.ListView,'Value');
1203PairString{iview,1}=string;
1204% report the selected pair string to the table PairString
1205set(handles.PairString,'Data',PairString)
1206
1207%------------------------------------------------------------------------
1208function num_ref_i_Callback(hObject, eventdata, handles)
1209%------------------------------------------------------------------------
1210mode_list=get(handles.mode,'String');
1211mode=mode_list{get(handles.mode,'Value')};
1212SeriesData=get(handles.series,'UserData');
1213iview=get(handles.ListView,'Value');
1214fill_ListPair(handles,SeriesData.i1_series{iview},SeriesData.i2_series{iview},...
1215    SeriesData.j1_series{iview},SeriesData.j2_series{iview},SeriesData.Time{iview});% update the menu of pairs depending on the available netcdf files
1216ListPairs_Callback([],[],handles)
1217
1218%------------------------------------------------------------------------
1219function num_ref_j_Callback(hObject, eventdata, handles)
1220%------------------------------------------------------------------------
1221num_ref_i_Callback(hObject, eventdata, handles)
1222
1223%------------------------------------------------------------------------
1224function update_mode(handles,i1_series,i2_series,j1_series,j2_series,time)
1225%------------------------------------------------------------------------   
1226% check_burst=0;
1227if isempty(j2_series)% no j pair
1228    if isempty(i2_series)
1229        set(handles.mode,'Value',1)
1230        set(handles.mode,'String',{''})% no pair menu to display
1231    else   
1232        set(handles.mode,'Value',1)
1233        set(handles.mode,'String',{'series(Di)'}) % pair menu with only option Di
1234    end
1235else %existence of j pairs
1236    pair_max=squeeze(max(i1_series,[],1)); %max on pair index
1237    j_max=max(pair_max,[],1);
1238    MaxIndex_i=max(find(j_max))-1;% max ref index i
1239    MinIndex_i=min(find(j_max))-1;% min ref index i
1240    i_max=max(pair_max,[],2);
1241    MaxIndex_j=max(find(i_max))-1;% max ref index i
1242    MinIndex_j=min(find(i_max))-1;% min ref index i
1243    if MaxIndex_j==MinIndex_j
1244        set(handles.mode,'Value',1);
1245        set(handles.mode,'String',{'bursts'})
1246%         check_burst=1;
1247    elseif MaxIndex_i==MinIndex_i
1248        set(handles.mode,'Value',1);
1249        set(handles.mode,'String',{'series(Dj)'})
1250    else
1251        set(handles.mode,'String',{'bursts';'series(Dj)'})
1252        if (MaxIndex_j-MinIndex_j)>10
1253            set(handles.mode,'Value',2);%set mode to series(Dj) if more than 10 j values
1254        else
1255            set(handles.mode,'Value',1);
1256%             check_burst=1;
1257        end
1258    end
1259end
1260fill_ListPair(handles,i1_series,i2_series,j1_series,j2_series,time)
1261ListPairs_Callback([],[],handles)
1262
1263%--------------------------------------------------------------
1264% determine the menu for pairstring depending on existing netcdf files
1265% with the reference indices num_ref_i and num_ref_j
1266%----------------------------------------------------------------
1267function fill_ListPair(handles,i1_series,i2_series,j1_series,j2_series,time)
1268
1269mode_list=get(handles.mode,'String');
1270mode=mode_list{get(handles.mode,'Value')};
1271ref_i=str2num(get(handles.num_ref_i,'String'));
1272if isempty(ref_i)
1273    ref_i=1;
1274end
1275if strcmp(get(handles.num_ref_j,'Visible'),'on')
1276    ref_j=str2num(get(handles.num_ref_j,'String'));
1277    if isempty(ref_j)
1278        ref_j=1;
1279    end
1280else
1281    ref_j=1;
1282end
1283TimeUnit=get(handles.TimeUnit,'String');
1284if length(TimeUnit)>=1
1285    dtunit=['m' TimeUnit];
1286else
1287    dtunit='e-03';
1288end
1289
1290displ_pair={};
1291if strcmp(mode,'series(Di)')
1292    if isempty(i2_series)
1293        msgbox_uvmat('ERROR','no i1-i2 pair available')
1294        return
1295    end
1296    diff_i=i2_series-i1_series;
1297    min_diff=min(diff_i(diff_i>0));
1298    max_diff=max(diff_i(diff_i>0));
1299    for ipair=min_diff:max_diff
1300        if numel(diff_i(diff_i==ipair))>0
1301            pair_string=['Di= ' num2str(-floor(ipair/2)) '|' num2str(ceil(ipair/2)) ];
1302            if ~isempty(time)
1303                if ref_i<=floor(ipair/2)
1304                    ref_i=floor(ipair/2)+1;% shift ref_i to get the first pair
1305                end
1306                Dt=time(ref_i+ceil(ipair/2),ref_j)-time(ref_i-floor(ipair/2),ref_j);
1307                pair_string=[pair_string ', Dt=' num2str(Dt) ' ' dtunit];
1308            end
1309            displ_pair=[displ_pair;{pair_string}];
1310        end
1311    end
1312    if ~isempty(displ_pair)
1313        displ_pair=[displ_pair;{'Di=*|*'}];
1314    end
1315elseif strcmp(mode,'series(Dj)')
1316    if isempty(j2_series)
1317        msgbox_uvmat('ERROR','no j1-j2 pair available')
1318        return
1319    end
1320    diff_j=j2_series-j1_series;
1321    min_diff=min(diff_j(diff_j>0));
1322    max_diff=max(diff_j(diff_j>0));
1323    for ipair=min_diff:max_diff
1324        if numel(diff_j(diff_j==ipair))>0
1325            pair_string=['Dj= ' num2str(-floor(ipair/2)) '|' num2str(ceil(ipair/2)) ];
1326            if ~isempty(time)
1327                if ref_j<=floor(ipair/2)
1328                    ref_j=floor(ipair/2)+1;% shift ref_i to get the first pair
1329                end
1330                Dt=time(ref_i,ref_j+ceil(ipair/2))-time(ref_i,ref_j-floor(ipair/2));
1331                pair_string=[pair_string ', Dt=' num2str(Dt) ' ' dtunit];
1332            end
1333            displ_pair=[displ_pair;{pair_string}];
1334        end
1335    end
1336    if ~isempty(displ_pair)
1337        displ_pair=[displ_pair;{'Dj=*|*'}];
1338    end
1339elseif strcmp(mode,'bursts')
1340    if isempty(j2_series)
1341        msgbox_uvmat('ERROR','no j1-j2 pair available')
1342        return
1343    end
1344    diff_j=j2_series-j1_series;
1345    min_j1=min(j1_series(j1_series>0));
1346    max_j1=max(j1_series(j1_series>0));
1347    min_j2=min(j2_series(j2_series>0));
1348    max_j2=max(j2_series(j2_series>0));
1349    for pair1=min_j1:min(max_j1,min_j1+20)
1350        for pair2=min_j2:min(max_j2,min_j2+20)
1351        if numel(j1_series(j1_series==pair1))>0 && numel(j2_series(j2_series==pair2))>0
1352            displ_pair=[displ_pair;{['j= ' num2str(pair1) '-' num2str(pair2)]}];
1353        end
1354        end
1355    end
1356    if ~isempty(displ_pair)
1357        displ_pair=[displ_pair;{'j=*-*'}];
1358    end
1359end
1360set(handles.num_ref_i,'String',num2str(ref_i)) % update ref_i and ref_j
1361set(handles.num_ref_j,'String',num2str(ref_j))
1362
1363%% display list of pairstring
1364displ_pair_list=get(handles.ListPairs,'String');
1365NewVal=[];
1366if ~isempty(displ_pair_list)
1367Val=get(handles.ListPairs,'Value');
1368NewVal=find(strcmp(displ_pair_list{Val},displ_pair),1);% look at the previous display in the new menu displ_pï¿œir
1369end
1370if ~isempty(NewVal)
1371    set(handles.ListPairs,'Value',NewVal)
1372else
1373    set(handles.ListPairs,'Value',1)
1374end
1375set(handles.ListPairs,'String',displ_pair)
1376
1377%-------------------------------------
1378function enable_i(handles,state)
1379set(handles.i_txt,'Visible',state)
1380set(handles.num_first_i,'Visible',state)
1381set(handles.num_last_i,'Visible',state)
1382set(handles.num_incr_i,'Visible',state)
1383set(handles.num_ref_i,'Visible',state)
1384set(handles.ref_i_text,'Visible',state)
1385
1386%-----------------------------------
1387function enable_j(handles,state)
1388set(handles.j_txt,'Visible',state)
1389set(handles.num_first_j,'Visible',state)
1390set(handles.num_last_j,'Visible',state)
1391set(handles.num_incr_j,'Visible',state)
1392set(handles.num_ref_j,'Visible',state)
1393set(handles.ref_j_text,'Visible',state)
1394set(handles.MinIndex_j,'Visible',state)
1395set(handles.MaxIndex_j,'Visible',state)
1396
1397
1398%%%%%%%%%%%%%%%%%%%%
1399%%  MAIN ActionName FUNCTIONS
1400%%%%%%%%%%%%%%%%%%%%
1401%------------------------------------------------------------------------
1402% --- Executes on button press in RUN.
1403%------------------------------------------------------------------------
1404function RUN_Callback(hObject, eventdata, handles)
1405
1406%% settings of the button RUN
1407set(handles.RUN,'BusyAction','queue');% activation of STOP button will set BusyAction to 'cancel'
1408set(handles.RUN, 'Enable','Off')% avoid further RUN action until the current one is finished
1409set(handles.RUN,'BackgroundColor',[1 1 0])%show activation of RUN by yellow color
1410drawnow
1411set(handles.status,'Value',0)% desable status display if relevant
1412status_Callback(hObject, eventdata, handles)
1413
1414%% read the data on the GUI series
1415Param=read_GUI_series(handles);%displayed parameters
1416SeriesData=get(handles.series,'UserData');%hidden parameters
1417
1418%% create the output data directory if needed
1419if isfield(Param,'OutputSubDir')
1420    SubDirOut=[get(handles.OutputSubDir,'String') Param.OutputDirExt];
1421    SubDirOutNew=SubDirOut;
1422    detect=exist(fullfile(Param.InputTable{1,1},SubDirOutNew),'dir');% test if  the dir  already exist
1423    check_create=1; %need to create the result directory by default
1424    while detect
1425        answer=msgbox_uvmat('INPUT_Y-N',['use existing ouput directory: ' fullfile(Param.InputTable{1,1},SubDirOutNew) ', possibly delete previous data']);
1426        if strcmp(answer,'Cancel')
1427            errormsg='Cancel';
1428            return
1429        elseif strcmp(answer,'Yes')
1430            detect=0;
1431            check_create=0;
1432        else
1433            r=regexp(SubDirOutNew,'(?<root>.*\D)(?<num1>\d+)$','names');%detect whether name ends by a number
1434            if isempty(r)
1435                r(1).root=[SubDirOutNew '_'];
1436                r(1).num1='0';
1437            end
1438            SubDirOutNew=[r(1).root num2str(str2num(r(1).num1)+1)];%increment the index by 1 or put 1
1439            detect=exist(fullfile(Param.InputTable{1,1},SubDirOutNew),'dir');% test if  the dir  already exists
1440            check_create=1;
1441        end
1442    end
1443    Param.OutputDirExt=regexprep(SubDirOutNew,Param.OutputSubDir,'');
1444    Param.OutputRootFile=Param.InputTable{1,3};% the first sorted RootFile taken for output
1445    set(handles.OutputDirExt,'String',Param.OutputDirExt)
1446    OutputDir=fullfile(Param.InputTable{1,1},[Param.OutputSubDir Param.OutputDirExt]);% full name (with path) of output directory
1447    if check_create    % create output directory if it does not exist
1448        [tild,msg1]=mkdir(OutputDir);
1449        if ~strcmp(msg1,'')
1450            msgbox_uvmat('ERROR',['cannot create ' OutputDir ': ' msg1]);%error message for directory creation
1451            return
1452        end
1453        [success,msg] = fileattrib(OutputDir,'+w','g','s');% allow writing access for the group of users, recursively in the folder 
1454        if success==0
1455            msgbox_uvmat('WARNING',{['unable to set group write access to ' OutputDir ':']; msg1});%error message for directory creation
1456            return
1457        end
1458    end
1459    OutputNomType=nomtype2pair(Param.InputTable{1,4});% nomenclature for output files
1460    DirXml=fullfile(OutputDir,'0_XML');
1461    if ~exist(DirXml,'dir')
1462        [tild,msg1]=mkdir(DirXml);
1463        if ~strcmp(msg1,'')
1464            msgbox_uvmat('ERROR',['cannot create ' DirXml ': ' msg1]);%error message for directory creation
1465            return
1466        end
1467                [success,msg] = fileattrib(DirXml,'+w','g','s');% allow writing access for the group of users, recursively in the folder 
1468        if success==0
1469            msgbox_uvmat('WARNING',{['unable to set group write access to ' DirXml ':']; msg1});%error message for directory creation
1470            return
1471        end
1472    end
1473end
1474
1475%% select the Action mode, 'local', 'background' or 'cluster' (if available)
1476RunMode='local';%default (needed for first opening of the GUI series)
1477if isfield(Param.Action,'RunMode')
1478    RunMode=Param.Action.RunMode;
1479end
1480ActionExt='.m';%default
1481if isfield(Param.Action,'ActionExt')
1482    ActionExt=Param.Action.ActionExt;% '.m' or '.sh' (compiled)
1483end
1484ActionName=Param.Action.ActionName;
1485ActionPath=Param.Action.ActionPath;
1486path_series=fileparts(which('series'));
1487
1488%% create the Action fct handle if RunMode option = 'local'
1489if strcmp(RunMode,'local')
1490    if ~isequal(ActionPath,path_series)
1491        eval(['spath=which(''' ActionName ''');']) %spath = current path of the selected function ACTION
1492        if ~exist(ActionPath,'dir')
1493            msgbox_uvmat('ERROR',['The prescribed function path ' ActionPath ' does not exist']);
1494            return
1495        end
1496        if ~isequal(spath,ActionPath)
1497            addpath(ActionPath)% add the prescribed path if not the current one
1498        end
1499    end
1500    eval(['h_fun=@' ActionName ';'])%create a function handle for ACTION
1501    if ~isequal(ActionPath,path_series)
1502        rmpath(ActionPath)% add the prescribed path if not the current one
1503    end
1504end
1505
1506%% Get RunTime code from the file PARAM.xml (needed to run compiled functions)
1507errormsg='';%default error message
1508xmlfile=fullfile(path_series,'PARAM.xml');
1509test_batch=0;%default: ,no batch mode available
1510if ~exist(xmlfile,'file')
1511    [success,message]=copyfile(fullfile(path_series,'PARAM.xml.default'),xmlfile);
1512end
1513RunTime='';
1514if strcmp(ActionExt,'.sh')
1515    if exist(xmlfile,'file')
1516        s=xml2struct(xmlfile);
1517        if strcmp(RunMode,'cluster_oar') && isfield(s,'BatchParam')
1518            if isfield(s.BatchParam,'RunTime')
1519                RunTime=s.BatchParam.RunTime;
1520            end
1521            if isfield(s.BatchParam,'NbCore')
1522                NbCore=s.BatchParam.NbCore;
1523            end
1524        elseif (strcmp(RunMode,'background')||strcmp(RunMode,'local')) && isfield(s,'RunParam')
1525            if isfield(s.RunParam,'RunTime')
1526                RunTime=s.RunParam.RunTime;
1527            end
1528            if isfield(s.RunParam,'NbCore')
1529                NbCore=s.RunParam.NbCore;
1530            end
1531        end
1532    end
1533    if isempty(RunTime) && strcmp(RunMode,'cluster_oar')
1534        msgbox_uvmat('ERROR','RunTime name not found in PARAM.xml, compiled version .sh cannot run on cluster')
1535        return
1536    end
1537end
1538
1539%% set nbre of cluster cores and processes
1540switch RunMode
1541    case {'local','background'}
1542        NbCore=1;% no need to split the calculation
1543    case 'cluster_oar'
1544        if strcmp(Param.Action.ActionExt,'.m')% case of Matlab function (uncompiled)
1545            NbCore=1;% one core used only (limitation of Matlab licences)
1546            msgbox_uvmat('WARNING','Number of cores =1: select the compiled version civ_matlab.sh for multi-core processing');
1547            extra_oar='';
1548        else
1549            answer=inputdlg({'Number of cores (max 36)','extra oar options'},'oarsub parameter',1,{'12',''});
1550            NbCore=str2double(answer{1});
1551            extra_oar=answer{2};
1552        end
1553end
1554if ~isfield(Param.IndexRange,'NbSlice')
1555    Param.IndexRange.NbSlice=[];
1556end
1557if isempty(Param.IndexRange.NbSlice)
1558    NbProcess=NbCore;% choose one process per core
1559else
1560    NbProcess=Param.IndexRange.NbSlice;% the nbre of run processes is equal to the number of slices
1561    NbCore=min(NbCore,NbProcess);% at least one process per core
1562end
1563       
1564%% get the set of reference field indices
1565first_i=1;
1566last_i=1;
1567incr_i=1;
1568first_j=1;
1569last_j=1;
1570incr_j=1;
1571if isfield(Param.IndexRange,'first_i')
1572    first_i=Param.IndexRange.first_i;
1573    incr_i=Param.IndexRange.incr_i;
1574    last_i=Param.IndexRange.last_i;
1575end
1576if isfield(Param.IndexRange,'first_j')
1577    first_j=Param.IndexRange.first_j;
1578    last_j=Param.IndexRange.last_j;
1579    incr_j=Param.IndexRange.incr_j;
1580end
1581if last_i < first_i || last_j < first_j
1582    msgbox_uvmat('ERROR', 'series/Run_Callback:last field index must be larger or equal to the first one')
1583    set(handles.RUN, 'Enable','On'),
1584    set(handles.RUN,'BackgroundColor',[1 0 0])
1585    return
1586end
1587%incr_i must be defined, =1 by default, if NbSlice is active
1588if isempty(incr_i)&& ~isempty(Param.IndexRange.NbSlice)
1589    incr_i=1;
1590    set(handles.num_incr_i,'String','1')
1591end
1592if isempty(incr_i)
1593    if isempty(incr_j)
1594        [ref_j,ref_i]=find(squeeze(SeriesData.i1_series{1}(1,:,:)));
1595        ref_j=ref_j(ref_j>=first_j & ref_j<=last_j);
1596        ref_i=ref_i(ref_i>=first_i & ref_i<=last_i);
1597        ref_j=ref_j-1;
1598        ref_i=ref_i-1;
1599    else
1600        ref_j=first_j:incr_j:last_j;
1601        [tild,ref_i]=find(squeeze(SeriesData.i1_series{1}(1,:,:)));
1602        ref_i=ref_i-1;
1603        ref_i=ref_i(ref_i>=first_i & ref_i<=last_i);
1604    end
1605else
1606    ref_i=first_i:incr_i:last_i;
1607    if isempty(incr_j)
1608    [ref_j,tild]=find(squeeze(SeriesData.i1_series{1}(1,:,:)));
1609    ref_j=ref_j-1;
1610    ref_j=ref_j(ref_j>=first_j & ref_j<=last_j);
1611    else
1612        ref_j=first_j:incr_j:last_j;
1613    end
1614end
1615BlockLength=ceil(numel(ref_i)/NbProcess);
1616nbfield_j=numel(ref_j);
1617
1618%% record nbre of output files and starting time for computation for status
1619StatusData=get(handles.status,'UserData');
1620if isfield(StatusData,'OutputFileMode')
1621    switch StatusData.OutputFileMode
1622        case 'NbInput'
1623            StatusData.NbOutputFile=numel(ref_i)*nbfield_j;
1624        case 'NbInput_i'
1625            StatusData.NbOutputFile=numel(ref_i);
1626        case 'NbSlice'   
1627            StatusData.NbOutputFile=str2num(get(handles.num_NbSlice,'String'));
1628    end
1629end
1630StatusData.TimeStart=now;
1631set(handles.status,'UserData',StatusData)
1632
1633%% direct processing on the current Matlab session
1634if strcmp (RunMode,'local')
1635    for iprocess=1:NbProcess
1636        if isempty(Param.IndexRange.NbSlice)
1637            %Param.IndexRange.first_i=first_i+(iprocess-1)*BlockLength*incr_i;
1638            Param.IndexRange.first_i=ref_i(1+(iprocess-1)*BlockLength);
1639            if Param.IndexRange.first_i>last_i
1640                break
1641            end
1642            Param.IndexRange.last_i=min(ref_i(iprocess*BlockLength),last_i);
1643            %Param.IndexRange.last_i=min(first_i+(iprocess)*BlockLength*incr_i-1,last_i);
1644        else %multislices (then incr_i is not empty)
1645             Param.IndexRange.first_i= first_i+incr_i*(iprocess-1);
1646             Param.IndexRange.incr_i=incr_i*Param.IndexRange.NbSlice;
1647        end
1648        if isfield(Param,'OutputSubDir')
1649        t=struct2xml(Param);
1650        t=set(t,1,'name','Series');
1651        filexml=fullfile_uvmat(DirXml,'',Param.InputTable{1,3},'.xml',OutputNomType,...
1652            Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1653        save(t,filexml);
1654        end
1655        switch ActionExt
1656            case '.m'
1657                h_fun(Param);
1658            case '.sh'
1659                switch computer
1660                    case {'PCWIN','PCWIN64'} %Windows system
1661                        filexml=regexprep(filexml,'\\','\\\\');% add '\' so that '\' are left as characters
1662                        system([fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml]);% TODO: adapt to DOS system
1663                    case {'GLNX86','GLNXA64','MACI64'}%Linux  system
1664                        system([fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml]);
1665                end
1666        end
1667    end
1668elseif strcmp(get(handles.OutputDirExt,'Visible'),'off')
1669    msgbox_uvmat('ERROR',['no output file for Action ' ActionName ', use run mode = local']);% a output dir is needed for background option
1670    return
1671else
1672    %% processing on a different session of the same computer (background) or cluster, create executable files
1673    batch_file_list=cell(NbProcess,1);% initiate the list of executable files
1674    DirBat=fullfile(OutputDir,'0_EXE');
1675    switch computer
1676        case {'PCWIN','PCWIN64'} %Windows system
1677            ExeExt='.bat';
1678        case {'GLNX86','GLNXA64','MACI64'}%Linux  system
1679           ExeExt='.sh';
1680    end
1681    %create subdirectory for executable files
1682    if ~exist(DirBat,'dir')
1683        [tild,msg1]=mkdir(DirBat);
1684        if ~strcmp(msg1,'')
1685            msgbox_uvmat('ERROR',['cannot create ' DirBat ': ' msg1]);%error message for directory creation
1686            return
1687        end
1688    end
1689    %create subdirectory for log files
1690    DirLog=fullfile(OutputDir,'0_LOG');
1691    if ~exist(DirLog,'dir')
1692        [tild,msg1]=mkdir(DirLog);
1693        if ~strcmp(msg1,'')
1694            msgbox_uvmat('ERROR',['cannot create ' DirLog ': ' msg1]);%error message for directory creation
1695            return
1696        end
1697    end
1698    for iprocess=1:NbProcess
1699        if isempty(Param.IndexRange.NbSlice)% process by blocks of i index
1700            Param.IndexRange.first_i=first_i+(iprocess-1)*BlockLength*incr_i;
1701            if Param.IndexRange.first_i>last_i
1702                NbProcess=iprocess-1;
1703                break% leave the loop, we are at the end of the calculation
1704            end
1705            Param.IndexRange.last_i=min(last_i,first_i+(iprocess)*BlockLength*incr_i-1);
1706        else% process by slices of i index if NbSlice is defined, computation in a single process if NbSlice =1
1707            Param.IndexRange.first_i= first_i+iprocess-1;
1708            Param.IndexRange.incr_i=incr_i*Param.IndexRange.NbSlice;
1709        end
1710       
1711        % create, fill and save the xml parameter file
1712        t=struct2xml(Param);
1713        t=set(t,1,'name','Series');
1714        filexml=fullfile_uvmat(DirXml,'',Param.InputTable{1,3},'.xml',OutputNomType,...
1715            Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1716        save(t,filexml);% save the parameter file
1717       
1718        %create the executable file
1719         filebat=fullfile_uvmat(DirBat,'',Param.InputTable{1,3},ExeExt,OutputNomType,...
1720           Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1721        batch_file_list{iprocess}=filebat;
1722        [fid,message]=fopen(filebat,'w');% create the executable file
1723        if isequal(fid,-1)
1724            msgbox_uvmat('ERROR', ['creation of .bat file: ' message]);
1725            return
1726        end
1727       
1728        % set the log file name
1729        filelog=fullfile_uvmat(DirLog,'',Param.InputTable{1,3},'.log',OutputNomType,...
1730            Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1731       
1732        % fill and save the executable file
1733        switch ActionExt
1734            case '.m'% Matlab function
1735                switch computer
1736                    case {'GLNX86','GLNXA64','MACI64'}
1737                        cmd=[...
1738                            '#!/bin/bash \n'...
1739                            '. /etc/sysprofile \n'...
1740                            'matlab -nodisplay -nosplash -nojvm -logfile ''' filelog ''' <<END_MATLAB \n'...
1741                            'addpath(''' path_series '''); \n'...
1742                            'addpath(''' Param.Action.ActionPath '''); \n'...
1743                            '' Param.Action.ActionName  '( ''' filexml '''); \n'...
1744                            'exit \n'...
1745                            'END_MATLAB \n'];
1746                        fprintf(fid,cmd);%fill the executable file with the  char string cmd
1747                        fclose(fid);% close the executable file
1748                        system(['chmod +x ' filebat]);% set the file to executable
1749                    case {'PCWIN','PCWIN64'}
1750                        text_matlabscript=['matlab -automation -logfile ' regexprep(filelog,'\\','\\\\')...
1751                            ' -r "addpath(''' regexprep(path_series,'\\','\\\\') ''');'...
1752                            'addpath(''' regexprep(Param.Action.ActionPath,'\\','\\\\') ''');'...
1753                            '' Param.Action.ActionName  '( ''' regexprep(filexml,'\\','\\\\') ''');exit"'];
1754                        fprintf(fid,text_matlabscript);%fill the executable file with the  char string cmd
1755                        fclose(fid);% close the executable file
1756                end
1757            case '.sh' % compiled Matlab function
1758                switch computer
1759                    case {'GLNX86','GLNXA64','MACI64'}
1760                        cmd=['#!/bin/bash \n '...
1761                            '#$ -cwd \n '...
1762                            'hostname && date \n '...
1763                            'umask 002 \n'...
1764                            fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml];%allow writting access to created files for user group
1765                        fprintf(fid,cmd);%fill the executable file with the  char string cmd
1766                        fclose(fid);% close the executable file
1767                        system(['chmod +x ' filebat]);% set the file to executable
1768                       
1769                    case {'PCWIN','PCWIN64'}    %       TODO: adapt to Windows system
1770                        %                                 cmd=['matlab -automation -logfile ' regexprep(filelog,'\\','\\\\')...
1771                        %                                     ' -r "addpath(''' regexprep(path_series,'\\','\\\\') ''');'...
1772                        %                                     'addpath(''' regexprep(Param.Action.ActionPath,'\\','\\\\') ''');'...
1773                        %                                     '' Param.Action.ActionName  '( ''' regexprep(filexml,'\\','\\\\') ''');exit"'];
1774                        fprintf(fid,cmd);
1775                        fclose(fid);
1776                        %                               dos([filebat ' &']);
1777                end
1778        end
1779    end
1780end
1781
1782%% launch the executable files for background or cluster processing
1783switch RunMode
1784    case 'background'
1785        for iprocess=1:NbProcess
1786            system([batch_file_list{iprocess} ' &'])% directly execute the command file for each process
1787        end
1788    case 'cluster_oar' % option 'oar-parexec' used
1789        %create subdirectory for oar command and log files
1790        DirOAR=fullfile(OutputDir,'0_OAR');
1791        if exist(DirOAR,'dir')% delete the content of the dir 0_OAR to allow new input
1792            curdir=pwd;
1793            cd(DirOAR)
1794            delete('*')
1795            cd(curdir)
1796        else
1797            [tild,msg1]=mkdir(DirOAR);
1798            if ~strcmp(msg1,'')
1799                msgbox_uvmat('ERROR',['cannot create ' DirOAR ': ' msg1]);%error message for directory creation
1800                return
1801            end
1802        end
1803        max_walltime=3600*12; % 12h max total calculation
1804        walltime_onejob=600;%seconds, max estimated time for asingle file index value
1805        filename_joblist=fullfile(DirOAR,'job_list.txt');%create name of the global executable file
1806        fid=fopen(filename_joblist,'w');
1807        for p=1:length(batch_file_list)
1808            fprintf(fid,[batch_file_list{p} '\n']);% list of exe files
1809        end
1810        fclose(fid);
1811        system(['chmod +x ' filename_joblist]);% set the file to executable
1812        oar_command=['oarsub -n CIVX '...
1813            '-t idempotent --checkpoint ' num2str(walltime_onejob+60) ' '...
1814            '-l /core=' num2str(NbCore) ','...
1815            'walltime=' datestr(min(1.05*walltime_onejob/86400*max(NbProcess*BlockLength*nbfield_j,NbCore)/NbCore,max_walltime/86400),13) ' '...
1816            '-E ' regexprep(filename_joblist,'\.txt\>','.stderr') ' '...
1817            '-O ' regexprep(filename_joblist,'\.txt\>','.stdout') ' '...
1818            extra_oar ' '...
1819            '"oar-parexec -s -f ' filename_joblist ' '...
1820            '-l ' filename_joblist '.log"\n'];
1821        filename_oarcommand=fullfile(DirOAR,'oar_command');
1822        fid=fopen(filename_oarcommand,'w');
1823        fprintf(fid,oar_command);
1824        fclose(fid);
1825        fprintf(oar_command);% display in command line
1826        %system(['chmod +x ' oar_command]);% set the file to executable
1827        system(oar_command);     
1828end
1829
1830%% reset the GUI series
1831update_waitbar(handles.Waitbar,1); % put the waitbar to end position to indicate launching is finished
1832set(handles.RUN, 'Enable','On')
1833set(handles.RUN,'BackgroundColor',[1 0 0])
1834set(handles.RUN, 'Value',0)
1835
1836%------------------------------------------------------------------------
1837function STOP_Callback(hObject, eventdata, handles)
1838%------------------------------------------------------------------------
1839set(handles.RUN, 'BusyAction','cancel')
1840set(handles.RUN,'BackgroundColor',[1 0 0])
1841set(handles.RUN,'enable','on')
1842set(handles.RUN, 'Value',0)
1843
1844
1845%------------------------------------------------------------------------
1846% --- read parameters from the GUI series
1847%------------------------------------------------------------------------
1848function Param=read_GUI_series(handles)
1849
1850%% read raw parameters from the GUI series
1851Param=read_GUI(handles.series);
1852
1853%% clean the output structure by removing unused information
1854if isfield(Param,'Pairs')
1855    Param=rmfield(Param,'Pairs'); %info Pairs not needed for output
1856end
1857Param.IndexRange=rmfield(Param.IndexRange,'TimeTable');
1858empty_line=false(size(Param.InputTable,1),1);
1859for iline=1:size(Param.InputTable,1)
1860    empty_line(iline)=isempty(cell2mat(Param.InputTable(iline,1:3)));
1861end
1862Param.InputTable(empty_line,:)=[];
1863
1864%------------------------------------------------------------------------
1865% --- Executes on selection change in ActionName.
1866function ActionName_Callback(hObject, eventdata, handles)
1867%------------------------------------------------------------------------
1868
1869%% stop any ongoing series processing
1870if isequal(get(handles.RUN,'Value'),1)
1871    answer= msgbox_uvmat('INPUT_Y-N','stop current Action process?');
1872    if strcmp(answer,'Yes')
1873        STOP_Callback(hObject, eventdata, handles)
1874    else
1875        return
1876    end
1877end
1878set(handles.ActionName,'BackgroundColor',[1 1 0])
1879huigetfile=findobj(allchild(0),'tag','status_display');
1880if ~isempty(huigetfile)
1881    delete(huigetfile)
1882end
1883drawnow
1884
1885%% get Action name and path
1886nb_builtin_ACTION=4; %nbre of functions initially proposed in the menu ActionName (as defined in the Opening fct of series)
1887ActionList=get(handles.ActionName,'String');% list menu fields
1888ActionIndex=get(handles.ActionName,'Value');
1889if ~isequal(ActionIndex,1)% if we are not just opening series
1890    InputTable=get(handles.InputTable,'Data');
1891    if isempty(InputTable{1,4})
1892        msgbox_uvmat('ERROR','no input file available: use Open in the menu bar')
1893        return
1894    end
1895end
1896ActionName= ActionList{get(handles.ActionName,'Value')}; % selected function name
1897ActionPathList=get(handles.ActionName,'UserData');%list of recorded paths to functions of the list ActionName
1898
1899%% add a new function to the menu if 'more...' has been selected in the menu ActionName
1900if isequal(ActionName,'more...')
1901    [FileName, PathName] = uigetfile( ...
1902        {'*.m', ' (*.m)';
1903        '*.m',  '.m files '; ...
1904        '*.*', 'All Files (*.*)'}, ...
1905        'Pick a series processing function ',get(handles.ActionPath,'String'));
1906    if length(FileName)<2
1907        return
1908    end
1909    [ActionPath,ActionName,ActionExt]=fileparts(FileName);
1910   
1911    % insert the choice in the menu ActionName
1912    ActionIndex=find(strcmp(ActionName,ActionList),1);% look for the selected function in the menu Action
1913    if isempty(ActionIndex)%the input string does not exist in the menu
1914        ActionIndex= length(ActionList);
1915        ActionList=[ActionList(1:end-1);{ActionName};ActionList(end)];% the selected function is appended in the menu, before the last item 'more...'
1916        set(handles.ActionName,'String',ActionList)
1917    end
1918   
1919    % record the file extension and extend the path list if it is a new extension
1920    ActionExtList=get(handles.ActionExt,'String');
1921    ActionExtIndex=find(strcmp(ActionExt,ActionExtList), 1);
1922    if isempty(ActionExtIndex)
1923        set(handles.ActionExt,'String',[ActionExtList;{ActionExt}])
1924        ActionExtIndex=numel(ActionExtList)+1;
1925        ActionPathNew=cell(size(ActionPathList,1),1);%new column of ActionPath
1926        ActionPathList=[ActionPathList ActionPathNew];
1927    end
1928    set(handles.ActionName,'UserData',ActionPathList);
1929
1930    % remove old Action options in the menu (keeping a menu length <nb_builtin_ACTION+5)
1931    if length(ActionList)>nb_builtin_ACTION+5; %nb_builtin=nbre of functions always remaining in the initial menu
1932        nbremove=length(ActionList)-nb_builtin_ACTION-5;
1933        ActionList(nb_builtin_ACTION+1:end-5)=[];
1934        ActionPathList(nb_builtin_ACTION+1:end-4,:)=[];
1935        ActionIndex=ActionIndex-nbremove;
1936    end
1937   
1938    % record action menu, choice and path
1939    set(handles.ActionName,'Value',ActionIndex)
1940    set(handles.ActionName,'String',ActionList)
1941    set(handles.ActionExt,'Value',ActionExtIndex)
1942    ActionPathList{ActionIndex,ActionExtIndex}=PathName;
1943       
1944    %record the user defined menu additions in personal file profil_perso
1945    dir_perso=prefdir;
1946    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
1947    if nb_builtin_ACTION+1<=numel(ActionList)-1
1948        ActionListUser=ActionList(nb_builtin_ACTION+1:numel(ActionList)-1);
1949        ActionPathListUser=ActionPathList(nb_builtin_ACTION+1:numel(ActionList)-1,:);
1950        ActionExtListUser={};
1951        if numel(ActionExtList)>2
1952            ActionExtListUser=ActionExtList(3:end);
1953        end
1954        if exist(profil_perso,'file')
1955            save(profil_perso,'ActionListUser','ActionPathListUser','ActionExtListUser','-append')
1956        else
1957            save(profil_perso,'ActionListUser','ActionPathListUser','ActionExtListUser','-V6')
1958        end
1959    end
1960end
1961
1962%% check the current ActionPath to the selected function
1963ActionPath=ActionPathList{ActionIndex};%current recorded path
1964set(handles.ActionPath,'String',ActionPath); %show the path to the senlected function
1965
1966%% reinitialise the waitbar
1967update_waitbar(handles.Waitbar,0)
1968
1969%% default setting for the visibility of the GUI elements
1970% set(handles.FieldTransform,'Visible','off')
1971% set(handles.CheckObject,'Visible','off');
1972% set(handles.ProjObject,'Visible','off');
1973% set(handles.CheckMask,'Visible','off')
1974% set(handles.Mask,'Visible','off')
1975
1976%% create the function handle for Action
1977path_series=which('series');
1978if ~isequal(ActionPath,path_series)
1979    eval(['spath=which(''' ActionName ''');']) %spath = current path of the selected function ACTION
1980    if ~exist(ActionPath,'dir')
1981        errormsg=['The prescribed function path ' ActionPath ' does not exist'];
1982        return
1983    end
1984    if ~isequal(spath,ActionPath)
1985        addpath(ActionPath)% add the prescribed path if not the current one
1986    end
1987end
1988eval(['h_fun=@' ActionName ';'])%create a function handle for ACTION
1989if ~isequal(ActionPath,path_series)
1990        rmpath(ActionPath)% add the prescribed path if not the current one   
1991end
1992
1993%% Activate the Action fct
1994Param=read_GUI_series(handles);% read the parameters from the GUI series
1995ParamOut=h_fun(Param);%run the selected Action function to get the relevant input
1996
1997%% Put the first line of the selected Action fct as tooltip help
1998try
1999    [fid,errormsg] =fopen([ActionName '.m']);
2000    InputText=textscan(fid,'%s',1,'delimiter','\n');
2001    fclose(fid);
2002    set(handles.ActionName,'ToolTipString',InputText{1}{1})% put the first line of the selected function as tooltip help
2003end
2004
2005%% Detect the types of input files
2006SeriesData=get(handles.series,'UserData');
2007iview_civ=[];nb_netcdf=0;
2008if ~isempty(SeriesData)&&isfield(SeriesData,'FileType')
2009    iview_civ=find(strcmp('civx',SeriesData.FileType)|strcmp('civdata',SeriesData.FileType));
2010    nb_netcdf=numel(find(strcmp('netcdf',SeriesData.FileType)));
2011end
2012%menu={''};
2013if numel(iview_civ)>=1
2014    menu=set_veltype_display(SeriesData.FileInfo{iview_civ(1)}.CivStage,SeriesData.FileType{iview_civ(1)});
2015    set(handles.VelType,'String',[{'*'};menu])
2016    if numel(iview_civ)>=2
2017        menu=set_veltype_display(SeriesData.FileInfo{iview_civ(2)}.CivStage,SeriesData.FileType{iview_civ(2)});
2018        set(handles.VelType_1,'String',[{'*'};menu])
2019    end
2020end       
2021
2022%% Check whether alphabetical sorting of input Subdir is allowed by the Action fct  (for multiples series entries)
2023if isfield(ParamOut,'AllowInputSort')&&isequal(ParamOut.AllowInputSort,'on')&& size(Param.InputTable,1)>1
2024    [tild,iview]=sort(InputTable(:,2)); %subdirectories sorted in alphabetical order
2025    set(handles.InputTable,'Data',InputTable(iview,:));
2026    MinIndex_i=get(handles.MinIndex_i,'Data');
2027    MinIndex_j=get(handles.MinIndex_j,'Data');
2028    MaxIndex_i=get(handles.MaxIndex_i,'Data');
2029    MaxIndex_j=get(handles.MaxIndex_j,'Data');
2030    set(handles.MinIndex_i,'Data',MinIndex_i(iview,:));
2031    set(handles.MinIndex_j,'Data',MinIndex_j(iview,:));
2032    set(handles.MaxIndex_i,'Data',MaxIndex_i(iview,:));
2033    set(handles.MaxIndex_j,'Data',MaxIndex_j(iview,:));
2034    TimeTable=get(handles.TimeTable,'Data');
2035    set(handles.TimeTable,'Data',TimeTable(iview,:));
2036    PairString=get(handles.PairString,'Data');
2037    set(handles.PairString,'Data',PairString(iview,:));
2038end
2039
2040%% Impose the whole input file index range if requested
2041if isfield(ParamOut,'WholeIndexRange')&&isequal(ParamOut.WholeIndexRange,'on')
2042    MinIndex_i=get(handles.MinIndex_i,'Data');
2043    MinIndex_j=get(handles.MinIndex_j,'Data');
2044    MaxIndex_i=get(handles.MaxIndex_i,'Data');
2045    MaxIndex_j=get(handles.MaxIndex_j,'Data');
2046    set(handles.num_first_i,'String',num2str(MinIndex_i(1)))% set first as the min index (for the first line)
2047    set(handles.num_last_i,'String',num2str(MaxIndex_i(1)))% set last as the max index (for the first line)
2048    set(handles.num_incr_i,'String','1')
2049    set(handles.num_first_j,'String',num2str(MinIndex_j(1)))% set first as the min index (for the first line)
2050    set(handles.num_last_j,'String',num2str(MaxIndex_j(1)))% set last as the max index (for the first line)
2051    set(handles.num_incr_j,'String','1')
2052else  % check index ranges
2053    first_i=1;last_i=1;first_j=1;last_j=1;
2054    if isfield(Param.IndexRange,'first_i')
2055        first_i=Param.IndexRange.first_i;
2056       % incr_i=Param.IndexRange.incr_i;
2057        last_i=Param.IndexRange.last_i;
2058    end
2059    if isfield(Param.IndexRange,'first_j')
2060        first_j=Param.IndexRange.first_j;
2061       % incr_j=Param.IndexRange.incr_j;
2062        last_j=Param.IndexRange.last_j;
2063    end
2064    if last_i < first_i || last_j < first_j , msgbox_uvmat('ERROR','last field number must be larger than the first one'),...
2065            set(handles.RUN, 'Enable','On'), set(handles.RUN,'BackgroundColor',[1 0 0]),return,end;
2066end
2067
2068%% NbSlice visibility
2069NbSliceVisible='off';%default
2070if isfield(ParamOut,'NbSlice') && isequal(ParamOut.NbSlice,'on')
2071    NbSliceVisible='on';
2072    set(handles.num_NbProcess,'String',get(handles.num_NbSlice,'String'))% the nbre of processes is imposed as the nbre of slices
2073else
2074    set(handles.num_NbProcess,'String','')% free nbre of processes
2075end
2076set(handles.num_NbSlice,'Visible',NbSliceVisible)
2077set(handles.NbSlice_title,'Visible',NbSliceVisible)
2078
2079%% Visibility of VelType and VelType_1 menus
2080VelTypeVisible='off';  %hidden by default
2081VelType_1Visible='off';
2082InputFieldsVisible='off';%visibility of the frame Fields
2083if isfield(ParamOut,'VelType')
2084    if strcmp( ParamOut.VelType,'on')||strcmp(ParamOut.VelType,'one')||strcmp( ParamOut.VelType,'two')
2085        if numel(iview_civ)>=1
2086            VelTypeVisible='on';
2087            InputFieldsVisible='on';
2088        end
2089    end
2090    if strcmp( ParamOut.VelType,'two')
2091        if numel(iview_civ)>=2
2092            VelType_1Visible='on';
2093        end
2094    end
2095end
2096set(handles.VelType,'Visible',VelTypeVisible)
2097set(handles.VelType_text,'Visible',VelTypeVisible);
2098set(handles.VelType_1,'Visible',VelType_1Visible)
2099set(handles.VelType_text_1,'Visible',VelType_1Visible);
2100
2101%% Visibility of FieldName and FieldName_1 menus
2102FieldNameVisible='off';  %hidden by default
2103FieldName_1Visible='off';  %hidden by default
2104if isfield(ParamOut,'FieldName')
2105    if strcmp( ParamOut.FieldName,'on') || strcmp(ParamOut.FieldName,'one')||strcmp( ParamOut.FieldName,'two')
2106        if (numel(iview_civ)+nb_netcdf)>=1
2107            InputFieldsVisible='on';
2108            FieldNameVisible='on';
2109        end
2110    end
2111    if strcmp( ParamOut.FieldName,'two')
2112        if (numel(iview_civ)+nb_netcdf)>=1
2113            FieldName_1Visible='on';
2114        end
2115    end
2116end
2117set(handles.InputFields,'Visible',InputFieldsVisible)
2118set(handles.FieldName,'Visible',FieldNameVisible) % test for MenuBorser
2119set(handles.FieldName_1,'Visible',FieldName_1Visible)
2120
2121%% Visibility of FieldTransform menu
2122FieldTransformVisible='off';  %hidden by default
2123if isfield(ParamOut,'FieldTransform')
2124    FieldTransformVisible=ParamOut.FieldTransform; 
2125    TransformName_Callback([],[], handles)
2126end
2127set(handles.FieldTransform,'Visible',FieldTransformVisible)
2128if isfield(ParamOut,'TransformPath')
2129    set(handles.ActionExt,'UserData',ParamOut.TransformPath)
2130else
2131    set(handles.ActionExt,'UserData',[])
2132end
2133
2134%% Visibility of projection object
2135ProjObjectVisible='off';  %hidden by default
2136if isfield(ParamOut,'ProjObject')
2137    ProjObjectVisible=ParamOut.ProjObject;
2138end
2139set(handles.CheckObject,'Visible',ProjObjectVisible)
2140if ~get(handles.CheckObject,'Value')
2141    ProjObjectVisible='off';
2142end
2143set(handles.ProjObject,'Visible',ProjObjectVisible)
2144set(handles.DeleteObject,'Visible',ProjObjectVisible)
2145set(handles.ViewObject,'Visible',ProjObjectVisible)
2146set(handles.EditObject,'Visible',ProjObjectVisible)
2147
2148%% Visibility of mask input
2149MaskVisible='off';  %hidden by default
2150if isfield(ParamOut,'Mask')
2151    MaskVisible=ParamOut.Mask;
2152end
2153%set(handles.Mask,'Visible',MaskVisible)
2154set(handles.CheckMask,'Visible',MaskVisible);
2155
2156%% definition of the directory containing the output files
2157OutputDirVisible='off';
2158if isfield(ParamOut,'OutputDirExt')&&~isempty(ParamOut.OutputDirExt)
2159    OutputSubDirMode='all';%default
2160    if isfield(ParamOut,'OutputSubDirMode')
2161        OutputSubDirMode=ParamOut.OutputSubDirMode;
2162    end
2163    set(handles.OutputDirExt,'String',ParamOut.OutputDirExt)
2164    OutputDirVisible='on';
2165    SubDir=InputTable(1:end,2); %set of subdirectories sorted in alphabetical order
2166    if strcmp(OutputSubDirMode,'last')
2167        SubDirOut=SubDir{end};
2168    else
2169        SubDirOut=SubDir{1};
2170        if ~strcmp(OutputSubDirMode,'first')  && numel(SubDir)>1
2171            for ilist=2:numel(SubDir)
2172                SubDirOut=[SubDirOut '-' SubDir{ilist}];
2173            end
2174        end
2175    end
2176    set(handles.OutputSubDir,'String',SubDirOut)
2177end
2178set(handles.OutputDirExt,'Visible',OutputDirVisible)
2179set(handles.OutputSubDir,'Visible',OutputDirVisible)
2180set(handles.OutputDir_title,'Visible',OutputDirVisible)
2181set(handles.RunMode,'Visible',OutputDirVisible)
2182set(handles.ActionExt,'Visible',OutputDirVisible)
2183set(handles.RunMode_title,'Visible',OutputDirVisible)
2184set(handles.ActionExt_title,'Visible',OutputDirVisible)
2185
2186
2187%% Expected nbre of output files
2188if isfield(ParamOut,'OutputFileMode')
2189    StatusData.OutputFileMode=ParamOut.OutputFileMode;
2190    set(handles.status,'UserData',StatusData)
2191end
2192
2193%% definition of an additional parameter set, determined by an ancillary GUI
2194if isfield(ParamOut,'ActionInput')
2195%     set(handles.ActionInput,'Visible','on')
2196%     set(handles.ActionInput_title,'Visible','on')
2197    set(handles.ActionInput,'Visible','on')
2198 %   set(handles.ActionInput,'Value',0)
2199%     set(handles.ActionInput,'String',ActionName)
2200    ParamOut.ActionInput.Program=ActionName; % record the program in ActionInput
2201    SeriesData.ActionInput=ParamOut.ActionInput;
2202else
2203%     set(handles.ActionInput,'Visible','off')
2204%     set(handles.ActionInput_title,'Visible','off')
2205    set(handles.ActionInput,'Visible','off')
2206    if isfield(SeriesData,'ActionInput')
2207    SeriesData=rmfield(SeriesData,'ActionInput');
2208    end
2209end   
2210set(handles.series,'UserData',SeriesData)
2211set(handles.ActionName,'BackgroundColor',[1 1 1])
2212
2213%------------------------------------------------------------------------
2214% --- Executes on button press in ActionInput.
2215function ActionInput_Callback(hObject, eventdata, handles)
2216%------------------------------------------------------------------------
2217% if get(handles.ActionInput,'Value')
2218ActionName_Callback(hObject, eventdata, handles)
2219% end
2220
2221%------------------------------------------------------------------------
2222% --- Executes on selection change in FieldName.
2223function FieldName_Callback(hObject, eventdata, handles)
2224%------------------------------------------------------------------------
2225field_str=get(handles.FieldName,'String');
2226field_index=get(handles.FieldName,'Value');
2227field=field_str{field_index(1)};
2228if isequal(field,'get_field...')
2229    hget_field=findobj(allchild(0),'name','get_field');
2230    if ~isempty(hget_field)
2231        delete(hget_field)%delete opened versions of get_field
2232    end
2233    Param=read_GUI(handles.series);
2234    Param.InputTable=Param.InputTable(1,:);
2235    filecell=get_file_series(Param);
2236   
2237    if exist(filecell{1,1},'file')
2238        GetFieldData=get_field(filecell{1,1});
2239        FieldList={};
2240        switch GetFieldData.FieldOption
2241            case 'vectors'
2242                UName=GetFieldData.PanelVectors.vector_x;
2243                VName=GetFieldData.PanelVectors.vector_y;
2244                YName={GetFieldData.Coordinates.Coord_y};
2245                CName=GetFieldData.PanelVectors.vec_color;
2246                FieldList={['vec(' UName ',' VName ')'];...
2247                    ['norm(' UName ',' VName ')'];...
2248                    UName;VName};
2249                VecColorList={['norm(' UName ',' VName ')'];...
2250                    UName;VName};
2251                if ~isempty(CName)
2252                    VecColorList=[{CName};VecColorList];
2253                end
2254            case 'scalar'
2255                AName=GetFieldData.PanelScalar.scalar;
2256                YName={GetFieldData.Coordinates.Coord_y};
2257                FieldList={AName};
2258            case '1D plot'
2259                YName=GetFieldData.PanelOrdinate.ordinate;
2260%             case 'civdata...'%reinitiate input, return to automatic civ data reading
2261%                 display_file_name(handles,FileName,1)
2262        end
2263        if ~strcmp(GetFieldData.FieldOption,'civdata...')
2264            XName=GetFieldData.Coordinates.Coord_x;
2265            TimeNameStr=GetFieldData.Time.SwitchVarIndexTime;
2266            switch TimeNameStr
2267                case 'file index'
2268                    set(handles.TimeName,'String','');
2269                case 'attribute'
2270                    set(handles.TimeName,'String',['att:' GetFieldData.Time.TimeName]);
2271                case 'variable'
2272                    set(handles.TimeName,'String',['var:' GetFieldData.Time.TimeName])
2273                    set(handles.NomType,'String','*')
2274                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])% A VERIFIER !!!!!!
2275                    set(handles.FileIndex,'String','')
2276                    ParamIn.TimeVarName=GetFieldData.Time.TimeName;
2277                case 'matrix_index'
2278                    set(handles.TimeName,'String',['dim:' GetFieldData.Time.TimeName]);
2279                    set(handles.NomType,'String','*')
2280                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
2281                    set(handles.FileIndex,'String','')
2282                    ParamIn.TimeDimName=GetFieldData.Time.TimeName;
2283            end
2284            set(handles.Coord_x,'String',{XName})
2285            set(handles.Coord_y,'String',YName)
2286            set(handles.FieldName,'Value',1)
2287            set(handles.FieldName,'String',[FieldList; {'get_field...'}]);
2288        end
2289    end
2290end
2291
2292%------------------------------------------------------------------------
2293% --- Executes on selection change in FieldName_1.
2294function FieldName_1_Callback(hObject, eventdata, handles)
2295%------------------------------------------------------------------------
2296field_str=get(handles.FieldName_1,'String');
2297field_index=get(handles.FieldName_1,'Value');
2298field=field_str{field_index};
2299if isequal(field,'get_field...')   
2300     hget_field=findobj(allchild(0),'name','get_field_1');
2301     if ~isempty(hget_field)
2302         delete(hget_field)
2303     end
2304     SeriesData=get(handles.series,'UserData');
2305     filename=SeriesData.CurrentInputFile_1;
2306     if exist(filename,'file')
2307        hget_field=get_field(filename);
2308        set(hget_field,'name','get_field_1')
2309     end
2310% elseif isequal(field,'more...')
2311%     str=calc_field;
2312%     [ind_answer,v] = listdlg('PromptString','Select a file:',...
2313%                 'SelectionMode','single',...
2314%                 'ListString',str);
2315%        % edit the choice in the fields and actionname menu
2316%      scalar=cell2mat(str(ind_answer));
2317%      update_menu(handles.FieldName_1,scalar)
2318end   
2319
2320
2321%%%%%%%%%%%%%
2322function [ind_remove]=find_pairs(dirpair,ind_i,last_i)
2323indsel=ind_i;
2324indiff=diff(ind_i); %test index increment to detect multiplets (several pairs with the same index ind_i) and holes in the series
2325indiff=[1 indiff last_i-ind_i(end)+1];%for testing gaps with the imposed bounds
2326if ~isempty(indiff)
2327    indiff2=diff(indiff);
2328    indiffp=[indiff2 1];
2329    indiffm=[1 indiff2];
2330    ind_multi_m=find((indiff==0)&(indiffm<0))-1;%indices of first members of multiplets
2331    ind_multi_p=find((indiff==0)&(indiffp>0));%indices of last members of multiplets
2332    %for each multiplet, select the most recent file
2333    ind_remove=[];
2334    for i=1:length(ind_multi_m)
2335        ind_pairs=ind_multi_m(i):ind_multi_p(i);
2336        for imulti=1:length(ind_pairs)
2337            datepair(imulti)=datenum(dirpair(ind_pairs(imulti)).date);%dates of creation
2338        end
2339        [datenew,indsort2]=sort(datepair); %sort the multiplet by creation date
2340        ind_s=indsort2(1:end-1);%
2341        ind_remove=[ind_remove ind_pairs(ind_s)];%remove these indices, leave the last one
2342    end
2343end
2344
2345%------------------------------------------------------------------------
2346% --- determine the list of index pairstring of processing file
2347function [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)
2348%------------------------------------------------------------------------
2349num_i1=num_i;% set of first image numbers by default
2350num_i2=num_i;
2351num_j1=num_j;
2352num_j2=num_j;
2353num_i_out=num_i;
2354num_j_out=num_j;
2355% if isequal (NomType,'_1-2_1') || isequal (NomType,'_1-2')
2356if isequal(mode,'series(Di)')
2357    num_i1_line=num_i+ind_shift(3);% set of first image numbers
2358    num_i2_line=num_i+ind_shift(4);
2359    % adjust the first and last field number
2360        indsel=find(num_i1_line >= 1);
2361    num_i_out=num_i(indsel);
2362    num_i1_line=num_i1_line(indsel);
2363    num_i2_line=num_i2_line(indsel);
2364    num_j1=meshgrid(num_j,ones(size(num_i1_line)));
2365    num_j2=meshgrid(num_j,ones(size(num_i1_line)));
2366    [xx,num_i1]=meshgrid(num_j,num_i1_line);
2367    [xx,num_i2]=meshgrid(num_j,num_i2_line);
2368elseif isequal (mode,'series(Dj)')||isequal (mode,'bursts')
2369    if isequal(mode,'bursts') %case of bursts (png_old or png_2D)
2370        num_j1=ind_shift(1)*ones(size(num_i));
2371        num_j2=ind_shift(2)*ones(size(num_i));
2372    else
2373        num_j1_col=num_j+ind_shift(1);% set of first image numbers
2374        num_j2_col=num_j+ind_shift(2);
2375        % adjust the first field number
2376        indsel=find((num_j1_col >= 1));   
2377        num_j_out=num_j(indsel);
2378        num_j1_col=num_j1_col(indsel);
2379        num_j2_col=num_j2_col(indsel);
2380        [num_i1,num_j1]=meshgrid(num_i,num_j1_col);
2381        [num_i2,num_j2]=meshgrid(num_i,num_j2_col);
2382    end   
2383end
2384
2385%------------------------------------------------------------------------
2386% --- Executes on button press in CheckObject.
2387function CheckObject_Callback(hObject, eventdata, handles)
2388%------------------------------------------------------------------------
2389hset_object=findobj(allchild(0),'tag','set_object');%find the set_object interface handle
2390if get(handles.CheckObject,'Value')
2391    SeriesData=get(handles.series,'UserData');
2392    if isfield(SeriesData,'ProjObject') && ~isempty(SeriesData.ProjObject)
2393        set(handles.ViewObject,'Value',1)
2394        ViewObject_Callback(hObject, eventdata, handles)
2395    else
2396        if ishandle(hset_object)
2397            uistack(hset_object,'top')% show the GUI set_object if opened
2398        else
2399            %get the object file
2400            InputTable=get(handles.InputTable,'Data');
2401            defaultname=InputTable{1,1};
2402            if isempty(defaultname)
2403                defaultname={''};
2404            end
2405            fileinput=uigetfile_uvmat('pick a xml object file (or use uvmat to create it)',defaultname,'.xml');
2406            if isempty(fileinput)% exit if no object file is selected
2407                set(handles.CheckObject,'Value',0)
2408                return
2409            end
2410            %read the file
2411            data=xml2struct(fileinput);
2412            if ~isfield(data,'Type')
2413                msgbox_uvmat('ERROR',[fileinput ' is not an object xml file'])
2414                set(handles.CheckObject,'Value',0)
2415                return
2416            end
2417            if ~isfield(data,'ProjMode')
2418                data.ProjMode='none';
2419            end
2420            hset_object=set_object(data);% call the set_object interface
2421        end
2422        ProjObject=read_GUI(hset_object);
2423        set(handles.ProjObject,'String',ProjObject.Name);%display the object name
2424        SeriesData=get(handles.series,'UserData');
2425        SeriesData.ProjObject=ProjObject;
2426        set(handles.series,'UserData',SeriesData);
2427    end
2428    set(handles.EditObject,'Visible','on');
2429    set(handles.DeleteObject,'Visible','on');
2430    set(handles.ViewObject,'Visible','on');
2431    set(handles.ProjObject,'Visible','on');
2432else
2433    set(handles.EditObject,'Visible','off');
2434    set(handles.DeleteObject,'Visible','off');
2435    set(handles.ViewObject,'Visible','off');
2436    if ~ishandle(hset_object)
2437        set(handles.ViewObject,'Value',0);
2438    end
2439    set(handles.ProjObject,'Visible','off');
2440end
2441
2442%------------------------------------------------------------------------
2443% --- Executes on button press in ViewObject.
2444%------------------------------------------------------------------------
2445function ViewObject_Callback(hObject, eventdata, handles)
2446
2447UserData=get(handles.series,'UserData');
2448hset_object=findobj(allchild(0),'Tag','set_object');
2449if ~isempty(hset_object)
2450    delete(hset_object)% refresh set_object if already opened
2451end
2452hset_object=set_object(UserData.ProjObject);
2453set(hset_object,'Name','view_object_series')
2454
2455
2456%------------------------------------------------------------------------
2457% --- Executes on button press in EditObject.
2458function EditObject_Callback(hObject, eventdata, handles)
2459%------------------------------------------------------------------------
2460if get(handles.EditObject,'Value')
2461    set(handles.ViewObject,'Value',0)
2462        UserData=get(handles.series,'UserData');
2463    hset_object=set_object(UserData.ProjObject);
2464    set(hset_object,'Name','edit_object_series')
2465    set(get(hset_object,'Children'),'Enable','on')
2466else
2467    hset_object=findobj(allchild(0),'Tag','set_object');
2468    if ~isempty(hset_object)
2469        set(get(hset_object,'Children'),'Enable','off')
2470    end
2471end
2472
2473%------------------------------------------------------------------------
2474% --- Executes on button press in DeleteObject.
2475function DeleteObject_Callback(hObject, eventdata, handles)
2476%------------------------------------------------------------------------
2477SeriesData=get(handles.series,'UserData');
2478SeriesData.ProjObject=[];
2479set(handles.series,'UserData',SeriesData)
2480set(handles.ProjObject,'String','')
2481set(handles.ProjObject,'Visible','off')
2482set(handles.CheckObject,'Value',0)
2483set(handles.ViewObject,'Visible','off')
2484set(handles.EditObject,'Visible','off')
2485hset_object=findobj(allchild(0),'Tag','set_object');
2486if ~isempty(hset_object)
2487    delete(hset_object)
2488end
2489set(handles.DeleteObject,'Visible','off')
2490
2491%------------------------------------------------------------------------
2492% --- Executed when CheckMask is activated
2493%------------------------------------------------------------------------
2494function CheckMask_Callback(hObject, eventdata, handles)
2495
2496if get(handles.CheckMask,'Value')
2497    InputTable=get(handles.InputTable,'Data');
2498    nbview=size(InputTable,1);
2499    MaskTable=cell(nbview,1);%default
2500    ListMask=cell(nbview,1);%default
2501    MaskData=get(handles.MaskTable,'Data');
2502    MaskData(size(MaskData,1):nbview,1)=cell(size(MaskData,1):nbview,1);%complement if undefined lines
2503    for iview=1:nbview
2504        ListMask{iview,1}=num2str(iview);
2505        RootPath=InputTable{iview,1};
2506        if ~isempty(RootPath)
2507            if isempty(MaskData{iview})
2508                SubDir=InputTable{iview,2};
2509                MaskPath=fullfile(RootPath,[regexprep(SubDir,'\..*','') '.mask']);%take the root part of SubDir, before the first dot '.'
2510                if exist(MaskPath,'dir')
2511                    ListStruct=dir(MaskPath);%look for a mask file
2512                    ListCells=struct2cell(ListStruct);% transform dir struct to a cell arrray
2513                    check_dir=cell2mat(ListCells(4,:));% =1 for directories, =0 for files
2514                    ListFiles=ListCells(1,:);%list of file and dri names
2515                    ListFiles=ListFiles(~check_dir);%list of file names (excluding dir)
2516                    mdetect=0;
2517                    if ~isempty(ListFiles)
2518                        for ifile=1:numel(ListFiles)
2519                            [tild,tild,MaskFile{ifile},i1_series,i2_series,j1_series,j2_series,MaskNomType,MaskFileType]=find_file_series(MaskPath,ListFiles{ifile},0);
2520                            if strcmp(MaskFileType,'image') && isempty(i2_series) && isempty(j2_series)
2521                                mdetect=1;
2522                                MaskName=ListFiles{ifile};
2523                            end
2524                            if ~strcmp(MaskFile{ifile},MaskFile{1})
2525                                mdetect=0;% cancel detection test in case of multiple masks, use the brower for selection
2526                                break
2527                            end
2528                        end
2529                    end
2530                    if mdetect==1
2531                        MaskName=fullfile(MaskPath,'mask_1.png');
2532                    else
2533                        MaskName=uigetfile_uvmat('select a mask file:',MaskPath,'image');
2534                    end
2535                else
2536                    MaskName=uigetfile_uvmat('select a mask file:',RootPath,'image');
2537                end
2538                MaskTable{iview,1}=MaskName ;
2539                ListMask{iview,1}=num2str(iview);
2540            end
2541        end
2542    end
2543    set(handles.MaskTable,'Data',MaskTable)
2544    set(handles.MaskTable,'Visible','on')
2545    set(handles.MaskBrowse,'Visible','on')
2546    set(handles.ListMask,'Visible','on')
2547    set(handles.ListMask,'String',ListMask)
2548    set(handles.ListMask,'Value',1)
2549else
2550    set(handles.MaskTable,'Visible','off')
2551    set(handles.MaskBrowse,'Visible','off')
2552    set(handles.ListMask,'Visible','off')
2553end
2554
2555%------------------------------------------------------------------------
2556% --- Executes on button press in MaskBrowse.
2557%------------------------------------------------------------------------
2558function MaskBrowse_Callback(hObject, eventdata, handles)
2559
2560InputTable=get(handles.InputTable,'Data');
2561iview=get(handles.ListMask,'Value');
2562RootPath=InputTable{iview,1};
2563MaskName=uigetfile_uvmat('select a mask file:',RootPath,'image');
2564if ~isempty(MaskName)
2565    MaskTable=get(handles.MaskTable,'Data');
2566    MaskTable{iview,1}=MaskName ;
2567    set(handles.MaskTable,'Data',MaskTable)
2568end
2569
2570%------------------------------------------------------------------------
2571% --- Executes when selected cell(s) is changed in MaskTable.
2572%------------------------------------------------------------------------
2573function MaskTable_CellSelectionCallback(hObject, eventdata, handles)
2574
2575if numel(eventdata.Indices)>=1
2576set(handles.ListMask,'Value',eventdata.Indices(1))
2577end
2578
2579%-------------------------------------------------------------------
2580function MenuHelp_Callback(hObject, eventdata, handles)
2581%-------------------------------------------------------------------
2582path_to_uvmat=which ('uvmat');% check the path of uvmat
2583pathelp=fileparts(path_to_uvmat);
2584helpfile=fullfile(pathelp,'uvmat_doc','uvmat_doc.html');
2585if isempty(dir(helpfile)), msgbox_uvmat('ERROR','Please put the help file uvmat_doc.html in the sub-directory /uvmat_doc of the UVMAT package')
2586else
2587    addpath (fullfile(pathelp,'uvmat_doc'))
2588    web([helpfile '#series'])
2589end
2590
2591%-------------------------------------------------------------------
2592% --- Executes on selection change in TransformName.
2593function TransformName_Callback(hObject, eventdata, handles)
2594%----------------------------------------------------------------------
2595TransformList=get(handles.TransformName,'String');
2596TransformIndex=get(handles.TransformName,'Value');
2597TransformName=TransformList{TransformIndex};
2598TransformPathList=get(handles.TransformName,'UserData');
2599nb_builtin_transform=4;
2600% ff=functions(list_transform{end});
2601if isequal(TransformName,'more...');
2602%     [FileName, PathName] = uigetfile( ...
2603%        {'*.m', ' (*.m)';
2604%         '*.m',  '.m files '; ...
2605%         '*.*', 'All Files (*.*)'}, ...
2606%         'Pick a transform function',get(handles.TransformPath,'String'));
2607   
2608    FileName=uigetfile_uvmat('Pick a transform function',get(handles.TransformPath,'String'),'.m');
2609    if isempty(FileName)
2610        return     %browser closed without choice
2611    end
2612%     if isequal(PathName(end),'/')||isequal(PathName(end),'\')
2613%         PathName(end)=[];
2614%     end
2615    [TransformPath,TransformName,TransformExt]=fileparts(FileName);% removes extension .m
2616    if ~strcmp(TransformExt,'.m')
2617        msgbox_uvmat('ERROR','a Matlab function .m must be introduced');
2618        return
2619    end
2620     % insert the choice in the menu
2621    TransformIndex=find(strcmp(TransformName,TransformList),1);% look for the selected function in the menu Action
2622    if isempty(TransformIndex)%the input string does not exist in the menu
2623        TransformIndex= length(TransformList);
2624        TransformList=[TransformList(1:end-1);{TransformName};TransformList(end)];% the selected function is appended in the menu, before the last item 'more...'
2625        set(handles.TransformName,'String',TransformList)
2626        TransformPathList=[TransformPathList;{TransformPath}];
2627    end
2628   % save the new menu in the personal file 'uvmat_perso.mat'
2629   dir_perso=prefdir;%personal Matalb directory
2630   profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
2631   if exist(profil_perso,'file')
2632       for ilist=nb_builtin_transform+1:numel(TransformPathList)
2633           TransformListUser{ilist-nb_builtin_transform}=TransformList{ilist};
2634           TransformPathListUser{ilist-nb_builtin_transform}=TransformPathList{ilist};
2635       end
2636       TransformPathListUser=TransformPathListUser';
2637       TransformListUser=TransformListUser';
2638       save (profil_perso,'TransformPathListUser','TransformListUser','-append'); %store the root name for future opening of uvmat
2639   end
2640end
2641
2642%display the current function path
2643set(handles.TransformPath,'String',TransformPathList{TransformIndex}); %show the path to the senlected function
2644set(handles.TransformName,'UserData',TransformPathList);
2645
2646%------------------------------------------------------------------------
2647% --- fct activated by the upper bar menu ExportConfig
2648%------------------------------------------------------------------------
2649function MenuExportConfig_Callback(hObject, eventdata, handles)
2650
2651global Param
2652Param=read_GUI_series(handles);
2653evalin('base','global Param')%make CurData global in the workspace
2654display('current series config :')
2655evalin('base','Param') %display CurData in the workspace
2656commandwindow; %brings the Matlab command window to the front
2657
2658%------------------------------------------------------------------------
2659% --- fct activated by the upper bar menu InportConfig: import
2660%     menu settings from an xml file (stored in /0_XML for each run)
2661%------------------------------------------------------------------------
2662function MenuImportConfig_Callback(hObject, eventdata, handles)
2663% SeriesData=get(handles.series,'UserData');
2664% if isfield(SeriesData,'RefFile')
2665%     oldfile=SeriesData.RefFile{1};
2666% end
2667%% use a strating file name for browserr
2668InputTable=get(handles.InputTable,'Data');
2669oldfile=InputTable{1,1};
2670if isempty(oldfile)
2671    % use a file name stored in prefdir
2672    dir_perso=prefdir;
2673    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
2674    if exist(profil_perso,'file')
2675        h=load (profil_perso);
2676        if isfield(h,'RootPath') && ischar(h.RootPath)
2677            oldfile=h.RootPath;
2678        end
2679    end
2680end
2681filexml=uigetfile_uvmat('pick a xml parameter file',oldfile,'.xml');% get the xml file containing processing parameters
2682%proceed only if a file has been introduced by the browser
2683if ~isempty(filexml)
2684    Param=xml2struct(filexml);% read the input xml file as a Matlab structure
2685    % ask to stop current Action if button RUN is in action (another process is already running)
2686    if isequal(get(handles.RUN,'Value'),1)
2687        answer= msgbox_uvmat('INPUT_Y-N','stop current Action process?');
2688        if strcmp(answer,'Yes')
2689            STOP_Callback(hObject, eventdata, handles)
2690        else
2691            return
2692        end
2693    end
2694    Param.Action.RUN=0; %desactivate the input RUN=1
2695    fill_GUI(Param,handles.series)% fill the elements of the GUI series with the input parameters
2696    SeriesData=get(handles.series,'UserData');
2697    if isfield(Param,'ActionInput')%  introduce  parameters specific to an Action fct, for instance PIV parameters
2698        set(handles.ActionInput,'Visible','on')
2699        set(handles.ActionInput,'Value',0)
2700        SeriesData.ActionInput=Param.ActionInput;
2701    end
2702    if isfield(Param,'ProjObject') %introduce projection object if relevant
2703        SeriesData.ProjObject=Param.ProjObject;
2704    end
2705    set(handles.series,'UserData',SeriesData)
2706    if isfield(Param,'CheckObject') && isequal(Param.CheckObject,1)
2707        set(handles.ProjObject,'String',Param.ProjObject.Name)
2708        set(handles.ViewObject,'Visible','on')
2709        set(handles.EditObject,'Visible','on')
2710        set(handles.DeleteObject,'Visible','on')
2711    else     
2712        set(handles.ProjObject,'String','')
2713        set(handles.ProjObject,'Visible','off')
2714        set(handles.ViewObject,'Visible','off')
2715        set(handles.EditObject,'Visible','off')
2716        set(handles.DeleteObject,'Visible','off')     
2717    end     
2718    set(handles.REFRESH,'BackgroundColor',[1 0 1]); %paint REFRESH button in magenta to indicate that it should be activated
2719end
2720
2721%------------------------------------------------------------------------
2722% --- Executes when the GUI series is resized.
2723%------------------------------------------------------------------------
2724function series_ResizeFcn(hObject, eventdata, handles)
2725
2726%% input table
2727set(handles.InputTable,'Unit','pixel')
2728Pos=get(handles.InputTable,'Position');
2729set(handles.InputTable,'Unit','normalized')
2730ColumnWidth=round([0.5 0.14 0.14 0.14 0.08]*(Pos(3)-52));
2731ColumnWidth=num2cell(ColumnWidth);
2732set(handles.InputTable,'ColumnWidth',ColumnWidth)
2733
2734%% MinIndex_j and MaxIndex_i
2735unit=get(handles.MinIndex_i,'Unit');
2736set(handles.MinIndex_i,'Unit','pixel')
2737Pos=get(handles.MinIndex_i,'Position');
2738set(handles.MinIndex_i,'Unit',unit)
2739set(handles.MinIndex_i,'ColumnWidth',{Pos(3)-18})
2740set(handles.MaxIndex_i,'ColumnWidth',{Pos(3)-18})
2741set(handles.MinIndex_j,'ColumnWidth',{Pos(3)-18})
2742set(handles.MaxIndex_j,'ColumnWidth',{Pos(3)-18})
2743
2744%% TimeTable
2745set(handles.TimeTable,'Unit','pixel')
2746Pos=get(handles.TimeTable,'Position');
2747set(handles.TimeTable,'Unit','normalized')
2748% ColumnWidth=get(handles.TimeTable,'ColumnWidth');
2749ColumnWidth=num2cell(floor([0.25 0.25 0.25 0.25]*(Pos(3)-20)));
2750set(handles.TimeTable,'ColumnWidth',ColumnWidth)
2751
2752
2753%% PairString
2754set(handles.PairString,'Unit','pixel')
2755Pos=get(handles.PairString,'Position');
2756set(handles.PairString,'Unit','normalized')
2757set(handles.PairString,'ColumnWidth',{Pos(3)-5})
2758
2759%% MaskTable
2760set(handles.MaskTable,'Unit','pixel')
2761Pos=get(handles.MaskTable,'Position');
2762set(handles.MaskTable,'Unit','normalized')
2763set(handles.MaskTable,'ColumnWidth',{Pos(3)-5})
2764
2765%------------------------------------------------------------------------
2766% --- Executes on button press in status.
2767%------------------------------------------------------------------------
2768function status_Callback(hObject, eventdata, handles)
2769
2770if get(handles.status,'Value')
2771    set(handles.status,'BackgroundColor',[1 1 0])
2772    drawnow
2773    Param=read_GUI(handles.series);
2774    RootPath=Param.InputTable{1,1};
2775    if ~isfield(Param,'OutputSubDir')   
2776        msgbox_uvmat('ERROR','no directory defined for output files')
2777        return
2778    end
2779    OutputSubDir=[Param.OutputSubDir Param.OutputDirExt];% subdirectory for output files
2780    OutputDir=fullfile(RootPath,OutputSubDir);
2781    if exist(OutputDir,'dir')
2782        uigetfile_uvmat('status_display',OutputDir)
2783    else
2784        msgbox_uvmat('ERROR','output folder not created yet: calculation did not start')
2785        set(handles.status,'BackgroundColor',[0 1 0])
2786    end
2787else
2788    %% delete current display fig if selection is off
2789    set(handles.status,'BackgroundColor',[0 1 0])
2790    hfig=findobj(allchild(0),'name','status_display');
2791    if ~isempty(hfig)
2792        delete(hfig)
2793    end
2794    return
2795end
2796
2797
2798%------------------------------------------------------------------------   
2799% launched by selecting a file on the list
2800%------------------------------------------------------------------------
2801function view_file(hObject, eventdata)
2802
2803list=get(hObject,'String');
2804index=get(hObject,'Value');
2805rootroot=get(hObject,'UserData');
2806selectname=list{index};
2807ind_dot=regexp(selectname,'\.\.\.');
2808if ~isempty(ind_dot)
2809    selectname=selectname(1:ind_dot-1);
2810end
2811FullSelectName=fullfile(rootroot,selectname);
2812if exist(FullSelectName,'dir')% a directory has been selected
2813    ListFiles=dir(FullSelectName);
2814    ListDisplay=cell(numel(ListFiles),1);
2815    for ilist=2:numel(ListDisplay)% suppress the first line '.'
2816        ListDisplay{ilist-1}=ListFiles(ilist).name;
2817    end
2818    set(hObject,'Value',1)
2819    set(hObject,'String',ListDisplay)
2820    if strcmp(selectname,'..')
2821        FullSelectName=fileparts(fileparts(FullSelectName));
2822    end
2823    set(hObject,'UserData',FullSelectName)
2824    hfig=get(hObject,'parent');
2825    htitlebox=findobj(hfig,'tag','titlebox');   
2826    set(htitlebox,'String',FullSelectName)
2827elseif exist(FullSelectName,'file')%visualise the vel field if it exists
2828    FileType=get_file_type(FullSelectName);
2829    if strcmp(FileType,'txt')
2830        edit(FullSelectName)
2831    elseif strcmp(FileType,'xml')
2832        editxml(FullSelectName)
2833    else
2834        uvmat(FullSelectName)
2835    end
2836    set(gcbo,'Value',1)
2837end
2838
2839
2840%------------------------------------------------------------------------   
2841% launched by refreshing the status figure
2842%------------------------------------------------------------------------
2843function refresh_GUI(hfig)
2844
2845htitlebox=findobj(hfig,'tag','titlebox');
2846hlist=findobj(hfig,'tag','list');
2847hseries=findobj(allchild(0),'tag','series');
2848hstatus=findobj(hseries,'tag','status');
2849StatusData=get(hstatus,'UserData');
2850OutputDir=get(htitlebox,'String');
2851if ischar(OutputDir),OutputDir={OutputDir};end
2852ListFiles=dir(OutputDir{1});
2853if numel(ListFiles)<1
2854    return
2855end
2856ListFiles(1)=[];%removes the first line ='.'
2857ListDisplay=cell(numel(ListFiles),1);
2858testrecent=0;
2859datnum=zeros(numel(ListDisplay),1);
2860for ilist=1:numel(ListDisplay)
2861    ListDisplay{ilist}=ListFiles(ilist).name;
2862      if ~ListFiles(ilist).isdir && isfield(ListFiles(ilist),'datenum')
2863            datnum(ilist)=ListFiles(ilist).datenum;%only available in recent matlab versions
2864            testrecent=1;
2865       end
2866end
2867set(hlist,'String',ListDisplay)
2868
2869%% Look at date of creation
2870ListDisplay=ListDisplay(datnum~=0);
2871datnum=datnum(datnum~=0);%keep the non zero values corresponding to existing files
2872NbOutputFile=[];
2873if isempty(datnum)
2874    if testrecent
2875        message='no civ result created yet';
2876    else
2877        message='';
2878    end
2879else
2880    [first,indfirst]=min(datnum);
2881    [last,indlast]=max(datnum);
2882    NbOutputFile_str='?';
2883    NbOutputFile=[];
2884    if isfield(StatusData,'NbOutputFile')
2885        NbOutputFile=StatusData.NbOutputFile;
2886        NbOutputFile_str=num2str(NbOutputFile);
2887    end
2888    message={[num2str(numel(datnum)) ' file(s) done over ' NbOutputFile_str] ;['oldest modification:  ' ListDisplay{indfirst} ' : ' datestr(first)];...
2889        ['latest modification:  ' ListDisplay{indlast} ' : ' datestr(last)]};
2890end
2891set(htitlebox,'String', [OutputDir{1};message])
2892
2893%% update the waitbar
2894hwaitbar=findobj(hfig,'tag','waitbar');
2895if ~isempty(NbOutputFile)
2896    BarPosition=get(hwaitbar,'Position');
2897    BarPosition(3)=0.9*numel(datnum)/NbOutputFile;
2898    set(hwaitbar,'Position',BarPosition)
2899end
2900
2901%------------------------------------------------------------------------
2902% --- Executes on selection change in ActionExt.
2903%------------------------------------------------------------------------
2904function ActionExt_Callback(hObject, eventdata, handles)
2905
2906ActionExtList=get(handles.ActionExt,'String');
2907ActionExt=ActionExtList{get(handles.ActionExt,'Value')};
2908ActionList=get(handles.ActionName,'String');
2909ActionName=ActionList{get(handles.ActionName,'Value')};
2910TransformPath='';
2911if ~isempty(get(handles.ActionExt,'UserData'))
2912    TransformPath=get(handles.ActionExt,'UserData');
2913end
2914if strcmp(ActionExt,'.sh')
2915    set(handles.series,'Pointer','watch') % set the mouse pointer to 'watch'
2916    set(handles.ActionExt,'BackgroundColor',[1 1 0])
2917    ActionFullName=fullfile(get(handles.ActionPath,'String'),[ActionName '.sh']);
2918    if ~exist(ActionFullName,'file')
2919        answer=msgbox_uvmat('INPUT_Y-N','compiled version has not been created: compile now?');
2920        if strcmp(answer,'Yes')
2921            set(handles.ActionExt,'BackgroundColor',[1 1 0])
2922            path_uvmat=fileparts(which('series'));
2923            currentdir=pwd;
2924            cd(get(handles.ActionPath,'String'))% go to the directory of Action
2925            %  addpath(get(handles.TransformPath,'String'))
2926            addpath(path_uvmat)% add the path to uvmat to run the fct 'compile'
2927           % addpath(fullfile(path_uvmat,'transform_field'))% add the path to uvmat to run the fct 'compile'
2928            compile(ActionName,TransformPath)
2929            cd(currentdir)
2930        end       
2931    else
2932        sh_file_info=dir(fullfile(get(handles.ActionPath,'String'),[ActionName '.sh']));
2933        m_file_info=dir(fullfile(get(handles.ActionPath,'String'),[ActionName '.m']));
2934        if isfield(m_file_info,'datenum') && m_file_info.datenum>sh_file_info.datenum
2935            set(handles.ActionExt,'BackgroundColor',[1 1 0])
2936            drawnow
2937            answer=msgbox_uvmat('INPUT_Y-N',[ActionName '.sh needs to be updated: recompile now?']);
2938            if strcmp(answer,'Yes')
2939                path_uvmat=fileparts(which('series'));
2940                currentdir=pwd;
2941                cd(get(handles.ActionPath,'String'))% go to the directory of Action
2942                %  addpath(get(handles.TransformPath,'String'))
2943                addpath(path_uvmat)% add the path to uvmat to run the fct 'compile'
2944                addpath(fullfile(path_uvmat,'transform_field'))% add the path to uvmat to run the fct 'compile'
2945                compile(ActionName,TransformPath)
2946                cd(currentdir)
2947            end
2948        end
2949    end
2950    set(handles.ActionExt,'BackgroundColor',[1 1 1])
2951     set(handles.series,'Pointer','arrow') % set the mouse pointer to 'watch
2952end
2953
2954
2955
2956
2957function num_NbProcess_Callback(hObject, eventdata, handles)
2958
2959
2960function num_NbSlice_Callback(hObject, eventdata, handles)
2961NbSlice=str2num(get(handles.num_NbSlice,'String'));
2962set(handles.num_NbProcess,'String',num2str(NbSlice))
2963
2964%------------------------------------------------------------------------
2965% --- set the visibility of relevant velocity type menus:
2966function menu=set_veltype_display(Civ,FileType)
2967%------------------------------------------------------------------------
2968if ~exist('FileType','var')
2969    FileType='civx';
2970end
2971switch FileType
2972    case 'civx'
2973        menu={'civ1';'interp1';'filter1';'civ2';'interp2';'filter2'};
2974        if isequal(Civ,0)
2975            imax=0;
2976        elseif isequal(Civ,1) || isequal(Civ,2)
2977            imax=1;
2978        elseif isequal(Civ,3)
2979            imax=3;
2980        elseif isequal(Civ,4) || isequal(Civ,5)
2981            imax=4;
2982        elseif isequal(Civ,6) %patch2
2983            imax=6;
2984        end
2985    case 'civdata'
2986        menu={'civ1';'filter1';'civ2';'filter2'};
2987        if isequal(Civ,0)
2988            imax=0;
2989        elseif isequal(Civ,1) || isequal(Civ,2)
2990            imax=1;
2991        elseif isequal(Civ,3)
2992            imax=2;
2993        elseif isequal(Civ,4) || isequal(Civ,5)
2994            imax=3;
2995        elseif isequal(Civ,6) %patch2
2996            imax=4;
2997        end
2998end
2999menu=menu(1:imax);
3000
3001
3002% --- Executes on mouse motion over figure - except title and menu.
3003function series_WindowButtonMotionFcn(hObject, eventdata, handles)
3004set(hObject,'Pointer','arrow');
Note: See TracBrowser for help on using the repository browser.