source: trunk/src/series.m @ 989

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