source: trunk/src/series.m @ 922

Last change on this file since 922 was 922, checked in by sommeria, 5 years ago

corrections quentin

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