source: trunk/src/series.m @ 915

Last change on this file since 915 was 915, checked in by g7moreau, 9 years ago
  • Delay a few second each subjob
File size: 158.5 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 2008-2015, LEGI / CNRS UJF G-INP, Joel.Sommeria@legi.grenoble-inp.fr
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(hObject,'DeleteFcn',{@closefcn})%
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);
134set(handles.Action,'UserData',NbBuiltinAction)
135[path_series,name,ext]=fileparts(which('series'));% path to the GUI series
136path_series_fct=fullfile(path_series,'series');%path of the functions in subdirectroy 'series'
137[code, message] = system...
138    ('LD_LIBRARY_PATH=$(echo $LD_LIBRARY_PATH | pyp "p.split('':'') |... [s for s in p if ''matlab'' not in s] | '':''.join(p)") python -c "import fluiddyn"');
139if code==0
140    ActionExtList={'.m';'.sh';'.py (in dev.)'};% default choice of extensions (Matlab fct .m or compiled version .sh
141else
142    ActionExtList={'.m';'.sh'};  % python options not installed
143end
144ActionPathList=cell(NbBuiltinAction,1);%initiate the cell matrix of Action fct paths
145ActionPathList(:)={path_series_fct}; %set the default path to series fcts to all list members
146RunModeList={'local';'background'};% default choice of extensions (Matlab fct .m or compiled version .sh)
147[s,w]=system('oarstat');% look for cluster system 'oar'
148if isequal(s,0)
149    RunModeList=[RunModeList;{'cluster_oar'}];
150    set(handles.MonitorCluster,'Visible','on'); % make visible button for access to Monika
151    set(handles.num_CPUTime,'Visible','on'); % make visible button for access to Monika
152    set(handles.CPUTime_txt,'Visible','on'); % make visible button for access to Monika
153end
154[s,w]=system('qstat --version');% look for cluster system 'sge'
155if isequal(s,0)
156    if regexp(w,'^pbs')
157        RunModeList=[RunModeList;{'cluster_pbs'}];
158    else
159        RunModeList=[RunModeList;{'cluster_sge'}];
160    end
161end
162set(handles.RunMode,'String',RunModeList)
163
164%% list of builtin transform functions in the menu TransformName
165TransformList={'';'sub_field';'phys';'phys_polar'};% WARNING: must fit with the corresponding menu in uvmat and nb_builtin_transform=4 in  TransformName_callback
166NbBuiltinTransform=numel(TransformList);
167path_transform_fct=fullfile(path_series,'transform_field');
168TransformPathList=cell(NbBuiltinTransform,1);%initiate the cell matrix of Action fct paths
169TransformPathList(:)={path_transform_fct}; %set the default path to series fcts to all list members
170
171%% get the user defined functions stored in the personal file uvmat_perso.mat
172dir_perso=prefdir;
173profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
174if exist(profil_perso,'file')
175    h=load (profil_perso);
176    %get the list of previous input files in the upper bar menu Open
177    if isfield(h,'MenuFile')
178        for ifile=1:min(length(h.MenuFile),5)
179            set(handles.(['MenuFile_' num2str(ifile)]),'Label',h.MenuFile{ifile});
180            set(handles.(['MenuFile_' num2str(ifile+5)]),'Label',h.MenuFile{ifile});
181        end
182    end
183    %get the list of previous campaigns in the upper bar menu Open campaign
184    if isfield(h,'MenuCampaign')
185        for ifile=1:min(length(h.MenuCampaign),5)
186            set(handles.(['MenuCampaign_' num2str(ifile)]),'Label',h.MenuCampaign{ifile});
187        end
188    end
189    %get the menu of actions
190%     if isfield(h,'ActionExtListUser') && iscell(h.ActionExtListUser)
191%         ActionExtList=[ActionExtList; h.ActionExtListUser];
192%     end
193    if isfield(h,'ActionListUser') && iscell(h.ActionListUser) && isfield(h,'ActionPathListUser') && iscell(h.ActionPathListUser)
194        ActionList=[ActionList;h.ActionListUser];
195        ActionPathList=[ActionPathList;h.ActionPathListUser(:,1)];
196    end
197    %get the menu of transform fct
198    if isfield(h,'TransformListUser') && iscell(h.TransformListUser) && isfield(h,'TransformPathListUser') && iscell(h.TransformPathListUser)
199        TransformList=[TransformList;h.TransformListUser];
200        TransformPathList=[TransformPathList;h.TransformPathListUser];
201    end
202end
203
204%% selection of the input Action fct
205ActionCheckExist=true(size(ActionList));%initiate the check of the path to the listed action fct
206for ilist=NbBuiltinAction+1:numel(ActionList)%check  the validity of the path of the user defined Action fct
207    ActionCheckExist(ilist)=exist(fullfile(ActionPathList{ilist},[ActionList{ilist} '.m']),'file');
208end
209ActionPathList=ActionPathList(ActionCheckExist,:);% suppress the menu options which are not valid anymore
210ActionList=ActionList(ActionCheckExist);
211set(handles.ActionName,'String',[ActionList;{'more...'}])
212set(handles.ActionName,'UserData',ActionPathList)
213ActionIndex=[];
214if isfield(Param,'ActionName')% copy the selected menu index transferred in Param from uvmat
215    ActionIndex=find(strcmp(Param.ActionName,ActionList),1);
216end
217if isempty(ActionIndex)
218    ActionIndex=1;
219end
220set(handles.ActionName,'Value',ActionIndex)
221set(handles.ActionPath,'String',ActionPathList{ActionIndex})
222set(handles.ActionExt,'Value',1)
223set(handles.ActionExt,'String',ActionExtList)
224
225%% selection of the input transform fct
226TransformCheckExist=true(size(TransformList));
227for ilist=NbBuiltinTransform+1:numel(TransformList)
228    TransformCheckExist(ilist)=exist(fullfile(TransformPathList{ilist},[TransformList{ilist} '.m']),'file');
229end
230TransformPathList=TransformPathList(TransformCheckExist);
231TransformList=TransformList(TransformCheckExist);
232set(handles.TransformName,'String',[TransformList;{'more...'}])
233set(handles.TransformName,'UserData',TransformPathList)
234TransformIndex=[];
235if isfield(Param,'TransformName')% copy the selected menu index transferred in Param from uvmat
236    TransformIndex=find(strcmp(Param.TransformName,TransformList),1);
237end
238if isempty(TransformIndex)
239    TransformIndex=1;
240end
241set(handles.TransformName,'Value',TransformIndex)
242set(handles.TransformPath,'String',TransformPathList{TransformIndex})
243   
244%% fields input initialisation
245if isfield(Param,'list_fields')&& isfield(Param,'index_fields') &&~isempty(Param.list_fields) &&~isempty(Param.index_fields)
246    set(handles.FieldName,'String',Param.list_fields);% list menu fields
247    set(handles.FieldName,'Value',Param.index_fields);% selected string index
248end
249if isfield(Param,'Coordinates')
250    if isfield(Param.Coordinates,'Coord_x')
251        set(handles.Coord_x,'String',Param.Coordinates.Coord_x)
252    end
253    if isfield(Param.Coordinates,'Coord_y')
254        set(handles.Coord_y,'String',Param.Coordinates.Coord_y)
255    end
256    if isfield(Param.Coordinates,'Coord_z')
257        set(handles.Coord_z,'String',Param.Coordinates.Coord_z)
258    end
259end
260% if isfield(Param,'Coord_x_str') && ischar(Param.Coord_x_str)
261%         set(handles.Coord_x,'String',Param.Coord_x_str);% list menu fields
262% end
263% if isfield(Param,'Coord_y_str')&& ischar(Param.Coord_y_str)
264%         set(handles.Coord_y,'String',Param.Coord_y_str);% list menu fields
265% end
266
267%% introduce the input file name(s) if defined from input Param,
268set(handles.series,'UserData',[])% initiate Userdata
269if isfield(Param,'InputFile')
270   
271    %% fill the list of file series
272    InputTable=[{Param.InputFile.RootPath},{Param.InputFile.SubDir},{Param.InputFile.RootFile},{Param.InputFile.NomType},{Param.InputFile.FileExt}];
273    if isempty(find(cellfun('isempty',InputTable)==0));% if there is no input file, do not introduce input info
274        set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH button to magenta color to indicate that input refresh is needed
275        return
276    end
277    TimeTable=[{Param.InputFile.TimeName},{[]},{[]},{[]},{[]}];
278    if isfield(Param.InputFile,'RootPath_1')
279        InputTable=[InputTable;[{Param.InputFile.RootPath_1},{Param.InputFile.SubDir_1},{Param.InputFile.RootFile_1},{Param.InputFile.NomType_1},{Param.InputFile.FileExt_1}]];
280        TimeTable=[TimeTable; [{Param.InputFile.TimeName_1},{[]},{[]},{[]},{[]}]];
281    end
282    set(handles.InputTable,'Data',InputTable)
283    %% determine the selected reference field indices for pair display
284   
285    [tild,tild,tild,i1,i2,j1,j2]=fileparts_uvmat(Param.InputFile.FileIndex);
286    if isempty(i1)
287        i1=1;
288    end
289    if isempty(i2)
290        i2=i1;
291    end
292    ref_i=floor((i1+i2)/2);% reference image number corresponding to the file
293    % set(handles.num_ref_i,'String',num2str(ref_i));
294    if isempty(j1)
295        j1=1;
296    end
297    if isempty(j2)
298        j2=j1;
299    end
300    ref_j=floor((j1+j2)/2);% reference image number corresponding to the file
301    SeriesData.ref_i=ref_i;
302    SeriesData.ref_j=ref_j;
303    set(handles.series,'UserData',SeriesData)
304    update_rootinfo(handles,Param.HiddenData.i1_series{1},Param.HiddenData.i2_series{1},Param.HiddenData.j1_series{1},Param.HiddenData.j2_series{1},...
305        Param.HiddenData.FileInfo{1},Param.HiddenData.MovieObject{1},1)
306    if isfield(Param,'FileName_1')
307        %         display_file_name(handles,Param,2)
308        update_rootinfo(handles,Param.HiddenData.i1_series{2},Param.HiddenData.i2_series{2},Param.HiddenData.j1_series{2},Param.HiddenData.j2_series{2},...
309            Param.HiddenData.FileInfo{2},Param.HiddenData.MovieObject{2},2)
310    end
311    %% enable field and veltype menus, in accordance with the current action
312    ActionName_Callback([],[], handles)
313   
314    %% set length of waitbar
315    displ_time(handles)
316   
317else
318    set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH button to magenta color to indicate that input refresh is needed
319end
320if isfield(Param,'incr_i')
321    set(handles.num_incr_i,'String',num2str(Param.incr_i))
322else
323    set(handles.num_incr_i,'String','1')
324end
325if isfield(Param,'incr_j')
326    set(handles.num_incr_j,'String',num2str(Param.incr_j))
327else
328    set(handles.num_incr_j,'String','1')
329end
330
331%------------------------------------------------------------------------
332% --- Outputs from this function are returned to the command line.
333function varargout = series_OutputFcn(hObject, eventdata, handles)
334%------------------------------------------------------------------------
335varargout{1} = handles.output;
336
337%------------------------------------------------------------------------
338% --- executed when closing uvmat: delete or desactivate the associated figures if exist
339function closefcn(gcbo,eventdata)
340%------------------------------------------------------------------------
341
342% delete set_object_series if detected
343hh=findobj(allchild(0),'name','view_object_series');
344if ~isempty(hh)
345    delete(hh)
346end
347hh=findobj(allchild(0),'name','edit_object_series');
348if ~isempty(hh)
349    delete(hh)
350end
351
352%delete the bowser if detected
353hh=findobj(allchild(0),'tag','browser');
354if ~isempty(hh)
355    delete(hh)
356end
357
358
359%------------------------------------------------------------------------
360%------------------------------------------------------------------------
361%  II - FUNCTIONS FOR INTRODUCING THE INPUT FILES
362% automatically sets the global properties when the rootfile name is introduced
363% then activate the view-field actionname if selected
364% it is activated either by clicking on the RootPath window or by the
365% browser
366%------------------------------------------------------------------------
367%------------------------------------------------------------------------
368% --- fct activated by the browser under 'Open'
369%------------------------------------------------------------------------ 
370function MenuBrowse_Callback(hObject, eventdata, handles)
371%% look for the previously opened file 'oldfile'
372InputTable=get(handles.InputTable,'Data');
373oldfile=InputTable{1,1};
374if isempty(oldfile)
375    % use a file name stored in prefdir
376    dir_perso=prefdir;
377    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
378    if exist(profil_perso,'file')
379        h=load (profil_perso);
380        if isfield(h,'RootPath') && ischar(h.RootPath)
381            oldfile=h.RootPath;
382        end
383    end
384end
385%% launch the browser
386fileinput=uigetfile_uvmat('pick an input file in the series',oldfile);
387hh=dir(fileinput);
388if numel(hh)>1
389    msgbox_uvmat('ERROR','invalid input, probably a broken link');
390else
391    if ~isempty(fileinput)
392        display_file_name(handles,fileinput,'one')
393    end
394end
395
396% --------------------------------------------------------------------
397function MenuBrowseAppend_Callback(hObject, eventdata, handles)
398
399%% look for the previously opened file 'oldfile'
400InputTable=get(handles.InputTable,'Data');
401RootPathCell=InputTable(:,1);
402if isempty(RootPathCell{1})% no input file in the table
403     MenuBrowse_Callback(hObject, eventdata, handles)%refresh the input table, not append
404     return
405end
406SubDirCell=InputTable(:,2);
407oldfile=fullfile(RootPathCell{1},SubDirCell{1});
408
409%% use a file name stored in prefdir
410dir_perso=prefdir;
411profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
412if exist(profil_perso,'file')
413    h=load (profil_perso);
414    if isfield(h,'RootPath') && ischar(h.RootPath)
415        oldfile=h.RootPath;
416    end
417end
418
419%% launch the browser
420fileinput=uigetfile_uvmat('pick a file to append in the input table',oldfile);
421hh=dir(fileinput);
422if numel(hh)>1
423    msgbox_uvmat('ERROR','invalid input, probably a broken link');
424else
425    if ~isempty(fileinput)
426        display_file_name(handles,fileinput,'append')
427    end
428end
429
430%------------------------------------------------------------------------
431% --- fct activated by selecting a previous file under the menu Open
432%------------------------------------------------------------------------
433function MenuFile_Callback(hObject, eventdata, handles)
434
435errormsg=display_file_name(handles,get(hObject,'Label'),'one');
436if ~isempty(errormsg)
437    set(hObject,'Label','')
438    MenuFile=[{get(handles.MenuFile_1,'Label')};{get(handles.MenuFile_2,'Label')};...
439        {get(handles.MenuFile_3,'Label')};{get(handles.MenuFile_4,'Label')};{get(handles.MenuFile_5,'Label')}];
440    str_find=strcmp(get(hObject,'Label'),MenuFile);
441    MenuFile(str_find)=[];% suppress the input file to the list
442    for ifile=1:numel(MenuFile)
443        set(handles.(['MenuFile_' num2str(ifile)]),'Label',MenuFile{ifile});
444    end
445end
446
447%------------------------------------------------------------------------
448% --- fct activated by selecting a previous file under the menu Open/append
449%------------------------------------------------------------------------
450function MenuFile_append_Callback(hObject, eventdata, handles)
451
452InputTable=get(handles.InputTable,'Data');
453if isempty(InputTable{1,1})% no input file in the table
454    display_file_name(handles,get(hObject,'Label'),'one') %refresh the input table, not append
455else
456    display_file_name(handles,get(hObject,'Label'),'append')% append the selected file to the current list of InputTable
457end
458
459%------------------------------------------------------------------------
460% --- fct activated by the browser under 'Open campaign/Browse...'
461%------------------------------------------------------------------------
462function MenuBrowseCampaign_Callback(hObject, eventdata, handles)
463
464%% look for the previously opened file 'oldfile'
465InputTable=get(handles.InputTable,'Data');
466RootPathCell=InputTable(:,1);
467SubDirCell=InputTable(:,2);
468oldfile=fullfile(RootPathCell{1},SubDirCell{1});
469if isempty(oldfile)
470    % use a file name stored in prefdir
471    dir_perso=prefdir;
472    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
473    if exist(profil_perso,'file')
474        h=load (profil_perso);
475        if isfield(h,'RootPath') && ischar(h.RootPath)
476            oldfile=h.RootPath;
477        end
478    end
479end
480%% launch the browser
481fileinput=uigetfile_uvmat('pick an input file in the series',oldfile);
482hh=dir(fileinput);
483if numel(hh)>1
484    msgbox_uvmat('ERROR','invalid input, probably a broken link');
485else
486    if ~isempty(fileinput)
487        display_file_name(handles,fileinput,'one')
488    end
489end
490append='one';
491set(handles.MenuOpenCampaign,'ForegroundColor',[1 1 0])
492drawnow
493browse_campaign(handles,append);
494
495%------------------------------------------------------------------------
496% --- fct activated by the browser under 'Open campaign/Browse...'
497%------------------------------------------------------------------------
498function MenuBrowseCampaignAppend_Callback(hObject, eventdata, handles)
499append='append';
500browse_campaign(handles,append);
501
502%------------------------------------------------------------------------
503function browse_campaign(handles,append);
504
505%% look for the previously opened file 'oldfile'
506
507%
508%
509% InputTable=get(handles.InputTable,'Data');
510% RootPath=InputTable{1,1};
511% CampaignPath=fileparts(fileparts(RootPath));
512% DirFull=uigetfile_uvmat('define this path as the Campaign folder:',CampaignPath,'uigetdir');
513% if ~ischar(DirFull)|| ~exist(DirFull,'dir')
514%     return
515% end
516OutPut=browse_data(oldfile);% open the GUI browse_data to get select a campaign dir, experiment and device
517if ~isfield(OutPut,'Campaign')
518    return
519end
520DirName=fullfile(OutPut.Campaign,OutPut.Experiment{1},OutPut.DataSeries{1});
521ListStruct=dir(DirName); %list files and the dir DataSeries
522% select the first appropriate file in the dir
523FileName='';
524for ilist=1:numel(ListStruct)
525    if ~isequal(ListStruct(ilist).isdir,1)%look for files, not dir
526        FileName=ListStruct(ilist).name;
527        FileInfo=get_file_info(fullfile(DirName,FileName));
528        switch FileInfo.FileType
529            case {'image','multimage','civx','civdata','netcdf'}
530                break
531        end
532    end
533end
534if isempty(FileName)
535    msgbox_uvmat('ERROR',['no appropriate input file in the DataSeries folder ' fullfile(DirName)])
536    return
537end
538
539%% update the list of campaigns in the menubar
540MenuCampaign=[{get(handles.MenuCampaign_1,'Label')};{get(handles.MenuCampaign_2,'Label')};...
541    {get(handles.MenuCampaign_3,'Label')};{get(handles.MenuCampaign_4,'Label')};{get(handles.MenuCampaign_5,'Label')}];
542check_dir=isempty(find(strcmp(DirName,MenuCampaign)));
543if check_dir %insert the new campaign in the list if it is not found
544    MenuCampaign(end)=[]; %suppress the last item
545    MenuCampaign=[{DirName};MenuCampaign];%insert the new campaign
546    for ilist=1:numel(MenuCampaign)
547        set(handles.(['MenuCampaign_' num2str(ilist)]),'Label',MenuCampaign{ilist})
548    end
549    % save the list for future opening:
550    dir_perso=prefdir;
551    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
552    if exist(profil_perso,'file')
553        save (profil_perso,'MenuCampaign','-append'); %store the file names for future opening of uvmat
554    else
555        save (profil_perso,'MenuCampaign','-V6'); %store the file names for future opening of uvmat
556    end
557end
558
559%% display the selected field and related information
560if get(handles.CheckAppend,'Value')
561    display_file_name(handles,fullfile(DirName,FileName),'append')
562else
563    display_file_name(handles,fullfile(DirName,FileName),'one')
564end
565set(handles.MenuOpenCampaign,'ForegroundColor',[0 0 0])
566
567% --------------------------------------------------------------------
568function MenuCampaign_Callback(hObject, eventdata, handles)
569% --------------------------------------------------------------------
570set(handles.MenuOpenCampaign,'ForegroundColor',[1 1 0])
571OutPut=browse_data(get(hObject,'Label'));% open the GUI browse_data to get select a campaign dir, experiment and device
572if ~isfield(OutPut,'Campaign')
573    return
574end
575DirName=fullfile(OutPut.Campaign,OutPut.Experiment{1},OutPut.DataSeries{1});
576hdir=dir(DirName); %list files and dirs
577for ilist=1:numel(hdir)
578    if ~isequal(hdir(ilist).isdir,1)%look for files, not dir
579        FileName=hdir(ilist).name;
580        FileInfo=get_file_info(fullfile(DirName,FileName));
581        switch FileInfo.FileType
582            case {'image','multimage','civx','civdata','netcdf'}
583            break
584        end
585    end
586end
587if get(handles.CheckAppend,'Value')
588    display_file_name(handles,fullfile(DirName,FileName),'append')
589else
590    display_file_name(handles,fullfile(DirName,FileName),'one')
591end
592set(handles.MenuOpenCampaign,'ForegroundColor',[0 0 0])
593
594
595% --- Executes when selected cell(s) is changed in InputTable.
596function InputTable_CellSelectionCallback(hObject, eventdata, handles)
597iline=[];
598if ~isempty(eventdata.Indices)
599    iline=eventdata.Indices(1);
600end
601set(handles.InputLine,'String',num2str(iline));
602% set(handles.InputTable,'UserData',iline);
603
604%------------------------------------------------------------------------
605% --- 'key_press_fcn:' function activated when a key is pressed on the keyboard
606%------------------------------------------------------------------------
607function InputTable_KeyPressFcn(hObject, eventdata, handles)
608set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH button to magenta color to indicate that input refresh is needed
609set(handles.OutputSubDir,'BackgroundColor',[1 0 1])% set edit box OutputSubDir to magenta color to indicate that refresh may be needed
610xx=double(get(handles.series,'CurrentCharacter')); %get the keyboard character
611if ~isempty(xx)
612    switch xx
613        case 31 %downward arrow
614            InputTable=get(handles.InputTable,'Data');
615            iline=str2double(get(handles.InputLine,'String'));
616            if isequal(iline,size(InputTable,1))% arrow downward
617                InputTable=[InputTable;InputTable(iline,:)];% create a new line as a copy of the last one
618                set(handles.InputTable,'Data',InputTable);
619            end
620        case 127  %key 'Suppress'
621            ClearLine_Callback(hObject, eventdata, handles)
622    end
623end
624
625%------------------------------------------------------------------------
626% --- Executes on button press in REFRESH.
627function REFRESH_Callback(hObject, eventdata, handles)
628%------------------------------------------------------------------------
629InputTable=get(handles.InputTable,'Data');
630set(handles.series,'Pointer','watch') % set the mouse pointer to 'watch'
631set(handles.REFRESH,'BackgroundColor',[1 1 0])% set REFRESH  button to yellow color (indicate activation)
632drawnow
633empty_line=false(size(InputTable,1),1);
634for iline=1:size(InputTable,1)
635    empty_line(iline)= isempty(cell2mat(InputTable(iline,1:3)));
636end
637if ~isempty(find(empty_line));
638    InputTable(empty_line,:)=[];%remove empty lines
639    set(handles.InputTable,'Data',InputTable)
640    ListTable={'MinIndex_i','MaxIndex_i','MinIndex_j','MaxIndex_j','PairString','TimeTable'};
641    for ilist=1:numel(ListTable)
642        Table=get(handles.(ListTable{ilist}),'Data');
643        Table(empty_line,:)=[];%remove empty lines
644        set(handles.(ListTable{ilist}),'Data',Table);
645    end
646    set(handles.series,'UserData',[])%refresh the stored info
647end
648nbview=size(InputTable,1);
649for iview=1:nbview
650    RootPath=fullfile(InputTable{iview,1},InputTable{iview,2});
651    if ~exist(RootPath,'dir')
652        i1_series=[];
653        RootFile='';
654    else %scan the input folder
655        [RootPath,~,RootFile,i1_series,i2_series,j1_series,j2_series,tild,FileInfo,MovieObject]=...
656            find_file_series(fullfile(InputTable{iview,1},InputTable{iview,2}),[InputTable{iview,3} InputTable{iview,4} InputTable{iview,5}]);
657    end
658    % if no file is found, open a browser
659    if isempty(RootFile)&& isempty(i1_series)
660        fileinput=uigetfile_uvmat(['wrong input at line ' num2str(iview) ':pick a new input file'],RootPath);
661        if isempty(fileinput)
662            set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  back to red color
663            return
664        else
665            display_file_name(handles,fileinput,iview)
666        end
667    else
668       update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileInfo,MovieObject,iview)
669    end
670end
671
672%% update MinIndex_i and MaxIndex_i if the input table content has been reduced in line nbre
673MinIndex_i_table=get(handles.MinIndex_i,'Data');%retrieve the min indices in the table MinIndex
674set(handles.MinIndex_i,'Data',MinIndex_i_table(1:nbview,:));
675MinIndex_j_table=get(handles.MinIndex_j,'Data');%retrieve the min indices in the table MinIndex
676set(handles.MinIndex_j,'Data',MinIndex_j_table(1:nbview,:));
677MaxIndex_i_table=get(handles.MaxIndex_i,'Data');%retrieve the min indices in the table MinIndex
678set(handles.MaxIndex_i,'Data',MaxIndex_i_table(1:nbview,:));
679MaxIndex_j_table=get(handles.MaxIndex_j,'Data');%retrieve the min indices in the table MinIndex
680set(handles.MaxIndex_j,'Data',MaxIndex_j_table(1:nbview,:));
681PairString=get(handles.PairString,'Data');%retrieve the min indices in the table MinIndex
682set(handles.PairString,'Data',PairString(1:nbview,:));
683TimeTable=get(handles.TimeTable,'Data');%retrieve the min indices in the table MinIndex
684set(handles.TimeTable,'Data',TimeTable(1:nbview,:));
685
686%% enable field and veltype menus, in accordance with the current action
687ActionName_Callback([],[], handles)
688
689%% set length of waitbar
690displ_time(handles)
691
692set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (indicate activation finished)
693set(handles.series,'Pointer','arrow') % set the mouse pointer to 'watch'
694
695%------------------------------------------------------------------------
696% --- Function called when a new file is opened, either by series_OpeningFcn or by the browser
697%------------------------------------------------------------------------
698% INPUT:
699% handles: handles of elements in the GUI
700% Param: structure of input parameters, including  input file name and path
701% iview: line index in the input table
702%       or 'one': refresh the list
703%         'append': add a new line to the input table
704function errormsg=display_file_name(handles,Param,iview)
705 
706set(handles.REFRESH,'BackgroundColor',[1 1 0])% set REFRESH  button to yellow color (indicate activation)
707drawnow
708errormsg='';%default
709if ischar(Param)
710    fileinput=Param;
711else% input set when series is opened (called by the GUI uvmat)
712    fileinput=Param.FileName;
713end
714   
715%% get the input root name, indices, file extension and nomenclature NomType
716if ~exist(fileinput,'file')
717    errormsg=['input file ' fileinput  ' does not exist'];
718    msgbox_uvmat('ERROR',errormsg)
719    set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH  button to magenta color (refresh still needed)
720    return
721end
722
723%% detect root name, nomenclature and indices in the input file name:
724[FilePath,FileName,FileExt]=fileparts(fileinput);
725%%%%%%%%%%%%%%%%%%
726%TODO: case of input by uvmat: do not check agai the input seies %%%%%%%
727%%%%%%%%%%%%%%%%%%%
728% detect the file type, get the movie object if relevant, and look for the corresponding file series:
729% the root name and indices may be corrected by including the first index i1 if a corresponding xml file exists
730[RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,NomType,FileInfo,MovieObject,i1,i2,j1,j2]=find_file_series(FilePath,[FileName FileExt]);
731FileType=FileInfo.FileType;
732if isempty(RootFile)&&isempty(i1_series)
733    errormsg='no input file in the series';
734    msgbox_uvmat('ERROR',errormsg)
735    set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH  button to magenta color (end of activation)
736    return
737end
738if strcmp(FileType,'txt')
739    edit(fileinput)
740    set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH  button to  magenta color (end of activation)
741    return
742elseif strcmp(FileType,'xml')
743    editxml(fileinput)
744    set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH  button to magenta  color (end of activation)
745     return
746elseif strcmp(FileType,'figure')
747    open(fileinput)
748    set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH  button to magenta  color (end of activation)
749     return
750end
751
752%% enable other menus and uicontrols
753set(handles.MenuOpenCampaign,'Enable','on')
754set(handles.MenuCampaign_1,'Enable','on')
755set(handles.MenuCampaign_2,'Enable','on')
756set(handles.MenuCampaign_3,'Enable','on')
757set(handles.MenuCampaign_4,'Enable','on')
758set(handles.MenuCampaign_5,'Enable','on')
759set(handles.RUN, 'Enable','On')
760set(handles.RUN,'BackgroundColor',[1 0 0])% set RUN button to red
761set(handles.InputTable,'BackgroundColor',[1 1 0]) % set RootPath edit box  to yellow
762drawnow
763
764
765%% fill the list of file series
766InputTable=get(handles.InputTable,'Data');
767SeriesData=get(handles.series,'UserData');
768if strcmp(iview,'append') % display the input data as a new line in the table
769    iview=size(InputTable,1)+1;% the next line in InputTable becomes the current line
770%     InputTable(iview,:)=[{RootPath},{SubDir},{RootFile},{NomType},{FileExt}];
771elseif strcmp(iview,'one') % refresh the list of  input  file series
772    iview=1; %the first line in InputTable becomes the current line
773    InputTable={'','','','',''};
774%     InputTable(iview,:)=[{RootPath},{SubDir},{RootFile},{NomType},{FileExt}];
775    set(handles.TimeTable,'Data',[{''},{[]},{[]},{[]},{[]}])
776    set(handles.MinIndex_i,'Data',[])
777    set(handles.MaxIndex_i,'Data',[])
778    set(handles.MinIndex_j,'Data',[])
779    set(handles.MaxIndex_j,'Data',[])
780    set(handles.PairString,'Data',{''})
781    SeriesData.CheckPair=0;%reset the list of input lines with pairs
782    SeriesData.i1_series={};
783    SeriesData.i2_series={};
784    SeriesData.j1_series={};
785    SeriesData.j2_series={};
786    SeriesData.FileType={};
787    SeriesData.FileInfo={};
788    SeriesData.Time={};
789end
790if isfield(SeriesData,'i1_series')
791    SeriesData.i1_series(iview+1:end)=[];
792    SeriesData.i2_series(iview+1:end)=[];
793    SeriesData.j1_series(iview+1:end)=[];
794    SeriesData.j2_series(iview+1:end)=[];
795    SeriesData.FileType(iview+1:end)=[];
796    SeriesData.FileInfo(iview+1:end)=[];
797    SeriesData.Time(iview+1:end)=[];
798end
799InputTable(iview,:)=[{RootPath},{SubDir},{RootFile},{NomType},{FileExt}];
800if iview >1
801    set(handles.InputLine,'String',num2str(iview))
802end
803set(handles.InputTable,'Data',InputTable)
804
805%% determine the selected reference field indices for pair display
806if isempty(i1)
807    i1=1;
808end
809if isempty(i2)
810    i2=i1;
811end
812ref_i=floor((i1+i2)/2);% reference image number corresponding to the file
813% set(handles.num_ref_i,'String',num2str(ref_i));
814if isempty(j1)
815    j1=1;
816end
817if isempty(j2)
818    j2=j1;
819end
820ref_j=floor((j1+j2)/2);% reference image number corresponding to the file
821SeriesData.ref_i=ref_i;
822SeriesData.ref_j=ref_j;
823
824%% update first and last indices if they do not exist
825Param=read_GUI(handles.series);
826first_j=[];
827if isfield(Param.IndexRange,'first_j'); first_j=Param.IndexRange.first_j; end
828last_j=[];
829if isfield(Param.IndexRange,'last_j'); last_j=Param.IndexRange.last_j; end
830PairString='';
831if isfield(Param.IndexRange,'PairString'); PairString=Param.IndexRange.PairString; end
832[i1,i2,j1,j2] = get_file_index(Param.IndexRange.first_i,first_j,PairString);
833FirstFileName=fullfile_uvmat(Param.InputTable{1,1},Param.InputTable{1,2},Param.InputTable{1,3},...
834    Param.InputTable{1,5},Param.InputTable{1,4},i1,i2,j1,j2);
835if ~exist(FirstFileName,'file')
836    set(handles.num_first_i,'String',num2str(ref_i))
837    set(handles.num_first_j,'String',num2str(ref_j))
838end
839[i1,i2,j1,j2] = get_file_index(Param.IndexRange.last_i,last_j,PairString);
840LastFileName=fullfile_uvmat(Param.InputTable{1,1},Param.InputTable{1,2},Param.InputTable{1,3},...
841    Param.InputTable{1,5},Param.InputTable{1,4},i1,i2,j1,j2);
842if ~exist(LastFileName,'file')
843    set(handles.num_last_i,'String',num2str(ref_i))
844    set(handles.num_last_j,'String',num2str(ref_j))
845end
846
847%% update the list of recent files in the menubar and save it for future opening
848MenuFile=[{get(handles.MenuFile_1,'Label')};{get(handles.MenuFile_2,'Label')};...
849    {get(handles.MenuFile_3,'Label')};{get(handles.MenuFile_4,'Label')};{get(handles.MenuFile_5,'Label')}];
850str_find=strcmp(fileinput,MenuFile);
851if isempty(find(str_find,1))
852    MenuFile=[{fileinput};MenuFile];%insert the current file if not already in the list
853end
854for ifile=1:min(length(MenuFile),5)
855    eval(['set(handles.MenuFile_' num2str(ifile) ',''Label'',MenuFile{ifile});'])
856end
857dir_perso=prefdir;
858profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
859if exist(profil_perso,'file')
860    save (profil_perso,'MenuFile','-append'); %store the file names for future opening of uvmat
861else
862    save (profil_perso,'MenuFile','-V6'); %store the file names for future opening of uvmat
863end
864% save the opened file to initiate future opening
865SeriesData.RefFile{iview}=fileinput;% reference opening file for line iview
866SeriesData.Ref_i1=i1;
867SeriesData.Ref_i2=i2;
868SeriesData.Ref_j1=j1;
869SeriesData.Ref_j2=j2;
870set(handles.series,'UserData',SeriesData)
871
872set(handles.InputTable,'BackgroundColor',[1 1 1])
873
874%% initiate input file series and refresh the current field view:     
875update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileInfo,MovieObject,iview);
876%% enable field and veltype menus, in accordance with the current action
877ActionName_Callback([],[], handles)
878
879%% set length of waitbar
880displ_time(handles)
881
882set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (end of activation)
883
884%------------------------------------------------------------------------
885% --- Update information about a new field series (indices to scan, timing,
886%     calibration from an xml file
887function update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileInfo,VideoObject,iview)
888%------------------------------------------------------------------------
889InputTable=get(handles.InputTable,'Data');
890
891%% display the min and max indices for the whole file series
892if size(i1_series,2)==2 && min(min(i1_series(:,1,:)))==0
893    MinIndex_j=1;% index j set to 1 by default
894    MaxIndex_j=1;
895    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)
896    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)
897else
898    ref_i=squeeze(max(i1_series(1,:,:),[],2));% select ref_j index for each ref_i
899    ref_j=squeeze(max(j1_series(1,:,:),[],3));% select ref_i index for each ref_j
900     MinIndex_i=min(find(ref_i))-1;
901     MaxIndex_i=max(find(ref_i))-1;
902     MaxIndex_j=max(find(ref_j))-1;
903     MinIndex_j=min(find(ref_j))-1;
904    diff_j_max=diff(ref_j);
905    diff_i_max=diff(ref_i);
906    if ~isempty(diff_i_max) && isequal (diff_i_max,diff_i_max(1)*ones(size(diff_i_max)))
907        set(handles.num_incr_i,'String',num2str(diff_i_max(1)))% detect an increment to dispaly by default
908    end
909    if ~isempty(diff_j_max) && isequal (diff_j_max,diff_j_max(1)*ones(size(diff_j_max)))
910        set(handles.num_incr_j,'String',num2str(diff_j_max(1)))
911    end
912end
913if isequal(MinIndex_i,-1)
914    MinIndex_i=0;
915end
916if isequal(MinIndex_j,-1)
917    MinIndex_j=0;
918end
919MinIndex_i_table=get(handles.MinIndex_i,'Data');%retrieve the min indices in the table MinIndex
920MinIndex_j_table=get(handles.MinIndex_j,'Data');%retrieve the min indices in the table MinIndex
921MaxIndex_i_table=get(handles.MaxIndex_i,'Data');%retrieve the min indices in the table MinIndex
922MaxIndex_j_table=get(handles.MaxIndex_j,'Data');%retrieve the min indices in the table MinIndex
923if ~isempty(MinIndex_i)&&~isempty(MaxIndex_i)
924    MinIndex_i_table(iview,1)=MinIndex_i;
925    MaxIndex_i_table(iview,1)=MaxIndex_i;
926end
927if ~isempty(MinIndex_j)&&~isempty(MaxIndex_j)
928    MinIndex_j_table(iview,1)=MinIndex_j;
929    MaxIndex_j_table(iview,1)=MaxIndex_j;
930end
931set(handles.MinIndex_i,'Data',MinIndex_i_table)%display the min indices in the table MinIndex
932set(handles.MinIndex_j,'Data',MinIndex_j_table)%display the max indices in the table MaxIndex
933set(handles.MaxIndex_i,'Data',MaxIndex_i_table)%display the min indices in the table MinIndex
934set(handles.MaxIndex_j,'Data',MaxIndex_j_table)%display the max indices in the table MaxIndex
935SeriesData=get(handles.series,'UserData');
936
937%% adjust the first and last indices for the selected series, only if requested by the bounds
938% i index, compare input to min index i
939first_i=str2num(get(handles.num_first_i,'String'));%retrieve previous first i
940% ref_i=str2num(get(handles.num_ref_i,'String'));%index i given by the input field
941ref_i=1;
942if isfield(SeriesData,'ref_i')
943ref_i=SeriesData.ref_i;
944end
945if isempty(first_i)
946    first_i=ref_i;% first_i updated by the input value
947elseif first_i < MinIndex_i
948    first_i=MinIndex_i; % first_i set to the min i index (restricted by oter input lines)
949elseif first_i >MaxIndex_i
950    first_i=MaxIndex_i;% first_i set to the max i index (restricted by oter input lines)
951end
952% j index,  compare input to min index j
953first_j=str2num(get(handles.num_first_j,'String'));
954ref_j=1;
955if isfield(SeriesData,'ref_j')
956ref_j=SeriesData.ref_j;
957end
958if isempty(first_j)
959    first_j=ref_j;% first_j updated by the input value
960elseif first_j<MinIndex_j
961    first_j=MinIndex_j; % first_j set to the min j index (restricted by oter input lines)
962elseif first_j >MaxIndex_j
963    first_j=MaxIndex_j; % first_j set to the max j index (restricted by oter input lines)
964end
965% i index, compare input to max index i
966last_i=str2num(get(handles.num_last_i,'String'));
967if isempty(last_i)
968    last_i=ref_i;
969elseif last_i > MaxIndex_i
970    last_i=MaxIndex_i;
971elseif last_i<first_i
972    last_i=first_i;
973end
974% j index, compare input to max index j
975last_j=str2num(get(handles.num_last_j,'String'));
976if isempty(last_j)
977    last_j=ref_j;
978elseif last_j>MaxIndex_j
979    last_j=MaxIndex_j;
980elseif last_j<first_j
981    last_j=first_j;
982end
983set(handles.num_first_i,'String',num2str(first_i));
984set(handles.num_first_j,'String',num2str(first_j));
985set(handles.num_last_i,'String',num2str(last_i));
986set(handles.num_last_j,'String',num2str(last_j));
987
988%% number of slices set by default
989NbSlice=1;%default
990% read  value set by the first series for the append mode (iwiew >1)
991if iview>1 && strcmp(get(handles.num_NbSlice,'Visible'),'on')
992    NbSlice=str2num(get(handles.num_NbSlice,'String'));
993end
994
995%% default time settings
996TimeUnit='';
997% read  value set by the first series for the append mode (iwiew >1)
998if iview>1
999    TimeUnit=get(handles.TimeUnit,'String');
1000end
1001TimeName='';
1002Time=[];%default
1003TimeMin=[];
1004TimeFirst=[];
1005TimeLast=[];
1006TimeMax=[];
1007
1008%%  read image documentation file if found
1009XmlData=[];
1010check_calib=0;
1011XmlFileName=find_imadoc(InputTable{iview,1},InputTable{iview,2},InputTable{iview,3},InputTable{iview,5});
1012if ~isempty(XmlFileName)
1013    [XmlData,errormsg]=imadoc2struct(XmlFileName);
1014    if ~isempty(errormsg)
1015         msgbox_uvmat('WARNING',['error in reading ' XmlFileName ': ' errormsg]);
1016    end
1017    % read time if available
1018    if isfield(XmlData,'Time')
1019         Time=XmlData.Time;
1020        TimeName='xml';
1021    end
1022    if isfield(XmlData,'Camera')
1023        if isfield(XmlData.Camera,'NbSlice')&& ~isempty(XmlData.Camera.NbSlice)
1024            if iview>1 && ~isempty(NbSlice) && ~strcmp(NbSlice,XmlData.Camera.NbSlice)
1025                msgbox_uvmat('WARNING','inconsistent number of slices with the first field series');
1026            end
1027            NbSlice=XmlData.Camera.NbSlice;% Nbre of slices from camera
1028        end
1029        if isfield(XmlData.Camera,'TimeUnit')&& ~isempty(XmlData.Camera.TimeUnit)
1030            if iview>1 && ~isempty(TimeUnit) && ~strcmp(TimeUnit,XmlData.Camera.TimeUnit)
1031                msgbox_uvmat('WARNING','inconsistent time unit with the first field series');
1032            end
1033            TimeUnit=XmlData.Camera.TimeUnit;
1034        end
1035    end
1036    % number of slices
1037    if isfield(XmlData,'GeometryCalib')
1038        check_calib=1;
1039        if isfield(XmlData.GeometryCalib,'SliceCoord')
1040            siz=size(XmlData.GeometryCalib.SliceCoord);
1041            if siz(1)>1
1042                if iview>1 && ~isempty(NbSlice) && ~strcmp(NbSlice,siz(1))
1043                    msgbox_uvmat('WARNING','inconsistent number of Z indices with the first field series');
1044                end
1045                NbSlice=siz(1);
1046            end
1047        end
1048    end
1049    set(handles.num_NbSlice,'String',num2str(NbSlice))
1050end
1051
1052%% read timing  from the current file (prioritary)
1053if ~isempty(VideoObject)% case of movies
1054    imainfo=get(VideoObject);
1055    if isempty(j1_series); %frame index along i
1056        Time=zeros(imainfo.NumberOfFrames+1,2);
1057        Time(:,2)=(0:1/imainfo.FrameRate:(imainfo.NumberOfFrames)/imainfo.FrameRate)';
1058    else
1059        Time=[0;ones(size(i1_series,3)-1,1)]*(0:1/imainfo.FrameRate:(imainfo.NumberOfFrames)/imainfo.FrameRate);
1060    end
1061    TimeName='video';
1062end
1063
1064
1065%% determine the min and max times: case of Netcdf files will be treated later in FieldName_Callback
1066if ~isempty(TimeName)
1067    TimeMin=Time(MinIndex_i+1,MinIndex_j+1);
1068    if size(Time)>=[first_i+1 first_j+1]
1069        TimeFirst=Time(first_i+1,first_j+1);
1070    end
1071    if size(Time)>=[last_i+1 last_j+1]
1072        TimeLast=Time(last_i+1,last_j+1);
1073    end
1074    if size(Time)>=[MaxIndex_i+1 MaxIndex_j+1];
1075        TimeMax=Time(MaxIndex_i+1,MaxIndex_j+1);
1076    end
1077end
1078
1079%% update the time table
1080TimeTable=get(handles.TimeTable,'Data');
1081TimeTable{iview,1}=TimeName;
1082TimeTable{iview,2}=TimeMin;
1083TimeTable{iview,3}=TimeFirst;
1084TimeTable{iview,4}=TimeLast;
1085TimeTable{iview,5}=TimeMax;
1086set(handles.TimeTable,'Data',TimeTable)
1087
1088%% update the series info in 'UserData'
1089SeriesData.i1_series{iview}=i1_series;
1090SeriesData.i2_series{iview}=i2_series;
1091SeriesData.j1_series{iview}=j1_series;
1092SeriesData.j2_series{iview}=j2_series;
1093SeriesData.FileType{iview}=FileInfo.FileType;
1094SeriesData.FileInfo{iview}=FileInfo;
1095SeriesData.Time{iview}=Time;
1096% if ~isempty(TimeName)
1097%     SeriesData.TimeSource=TimeSource;
1098% end
1099if check_calib
1100    SeriesData.GeometryCalib{iview}=XmlData.GeometryCalib;
1101end
1102set(handles.series,'UserData',SeriesData)
1103
1104%% update pair menus
1105hset_pair=findobj(allchild(0),'Tag','set_pairs');
1106if ~isempty(hset_pair), delete(hset_pair); end % delete the GUI set_pair if opened
1107CheckPair= ~isempty(i2_series)||~isempty(j2_series); % check whether index pairs need to be defined
1108PairString=get(handles.PairString,'Data');
1109if CheckPair% if pairs need to be display for line iview
1110    [ModeMenu,ModeValue]=update_mode(i1_series,i2_series,j2_series);
1111    Menu=update_listpair(i1_series,i2_series,j1_series,j2_series,ModeMenu{ModeValue},Time,TimeUnit,ref_i,ref_j,TimeName,InputTable(iview,:),FileInfo);
1112    PairString{iview,1}=Menu{1};
1113else
1114    PairString{iview,1}='';%no pair for #iview
1115end
1116set(handles.PairString,'Data',PairString)
1117if isempty(find(cellfun('isempty',get(handles.PairString,'Data'))==0, 1))% if all lines of pairs are empty
1118    set(handles.PairString,'Visible','off')
1119    set(handles.SetPairs,'Visible','off')
1120else
1121    set(handles.PairString,'Visible','on')
1122    set(handles.SetPairs,'Visible','on')
1123end
1124
1125
1126%% display the set of existing files as an image
1127set(handles.FileStatus,'Units','pixels')
1128Position=get(handles.FileStatus,'Position');
1129set(handles.FileStatus,'Units','normalized')
1130%xI=0.5:Position(3)-0.5;
1131nbview=numel(SeriesData.i1_series);
1132j_max=cell(1,nbview);
1133MaxIndex_i=ones(1,nbview);%default
1134MinIndex_i=ones(1,nbview);%default
1135for iline=1:nbview
1136    pair_max=squeeze(max(SeriesData.i1_series{iline},[],1)); %max on pair index
1137    j_max{iline}=max(pair_max,[],1);%max on j index
1138    if ~isempty(j_max{iline})
1139    MaxIndex_i(iline)=max(find(j_max{iline}))-1;% max ref index i
1140    MinIndex_i(iline)=min(find(j_max{iline}))-1;% min ref index i
1141    end
1142end
1143MinIndex_i=min(MinIndex_i);
1144MaxIndex_i=max(MaxIndex_i);
1145range_index=MaxIndex_i-MinIndex_i+1;
1146range_y=max(1,floor(Position(4)/nbview));
1147npx=floor(Position(3));
1148file_indices=MinIndex_i+floor(((0.5:npx-0.5)/npx)*range_index)+1;
1149CData=zeros(nbview*range_y,npx);% initiate the image representing the existing files
1150for iline=1:nbview
1151    ind_y=1+(iline-1)*range_y:iline*range_y;
1152    LineData=zeros(size(file_indices));
1153    file_select=file_indices(file_indices<=numel(j_max{iline}));
1154    ind_select=find(file_indices<=numel(j_max{iline}));
1155    LineData(ind_select)=j_max{iline}(file_select)~=0;
1156    CData(ind_y,:)=ones(size(ind_y'))*LineData;
1157end
1158CData=cat(3,zeros(size(CData)),CData,zeros(size(CData)));%make color images r=0,g,b=0
1159set(handles.FileStatus,'CData',CData);
1160
1161%-----------------------------------------------------------guide -------------
1162%------------------------------------------------------------------------
1163%  III - FUNCTIONS ASSOCIATED TO THE FRAME IndexRange
1164%------------------------------------------------------------------------
1165
1166
1167% ---- determine the menu to put in mode and advice a default choice
1168%------------------------------------------------------------------------
1169function [ModeMenu,ModeValue]=update_mode(i1_series,i2_series,j2_series)
1170%------------------------------------------------------------------------   
1171ModeMenu={''};
1172if isempty(j2_series)% no j pair
1173    ModeValue=1;
1174    if ~isempty(i2_series)
1175        ModeMenu={'series(Di)'}; % pair menu with only option Di
1176    end
1177else %existence of j pairs
1178    pair_max=squeeze(max(i1_series,[],1)); %max on pair index
1179    j_max=max(pair_max,[],1);
1180    MaxIndex_i=find(j_max, 1, 'last' )-1;% max ref index i
1181    MinIndex_i=find(j_max, 1 )-1;% min ref index i
1182    i_max=max(pair_max,[],2);
1183    MaxIndex_j=find(i_max, 1, 'last' )-1;% max ref index i
1184    MinIndex_j=find(i_max, 1 )-1;% min ref index i
1185    if MaxIndex_j==MinIndex_j
1186        ModeValue=1;
1187        ModeMenu={'bursts'};
1188    elseif MaxIndex_i==MinIndex_i
1189        ModeValue=1;
1190        ModeMenu={'series(Dj)'};
1191    else
1192        ModeMenu={'bursts';'series(Dj)'};
1193        if (MaxIndex_j-MinIndex_j)>10
1194            ModeValue=2;%set mode to series(Dj) if more than 10 j values
1195        else
1196            ModeValue=1;
1197        end
1198    end
1199end
1200
1201
1202%------------------------------------------------------------------------
1203function displ_pair=update_listpair(i1_series,i2_series,j1_series,j2_series,mode,time,TimeUnit,ref_i,ref_j,TimeName,InputTable,FileInfo)
1204%------------------------------------------------------------------------
1205displ_pair={};
1206if isempty(TimeUnit)
1207    dtunit='e-03';
1208else
1209    dtunit=['m' TimeUnit];
1210end
1211switch mode
1212    case 'series(Di)'
1213        diff_i=i2_series-i1_series;
1214        min_diff=min(diff_i(diff_i>0));
1215        max_diff=max(diff_i(diff_i>0));
1216        for ipair=min_diff:max_diff
1217            if numel(diff_i(diff_i==ipair))>0
1218                pair_string=['Di= ' num2str(-floor(ipair/2)) '|' num2str(ceil(ipair/2)) ];
1219                if ~isempty(time)
1220                    if ref_i<=floor(ipair/2)
1221                        ref_i=floor(ipair/2)+1;% shift ref_i to get the first pair
1222                    end
1223                    Dt=time(ref_i+ceil(ipair/2),ref_j)-time(ref_i-floor(ipair/2),ref_j);
1224                    pair_string=[pair_string ', Dt=' num2str(Dt) ' ' dtunit];
1225                end
1226                displ_pair=[displ_pair;{pair_string}];
1227            end
1228        end
1229        if ~isempty(displ_pair)
1230            displ_pair=[displ_pair;{'Di=*|*'}];
1231        end
1232    case 'series(Dj)'
1233        if isempty(j2_series)
1234            msgbox_uvmat('ERROR','no j1-j2 pair available')
1235            return
1236        end
1237        diff_j=j2_series-j1_series;
1238        min_diff=min(diff_j(diff_j>0));
1239        max_diff=max(diff_j(diff_j>0));
1240        for ipair=min_diff:max_diff
1241            if numel(diff_j(diff_j==ipair))>0
1242                pair_string=['Dj= ' num2str(-floor(ipair/2)) '|' num2str(ceil(ipair/2)) ];
1243                if ~isempty(time)
1244                    if ref_j<=floor(ipair/2)
1245                        ref_j=floor(ipair/2)+1;% shift ref_i to get the first pair
1246                    end
1247                    Dt=time(ref_i,ref_j+ceil(ipair/2))-time(ref_i,ref_j-floor(ipair/2));
1248                    pair_string=[pair_string ', Dt=' num2str(Dt) ' ' dtunit];
1249                end
1250                displ_pair=[displ_pair;{pair_string}];
1251            end
1252        end
1253        if ~isempty(displ_pair)
1254            displ_pair=[displ_pair;{'Dj=*|*'}];
1255        end
1256    case 'bursts'
1257        if isempty(j2_series)
1258            msgbox_uvmat('ERROR','no j1-j2 pair available')
1259            return
1260        end
1261        %diff_j=j2_series-j1_series;
1262        min_j1=min(j1_series(j1_series>0));
1263        max_j1=max(j1_series(j1_series>0));
1264        min_j2=min(j2_series(j2_series>0));
1265        max_j2=max(j2_series(j2_series>0));
1266        for pair1=min_j1:min(max_j1,min_j1+20)
1267            for pair2=min_j2:min(max_j2,min_j2+20)
1268                if numel(j1_series(j1_series==pair1))>0 && numel(j2_series(j2_series==pair2))>0
1269                    pair_string=['j= ' num2str(pair1) '-' num2str(pair2)];
1270                    [TimeValue,DtValue]=get_time(ref_i,[],pair_string,InputTable,FileInfo,TimeName,'Dt');
1271                    %Dt=time(ref_i,pair2+1)-time(ref_i,pair1+1);
1272                    pair_string=[pair_string ', Dt=' num2str(DtValue) ' ' dtunit];
1273                    displ_pair=[displ_pair;{pair_string}];
1274                end
1275            end
1276        end
1277        if ~isempty(displ_pair)
1278            displ_pair=[displ_pair;{'j=*-*'}];
1279        end
1280end
1281
1282%------------------------------------------------------------------------
1283function num_first_i_Callback(hObject, eventdata, handles)
1284%------------------------------------------------------------------------
1285num_last_i_Callback(hObject, eventdata, handles)
1286
1287%------------------------------------------------------------------------
1288function num_last_i_Callback(hObject, eventdata, handles)
1289%------------------------------------------------------------------------
1290SeriesData=get(handles.series,'UserData');
1291if ~isfield(SeriesData,'Time')
1292    SeriesData.Time{1}=[];
1293end
1294displ_time(handles);
1295
1296%------------------------------------------------------------------------
1297function num_first_j_Callback(hObject, eventdata, handles)
1298%------------------------------------------------------------------------
1299 num_last_j_Callback(hObject, eventdata, handles)
1300
1301%------------------------------------------------------------------------
1302function num_last_j_Callback(hObject, eventdata, handles)
1303%------------------------------------------------------------------------
1304% first_j=str2num(get(handles.num_first_j,'String'));
1305% last_j=str2num(get(handles.num_last_j,'String'));
1306% ref_j=ceil((first_j+last_j)/2);
1307% set(handles.num_ref_j,'String', num2str(ref_j))
1308% num_ref_j_Callback(hObject, eventdata, handles)
1309SeriesData=get(handles.series,'UserData');
1310if ~isfield(SeriesData,'Time')
1311    SeriesData.Time{1}=[];
1312end
1313displ_time(handles);
1314
1315%------------------------------------------------------------------------
1316% ---- find the times corresponding to the first and last indices of a series
1317function displ_time(handles)
1318%------------------------------------------------------------------------
1319SeriesData=get(handles.series,'UserData');%
1320if ~isfield(SeriesData,'Time')
1321    return
1322end
1323PairString=get(handles.PairString,'Data');
1324ref_i_1=str2num(get(handles.num_first_i,'String'));%first reference index
1325ref_i_2=str2num(get(handles.num_last_i,'String'));%last reference index
1326ref_j_1=[];ref_j_2=[];
1327if strcmp(get(handles.num_first_j,'Visible'),'on')
1328ref_j_1=str2num(get(handles.num_first_j,'String'));
1329ref_j_2=str2num(get(handles.num_last_j,'String'));
1330end
1331[i1_1,i2_1,j1_1,j2_1] = get_file_index(ref_i_1,ref_j_1,PairString);
1332[i1_2,i2_2,j1_2,j2_2] = get_file_index(ref_i_2,ref_j_2,PairString);
1333TimeTable=get(handles.TimeTable,'Data');
1334%%%%%%
1335%TODO: read time in netcdf file, see ActionName_Callback
1336%%%%%%%
1337%Pairs=get(handles.PairString,'Data');
1338for iview=1:size(TimeTable,1)
1339    if size(SeriesData.Time,1)<iview
1340        break
1341    end
1342    TimeTable{iview,3}=[];
1343    TimeTable{iview,4}=[];
1344    if size(SeriesData.Time{iview},1)>=i2_2+1 && (isempty(ref_j_1)||size(SeriesData.Time{iview},2)>=j2_2+1)
1345        if isempty(ref_j_1)
1346            time_first=(SeriesData.Time{iview}(i1_1+1,2)+SeriesData.Time{iview}(i2_1+1,2))/2;
1347            time_last=(SeriesData.Time{iview}(i1_2+1,2)+SeriesData.Time{iview}(i2_2+1,2))/2;
1348        else
1349            time_first=(SeriesData.Time{iview}(i1_1+1,j1_1+1)+SeriesData.Time{iview}(i2_1+1,j2_1+1))/2;
1350            time_last=(SeriesData.Time{iview}(i1_2+1,j1_2+1)+SeriesData.Time{iview}(i2_2+1,j2_1+1))/2;
1351        end
1352        TimeTable{iview,3}=time_first; %TODO: take into account pairs
1353        TimeTable{iview,4}=time_last; %TODO: take into account pairs
1354    end
1355end
1356set(handles.TimeTable,'Data',TimeTable)
1357
1358%% set the waitbar position with respect to the min and max in the series
1359MinIndex_i=min(get(handles.MinIndex_i,'Data'));
1360MaxIndex_i=max(get(handles.MaxIndex_i,'Data'));
1361pos_first=(ref_i_1-MinIndex_i)/(MaxIndex_i-MinIndex_i+1);
1362pos_last=(ref_i_2-MinIndex_i+1)/(MaxIndex_i-MinIndex_i+1);
1363if isempty(pos_first), pos_first=0; end
1364if isempty(pos_last), pos_last=1; end
1365Position=get(handles.Waitbar,'Position');% position of the waitbar:= [ x,y, width, height]
1366Position_status=get(handles.FileStatus,'Position');
1367Position(1)=Position_status(1)+Position_status(3)*pos_first;
1368Position(3)=max(Position_status(3)*(pos_last-pos_first),0.001);% width must remain positive
1369set(handles.Waitbar,'Position',Position)
1370update_waitbar(handles.Waitbar,0)
1371
1372%------------------------------------------------------------------------
1373% --- Executes when selected cell(s) is changed in PairString.
1374function PairString_CellSelectionCallback(hObject, eventdata, handles)
1375%------------------------------------------------------------------------   
1376if numel(eventdata.Indices)>=1
1377    PairString=get(hObject,'Data');
1378    if ~isempty(PairString{eventdata.Indices(1)})
1379        SetPairs_Callback(hObject, eventdata.Indices(1), handles)
1380    end
1381end
1382
1383%-------------------------------------
1384function enable_i(handles,state)
1385set(handles.i_txt,'Visible',state)
1386set(handles.num_first_i,'Visible',state)
1387set(handles.num_last_i,'Visible',state)
1388set(handles.num_incr_i,'Visible',state)
1389
1390%-----------------------------------
1391function enable_j(handles,state)
1392set(handles.j_txt,'Visible',state)
1393set(handles.num_first_j,'Visible',state)
1394set(handles.num_last_j,'Visible',state)
1395set(handles.num_incr_j,'Visible',state)
1396set(handles.MinIndex_j,'Visible',state)
1397set(handles.MaxIndex_j,'Visible',state)
1398
1399
1400%%%%%%%%%%%%%%%%%%%%
1401%%  MAIN ActionName FUNCTIONS
1402%%%%%%%%%%%%%%%%%%%%
1403%------------------------------------------------------------------------
1404% --- Executes on button press in RUN.
1405%------------------------------------------------------------------------
1406function RUN_Callback(hObject, eventdata, handles)
1407
1408%% settings of the button RUN
1409set(handles.RUN,'BusyAction','queue');% activation of STOP button will set BusyAction to 'cancel'
1410set(handles.RUN, 'Enable','Off')% avoid further RUN action until the current one is finished
1411set(handles.RUN,'BackgroundColor',[1 1 0])%show activation of RUN by yellow color
1412drawnow
1413set(handles.status,'Value',0)% desable status display if relevant
1414status_Callback([], eventdata, handles)
1415
1416%% launch action
1417errormsg=launch_action(handles);
1418if ~isempty(errormsg)
1419     msgbox_uvmat('ERROR',errormsg)
1420end
1421
1422%% reset the GUI series
1423update_waitbar(handles.Waitbar,1); % put the waitbar to end position to indicate launching is finished
1424set(handles.RUN, 'Enable','On')
1425set(handles.RUN,'BackgroundColor',[1 0 0])
1426set(handles.RUN, 'Value',0)
1427
1428%------------------------------------------------------------------------
1429% --- called by RUN_Callback
1430%------------------------------------------------------------------------
1431function errormsg=launch_action(handles)
1432errormsg='';%default
1433
1434%% read the data on the GUI series
1435Param=read_GUI_series(handles);%displayed parameters
1436SeriesData=get(handles.series,'UserData');%hidden parameters
1437if isfield(SeriesData,'TransformInput')
1438    Param.TransformInput=SeriesData.TransformInput;
1439end
1440if ~isfield(SeriesData,'i1_series')
1441    errormsg='The input field series needs to be refreshed: press REFRESH';
1442    return
1443end
1444if isfield(Param,'InputFields')&& isequal(Param.InputFields.FieldName,'get_field...')
1445    errormsg='input field name(s) not defined, select get_field...';
1446    return
1447end
1448
1449%% select the Action mode, 'local', 'background' or 'cluster' (if available)
1450RunMode='local';%default (needed for first opening of the GUI series)
1451if isfield(Param.Action,'RunMode')
1452    RunMode=Param.Action.RunMode;
1453    Param.Action=rmfield(Param.Action,'RunMode');%remove from the recorded xml file to avoid interference during ImportConfig
1454end
1455ActionExt='.m';%default
1456if isfield(Param.Action,'ActionExt')
1457    ActionExt=Param.Action.ActionExt;% '.m', '.sh' (compiled)  or '.py' (Python)
1458    Param.Action=rmfield(Param.Action,'ActionExt');%remove from the recorded xml file to avoid interference during ImportConfig
1459end
1460ActionName=Param.Action.ActionName;
1461ActionPath=Param.Action.ActionPath;
1462path_series=fileparts(which('series'));
1463
1464%% create the Action fct handle if RunMode option = 'local'
1465if strcmp(RunMode,'local')
1466    if ~isequal(ActionPath,path_series)
1467        eval(['spath=which(''' ActionName ''');']) %spath = current path of the selected function ACTION
1468        if ~exist(ActionPath,'dir')
1469            errormsg=['The prescribed function path ' ActionPath ' does not exist'];
1470            return
1471        end
1472        if ~isequal(spath,ActionPath)
1473            addpath(ActionPath)% add the prescribed path if not the current one
1474        end
1475    end
1476    eval(['h_fun=@' ActionName ';'])%create a function handle for ACTION
1477    if ~isequal(ActionPath,path_series)
1478        rmpath(ActionPath)% add the prescribed path if not the current one
1479    end
1480end
1481
1482%% Get RunTime code from the file PARAM.xml (needed to run compiled functions)
1483errormsg='';%default error message
1484xmlfile=fullfile(path_series,'PARAM.xml');
1485%test_batch=0;%default: ,no batch mode available
1486if ~exist(xmlfile,'file')
1487    [success,message]=copyfile(fullfile(path_series,'PARAM.xml.default'),xmlfile);
1488end
1489if strcmp(ActionExt,'.sh')
1490    if exist(xmlfile,'file')
1491        s=xml2struct(xmlfile);
1492        if strcmp(RunMode,'cluster_oar') && isfield(s,'BatchParam')
1493            if isfield(s.BatchParam,'NbCore')
1494                NbCore=s.BatchParam.NbCore;
1495            end
1496        elseif (strcmp(RunMode,'background')||strcmp(RunMode,'local')) && isfield(s,'RunParam')
1497            if isfield(s.RunParam,'NbCore')
1498                NbCore=s.RunParam.NbCore;
1499            end
1500        end
1501    end
1502end
1503
1504%% If a compiled version has been selected (ext .sh) check weather it needs to be recompiled
1505if strcmp(ActionExt,'.sh')
1506    TransformPath='';
1507    if ~isempty(get(handles.ActionExt,'UserData'))
1508        TransformPath=get(handles.ActionExt,'UserData');
1509    end
1510    set(handles.series,'Pointer','watch') % set the mouse pointer to 'watch'
1511    set(handles.ActionExt,'BackgroundColor',[1 1 0])
1512    hver=ver('MATLAB');
1513    MCRROOT=['MCRROOT' regexprep(hver.Version,'\.','')];%suppress the dot in version number
1514    RunTime = getenv(MCRROOT);
1515    ActionNameVersion=[ActionName '_' MCRROOT];
1516    ActionFullName=fullfile(get(handles.ActionPath,'String'),[ActionNameVersion '.sh']);
1517    if ~exist(ActionFullName,'file')
1518        answer=msgbox_uvmat('INPUT_Y-N','compiled version has not been created: compile now?');
1519        if strcmp(answer,'Yes')
1520            set(handles.ActionExt,'BackgroundColor',[1 1 0])
1521            path_uvmat=fileparts(which('series'));
1522            currentdir=pwd;
1523            cd(get(handles.ActionPath,'String'))% go to the directory of Action
1524            addpath(path_uvmat)% add the path to uvmat to run the fct 'compile'
1525            compile(ActionName,TransformPath)
1526            cd(currentdir)
1527        else
1528            errormsg='Action launch interrupted';
1529            return
1530        end       
1531    else
1532        sh_file_info=dir(fullfile(get(handles.ActionPath,'String'),[ActionNameVersion '.sh']));
1533        m_file_info=dir(fullfile(get(handles.ActionPath,'String'),[ActionName '.m']));
1534        if isfield(m_file_info,'datenum') && m_file_info.datenum>sh_file_info.datenum
1535            set(handles.ActionExt,'BackgroundColor',[1 1 0])
1536            drawnow
1537            answer=msgbox_uvmat('INPUT_Y-N',[ActionNameVersion '.sh needs to be updated: recompile now?']);
1538            if strcmp(answer,'Yes')
1539                path_uvmat=fileparts(which('series'));
1540                currentdir=pwd;
1541                cd(get(handles.ActionPath,'String'))% go to the directory of Action
1542                addpath(path_uvmat)% add the path to uvmat to run the fct 'compile'
1543                addpath(fullfile(path_uvmat,'transform_field'))% add the path to uvmat to run the fct 'compile'
1544                compile(ActionName,TransformPath)
1545                cd(currentdir)
1546            end
1547        end
1548    end
1549    set(handles.ActionExt,'BackgroundColor',[1 1 1])
1550     set(handles.series,'Pointer','arrow') % set the mouse pointer to 'watch
1551end
1552
1553%% set nbre of cluster cores and processes:
1554% NbCore is the number of computer processors used
1555% NbProcess is the number of independent processes in which the required calculation is split
1556switch RunMode
1557    case {'local','background'}
1558        NbCore=1;% no need to split the calculation
1559    case 'cluster_oar'
1560        if strcmp(ActionExt,'.m')% case of Matlab function (uncompiled)
1561            NbCore=1;% one core used only (limitation of Matlab licences)
1562            answer=msgbox_uvmat('INPUT_Y-N','Number of cores =1: select the compiled version .sh for multi-core processing. Proceed with the .m version?');
1563            if ~strcmp(answer,'Yes')
1564                errormsg='Action launch interrupted by user';
1565                return
1566            end
1567            extra_oar='';
1568        else
1569            answer=inputdlg({'Number of cores (max 36)','extra oar options'},'oarsub parameter',1,{'12',''});
1570            if isempty(answer)
1571                                errormsg='Action launch interrupted by user';
1572                return
1573            end
1574            NbCore=str2double(answer{1});
1575            extra_oar=answer{2};
1576        end
1577    case 'cluster_pbs'
1578        if strcmp(ActionExt,'.m')% case of Matlab function (uncompiled)
1579            NbCore=1;% one core used only (limitation of Matlab licences)
1580            answer=msgbox_uvmat('INPUT_Y-N','Number of cores =1: select the compiled version .sh for multi-core processing. Proceed with the .m version?');
1581            if ~strcmp(answer,'Yes')
1582                errormsg='Action launch interrupted';
1583                return
1584            end
1585            extra_oar='';
1586        else
1587            answer=inputdlg({'Number of cores (max 36)','extra oar options'},'oarsub parameter',1,{'12',''});
1588            NbCore=str2double(answer{1});
1589            %extra_oar=answer{2};%TODO : fix this for LMFA cluster. Maybe
1590            %extrs_oar and extra_pbs are not the best names
1591        end
1592end
1593if ~isfield(Param.IndexRange,'NbSlice')
1594    Param.IndexRange.NbSlice=[];
1595end
1596
1597%% create the output data directory if needed
1598OutputDir='';
1599if isfield(Param,'OutputSubDir')
1600    SubDirOut=[get(handles.OutputSubDir,'String') Param.OutputDirExt];
1601    SubDirOutNew=SubDirOut;
1602    detect=exist(fullfile(Param.InputTable{1,1},SubDirOutNew),'dir');% test if  the dir  already exist
1603    check_create=1; %need to create the result directory by default
1604    CheckOverwrite=1;
1605    if isfield(Param,'CheckOverwrite')
1606        CheckOverwrite=Param.CheckOverwrite;
1607    end
1608    while detect
1609        if CheckOverwrite
1610            comment=', possibly overwrite previous data';
1611        else
1612            comment=', will complement existing result files (no overwriting)';
1613        end
1614        answer=msgbox_uvmat('INPUT_Y-N-Cancel',['use existing ouput directory: ' fullfile(Param.InputTable{1,1},SubDirOutNew) comment]);
1615        if strcmp(answer,'Cancel')
1616            return
1617        elseif strcmp(answer,'Yes')
1618            detect=0;
1619            check_create=0;
1620        else
1621            r=regexp(SubDirOutNew,'(?<root>.*\D)(?<num1>\d+)$','names');%detect whether name ends by a number
1622            if isempty(r)
1623                r(1).root=[SubDirOutNew '_'];
1624                r(1).num1='0';
1625            end
1626            SubDirOutNew=[r(1).root num2str(str2num(r(1).num1)+1)];%increment the index by 1 or put 1
1627            detect=exist(fullfile(Param.InputTable{1,1},SubDirOutNew),'dir');% test if  the dir  already exists
1628            check_create=1;
1629        end
1630    end
1631    Param.OutputDirExt=regexprep(SubDirOutNew,Param.OutputSubDir,'');
1632    Param.OutputRootFile=Param.InputTable{1,3};% the first sorted RootFile taken for output
1633    set(handles.OutputDirExt,'String',Param.OutputDirExt)
1634    OutputDir=fullfile(Param.InputTable{1,1},[Param.OutputSubDir Param.OutputDirExt]);% full name (with path) of output directory
1635    if check_create    % create output directory if it does not exist
1636        [tild,msg1]=mkdir(OutputDir);
1637        if ~strcmp(msg1,'')
1638            errormsg=['cannot create ' OutputDir ': ' msg1];%error message for directory creation
1639            return
1640        end
1641        [success,msg] = fileattrib(OutputDir,'+w','g','s');% allow writing access for the group of users, recursively in the folder 
1642        if success==0
1643            msgbox_uvmat('WARNING',{['unable to set group write access to ' OutputDir ':']; msg1});%error message for directory creation
1644        end
1645    end
1646   
1647elseif isfield(Param,'ActionInput')&&isfield(Param.ActionInput,'LogPath')% custom definition of the output dir
1648    OutputDir=Param.ActionInput.LogPath;   
1649end
1650DirXml=fullfile(OutputDir,'0_XML');
1651if ~exist(DirXml,'dir')
1652    [tild,msg1]=mkdir(DirXml);
1653    if ~strcmp(msg1,'')
1654        errormsg=['cannot create ' DirXml ': ' msg1];%error message for directory creation
1655        return
1656    end
1657    [success,msg] = fileattrib(DirXml,'+w','g','s');% allow writing access for the group of users, recursively in the folder
1658    if success==0
1659        msgbox_uvmat('WARNING',{['unable to set group write access to ' DirXml ':']; msg});%error message for directory creation
1660    end
1661end
1662OutputNomType=nomtype2pair(Param.InputTable{1,4});% nomenclature for output files
1663
1664%% get the set of reference input field indices
1665first_i=1;% first i index to process
1666last_i=1;% last i index to process
1667incr_i=1;% increment step in i index
1668first_j=1;% first j index to process
1669last_j=1;% last j index to process
1670incr_j=1;% increment step in j index
1671if isfield(Param.IndexRange,'first_i')
1672    first_i=Param.IndexRange.first_i;
1673    incr_i=Param.IndexRange.incr_i;
1674    last_i=Param.IndexRange.last_i;
1675end
1676if isfield(Param.IndexRange,'first_j')
1677    first_j=Param.IndexRange.first_j;
1678    last_j=Param.IndexRange.last_j;
1679    incr_j=Param.IndexRange.incr_j;
1680end
1681if last_i < first_i || last_j < first_j
1682    errormsg= 'series/Run_Callback:last field index must be larger or equal to the first one';
1683    return
1684end
1685%incr_i must be defined, =1 by default, if NbSlice is active
1686if isempty(incr_i)&& ~isempty(Param.IndexRange.NbSlice)
1687    incr_i=1;
1688    set(handles.num_incr_i,'String','1')
1689end
1690% case of no increment i defined: processing is done on the available files found in i1_series
1691if isempty(incr_i)
1692    if isempty(incr_j)
1693        [ref_j,ref_i]=find(squeeze(SeriesData.i1_series{1}(1,:,:)));
1694        ref_j=ref_j(ref_j>=first_j & ref_j<=last_j);
1695        ref_i=ref_i(ref_i>=first_i & ref_i<=last_i);
1696        ref_j=ref_j-1;
1697        ref_i=ref_i-1;
1698    else
1699        ref_j=first_j:incr_j:last_j;
1700        [tild,ref_i]=find(squeeze(SeriesData.i1_series{1}(1,:,:)));
1701        ref_i=ref_i-1;
1702        ref_i=ref_i(ref_i>=first_i & ref_i<=last_i);
1703    end
1704% increment i is defined: processing is done on first_i:incr_i:last_i;
1705else
1706    ref_i=first_i:incr_i:last_i;
1707    if isempty(incr_j)% automatic finding of the existing j indices
1708        [ref_j,tild]=find(squeeze(SeriesData.i1_series{1}(1,:,:)));
1709        ref_j=ref_j-1;
1710        ref_j=ref_j(ref_j>=first_j & ref_j<=last_j);
1711    else
1712        ref_j=first_j:incr_j:last_j;
1713    end
1714end
1715CPUTime=1;% job time estimated at 1 min per iteration (on index i and j) by default
1716if isfield(Param.Action, 'CPUTime') && ~isempty(Param.Action.CPUTime)
1717    CPUTime=Param.Action.CPUTime;%Note: CpUTime for one iteration ref_i has to be multiplied by the number of j indices nbfield_j
1718end
1719nbfield_j=numel(ref_j); % number of j indices
1720BlockLength=numel(ref_i);% by default, job involves the full set of i field indices
1721NbProcess=1;
1722switch RunMode
1723    case {'cluster_oar','cluster_pbs'}
1724        if isempty(Param.IndexRange.NbSlice)% if NbSlice is not defined
1725             BlockLength= ceil(20/(CPUTime*nbfield_j));% short iterations are grouped such that the minimum time of a process is 20 min.
1726             BlockLength=max(BlockLength,ceil(numel(ref_i)/500));% possibly increase the BlockLength to have less than 500 jobs
1727             NbProcess=ceil(numel(ref_i)/BlockLength) ; % nbre of processes sent to oar
1728        else
1729            NbProcess=Param.IndexRange.NbSlice;% the parameter NbSlice sets the nbre of run processes
1730            NbCore=min(NbCore,NbProcess);% reduces the number of cores if it exceeds the number of processes
1731        end
1732end
1733
1734%% record nbre of output files and starting time for computation for status
1735StatusData=get(handles.status,'UserData');
1736if isfield(StatusData,'OutputFileMode')
1737    switch StatusData.OutputFileMode
1738        case 'NbInput'
1739            StatusData.NbOutputFile=numel(ref_i)*nbfield_j;
1740        case 'NbInput_i'
1741            StatusData.NbOutputFile=numel(ref_i);
1742        case 'NbSlice'   
1743            StatusData.NbOutputFile=str2num(get(handles.num_NbSlice,'String'));
1744    end
1745end
1746StatusData.TimeStart=now;
1747set(handles.status,'UserData',StatusData)
1748
1749%% case of a function in Python
1750if strcmp(ActionExt, '.py (in dev.)')
1751    fprintf([
1752        '\n' ...
1753        '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n' ...
1754        'The option .py is used. It is still in development.\n' ...
1755        'Do not use it unless you really know what you do!\n' ...
1756        'To try it, first install Pyp and the most recent version of FluidDyn.\n' ...
1757        '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n'])
1758    RunMode = 'python';
1759    t = struct2xml(Param);
1760    t = set(t, 1, 'name', 'Series');
1761    filexml = fullfile_uvmat(DirXml, '', Param.InputTable{1,3}, '.xml', OutputNomType,...
1762         Param.IndexRange.first_i, Param.IndexRange.last_i, first_j, last_j);
1763    save(t, filexml);
1764end
1765
1766
1767%% direct processing on the current Matlab session
1768if strcmp (RunMode,'local')
1769    for iprocess=1:NbProcess
1770        if isempty(Param.IndexRange.NbSlice)
1771            %Param.IndexRange.first_i=first_i+(iprocess-1)*BlockLength*incr_i;
1772            Param.IndexRange.first_i=ref_i(1+(iprocess-1)*BlockLength);
1773            if Param.IndexRange.first_i>last_i
1774                break
1775            end
1776            Param.IndexRange.last_i=min(ref_i(iprocess*BlockLength),last_i);
1777            %Param.IndexRange.last_i=min(first_i+(iprocess)*BlockLength*incr_i-1,last_i);
1778        else %multislices (then incr_i is not empty)
1779            Param.IndexRange.first_i= first_i+incr_i*(iprocess-1);
1780            Param.IndexRange.incr_i=incr_i*Param.IndexRange.NbSlice;
1781        end
1782        if isfield(Param,'OutputSubDir')
1783            t=struct2xml(Param);
1784            t=set(t,1,'name','Series');
1785            filexml=fullfile_uvmat(DirXml,'',Param.InputTable{1,3},'.xml',OutputNomType,...
1786                Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1787            save(t,filexml);
1788        end
1789        switch ActionExt
1790            case '.m'
1791                h_fun(Param);
1792            case '.sh'
1793                switch computer
1794                    case {'PCWIN','PCWIN64'} %Windows system
1795                        filexml=regexprep(filexml,'\\','\\\\');% add '\' so that '\' are left as characters
1796                        system([fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml]);% TODO: adapt to DOS system
1797                    case {'GLNX86','GLNXA64','MACI64'}%Linux  system
1798                        system([fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml]);
1799                end
1800        end
1801    end
1802elseif ~strcmp(RunMode,'python')
1803    %% processing on a different session of the same computer (background) or cluster, create executable files
1804    batch_file_list=cell(NbProcess,1);% initiate the list of executable files
1805    DirExe=fullfile(OutputDir,'0_EXE');%directory name for executable files
1806    switch computer
1807        case {'PCWIN','PCWIN64'} %Windows system
1808            ExeExt='.bat';
1809        case {'GLNX86','GLNXA64','MACI64'}%Linux  system
1810           ExeExt='.sh';
1811    end
1812    %create subdirectory for executable files
1813    if ~exist(DirExe,'dir')
1814        [tild,msg1]=mkdir(DirExe);
1815        if ~strcmp(msg1,'')
1816            errormsg=['cannot create ' DirExe ': ' msg1];%error message for directory creation
1817            return
1818        end
1819    end
1820    %create subdirectory for log files
1821    DirLog=fullfile(OutputDir,'0_LOG');
1822    if ~exist(DirLog,'dir')
1823        [tild,msg1]=mkdir(DirLog);
1824        if ~strcmp(msg1,'')
1825            errormsg=['cannot create ' DirLog ': ' msg1];%error message for directory creation
1826            return
1827        end
1828    end
1829    for iprocess=1:NbProcess
1830        if isempty(Param.IndexRange.NbSlice)% process by blocks of i index
1831            Param.IndexRange.first_i=first_i+(iprocess-1)*BlockLength*incr_i;
1832            if Param.IndexRange.first_i>last_i
1833                NbProcess=iprocess-1;
1834                break% leave the loop, we are at the end of the calculation
1835            end
1836            Param.IndexRange.last_i=min(last_i,first_i+(iprocess)*BlockLength*incr_i-1);
1837        else% process by slices of i index if NbSlice is defined, computation in a single process if NbSlice =1
1838            Param.IndexRange.first_i= first_i+iprocess-1;
1839            Param.IndexRange.incr_i=incr_i*Param.IndexRange.NbSlice;
1840        end
1841        for ilist=1:size(Param.InputTable,1)
1842        Param.InputTable{ilist,1}=regexprep(Param.InputTable{ilist,1},'\','/');%correct path name for PCWIN system
1843        end
1844        % create, fill and save the xml parameter file
1845        t=struct2xml(Param);
1846        t=set(t,1,'name','Series');
1847        filexml=fullfile_uvmat(DirXml,'',Param.InputTable{1,3},'.xml',OutputNomType,...
1848            Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1849        save(t,filexml);% save the parameter file
1850       
1851        %create the executable file
1852         filebat=fullfile_uvmat(DirExe,'',Param.InputTable{1,3},ExeExt,OutputNomType,...
1853           Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1854        batch_file_list{iprocess}=filebat;
1855        [fid,message]=fopen(filebat,'w');% create the executable file
1856        if isequal(fid,-1)
1857            errormsg=['creation of .bat file: ' message];
1858            return
1859        end
1860       
1861        % set the log file name
1862        filelog=fullfile_uvmat(DirLog,'',Param.InputTable{1,3},'.log',OutputNomType,...
1863            Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1864       
1865        % fill and save the executable file
1866        switch ActionExt
1867            case '.m'% Matlab function
1868                switch computer
1869                    case {'GLNX86','GLNXA64','MACI64'}
1870                        cmd=[...
1871                            '#!/bin/bash \n'...
1872                            '. /etc/sysprofile \n'...
1873                            'matlab -nodisplay -nosplash -nojvm -logfile ''' filelog ''' <<END_MATLAB \n'...
1874                            'addpath(''' path_series '''); \n'...
1875                            'addpath(''' Param.Action.ActionPath '''); \n'...
1876                            '' Param.Action.ActionName  '( ''' filexml '''); \n'...
1877                            'exit \n'...
1878                            'END_MATLAB \n'];
1879                        fprintf(fid,cmd);%fill the executable file with the  char string cmd
1880                        fclose(fid);% close the executable file
1881                        system(['chmod +x ' filebat]);% set the file to executable
1882                    case {'PCWIN','PCWIN64'}
1883                        text_matlabscript=['matlab -automation -logfile ' regexprep(filelog,'\\','\\\\')...
1884                            ' -r "addpath(''' regexprep(path_series,'\\','\\\\') ''');'...
1885                            'addpath(''' regexprep(Param.Action.ActionPath,'\\','\\\\') ''');'...
1886                            '' Param.Action.ActionName  '( ''' regexprep(filexml,'\\','\\\\') ''');exit"'];
1887                        fprintf(fid,text_matlabscript);%fill the executable file with the  char string cmd
1888                        fclose(fid);% close the executable file
1889                end
1890            case '.sh' % compiled Matlab function
1891                switch computer
1892                    case {'GLNX86','GLNXA64','MACI64'}
1893                        cmd=['#!/bin/bash \n '...
1894                            '#$ -cwd \n '...
1895                            'sleep $(( $RANDOM / 3000 )) \n '...
1896                            'hostname && date \n '...
1897                            'umask 002 \n'...
1898                            fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml];%allow writting access to created files for user group
1899                        fprintf(fid,cmd);%fill the executable file with the  char string cmd
1900                        fclose(fid);% close the executable file
1901                        system(['chmod +x ' filebat]);% set the file to executable
1902                       
1903                    case {'PCWIN','PCWIN64'}   
1904                        fprintf(fid,cmd);
1905                        fclose(fid);
1906                end
1907        end
1908    end
1909end
1910
1911%% launch the executable files for background or cluster processing
1912switch RunMode
1913    case 'background'
1914        for iprocess=1:NbProcess
1915            system([batch_file_list{iprocess} ' &'])% directly execute the command file for each process
1916        end
1917        msgbox_uvmat('CONFIRMATION',[ActionName ' launched in background: press STATUS to see results'])
1918    case 'cluster_oar' % option 'oar-parexec' used
1919        %create subdirectory for oar command and log files
1920        %DirOARLog=fullfile(OutputDir,'0_LOG');
1921        DirOAR=fullfile(OutputDir,'0_OAR');
1922        if exist(DirOAR,'dir')% delete the content of the dir 0_LOG to allow new input
1923            curdir=pwd;
1924            cd(DirOAR)
1925            delete('*')
1926            cd(curdir)
1927        else
1928            [tild,msg1]=mkdir(DirOAR);
1929            if ~strcmp(msg1,'')
1930                errormsg=['cannot create ' DirOAR ': ' msg1];%error message for directory creation
1931                return
1932            end
1933        end
1934        filename_joblist=fullfile(DirOAR,'job_list.txt');%create name of the global executable file
1935        filename_log=fullfile(DirLog,'job_list.stdout');%file for output messages of the master oar process
1936        filename_errors=fullfile(DirLog,'job_list.stderr');%file for error messages of the master oar process
1937       
1938        fid=fopen(filename_joblist,'w');
1939        for p=1:length(batch_file_list)
1940            fprintf(fid,[batch_file_list{p} '\n']);% list of exe files
1941        end
1942        fclose(fid);
1943        system(['chmod +x ' filename_joblist]);% set the file to executable
1944       
1945        % the command job_list.txt contains the list of NbProcess independent individual jobs
1946        % in which the total calculation has been split. Those are written as executable files .sh in the folder /O_EXE.
1947        %  These individual jobs are grouped by the system as oar jobs on the NbCore processors.
1948        %  For each processor, the oar job must stop after the walltime which has been set, which is limited to 24 h.
1949        %  However, the oar job is automatically restarted (option 'idempotent') provided the individual jobs are
1950        % shorter than the wall time: in the time interval 'checkpoint' (WallTimeOneJob) before the end of the allowed duration,
1951        %  the oar job restarts when an individual job ends.
1952        JobTime=CPUTime*BlockLength*nbfield_j;% estimated time for one individual job (in minutes)
1953        % wall time (in hours ) for each oar job, allowing 10 individual jobs, but limited to 23 h:
1954        WallTimeTotal=min(23,4*JobTime/60);
1955        %disp(['WallTimeTotal: ' num2str(WallTimeTotal) ' hours'])
1956        % estimated time of an individual job (in min), with a margin of error
1957        WallTimeOneJob=min(4*JobTime+10,WallTimeTotal*60/2);% estimated max time of an individual job for checkpoint
1958        disp(['WallTimeOneJob: ' num2str(WallTimeOneJob) ' minutes'])
1959        oar_command=['oarsub -n UVmat_' ActionName ' '...
1960            '-t idempotent --checkpoint ' num2str(WallTimeOneJob*60) ' '...
1961            '-l /core=' num2str(NbCore) ','...
1962            'walltime=' datestr(WallTimeTotal/24,13) ' '...
1963            '-E ' filename_errors ' '...
1964            '-O ' filename_log ' '...
1965            extra_oar ' '...
1966            '"oar-parexec -s -f ' filename_joblist ' '...
1967            '-l ' filename_joblist '.log"\n'];
1968        fprintf(oar_command);% display  system command on the Matlab command window
1969         [status,result]=system(oar_command)% execute system command and show the result (ID number of the launched job) on the Matlab command window
1970        filename_oarcommand=fullfile(DirOAR,'0_oar_command');% keep track of the command in file '0-OAR/0_oar_command'
1971        fid=fopen(filename_oarcommand,'w');
1972        fprintf(fid,oar_command); % store the command
1973        fprintf(fid,result);% store the result (job ID number)
1974        fclose(fid);
1975
1976        msgbox_uvmat('CONFIRMATION',[ActionName ' launched as  ' num2str(NbProcess) ' processes in cluster: press STATUS to see results'])
1977    case 'cluster_pbs' % for LMFA Kepler machine
1978        %create subdirectory for pbs command and log files
1979        DirPBS=fullfile(OutputDir,'0_PBS'); %todo : common name OAR/PBS
1980        if exist(DirPBS,'dir')% delete the content of the dir 0_LOG to allow new input
1981            curdir=pwd;
1982            cd(DirPBS)
1983            delete('*')
1984            cd(curdir)
1985        else
1986            [tild,msg1]=mkdir(DirPBS);
1987            if ~strcmp(msg1,'')
1988                errormsg=['cannot create ' DirPBS ': ' msg1];%error message for directory creation
1989                return
1990            end
1991        end
1992        max_walltime=3600*20; % 20h max total calculation (cannot exceed 24 h)
1993        walltime_onejob=1800; % seconds, max estimated time for asingle file index value
1994        filename_joblist=fullfile(DirPBS,'job_list.txt');%create name of the global executable file
1995        fid=fopen(filename_joblist,'w');
1996        for p=1:length(batch_file_list)
1997            fprintf(fid,[batch_file_list{p} '\n']);% list of exe files
1998        end
1999        fclose(fid);
2000        system(['chmod +x ' filename_joblist]);% set the file to executable
2001        pbs_command=['qstat -n CIVX '...
2002            '-t idempotent --checkpoint ' num2str(walltime_onejob+60) ' '...
2003            '-l /core=' num2str(NbCore) ','...
2004            'walltime=' datestr(min(1.05*walltime_onejob/86400*max(NbProcess*BlockLength*nbfield_j,NbCore)/NbCore,max_walltime/86400),13) ' '...
2005            '-E ' regexprep(filename_joblist,'\.txt\>','.stderr') ' '...
2006            '-O ' regexprep(filename_joblist,'\.txt\>','.log') ' '...
2007            extra_oar ' '...
2008            '"oar-parexec -s -f ' filename_joblist ' '...
2009            '-l ' filename_joblist '.log"\n'];
2010        filename_oarcommand=fullfile(DirPBS,'pbs_command');
2011        fid=fopen(filename_oarcommand,'w');
2012        fprintf(fid,pbs_command);
2013        fclose(fid);
2014        fprintf(pbs_command);% display in command line
2015        %system(pbs_command); 
2016        msgbox_uvmat('CONFIRMATION',[ActionName ' command ready to be launched in cluster'])       
2017    case 'python'
2018        command = [
2019            'LD_LIBRARY_PATH=$(echo $LD_LIBRARY_PATH | pyp "p.split('':'') | [s for s in p if ''matlab'' not in s] | '':''.join(p)") ' ...
2020            'python -m fluiddyn.postproc.uvmat ' filexml];
2021        % fprintf(['command:\n' command '\n\n'])
2022        system(command, '-echo');
2023end
2024
2025%------------------------------------------------------------------------
2026function STOP_Callback(hObject, eventdata, handles)
2027%------------------------------------------------------------------------
2028set(handles.RUN, 'BusyAction','cancel')
2029set(handles.RUN,'BackgroundColor',[1 0 0])
2030set(handles.RUN,'enable','on')
2031set(handles.RUN, 'Value',0)
2032
2033
2034%------------------------------------------------------------------------
2035% --- read parameters from the GUI series
2036%------------------------------------------------------------------------
2037function Param=read_GUI_series(handles)
2038
2039%% read raw parameters from the GUI series
2040Param=read_GUI(handles.series);
2041
2042%% clean the output structure by removing unused information
2043if isfield(Param,'Pairs')
2044    Param=rmfield(Param,'Pairs'); %info Pairs not needed for output
2045end
2046if isfield(Param,'InputLine')
2047    Param=rmfield(Param,'InputLine');
2048end
2049if isfield(Param,'EditObject')
2050    Param=rmfield(Param,'EditObject');
2051end
2052Param.IndexRange.TimeSource=Param.IndexRange.TimeTable{end,1};
2053Param.IndexRange=rmfield(Param.IndexRange,'TimeTable');
2054empty_line=false(size(Param.InputTable,1),1);
2055for iline=1:size(Param.InputTable,1)
2056    empty_line(iline)=isempty(cell2mat(Param.InputTable(iline,1:3)));
2057end
2058Param.InputTable(empty_line,:)=[];
2059
2060%------------------------------------------------------------------------
2061% --- Executes on selection change in ActionName.
2062function ActionName_Callback(hObject, eventdata, handles)
2063%------------------------------------------------------------------------
2064
2065%% stop any ongoing series processing
2066if isequal(get(handles.RUN,'Value'),1)
2067    answer= msgbox_uvmat('INPUT_Y-N','stop current Action process?');
2068    if strcmp(answer,'Yes')
2069        STOP_Callback(hObject, eventdata, handles)
2070    else
2071        return
2072    end
2073end
2074set(handles.ActionName,'BackgroundColor',[1 1 0])
2075huigetfile=findobj(allchild(0),'tag','status_display');
2076if ~isempty(huigetfile)
2077    delete(huigetfile)
2078end
2079drawnow
2080
2081%% get Action name and path
2082NbBuiltinAction=get(handles.Action,'UserData'); %nbre of functions initially proposed in the menu ActionName (as defined in the Opening fct of series)
2083ActionList=get(handles.ActionName,'String');% list menu fields
2084ActionIndex=get(handles.ActionName,'Value');
2085if ~isequal(ActionIndex,1)% if we are not just opening series
2086    InputTable=get(handles.InputTable,'Data');
2087    if isempty(InputTable{1,4})
2088        msgbox_uvmat('ERROR','no input file available: use Open in the menu bar')
2089        return
2090    end
2091end
2092ActionName= ActionList{get(handles.ActionName,'Value')}; % selected function name
2093ActionPathList=get(handles.ActionName,'UserData');%list of recorded paths to functions of the list ActionName
2094
2095%% add a new function to the menu if 'more...' has been selected in the menu ActionName
2096if isequal(ActionName,'more...')
2097    [FileName, PathName] = uigetfile( ...
2098        {'*.m', ' (*.m)';
2099        '*.m',  '.m files '; ...
2100        '*.*', 'All Files (*.*)'}, ...
2101        'Pick a series processing function ',get(handles.ActionPath,'String'));
2102    if length(FileName)<2
2103        return
2104    end
2105    [tild,ActionName,ActionExt]=fileparts(FileName);
2106   
2107    % insert the choice in the menu ActionName
2108    ActionIndex=find(strcmp(ActionName,ActionList),1);% look for the selected function in the menu Action
2109    PathName=regexprep(PathName,'/$','');
2110    if ~isempty(ActionIndex) && ~strcmp(ActionPathList{ActionIndex},PathName)%compare the path to the existing fct
2111        ActionIndex=[]; % the selected path is different than the recorded one
2112    end
2113    if isempty(ActionIndex)%the qselected fct (with selected path) does not exist in the menu
2114        ActionIndex= length(ActionList);
2115        ActionList=[ActionList(1:end-1);{ActionName};ActionList(end)];% the selected function is appended in the menu, before the last item 'more...'
2116         ActionPathList=[ActionPathList; PathName];
2117    end
2118   
2119    % record the file extension and extend the path list if it is a new extension
2120    ActionExtList=get(handles.ActionExt,'String');
2121    ActionExtIndex=find(strcmp(ActionExt,ActionExtList), 1);
2122    if isempty(ActionExtIndex)
2123        set(handles.ActionExt,'String',[ActionExtList;{ActionExt}])
2124    end
2125
2126    % remove old Action options in the menu (keeping a menu length <nb_builtin_ACTION+5)
2127    if length(ActionList)>NbBuiltinAction+5; %nb_builtin_ACTION=nbre of functions always remaining in the initial menu
2128        nbremove=length(ActionList)-NbBuiltinAction-5;
2129        ActionList(NbBuiltinAction+1:end-5)=[];
2130        ActionPathList(NbBuiltinAction+1:end-4,:)=[];
2131        ActionIndex=ActionIndex-nbremove;
2132    end
2133   
2134    % record action menu, choice and path
2135    set(handles.ActionName,'Value',ActionIndex)
2136    set(handles.ActionName,'String',ActionList)
2137       set(handles.ActionName,'UserData',ActionPathList);
2138    set(handles.ActionExt,'Value',ActionExtIndex)
2139       
2140    %record the user defined menu additions in personal file profil_perso
2141    dir_perso=prefdir;
2142    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
2143    if NbBuiltinAction+1<=numel(ActionList)-1
2144        ActionListUser=ActionList(NbBuiltinAction+1:numel(ActionList)-1);
2145        ActionPathListUser=ActionPathList(NbBuiltinAction+1:numel(ActionList)-1);
2146        ActionExtListUser={};
2147        if numel(ActionExtList)>2
2148            ActionExtListUser=ActionExtList(3:end);
2149        end
2150        if exist(profil_perso,'file')
2151            save(profil_perso,'ActionListUser','ActionPathListUser','ActionExtListUser','-append')
2152        else
2153            save(profil_perso,'ActionListUser','ActionPathListUser','ActionExtListUser','-V6')
2154        end
2155    end
2156end
2157
2158%% check the current ActionPath to the selected function
2159ActionPath=ActionPathList{ActionIndex};%current recorded path
2160set(handles.ActionPath,'String',ActionPath); %show the path to the senlected function
2161
2162%% reinitialise the waitbar
2163update_waitbar(handles.Waitbar,0)
2164
2165%% create the function handle for Action
2166if ~exist(ActionPath,'dir')
2167    msgbox_uvmat('ERROR',['The prescribed function path ' ActionPath ' does not exist']);
2168    return
2169end
2170current_dir=pwd;%current working dir
2171cd(ActionPath)
2172h_fun=str2func(ActionName);
2173cd(current_dir)
2174
2175%
2176% checkaddpath=0;
2177% path_series=which('series');
2178% %eval(['spath=which(''' ActionName ''');']) %spath = current path of the selected function ACTION
2179% spath=fileparts(which(ActionName)); %spath = current path of the selected function ACTION
2180% if ~exist(ActionPath,'dir')
2181%     msgbox_uvmat('ERROR',['The prescribed function path ' ActionPath ' does not exist']);
2182%     return
2183% end
2184% if ~strcmp(spath,ActionPath)
2185%     if strcmp(pwd,spath)
2186%         msgbox_uvmat('ERROR',[ 'a function called ' ActionName ' on your working space oversets the selected one']);
2187%         return
2188%     else
2189%         addpath(ActionPath)% add the prescribed path if not the current one
2190%         checkaddpath=1;
2191%     end
2192% end
2193% eval(['h_fun=@' ActionName ';'])%create a function handle for ACTION
2194% if checkaddpath && ~isequal(ActionPath,path_series)
2195%     rmpath(ActionPath)% add the prescribed path if not the current one
2196% end
2197
2198%% Activate the Action fct to adapt the configuration of the GUI series and bring specific parameters in SeriesData
2199Param=read_GUI_series(handles);% read the parameters from the GUI series
2200ParamOut=h_fun(Param);%run the selected Action function to get the relevant input
2201
2202%% Put the first line of the selected Action fct as tooltip help
2203try
2204    [fid,errormsg] =fopen([ActionName '.m']);
2205    InputText=textscan(fid,'%s',1,'delimiter','\n');
2206    fclose(fid);
2207    set(handles.ActionName,'ToolTipString',InputText{1}{1})% put the first line of the selected function as tooltip help
2208end
2209
2210
2211%% Visibility of VelType and VelType_1 menus asked by ActionName
2212VelTypeRequest=1;%VelType requested by default
2213VelTypeRequest_1=1;%VelType requested by default
2214if isfield(ParamOut,'VelType')
2215    VelTypeRequest=ismember(ParamOut.VelType,{'on','one','two'});
2216    VelTypeRequest_1=strcmp( ParamOut.VelType,'two');
2217end
2218FieldNameRequest=0;  %hidden by default
2219FieldNameRequest_1=0;  %hidden by default
2220if isfield(ParamOut,'FieldName')
2221    FieldNameRequest=ismember(ParamOut.FieldName,{'on','one','two'});
2222    FieldNameRequest_1=strcmp( ParamOut.FieldName,'two');
2223end
2224
2225%% Detect the types of input files and set menus and default options in 'VelType'
2226SeriesData=get(handles.series,'UserData');% info on the input file series
2227iview_civ=find(strcmp('civx',SeriesData.FileType)|strcmp('civdata',SeriesData.FileType));
2228iview_netcdf=find(strcmp('netcdf',SeriesData.FileType)|strcmp('civx',SeriesData.FileType)|strcmp('civdata',SeriesData.FileType));% all nc files, icluding civ
2229FieldList=get(handles.FieldName,'String');% previous list as default
2230if ~iscell(FieldList),FieldList={FieldList};end
2231FieldList_1=get(handles.FieldName_1,'String');% previous list as default
2232if ~iscell(FieldList_1),FieldList_1={FieldList_1};end
2233%CheckList=0;% indicate whether FieldName has been updated
2234CheckList_1=1;% indicate whether FieldName_1 has been updated
2235handles_coord=[handles.Coord_x handles.Coord_y handles.Coord_z handles.Coord_x_title handles.Coord_y_title handles.Coord_z_title];
2236if VelTypeRequest && numel(iview_civ)>=1
2237    menu=set_veltype_display(SeriesData.FileInfo{iview_civ(1)}.CivStage,SeriesData.FileType{iview_civ(1)});
2238    set(handles.VelType,'Value',1)% set first choice by default
2239    set(handles.VelType,'String',[{'*'};menu])
2240    set(handles.VelType,'Visible','on')
2241    set(handles.VelType_title,'Visible','on')
2242    FieldList=[set_field_list('U','V');{'C'};{'get_field...'}];%standard menu for civx data
2243    %CheckList=1;
2244    set(handles.FieldName,'Value',1); %velocity vector choice by default
2245    if  VelTypeRequest_1 && numel(iview_civ)>=2
2246        menu=set_veltype_display(SeriesData.FileInfo{iview_civ(2)}.CivStage,SeriesData.FileType{iview_civ(2)});
2247        set(handles.VelType_1,'Value',1)% set first choice by default
2248        set(handles.VelType_1,'String',[{'*'};menu])
2249        set(handles.VelType_1,'Visible','on')
2250        set(handles.VelType_title_1,'Visible','on')
2251        FieldList_1=[set_field_list('U','V');{'C'};{'get_field...'}];%standard menu for civx data
2252        CheckList_1=1;
2253        set(handles.FieldName_1,'Value',1); %velocity vector choice by default
2254    else
2255        set(handles.VelType_1,'Visible','off')
2256        set(handles.VelType_title_1,'Visible','off')
2257    end
2258else
2259    set(handles.VelType,'Visible','off')
2260    set(handles.VelType_title,'Visible','off')
2261end   
2262
2263%% Detect the types of input files and set menus and default options in 'FieldName'
2264if FieldNameRequest && numel(iview_netcdf)>=1
2265    set(handles.InputFields,'Visible','on')
2266    %if CheckList==0        % not civ input made
2267        if isfield(SeriesData.FileInfo{iview_netcdf(1)},'ListVarName')
2268        ListVarName=SeriesData.FileInfo{iview_netcdf(1)}.ListVarName;
2269        ind_var=get(handles.FieldName,'Value');%indices of previously selected variables
2270        for ilist=1:numel(ind_var)
2271            if isempty(find(strcmp(FieldList{ind_var(ilist)},ListVarName)))
2272                FieldList={};% previous choice not consistent with new input field
2273                set(handles.FieldName,'Value',1)
2274                break
2275            end
2276        end
2277        if ~isempty(FieldList)
2278            if isempty(find(strcmp(get(handles.Coord_x,'String'),ListVarName)))||...
2279                    isempty(find(strcmp(get(handles.Coord_y,'String'),ListVarName)))
2280                FieldList={};
2281                set(handles.Coord_x,'String','')
2282                set(handles.Coord_y,'String','')
2283            end
2284            Coord_z=get(handles.Coord_z,'String');
2285            if ~isempty(Coord_z) && isempty(find(strcmp(Coord_z,ListVarName)))
2286                FieldList={};
2287                set(handles.Coord_z,'String','')
2288            end
2289        end
2290        set(handles_coord,'Visible','on')
2291        FieldList=[FieldList;{'get_field...'}];
2292        if FieldNameRequest_1 && numel(iview_netcdf)>=2
2293            set(handles.FieldName_1,'Visible','on')
2294            if CheckList_1==0        % not civ input made
2295                ListVarName=SeriesData.FileInfo{iview_netcdf(2)}.ListVarName;
2296                ind_var=get(handles.FieldName,'Value');%indices of previously selected variables
2297                for ilist=1:numel(ind_var)
2298                    if isempty(find(strcmp(FieldList{ind_var(ilist)},ListVarName)))
2299                        FieldList_1={};% previous choice not consistent with new input field
2300                        set(handles.FieldName_1,'Value',1)
2301                        break
2302                    end
2303                end
2304                warn_coord=0;
2305                if isempty(find(strcmp(get(handles.Coord_x,'String'),ListVarName)))||...
2306                        isempty(find(strcmp(get(handles.Coord_y,'String'),ListVarName)))
2307                    warn_coord=1;
2308                end
2309                if ~isempty(Coord_z) && isempty(find(strcmp(Coord_z,ListVarName)))
2310                    FieldList_1={};
2311                    warn_coord=1;
2312                end
2313                if warn_coord
2314                    msgbox_uvmat('WARNING','coordiante names do not exist in the second netcdf input file')
2315                end
2316                set(handles.FieldName,'String',[FieldList;{'get_field...'}])
2317                set(handles.FieldName_1,'Visible','on')
2318                set(handles.FieldName_1,'Value',1)
2319                set(handles.FieldName_1,'String',FieldList_1)
2320            end
2321        else
2322            set(handles.FieldName_1,'Visible','off')
2323        end
2324        end
2325%     else
2326%         set(handles_coord,'Visible','off')% no coord display for civ data
2327%     end
2328    set(handles.FieldName,'String',FieldList)
2329else
2330    set(handles.InputFields,'Visible','off')
2331end
2332
2333%% Introduce visibility of file overwrite option
2334if isfield(ParamOut,'CheckOverwriteVisible')&& strcmp(ParamOut.CheckOverwriteVisible,'on')
2335    set(handles.CheckOverwrite,'Visible','on')
2336else
2337    set(handles.CheckOverwrite,'Visible','off')
2338end
2339
2340%% Check whether alphabetical sorting of input Subdir is allowed by the Action fct  (for multiples series entries)
2341if isfield(ParamOut,'AllowInputSort')&&isequal(ParamOut.AllowInputSort,'on')&& size(Param.InputTable,1)>1
2342    [tild,iview]=sort(InputTable(:,2)); %subdirectories sorted in alphabetical order
2343    set(handles.InputTable,'Data',InputTable(iview,:));
2344    MinIndex_i=get(handles.MinIndex_i,'Data');
2345    MinIndex_j=get(handles.MinIndex_j,'Data');
2346    MaxIndex_i=get(handles.MaxIndex_i,'Data');
2347    MaxIndex_j=get(handles.MaxIndex_j,'Data');
2348    set(handles.MinIndex_i,'Data',MinIndex_i(iview,:));
2349    set(handles.MinIndex_j,'Data',MinIndex_j(iview,:));
2350    set(handles.MaxIndex_i,'Data',MaxIndex_i(iview,:));
2351    set(handles.MaxIndex_j,'Data',MaxIndex_j(iview,:));
2352    TimeTable=get(handles.TimeTable,'Data');
2353    set(handles.TimeTable,'Data',TimeTable(iview,:));
2354    PairString=get(handles.PairString,'Data');
2355    set(handles.PairString,'Data',PairString(iview,:));
2356end
2357
2358%% Impose the whole input file index range if requested
2359if isfield(ParamOut,'WholeIndexRange')&&isequal(ParamOut.WholeIndexRange,'on')
2360    MinIndex_i=get(handles.MinIndex_i,'Data');
2361    MinIndex_j=get(handles.MinIndex_j,'Data');
2362    MaxIndex_i=get(handles.MaxIndex_i,'Data');
2363    MaxIndex_j=get(handles.MaxIndex_j,'Data');
2364    set(handles.num_first_i,'String',num2str(MinIndex_i(1)))% set first as the min index (for the first line)
2365    set(handles.num_last_i,'String',num2str(MaxIndex_i(1)))% set last as the max index (for the first line)
2366    set(handles.num_incr_i,'String','1')
2367    set(handles.num_first_j,'String',num2str(MinIndex_j(1)))% set first as the min index (for the first line)
2368    set(handles.num_last_j,'String',num2str(MaxIndex_j(1)))% set last as the max index (for the first line)
2369    set(handles.num_incr_j,'String','1')
2370else  % check index ranges
2371    first_i=1;last_i=1;first_j=1;last_j=1;
2372    if isfield(Param.IndexRange,'first_i')
2373        first_i=Param.IndexRange.first_i;
2374        last_i=Param.IndexRange.last_i;
2375    end
2376    if isfield(Param.IndexRange,'first_j')
2377        first_j=Param.IndexRange.first_j;
2378        last_j=Param.IndexRange.last_j;
2379    end
2380    if last_i < first_i || last_j < first_j , msgbox_uvmat('ERROR','last field number must be larger than the first one'),...
2381            set(handles.RUN, 'Enable','On'), set(handles.RUN,'BackgroundColor',[1 0 0]),return,end;
2382end
2383
2384%% enable or desable j index visibility
2385status_j='on';%default
2386if isfield(ParamOut,'Desable_j_index')&&isequal(ParamOut.Desable_j_index,'on')
2387    status_j='off';
2388end
2389if isempty(find(~cellfun(@isempty,SeriesData.j1_series), 1)); % case of empty j indices
2390    status_j='off'; % no j index needed
2391elseif strcmp(get(handles.PairString,'Visible'),'on')
2392    check_burst=cellfun(@isempty,regexp(get(handles.PairString,'Data'),'^j'));%=0 for burst case, 1 otherwise
2393    if isempty(find(check_burst, 1))% if all pair string begins by j (burst)
2394        status_j='off'; % no j index needed for bust case
2395    end
2396end
2397enable_j(handles,status_j) % no j index needed
2398
2399
2400%% NbSlice visibility
2401%NbSliceVisible='off';%default
2402if isfield(ParamOut,'NbSlice') && (strcmp(ParamOut.NbSlice,'on')||isnumeric(ParamOut.NbSlice))
2403    set(handles.num_NbSlice,'Visible','on')
2404    set(handles.NbSlice_title,'Visible','on')
2405else
2406    set(handles.num_NbSlice,'Visible','off')
2407    set(handles.NbSlice_title,'Visible','off')
2408    %     set(handles.num_NbProcess,'String',get(handles.num_NbSlice,'String'))% the nbre of processes is imposed as the nbre of slices
2409    % else
2410    %     set(handles.num_NbProcess,'String','')% free nbre of processes
2411end
2412if isnumeric(ParamOut.NbSlice)
2413    set(handles.num_NbSlice,'String',num2str(ParamOut.NbSlice))
2414    set(handles.num_NbSlice,'Enable','off'); % NbSlice set by the activation of the Action function
2415else
2416    set(handles.num_NbSlice,'Enable','on'); % NbSlice can be modified on the GUI series
2417end
2418% set(handles.num_NbSlice,'Visible',NbSliceVisible)
2419% set(handles.NbSlice_title,'Visible',NbSliceVisible)
2420
2421
2422
2423%% Visibility of FieldTransform menu
2424FieldTransformVisible='off';  %hidden by default
2425if isfield(ParamOut,'FieldTransform')
2426    FieldTransformVisible=ParamOut.FieldTransform; 
2427    TransformName_Callback([],[], handles)
2428end
2429set(handles.FieldTransform,'Visible',FieldTransformVisible)
2430if isfield(ParamOut,'TransformPath')
2431    set(handles.ActionExt,'UserData',ParamOut.TransformPath)
2432else
2433    set(handles.ActionExt,'UserData',[])
2434end
2435
2436%% Visibility of projection object
2437ProjObjectVisible='off';  %hidden by default
2438if isfield(ParamOut,'ProjObject')
2439    ProjObjectVisible=ParamOut.ProjObject;
2440end
2441set(handles.CheckObject,'Visible',ProjObjectVisible)
2442if ~get(handles.CheckObject,'Value')
2443    ProjObjectVisible='off';
2444end
2445set(handles.ProjObject,'Visible',ProjObjectVisible)
2446set(handles.DeleteObject,'Visible',ProjObjectVisible)
2447set(handles.ViewObject,'Visible',ProjObjectVisible)
2448set(handles.EditObject,'Visible',ProjObjectVisible)
2449
2450%% Visibility of mask input
2451MaskVisible='off';  %hidden by default
2452if isfield(ParamOut,'Mask')
2453    MaskVisible=ParamOut.Mask;
2454end
2455set(handles.CheckMask,'Visible',MaskVisible);
2456
2457%% definition of the directory containing the output files
2458if  ~(isfield(SeriesData,'ActionName') && strcmp(ActionName,SeriesData.ActionName))
2459    OutputDirExt='.series'; %default
2460    if isfield(ParamOut,'OutputDirExt')&&~isempty(ParamOut.OutputDirExt)
2461        OutputDirExt=ParamOut.OutputDirExt;
2462    end
2463    set(handles.OutputDirExt,'String',OutputDirExt)
2464end
2465OutputDirVisible='off';
2466OutputSubDirMode='auto';%default
2467SubDirOut='';
2468if isfield(ParamOut,'OutputSubDirMode')
2469    OutputSubDirMode=ParamOut.OutputSubDirMode;
2470end
2471switch OutputSubDirMode
2472    case 'auto';%default
2473        OutputDirVisible='on';
2474        SubDir=InputTable(1:end,2); %set of subdirectories
2475        SubDirOut=SubDir{1};
2476        if numel(SubDir)>1
2477            for ilist=2:numel(SubDir)
2478                SubDirOut=[SubDirOut '-' regexprep(SubDir{ilist},'^/','')];
2479            end
2480        end
2481    case 'one'
2482        OutputDirVisible='on';
2483        SubDirOut=InputTable{1,2}; %use the first subdir name (+OutputDirExt) as output  subdirectory
2484    case 'two'
2485        OutputDirVisible='on';   
2486        SubDir=InputTable(1:2,2); %set of subdirectories
2487        SubDirOut=SubDir{1};
2488        if numel(SubDir)>1
2489                SubDirOut=[SubDirOut '-' regexprep(SubDir{2},'^/','')];
2490        end
2491    case 'last'
2492        OutputDirVisible='on';
2493        SubDirOut=InputTable{end,2}; %use the last subdir name (+OutputDirExt) as output  subdirectory
2494end
2495set(handles.OutputSubDir,'String',SubDirOut)
2496set(handles.OutputSubDir,'BackgroundColor',[1 1 1])% set edit box to white color to indicate refreshment
2497set(handles.OutputDirExt,'Visible',OutputDirVisible)
2498set(handles.OutputSubDir,'Visible',OutputDirVisible)
2499%set(handles.CheckOverwrite,'Visible',OutputDirVisible)
2500set(handles.OutputDir_title,'Visible',OutputDirVisible)
2501SeriesData.ActionName=ActionName;%record ActionName for next use
2502
2503
2504%% visibility of the run mode (local or background or cluster)
2505if strcmp(OutputSubDirMode,'none')
2506    RunModeVisible='off';% only local mode available if no output file is produced
2507else
2508    RunModeVisible='on';
2509end
2510set(handles.RunMode,'Visible',RunModeVisible)
2511set(handles.ActionExt,'Visible',RunModeVisible)
2512set(handles.RunMode_title,'Visible',RunModeVisible)
2513set(handles.ActionExt_title,'Visible',RunModeVisible)
2514
2515
2516%% Expected nbre of output files
2517if isfield(ParamOut,'OutputFileMode')
2518    StatusData.OutputFileMode=ParamOut.OutputFileMode;
2519    set(handles.status,'UserData',StatusData)
2520end
2521
2522%% definition of an additional parameter set, determined by an ancillary GUI
2523if isfield(ParamOut,'ActionInput')
2524    set(handles.ActionInput,'Visible','on')
2525    ParamOut.ActionInput.Program=ActionName; % record the program in ActionInput
2526    SeriesData.ActionInput=ParamOut.ActionInput;
2527else
2528    set(handles.ActionInput,'Visible','off')
2529    if isfield(SeriesData,'ActionInput')
2530        SeriesData=rmfield(SeriesData,'ActionInput');
2531    end
2532end
2533set(handles.series,'UserData',SeriesData)
2534set(handles.ActionName,'BackgroundColor',[1 1 1])
2535
2536%------------------------------------------------------------------------
2537% --- Executes on selection change in FieldName.
2538function FieldName_Callback(hObject, eventdata, handles)
2539%------------------------------------------------------------------------
2540field_str=get(handles.FieldName,'String');
2541field_index=get(handles.FieldName,'Value');
2542field=field_str{field_index(1)};
2543if isequal(field,'get_field...')
2544    SeriesData=get(handles.series,'UserData');
2545    % input line for which the field choice is relevant
2546    iview=find(ismember(SeriesData.FileType,{'netcdf','civx','civdata'}));% all nc files, icluding civ
2547    hget_field=findobj(allchild(0),'name','get_field');
2548    if ~isempty(hget_field)
2549        delete(hget_field)%delete opened versions of get_field
2550    end
2551    Param=read_GUI(handles.series);
2552    InputTable=Param.InputTable(iview,:);
2553    % check the existence of the first file in the series
2554    first_j=[];last_j=[];MinIndex_j=1;MaxIndex_j=1;%default setting for index j
2555    if isfield(Param.IndexRange,'first_j');% if index j is used     
2556        first_j=Param.IndexRange.first_j;
2557        last_j=Param.IndexRange.last_j;
2558        MinIndex_j=Param.IndexRange.MinIndex_j(iview);
2559        MaxIndex_j=Param.IndexRange.MaxIndex_j(iview);
2560    end
2561    PairString='';
2562    if isfield(Param.IndexRange,'PairString'); PairString=Param.IndexRange.PairString{iview}; end
2563    [i1,i2,j1,j2] = get_file_index(Param.IndexRange.first_i,first_j,PairString);
2564    LineIndex=iview(1);
2565    if numel(iview)>1     
2566        answer=msgbox_uvmat('INPUT_TXT',['select the line of the input table:' num2str(iview)] ,num2str(iview(1)));
2567        LineIndex=str2num(answer);
2568%         InputLine=str2num(get(handles.InputLine,'String'));
2569%         if ismember(InputLine,iview)
2570%             LineIndex=InputLine;
2571%         end
2572    end
2573    FirstFileName=fullfile_uvmat(InputTable{LineIndex,1},InputTable{LineIndex,2},InputTable{LineIndex,3},...
2574        InputTable{LineIndex,5},InputTable{LineIndex,4},i1,i2,j1,j2);
2575    if exist(FirstFileName,'file')
2576        ParamIn.Title='get_field: pick input variables and coordinates for series processing';
2577        ParamIn.SeriesInput=1;
2578        GetFieldData=get_field(FirstFileName,ParamIn);
2579        FieldList={};
2580        if isfield(GetFieldData,'FieldOption')% if a field has been selected
2581        switch GetFieldData.FieldOption
2582            case 'vectors'
2583                UName=GetFieldData.PanelVectors.vector_x;
2584                VName=GetFieldData.PanelVectors.vector_y;
2585                YName={GetFieldData.Coordinates.Coord_y};
2586                FieldList={['vec(' UName ',' VName ')'];...
2587                    ['norm(' UName ',' VName ')'];...
2588                    UName;VName};
2589            case {'scalar'}
2590                FieldList=GetFieldData.PanelScalar.scalar;
2591                YName={GetFieldData.Coordinates.Coord_y};
2592                if ischar(FieldList)
2593                    FieldList={FieldList};
2594                end
2595            case 'civdata...'
2596                FieldList=[set_field_list('U','V') ;{'C'}];
2597                set(handles.FieldName,'Value',1) % set menu to 'velocity
2598                XName='X';
2599                YName='y';
2600        end
2601        set(handles.FieldName,'Value',1)
2602        set(handles.FieldName,'String',[FieldList; {'get_field...'}]);
2603        if ~strcmp(GetFieldData.FieldOption,'civdata...')
2604           if ~isempty(regexp(FieldList{1},'^vec'))
2605                set(handles.FieldName,'Value',1)
2606           else
2607                set(handles.FieldName,'Value',1:numel(FieldList))%select all input fields by default
2608           end
2609            XName=GetFieldData.Coordinates.Coord_x;
2610            YName=GetFieldData.Coordinates.Coord_y;
2611            TimeNameStr=GetFieldData.Time.SwitchVarIndexTime;
2612            % get the time info                     
2613            TimeTable=get(handles.TimeTable,'Data');
2614            switch TimeNameStr
2615                case 'file index'
2616                    TimeName='';
2617                case 'attribute'
2618                    TimeName=['att:' GetFieldData.Time.TimeName];
2619                    % update the time table
2620                    TimeTable{LineIndex,2}=get_time(Param.IndexRange.MinIndex_i(LineIndex),MinIndex_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % Min time     
2621                    TimeTable{LineIndex,3}=get_time(Param.IndexRange.first_i,first_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % first time             
2622                    TimeTable{LineIndex,4}=get_time(Param.IndexRange.last_i,last_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % last time                     
2623                    TimeTable{LineIndex,5}=get_time(Param.IndexRange.MaxIndex_i(LineIndex),MaxIndex_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % Max time
2624                case 'variable'
2625                    set(handles.TimeName,'String',['var:' GetFieldData.Time.TimeName])
2626                    set(handles.NomType,'String','*')
2627                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])% A VERIFIER !!!!!!
2628                    set(handles.FileIndex,'String','')
2629                    ParamIn.TimeVarName=GetFieldData.Time.TimeName;
2630                case 'matrix_index'
2631                    TimeName=['dim:' GetFieldData.Time.TimeName];
2632                    set(handles.NomType,'String','*')
2633                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
2634                    set(handles.FileIndex,'String','')
2635                    ParamIn.TimeDimName=GetFieldData.Time.TimeName;
2636            end
2637            TimeTable{LineIndex,1}=TimeName;
2638            set(handles.TimeTable,'Data',TimeTable);
2639        end
2640        set(handles.Coord_x,'String',XName)
2641        set(handles.Coord_y,'String',YName)
2642        set(handles.Coord_x,'Visible','on')
2643        set(handles.Coord_y,'Visible','on')
2644        end
2645    else
2646        msgbox_uvmat('ERROR',[FirstFileName ' does not exist'])
2647    end
2648end
2649
2650function [TimeValue,DtValue]=get_time(ref_i,ref_j,PairString,InputTable,FileInfo,TimeName,DtName)
2651[i1,i2,j1,j2] = get_file_index(ref_i,ref_j,PairString);
2652FileName=fullfile_uvmat(InputTable{1},InputTable{2},InputTable{3},InputTable{5},InputTable{4},i1,i2,j1,j2);
2653Data=nc2struct(FileName,[]);
2654TimeValue=[];
2655DtValue=[];
2656if isequal(FileInfo.FileType,'civdata')
2657    if ismember(TimeName,{'civ1','filter1'})
2658        TimeValue=Data.Civ1_Time;
2659        DtValue=Data.Civ1_Dt;
2660    else
2661        TimeValue=Data.Civ2_Time;
2662        DtValue=Data.Civ2_Dt;
2663    end
2664else
2665    if ~isempty(TimeName)&& isfield(Data,TimeName)
2666        TimeValue=Data.(TimeName);
2667    end
2668    if exist('DtName','var') && isfield(Data,DtName)
2669        DtValue=Data.(DtName);
2670    end
2671end
2672
2673%------------------------------------------------------------------------
2674% --- Executes on selection change in FieldName_1.
2675function FieldName_1_Callback(hObject, eventdata, handles)
2676%------------------------------------------------------------------------
2677field_str=get(handles.FieldName_1,'String');
2678field_index=get(handles.FieldName_1,'Value');
2679field=field_str{field_index(1)};
2680if isequal(field,'get_field...')
2681    hget_field=findobj(allchild(0),'name','get_field');
2682    if ~isempty(hget_field)
2683        delete(hget_field)%delete opened versions of get_field
2684    end
2685    Param=read_GUI(handles.series);
2686    Param.InputTable=Param.InputTable(1,:);
2687    % check the existence of the first file in the series
2688    first_j=[];
2689    if isfield(Param.IndexRange,'first_j'); first_j=Param.IndexRange.first_j; end
2690    if isfield(Param.IndexRange,'last_j'); last_j=Param.IndexRange.last_j; end
2691    PairString='';
2692    if isfield(Param.IndexRange,'PairString'); PairString=Param.IndexRange.PairString; end
2693    [i1,i2,j1,j2] = get_file_index(Param.IndexRange.first_i,first_j,PairString);
2694    FirstFileName=fullfile_uvmat(Param.InputTable{1,1},Param.InputTable{1,2},Param.InputTable{1,3},...
2695        Param.InputTable{1,5},Param.InputTable{1,4},i1,i2,j1,j2);
2696    if exist(FirstFileName,'file')
2697        ParamIn.SeriesInput=1;
2698        GetFieldData=get_field(FirstFileName,ParamIn);
2699        FieldList={};
2700        switch GetFieldData.FieldOption
2701            case 'vectors'
2702                UName=GetFieldData.PanelVectors.vector_x;
2703                VName=GetFieldData.PanelVectors.vector_y;
2704                FieldList={['vec(' UName ',' VName ')'];...
2705                    ['norm(' UName ',' VName ')'];...
2706                    UName;VName};
2707            case {'scalar','pick variables'}
2708                FieldList=GetFieldData.PanelScalar.scalar;
2709                if ischar(FieldList)
2710                    FieldList={FieldList};
2711                end
2712            case '1D plot'
2713
2714            case 'civdata...'
2715                FieldList=set_field_list('U','V','C');
2716                set(handles.FieldName,'Value',2) % set menu to 'velocity
2717        end
2718        if ~strcmp(GetFieldData.FieldOption,'civdata...')
2719            TimeNameStr=GetFieldData.Time.SwitchVarIndexTime;
2720            switch TimeNameStr
2721                case 'file index'
2722                    set(handles.TimeName,'String','');
2723                case 'attribute'
2724                    set(handles.TimeName,'String',['att:' GetFieldData.Time.TimeName]);
2725                case 'variable'
2726                    set(handles.TimeName,'String',['var:' GetFieldData.Time.TimeName])
2727                    set(handles.NomType,'String','*')
2728                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])% A VERIFIER !!!!!!
2729                    set(handles.FileIndex,'String','')
2730                    ParamIn.TimeVarName=GetFieldData.Time.TimeName;
2731                case 'matrix_index'
2732                    set(handles.TimeName,'String',['dim:' GetFieldData.Time.TimeName]);
2733                    set(handles.NomType,'String','*')
2734                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
2735                    set(handles.FileIndex,'String','')
2736                    ParamIn.TimeDimName=GetFieldData.Time.TimeName;
2737            end
2738        end
2739        set(handles.FieldName_1,'Value',1)
2740        set(handles.FieldName_1,'String',[FieldList; {'get_field...'}]);
2741    end
2742end   
2743
2744
2745%%%%%%%%%%%%%
2746function [ind_remove]=find_pairs(dirpair,ind_i,last_i)
2747indsel=ind_i;
2748indiff=diff(ind_i); %test index increment to detect multiplets (several pairs with the same index ind_i) and holes in the series
2749indiff=[1 indiff last_i-ind_i(end)+1];%for testing gaps with the imposed bounds
2750if ~isempty(indiff)
2751    indiff2=diff(indiff);
2752    indiffp=[indiff2 1];
2753    indiffm=[1 indiff2];
2754    ind_multi_m=find((indiff==0)&(indiffm<0))-1;%indices of first members of multiplets
2755    ind_multi_p=find((indiff==0)&(indiffp>0));%indices of last members of multiplets
2756    %for each multiplet, select the most recent file
2757    ind_remove=[];
2758    for i=1:length(ind_multi_m)
2759        ind_pairs=ind_multi_m(i):ind_multi_p(i);
2760        for imulti=1:length(ind_pairs)
2761            datepair(imulti)=datenum(dirpair(ind_pairs(imulti)).date);%dates of creation
2762        end
2763        [datenew,indsort2]=sort(datepair); %sort the multiplet by creation date
2764        ind_s=indsort2(1:end-1);%
2765        ind_remove=[ind_remove ind_pairs(ind_s)];%remove these indices, leave the last one
2766    end
2767end
2768
2769%------------------------------------------------------------------------
2770% --- determine the list of index pairstring of processing file
2771function [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)
2772%------------------------------------------------------------------------
2773num_i1=num_i;% set of first image numbers by default
2774num_i2=num_i;
2775num_j1=num_j;
2776num_j2=num_j;
2777num_i_out=num_i;
2778num_j_out=num_j;
2779% if isequal (NomType,'_1-2_1') || isequal (NomType,'_1-2')
2780if isequal(mode,'series(Di)')
2781    num_i1_line=num_i+ind_shift(3);% set of first image numbers
2782    num_i2_line=num_i+ind_shift(4);
2783    % adjust the first and last field number
2784        indsel=find(num_i1_line >= 1);
2785    num_i_out=num_i(indsel);
2786    num_i1_line=num_i1_line(indsel);
2787    num_i2_line=num_i2_line(indsel);
2788    num_j1=meshgrid(num_j,ones(size(num_i1_line)));
2789    num_j2=meshgrid(num_j,ones(size(num_i1_line)));
2790    [xx,num_i1]=meshgrid(num_j,num_i1_line);
2791    [xx,num_i2]=meshgrid(num_j,num_i2_line);
2792elseif isequal (mode,'series(Dj)')||isequal (mode,'bursts')
2793    if isequal(mode,'bursts') %case of bursts (png_old or png_2D)
2794        num_j1=ind_shift(1)*ones(size(num_i));
2795        num_j2=ind_shift(2)*ones(size(num_i));
2796    else
2797        num_j1_col=num_j+ind_shift(1);% set of first image numbers
2798        num_j2_col=num_j+ind_shift(2);
2799        % adjust the first field number
2800        indsel=find((num_j1_col >= 1));   
2801        num_j_out=num_j(indsel);
2802        num_j1_col=num_j1_col(indsel);
2803        num_j2_col=num_j2_col(indsel);
2804        [num_i1,num_j1]=meshgrid(num_i,num_j1_col);
2805        [num_i2,num_j2]=meshgrid(num_i,num_j2_col);
2806    end   
2807end
2808
2809%------------------------------------------------------------------------
2810% --- Executes on button press in CheckObject.
2811function CheckObject_Callback(hObject, eventdata, handles)
2812%------------------------------------------------------------------------
2813hset_object=findobj(allchild(0),'tag','set_object');%find the set_object interface handle
2814if get(handles.CheckObject,'Value')
2815    SeriesData=get(handles.series,'UserData');
2816    if isfield(SeriesData,'ProjObject') && ~isempty(SeriesData.ProjObject)
2817        set(handles.ViewObject,'Value',1)
2818        ViewObject_Callback(hObject, eventdata, handles)
2819    else
2820        if ishandle(hset_object)
2821            uistack(hset_object,'top')% show the GUI set_object if opened
2822        else
2823            %get the object file
2824            InputTable=get(handles.InputTable,'Data');
2825            defaultname=InputTable{1,1};
2826            if isempty(defaultname)
2827                defaultname={''};
2828            end
2829            fileinput=uigetfile_uvmat('pick a xml object file (or use uvmat to create it)',defaultname,'.xml');
2830            if isempty(fileinput)% exit if no object file is selected
2831                set(handles.CheckObject,'Value',0)
2832                return
2833            end
2834            %read the file
2835            data=xml2struct(fileinput);
2836            if ~isfield(data,'Type')
2837                msgbox_uvmat('ERROR',[fileinput ' is not an object xml file'])
2838                set(handles.CheckObject,'Value',0)
2839                return
2840            end
2841            if ~isfield(data,'ProjMode')
2842                data.ProjMode='none';
2843            end
2844            hset_object=set_object(data);% call the set_object interface
2845            set(hset_object,'Name','set_object_series')% name to distinguish from set_object used with uvmat
2846        end
2847        ProjObject=read_GUI(hset_object);
2848        set(handles.ProjObject,'String',ProjObject.Name);%display the object name
2849        SeriesData=get(handles.series,'UserData');
2850        SeriesData.ProjObject=ProjObject;
2851        set(handles.series,'UserData',SeriesData);
2852    end
2853    set(handles.EditObject,'Visible','on');
2854    set(handles.DeleteObject,'Visible','on');
2855    set(handles.ViewObject,'Visible','on');
2856    set(handles.ProjObject,'Visible','on');
2857else
2858    set(handles.EditObject,'Visible','off');
2859    set(handles.DeleteObject,'Visible','off');
2860    set(handles.ViewObject,'Visible','off');
2861    if ~ishandle(hset_object)
2862        set(handles.ViewObject,'Value',0);
2863    end
2864    set(handles.ProjObject,'Visible','off');
2865end
2866
2867%------------------------------------------------------------------------
2868% --- Executes on button press in ViewObject.
2869%------------------------------------------------------------------------
2870function ViewObject_Callback(hObject, eventdata, handles)
2871
2872UserData=get(handles.series,'UserData');
2873hset_object=findobj(allchild(0),'Tag','set_object');
2874if ~isempty(hset_object)
2875    delete(hset_object)% refresh set_object if already opened
2876end
2877hset_object=set_object(UserData.ProjObject);
2878set(hset_object,'Name','view_object_series')
2879
2880
2881%------------------------------------------------------------------------
2882% --- Executes on button press in EditObject.
2883function EditObject_Callback(hObject, eventdata, handles)
2884%------------------------------------------------------------------------
2885if get(handles.EditObject,'Value')
2886    set(handles.ViewObject,'Value',0)
2887        UserData=get(handles.series,'UserData');
2888    hset_object=set_object(UserData.ProjObject);
2889    set(hset_object,'Name','edit_object_series')
2890    set(get(hset_object,'Children'),'Enable','on')
2891else
2892    hset_object=findobj(allchild(0),'Tag','set_object');
2893    if ~isempty(hset_object)
2894        set(get(hset_object,'Children'),'Enable','off')
2895    end
2896end
2897
2898%------------------------------------------------------------------------
2899% --- Executes on button press in DeleteObject.
2900function DeleteObject_Callback(hObject, eventdata, handles)
2901%------------------------------------------------------------------------
2902SeriesData=get(handles.series,'UserData');
2903SeriesData.ProjObject=[];
2904set(handles.series,'UserData',SeriesData)
2905set(handles.ProjObject,'String','')
2906set(handles.ProjObject,'Visible','off')
2907set(handles.CheckObject,'Value',0)
2908set(handles.ViewObject,'Visible','off')
2909set(handles.EditObject,'Visible','off')
2910hset_object=findobj(allchild(0),'name','set_object_series');
2911if ~isempty(hset_object)
2912    delete(hset_object)
2913end
2914set(handles.DeleteObject,'Visible','off')
2915
2916%------------------------------------------------------------------------
2917% --- Executed when CheckMask is activated
2918%------------------------------------------------------------------------
2919function CheckMask_Callback(hObject, eventdata, handles)
2920
2921if get(handles.CheckMask,'Value')
2922    InputTable=get(handles.InputTable,'Data');
2923    nbview=size(InputTable,1);
2924    MaskTable=cell(nbview,1);%default
2925    ListMask=cell(nbview,1);%default
2926    MaskData=get(handles.MaskTable,'Data');
2927    MaskData(size(MaskData,1):nbview,1)=cell(size(MaskData,1):nbview,1);%complement if undefined lines
2928    for iview=1:nbview
2929        ListMask{iview,1}=num2str(iview);
2930        RootPath=InputTable{iview,1};
2931        if ~isempty(RootPath)
2932            if isempty(MaskData{iview})
2933                SubDir=InputTable{iview,2};
2934                MaskPath=fullfile(RootPath,[regexprep(SubDir,'\..*','') '.mask']);%take the root part of SubDir, before the first dot '.'
2935                if exist(MaskPath,'dir')
2936                    ListStruct=dir(MaskPath);%look for a mask file
2937                    ListCells=struct2cell(ListStruct);% transform dir struct to a cell arrray
2938                    check_dir=cell2mat(ListCells(4,:));% =1 for directories, =0 for files
2939                    ListFiles=ListCells(1,:);%list of file and dri names
2940                    ListFiles=ListFiles(~check_dir);%list of file names (excluding dir)
2941                    mdetect=0;
2942                    if ~isempty(ListFiles)
2943                        for ifile=1:numel(ListFiles)
2944                            [tild,tild,MaskFile{ifile},i1_series,i2_series,j1_series,j2_series,MaskNomType,MaskFileType]=find_file_series(MaskPath,ListFiles{ifile},0);
2945                            if strcmp(MaskFileType,'image') && isempty(i2_series) && isempty(j2_series)
2946                                mdetect=1;
2947                                MaskName=ListFiles{ifile};
2948                            end
2949                            if ~strcmp(MaskFile{ifile},MaskFile{1})
2950                                mdetect=0;% cancel detection test in case of multiple masks, use the brower for selection
2951                                break
2952                            end
2953                        end
2954                    end
2955                    if mdetect==1
2956                        MaskName=fullfile(MaskPath,'mask_1.png');
2957                    else
2958                        MaskName=uigetfile_uvmat('select a mask file:',MaskPath,'image');
2959                    end
2960                else
2961                    MaskName=uigetfile_uvmat('select a mask file:',RootPath,'image');
2962                end
2963                MaskTable{iview,1}=MaskName ;
2964                ListMask{iview,1}=num2str(iview);
2965            end
2966        end
2967    end
2968    set(handles.MaskTable,'Data',MaskTable)
2969    set(handles.MaskTable,'Visible','on')
2970    set(handles.MaskBrowse,'Visible','on')
2971    set(handles.ListMask,'Visible','on')
2972    set(handles.ListMask,'String',ListMask)
2973    set(handles.ListMask,'Value',1)
2974else
2975    set(handles.MaskTable,'Visible','off')
2976    set(handles.MaskBrowse,'Visible','off')
2977    set(handles.ListMask,'Visible','off')
2978end
2979
2980%------------------------------------------------------------------------
2981% --- Executes on button press in MaskBrowse.
2982%------------------------------------------------------------------------
2983function MaskBrowse_Callback(hObject, eventdata, handles)
2984
2985InputTable=get(handles.InputTable,'Data');
2986iview=get(handles.ListMask,'Value');
2987RootPath=InputTable{iview,1};
2988MaskName=uigetfile_uvmat('select a mask file:',RootPath,'image');
2989if ~isempty(MaskName)
2990    MaskTable=get(handles.MaskTable,'Data');
2991    MaskTable{iview,1}=MaskName ;
2992    set(handles.MaskTable,'Data',MaskTable)
2993end
2994
2995%------------------------------------------------------------------------
2996% --- Executes when selected cell(s) is changed in MaskTable.
2997%------------------------------------------------------------------------
2998function MaskTable_CellSelectionCallback(hObject, eventdata, handles)
2999
3000if numel(eventdata.Indices)>=1
3001set(handles.ListMask,'Value',eventdata.Indices(1))
3002end
3003
3004%-------------------------------------------------------------------
3005function MenuHelp_Callback(hObject, eventdata, handles)
3006%-------------------------------------------------------------------
3007
3008
3009% path_to_uvmat=which ('uvmat');% check the path of uvmat
3010% pathelp=fileparts(path_to_uvmat);
3011% helpfile=fullfile(pathelp,'uvmat_doc','uvmat_doc.html');
3012% if isempty(dir(helpfile)), msgbox_uvmat('ERROR','Please put the help file uvmat_doc.html in the sub-directory /uvmat_doc of the UVMAT package')
3013% else
3014%     addpath (fullfile(pathelp,'uvmat_doc'))
3015%     web([helpfile '#series'])
3016% end
3017
3018%-------------------------------------------------------------------
3019% --- Executes on selection change in TransformName.
3020function TransformName_Callback(hObject, eventdata, handles)
3021%----------------------------------------------------------------------
3022TransformList=get(handles.TransformName,'String');
3023TransformIndex=get(handles.TransformName,'Value');
3024TransformName=TransformList{TransformIndex};
3025TransformPathList=get(handles.TransformName,'UserData');
3026nb_builtin_transform=4;
3027if isequal(TransformName,'more...');     
3028    FileName=uigetfile_uvmat('Pick a transform function',get(handles.TransformPath,'String'),'.m');
3029    if isempty(FileName)
3030        return     %browser closed without choice
3031    end
3032    [TransformPath,TransformName,TransformExt]=fileparts(FileName);% removes extension .m
3033    if ~strcmp(TransformExt,'.m')
3034        msgbox_uvmat('ERROR','a Matlab function .m must be introduced');
3035        return
3036    end
3037     % insert the choice in the menu
3038    TransformIndex=find(strcmp(TransformName,TransformList),1);% look for the selected function in the menu Action
3039    if isempty(TransformIndex)%the input string does not exist in the menu
3040        TransformIndex= length(TransformList);
3041        TransformList=[TransformList(1:end-1);{TransformName};TransformList(end)];% the selected function is appended in the menu, before the last item 'more...'
3042        set(handles.TransformName,'String',TransformList)
3043        TransformPathList=[TransformPathList;{TransformPath}];
3044    else% the input function already exist, we update its path (possibly new)
3045        TransformPathList{TransformIndex}=TransformPath;%
3046        set(handles.TransformName,'Value',TransformIndex)
3047    end
3048   % save the new menu in the personal file 'uvmat_perso.mat'
3049   dir_perso=prefdir;%personal Matalb directory
3050   profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
3051   if exist(profil_perso,'file')
3052       for ilist=nb_builtin_transform+1:numel(TransformPathList)
3053           TransformListUser{ilist-nb_builtin_transform}=TransformList{ilist};
3054           TransformPathListUser{ilist-nb_builtin_transform}=TransformPathList{ilist};
3055       end
3056       TransformPathListUser=TransformPathListUser';
3057       TransformListUser=TransformListUser';
3058       save (profil_perso,'TransformPathListUser','TransformListUser','-append'); %store the root name for future opening of uvmat
3059   end
3060end
3061
3062%display the current function path
3063set(handles.TransformPath,'String',TransformPathList{TransformIndex}); %show the path to the senlected function
3064set(handles.TransformName,'UserData',TransformPathList);
3065
3066%% create the function handle of the selected fct
3067if ~isempty(TransformName)
3068    if ~exist(TransformPathList{TransformIndex},'dir')
3069        msgbox_uvmat('ERROR',['The prescribed transform function path ' TransformPathList{TransformIndex} ' does not exist']);
3070        return
3071    end
3072    current_dir=pwd;%current working dir
3073    cd(TransformPathList{TransformIndex})
3074    transform_handle=str2func(TransformName);
3075    cd(current_dir)
3076    Field.Action.RUN=0;% indicate that the transform fct is called only to get input param
3077    DataOut=feval(transform_handle,Field,[]);% execute the transform fct to get the required conditions
3078    if isfield(DataOut,'TransformInput')%  used to add transform parameters at selection of the transform fct
3079        SeriesData=get(handles.series,'UserData');
3080        SeriesData.TransformInput=DataOut.TransformInput;
3081        set(handles.series,'UserData',SeriesData)
3082    end
3083end
3084
3085%------------------------------------------------------------------------
3086% --- fct activated by the upper bar menu ExportConfig
3087%------------------------------------------------------------------------
3088function MenuDisplayConfig_Callback(hObject, eventdata, handles)
3089
3090global Param
3091Param=read_GUI_series(handles);
3092evalin('base','global Param')%make CurData global in the workspace
3093display('current series config :')
3094evalin('base','Param') %display CurData in the workspace
3095commandwindow; %brings the Matlab command window to the front
3096
3097%------------------------------------------------------------------------
3098% --- fct activated by the upper bar menu InportConfig: import
3099%     menu settings from an xml file (stored in /0_XML for each run)
3100%------------------------------------------------------------------------
3101function MenuImportConfig_Callback(hObject, eventdata, handles)
3102
3103%% use a browser to choose the xml file containing the processing config
3104InputTable=get(handles.InputTable,'Data');
3105oldfile=InputTable{1,1};%current path in InputTable
3106if isempty(oldfile)
3107    % use a file name stored in prefdir
3108    dir_perso=prefdir;
3109    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
3110    if exist(profil_perso,'file')
3111        h=load (profil_perso);
3112        if isfield(h,'RootPath') && ischar(h.RootPath)
3113            oldfile=h.RootPath;
3114        end
3115    end
3116end
3117filexml=uigetfile_uvmat('pick a xml parameter file',oldfile,'.xml');% get the xml file containing processing parameters
3118if isempty(filexml), return, end % quit function if an xml file has not been opened
3119
3120%% fill the GUI series with the content of the xml file
3121Param=xml2struct(filexml);% read the input xml file as a Matlab structure
3122
3123% ask to stop current Action if button RUN is in action (another process is already running)
3124if isequal(get(handles.RUN,'Value'),1)
3125    answer= msgbox_uvmat('INPUT_Y-N','stop current Action process?');
3126    if strcmp(answer,'Yes')
3127        STOP_Callback(hObject, eventdata, handles)
3128    else
3129        return
3130    end
3131end
3132Param.Action.RUN=0; %desactivate the input RUN=1
3133
3134fill_GUI(Param,handles.series)% fill the elements of the GUI series with the input parameters
3135SeriesData=get(handles.series,'UserData');
3136if isfield(Param,'InputFields')
3137    ListField=Param.InputFields.FieldName;
3138    if ischar(ListField),ListField={ListField}; end
3139    set(handles.FieldName,'String',[ListField;{'get-field...'}])
3140     set(handles.FieldName,'Value',1:numel(ListField))
3141     set(handles.FieldName,'Visible','on')
3142end       
3143if isfield(Param,'ActionInput')%  introduce  parameters specific to an Action fct, for instance PIV parameters
3144    set(handles.ActionInput,'Visible','on')
3145    set(handles.ActionInput,'Value',0)
3146    Param.ActionInput.ConfigSource=filexml;% record the source of config for future info
3147    SeriesData.ActionInput=Param.ActionInput;
3148end
3149if isfield(Param,'TransformInput')%  introduce  parameters specific to a transform fct
3150    SeriesData.TransformInput=Param.TransformInput;
3151end
3152if isfield(Param,'ProjObject') %introduce projection object if relevant
3153    SeriesData.ProjObject=Param.ProjObject;
3154end
3155set(handles.series,'UserData',SeriesData)
3156if isfield(Param,'CheckObject') && isequal(Param.CheckObject,1)
3157    set(handles.ProjObject,'String',Param.ProjObject.Name)
3158    set(handles.ViewObject,'Visible','on')
3159    set(handles.EditObject,'Visible','on')
3160    set(handles.DeleteObject,'Visible','on')
3161else     
3162    set(handles.ProjObject,'String','')
3163    set(handles.ProjObject,'Visible','off')
3164    set(handles.ViewObject,'Visible','off')
3165    set(handles.EditObject,'Visible','off')
3166    set(handles.DeleteObject,'Visible','off')     
3167end     
3168set(handles.REFRESH,'BackgroundColor',[1 0 1]); %paint REFRESH button in magenta to indicate that it should be activated
3169
3170
3171%------------------------------------------------------------------------
3172% --- Executes when the GUI series is resized.
3173%------------------------------------------------------------------------
3174function series_ResizeFcn(hObject, eventdata, handles)
3175
3176%% input table
3177set(handles.InputTable,'Unit','pixel')
3178Pos=get(handles.InputTable,'Position');
3179set(handles.InputTable,'Unit','normalized')
3180ColumnWidth=round([0.5 0.14 0.14 0.14 0.08]*(Pos(3)-52));
3181ColumnWidth=num2cell(ColumnWidth);
3182set(handles.InputTable,'ColumnWidth',ColumnWidth)
3183
3184%% MinIndex_j and MaxIndex_i
3185unit=get(handles.MinIndex_i,'Unit');
3186set(handles.MinIndex_i,'Unit','pixel')
3187Pos=get(handles.MinIndex_i,'Position');
3188set(handles.MinIndex_i,'Unit',unit)
3189set(handles.MinIndex_i,'ColumnWidth',{Pos(3)-18})
3190set(handles.MaxIndex_i,'ColumnWidth',{Pos(3)-18})
3191set(handles.MinIndex_j,'ColumnWidth',{Pos(3)-18})
3192set(handles.MaxIndex_j,'ColumnWidth',{Pos(3)-18})
3193
3194%% TimeTable
3195set(handles.TimeTable,'Unit','pixel')
3196Pos=get(handles.TimeTable,'Position');
3197set(handles.TimeTable,'Unit','normalized')
3198% ColumnWidth=get(handles.TimeTable,'ColumnWidth');
3199ColumnWidth=num2cell(floor([0.2 0.2 0.2 0.2 0.2]*(Pos(3)-20)));
3200set(handles.TimeTable,'ColumnWidth',ColumnWidth)
3201
3202
3203%% PairString
3204set(handles.PairString,'Unit','pixel')
3205Pos=get(handles.PairString,'Position');
3206set(handles.PairString,'Unit','normalized')
3207set(handles.PairString,'ColumnWidth',{Pos(3)-5})
3208
3209%% MaskTable
3210set(handles.MaskTable,'Unit','pixel')
3211Pos=get(handles.MaskTable,'Position');
3212set(handles.MaskTable,'Unit','normalized')
3213set(handles.MaskTable,'ColumnWidth',{Pos(3)-5})
3214
3215%------------------------------------------------------------------------
3216% --- Executes on button press in status.
3217%------------------------------------------------------------------------
3218function status_Callback(hObject, eventdata, handles)
3219
3220if get(handles.status,'Value')
3221    set(handles.status,'BackgroundColor',[1 1 0])
3222    drawnow
3223    Param=read_GUI(handles.series);
3224    RootPath=Param.InputTable{1,1};
3225    if ~isfield(Param,'OutputSubDir')   
3226        msgbox_uvmat('ERROR','no standard sub-directory definition for output files, use a browser to check the output')
3227        set(handles.status,'BackgroundColor',[0 1 0])
3228        return
3229    end
3230    OutputSubDir=[Param.OutputSubDir Param.OutputDirExt];% subdirectory for output files
3231    OutputDir=fullfile(RootPath,OutputSubDir);
3232    if exist(OutputDir,'dir')
3233        uigetfile_uvmat('status_display',OutputDir)
3234    else
3235        msgbox_uvmat('ERROR','output folder not created yet: calculation did not start')
3236        set(handles.status,'BackgroundColor',[0 1 0])
3237    end
3238else
3239    %% delete current display fig if selection is off
3240    set(handles.status,'BackgroundColor',[0 1 0])
3241    hfig=findobj(allchild(0),'name','status_display');
3242    if ~isempty(hfig)
3243        delete(hfig)
3244    end
3245    return
3246end
3247
3248
3249%------------------------------------------------------------------------   
3250% launched by selecting a file on the list
3251%------------------------------------------------------------------------
3252function view_file(hObject, eventdata)
3253
3254list=get(hObject,'String');
3255index=get(hObject,'Value');
3256rootroot=get(hObject,'UserData');
3257selectname=list{index};
3258ind_dot=regexp(selectname,'\.\.\.');
3259if ~isempty(ind_dot)
3260    selectname=selectname(1:ind_dot-1);
3261end
3262FullSelectName=fullfile(rootroot,selectname);
3263if exist(FullSelectName,'dir')% a directory has been selected
3264    ListFiles=dir(FullSelectName);
3265    ListDisplay=cell(numel(ListFiles),1);
3266    for ilist=2:numel(ListDisplay)% suppress the first line '.'
3267        ListDisplay{ilist-1}=ListFiles(ilist).name;
3268    end
3269    set(hObject,'Value',1)
3270    set(hObject,'String',ListDisplay)
3271    if strcmp(selectname,'..')
3272        FullSelectName=fileparts(fileparts(FullSelectName));
3273    end
3274    set(hObject,'UserData',FullSelectName)
3275    hfig=get(hObject,'parent');
3276    htitlebox=findobj(hfig,'tag','titlebox');   
3277    set(htitlebox,'String',FullSelectName)
3278elseif exist(FullSelectName,'file')%visualise the vel field if it exists
3279    FileInfo=get_file_info(FullSelectName);   
3280    if strcmp(FileInfo.FileType,'txt')
3281        edit(FullSelectName)
3282    elseif strcmp(FileInfo.FileType,'xml')
3283        editxml(FullSelectName)
3284    else
3285        uvmat(FullSelectName)
3286    end
3287    set(gcbo,'Value',1)
3288end
3289
3290
3291%------------------------------------------------------------------------   
3292% launched by refreshing the status figure
3293%------------------------------------------------------------------------
3294function refresh_GUI(hfig)
3295
3296htitlebox=findobj(hfig,'tag','titlebox');
3297hlist=findobj(hfig,'tag','list');
3298hseries=findobj(allchild(0),'tag','series');
3299hstatus=findobj(hseries,'tag','status');
3300StatusData=get(hstatus,'UserData');
3301OutputDir=get(htitlebox,'String');
3302if ischar(OutputDir),OutputDir={OutputDir};end
3303ListFiles=dir(OutputDir{1});
3304if numel(ListFiles)<1
3305    return
3306end
3307ListFiles(1)=[];%removes the first line ='.'
3308ListDisplay=cell(numel(ListFiles),1);
3309testrecent=0;
3310datnum=zeros(numel(ListDisplay),1);
3311for ilist=1:numel(ListDisplay)
3312    ListDisplay{ilist}=ListFiles(ilist).name;
3313      if ~ListFiles(ilist).isdir && isfield(ListFiles(ilist),'datenum')
3314            datnum(ilist)=ListFiles(ilist).datenum;%only available in recent matlab versions
3315            testrecent=1;
3316       end
3317end
3318set(hlist,'String',ListDisplay)
3319
3320%% Look at date of creation
3321ListDisplay=ListDisplay(datnum~=0);
3322datnum=datnum(datnum~=0);%keep the non zero values corresponding to existing files
3323NbOutputFile=[];
3324if isempty(datnum)
3325    if testrecent
3326        message='no civ result created yet';
3327    else
3328        message='';
3329    end
3330else
3331    [first,indfirst]=min(datnum);
3332    [last,indlast]=max(datnum);
3333    NbOutputFile_str='?';
3334    NbOutputFile=[];
3335    if isfield(StatusData,'NbOutputFile')
3336        NbOutputFile=StatusData.NbOutputFile;
3337        NbOutputFile_str=num2str(NbOutputFile);
3338    end
3339    message={[num2str(numel(datnum)) ' file(s) done over ' NbOutputFile_str] ;['oldest modification:  ' ListDisplay{indfirst} ' : ' datestr(first)];...
3340        ['latest modification:  ' ListDisplay{indlast} ' : ' datestr(last)]};
3341end
3342set(htitlebox,'String', [OutputDir{1};message])
3343
3344%% update the waitbar
3345hwaitbar=findobj(hfig,'tag','waitbar');
3346if ~isempty(NbOutputFile)
3347    BarPosition=get(hwaitbar,'Position');
3348    BarPosition(3)=0.9*numel(datnum)/NbOutputFile;
3349    set(hwaitbar,'Position',BarPosition)
3350end
3351
3352%------------------------------------------------------------------------
3353% --- Executes on selection change in ActionExt.
3354%------------------------------------------------------------------------
3355function ActionExt_Callback(hObject, eventdata, handles)
3356
3357ActionExtList=get(handles.ActionExt,'String');
3358ActionExt=ActionExtList{get(handles.ActionExt,'Value')};
3359if strcmp(ActionExt,'.py (in dev.)')
3360    set(handles.RunMode,'Value',2)
3361end
3362
3363%function num_NbProcess_Callback(hObject, eventdata, handles)
3364
3365
3366function num_NbSlice_Callback(hObject, eventdata, handles)
3367NbSlice=str2num(get(handles.num_NbSlice,'String'));
3368%set(handles.num_NbProcess,'String',num2str(NbSlice))
3369
3370%------------------------------------------------------------------------
3371% --- set the visibility of relevant velocity type menus:
3372function menu=set_veltype_display(Civ,FileType)
3373%------------------------------------------------------------------------
3374if ~exist('FileType','var')
3375    FileType='civx';
3376end
3377switch FileType
3378    case 'civx'
3379        menu={'civ1';'interp1';'filter1';'civ2';'interp2';'filter2'};
3380        if isequal(Civ,0)
3381            imax=0;
3382        elseif isequal(Civ,1) || isequal(Civ,2)
3383            imax=1;
3384        elseif isequal(Civ,3)
3385            imax=3;
3386        elseif isequal(Civ,4) || isequal(Civ,5)
3387            imax=4;
3388        elseif isequal(Civ,6) %patch2
3389            imax=6;
3390        end
3391    case 'civdata'
3392        menu={'civ1';'filter1';'civ2';'filter2'};
3393        if isequal(Civ,0)
3394            imax=0;
3395        elseif isequal(Civ,1) || isequal(Civ,2)
3396            imax=1;
3397        elseif isequal(Civ,3)
3398            imax=2;
3399        elseif isequal(Civ,4) || isequal(Civ,5)
3400            imax=3;
3401        else%if isequal(Civ,6) %patch2
3402            imax=4;
3403        end
3404end
3405menu=menu(1:imax);
3406
3407
3408% --- Executes on mouse motion over figure - except title and menu.
3409function series_WindowButtonMotionFcn(hObject, eventdata, handles)
3410set(hObject,'Pointer','arrow');
3411
3412
3413% --- Executes on button press in SetPairs.
3414function SetPairs_Callback(hObject, iview, handles)
3415
3416%% delete previous occurrence of 'set_pairs'
3417hfig=findobj(allchild(0),'Tag','set_pairs');
3418if ~isempty(hfig)
3419delete(hfig)
3420end
3421
3422%% create the GUI set_pairs
3423set(0,'Unit','points')
3424ScreenSize=get(0,'ScreenSize');% get the size of the screen, to put the fig on the upper right
3425Width=220;% fig width in points (1/72 inch)
3426Height=min(0.8*ScreenSize(4),300);
3427Left=ScreenSize(3)- Width-40; %right edge close to the right, with margin=40
3428Bottom=ScreenSize(4)-Height-40; %put fig at top right
3429hfig=findobj(allchild(0),'Tag','set_slice');
3430if ~isempty(hfig),delete(hfig), end; %delete existing version of the GUI
3431hfig=figure('name','set_pairs','tag','set_pairs','MenuBar','none','NumberTitle','off','Unit','points','Position',[Left,Bottom,Width,Height]);
3432BackgroundColor=get(hfig,'Color');
3433SeriesData=get(handles.series,'UserData');
3434TimeUnit=get(handles.TimeUnit,'String');
3435PairString=get(handles.PairString,'Data');
3436ListViewLines=find(cellfun('isempty',PairString)==0);%find list of non empty pairs
3437ListViewMenu=cell(numel(ListViewLines),1);
3438for ilist=1:numel(ListViewLines)
3439    ListViewMenu{ilist}=num2str(ListViewLines(ilist));
3440end
3441if isempty(iview)
3442    ListViewValue=numel(ListViewLines);% we work by default on the pair option for the last line which requires pairs
3443    iview=ListViewLines(end);
3444else
3445    ListViewValue=find(ListViewLines==iview);
3446end
3447ref_i=str2num(get(handles.num_first_i,'String'));
3448ref_j=1;%default
3449if strcmp(get(handles.num_first_j,'String'),'Visible')
3450    ref_j=str2num(get(handles.num_first_j,'String'));
3451end
3452[ModeMenu,ModeValue]=update_mode(SeriesData.i1_series{iview},SeriesData.i2_series{iview},SeriesData.j2_series{iview});
3453displ_pair=update_listpair(SeriesData.i1_series{iview},SeriesData.i2_series{iview},SeriesData.j1_series{iview},SeriesData.j2_series{iview},ModeMenu{ModeValue},...
3454                                                     SeriesData.Time{iview},TimeUnit,ref_i,ref_j,SeriesData.FileInfo{iview});
3455% first raw of the GUI
3456uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.88 0.5 0.1],'BackgroundColor',BackgroundColor,...
3457    'String','row to edit #','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','right');%title
3458uicontrol('Style','popupmenu','Units','normalized', 'Position', [0.54 0.8 0.3 0.2],'BackgroundColor',[1 1 1],...
3459    'Callback',@(hObject,eventdata)ListView_Callback(hObject,eventdata),'String',ListViewMenu,'Value',ListViewValue,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3460    'Tag','ListView','TooltipString','''ListView'':choice of the file series w for pair display');
3461% second raw of the GUI
3462uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.79 0.7 0.1],'BackgroundColor',BackgroundColor,...
3463    'String','mode of index pairing:','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','left');%title
3464uicontrol('Style','popupmenu','Units','normalized', 'Position', [0.05 0.62 0.9 0.2],'BackgroundColor',[1 1 1],...
3465    'Callback',@(hObject,eventdata)Mode_Callback(hObject,eventdata),'String',ModeMenu,'Value',ModeValue,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3466    'Tag','Mode','TooltipString','''Mode'': choice of the image pair mode');
3467% third raw
3468uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.6 0.7 0.1],'BackgroundColor',BackgroundColor,...
3469    'String','pair choice:','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','left');%title
3470uicontrol('Style','listbox','Units','normalized', 'Position', [0.05 0.42 0.9 0.2],'BackgroundColor',[1 1 1],...
3471    'Callback',@(hObject,eventdata)ListPair_Callback(hObject,eventdata),'String',displ_pair,'Value',1,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3472    'Tag','ListPair','TooltipString','''ListPair'': menu for selecting the image pair');
3473uicontrol('Style','text','Units','normalized', 'Position', [0.1 0.22 0.8 0.1],'BackgroundColor',BackgroundColor,...
3474    'String','ref_i           ref_j','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','center');%title
3475uicontrol('Style','edit','Units','normalized', 'Position', [0.15 0.17 0.3 0.08],'BackgroundColor',[1 1 1],...
3476    'Callback',@(hObject,eventdata)num_ref_i_Callback(hObject,eventdata),'String',num2str(ref_i),'FontUnits','points','FontSize',12,'FontWeight','bold',...
3477    'Tag','num_ref_i','TooltipString','''num_ref_i'': reference field index i used to display dt in ''list_pair_civ''');
3478uicontrol('Style','edit','Units','normalized', 'Position', [0.55 0.17 0.3 0.08],'BackgroundColor',[1 1 1],...
3479    'Callback',@(hObject,eventdata)num_ref_j_Callback(hObject,eventdata),'String',num2str(ref_j),'FontUnits','points','FontSize',12,'FontWeight','bold',...
3480    'Tag','num_ref_j','TooltipString','''num_ref_j'': reference field index i used to display dt in ''list_pair_civ''');
3481uicontrol('Style','pushbutton','Units','normalized', 'Position', [0.01 0.01 0.3 0.12],'BackgroundColor',[0 1 0],...
3482    'Callback',@(hObject,eventdata)OK_Callback(hObject,eventdata),'String','OK','FontUnits','points','FontSize',12,'FontWeight','bold',...
3483    'Tag','OK','TooltipString','''OK'': validate the choice');
3484%  last raw  of the GUI: pushbuttons
3485% uicontrol('Style','pushbutton','Units','normalized', 'Position', [0.35 0.01 0.3 0.15],'BackgroundColor',[0 1 0],'String','OK','Callback',@(hObject,eventdata)OK_Callback(hObject,eventdata),...
3486%     'FontWeight','bold','FontUnits','points','FontSize',12,'TooltipString','''OK'': apply the output to the current field series in uvmat');
3487drawnow
3488
3489%------------------------------------------------------------------------
3490function ListView_Callback(hObject,eventdata)
3491Mode_Callback(hObject,eventdata)
3492
3493%------------------------------------------------------------------------   
3494function Mode_Callback(hObject,eventdata)
3495%% get input info
3496hseries=findobj(allchild(0),'tag','series');%handles of the GUI series
3497hhseries=guidata(hseries);%handles of the elements in the GUI series
3498TimeUnit=get(hhseries.TimeUnit,'String');
3499SeriesData=get(hseries,'UserData');
3500mode_list=get(hObject,'String');
3501mode=mode_list{get(hObject,'Value')};
3502hListView=findobj(get(hObject,'parent'),'Tag','ListView');
3503iview=get(hListView,'Value');
3504i1_series=SeriesData.i1_series{iview};
3505i2_series=SeriesData.i2_series{iview};
3506j1_series=SeriesData.j1_series{iview};
3507j2_series=SeriesData.j2_series{iview};
3508
3509%% enable j index visibility after the new choice
3510status_j='on';%default
3511if isempty(find(~cellfun(@isempty,SeriesData.j1_series), 1)); % case of empty j indices
3512    status_j='off'; % no j index needed
3513elseif strcmp(get(handles.PairString,'Visible'),'on')
3514    check_burst=cellfun(@isempty,regexp(PairString,'^j'));%=0 for burst case, 1 otherwise
3515    if isempty(find(check_burst, 1))% if all pair string begins by j (burst)
3516        status_j='off'; % no j index needed for bust case
3517    end
3518end
3519enable_j(handles,status_j) % no j index needed
3520
3521%% get the reference indices for the time interval Dt
3522href_i=findobj(get(hObject,'parent'),'Tag','ref_i');
3523ref_i=[];ref_j=[];
3524if strcmp(get(href_i,'Visible'),'on')
3525    ref_i=str2num(get(href_i,'String'));
3526end
3527if isempty(ref_i)
3528    ref_i=1;
3529end
3530if isempty(ref_j)
3531    ref_j=1;
3532end
3533
3534%% update the menu ListPair
3535Menu=update_listpair(i1_series,i2_series,j1_series,j2_series,mode,SeriesData.Time{iview},TimeUnit,ref_i,ref_j,FileInfo);
3536hlist_pairs=findobj(get(hObject,'parent'),'Tag','ListPair');
3537set(hlist_pairs,'Value',1)% set the first choice by default in ListPair
3538set(hlist_pairs,'String',Menu)% set the menu in ListPair
3539ListPair_Callback(hlist_pairs,[])% apply the default choice in ListPair
3540
3541%-------------------------------------------------------------
3542% --- Executes on selection in ListPair.
3543function ListPair_Callback(hObject,eventdata)
3544%------------------------------------------------------------
3545list_pair=get(hObject,'String');%get the menu of image pairs
3546if isempty(list_pair)
3547    string='';
3548else
3549    string=list_pair{get(hObject,'Value')};
3550   % string=regexprep(string,',.*','');%removes time indication (after ',')
3551end
3552hseries=findobj(allchild(0),'tag','series');
3553hPairString=findobj(hseries,'tag','PairString');
3554PairString=get(hPairString,'Data');
3555hListView=findobj(get(hObject,'parent'),'Tag','ListView');
3556iview=get(hListView,'Value');
3557PairString{iview,1}=string;
3558% report the selected pair string to the table PairString
3559set(hPairString,'Data',PairString)
3560
3561
3562%------------------------------------------------------------------------
3563function num_ref_i_Callback(hObject, eventdata)
3564%------------------------------------------------------------------------
3565Mode_Callback([],[])
3566
3567%------------------------------------------------------------------------
3568function num_ref_j_Callback(hObject, eventdata)
3569%------------------------------------------------------------------------
3570Mode_Callback([],[])
3571
3572%------------------------------------------------------------------------
3573function OK_Callback(hObject, eventdata)
3574%------------------------------------------------------------------------
3575delete(get(hObject,'parent'))
3576
3577
3578%------------------------------------------------------------------------
3579% --- Executes on button press in ClearLine.
3580%------------------------------------------------------------------------
3581function ClearLine_Callback(hObject, eventdata, handles)
3582InputTable=get(handles.InputTable,'Data');
3583iline=str2double(get(handles.InputLine,'String'));
3584if size(InputTable,1)>1
3585    InputTable(iline,:)=[];% suppress the current line if not the first
3586    set(handles.InputTable,'Data',InputTable);
3587end
3588set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH button to magenta color to indicate that input refr
3589
3590
3591% --- Executes on button press in MonitorCluster.
3592function MonitorCluster_Callback(hObject, eventdata, handles)
3593web('https://www.legi.grenoble-inp.fr/servload/monika')
3594
3595
3596
3597function OutputSubDir_Callback(hObject, eventdata, handles)
3598set(handles.OutputSubDir,'BackgroundColor',[1 1 1])
3599
3600
3601% --- Executes on button press in CheckOverwrite.
3602function CheckOverwrite_Callback(hObject, eventdata, handles)
3603
3604
3605
3606% --- Executes on button press in TestCPUTime.
3607function TestCPUTime_Callback(hObject, eventdata, handles)
3608% hObject    handle to TestCPUTime (see GCBO)
3609% eventdata  reserved - to be defined in a future version of MATLAB
3610% handles    structure with handles and user data (see GUIDATA)
3611
3612
3613
3614
3615
Note: See TracBrowser for help on using the repository browser.