source: trunk/src/series.m @ 985

Last change on this file since 985 was 984, checked in by sommeria, 8 years ago

introduce .cine in various functions, improve stero PIV

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