source: trunk/src/series.m @ 917

Last change on this file since 917 was 917, checked in by sommeria, 9 years ago

series modified to deal with NbSlice? in local mode, subbackground fixed, edge detection introduced

File size: 160.0 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
1732    otherwise
1733         if ~isempty(Param.IndexRange.NbSlice)
1734             NbProcess=Param.IndexRange.NbSlice;% the parameter NbSlice sets the nbre of run processes
1735         end
1736end
1737
1738%% record nbre of output files and starting time for computation for status
1739StatusData=get(handles.status,'UserData');
1740if isfield(StatusData,'OutputFileMode')
1741    switch StatusData.OutputFileMode
1742        case 'NbInput'
1743            StatusData.NbOutputFile=numel(ref_i)*nbfield_j;
1744        case 'NbInput_i'
1745            StatusData.NbOutputFile=numel(ref_i);
1746        case 'NbSlice'   
1747            StatusData.NbOutputFile=str2num(get(handles.num_NbSlice,'String'));
1748    end
1749end
1750StatusData.TimeStart=now;
1751set(handles.status,'UserData',StatusData)
1752
1753%% case of a function in Python
1754if strcmp(ActionExt, '.py (in dev.)')
1755    fprintf([
1756        '\n' ...
1757        '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n' ...
1758        'The option .py is used. It is still in development.\n' ...
1759        'Do not use it unless you really know what you do!\n' ...
1760        'To try it, first install Pyp and the most recent version of FluidDyn.\n' ...
1761        '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n'])
1762    RunMode = 'python';
1763    t = struct2xml(Param);
1764    t = set(t, 1, 'name', 'Series');
1765    filexml = fullfile_uvmat(DirXml, '', Param.InputTable{1,3}, '.xml', OutputNomType,...
1766         Param.IndexRange.first_i, Param.IndexRange.last_i, first_j, last_j);
1767    save(t, filexml);
1768end
1769
1770
1771%% direct processing on the current Matlab session
1772if strcmp (RunMode,'local')
1773    for iprocess=1:NbProcess
1774        if ~strcmp(get(handles.RUN,'BusyAction'),'queue')% allow for STOP action
1775            disp('program stopped by user')
1776            return
1777        end
1778        if isempty(Param.IndexRange.NbSlice)
1779            %Param.IndexRange.first_i=first_i+(iprocess-1)*BlockLength*incr_i;
1780            Param.IndexRange.first_i=ref_i(1+(iprocess-1)*BlockLength);
1781            if Param.IndexRange.first_i>last_i
1782                break
1783            end
1784            Param.IndexRange.last_i=min(ref_i(iprocess*BlockLength),last_i);
1785            %Param.IndexRange.last_i=min(first_i+(iprocess)*BlockLength*incr_i-1,last_i);
1786        else %multislices (then incr_i is not empty)
1787            Param.IndexRange.first_i= first_i+incr_i*(iprocess-1);
1788            Param.IndexRange.incr_i=incr_i*Param.IndexRange.NbSlice;
1789        end
1790        if isfield(Param,'OutputSubDir')
1791            t=struct2xml(Param);
1792            t=set(t,1,'name','Series');
1793            filexml=fullfile_uvmat(DirXml,'',Param.InputTable{1,3},'.xml',OutputNomType,...
1794                Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1795            save(t,filexml);
1796        end
1797        switch ActionExt
1798            case '.m'
1799                h_fun(Param);
1800            case '.sh'
1801                switch computer
1802                    case {'PCWIN','PCWIN64'} %Windows system
1803                        filexml=regexprep(filexml,'\\','\\\\');% add '\' so that '\' are left as characters
1804                        system([fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml]);% TODO: adapt to DOS system
1805                    case {'GLNX86','GLNXA64','MACI64'}%Linux  system
1806                        system([fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml]);
1807                end
1808        end
1809    end
1810elseif ~strcmp(RunMode,'python')
1811    %% processing on a different session of the same computer (background) or cluster, create executable files
1812    batch_file_list=cell(NbProcess,1);% initiate the list of executable files
1813    DirExe=fullfile(OutputDir,'0_EXE');%directory name for executable files
1814    switch computer
1815        case {'PCWIN','PCWIN64'} %Windows system
1816            ExeExt='.bat';
1817        case {'GLNX86','GLNXA64','MACI64'}%Linux  system
1818            ExeExt='.sh';
1819    end
1820    %create subdirectory for executable files
1821    if ~exist(DirExe,'dir')
1822        [tild,msg1]=mkdir(DirExe);
1823        if ~strcmp(msg1,'')
1824            errormsg=['cannot create ' DirExe ': ' msg1];%error message for directory creation
1825            return
1826        end
1827    end
1828    %create subdirectory for log files
1829    DirLog=fullfile(OutputDir,'0_LOG');
1830    if ~exist(DirLog,'dir')
1831        [tild,msg1]=mkdir(DirLog);
1832        if ~strcmp(msg1,'')
1833            errormsg=['cannot create ' DirLog ': ' msg1];%error message for directory creation
1834            return
1835        end
1836    end
1837    for iprocess=1:NbProcess
1838        if isempty(Param.IndexRange.NbSlice)% process by blocks of i index
1839            Param.IndexRange.first_i=first_i+(iprocess-1)*BlockLength*incr_i;
1840            if Param.IndexRange.first_i>last_i
1841                NbProcess=iprocess-1;
1842                break% leave the loop, we are at the end of the calculation
1843            end
1844            Param.IndexRange.last_i=min(last_i,first_i+(iprocess)*BlockLength*incr_i-1);
1845        else% process by slices of i index if NbSlice is defined, computation in a single process if NbSlice =1
1846            Param.IndexRange.first_i= first_i+iprocess-1;
1847            Param.IndexRange.incr_i=incr_i*Param.IndexRange.NbSlice;
1848        end
1849        for ilist=1:size(Param.InputTable,1)
1850            Param.InputTable{ilist,1}=regexprep(Param.InputTable{ilist,1},'\','/');%correct path name for PCWIN system
1851        end
1852        % create, fill and save the xml parameter file
1853        t=struct2xml(Param);
1854        t=set(t,1,'name','Series');
1855        filexml{iprocess}=fullfile_uvmat(DirXml,'',Param.InputTable{1,3},'.xml',OutputNomType,...
1856            Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1857        save(t,filexml{iprocess});% save the parameter file
1858       
1859       
1860        % set the log file name
1861        filelog{iprocess}=fullfile_uvmat(DirLog,'',Param.InputTable{1,3},'.log',OutputNomType,...
1862            Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1863    end
1864end
1865
1866%% launch the executable files for background or cluster processing
1867switch RunMode
1868    case 'background'
1869        % create the executable file
1870        filebat=fullfile_uvmat(DirExe,'',Param.InputTable{1,3},ExeExt,OutputNomType,...
1871            first_i,last_i,first_j,last_j);
1872        %batch_file_list{iprocess}=filebat;
1873        [fid,message]=fopen(filebat,'w');% create the executable file
1874        if isequal(fid,-1)
1875            errormsg=['creation of .bat file: ' message];
1876            return
1877        end
1878        filelog=fullfile_uvmat(DirLog,'',Param.InputTable{1,3},'.log',OutputNomType,...
1879           first_i,last_i,first_j,last_j);
1880        switch ActionExt
1881            case '.m'% Matlab function
1882                switch computer
1883                    case {'GLNX86','GLNXA64','MACI64'}
1884                        cmd=[...
1885                            '#!/bin/bash \n'...
1886                            '. /etc/sysprofile \n'...
1887                            'matlab -nodisplay -nosplash -nojvm -logfile ''' filelog ''' <<END_MATLAB \n'...
1888                            'addpath(''' path_series '''); \n'...
1889                            'addpath(''' Param.Action.ActionPath '''); \n'];
1890                        for iprocess=1:NbProcess
1891                            cmd=[cmd '' Param.Action.ActionName  '( ''' filexml{iprocess} '''); \n'];
1892                        end
1893                        cmd=[cmd  'exit \n' 'END_MATLAB \n'];
1894                        fprintf(fid,cmd);%fill the executable file with the  char string cmd
1895                        fclose(fid);% close the executable file
1896                        system(['chmod +x ' filebat]);% set the file to executable
1897                    case {'PCWIN','PCWIN64'}
1898                        cmd=['matlab -automation -logfile ' regexprep(filelog{iprocess},'\\','\\\\')...
1899                            ' -r "addpath(''' regexprep(path_series,'\\','\\\\') ''');'...
1900                            'addpath(''' regexprep(Param.Action.ActionPath,'\\','\\\\') ''');'];
1901                        for iprocess=1:NbProcess
1902                            cmd=[cmd '' Param.Action.ActionName  '( ''' regexprep(filexml{iprocess},'\\','\\\\') ''');']   
1903                        end
1904                        cmd=[cmd ';exit"'];
1905                        fprintf(fid,cmd);%fill the executable file with the  char string cmd
1906                        fclose(fid);% close the executable file
1907                end
1908                system([filebat ' &'])% directly execute the command file
1909            case '.sh' % compiled Matlab function
1910                switch computer
1911                    case {'GLNX86','GLNXA64','MACI64'}
1912                        cmd=['#!/bin/bash \n '...
1913                            '#$ -cwd \n '...
1914                            'sleep $(( $RANDOM / 3000 )) \n '...
1915                            'hostname && date \n '...
1916                            'umask 002 \n']
1917                        for iprocess=1:NbProcess
1918                            cmd=[cmd fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml{iprocess}];%allow writting access to created files for user group
1919                        end
1920                        fprintf(fid,cmd);%fill the executable file with the  char string cmd
1921                        fclose(fid);% close the executable file
1922                        system(['chmod +x ' filebat]);% set the file to executable
1923                        system([filebat ' &'])% directly execute the command file
1924                    case {'PCWIN','PCWIN64'}
1925                        msgbox_uvmat('ERROR','option for compiled Matlab functions not implemented for Windows system')
1926                        return
1927                end
1928                msgbox_uvmat('CONFIRMATION',[ActionName ' launched in background: press STATUS to see results'])
1929            case 'cluster_oar' % option 'oar-parexec' used
1930                %create subdirectory for oar command and global log files
1931                DirOAR=fullfile(OutputDir,'0_OAR');
1932                if exist(DirOAR,'dir')% delete the content of the dir 0_LOG to allow new input
1933                    curdir=pwd;
1934                    cd(DirOAR)
1935                    delete('*')
1936                    cd(curdir)
1937                else
1938                    [tild,msg1]=mkdir(DirOAR);
1939                    if ~strcmp(msg1,'')
1940                        errormsg=['cannot create ' DirOAR ': ' msg1];%error message for directory creation
1941                        return
1942                    end
1943                end
1944                filename_joblist=fullfile(DirOAR,'job_list.txt');%create name of the global executable file
1945                filename_log=fullfile(DirLog,'job_list.stdout');%file for output messages of the master oar process
1946                filename_errors=fullfile(DirLog,'job_list.stderr');%file for error messages of the master oar process
1947               
1948                fid=fopen(filename_joblist,'w');
1949                for p=1:length(batch_file_list)
1950                    fprintf(fid,[batch_file_list{p} '\n']);% list of exe files
1951                end
1952                fclose(fid);
1953                system(['chmod +x ' filename_joblist]);% set the file to executable
1954               
1955                % the command job_list.txt contains the list of NbProcess independent individual jobs
1956                % in which the total calculation has been split. Those are written as executable files .sh in the folder /O_EXE.
1957                %  These individual jobs are grouped by the system as oar jobs on the NbCore processors.
1958                %  For each processor, the oar job must stop after the walltime which has been set, which is limited to 24 h.
1959                %  However, the oar job is automatically restarted (option 'idempotent') provided the individual jobs are
1960                % shorter than the wall time: in the time interval 'checkpoint' (WallTimeOneJob) before the end of the allowed duration,
1961                %  the oar job restarts when an individual job ends.
1962                JobTime=CPUTime*BlockLength*nbfield_j;% estimated time for one individual job (in minutes)
1963                % wall time (in hours ) for each oar job, allowing 10 individual jobs, but limited to 23 h:
1964                WallTimeTotal=min(23,4*JobTime/60);
1965                %disp(['WallTimeTotal: ' num2str(WallTimeTotal) ' hours'])
1966                % estimated time of an individual job (in min), with a margin of error
1967                WallTimeOneJob=min(4*JobTime+10,WallTimeTotal*60/2);% estimated max time of an individual job for checkpoint
1968                disp(['WallTimeOneJob: ' num2str(WallTimeOneJob) ' minutes'])
1969                oar_command=['oarsub -n UVmat_' ActionName ' '...
1970                    '-t idempotent --checkpoint ' num2str(WallTimeOneJob*60) ' '...
1971                    '-l /core=' num2str(NbCore) ','...
1972                    'walltime=' datestr(WallTimeTotal/24,13) ' '...
1973                    '-E ' filename_errors ' '...
1974                    '-O ' filename_log ' '...
1975                    extra_oar ' '...
1976                    '"oar-parexec -s -f ' filename_joblist ' '...
1977                    '-l ' filename_joblist '.log"'];
1978                fprintf(oar_command);% display  system command on the Matlab command window
1979                [status,result]=system(oar_command)% execute system command and show the result (ID number of the launched job) on the Matlab command window
1980                filename_oarcommand=fullfile(DirOAR,'0_oar_command');% keep track of the command in file '0-OAR/0_oar_command'
1981                fid=fopen(filename_oarcommand,'w');
1982                fprintf(fid,oar_command); % store the command
1983                fprintf(fid,result);% store the result (job ID number)
1984                fclose(fid);
1985               
1986                msgbox_uvmat('CONFIRMATION',[ActionName ' launched as  ' num2str(NbProcess) ' processes in cluster: press STATUS to see results'])
1987            case 'cluster_pbs' % for LMFA Kepler machine
1988                %create subdirectory for pbs command and log files
1989                DirPBS=fullfile(OutputDir,'0_PBS'); %todo : common name OAR/PBS
1990                if exist(DirPBS,'dir')% delete the content of the dir 0_LOG to allow new input
1991                    curdir=pwd;
1992                    cd(DirPBS)
1993                    delete('*')
1994                    cd(curdir)
1995                else
1996                    [tild,msg1]=mkdir(DirPBS);
1997                    if ~strcmp(msg1,'')
1998                        errormsg=['cannot create ' DirPBS ': ' msg1];%error message for directory creation
1999                        return
2000                    end
2001                end
2002                max_walltime=3600*20; % 20h max total calculation (cannot exceed 24 h)
2003                walltime_onejob=1800; % seconds, max estimated time for asingle file index value
2004                filename_joblist=fullfile(DirPBS,'job_list.txt');%create name of the global executable file
2005                fid=fopen(filename_joblist,'w');
2006                for p=1:length(batch_file_list)
2007                    fprintf(fid,[batch_file_list{p} '\n']);% list of exe files
2008                end
2009                fclose(fid);
2010                system(['chmod +x ' filename_joblist]);% set the file to executable
2011                pbs_command=['qstat -n CIVX '...
2012                    '-t idempotent --checkpoint ' num2str(walltime_onejob+60) ' '...
2013                    '-l /core=' num2str(NbCore) ','...
2014                    'walltime=' datestr(min(1.05*walltime_onejob/86400*max(NbProcess*BlockLength*nbfield_j,NbCore)/NbCore,max_walltime/86400),13) ' '...
2015                    '-E ' regexprep(filename_joblist,'\.txt\>','.stderr') ' '...
2016                    '-O ' regexprep(filename_joblist,'\.txt\>','.log') ' '...
2017                    extra_oar ' '...
2018                    '"oar-parexec -s -f ' filename_joblist ' '...
2019                    '-l ' filename_joblist '.log"'];
2020                filename_oarcommand=fullfile(DirPBS,'pbs_command');
2021                fid=fopen(filename_oarcommand,'w');
2022                fprintf(fid,pbs_command);
2023                fclose(fid);
2024                fprintf(pbs_command);% display in command line
2025                %system(pbs_command);
2026                msgbox_uvmat('CONFIRMATION',[ActionName ' command ready to be launched in cluster'])
2027            case 'python'
2028                command = [
2029                    'LD_LIBRARY_PATH=$(echo $LD_LIBRARY_PATH | pyp "p.split('':'') | [s for s in p if ''matlab'' not in s] | '':''.join(p)") ' ...
2030                    'python -m fluiddyn.postproc.uvmat ' filexml{iprocess}];
2031                % fprintf(['command:\n' command '\n\n'])
2032                system(command, '-echo');
2033        end
2034end
2035%------------------------------------------------------------------------
2036function STOP_Callback(hObject, eventdata, handles)
2037%------------------------------------------------------------------------
2038set(handles.RUN, 'BusyAction','cancel')
2039set(handles.RUN,'BackgroundColor',[1 0 0])
2040set(handles.RUN,'enable','on')
2041set(handles.RUN, 'Value',0)
2042
2043
2044%------------------------------------------------------------------------
2045% --- read parameters from the GUI series
2046%------------------------------------------------------------------------
2047function Param=read_GUI_series(handles)
2048
2049%% read raw parameters from the GUI series
2050Param=read_GUI(handles.series);
2051
2052%% clean the output structure by removing unused information
2053if isfield(Param,'Pairs')
2054    Param=rmfield(Param,'Pairs'); %info Pairs not needed for output
2055end
2056if isfield(Param,'InputLine')
2057    Param=rmfield(Param,'InputLine');
2058end
2059if isfield(Param,'EditObject')
2060    Param=rmfield(Param,'EditObject');
2061end
2062Param.IndexRange.TimeSource=Param.IndexRange.TimeTable{end,1};
2063Param.IndexRange=rmfield(Param.IndexRange,'TimeTable');
2064empty_line=false(size(Param.InputTable,1),1);
2065for iline=1:size(Param.InputTable,1)
2066    empty_line(iline)=isempty(cell2mat(Param.InputTable(iline,1:3)));
2067end
2068Param.InputTable(empty_line,:)=[];
2069
2070%------------------------------------------------------------------------
2071% --- Executes on selection change in ActionName.
2072function ActionName_Callback(hObject, eventdata, handles)
2073%------------------------------------------------------------------------
2074
2075%% stop any ongoing series processing
2076if isequal(get(handles.RUN,'Value'),1)
2077    answer= msgbox_uvmat('INPUT_Y-N','stop current Action process?');
2078    if strcmp(answer,'Yes')
2079        STOP_Callback(hObject, eventdata, handles)
2080    else
2081        return
2082    end
2083end
2084set(handles.ActionName,'BackgroundColor',[1 1 0])
2085huigetfile=findobj(allchild(0),'tag','status_display');
2086if ~isempty(huigetfile)
2087    delete(huigetfile)
2088end
2089drawnow
2090
2091%% get Action name and path
2092NbBuiltinAction=get(handles.Action,'UserData'); %nbre of functions initially proposed in the menu ActionName (as defined in the Opening fct of series)
2093ActionList=get(handles.ActionName,'String');% list menu fields
2094ActionIndex=get(handles.ActionName,'Value');
2095if ~isequal(ActionIndex,1)% if we are not just opening series
2096    InputTable=get(handles.InputTable,'Data');
2097    if isempty(InputTable{1,4})
2098        msgbox_uvmat('ERROR','no input file available: use Open in the menu bar')
2099        return
2100    end
2101end
2102ActionName= ActionList{get(handles.ActionName,'Value')}; % selected function name
2103ActionPathList=get(handles.ActionName,'UserData');%list of recorded paths to functions of the list ActionName
2104
2105%% add a new function to the menu if 'more...' has been selected in the menu ActionName
2106if isequal(ActionName,'more...')
2107    [FileName, PathName] = uigetfile( ...
2108        {'*.m', ' (*.m)';
2109        '*.m',  '.m files '; ...
2110        '*.*', 'All Files (*.*)'}, ...
2111        'Pick a series processing function ',get(handles.ActionPath,'String'));
2112    if length(FileName)<2
2113        return
2114    end
2115    [tild,ActionName,ActionExt]=fileparts(FileName);
2116   
2117    % insert the choice in the menu ActionName
2118    ActionIndex=find(strcmp(ActionName,ActionList),1);% look for the selected function in the menu Action
2119    PathName=regexprep(PathName,'/$','');
2120    if ~isempty(ActionIndex) && ~strcmp(ActionPathList{ActionIndex},PathName)%compare the path to the existing fct
2121        ActionIndex=[]; % the selected path is different than the recorded one
2122    end
2123    if isempty(ActionIndex)%the qselected fct (with selected path) does not exist in the menu
2124        ActionIndex= length(ActionList);
2125        ActionList=[ActionList(1:end-1);{ActionName};ActionList(end)];% the selected function is appended in the menu, before the last item 'more...'
2126         ActionPathList=[ActionPathList; PathName];
2127    end
2128   
2129    % record the file extension and extend the path list if it is a new extension
2130    ActionExtList=get(handles.ActionExt,'String');
2131    ActionExtIndex=find(strcmp(ActionExt,ActionExtList), 1);
2132    if isempty(ActionExtIndex)
2133        set(handles.ActionExt,'String',[ActionExtList;{ActionExt}])
2134    end
2135
2136    % remove old Action options in the menu (keeping a menu length <nb_builtin_ACTION+5)
2137    if length(ActionList)>NbBuiltinAction+5; %nb_builtin_ACTION=nbre of functions always remaining in the initial menu
2138        nbremove=length(ActionList)-NbBuiltinAction-5;
2139        ActionList(NbBuiltinAction+1:end-5)=[];
2140        ActionPathList(NbBuiltinAction+1:end-4,:)=[];
2141        ActionIndex=ActionIndex-nbremove;
2142    end
2143   
2144    % record action menu, choice and path
2145    set(handles.ActionName,'Value',ActionIndex)
2146    set(handles.ActionName,'String',ActionList)
2147       set(handles.ActionName,'UserData',ActionPathList);
2148    set(handles.ActionExt,'Value',ActionExtIndex)
2149       
2150    %record the user defined menu additions in personal file profil_perso
2151    dir_perso=prefdir;
2152    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
2153    if NbBuiltinAction+1<=numel(ActionList)-1
2154        ActionListUser=ActionList(NbBuiltinAction+1:numel(ActionList)-1);
2155        ActionPathListUser=ActionPathList(NbBuiltinAction+1:numel(ActionList)-1);
2156        ActionExtListUser={};
2157        if numel(ActionExtList)>2
2158            ActionExtListUser=ActionExtList(3:end);
2159        end
2160        if exist(profil_perso,'file')
2161            save(profil_perso,'ActionListUser','ActionPathListUser','ActionExtListUser','-append')
2162        else
2163            save(profil_perso,'ActionListUser','ActionPathListUser','ActionExtListUser','-V6')
2164        end
2165    end
2166end
2167
2168%% check the current ActionPath to the selected function
2169ActionPath=ActionPathList{ActionIndex};%current recorded path
2170set(handles.ActionPath,'String',ActionPath); %show the path to the senlected function
2171
2172%% reinitialise the waitbar
2173update_waitbar(handles.Waitbar,0)
2174
2175%% create the function handle for Action
2176if ~exist(ActionPath,'dir')
2177    msgbox_uvmat('ERROR',['The prescribed function path ' ActionPath ' does not exist']);
2178    return
2179end
2180current_dir=pwd;%current working dir
2181cd(ActionPath)
2182h_fun=str2func(ActionName);
2183cd(current_dir)
2184
2185%
2186% checkaddpath=0;
2187% path_series=which('series');
2188% %eval(['spath=which(''' ActionName ''');']) %spath = current path of the selected function ACTION
2189% spath=fileparts(which(ActionName)); %spath = current path of the selected function ACTION
2190% if ~exist(ActionPath,'dir')
2191%     msgbox_uvmat('ERROR',['The prescribed function path ' ActionPath ' does not exist']);
2192%     return
2193% end
2194% if ~strcmp(spath,ActionPath)
2195%     if strcmp(pwd,spath)
2196%         msgbox_uvmat('ERROR',[ 'a function called ' ActionName ' on your working space oversets the selected one']);
2197%         return
2198%     else
2199%         addpath(ActionPath)% add the prescribed path if not the current one
2200%         checkaddpath=1;
2201%     end
2202% end
2203% eval(['h_fun=@' ActionName ';'])%create a function handle for ACTION
2204% if checkaddpath && ~isequal(ActionPath,path_series)
2205%     rmpath(ActionPath)% add the prescribed path if not the current one
2206% end
2207
2208%% Activate the Action fct to adapt the configuration of the GUI series and bring specific parameters in SeriesData
2209Param=read_GUI_series(handles);% read the parameters from the GUI series
2210ParamOut=h_fun(Param);%run the selected Action function to get the relevant input
2211
2212%% Put the first line of the selected Action fct as tooltip help
2213try
2214    [fid,errormsg] =fopen([ActionName '.m']);
2215    InputText=textscan(fid,'%s',1,'delimiter','\n');
2216    fclose(fid);
2217    set(handles.ActionName,'ToolTipString',InputText{1}{1})% put the first line of the selected function as tooltip help
2218end
2219
2220
2221%% Visibility of VelType and VelType_1 menus asked by ActionName
2222VelTypeRequest=1;%VelType requested by default
2223VelTypeRequest_1=1;%VelType requested by default
2224if isfield(ParamOut,'VelType')
2225    VelTypeRequest=ismember(ParamOut.VelType,{'on','one','two'});
2226    VelTypeRequest_1=strcmp( ParamOut.VelType,'two');
2227end
2228FieldNameRequest=0;  %hidden by default
2229FieldNameRequest_1=0;  %hidden by default
2230if isfield(ParamOut,'FieldName')
2231    FieldNameRequest=ismember(ParamOut.FieldName,{'on','one','two'});
2232    FieldNameRequest_1=strcmp( ParamOut.FieldName,'two');
2233end
2234
2235%% Detect the types of input files and set menus and default options in 'VelType'
2236SeriesData=get(handles.series,'UserData');% info on the input file series
2237iview_civ=find(strcmp('civx',SeriesData.FileType)|strcmp('civdata',SeriesData.FileType));
2238iview_netcdf=find(strcmp('netcdf',SeriesData.FileType)|strcmp('civx',SeriesData.FileType)|strcmp('civdata',SeriesData.FileType));% all nc files, icluding civ
2239FieldList=get(handles.FieldName,'String');% previous list as default
2240if ~iscell(FieldList),FieldList={FieldList};end
2241FieldList_1=get(handles.FieldName_1,'String');% previous list as default
2242if ~iscell(FieldList_1),FieldList_1={FieldList_1};end
2243%CheckList=0;% indicate whether FieldName has been updated
2244CheckList_1=1;% indicate whether FieldName_1 has been updated
2245handles_coord=[handles.Coord_x handles.Coord_y handles.Coord_z handles.Coord_x_title handles.Coord_y_title handles.Coord_z_title];
2246if VelTypeRequest && numel(iview_civ)>=1
2247    menu=set_veltype_display(SeriesData.FileInfo{iview_civ(1)}.CivStage,SeriesData.FileType{iview_civ(1)});
2248    set(handles.VelType,'Value',1)% set first choice by default
2249    set(handles.VelType,'String',[{'*'};menu])
2250    set(handles.VelType,'Visible','on')
2251    set(handles.VelType_title,'Visible','on')
2252    FieldList=[set_field_list('U','V');{'C'};{'get_field...'}];%standard menu for civx data
2253    %CheckList=1;
2254    set(handles.FieldName,'Value',1); %velocity vector choice by default
2255    if  VelTypeRequest_1 && numel(iview_civ)>=2
2256        menu=set_veltype_display(SeriesData.FileInfo{iview_civ(2)}.CivStage,SeriesData.FileType{iview_civ(2)});
2257        set(handles.VelType_1,'Value',1)% set first choice by default
2258        set(handles.VelType_1,'String',[{'*'};menu])
2259        set(handles.VelType_1,'Visible','on')
2260        set(handles.VelType_title_1,'Visible','on')
2261        FieldList_1=[set_field_list('U','V');{'C'};{'get_field...'}];%standard menu for civx data
2262        CheckList_1=1;
2263        set(handles.FieldName_1,'Value',1); %velocity vector choice by default
2264    else
2265        set(handles.VelType_1,'Visible','off')
2266        set(handles.VelType_title_1,'Visible','off')
2267    end
2268else
2269    set(handles.VelType,'Visible','off')
2270    set(handles.VelType_title,'Visible','off')
2271end   
2272
2273%% Detect the types of input files and set menus and default options in 'FieldName'
2274if FieldNameRequest && numel(iview_netcdf)>=1
2275    set(handles.InputFields,'Visible','on')
2276    %if CheckList==0        % not civ input made
2277        if isfield(SeriesData.FileInfo{iview_netcdf(1)},'ListVarName')
2278        ListVarName=SeriesData.FileInfo{iview_netcdf(1)}.ListVarName;
2279        ind_var=get(handles.FieldName,'Value');%indices of previously selected variables
2280        for ilist=1:numel(ind_var)
2281            if isempty(find(strcmp(FieldList{ind_var(ilist)},ListVarName)))
2282                FieldList={};% previous choice not consistent with new input field
2283                set(handles.FieldName,'Value',1)
2284                break
2285            end
2286        end
2287        if ~isempty(FieldList)
2288            if isempty(find(strcmp(get(handles.Coord_x,'String'),ListVarName)))||...
2289                    isempty(find(strcmp(get(handles.Coord_y,'String'),ListVarName)))
2290                FieldList={};
2291                set(handles.Coord_x,'String','')
2292                set(handles.Coord_y,'String','')
2293            end
2294            Coord_z=get(handles.Coord_z,'String');
2295            if ~isempty(Coord_z) && isempty(find(strcmp(Coord_z,ListVarName)))
2296                FieldList={};
2297                set(handles.Coord_z,'String','')
2298            end
2299        end
2300        set(handles_coord,'Visible','on')
2301        FieldList=[FieldList;{'get_field...'}];
2302        if FieldNameRequest_1 && numel(iview_netcdf)>=2
2303            set(handles.FieldName_1,'Visible','on')
2304            if CheckList_1==0        % not civ input made
2305                ListVarName=SeriesData.FileInfo{iview_netcdf(2)}.ListVarName;
2306                ind_var=get(handles.FieldName,'Value');%indices of previously selected variables
2307                for ilist=1:numel(ind_var)
2308                    if isempty(find(strcmp(FieldList{ind_var(ilist)},ListVarName)))
2309                        FieldList_1={};% previous choice not consistent with new input field
2310                        set(handles.FieldName_1,'Value',1)
2311                        break
2312                    end
2313                end
2314                warn_coord=0;
2315                if isempty(find(strcmp(get(handles.Coord_x,'String'),ListVarName)))||...
2316                        isempty(find(strcmp(get(handles.Coord_y,'String'),ListVarName)))
2317                    warn_coord=1;
2318                end
2319                if ~isempty(Coord_z) && isempty(find(strcmp(Coord_z,ListVarName)))
2320                    FieldList_1={};
2321                    warn_coord=1;
2322                end
2323                if warn_coord
2324                    msgbox_uvmat('WARNING','coordiante names do not exist in the second netcdf input file')
2325                end
2326                set(handles.FieldName,'String',[FieldList;{'get_field...'}])
2327                set(handles.FieldName_1,'Visible','on')
2328                set(handles.FieldName_1,'Value',1)
2329                set(handles.FieldName_1,'String',FieldList_1)
2330            end
2331        else
2332            set(handles.FieldName_1,'Visible','off')
2333        end
2334        end
2335%     else
2336%         set(handles_coord,'Visible','off')% no coord display for civ data
2337%     end
2338    set(handles.FieldName,'String',FieldList)
2339else
2340    set(handles.InputFields,'Visible','off')
2341end
2342
2343%% Introduce visibility of file overwrite option
2344if isfield(ParamOut,'CheckOverwriteVisible')&& strcmp(ParamOut.CheckOverwriteVisible,'on')
2345    set(handles.CheckOverwrite,'Visible','on')
2346else
2347    set(handles.CheckOverwrite,'Visible','off')
2348end
2349
2350%% Check whether alphabetical sorting of input Subdir is allowed by the Action fct  (for multiples series entries)
2351if isfield(ParamOut,'AllowInputSort')&&isequal(ParamOut.AllowInputSort,'on')&& size(Param.InputTable,1)>1
2352    [tild,iview]=sort(InputTable(:,2)); %subdirectories sorted in alphabetical order
2353    set(handles.InputTable,'Data',InputTable(iview,:));
2354    MinIndex_i=get(handles.MinIndex_i,'Data');
2355    MinIndex_j=get(handles.MinIndex_j,'Data');
2356    MaxIndex_i=get(handles.MaxIndex_i,'Data');
2357    MaxIndex_j=get(handles.MaxIndex_j,'Data');
2358    set(handles.MinIndex_i,'Data',MinIndex_i(iview,:));
2359    set(handles.MinIndex_j,'Data',MinIndex_j(iview,:));
2360    set(handles.MaxIndex_i,'Data',MaxIndex_i(iview,:));
2361    set(handles.MaxIndex_j,'Data',MaxIndex_j(iview,:));
2362    TimeTable=get(handles.TimeTable,'Data');
2363    set(handles.TimeTable,'Data',TimeTable(iview,:));
2364    PairString=get(handles.PairString,'Data');
2365    set(handles.PairString,'Data',PairString(iview,:));
2366end
2367
2368%% Impose the whole input file index range if requested
2369if isfield(ParamOut,'WholeIndexRange')&&isequal(ParamOut.WholeIndexRange,'on')
2370    MinIndex_i=get(handles.MinIndex_i,'Data');
2371    MinIndex_j=get(handles.MinIndex_j,'Data');
2372    MaxIndex_i=get(handles.MaxIndex_i,'Data');
2373    MaxIndex_j=get(handles.MaxIndex_j,'Data');
2374    set(handles.num_first_i,'String',num2str(MinIndex_i(1)))% set first as the min index (for the first line)
2375    set(handles.num_last_i,'String',num2str(MaxIndex_i(1)))% set last as the max index (for the first line)
2376    set(handles.num_incr_i,'String','1')
2377    set(handles.num_first_j,'String',num2str(MinIndex_j(1)))% set first as the min index (for the first line)
2378    set(handles.num_last_j,'String',num2str(MaxIndex_j(1)))% set last as the max index (for the first line)
2379    set(handles.num_incr_j,'String','1')
2380else  % check index ranges
2381    first_i=1;last_i=1;first_j=1;last_j=1;
2382    if isfield(Param.IndexRange,'first_i')
2383        first_i=Param.IndexRange.first_i;
2384        last_i=Param.IndexRange.last_i;
2385    end
2386    if isfield(Param.IndexRange,'first_j')
2387        first_j=Param.IndexRange.first_j;
2388        last_j=Param.IndexRange.last_j;
2389    end
2390    if last_i < first_i || last_j < first_j , msgbox_uvmat('ERROR','last field number must be larger than the first one'),...
2391            set(handles.RUN, 'Enable','On'), set(handles.RUN,'BackgroundColor',[1 0 0]),return,end;
2392end
2393
2394%% enable or desable j index visibility
2395status_j='on';%default
2396if isfield(ParamOut,'Desable_j_index')&&isequal(ParamOut.Desable_j_index,'on')
2397    status_j='off';
2398end
2399if isempty(find(~cellfun(@isempty,SeriesData.j1_series), 1)); % case of empty j indices
2400    status_j='off'; % no j index needed
2401elseif strcmp(get(handles.PairString,'Visible'),'on')
2402    check_burst=cellfun(@isempty,regexp(get(handles.PairString,'Data'),'^j'));%=0 for burst case, 1 otherwise
2403    if isempty(find(check_burst, 1))% if all pair string begins by j (burst)
2404        status_j='off'; % no j index needed for bust case
2405    end
2406end
2407enable_j(handles,status_j) % no j index needed
2408
2409
2410%% NbSlice visibility
2411%NbSliceVisible='off';%default
2412if isfield(ParamOut,'NbSlice') && (strcmp(ParamOut.NbSlice,'on')||isnumeric(ParamOut.NbSlice))
2413    set(handles.num_NbSlice,'Visible','on')
2414    set(handles.NbSlice_title,'Visible','on')
2415else
2416    set(handles.num_NbSlice,'Visible','off')
2417    set(handles.NbSlice_title,'Visible','off')
2418    %     set(handles.num_NbProcess,'String',get(handles.num_NbSlice,'String'))% the nbre of processes is imposed as the nbre of slices
2419    % else
2420    %     set(handles.num_NbProcess,'String','')% free nbre of processes
2421end
2422if isnumeric(ParamOut.NbSlice)
2423    set(handles.num_NbSlice,'String',num2str(ParamOut.NbSlice))
2424    set(handles.num_NbSlice,'Enable','off'); % NbSlice set by the activation of the Action function
2425else
2426    set(handles.num_NbSlice,'Enable','on'); % NbSlice can be modified on the GUI series
2427end
2428% set(handles.num_NbSlice,'Visible',NbSliceVisible)
2429% set(handles.NbSlice_title,'Visible',NbSliceVisible)
2430
2431
2432
2433%% Visibility of FieldTransform menu
2434FieldTransformVisible='off';  %hidden by default
2435if isfield(ParamOut,'FieldTransform')
2436    FieldTransformVisible=ParamOut.FieldTransform; 
2437    TransformName_Callback([],[], handles)
2438end
2439set(handles.FieldTransform,'Visible',FieldTransformVisible)
2440if isfield(ParamOut,'TransformPath')
2441    set(handles.ActionExt,'UserData',ParamOut.TransformPath)
2442else
2443    set(handles.ActionExt,'UserData',[])
2444end
2445
2446%% Visibility of projection object
2447ProjObjectVisible='off';  %hidden by default
2448if isfield(ParamOut,'ProjObject')
2449    ProjObjectVisible=ParamOut.ProjObject;
2450end
2451set(handles.CheckObject,'Visible',ProjObjectVisible)
2452if ~get(handles.CheckObject,'Value')
2453    ProjObjectVisible='off';
2454end
2455set(handles.ProjObject,'Visible',ProjObjectVisible)
2456set(handles.DeleteObject,'Visible',ProjObjectVisible)
2457set(handles.ViewObject,'Visible',ProjObjectVisible)
2458set(handles.EditObject,'Visible',ProjObjectVisible)
2459
2460%% Visibility of mask input
2461MaskVisible='off';  %hidden by default
2462if isfield(ParamOut,'Mask')
2463    MaskVisible=ParamOut.Mask;
2464end
2465set(handles.CheckMask,'Visible',MaskVisible);
2466
2467%% definition of the directory containing the output files
2468if  ~(isfield(SeriesData,'ActionName') && strcmp(ActionName,SeriesData.ActionName))
2469    OutputDirExt='.series'; %default
2470    if isfield(ParamOut,'OutputDirExt')&&~isempty(ParamOut.OutputDirExt)
2471        OutputDirExt=ParamOut.OutputDirExt;
2472    end
2473    set(handles.OutputDirExt,'String',OutputDirExt)
2474end
2475OutputDirVisible='off';
2476OutputSubDirMode='auto';%default
2477SubDirOut='';
2478if isfield(ParamOut,'OutputSubDirMode')
2479    OutputSubDirMode=ParamOut.OutputSubDirMode;
2480end
2481switch OutputSubDirMode
2482    case 'auto';%default
2483        OutputDirVisible='on';
2484        SubDir=InputTable(1:end,2); %set of subdirectories
2485        SubDirOut=SubDir{1};
2486        if numel(SubDir)>1
2487            for ilist=2:numel(SubDir)
2488                SubDirOut=[SubDirOut '-' regexprep(SubDir{ilist},'^/','')];
2489            end
2490        end
2491    case 'one'
2492        OutputDirVisible='on';
2493        SubDirOut=InputTable{1,2}; %use the first subdir name (+OutputDirExt) as output  subdirectory
2494    case 'two'
2495        OutputDirVisible='on';   
2496        SubDir=InputTable(1:2,2); %set of subdirectories
2497        SubDirOut=SubDir{1};
2498        if numel(SubDir)>1
2499                SubDirOut=[SubDirOut '-' regexprep(SubDir{2},'^/','')];
2500        end
2501    case 'last'
2502        OutputDirVisible='on';
2503        SubDirOut=InputTable{end,2}; %use the last subdir name (+OutputDirExt) as output  subdirectory
2504end
2505set(handles.OutputSubDir,'String',SubDirOut)
2506set(handles.OutputSubDir,'BackgroundColor',[1 1 1])% set edit box to white color to indicate refreshment
2507set(handles.OutputDirExt,'Visible',OutputDirVisible)
2508set(handles.OutputSubDir,'Visible',OutputDirVisible)
2509%set(handles.CheckOverwrite,'Visible',OutputDirVisible)
2510set(handles.OutputDir_title,'Visible',OutputDirVisible)
2511SeriesData.ActionName=ActionName;%record ActionName for next use
2512
2513
2514%% visibility of the run mode (local or background or cluster)
2515if strcmp(OutputSubDirMode,'none')
2516    RunModeVisible='off';% only local mode available if no output file is produced
2517else
2518    RunModeVisible='on';
2519end
2520set(handles.RunMode,'Visible',RunModeVisible)
2521set(handles.ActionExt,'Visible',RunModeVisible)
2522set(handles.RunMode_title,'Visible',RunModeVisible)
2523set(handles.ActionExt_title,'Visible',RunModeVisible)
2524
2525
2526%% Expected nbre of output files
2527if isfield(ParamOut,'OutputFileMode')
2528    StatusData.OutputFileMode=ParamOut.OutputFileMode;
2529    set(handles.status,'UserData',StatusData)
2530end
2531
2532%% definition of an additional parameter set, determined by an ancillary GUI
2533if isfield(ParamOut,'ActionInput')
2534    set(handles.ActionInput,'Visible','on')
2535    ParamOut.ActionInput.Program=ActionName; % record the program in ActionInput
2536    SeriesData.ActionInput=ParamOut.ActionInput;
2537else
2538    set(handles.ActionInput,'Visible','off')
2539    if isfield(SeriesData,'ActionInput')
2540        SeriesData=rmfield(SeriesData,'ActionInput');
2541    end
2542end
2543set(handles.series,'UserData',SeriesData)
2544set(handles.ActionName,'BackgroundColor',[1 1 1])
2545
2546%------------------------------------------------------------------------
2547% --- Executes on selection change in FieldName.
2548function FieldName_Callback(hObject, eventdata, handles)
2549%------------------------------------------------------------------------
2550field_str=get(handles.FieldName,'String');
2551field_index=get(handles.FieldName,'Value');
2552field=field_str{field_index(1)};
2553if isequal(field,'get_field...')
2554    SeriesData=get(handles.series,'UserData');
2555    % input line for which the field choice is relevant
2556    iview=find(ismember(SeriesData.FileType,{'netcdf','civx','civdata'}));% all nc files, icluding civ
2557    hget_field=findobj(allchild(0),'name','get_field');
2558    if ~isempty(hget_field)
2559        delete(hget_field)%delete opened versions of get_field
2560    end
2561    Param=read_GUI(handles.series);
2562    InputTable=Param.InputTable(iview,:);
2563    % check the existence of the first file in the series
2564    first_j=[];last_j=[];MinIndex_j=1;MaxIndex_j=1;%default setting for index j
2565    if isfield(Param.IndexRange,'first_j');% if index j is used     
2566        first_j=Param.IndexRange.first_j;
2567        last_j=Param.IndexRange.last_j;
2568        MinIndex_j=Param.IndexRange.MinIndex_j(iview);
2569        MaxIndex_j=Param.IndexRange.MaxIndex_j(iview);
2570    end
2571    PairString='';
2572    if isfield(Param.IndexRange,'PairString'); PairString=Param.IndexRange.PairString{iview}; end
2573    [i1,i2,j1,j2] = get_file_index(Param.IndexRange.first_i,first_j,PairString);
2574    LineIndex=iview(1);
2575    if numel(iview)>1     
2576        answer=msgbox_uvmat('INPUT_TXT',['select the line of the input table:' num2str(iview)] ,num2str(iview(1)));
2577        LineIndex=str2num(answer);
2578%         InputLine=str2num(get(handles.InputLine,'String'));
2579%         if ismember(InputLine,iview)
2580%             LineIndex=InputLine;
2581%         end
2582    end
2583    FirstFileName=fullfile_uvmat(InputTable{LineIndex,1},InputTable{LineIndex,2},InputTable{LineIndex,3},...
2584        InputTable{LineIndex,5},InputTable{LineIndex,4},i1,i2,j1,j2);
2585    if exist(FirstFileName,'file')
2586        ParamIn.Title='get_field: pick input variables and coordinates for series processing';
2587        ParamIn.SeriesInput=1;
2588        GetFieldData=get_field(FirstFileName,ParamIn);
2589        FieldList={};
2590        if isfield(GetFieldData,'FieldOption')% if a field has been selected
2591        switch GetFieldData.FieldOption
2592            case 'vectors'
2593                UName=GetFieldData.PanelVectors.vector_x;
2594                VName=GetFieldData.PanelVectors.vector_y;
2595                YName={GetFieldData.Coordinates.Coord_y};
2596                FieldList={['vec(' UName ',' VName ')'];...
2597                    ['norm(' UName ',' VName ')'];...
2598                    UName;VName};
2599            case {'scalar'}
2600                FieldList=GetFieldData.PanelScalar.scalar;
2601                YName={GetFieldData.Coordinates.Coord_y};
2602                if ischar(FieldList)
2603                    FieldList={FieldList};
2604                end
2605            case 'civdata...'
2606                FieldList=[set_field_list('U','V') ;{'C'}];
2607                set(handles.FieldName,'Value',1) % set menu to 'velocity
2608                XName='X';
2609                YName='y';
2610        end
2611        set(handles.FieldName,'Value',1)
2612        set(handles.FieldName,'String',[FieldList; {'get_field...'}]);
2613        if ~strcmp(GetFieldData.FieldOption,'civdata...')
2614           if ~isempty(regexp(FieldList{1},'^vec'))
2615                set(handles.FieldName,'Value',1)
2616           else
2617                set(handles.FieldName,'Value',1:numel(FieldList))%select all input fields by default
2618           end
2619            XName=GetFieldData.Coordinates.Coord_x;
2620            YName=GetFieldData.Coordinates.Coord_y;
2621            TimeNameStr=GetFieldData.Time.SwitchVarIndexTime;
2622            % get the time info                     
2623            TimeTable=get(handles.TimeTable,'Data');
2624            switch TimeNameStr
2625                case 'file index'
2626                    TimeName='';
2627                case 'attribute'
2628                    TimeName=['att:' GetFieldData.Time.TimeName];
2629                    % update the time table
2630                    TimeTable{LineIndex,2}=get_time(Param.IndexRange.MinIndex_i(LineIndex),MinIndex_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % Min time     
2631                    TimeTable{LineIndex,3}=get_time(Param.IndexRange.first_i,first_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % first time             
2632                    TimeTable{LineIndex,4}=get_time(Param.IndexRange.last_i,last_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % last time                     
2633                    TimeTable{LineIndex,5}=get_time(Param.IndexRange.MaxIndex_i(LineIndex),MaxIndex_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % Max time
2634                case 'variable'
2635                    set(handles.TimeName,'String',['var:' GetFieldData.Time.TimeName])
2636                    set(handles.NomType,'String','*')
2637                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])% A VERIFIER !!!!!!
2638                    set(handles.FileIndex,'String','')
2639                    ParamIn.TimeVarName=GetFieldData.Time.TimeName;
2640                case 'matrix_index'
2641                    TimeName=['dim:' GetFieldData.Time.TimeName];
2642                    set(handles.NomType,'String','*')
2643                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
2644                    set(handles.FileIndex,'String','')
2645                    ParamIn.TimeDimName=GetFieldData.Time.TimeName;
2646            end
2647            TimeTable{LineIndex,1}=TimeName;
2648            set(handles.TimeTable,'Data',TimeTable);
2649        end
2650        set(handles.Coord_x,'String',XName)
2651        set(handles.Coord_y,'String',YName)
2652        set(handles.Coord_x,'Visible','on')
2653        set(handles.Coord_y,'Visible','on')
2654        end
2655    else
2656        msgbox_uvmat('ERROR',[FirstFileName ' does not exist'])
2657    end
2658end
2659
2660function [TimeValue,DtValue]=get_time(ref_i,ref_j,PairString,InputTable,FileInfo,TimeName,DtName)
2661[i1,i2,j1,j2] = get_file_index(ref_i,ref_j,PairString);
2662FileName=fullfile_uvmat(InputTable{1},InputTable{2},InputTable{3},InputTable{5},InputTable{4},i1,i2,j1,j2);
2663Data=nc2struct(FileName,[]);
2664TimeValue=[];
2665DtValue=[];
2666if isequal(FileInfo.FileType,'civdata')
2667    if ismember(TimeName,{'civ1','filter1'})
2668        TimeValue=Data.Civ1_Time;
2669        DtValue=Data.Civ1_Dt;
2670    else
2671        TimeValue=Data.Civ2_Time;
2672        DtValue=Data.Civ2_Dt;
2673    end
2674else
2675    if ~isempty(TimeName)&& isfield(Data,TimeName)
2676        TimeValue=Data.(TimeName);
2677    end
2678    if exist('DtName','var') && isfield(Data,DtName)
2679        DtValue=Data.(DtName);
2680    end
2681end
2682
2683%------------------------------------------------------------------------
2684% --- Executes on selection change in FieldName_1.
2685function FieldName_1_Callback(hObject, eventdata, handles)
2686%------------------------------------------------------------------------
2687field_str=get(handles.FieldName_1,'String');
2688field_index=get(handles.FieldName_1,'Value');
2689field=field_str{field_index(1)};
2690if isequal(field,'get_field...')
2691    hget_field=findobj(allchild(0),'name','get_field');
2692    if ~isempty(hget_field)
2693        delete(hget_field)%delete opened versions of get_field
2694    end
2695    Param=read_GUI(handles.series);
2696    Param.InputTable=Param.InputTable(1,:);
2697    % check the existence of the first file in the series
2698    first_j=[];
2699    if isfield(Param.IndexRange,'first_j'); first_j=Param.IndexRange.first_j; end
2700    if isfield(Param.IndexRange,'last_j'); last_j=Param.IndexRange.last_j; end
2701    PairString='';
2702    if isfield(Param.IndexRange,'PairString'); PairString=Param.IndexRange.PairString; end
2703    [i1,i2,j1,j2] = get_file_index(Param.IndexRange.first_i,first_j,PairString);
2704    FirstFileName=fullfile_uvmat(Param.InputTable{1,1},Param.InputTable{1,2},Param.InputTable{1,3},...
2705        Param.InputTable{1,5},Param.InputTable{1,4},i1,i2,j1,j2);
2706    if exist(FirstFileName,'file')
2707        ParamIn.SeriesInput=1;
2708        GetFieldData=get_field(FirstFileName,ParamIn);
2709        FieldList={};
2710        switch GetFieldData.FieldOption
2711            case 'vectors'
2712                UName=GetFieldData.PanelVectors.vector_x;
2713                VName=GetFieldData.PanelVectors.vector_y;
2714                FieldList={['vec(' UName ',' VName ')'];...
2715                    ['norm(' UName ',' VName ')'];...
2716                    UName;VName};
2717            case {'scalar','pick variables'}
2718                FieldList=GetFieldData.PanelScalar.scalar;
2719                if ischar(FieldList)
2720                    FieldList={FieldList};
2721                end
2722            case '1D plot'
2723
2724            case 'civdata...'
2725                FieldList=set_field_list('U','V','C');
2726                set(handles.FieldName,'Value',2) % set menu to 'velocity
2727        end
2728        if ~strcmp(GetFieldData.FieldOption,'civdata...')
2729            TimeNameStr=GetFieldData.Time.SwitchVarIndexTime;
2730            switch TimeNameStr
2731                case 'file index'
2732                    set(handles.TimeName,'String','');
2733                case 'attribute'
2734                    set(handles.TimeName,'String',['att:' GetFieldData.Time.TimeName]);
2735                case 'variable'
2736                    set(handles.TimeName,'String',['var:' GetFieldData.Time.TimeName])
2737                    set(handles.NomType,'String','*')
2738                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])% A VERIFIER !!!!!!
2739                    set(handles.FileIndex,'String','')
2740                    ParamIn.TimeVarName=GetFieldData.Time.TimeName;
2741                case 'matrix_index'
2742                    set(handles.TimeName,'String',['dim:' GetFieldData.Time.TimeName]);
2743                    set(handles.NomType,'String','*')
2744                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
2745                    set(handles.FileIndex,'String','')
2746                    ParamIn.TimeDimName=GetFieldData.Time.TimeName;
2747            end
2748        end
2749        set(handles.FieldName_1,'Value',1)
2750        set(handles.FieldName_1,'String',[FieldList; {'get_field...'}]);
2751    end
2752end   
2753
2754
2755%%%%%%%%%%%%%
2756function [ind_remove]=find_pairs(dirpair,ind_i,last_i)
2757indsel=ind_i;
2758indiff=diff(ind_i); %test index increment to detect multiplets (several pairs with the same index ind_i) and holes in the series
2759indiff=[1 indiff last_i-ind_i(end)+1];%for testing gaps with the imposed bounds
2760if ~isempty(indiff)
2761    indiff2=diff(indiff);
2762    indiffp=[indiff2 1];
2763    indiffm=[1 indiff2];
2764    ind_multi_m=find((indiff==0)&(indiffm<0))-1;%indices of first members of multiplets
2765    ind_multi_p=find((indiff==0)&(indiffp>0));%indices of last members of multiplets
2766    %for each multiplet, select the most recent file
2767    ind_remove=[];
2768    for i=1:length(ind_multi_m)
2769        ind_pairs=ind_multi_m(i):ind_multi_p(i);
2770        for imulti=1:length(ind_pairs)
2771            datepair(imulti)=datenum(dirpair(ind_pairs(imulti)).date);%dates of creation
2772        end
2773        [datenew,indsort2]=sort(datepair); %sort the multiplet by creation date
2774        ind_s=indsort2(1:end-1);%
2775        ind_remove=[ind_remove ind_pairs(ind_s)];%remove these indices, leave the last one
2776    end
2777end
2778
2779%------------------------------------------------------------------------
2780% --- determine the list of index pairstring of processing file
2781function [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)
2782%------------------------------------------------------------------------
2783num_i1=num_i;% set of first image numbers by default
2784num_i2=num_i;
2785num_j1=num_j;
2786num_j2=num_j;
2787num_i_out=num_i;
2788num_j_out=num_j;
2789% if isequal (NomType,'_1-2_1') || isequal (NomType,'_1-2')
2790if isequal(mode,'series(Di)')
2791    num_i1_line=num_i+ind_shift(3);% set of first image numbers
2792    num_i2_line=num_i+ind_shift(4);
2793    % adjust the first and last field number
2794        indsel=find(num_i1_line >= 1);
2795    num_i_out=num_i(indsel);
2796    num_i1_line=num_i1_line(indsel);
2797    num_i2_line=num_i2_line(indsel);
2798    num_j1=meshgrid(num_j,ones(size(num_i1_line)));
2799    num_j2=meshgrid(num_j,ones(size(num_i1_line)));
2800    [xx,num_i1]=meshgrid(num_j,num_i1_line);
2801    [xx,num_i2]=meshgrid(num_j,num_i2_line);
2802elseif isequal (mode,'series(Dj)')||isequal (mode,'bursts')
2803    if isequal(mode,'bursts') %case of bursts (png_old or png_2D)
2804        num_j1=ind_shift(1)*ones(size(num_i));
2805        num_j2=ind_shift(2)*ones(size(num_i));
2806    else
2807        num_j1_col=num_j+ind_shift(1);% set of first image numbers
2808        num_j2_col=num_j+ind_shift(2);
2809        % adjust the first field number
2810        indsel=find((num_j1_col >= 1));   
2811        num_j_out=num_j(indsel);
2812        num_j1_col=num_j1_col(indsel);
2813        num_j2_col=num_j2_col(indsel);
2814        [num_i1,num_j1]=meshgrid(num_i,num_j1_col);
2815        [num_i2,num_j2]=meshgrid(num_i,num_j2_col);
2816    end   
2817end
2818
2819%------------------------------------------------------------------------
2820% --- Executes on button press in CheckObject.
2821function CheckObject_Callback(hObject, eventdata, handles)
2822%------------------------------------------------------------------------
2823hset_object=findobj(allchild(0),'tag','set_object');%find the set_object interface handle
2824if get(handles.CheckObject,'Value')
2825    SeriesData=get(handles.series,'UserData');
2826    if isfield(SeriesData,'ProjObject') && ~isempty(SeriesData.ProjObject)
2827        set(handles.ViewObject,'Value',1)
2828        ViewObject_Callback(hObject, eventdata, handles)
2829    else
2830        if ishandle(hset_object)
2831            uistack(hset_object,'top')% show the GUI set_object if opened
2832        else
2833            %get the object file
2834            InputTable=get(handles.InputTable,'Data');
2835            defaultname=InputTable{1,1};
2836            if isempty(defaultname)
2837                defaultname={''};
2838            end
2839            fileinput=uigetfile_uvmat('pick a xml object file (or use uvmat to create it)',defaultname,'.xml');
2840            if isempty(fileinput)% exit if no object file is selected
2841                set(handles.CheckObject,'Value',0)
2842                return
2843            end
2844            %read the file
2845            data=xml2struct(fileinput);
2846            if ~isfield(data,'Type')
2847                msgbox_uvmat('ERROR',[fileinput ' is not an object xml file'])
2848                set(handles.CheckObject,'Value',0)
2849                return
2850            end
2851            if ~isfield(data,'ProjMode')
2852                data.ProjMode='none';
2853            end
2854            hset_object=set_object(data);% call the set_object interface
2855            set(hset_object,'Name','set_object_series')% name to distinguish from set_object used with uvmat
2856        end
2857        ProjObject=read_GUI(hset_object);
2858        set(handles.ProjObject,'String',ProjObject.Name);%display the object name
2859        SeriesData=get(handles.series,'UserData');
2860        SeriesData.ProjObject=ProjObject;
2861        set(handles.series,'UserData',SeriesData);
2862    end
2863    set(handles.EditObject,'Visible','on');
2864    set(handles.DeleteObject,'Visible','on');
2865    set(handles.ViewObject,'Visible','on');
2866    set(handles.ProjObject,'Visible','on');
2867else
2868    set(handles.EditObject,'Visible','off');
2869    set(handles.DeleteObject,'Visible','off');
2870    set(handles.ViewObject,'Visible','off');
2871    if ~ishandle(hset_object)
2872        set(handles.ViewObject,'Value',0);
2873    end
2874    set(handles.ProjObject,'Visible','off');
2875end
2876
2877%------------------------------------------------------------------------
2878% --- Executes on button press in ViewObject.
2879%------------------------------------------------------------------------
2880function ViewObject_Callback(hObject, eventdata, handles)
2881
2882UserData=get(handles.series,'UserData');
2883hset_object=findobj(allchild(0),'Tag','set_object');
2884if ~isempty(hset_object)
2885    delete(hset_object)% refresh set_object if already opened
2886end
2887hset_object=set_object(UserData.ProjObject);
2888set(hset_object,'Name','view_object_series')
2889
2890
2891%------------------------------------------------------------------------
2892% --- Executes on button press in EditObject.
2893function EditObject_Callback(hObject, eventdata, handles)
2894%------------------------------------------------------------------------
2895if get(handles.EditObject,'Value')
2896    set(handles.ViewObject,'Value',0)
2897        UserData=get(handles.series,'UserData');
2898    hset_object=set_object(UserData.ProjObject);
2899    set(hset_object,'Name','edit_object_series')
2900    set(get(hset_object,'Children'),'Enable','on')
2901else
2902    hset_object=findobj(allchild(0),'Tag','set_object');
2903    if ~isempty(hset_object)
2904        set(get(hset_object,'Children'),'Enable','off')
2905    end
2906end
2907
2908%------------------------------------------------------------------------
2909% --- Executes on button press in DeleteObject.
2910function DeleteObject_Callback(hObject, eventdata, handles)
2911%------------------------------------------------------------------------
2912SeriesData=get(handles.series,'UserData');
2913SeriesData.ProjObject=[];
2914set(handles.series,'UserData',SeriesData)
2915set(handles.ProjObject,'String','')
2916set(handles.ProjObject,'Visible','off')
2917set(handles.CheckObject,'Value',0)
2918set(handles.ViewObject,'Visible','off')
2919set(handles.EditObject,'Visible','off')
2920hset_object=findobj(allchild(0),'name','set_object_series');
2921if ~isempty(hset_object)
2922    delete(hset_object)
2923end
2924set(handles.DeleteObject,'Visible','off')
2925
2926%------------------------------------------------------------------------
2927% --- Executed when CheckMask is activated
2928%------------------------------------------------------------------------
2929function CheckMask_Callback(hObject, eventdata, handles)
2930
2931if get(handles.CheckMask,'Value')
2932    InputTable=get(handles.InputTable,'Data');
2933    nbview=size(InputTable,1);
2934    MaskTable=cell(nbview,1);%default
2935    ListMask=cell(nbview,1);%default
2936    MaskData=get(handles.MaskTable,'Data');
2937    MaskData(size(MaskData,1):nbview,1)=cell(size(MaskData,1):nbview,1);%complement if undefined lines
2938    for iview=1:nbview
2939        ListMask{iview,1}=num2str(iview);
2940        RootPath=InputTable{iview,1};
2941        if ~isempty(RootPath)
2942            if isempty(MaskData{iview})
2943                SubDir=InputTable{iview,2};
2944                MaskPath=fullfile(RootPath,[regexprep(SubDir,'\..*','') '.mask']);%take the root part of SubDir, before the first dot '.'
2945                if exist(MaskPath,'dir')
2946                    ListStruct=dir(MaskPath);%look for a mask file
2947                    ListCells=struct2cell(ListStruct);% transform dir struct to a cell arrray
2948                    check_dir=cell2mat(ListCells(4,:));% =1 for directories, =0 for files
2949                    ListFiles=ListCells(1,:);%list of file and dri names
2950                    ListFiles=ListFiles(~check_dir);%list of file names (excluding dir)
2951                    mdetect=0;
2952                    if ~isempty(ListFiles)
2953                        for ifile=1:numel(ListFiles)
2954                            [tild,tild,MaskFile{ifile},i1_series,i2_series,j1_series,j2_series,MaskNomType,MaskFileType]=find_file_series(MaskPath,ListFiles{ifile},0);
2955                            if strcmp(MaskFileType,'image') && isempty(i2_series) && isempty(j2_series)
2956                                mdetect=1;
2957                                MaskName=ListFiles{ifile};
2958                            end
2959                            if ~strcmp(MaskFile{ifile},MaskFile{1})
2960                                mdetect=0;% cancel detection test in case of multiple masks, use the brower for selection
2961                                break
2962                            end
2963                        end
2964                    end
2965                    if mdetect==1
2966                        MaskName=fullfile(MaskPath,'mask_1.png');
2967                    else
2968                        MaskName=uigetfile_uvmat('select a mask file:',MaskPath,'image');
2969                    end
2970                else
2971                    MaskName=uigetfile_uvmat('select a mask file:',RootPath,'image');
2972                end
2973                MaskTable{iview,1}=MaskName ;
2974                ListMask{iview,1}=num2str(iview);
2975            end
2976        end
2977    end
2978    set(handles.MaskTable,'Data',MaskTable)
2979    set(handles.MaskTable,'Visible','on')
2980    set(handles.MaskBrowse,'Visible','on')
2981    set(handles.ListMask,'Visible','on')
2982    set(handles.ListMask,'String',ListMask)
2983    set(handles.ListMask,'Value',1)
2984else
2985    set(handles.MaskTable,'Visible','off')
2986    set(handles.MaskBrowse,'Visible','off')
2987    set(handles.ListMask,'Visible','off')
2988end
2989
2990%------------------------------------------------------------------------
2991% --- Executes on button press in MaskBrowse.
2992%------------------------------------------------------------------------
2993function MaskBrowse_Callback(hObject, eventdata, handles)
2994
2995InputTable=get(handles.InputTable,'Data');
2996iview=get(handles.ListMask,'Value');
2997RootPath=InputTable{iview,1};
2998MaskName=uigetfile_uvmat('select a mask file:',RootPath,'image');
2999if ~isempty(MaskName)
3000    MaskTable=get(handles.MaskTable,'Data');
3001    MaskTable{iview,1}=MaskName ;
3002    set(handles.MaskTable,'Data',MaskTable)
3003end
3004
3005%------------------------------------------------------------------------
3006% --- Executes when selected cell(s) is changed in MaskTable.
3007%------------------------------------------------------------------------
3008function MaskTable_CellSelectionCallback(hObject, eventdata, handles)
3009
3010if numel(eventdata.Indices)>=1
3011set(handles.ListMask,'Value',eventdata.Indices(1))
3012end
3013
3014%-------------------------------------------------------------------
3015function MenuHelp_Callback(hObject, eventdata, handles)
3016%-------------------------------------------------------------------
3017
3018
3019% path_to_uvmat=which ('uvmat');% check the path of uvmat
3020% pathelp=fileparts(path_to_uvmat);
3021% helpfile=fullfile(pathelp,'uvmat_doc','uvmat_doc.html');
3022% 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')
3023% else
3024%     addpath (fullfile(pathelp,'uvmat_doc'))
3025%     web([helpfile '#series'])
3026% end
3027
3028%-------------------------------------------------------------------
3029% --- Executes on selection change in TransformName.
3030function TransformName_Callback(hObject, eventdata, handles)
3031%----------------------------------------------------------------------
3032TransformList=get(handles.TransformName,'String');
3033TransformIndex=get(handles.TransformName,'Value');
3034TransformName=TransformList{TransformIndex};
3035TransformPathList=get(handles.TransformName,'UserData');
3036nb_builtin_transform=4;
3037if isequal(TransformName,'more...');     
3038    FileName=uigetfile_uvmat('Pick a transform function',get(handles.TransformPath,'String'),'.m');
3039    if isempty(FileName)
3040        return     %browser closed without choice
3041    end
3042    [TransformPath,TransformName,TransformExt]=fileparts(FileName);% removes extension .m
3043    if ~strcmp(TransformExt,'.m')
3044        msgbox_uvmat('ERROR','a Matlab function .m must be introduced');
3045        return
3046    end
3047     % insert the choice in the menu
3048    TransformIndex=find(strcmp(TransformName,TransformList),1);% look for the selected function in the menu Action
3049    if isempty(TransformIndex)%the input string does not exist in the menu
3050        TransformIndex= length(TransformList);
3051        TransformList=[TransformList(1:end-1);{TransformName};TransformList(end)];% the selected function is appended in the menu, before the last item 'more...'
3052        set(handles.TransformName,'String',TransformList)
3053        TransformPathList=[TransformPathList;{TransformPath}];
3054    else% the input function already exist, we update its path (possibly new)
3055        TransformPathList{TransformIndex}=TransformPath;%
3056        set(handles.TransformName,'Value',TransformIndex)
3057    end
3058   % save the new menu in the personal file 'uvmat_perso.mat'
3059   dir_perso=prefdir;%personal Matalb directory
3060   profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
3061   if exist(profil_perso,'file')
3062       for ilist=nb_builtin_transform+1:numel(TransformPathList)
3063           TransformListUser{ilist-nb_builtin_transform}=TransformList{ilist};
3064           TransformPathListUser{ilist-nb_builtin_transform}=TransformPathList{ilist};
3065       end
3066       TransformPathListUser=TransformPathListUser';
3067       TransformListUser=TransformListUser';
3068       save (profil_perso,'TransformPathListUser','TransformListUser','-append'); %store the root name for future opening of uvmat
3069   end
3070end
3071
3072%display the current function path
3073set(handles.TransformPath,'String',TransformPathList{TransformIndex}); %show the path to the senlected function
3074set(handles.TransformName,'UserData',TransformPathList);
3075
3076%% create the function handle of the selected fct
3077if ~isempty(TransformName)
3078    if ~exist(TransformPathList{TransformIndex},'dir')
3079        msgbox_uvmat('ERROR',['The prescribed transform function path ' TransformPathList{TransformIndex} ' does not exist']);
3080        return
3081    end
3082    current_dir=pwd;%current working dir
3083    cd(TransformPathList{TransformIndex})
3084    transform_handle=str2func(TransformName);
3085    cd(current_dir)
3086    Field.Action.RUN=0;% indicate that the transform fct is called only to get input param
3087    DataOut=feval(transform_handle,Field,[]);% execute the transform fct to get the required conditions
3088    if isfield(DataOut,'TransformInput')%  used to add transform parameters at selection of the transform fct
3089        SeriesData=get(handles.series,'UserData');
3090        SeriesData.TransformInput=DataOut.TransformInput;
3091        set(handles.series,'UserData',SeriesData)
3092    end
3093end
3094
3095%------------------------------------------------------------------------
3096% --- fct activated by the upper bar menu ExportConfig
3097%------------------------------------------------------------------------
3098function MenuDisplayConfig_Callback(hObject, eventdata, handles)
3099
3100global Param
3101Param=read_GUI_series(handles);
3102evalin('base','global Param')%make CurData global in the workspace
3103display('current series config :')
3104evalin('base','Param') %display CurData in the workspace
3105commandwindow; %brings the Matlab command window to the front
3106
3107%------------------------------------------------------------------------
3108% --- fct activated by the upper bar menu InportConfig: import
3109%     menu settings from an xml file (stored in /0_XML for each run)
3110%------------------------------------------------------------------------
3111function MenuImportConfig_Callback(hObject, eventdata, handles)
3112
3113%% use a browser to choose the xml file containing the processing config
3114InputTable=get(handles.InputTable,'Data');
3115oldfile=InputTable{1,1};%current path in InputTable
3116if isempty(oldfile)
3117    % use a file name stored in prefdir
3118    dir_perso=prefdir;
3119    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
3120    if exist(profil_perso,'file')
3121        h=load (profil_perso);
3122        if isfield(h,'RootPath') && ischar(h.RootPath)
3123            oldfile=h.RootPath;
3124        end
3125    end
3126end
3127filexml=uigetfile_uvmat('pick a xml parameter file',oldfile,'.xml');% get the xml file containing processing parameters
3128if isempty(filexml), return, end % quit function if an xml file has not been opened
3129
3130%% fill the GUI series with the content of the xml file
3131Param=xml2struct(filexml);% read the input xml file as a Matlab structure
3132
3133% ask to stop current Action if button RUN is in action (another process is already running)
3134if isequal(get(handles.RUN,'Value'),1)
3135    answer= msgbox_uvmat('INPUT_Y-N','stop current Action process?');
3136    if strcmp(answer,'Yes')
3137        STOP_Callback(hObject, eventdata, handles)
3138    else
3139        return
3140    end
3141end
3142Param.Action.RUN=0; %desactivate the input RUN=1
3143
3144fill_GUI(Param,handles.series)% fill the elements of the GUI series with the input parameters
3145SeriesData=get(handles.series,'UserData');
3146if isfield(Param,'InputFields')
3147    ListField=Param.InputFields.FieldName;
3148    if ischar(ListField),ListField={ListField}; end
3149    set(handles.FieldName,'String',[ListField;{'get-field...'}])
3150     set(handles.FieldName,'Value',1:numel(ListField))
3151     set(handles.FieldName,'Visible','on')
3152end       
3153if isfield(Param,'ActionInput')%  introduce  parameters specific to an Action fct, for instance PIV parameters
3154    set(handles.ActionInput,'Visible','on')
3155    set(handles.ActionInput,'Value',0)
3156    Param.ActionInput.ConfigSource=filexml;% record the source of config for future info
3157    SeriesData.ActionInput=Param.ActionInput;
3158end
3159if isfield(Param,'TransformInput')%  introduce  parameters specific to a transform fct
3160    SeriesData.TransformInput=Param.TransformInput;
3161end
3162if isfield(Param,'ProjObject') %introduce projection object if relevant
3163    SeriesData.ProjObject=Param.ProjObject;
3164end
3165set(handles.series,'UserData',SeriesData)
3166if isfield(Param,'CheckObject') && isequal(Param.CheckObject,1)
3167    set(handles.ProjObject,'String',Param.ProjObject.Name)
3168    set(handles.ViewObject,'Visible','on')
3169    set(handles.EditObject,'Visible','on')
3170    set(handles.DeleteObject,'Visible','on')
3171else     
3172    set(handles.ProjObject,'String','')
3173    set(handles.ProjObject,'Visible','off')
3174    set(handles.ViewObject,'Visible','off')
3175    set(handles.EditObject,'Visible','off')
3176    set(handles.DeleteObject,'Visible','off')     
3177end     
3178set(handles.REFRESH,'BackgroundColor',[1 0 1]); %paint REFRESH button in magenta to indicate that it should be activated
3179
3180
3181%------------------------------------------------------------------------
3182% --- Executes when the GUI series is resized.
3183%------------------------------------------------------------------------
3184function series_ResizeFcn(hObject, eventdata, handles)
3185
3186%% input table
3187set(handles.InputTable,'Unit','pixel')
3188Pos=get(handles.InputTable,'Position');
3189set(handles.InputTable,'Unit','normalized')
3190ColumnWidth=round([0.5 0.14 0.14 0.14 0.08]*(Pos(3)-52));
3191ColumnWidth=num2cell(ColumnWidth);
3192set(handles.InputTable,'ColumnWidth',ColumnWidth)
3193
3194%% MinIndex_j and MaxIndex_i
3195unit=get(handles.MinIndex_i,'Unit');
3196set(handles.MinIndex_i,'Unit','pixel')
3197Pos=get(handles.MinIndex_i,'Position');
3198set(handles.MinIndex_i,'Unit',unit)
3199set(handles.MinIndex_i,'ColumnWidth',{Pos(3)-18})
3200set(handles.MaxIndex_i,'ColumnWidth',{Pos(3)-18})
3201set(handles.MinIndex_j,'ColumnWidth',{Pos(3)-18})
3202set(handles.MaxIndex_j,'ColumnWidth',{Pos(3)-18})
3203
3204%% TimeTable
3205set(handles.TimeTable,'Unit','pixel')
3206Pos=get(handles.TimeTable,'Position');
3207set(handles.TimeTable,'Unit','normalized')
3208% ColumnWidth=get(handles.TimeTable,'ColumnWidth');
3209ColumnWidth=num2cell(floor([0.2 0.2 0.2 0.2 0.2]*(Pos(3)-20)));
3210set(handles.TimeTable,'ColumnWidth',ColumnWidth)
3211
3212
3213%% PairString
3214set(handles.PairString,'Unit','pixel')
3215Pos=get(handles.PairString,'Position');
3216set(handles.PairString,'Unit','normalized')
3217set(handles.PairString,'ColumnWidth',{Pos(3)-5})
3218
3219%% MaskTable
3220set(handles.MaskTable,'Unit','pixel')
3221Pos=get(handles.MaskTable,'Position');
3222set(handles.MaskTable,'Unit','normalized')
3223set(handles.MaskTable,'ColumnWidth',{Pos(3)-5})
3224
3225%------------------------------------------------------------------------
3226% --- Executes on button press in status.
3227%------------------------------------------------------------------------
3228function status_Callback(hObject, eventdata, handles)
3229
3230if get(handles.status,'Value')
3231    set(handles.status,'BackgroundColor',[1 1 0])
3232    drawnow
3233    Param=read_GUI(handles.series);
3234    RootPath=Param.InputTable{1,1};
3235    if ~isfield(Param,'OutputSubDir')   
3236        msgbox_uvmat('ERROR','no standard sub-directory definition for output files, use a browser to check the output')
3237        set(handles.status,'BackgroundColor',[0 1 0])
3238        return
3239    end
3240    OutputSubDir=[Param.OutputSubDir Param.OutputDirExt];% subdirectory for output files
3241    OutputDir=fullfile(RootPath,OutputSubDir);
3242    if exist(OutputDir,'dir')
3243        uigetfile_uvmat('status_display',OutputDir)
3244    else
3245        msgbox_uvmat('ERROR','output folder not created yet: calculation did not start')
3246        set(handles.status,'BackgroundColor',[0 1 0])
3247    end
3248else
3249    %% delete current display fig if selection is off
3250    set(handles.status,'BackgroundColor',[0 1 0])
3251    hfig=findobj(allchild(0),'name','status_display');
3252    if ~isempty(hfig)
3253        delete(hfig)
3254    end
3255    return
3256end
3257
3258
3259%------------------------------------------------------------------------   
3260% launched by selecting a file on the list
3261%------------------------------------------------------------------------
3262function view_file(hObject, eventdata)
3263
3264list=get(hObject,'String');
3265index=get(hObject,'Value');
3266rootroot=get(hObject,'UserData');
3267selectname=list{index};
3268ind_dot=regexp(selectname,'\.\.\.');
3269if ~isempty(ind_dot)
3270    selectname=selectname(1:ind_dot-1);
3271end
3272FullSelectName=fullfile(rootroot,selectname);
3273if exist(FullSelectName,'dir')% a directory has been selected
3274    ListFiles=dir(FullSelectName);
3275    ListDisplay=cell(numel(ListFiles),1);
3276    for ilist=2:numel(ListDisplay)% suppress the first line '.'
3277        ListDisplay{ilist-1}=ListFiles(ilist).name;
3278    end
3279    set(hObject,'Value',1)
3280    set(hObject,'String',ListDisplay)
3281    if strcmp(selectname,'..')
3282        FullSelectName=fileparts(fileparts(FullSelectName));
3283    end
3284    set(hObject,'UserData',FullSelectName)
3285    hfig=get(hObject,'parent');
3286    htitlebox=findobj(hfig,'tag','titlebox');   
3287    set(htitlebox,'String',FullSelectName)
3288elseif exist(FullSelectName,'file')%visualise the vel field if it exists
3289    FileInfo=get_file_info(FullSelectName);   
3290    if strcmp(FileInfo.FileType,'txt')
3291        edit(FullSelectName)
3292    elseif strcmp(FileInfo.FileType,'xml')
3293        editxml(FullSelectName)
3294    else
3295        uvmat(FullSelectName)
3296    end
3297    set(gcbo,'Value',1)
3298end
3299
3300
3301%------------------------------------------------------------------------   
3302% launched by refreshing the status figure
3303%------------------------------------------------------------------------
3304function refresh_GUI(hfig)
3305
3306htitlebox=findobj(hfig,'tag','titlebox');
3307hlist=findobj(hfig,'tag','list');
3308hseries=findobj(allchild(0),'tag','series');
3309hstatus=findobj(hseries,'tag','status');
3310StatusData=get(hstatus,'UserData');
3311OutputDir=get(htitlebox,'String');
3312if ischar(OutputDir),OutputDir={OutputDir};end
3313ListFiles=dir(OutputDir{1});
3314if numel(ListFiles)<1
3315    return
3316end
3317ListFiles(1)=[];%removes the first line ='.'
3318ListDisplay=cell(numel(ListFiles),1);
3319testrecent=0;
3320datnum=zeros(numel(ListDisplay),1);
3321for ilist=1:numel(ListDisplay)
3322    ListDisplay{ilist}=ListFiles(ilist).name;
3323      if ~ListFiles(ilist).isdir && isfield(ListFiles(ilist),'datenum')
3324            datnum(ilist)=ListFiles(ilist).datenum;%only available in recent matlab versions
3325            testrecent=1;
3326       end
3327end
3328set(hlist,'String',ListDisplay)
3329
3330%% Look at date of creation
3331ListDisplay=ListDisplay(datnum~=0);
3332datnum=datnum(datnum~=0);%keep the non zero values corresponding to existing files
3333NbOutputFile=[];
3334if isempty(datnum)
3335    if testrecent
3336        message='no civ result created yet';
3337    else
3338        message='';
3339    end
3340else
3341    [first,indfirst]=min(datnum);
3342    [last,indlast]=max(datnum);
3343    NbOutputFile_str='?';
3344    NbOutputFile=[];
3345    if isfield(StatusData,'NbOutputFile')
3346        NbOutputFile=StatusData.NbOutputFile;
3347        NbOutputFile_str=num2str(NbOutputFile);
3348    end
3349    message={[num2str(numel(datnum)) ' file(s) done over ' NbOutputFile_str] ;['oldest modification:  ' ListDisplay{indfirst} ' : ' datestr(first)];...
3350        ['latest modification:  ' ListDisplay{indlast} ' : ' datestr(last)]};
3351end
3352set(htitlebox,'String', [OutputDir{1};message])
3353
3354%% update the waitbar
3355hwaitbar=findobj(hfig,'tag','waitbar');
3356if ~isempty(NbOutputFile)
3357    BarPosition=get(hwaitbar,'Position');
3358    BarPosition(3)=0.9*numel(datnum)/NbOutputFile;
3359    set(hwaitbar,'Position',BarPosition)
3360end
3361
3362%------------------------------------------------------------------------
3363% --- Executes on selection change in ActionExt.
3364%------------------------------------------------------------------------
3365function ActionExt_Callback(hObject, eventdata, handles)
3366
3367ActionExtList=get(handles.ActionExt,'String');
3368ActionExt=ActionExtList{get(handles.ActionExt,'Value')};
3369if strcmp(ActionExt,'.py (in dev.)')
3370    set(handles.RunMode,'Value',2)
3371end
3372
3373%function num_NbProcess_Callback(hObject, eventdata, handles)
3374
3375
3376function num_NbSlice_Callback(hObject, eventdata, handles)
3377NbSlice=str2num(get(handles.num_NbSlice,'String'));
3378%set(handles.num_NbProcess,'String',num2str(NbSlice))
3379
3380%------------------------------------------------------------------------
3381% --- set the visibility of relevant velocity type menus:
3382function menu=set_veltype_display(Civ,FileType)
3383%------------------------------------------------------------------------
3384if ~exist('FileType','var')
3385    FileType='civx';
3386end
3387switch FileType
3388    case 'civx'
3389        menu={'civ1';'interp1';'filter1';'civ2';'interp2';'filter2'};
3390        if isequal(Civ,0)
3391            imax=0;
3392        elseif isequal(Civ,1) || isequal(Civ,2)
3393            imax=1;
3394        elseif isequal(Civ,3)
3395            imax=3;
3396        elseif isequal(Civ,4) || isequal(Civ,5)
3397            imax=4;
3398        elseif isequal(Civ,6) %patch2
3399            imax=6;
3400        end
3401    case 'civdata'
3402        menu={'civ1';'filter1';'civ2';'filter2'};
3403        if isequal(Civ,0)
3404            imax=0;
3405        elseif isequal(Civ,1) || isequal(Civ,2)
3406            imax=1;
3407        elseif isequal(Civ,3)
3408            imax=2;
3409        elseif isequal(Civ,4) || isequal(Civ,5)
3410            imax=3;
3411        else%if isequal(Civ,6) %patch2
3412            imax=4;
3413        end
3414end
3415menu=menu(1:imax);
3416
3417
3418% --- Executes on mouse motion over figure - except title and menu.
3419function series_WindowButtonMotionFcn(hObject, eventdata, handles)
3420set(hObject,'Pointer','arrow');
3421
3422
3423% --- Executes on button press in SetPairs.
3424function SetPairs_Callback(hObject, iview, handles)
3425
3426%% delete previous occurrence of 'set_pairs'
3427hfig=findobj(allchild(0),'Tag','set_pairs');
3428if ~isempty(hfig)
3429delete(hfig)
3430end
3431
3432%% create the GUI set_pairs
3433set(0,'Unit','points')
3434ScreenSize=get(0,'ScreenSize');% get the size of the screen, to put the fig on the upper right
3435Width=220;% fig width in points (1/72 inch)
3436Height=min(0.8*ScreenSize(4),300);
3437Left=ScreenSize(3)- Width-40; %right edge close to the right, with margin=40
3438Bottom=ScreenSize(4)-Height-40; %put fig at top right
3439hfig=findobj(allchild(0),'Tag','set_slice');
3440if ~isempty(hfig),delete(hfig), end; %delete existing version of the GUI
3441hfig=figure('name','set_pairs','tag','set_pairs','MenuBar','none','NumberTitle','off','Unit','points','Position',[Left,Bottom,Width,Height]);
3442BackgroundColor=get(hfig,'Color');
3443SeriesData=get(handles.series,'UserData');
3444TimeUnit=get(handles.TimeUnit,'String');
3445PairString=get(handles.PairString,'Data');
3446ListViewLines=find(cellfun('isempty',PairString)==0);%find list of non empty pairs
3447ListViewMenu=cell(numel(ListViewLines),1);
3448for ilist=1:numel(ListViewLines)
3449    ListViewMenu{ilist}=num2str(ListViewLines(ilist));
3450end
3451if isempty(iview)
3452    ListViewValue=numel(ListViewLines);% we work by default on the pair option for the last line which requires pairs
3453    iview=ListViewLines(end);
3454else
3455    ListViewValue=find(ListViewLines==iview);
3456end
3457ref_i=str2num(get(handles.num_first_i,'String'));
3458ref_j=1;%default
3459if strcmp(get(handles.num_first_j,'String'),'Visible')
3460    ref_j=str2num(get(handles.num_first_j,'String'));
3461end
3462[ModeMenu,ModeValue]=update_mode(SeriesData.i1_series{iview},SeriesData.i2_series{iview},SeriesData.j2_series{iview});
3463displ_pair=update_listpair(SeriesData.i1_series{iview},SeriesData.i2_series{iview},SeriesData.j1_series{iview},SeriesData.j2_series{iview},ModeMenu{ModeValue},...
3464                                                     SeriesData.Time{iview},TimeUnit,ref_i,ref_j,SeriesData.FileInfo{iview});
3465% first raw of the GUI
3466uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.88 0.5 0.1],'BackgroundColor',BackgroundColor,...
3467    'String','row to edit #','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','right');%title
3468uicontrol('Style','popupmenu','Units','normalized', 'Position', [0.54 0.8 0.3 0.2],'BackgroundColor',[1 1 1],...
3469    'Callback',@(hObject,eventdata)ListView_Callback(hObject,eventdata),'String',ListViewMenu,'Value',ListViewValue,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3470    'Tag','ListView','TooltipString','''ListView'':choice of the file series w for pair display');
3471% second raw of the GUI
3472uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.79 0.7 0.1],'BackgroundColor',BackgroundColor,...
3473    'String','mode of index pairing:','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','left');%title
3474uicontrol('Style','popupmenu','Units','normalized', 'Position', [0.05 0.62 0.9 0.2],'BackgroundColor',[1 1 1],...
3475    'Callback',@(hObject,eventdata)Mode_Callback(hObject,eventdata),'String',ModeMenu,'Value',ModeValue,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3476    'Tag','Mode','TooltipString','''Mode'': choice of the image pair mode');
3477% third raw
3478uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.6 0.7 0.1],'BackgroundColor',BackgroundColor,...
3479    'String','pair choice:','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','left');%title
3480uicontrol('Style','listbox','Units','normalized', 'Position', [0.05 0.42 0.9 0.2],'BackgroundColor',[1 1 1],...
3481    'Callback',@(hObject,eventdata)ListPair_Callback(hObject,eventdata),'String',displ_pair,'Value',1,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3482    'Tag','ListPair','TooltipString','''ListPair'': menu for selecting the image pair');
3483uicontrol('Style','text','Units','normalized', 'Position', [0.1 0.22 0.8 0.1],'BackgroundColor',BackgroundColor,...
3484    'String','ref_i           ref_j','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','center');%title
3485uicontrol('Style','edit','Units','normalized', 'Position', [0.15 0.17 0.3 0.08],'BackgroundColor',[1 1 1],...
3486    'Callback',@(hObject,eventdata)num_ref_i_Callback(hObject,eventdata),'String',num2str(ref_i),'FontUnits','points','FontSize',12,'FontWeight','bold',...
3487    'Tag','num_ref_i','TooltipString','''num_ref_i'': reference field index i used to display dt in ''list_pair_civ''');
3488uicontrol('Style','edit','Units','normalized', 'Position', [0.55 0.17 0.3 0.08],'BackgroundColor',[1 1 1],...
3489    'Callback',@(hObject,eventdata)num_ref_j_Callback(hObject,eventdata),'String',num2str(ref_j),'FontUnits','points','FontSize',12,'FontWeight','bold',...
3490    'Tag','num_ref_j','TooltipString','''num_ref_j'': reference field index i used to display dt in ''list_pair_civ''');
3491uicontrol('Style','pushbutton','Units','normalized', 'Position', [0.01 0.01 0.3 0.12],'BackgroundColor',[0 1 0],...
3492    'Callback',@(hObject,eventdata)OK_Callback(hObject,eventdata),'String','OK','FontUnits','points','FontSize',12,'FontWeight','bold',...
3493    'Tag','OK','TooltipString','''OK'': validate the choice');
3494%  last raw  of the GUI: pushbuttons
3495% 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),...
3496%     'FontWeight','bold','FontUnits','points','FontSize',12,'TooltipString','''OK'': apply the output to the current field series in uvmat');
3497drawnow
3498
3499%------------------------------------------------------------------------
3500function ListView_Callback(hObject,eventdata)
3501Mode_Callback(hObject,eventdata)
3502
3503%------------------------------------------------------------------------   
3504function Mode_Callback(hObject,eventdata)
3505%% get input info
3506hseries=findobj(allchild(0),'tag','series');%handles of the GUI series
3507hhseries=guidata(hseries);%handles of the elements in the GUI series
3508TimeUnit=get(hhseries.TimeUnit,'String');
3509SeriesData=get(hseries,'UserData');
3510mode_list=get(hObject,'String');
3511mode=mode_list{get(hObject,'Value')};
3512hListView=findobj(get(hObject,'parent'),'Tag','ListView');
3513iview=get(hListView,'Value');
3514i1_series=SeriesData.i1_series{iview};
3515i2_series=SeriesData.i2_series{iview};
3516j1_series=SeriesData.j1_series{iview};
3517j2_series=SeriesData.j2_series{iview};
3518
3519%% enable j index visibility after the new choice
3520status_j='on';%default
3521if isempty(find(~cellfun(@isempty,SeriesData.j1_series), 1)); % case of empty j indices
3522    status_j='off'; % no j index needed
3523elseif strcmp(get(handles.PairString,'Visible'),'on')
3524    check_burst=cellfun(@isempty,regexp(PairString,'^j'));%=0 for burst case, 1 otherwise
3525    if isempty(find(check_burst, 1))% if all pair string begins by j (burst)
3526        status_j='off'; % no j index needed for bust case
3527    end
3528end
3529enable_j(handles,status_j) % no j index needed
3530
3531%% get the reference indices for the time interval Dt
3532href_i=findobj(get(hObject,'parent'),'Tag','ref_i');
3533ref_i=[];ref_j=[];
3534if strcmp(get(href_i,'Visible'),'on')
3535    ref_i=str2num(get(href_i,'String'));
3536end
3537if isempty(ref_i)
3538    ref_i=1;
3539end
3540if isempty(ref_j)
3541    ref_j=1;
3542end
3543
3544%% update the menu ListPair
3545Menu=update_listpair(i1_series,i2_series,j1_series,j2_series,mode,SeriesData.Time{iview},TimeUnit,ref_i,ref_j,FileInfo);
3546hlist_pairs=findobj(get(hObject,'parent'),'Tag','ListPair');
3547set(hlist_pairs,'Value',1)% set the first choice by default in ListPair
3548set(hlist_pairs,'String',Menu)% set the menu in ListPair
3549ListPair_Callback(hlist_pairs,[])% apply the default choice in ListPair
3550
3551%-------------------------------------------------------------
3552% --- Executes on selection in ListPair.
3553function ListPair_Callback(hObject,eventdata)
3554%------------------------------------------------------------
3555list_pair=get(hObject,'String');%get the menu of image pairs
3556if isempty(list_pair)
3557    string='';
3558else
3559    string=list_pair{get(hObject,'Value')};
3560   % string=regexprep(string,',.*','');%removes time indication (after ',')
3561end
3562hseries=findobj(allchild(0),'tag','series');
3563hPairString=findobj(hseries,'tag','PairString');
3564PairString=get(hPairString,'Data');
3565hListView=findobj(get(hObject,'parent'),'Tag','ListView');
3566iview=get(hListView,'Value');
3567PairString{iview,1}=string;
3568% report the selected pair string to the table PairString
3569set(hPairString,'Data',PairString)
3570
3571
3572%------------------------------------------------------------------------
3573function num_ref_i_Callback(hObject, eventdata)
3574%------------------------------------------------------------------------
3575Mode_Callback([],[])
3576
3577%------------------------------------------------------------------------
3578function num_ref_j_Callback(hObject, eventdata)
3579%------------------------------------------------------------------------
3580Mode_Callback([],[])
3581
3582%------------------------------------------------------------------------
3583function OK_Callback(hObject, eventdata)
3584%------------------------------------------------------------------------
3585delete(get(hObject,'parent'))
3586
3587
3588%------------------------------------------------------------------------
3589% --- Executes on button press in ClearLine.
3590%------------------------------------------------------------------------
3591function ClearLine_Callback(hObject, eventdata, handles)
3592InputTable=get(handles.InputTable,'Data');
3593iline=str2double(get(handles.InputLine,'String'));
3594if size(InputTable,1)>1
3595    InputTable(iline,:)=[];% suppress the current line if not the first
3596    set(handles.InputTable,'Data',InputTable);
3597end
3598set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH button to magenta color to indicate that input refr
3599
3600
3601% --- Executes on button press in MonitorCluster.
3602function MonitorCluster_Callback(hObject, eventdata, handles)
3603web('https://www.legi.grenoble-inp.fr/servload/monika')
3604
3605
3606
3607function OutputSubDir_Callback(hObject, eventdata, handles)
3608set(handles.OutputSubDir,'BackgroundColor',[1 1 1])
3609
3610
3611% --- Executes on button press in CheckOverwrite.
3612function CheckOverwrite_Callback(hObject, eventdata, handles)
3613
3614
3615
3616% --- Executes on button press in TestCPUTime.
3617function TestCPUTime_Callback(hObject, eventdata, handles)
3618% hObject    handle to TestCPUTime (see GCBO)
3619% eventdata  reserved - to be defined in a future version of MATLAB
3620% handles    structure with handles and user data (see GUIDATA)
3621
3622
3623
3624
3625
Note: See TracBrowser for help on using the repository browser.