source: trunk/src/series.m @ 708

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

option get_field... in series fixed

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