source: trunk/src/series.m @ 972

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

multitif updated

File size: 161.4 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
2716
2717function [TimeValue,DtValue]=get_time(ref_i,ref_j,PairString,InputTable,FileInfo,TimeName,DtName)
2718[i1,i2,j1,j2] = get_file_index(ref_i,ref_j,PairString);
2719FileName=fullfile_uvmat(InputTable{1},InputTable{2},InputTable{3},InputTable{5},InputTable{4},i1,i2,j1,j2);
2720Data=nc2struct(FileName,[]);
2721TimeValue=[];
2722DtValue=[];
2723if isequal(FileInfo.FileType,'civdata')
2724    if ismember(TimeName,{'civ1','filter1'})
2725        if isfield(Data,'Civ1_Time')
2726        TimeValue=Data.Civ1_Time;
2727        end
2728        if isfield(Data,'Civ1_Dt')
2729        DtValue=Data.Civ1_Dt;
2730        end
2731    else
2732        if isfield(Data,'Civ2_Time')
2733        TimeValue=Data.Civ2_Time;
2734        end
2735        if isfield(Data,'Civ2_Dt')
2736        DtValue=Data.Civ2_Dt;
2737        end
2738    end
2739else
2740    if ~isempty(TimeName)&& isfield(Data,TimeName)
2741        TimeValue=Data.(TimeName);
2742    end
2743    if exist('DtName','var') && isfield(Data,DtName)
2744        DtValue=Data.(DtName);
2745    end
2746end
2747
2748%------------------------------------------------------------------------
2749% --- Executes on selection change in FieldName_1.
2750function FieldName_1_Callback(hObject, eventdata, handles)
2751%------------------------------------------------------------------------
2752field_str=get(handles.FieldName_1,'String');
2753field_index=get(handles.FieldName_1,'Value');
2754field=field_str{field_index(1)};
2755if isequal(field,'get_field...')
2756    hget_field=findobj(allchild(0),'name','get_field');
2757    if ~isempty(hget_field)
2758        delete(hget_field)%delete opened versions of get_field
2759    end
2760    Param=read_GUI(handles.series);
2761    Param.InputTable=Param.InputTable(1,:);
2762    % check the existence of the first file in the series
2763    first_j=[];
2764    if isfield(Param.IndexRange,'first_j'); first_j=Param.IndexRange.first_j; end
2765    if isfield(Param.IndexRange,'last_j'); last_j=Param.IndexRange.last_j; end
2766    PairString='';
2767    if isfield(Param.IndexRange,'PairString'); PairString=Param.IndexRange.PairString; end
2768    [i1,i2,j1,j2] = get_file_index(Param.IndexRange.first_i,first_j,PairString);
2769    FirstFileName=fullfile_uvmat(Param.InputTable{1,1},Param.InputTable{1,2},Param.InputTable{1,3},...
2770        Param.InputTable{1,5},Param.InputTable{1,4},i1,i2,j1,j2);
2771    if exist(FirstFileName,'file')
2772        ParamIn.SeriesInput=1;
2773        GetFieldData=get_field(FirstFileName,ParamIn);
2774        FieldList={};
2775        switch GetFieldData.FieldOption
2776            case 'vectors'
2777                UName=GetFieldData.PanelVectors.vector_x;
2778                VName=GetFieldData.PanelVectors.vector_y;
2779                FieldList={['vec(' UName ',' VName ')'];...
2780                    ['norm(' UName ',' VName ')'];...
2781                    UName;VName};
2782            case {'scalar','pick variables'}
2783                FieldList=GetFieldData.PanelScalar.scalar;
2784                if ischar(FieldList)
2785                    FieldList={FieldList};
2786                end
2787            case '1D plot'
2788
2789            case 'civdata...'
2790                FieldList=set_field_list('U','V','C');
2791                set(handles.FieldName,'Value',2) % set menu to 'velocity
2792        end
2793        if ~strcmp(GetFieldData.FieldOption,'civdata...')
2794            TimeNameStr=GetFieldData.Time.SwitchVarIndexTime;
2795            switch TimeNameStr
2796                case 'file index'
2797                    set(handles.TimeName,'String','');
2798                case 'attribute'
2799                    set(handles.TimeName,'String',['att:' GetFieldData.Time.TimeName]);
2800                case 'variable'
2801                    set(handles.TimeName,'String',['var:' GetFieldData.Time.TimeName])
2802                    set(handles.NomType,'String','*')
2803                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])% A VERIFIER !!!!!!
2804                    set(handles.FileIndex,'String','')
2805                    ParamIn.TimeVarName=GetFieldData.Time.TimeName;
2806                case 'matrix_index'
2807                    set(handles.TimeName,'String',['dim:' GetFieldData.Time.TimeName]);
2808                    set(handles.NomType,'String','*')
2809                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
2810                    set(handles.FileIndex,'String','')
2811                    ParamIn.TimeDimName=GetFieldData.Time.TimeName;
2812            end
2813        end
2814        set(handles.FieldName_1,'Value',1)
2815        set(handles.FieldName_1,'String',[FieldList; {'get_field...'}]);
2816    end
2817end   
2818
2819
2820%%%%%%%%%%%%%
2821function [ind_remove]=find_pairs(dirpair,ind_i,last_i)
2822indsel=ind_i;
2823indiff=diff(ind_i); %test index increment to detect multiplets (several pairs with the same index ind_i) and holes in the series
2824indiff=[1 indiff last_i-ind_i(end)+1];%for testing gaps with the imposed bounds
2825if ~isempty(indiff)
2826    indiff2=diff(indiff);
2827    indiffp=[indiff2 1];
2828    indiffm=[1 indiff2];
2829    ind_multi_m=find((indiff==0)&(indiffm<0))-1;%indices of first members of multiplets
2830    ind_multi_p=find((indiff==0)&(indiffp>0));%indices of last members of multiplets
2831    %for each multiplet, select the most recent file
2832    ind_remove=[];
2833    for i=1:length(ind_multi_m)
2834        ind_pairs=ind_multi_m(i):ind_multi_p(i);
2835        for imulti=1:length(ind_pairs)
2836            datepair(imulti)=datenum(dirpair(ind_pairs(imulti)).date);%dates of creation
2837        end
2838        [datenew,indsort2]=sort(datepair); %sort the multiplet by creation date
2839        ind_s=indsort2(1:end-1);%
2840        ind_remove=[ind_remove ind_pairs(ind_s)];%remove these indices, leave the last one
2841    end
2842end
2843
2844%------------------------------------------------------------------------
2845% --- determine the list of index pairstring of processing file
2846function [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)
2847%------------------------------------------------------------------------
2848num_i1=num_i;% set of first image numbers by default
2849num_i2=num_i;
2850num_j1=num_j;
2851num_j2=num_j;
2852num_i_out=num_i;
2853num_j_out=num_j;
2854% if isequal (NomType,'_1-2_1') || isequal (NomType,'_1-2')
2855if isequal(mode,'series(Di)')
2856    num_i1_line=num_i+ind_shift(3);% set of first image numbers
2857    num_i2_line=num_i+ind_shift(4);
2858    % adjust the first and last field number
2859        indsel=find(num_i1_line >= 1);
2860    num_i_out=num_i(indsel);
2861    num_i1_line=num_i1_line(indsel);
2862    num_i2_line=num_i2_line(indsel);
2863    num_j1=meshgrid(num_j,ones(size(num_i1_line)));
2864    num_j2=meshgrid(num_j,ones(size(num_i1_line)));
2865    [xx,num_i1]=meshgrid(num_j,num_i1_line);
2866    [xx,num_i2]=meshgrid(num_j,num_i2_line);
2867elseif isequal (mode,'series(Dj)')||isequal (mode,'bursts')
2868    if isequal(mode,'bursts') %case of bursts (png_old or png_2D)
2869        num_j1=ind_shift(1)*ones(size(num_i));
2870        num_j2=ind_shift(2)*ones(size(num_i));
2871    else
2872        num_j1_col=num_j+ind_shift(1);% set of first image numbers
2873        num_j2_col=num_j+ind_shift(2);
2874        % adjust the first field number
2875        indsel=find((num_j1_col >= 1));   
2876        num_j_out=num_j(indsel);
2877        num_j1_col=num_j1_col(indsel);
2878        num_j2_col=num_j2_col(indsel);
2879        [num_i1,num_j1]=meshgrid(num_i,num_j1_col);
2880        [num_i2,num_j2]=meshgrid(num_i,num_j2_col);
2881    end   
2882end
2883
2884%------------------------------------------------------------------------
2885% --- Executes on button press in CheckObject.
2886function CheckObject_Callback(hObject, eventdata, handles)
2887%------------------------------------------------------------------------
2888hset_object=findobj(allchild(0),'tag','set_object');%find the set_object interface handle
2889if get(handles.CheckObject,'Value')
2890    SeriesData=get(handles.series,'UserData');
2891    if isfield(SeriesData,'ProjObject') && ~isempty(SeriesData.ProjObject)
2892        set(handles.ViewObject,'Value',1)
2893        ViewObject_Callback(hObject, eventdata, handles)
2894    else
2895        if ishandle(hset_object)
2896            uistack(hset_object,'top')% show the GUI set_object if opened
2897        else
2898            %get the object file
2899            InputTable=get(handles.InputTable,'Data');
2900            defaultname=InputTable{1,1};
2901            if isempty(defaultname)
2902                defaultname={''};
2903            end
2904            fileinput=uigetfile_uvmat('pick a xml object file (or use uvmat to create it)',defaultname,'.xml');
2905            if isempty(fileinput)% exit if no object file is selected
2906                set(handles.CheckObject,'Value',0)
2907                return
2908            end
2909            %read the file
2910            data=xml2struct(fileinput);
2911            if ~isfield(data,'Type')
2912                msgbox_uvmat('ERROR',[fileinput ' is not an object xml file'])
2913                set(handles.CheckObject,'Value',0)
2914                return
2915            end
2916            if ~isfield(data,'ProjMode')
2917                data.ProjMode='none';
2918            end
2919            hset_object=set_object(data);% call the set_object interface
2920            set(hset_object,'Name','set_object_series')% name to distinguish from set_object used with uvmat
2921        end
2922        ProjObject=read_GUI(hset_object);
2923        set(handles.ProjObject,'String',ProjObject.Name);%display the object name
2924        SeriesData=get(handles.series,'UserData');
2925        SeriesData.ProjObject=ProjObject;
2926        set(handles.series,'UserData',SeriesData);
2927    end
2928    set(handles.EditObject,'Visible','on');
2929    set(handles.DeleteObject,'Visible','on');
2930    set(handles.ViewObject,'Visible','on');
2931    set(handles.ProjObject,'Visible','on');
2932else
2933    set(handles.EditObject,'Visible','off');
2934    set(handles.DeleteObject,'Visible','off');
2935    set(handles.ViewObject,'Visible','off');
2936    if ~ishandle(hset_object)
2937        set(handles.ViewObject,'Value',0);
2938    end
2939    set(handles.ProjObject,'Visible','off');
2940end
2941
2942%------------------------------------------------------------------------
2943% --- Executes on button press in ViewObject.
2944%------------------------------------------------------------------------
2945function ViewObject_Callback(hObject, eventdata, handles)
2946
2947UserData=get(handles.series,'UserData');
2948hset_object=findobj(allchild(0),'Tag','set_object');
2949if ~isempty(hset_object)
2950    delete(hset_object)% refresh set_object if already opened
2951end
2952hset_object=set_object(UserData.ProjObject);
2953set(hset_object,'Name','view_object_series')
2954
2955
2956%------------------------------------------------------------------------
2957% --- Executes on button press in EditObject.
2958function EditObject_Callback(hObject, eventdata, handles)
2959%------------------------------------------------------------------------
2960if get(handles.EditObject,'Value')
2961    set(handles.ViewObject,'Value',0)
2962        UserData=get(handles.series,'UserData');
2963    hset_object=set_object(UserData.ProjObject);
2964    set(hset_object,'Name','edit_object_series')
2965    set(get(hset_object,'Children'),'Enable','on')
2966else
2967    hset_object=findobj(allchild(0),'Tag','set_object');
2968    if ~isempty(hset_object)
2969        set(get(hset_object,'Children'),'Enable','off')
2970    end
2971end
2972
2973%------------------------------------------------------------------------
2974% --- Executes on button press in DeleteObject.
2975function DeleteObject_Callback(hObject, eventdata, handles)
2976%------------------------------------------------------------------------
2977SeriesData=get(handles.series,'UserData');
2978SeriesData.ProjObject=[];
2979set(handles.series,'UserData',SeriesData)
2980set(handles.ProjObject,'String','')
2981set(handles.ProjObject,'Visible','off')
2982set(handles.CheckObject,'Value',0)
2983set(handles.ViewObject,'Visible','off')
2984set(handles.EditObject,'Visible','off')
2985hset_object=findobj(allchild(0),'name','set_object_series');
2986if ~isempty(hset_object)
2987    delete(hset_object)
2988end
2989set(handles.DeleteObject,'Visible','off')
2990
2991%------------------------------------------------------------------------
2992% --- Executed when CheckMask is activated
2993%------------------------------------------------------------------------
2994function CheckMask_Callback(hObject, eventdata, handles)
2995
2996if get(handles.CheckMask,'Value')
2997    InputTable=get(handles.InputTable,'Data');
2998    nbview=size(InputTable,1);
2999    MaskTable=cell(nbview,1);%default
3000    ListMask=cell(nbview,1);%default
3001    MaskData=get(handles.MaskTable,'Data');
3002    MaskData(size(MaskData,1):nbview,1)=cell(size(MaskData,1):nbview,1);%complement if undefined lines
3003    for iview=1:nbview
3004        ListMask{iview,1}=num2str(iview);
3005        RootPath=InputTable{iview,1};
3006        if ~isempty(RootPath)
3007            if isempty(MaskData{iview})
3008                SubDir=InputTable{iview,2};
3009                MaskPath=fullfile(RootPath,[regexprep(SubDir,'\..*','') '.mask']);%take the root part of SubDir, before the first dot '.'
3010                if exist(MaskPath,'dir')
3011                    ListStruct=dir(MaskPath);%look for a mask file
3012                    ListCells=struct2cell(ListStruct);% transform dir struct to a cell arrray
3013                    check_dir=cell2mat(ListCells(4,:));% =1 for directories, =0 for files
3014                    ListFiles=ListCells(1,:);%list of file and dri names
3015                    ListFiles=ListFiles(~check_dir);%list of file names (excluding dir)
3016                    mdetect=0;
3017                    if ~isempty(ListFiles)
3018                        for ifile=1:numel(ListFiles)
3019                            [tild,tild,MaskFile{ifile},i1_series,i2_series,j1_series,j2_series,MaskNomType,MaskFileType]=find_file_series(MaskPath,ListFiles{ifile},0);
3020                            if strcmp(MaskFileType,'image') && isempty(i2_series) && isempty(j2_series)
3021                                mdetect=1;
3022                                MaskName=ListFiles{ifile};
3023                            end
3024                            if ~strcmp(MaskFile{ifile},MaskFile{1})
3025                                mdetect=0;% cancel detection test in case of multiple masks, use the brower for selection
3026                                break
3027                            end
3028                        end
3029                    end
3030                    if mdetect==1
3031                        MaskName=fullfile(MaskPath,'mask_1.png');
3032                    else
3033                        MaskName=uigetfile_uvmat('select a mask file:',MaskPath,'image');
3034                    end
3035                else
3036                    MaskName=uigetfile_uvmat('select a mask file:',RootPath,'image');
3037                end
3038                MaskTable{iview,1}=MaskName ;
3039                ListMask{iview,1}=num2str(iview);
3040            end
3041        end
3042    end
3043    set(handles.MaskTable,'Data',MaskTable)
3044    set(handles.MaskTable,'Visible','on')
3045    set(handles.MaskBrowse,'Visible','on')
3046    set(handles.ListMask,'Visible','on')
3047    set(handles.ListMask,'String',ListMask)
3048    set(handles.ListMask,'Value',1)
3049else
3050    set(handles.MaskTable,'Visible','off')
3051    set(handles.MaskBrowse,'Visible','off')
3052    set(handles.ListMask,'Visible','off')
3053end
3054
3055%------------------------------------------------------------------------
3056% --- Executes on button press in MaskBrowse.
3057%------------------------------------------------------------------------
3058function MaskBrowse_Callback(hObject, eventdata, handles)
3059
3060InputTable=get(handles.InputTable,'Data');
3061iview=get(handles.ListMask,'Value');
3062RootPath=InputTable{iview,1};
3063MaskName=uigetfile_uvmat('select a mask file:',RootPath,'image');
3064if ~isempty(MaskName)
3065    MaskTable=get(handles.MaskTable,'Data');
3066    MaskTable{iview,1}=MaskName ;
3067    set(handles.MaskTable,'Data',MaskTable)
3068end
3069
3070%------------------------------------------------------------------------
3071% --- Executes when selected cell(s) is changed in MaskTable.
3072%------------------------------------------------------------------------
3073function MaskTable_CellSelectionCallback(hObject, eventdata, handles)
3074
3075if numel(eventdata.Indices)>=1
3076set(handles.ListMask,'Value',eventdata.Indices(1))
3077end
3078
3079%-------------------------------------------------------------------
3080function MenuHelp_Callback(hObject, eventdata, handles)
3081%-------------------------------------------------------------------
3082
3083
3084% path_to_uvmat=which ('uvmat');% check the path of uvmat
3085% pathelp=fileparts(path_to_uvmat);
3086% helpfile=fullfile(pathelp,'uvmat_doc','uvmat_doc.html');
3087% 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')
3088% else
3089%     addpath (fullfile(pathelp,'uvmat_doc'))
3090%     web([helpfile '#series'])
3091% end
3092
3093%-------------------------------------------------------------------
3094% --- Executes on selection change in TransformName.
3095function TransformName_Callback(hObject, eventdata, handles)
3096%----------------------------------------------------------------------
3097TransformList=get(handles.TransformName,'String');
3098TransformIndex=get(handles.TransformName,'Value');
3099TransformName=TransformList{TransformIndex};
3100TransformPathList=get(handles.TransformName,'UserData');
3101nb_builtin_transform=4;
3102if isequal(TransformName,'more...');     
3103    FileName=uigetfile_uvmat('Pick a transform function',get(handles.TransformPath,'String'),'.m');
3104    if isempty(FileName)
3105        return     %browser closed without choice
3106    end
3107    [TransformPath,TransformName,TransformExt]=fileparts(FileName);% removes extension .m
3108    if ~strcmp(TransformExt,'.m')
3109        msgbox_uvmat('ERROR','a Matlab function .m must be introduced');
3110        return
3111    end
3112     % insert the choice in the menu
3113    TransformIndex=find(strcmp(TransformName,TransformList),1);% look for the selected function in the menu Action
3114    if isempty(TransformIndex)%the input string does not exist in the menu
3115        TransformIndex= length(TransformList);
3116        TransformList=[TransformList(1:end-1);{TransformName};TransformList(end)];% the selected function is appended in the menu, before the last item 'more...'
3117        set(handles.TransformName,'String',TransformList)
3118        TransformPathList=[TransformPathList;{TransformPath}];
3119    else% the input function already exist, we update its path (possibly new)
3120        TransformPathList{TransformIndex}=TransformPath;%
3121        set(handles.TransformName,'Value',TransformIndex)
3122    end
3123   % save the new menu in the personal file 'uvmat_perso.mat'
3124   dir_perso=prefdir;%personal Matalb directory
3125   profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
3126   if exist(profil_perso,'file')
3127       for ilist=nb_builtin_transform+1:numel(TransformPathList)
3128           TransformListUser{ilist-nb_builtin_transform}=TransformList{ilist};
3129           TransformPathListUser{ilist-nb_builtin_transform}=TransformPathList{ilist};
3130       end
3131       TransformPathListUser=TransformPathListUser';
3132       TransformListUser=TransformListUser';
3133       save (profil_perso,'TransformPathListUser','TransformListUser','-append'); %store the root name for future opening of uvmat
3134   end
3135end
3136
3137%display the current function path
3138set(handles.TransformPath,'String',TransformPathList{TransformIndex}); %show the path to the senlected function
3139set(handles.TransformName,'UserData',TransformPathList);
3140
3141%% create the function handle of the selected fct
3142if ~isempty(TransformName)
3143    if ~exist(TransformPathList{TransformIndex},'dir')
3144        msgbox_uvmat('ERROR',['The prescribed transform function path ' TransformPathList{TransformIndex} ' does not exist']);
3145        return
3146    end
3147    current_dir=pwd;%current working dir
3148    cd(TransformPathList{TransformIndex})
3149    transform_handle=str2func(TransformName);
3150    cd(current_dir)
3151    Field.Action.RUN=0;% indicate that the transform fct is called only to get input param
3152    DataOut=feval(transform_handle,Field,[]);% execute the transform fct to get the required conditions
3153    if isfield(DataOut,'TransformInput')%  used to add transform parameters at selection of the transform fct
3154        SeriesData=get(handles.series,'UserData');
3155        SeriesData.TransformInput=DataOut.TransformInput;
3156        set(handles.series,'UserData',SeriesData)
3157    end
3158end
3159
3160%------------------------------------------------------------------------
3161% --- fct activated by the upper bar menu ExportConfig
3162%------------------------------------------------------------------------
3163function MenuDisplayConfig_Callback(hObject, eventdata, handles)
3164
3165global Param
3166Param=read_GUI_series(handles);
3167evalin('base','global Param')%make CurData global in the workspace
3168display('current series config :')
3169evalin('base','Param') %display CurData in the workspace
3170commandwindow; %brings the Matlab command window to the front
3171
3172%------------------------------------------------------------------------
3173% --- fct activated by the upper bar menu InportConfig: import
3174%     menu settings from an xml file (stored in /0_XML for each run)
3175%------------------------------------------------------------------------
3176function MenuImportConfig_Callback(hObject, eventdata, handles)
3177
3178%% use a browser to choose the xml file containing the processing config
3179InputTable=get(handles.InputTable,'Data');
3180oldfile=InputTable{1,1};%current path in InputTable
3181if isempty(oldfile)
3182    % use a file name stored in prefdir
3183    dir_perso=prefdir;
3184    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
3185    if exist(profil_perso,'file')
3186        h=load (profil_perso);
3187        if isfield(h,'RootPath') && ischar(h.RootPath)
3188            oldfile=h.RootPath;
3189        end
3190    end
3191end
3192filexml=uigetfile_uvmat('pick a xml parameter file',oldfile,'.xml');% get the xml file containing processing parameters
3193if isempty(filexml), return, end % quit function if an xml file has not been opened
3194
3195%% fill the GUI series with the content of the xml file
3196Param=xml2struct(filexml);% read the input xml file as a Matlab structure
3197
3198% ask to stop current Action if button RUN is in action (another process is already running)
3199if isequal(get(handles.RUN,'Value'),1)
3200    answer= msgbox_uvmat('INPUT_Y-N','stop current Action process?');
3201    if strcmp(answer,'Yes')
3202        STOP_Callback(hObject, eventdata, handles)
3203    else
3204        return
3205    end
3206end
3207Param.Action.RUN=0; %desactivate the input RUN=1
3208
3209fill_GUI(Param,handles.series)% fill the elements of the GUI series with the input parameters
3210SeriesData=get(handles.series,'UserData');
3211if isfield(Param,'InputFields')
3212    ListField=Param.InputFields.FieldName;
3213    if ischar(ListField),ListField={ListField}; end
3214    set(handles.FieldName,'String',[ListField;{'get-field...'}])
3215     set(handles.FieldName,'Value',1:numel(ListField))
3216     set(handles.FieldName,'Visible','on')
3217end       
3218if isfield(Param,'ActionInput')%  introduce  parameters specific to an Action fct, for instance PIV parameters
3219    set(handles.ActionInput,'Visible','on')
3220    set(handles.ActionInput,'Value',0)
3221    Param.ActionInput.ConfigSource=filexml;% record the source of config for future info
3222    SeriesData.ActionInput=Param.ActionInput;
3223end
3224if isfield(Param,'TransformInput')%  introduce  parameters specific to a transform fct
3225    SeriesData.TransformInput=Param.TransformInput;
3226end
3227if isfield(Param,'ProjObject') %introduce projection object if relevant
3228    SeriesData.ProjObject=Param.ProjObject;
3229end
3230set(handles.series,'UserData',SeriesData)
3231if isfield(Param,'CheckObject') && isequal(Param.CheckObject,1)
3232    set(handles.ProjObject,'String',Param.ProjObject.Name)
3233    set(handles.ViewObject,'Visible','on')
3234    set(handles.EditObject,'Visible','on')
3235    set(handles.DeleteObject,'Visible','on')
3236else     
3237    set(handles.ProjObject,'String','')
3238    set(handles.ProjObject,'Visible','off')
3239    set(handles.ViewObject,'Visible','off')
3240    set(handles.EditObject,'Visible','off')
3241    set(handles.DeleteObject,'Visible','off')     
3242end     
3243set(handles.REFRESH,'BackgroundColor',[1 0 1]); %paint REFRESH button in magenta to indicate that it should be activated
3244
3245
3246%------------------------------------------------------------------------
3247% --- Executes when the GUI series is resized.
3248%------------------------------------------------------------------------
3249function series_ResizeFcn(hObject, eventdata, handles)
3250
3251%% input table
3252set(handles.InputTable,'Unit','pixel')
3253Pos=get(handles.InputTable,'Position');
3254set(handles.InputTable,'Unit','normalized')
3255ColumnWidth=round([0.5 0.14 0.14 0.14 0.08]*(Pos(3)-52));
3256ColumnWidth=num2cell(ColumnWidth);
3257set(handles.InputTable,'ColumnWidth',ColumnWidth)
3258
3259%% MinIndex_j and MaxIndex_i
3260unit=get(handles.MinIndex_i,'Unit');
3261set(handles.MinIndex_i,'Unit','pixel')
3262Pos=get(handles.MinIndex_i,'Position');
3263set(handles.MinIndex_i,'Unit',unit)
3264set(handles.MinIndex_i,'ColumnWidth',{Pos(3)-18})
3265set(handles.MaxIndex_i,'ColumnWidth',{Pos(3)-18})
3266set(handles.MinIndex_j,'ColumnWidth',{Pos(3)-18})
3267set(handles.MaxIndex_j,'ColumnWidth',{Pos(3)-18})
3268
3269%% TimeTable
3270set(handles.TimeTable,'Unit','pixel')
3271Pos=get(handles.TimeTable,'Position');
3272set(handles.TimeTable,'Unit','normalized')
3273% ColumnWidth=get(handles.TimeTable,'ColumnWidth');
3274ColumnWidth=num2cell(floor([0.2 0.2 0.2 0.2 0.2]*(Pos(3)-20)));
3275set(handles.TimeTable,'ColumnWidth',ColumnWidth)
3276
3277
3278%% PairString
3279set(handles.PairString,'Unit','pixel')
3280Pos=get(handles.PairString,'Position');
3281set(handles.PairString,'Unit','normalized')
3282set(handles.PairString,'ColumnWidth',{Pos(3)-5})
3283
3284%% MaskTable
3285set(handles.MaskTable,'Unit','pixel')
3286Pos=get(handles.MaskTable,'Position');
3287set(handles.MaskTable,'Unit','normalized')
3288set(handles.MaskTable,'ColumnWidth',{Pos(3)-5})
3289
3290%------------------------------------------------------------------------
3291% --- Executes on button press in status.
3292%------------------------------------------------------------------------
3293function status_Callback(hObject, eventdata, handles)
3294
3295if get(handles.status,'Value')
3296    set(handles.status,'BackgroundColor',[1 1 0])
3297    drawnow
3298    Param=read_GUI(handles.series);
3299    RootPath=Param.InputTable{1,1};
3300    if ~isfield(Param,'OutputSubDir')   
3301        msgbox_uvmat('ERROR','no standard sub-directory definition for output files, use a browser to check the output')
3302        set(handles.status,'BackgroundColor',[0 1 0])
3303        return
3304    end
3305    OutputSubDir=[Param.OutputSubDir Param.OutputDirExt];% subdirectory for output files
3306    OutputDir=fullfile(RootPath,OutputSubDir);
3307    if exist(OutputDir,'dir')
3308        uigetfile_uvmat('status_display',OutputDir)
3309    else
3310        msgbox_uvmat('ERROR','output folder not created yet: calculation did not start')
3311        set(handles.status,'BackgroundColor',[0 1 0])
3312    end
3313else
3314    %% delete current display fig if selection is off
3315    set(handles.status,'BackgroundColor',[0 1 0])
3316    hfig=findobj(allchild(0),'name','status_display');
3317    if ~isempty(hfig)
3318        delete(hfig)
3319    end
3320    return
3321end
3322
3323
3324%------------------------------------------------------------------------   
3325% launched by selecting a file on the list
3326%------------------------------------------------------------------------
3327function view_file(hObject, eventdata)
3328
3329list=get(hObject,'String');
3330index=get(hObject,'Value');
3331rootroot=get(hObject,'UserData');
3332selectname=list{index};
3333ind_dot=regexp(selectname,'\.\.\.');
3334if ~isempty(ind_dot)
3335    selectname=selectname(1:ind_dot-1);
3336end
3337FullSelectName=fullfile(rootroot,selectname);
3338if exist(FullSelectName,'dir')% a directory has been selected
3339    ListFiles=dir(FullSelectName);
3340    ListDisplay=cell(numel(ListFiles),1);
3341    for ilist=2:numel(ListDisplay)% suppress the first line '.'
3342        ListDisplay{ilist-1}=ListFiles(ilist).name;
3343    end
3344    set(hObject,'Value',1)
3345    set(hObject,'String',ListDisplay)
3346    if strcmp(selectname,'..')
3347        FullSelectName=fileparts(fileparts(FullSelectName));
3348    end
3349    set(hObject,'UserData',FullSelectName)
3350    hfig=get(hObject,'parent');
3351    htitlebox=findobj(hfig,'tag','titlebox');   
3352    set(htitlebox,'String',FullSelectName)
3353elseif exist(FullSelectName,'file')%visualise the vel field if it exists
3354    FileInfo=get_file_info(FullSelectName);   
3355    if strcmp(FileInfo.FileType,'txt')
3356        edit(FullSelectName)
3357    elseif strcmp(FileInfo.FileType,'xml')
3358        editxml(FullSelectName)
3359    else
3360        uvmat(FullSelectName)
3361    end
3362    set(gcbo,'Value',1)
3363end
3364
3365
3366%------------------------------------------------------------------------   
3367% launched by refreshing the status figure
3368%------------------------------------------------------------------------
3369function refresh_GUI(hfig)
3370
3371htitlebox=findobj(hfig,'tag','titlebox');
3372hlist=findobj(hfig,'tag','list');
3373hseries=findobj(allchild(0),'tag','series');
3374hstatus=findobj(hseries,'tag','status');
3375StatusData=get(hstatus,'UserData');
3376OutputDir=get(htitlebox,'String');
3377if ischar(OutputDir),OutputDir={OutputDir};end
3378ListFiles=dir(OutputDir{1});
3379if numel(ListFiles)<1
3380    return
3381end
3382ListFiles(1)=[];%removes the first line ='.'
3383ListDisplay=cell(numel(ListFiles),1);
3384testrecent=0;
3385datnum=zeros(numel(ListDisplay),1);
3386for ilist=1:numel(ListDisplay)
3387    ListDisplay{ilist}=ListFiles(ilist).name;
3388      if ~ListFiles(ilist).isdir && isfield(ListFiles(ilist),'datenum')
3389            datnum(ilist)=ListFiles(ilist).datenum;%only available in recent matlab versions
3390            testrecent=1;
3391       end
3392end
3393set(hlist,'String',ListDisplay)
3394
3395%% Look at date of creation
3396ListDisplay=ListDisplay(datnum~=0);
3397datnum=datnum(datnum~=0);%keep the non zero values corresponding to existing files
3398NbOutputFile=[];
3399if isempty(datnum)
3400    if testrecent
3401        message='no civ result created yet';
3402    else
3403        message='';
3404    end
3405else
3406    [first,indfirst]=min(datnum);
3407    [last,indlast]=max(datnum);
3408    NbOutputFile_str='?';
3409    NbOutputFile=[];
3410    if isfield(StatusData,'NbOutputFile')
3411        NbOutputFile=StatusData.NbOutputFile;
3412        NbOutputFile_str=num2str(NbOutputFile);
3413    end
3414    message={[num2str(numel(datnum)) ' file(s) done over ' NbOutputFile_str] ;['oldest modification:  ' ListDisplay{indfirst} ' : ' datestr(first)];...
3415        ['latest modification:  ' ListDisplay{indlast} ' : ' datestr(last)]};
3416end
3417set(htitlebox,'String', [OutputDir{1};message])
3418
3419%% update the waitbar
3420hwaitbar=findobj(hfig,'tag','waitbar');
3421if ~isempty(NbOutputFile)
3422    BarPosition=get(hwaitbar,'Position');
3423    BarPosition(3)=0.9*numel(datnum)/NbOutputFile;
3424    set(hwaitbar,'Position',BarPosition)
3425end
3426
3427%------------------------------------------------------------------------
3428% --- Executes on selection change in ActionExt.
3429%------------------------------------------------------------------------
3430function ActionExt_Callback(hObject, eventdata, handles)
3431
3432ActionExtList=get(handles.ActionExt,'String');
3433ActionExt=ActionExtList{get(handles.ActionExt,'Value')};
3434if strcmp(ActionExt,'.py (in dev.)')
3435    set(handles.RunMode,'Value',2)
3436end
3437
3438%function num_NbProcess_Callback(hObject, eventdata, handles)
3439
3440
3441function num_NbSlice_Callback(hObject, eventdata, handles)
3442NbSlice=str2num(get(handles.num_NbSlice,'String'));
3443%set(handles.num_NbProcess,'String',num2str(NbSlice))
3444
3445%------------------------------------------------------------------------
3446% --- set the visibility of relevant velocity type menus:
3447function menu=set_veltype_display(Civ,FileType)
3448%------------------------------------------------------------------------
3449if ~exist('FileType','var')
3450    FileType='civx';
3451end
3452switch FileType
3453    case 'civx'
3454        menu={'civ1';'interp1';'filter1';'civ2';'interp2';'filter2'};
3455        if isequal(Civ,0)
3456            imax=0;
3457        elseif isequal(Civ,1) || isequal(Civ,2)
3458            imax=1;
3459        elseif isequal(Civ,3)
3460            imax=3;
3461        elseif isequal(Civ,4) || isequal(Civ,5)
3462            imax=4;
3463        elseif isequal(Civ,6) %patch2
3464            imax=6;
3465        end
3466    case 'civdata'
3467        menu={'civ1';'filter1';'civ2';'filter2'};
3468        if isequal(Civ,0)
3469            imax=0;
3470        elseif isequal(Civ,1) || isequal(Civ,2)
3471            imax=1;
3472        elseif isequal(Civ,3)
3473            imax=2;
3474        elseif isequal(Civ,4) || isequal(Civ,5)
3475            imax=3;
3476        else%if isequal(Civ,6) %patch2
3477            imax=4;
3478        end
3479end
3480menu=menu(1:imax);
3481
3482
3483% --- Executes on mouse motion over figure - except title and menu.
3484function series_WindowButtonMotionFcn(hObject, eventdata, handles)
3485set(hObject,'Pointer','arrow');
3486
3487
3488% --- Executes on button press in SetPairs.
3489function SetPairs_Callback(hObject, eventdata, handles)
3490
3491%% delete previous occurrence of 'set_pairs'
3492hfig=findobj(allchild(0),'Tag','set_pairs');
3493if ~isempty(hfig)
3494delete(hfig)
3495end
3496
3497%% create the GUI set_pairs
3498set(0,'Unit','points')
3499ScreenSize=get(0,'ScreenSize');% get the size of the screen, to put the fig on the upper right
3500Width=220;% fig width in points (1/72 inch)
3501Height=min(0.8*ScreenSize(4),300);
3502Left=ScreenSize(3)- Width-40; %right edge close to the right, with margin=40
3503Bottom=ScreenSize(4)-Height-40; %put fig at top right
3504hfig=findobj(allchild(0),'Tag','set_slice');
3505if ~isempty(hfig),delete(hfig), end; %delete existing version of the GUI
3506hfig=figure('name','set_pairs','tag','set_pairs','MenuBar','none','NumberTitle','off','Unit','points','Position',[Left,Bottom,Width,Height]);
3507BackgroundColor=get(hfig,'Color');
3508SeriesData=get(handles.series,'UserData');
3509TimeUnit=get(handles.TimeUnit,'String');
3510PairString=get(handles.PairString,'Data');
3511ListViewLines=find(cellfun('isempty',PairString)==0);%find list of non empty pairs
3512ListViewMenu=cell(numel(ListViewLines),1);
3513iview=get(handles.PairString,'Value');
3514for ilist=1:numel(ListViewLines)
3515    ListViewMenu{ilist}=num2str(ListViewLines(ilist));
3516end
3517if isempty(iview)
3518    ListViewValue=numel(ListViewLines);% we work by default on the pair option for the last line which requires pairs
3519    iview=ListViewLines(end);
3520else
3521    ListViewValue=find(ListViewLines==iview);
3522end
3523ref_i=str2num(get(handles.num_first_i,'String'));
3524ref_j=1;%default
3525if strcmp(get(handles.num_first_j,'String'),'Visible')
3526    ref_j=str2num(get(handles.num_first_j,'String'));
3527end
3528[ModeMenu,ModeValue]=update_mode(SeriesData.i1_series{iview},SeriesData.i2_series{iview},SeriesData.j2_series{iview});
3529displ_pair=update_listpair(SeriesData.i1_series{iview},SeriesData.i2_series{iview},SeriesData.j1_series{iview},SeriesData.j2_series{iview},ModeMenu{ModeValue},...
3530                                                     SeriesData.Time{iview},TimeUnit,ref_i,ref_j,SeriesData.FileInfo{iview});
3531% first raw of the GUI
3532uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.88 0.5 0.1],'BackgroundColor',BackgroundColor,...
3533    'String','row to edit #','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','right');%title
3534uicontrol('Style','popupmenu','Units','normalized', 'Position', [0.54 0.8 0.3 0.2],'BackgroundColor',[1 1 1],...
3535    'Callback',@(hObject,eventdata)ListView_Callback(hObject,eventdata),'String',ListViewMenu,'Value',ListViewValue,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3536    'Tag','ListView','TooltipString','''ListView'':choice of the file series w for pair display');
3537% second raw of the GUI
3538uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.79 0.7 0.1],'BackgroundColor',BackgroundColor,...
3539    'String','mode of index pairing:','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','left');%title
3540uicontrol('Style','popupmenu','Units','normalized', 'Position', [0.05 0.62 0.9 0.2],'BackgroundColor',[1 1 1],...
3541    'Callback',@(hObject,eventdata)Mode_Callback(hObject,eventdata),'String',ModeMenu,'Value',ModeValue,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3542    'Tag','Mode','TooltipString','''Mode'': choice of the image pair mode');
3543% third raw
3544uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.6 0.7 0.1],'BackgroundColor',BackgroundColor,...
3545    'String','pair choice:','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','left');%title
3546uicontrol('Style','listbox','Units','normalized', 'Position', [0.05 0.42 0.9 0.2],'BackgroundColor',[1 1 1],...
3547    'Callback',@(hObject,eventdata)ListPair_Callback(hObject,eventdata),'String',displ_pair,'Value',1,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3548    'Tag','ListPair','TooltipString','''ListPair'': menu for selecting the image pair');
3549uicontrol('Style','text','Units','normalized', 'Position', [0.1 0.22 0.8 0.1],'BackgroundColor',BackgroundColor,...
3550    'String','ref_i           ref_j','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','center');%title
3551uicontrol('Style','edit','Units','normalized', 'Position', [0.15 0.17 0.3 0.08],'BackgroundColor',[1 1 1],...
3552    'Callback',@(hObject,eventdata)num_ref_i_Callback(hObject,eventdata),'String',num2str(ref_i),'FontUnits','points','FontSize',12,'FontWeight','bold',...
3553    'Tag','num_ref_i','TooltipString','''num_ref_i'': reference field index i used to display dt in ''list_pair_civ''');
3554uicontrol('Style','edit','Units','normalized', 'Position', [0.55 0.17 0.3 0.08],'BackgroundColor',[1 1 1],...
3555    'Callback',@(hObject,eventdata)num_ref_j_Callback(hObject,eventdata),'String',num2str(ref_j),'FontUnits','points','FontSize',12,'FontWeight','bold',...
3556    'Tag','num_ref_j','TooltipString','''num_ref_j'': reference field index i used to display dt in ''list_pair_civ''');
3557uicontrol('Style','pushbutton','Units','normalized', 'Position', [0.01 0.01 0.3 0.12],'BackgroundColor',[0 1 0],...
3558    'Callback',@(hObject,eventdata)OK_Callback(hObject,eventdata),'String','OK','FontUnits','points','FontSize',12,'FontWeight','bold',...
3559    'Tag','OK','TooltipString','''OK'': validate the choice');
3560%  last raw  of the GUI: pushbuttons
3561% 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),...
3562%     'FontWeight','bold','FontUnits','points','FontSize',12,'TooltipString','''OK'': apply the output to the current field series in uvmat');
3563drawnow
3564
3565%------------------------------------------------------------------------
3566function ListView_Callback(hObject,eventdata)
3567Mode_Callback(hObject,eventdata)
3568
3569%------------------------------------------------------------------------   
3570function Mode_Callback(hObject,eventdata)
3571%% get input info
3572hseries=findobj(allchild(0),'tag','series');%handles of the GUI series
3573hhseries=guidata(hseries);%handles of the elements in the GUI series
3574TimeUnit=get(hhseries.TimeUnit,'String');
3575SeriesData=get(hseries,'UserData');
3576mode_list=get(hObject,'String');
3577mode=mode_list{get(hObject,'Value')};
3578hListView=findobj(get(hObject,'parent'),'Tag','ListView');
3579iview=get(hListView,'Value');
3580i1_series=SeriesData.i1_series{iview};
3581i2_series=SeriesData.i2_series{iview};
3582j1_series=SeriesData.j1_series{iview};
3583j2_series=SeriesData.j2_series{iview};
3584
3585%% enable j index visibility after the new choice
3586status_j='on';%default
3587if isempty(find(~cellfun(@isempty,SeriesData.j1_series), 1)); % case of empty j indices
3588    status_j='off'; % no j index needed
3589elseif strcmp(get(handles.PairString,'Visible'),'on')
3590    check_burst=cellfun(@isempty,regexp(PairString,'^j'));%=0 for burst case, 1 otherwise
3591    if isempty(find(check_burst, 1))% if all pair string begins by j (burst)
3592        status_j='off'; % no j index needed for bust case
3593    end
3594end
3595enable_j(handles,status_j) % no j index needed
3596
3597%% get the reference indices for the time interval Dt
3598href_i=findobj(get(hObject,'parent'),'Tag','ref_i');
3599ref_i=[];ref_j=[];
3600if strcmp(get(href_i,'Visible'),'on')
3601    ref_i=str2num(get(href_i,'String'));
3602end
3603if isempty(ref_i)
3604    ref_i=1;
3605end
3606if isempty(ref_j)
3607    ref_j=1;
3608end
3609
3610%% update the menu ListPair
3611Menu=update_listpair(i1_series,i2_series,j1_series,j2_series,mode,SeriesData.Time{iview},TimeUnit,ref_i,ref_j,FileInfo);
3612hlist_pairs=findobj(get(hObject,'parent'),'Tag','ListPair');
3613set(hlist_pairs,'Value',1)% set the first choice by default in ListPair
3614set(hlist_pairs,'String',Menu)% set the menu in ListPair
3615ListPair_Callback(hlist_pairs,[])% apply the default choice in ListPair
3616
3617%-------------------------------------------------------------
3618% --- Executes on selection in ListPair.
3619function ListPair_Callback(hObject,eventdata)
3620%------------------------------------------------------------
3621list_pair=get(hObject,'String');%get the menu of image pairs
3622if isempty(list_pair)
3623    string='';
3624else
3625    string=list_pair{get(hObject,'Value')};
3626   % string=regexprep(string,',.*','');%removes time indication (after ',')
3627end
3628hseries=findobj(allchild(0),'tag','series');
3629hPairString=findobj(hseries,'tag','PairString');
3630PairString=get(hPairString,'Data');
3631hListView=findobj(get(hObject,'parent'),'Tag','ListView');
3632iview=get(hListView,'Value');
3633PairString{iview,1}=string;
3634% report the selected pair string to the table PairString
3635set(hPairString,'Data',PairString)
3636
3637
3638%------------------------------------------------------------------------
3639function num_ref_i_Callback(hObject, eventdata)
3640%------------------------------------------------------------------------
3641Mode_Callback([],[])
3642
3643%------------------------------------------------------------------------
3644function num_ref_j_Callback(hObject, eventdata)
3645%------------------------------------------------------------------------
3646Mode_Callback([],[])
3647
3648%------------------------------------------------------------------------
3649function OK_Callback(hObject, eventdata)
3650%------------------------------------------------------------------------
3651delete(get(hObject,'parent'))
3652
3653
3654%------------------------------------------------------------------------
3655% --- Executes on button press in ClearLine.
3656%------------------------------------------------------------------------
3657function ClearLine_Callback(hObject, eventdata, handles)
3658InputTable=get(handles.InputTable,'Data');
3659iline=str2double(get(handles.InputLine,'String'));
3660if size(InputTable,1)>1
3661    InputTable(iline,:)=[];% suppress the current line if not the first
3662    set(handles.InputTable,'Data',InputTable);
3663end
3664set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH button to magenta color to indicate that input refr
3665
3666
3667% --- Executes on button press in MonitorCluster.
3668function MonitorCluster_Callback(hObject, eventdata, handles)
3669web('https://www.legi.grenoble-inp.fr/servload/monika')
3670
3671
3672
3673function OutputSubDir_Callback(hObject, eventdata, handles)
3674set(handles.OutputSubDir,'BackgroundColor',[1 1 1])
3675
3676
3677% --- Executes on button press in CheckOverwrite.
3678function CheckOverwrite_Callback(hObject, eventdata, handles)
3679
3680
3681
3682% --- Executes on button press in TestCPUTime.
3683function TestCPUTime_Callback(hObject, eventdata, handles)
3684% hObject    handle to TestCPUTime (see GCBO)
3685% eventdata  reserved - to be defined in a future version of MATLAB
3686% handles    structure with handles and user data (see GUIDATA)
3687
3688
3689
3690
3691
Note: See TracBrowser for help on using the repository browser.