source: trunk/src/series.m @ 923

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