source: trunk/src/series.m @ 965

Last change on this file since 965 was 963, checked in by sommeria, 8 years ago

series adapted to level

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