source: trunk/src/series.m @ 919

Last change on this file since 919 was 919, checked in by sommeria, 7 years ago

netcdf files stored in 32 bits (not double)

File size: 161.7 KB
Line 
1%'series': master function associated to the GUI series.m for analysis field series 
2%------------------------------------------------------------------------
3% function varargout = series(varargin)
4% associated with the GUI series.fig
5%
6%INPUT
7% param: structure with input parameters (link with the GUI uvmat)
8%      .menu_coord_str: string for the TransformName (menu for coordinate transforms)
9%      .menu_coord_val: value for TransformName (menu for coordinate transforms)
10%      .FileName: input file name
11%      .FileName_1: second input file name
12%      .list_field: menu of input fields
13%      .index_fields: chosen index
14%      .civ1=0 or 1, .interp1,  ... : input civ field type
15%
16%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    hver=ver('MATLAB');
1513    MCRROOT=['MCRROOT' regexprep(hver.Version,'\.','')];%suppress the dot in version number
1514    RunTime = getenv(MCRROOT);
1515    ActionNameVersion=[ActionName '_' MCRROOT];
1516    ActionFullName=fullfile(get(handles.ActionPath,'String'),[ActionNameVersion '.sh']);
1517    if ~exist(ActionFullName,'file')
1518        answer=msgbox_uvmat('INPUT_Y-N','compiled version has not been created: compile now?');
1519        if strcmp(answer,'Yes')
1520            set(handles.ActionExt,'BackgroundColor',[1 1 0])
1521            path_uvmat=fileparts(which('series'));
1522            currentdir=pwd;
1523            cd(get(handles.ActionPath,'String'))% go to the directory of Action
1524            addpath(path_uvmat)% add the path to uvmat to run the fct 'compile'
1525            compile(ActionName,TransformPath)
1526            cd(currentdir)
1527        else
1528            errormsg='Action launch interrupted';
1529            return
1530        end       
1531    else
1532        sh_file_info=dir(fullfile(get(handles.ActionPath,'String'),[ActionNameVersion '.sh']));
1533        m_file_info=dir(fullfile(get(handles.ActionPath,'String'),[ActionName '.m']));
1534        if isfield(m_file_info,'datenum') && m_file_info.datenum>sh_file_info.datenum
1535            set(handles.ActionExt,'BackgroundColor',[1 1 0])
1536            drawnow
1537            answer=msgbox_uvmat('INPUT_Y-N',[ActionNameVersion '.sh needs to be updated: recompile now?']);
1538            if strcmp(answer,'Yes')
1539                path_uvmat=fileparts(which('series'));
1540                currentdir=pwd;
1541                cd(get(handles.ActionPath,'String'))% go to the directory of Action
1542                addpath(path_uvmat)% add the path to uvmat to run the fct 'compile'
1543                addpath(fullfile(path_uvmat,'transform_field'))% add the path to uvmat to run the fct 'compile'
1544                compile(ActionName,TransformPath)
1545                cd(currentdir)
1546            end
1547        end
1548    end
1549    set(handles.ActionExt,'BackgroundColor',[1 1 1])
1550     set(handles.series,'Pointer','arrow') % set the mouse pointer to 'watch
1551end
1552
1553%% set nbre of cluster cores and processes:
1554% NbCore is the number of computer processors used
1555% NbProcess is the number of independent processes in which the required calculation is split.
1556switch RunMode
1557    case {'local','background'}
1558        NbCore=1;% no need to split the calculation
1559    case 'cluster_oar'
1560        if strcmp(ActionExt,'.m')% case of Matlab function (uncompiled)
1561            NbCore=1;% one core used only (limitation of Matlab licences)
1562            answer=msgbox_uvmat('INPUT_Y-N','Number of cores =1: select the compiled version .sh for multi-core processing. Proceed with the .m version?');
1563            if ~strcmp(answer,'Yes')
1564                errormsg='Action launch interrupted by user';
1565                return
1566            end
1567            extra_oar='';
1568        else
1569            answer=inputdlg({'Number of cores (max 36)','extra oar options'},'oarsub parameter',1,{'12',''});
1570            if isempty(answer)
1571                                errormsg='Action launch interrupted by user';
1572                return
1573            end
1574            NbCore=str2double(answer{1});
1575            extra_oar=answer{2};
1576        end
1577    case 'cluster_pbs'
1578        if strcmp(ActionExt,'.m')% case of Matlab function (uncompiled)
1579            NbCore=1;% one core used only (limitation of Matlab licences)
1580            answer=msgbox_uvmat('INPUT_Y-N','Number of cores =1: select the compiled version .sh for multi-core processing. Proceed with the .m version?');
1581            if ~strcmp(answer,'Yes')
1582                errormsg='Action launch interrupted';
1583                return
1584            end
1585            extra_oar='';
1586        else
1587            answer=inputdlg({'Number of cores (max 36)','extra oar options'},'oarsub parameter',1,{'12',''});
1588            NbCore=str2double(answer{1});
1589            %extra_oar=answer{2};%TODO : fix this for LMFA cluster. Maybe
1590            %extrs_oar and extra_pbs are not the best names
1591        end
1592end
1593if ~isfield(Param.IndexRange,'NbSlice')
1594    Param.IndexRange.NbSlice=[];
1595end
1596
1597%% create the output data directory if needed
1598OutputDir='';
1599if isfield(Param,'OutputSubDir')
1600    SubDirOut=[get(handles.OutputSubDir,'String') Param.OutputDirExt];
1601    SubDirOutNew=SubDirOut;
1602    detect=exist(fullfile(Param.InputTable{1,1},SubDirOutNew),'dir');% test if  the dir  already exist
1603    check_create=1; %need to create the result directory by default
1604    CheckOverwrite=1;
1605    if isfield(Param,'CheckOverwrite')
1606        CheckOverwrite=Param.CheckOverwrite;
1607    end
1608    while detect
1609        if CheckOverwrite
1610            comment=', possibly overwrite previous data';
1611        else
1612            comment=', will complement existing result files (no overwriting)';
1613        end
1614        answer=msgbox_uvmat('INPUT_Y-N-Cancel',['use existing ouput directory: ' fullfile(Param.InputTable{1,1},SubDirOutNew) comment]);
1615        if strcmp(answer,'Cancel')
1616            return
1617        elseif strcmp(answer,'Yes')
1618            detect=0;
1619            check_create=0;
1620        else
1621            r=regexp(SubDirOutNew,'(?<root>.*\D)(?<num1>\d+)$','names');%detect whether name ends by a number
1622            if isempty(r)
1623                r(1).root=[SubDirOutNew '_'];
1624                r(1).num1='0';
1625            end
1626            SubDirOutNew=[r(1).root num2str(str2num(r(1).num1)+1)];%increment the index by 1 or put 1
1627            detect=exist(fullfile(Param.InputTable{1,1},SubDirOutNew),'dir');% test if  the dir  already exists
1628            check_create=1;
1629        end
1630    end
1631    Param.OutputDirExt=regexprep(SubDirOutNew,Param.OutputSubDir,'');
1632    Param.OutputRootFile=Param.InputTable{1,3};% the first sorted RootFile taken for output
1633    set(handles.OutputDirExt,'String',Param.OutputDirExt)
1634    OutputDir=fullfile(Param.InputTable{1,1},[Param.OutputSubDir Param.OutputDirExt]);% full name (with path) of output directory
1635    if check_create    % create output directory if it does not exist
1636        [tild,msg1]=mkdir(OutputDir);
1637        if ~strcmp(msg1,'')
1638            errormsg=['cannot create ' OutputDir ': ' msg1];%error message for directory creation
1639            return
1640        end
1641        [success,msg] = fileattrib(OutputDir,'+w','g','s');% allow writing access for the group of users, recursively in the folder 
1642        if success==0
1643            msgbox_uvmat('WARNING',{['unable to set group write access to ' OutputDir ':']; msg1});%error message for directory creation
1644        end
1645    end
1646   
1647elseif isfield(Param,'ActionInput')&&isfield(Param.ActionInput,'LogPath')% custom definition of the output dir
1648    OutputDir=Param.ActionInput.LogPath;   
1649end
1650DirXml=fullfile(OutputDir,'0_XML');
1651if ~exist(DirXml,'dir')
1652    [tild,msg1]=mkdir(DirXml);
1653    if ~strcmp(msg1,'')
1654        errormsg=['cannot create ' DirXml ': ' msg1];%error message for directory creation
1655        return
1656    end
1657    [success,msg] = fileattrib(DirXml,'+w','g','s');% allow writing access for the group of users, recursively in the folder
1658    if success==0
1659        msgbox_uvmat('WARNING',{['unable to set group write access to ' DirXml ':']; msg});%error message for directory creation
1660    end
1661end
1662OutputNomType=nomtype2pair(Param.InputTable{1,4});% nomenclature for output files
1663
1664%% get the set of reference input field indices
1665first_i=1;% first i index to process
1666last_i=1;% last i index to process
1667incr_i=1;% increment step in i index
1668first_j=1;% first j index to process
1669last_j=1;% last j index to process
1670incr_j=1;% increment step in j index
1671if isfield(Param.IndexRange,'first_i')
1672    first_i=Param.IndexRange.first_i;
1673    incr_i=Param.IndexRange.incr_i;
1674    last_i=Param.IndexRange.last_i;
1675end
1676if isfield(Param.IndexRange,'first_j')
1677    first_j=Param.IndexRange.first_j;
1678    last_j=Param.IndexRange.last_j;
1679    incr_j=Param.IndexRange.incr_j;
1680end
1681if last_i < first_i || last_j < first_j
1682    errormsg= 'series/Run_Callback:last field index must be larger or equal to the first one';
1683    return
1684end
1685%incr_i must be defined, =1 by default, if NbSlice is active
1686if isempty(incr_i)&& ~isempty(Param.IndexRange.NbSlice)
1687    incr_i=1;
1688    set(handles.num_incr_i,'String','1')
1689end
1690% case of no increment i defined: processing is done on the available files found in i1_series
1691if isempty(incr_i)
1692    if isempty(incr_j)
1693        [ref_j,ref_i]=find(squeeze(SeriesData.i1_series{1}(1,:,:)));
1694        ref_j=ref_j(ref_j>=first_j & ref_j<=last_j);
1695        ref_i=ref_i(ref_i>=first_i & ref_i<=last_i);
1696        ref_j=ref_j-1;
1697        ref_i=ref_i-1;
1698    else
1699        ref_j=first_j:incr_j:last_j;
1700        [tild,ref_i]=find(squeeze(SeriesData.i1_series{1}(1,:,:)));
1701        ref_i=ref_i-1;
1702        ref_i=ref_i(ref_i>=first_i & ref_i<=last_i);
1703    end
1704% increment i is defined: processing is done on first_i:incr_i:last_i;
1705else
1706    ref_i=first_i:incr_i:last_i;
1707    if isempty(incr_j)% automatic finding of the existing j indices
1708        [ref_j,tild]=find(squeeze(SeriesData.i1_series{1}(1,:,:)));
1709        ref_j=ref_j-1;
1710        ref_j=ref_j(ref_j>=first_j & ref_j<=last_j);
1711    else
1712        ref_j=first_j:incr_j:last_j;
1713    end
1714end
1715CPUTime=1;% job time estimated at 1 min per iteration (on index i and j) by default
1716if isfield(Param.Action, 'CPUTime') && ~isempty(Param.Action.CPUTime)
1717    CPUTime=Param.Action.CPUTime;%Note: CpUTime for one iteration ref_i has to be multiplied by the number of j indices nbfield_j
1718end
1719nbfield_j=numel(ref_j); % number of j indices
1720BlockLength=numel(ref_i);% by default, job involves the full set of i field indices
1721NbProcess=1;
1722switch RunMode
1723    case {'cluster_oar','cluster_pbs'}
1724        if isempty(Param.IndexRange.NbSlice)% if NbSlice is not defined
1725             BlockLength= ceil(20/(CPUTime*nbfield_j));% short iterations are grouped such that the minimum time of a process is 20 min.
1726             BlockLength=max(BlockLength,ceil(numel(ref_i)/500));% possibly increase the BlockLength to have less than 500 jobs
1727             NbProcess=ceil(numel(ref_i)/BlockLength) ; % nbre of processes sent to oar
1728        else
1729            NbProcess=Param.IndexRange.NbSlice;% the parameter NbSlice sets the nbre of run processes
1730            NbCore=min(NbCore,NbProcess);% reduces the number of cores if it exceeds the number of processes
1731        end
1732    otherwise
1733         if ~isempty(Param.IndexRange.NbSlice)
1734             NbProcess=Param.IndexRange.NbSlice;% the parameter NbSlice sets the nbre of run processes
1735         end
1736end
1737
1738%% record nbre of output files and starting time for computation for status
1739StatusData=get(handles.status,'UserData');
1740if isfield(StatusData,'OutputFileMode')
1741    switch StatusData.OutputFileMode
1742        case 'NbInput'
1743            StatusData.NbOutputFile=numel(ref_i)*nbfield_j;
1744        case 'NbInput_i'
1745            StatusData.NbOutputFile=numel(ref_i);
1746        case 'NbSlice'   
1747            StatusData.NbOutputFile=str2num(get(handles.num_NbSlice,'String'));
1748    end
1749end
1750StatusData.TimeStart=now;
1751set(handles.status,'UserData',StatusData)
1752
1753%% case of a function in Python
1754if strcmp(ActionExt, '.py (in dev.)')
1755    fprintf([
1756        '\n' ...
1757        '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n' ...
1758        'The option .py is used. It is still in development.\n' ...
1759        'Do not use it unless you really know what you do!\n' ...
1760        'To try it, first install Pyp and the most recent version of FluidDyn.\n' ...
1761        '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n'])
1762    RunMode = 'python';
1763end
1764
1765
1766%% direct processing on the current Matlab session or creation of command files
1767filexml=cell(1,NbProcess);% initialisation of the names of the files containing the processing parameters
1768extxml=cell(1,NbProcess); % initialisation of the set of labels used for the files documenting each process
1769for iprocess=1:NbProcess
1770    if ~strcmp(get(handles.RUN,'BusyAction'),'queue')% allow for STOP action
1771        disp('program stopped by user')
1772        return
1773    end
1774    if isempty(Param.IndexRange.NbSlice)
1775        Param.IndexRange.first_i=first_i+(iprocess-1)*BlockLength*incr_i;
1776        %         Param.IndexRange.first_i=ref_i(1+(iprocess-1)*BlockLength);
1777        if Param.IndexRange.first_i>last_i
1778            NbProcess=iprocess-1;% leave the loop, we are at the end of the calculation
1779            break
1780        end
1781        %Param.IndexRange.last_i=min(ref_i(iprocess*BlockLength),last_i);
1782        %Param.IndexRange.last_i=min(first_i+(iprocess)*BlockLength*incr_i-1,last_i);
1783        Param.IndexRange.last_i=min(last_i,first_i+(iprocess)*BlockLength*incr_i-1);
1784    else %multislices (then incr_i is not empty)
1785        %         Param.IndexRange.first_i= first_i+incr_i*(iprocess-1);
1786        %         Param.IndexRange.incr_i=incr_i*Param.IndexRange.NbSlice;
1787        Param.IndexRange.first_i= first_i+iprocess-1;
1788        Param.IndexRange.incr_i=incr_i*Param.IndexRange.NbSlice;
1789    end
1790    for ilist=1:size(Param.InputTable,1)
1791        Param.InputTable{ilist,1}=regexprep(Param.InputTable{ilist,1},'\','/');%correct path name for PCWIN system
1792    end
1793   
1794    %         if isempty(Param.IndexRange.NbSlice)% process by blocks of i index
1795    %             Param.IndexRange.first_i=first_i+(iprocess-1)*BlockLength*incr_i;
1796    %             if Param.IndexRange.first_i>last_i
1797    %                 NbProcess=iprocess-1;
1798    %                 break% leave the loop, we are at the end of the calculation
1799    %             end
1800    %             Param.IndexRange.last_i=min(last_i,first_i+(iprocess)*BlockLength*incr_i-1);
1801    %         else% process by slices of i index if NbSlice is defined, computation in a single process if NbSlice =1
1802    %             Param.IndexRange.first_i= first_i+iprocess-1;
1803    %             Param.IndexRange.incr_i=incr_i*Param.IndexRange.NbSlice;
1804    %         end
1805   
1806   
1807    if isfield(Param,'OutputSubDir')
1808        t=struct2xml(Param);
1809        t=set(t,1,'name','Series');
1810        extxml{iprocess}=fullfile_uvmat('','',Param.InputTable{1,3},'.xml',OutputNomType,...
1811            Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1812        filexml{iprocess}=fullfile(OutputDir,'0_XML',extxml{iprocess});
1813        try
1814            save(t, filexml{iprocess});% save the xml file containing the processing parameters
1815        catch ME
1816            if ~strcmp (RunMode,'local')
1817                errormsg=['error writting ' filexml{iprocess} ': ' ME.message];
1818                return
1819            end
1820        end
1821    end
1822    if strcmp (RunMode,'local')
1823        switch ActionExt
1824            case '.m'
1825                h_fun(Param);% direct launching
1826            case '.sh'
1827                switch computer
1828                    case {'PCWIN','PCWIN64'} %Windows system
1829                        filexml=regexprep(filexml,'\\','\\\\');% add '\' so that '\' are left as characters
1830                        system([fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml]);% TODO: adapt to DOS system
1831                    case {'GLNX86','GLNXA64','MACI64'}%Linux  system
1832                        system([fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml]);
1833                end
1834        end
1835    end
1836end
1837
1838if ~strcmp (RunMode,'local') && ~strcmp(RunMode,'python')
1839    %% processing on a different session of the same computer (background) or cluster, create executable files
1840    batch_file_list=cell(NbProcess,1);% initiate the list of executable files
1841    DirExe=fullfile(OutputDir,'0_EXE');%directory name for executable files
1842    switch computer
1843        case {'PCWIN','PCWIN64'} %Windows system
1844            ExeExt='.bat';
1845        case {'GLNX86','GLNXA64','MACI64'}%Linux  system
1846            ExeExt='.sh';
1847    end
1848    %create subdirectory for executable files
1849    if ~exist(DirExe,'dir')
1850        [tild,msg1]=mkdir(DirExe);
1851        if ~strcmp(msg1,'')
1852            errormsg=['cannot create ' DirExe ': ' msg1];%error message for directory creation
1853            return
1854        end
1855    end
1856    %create subdirectory for log files
1857    DirLog=fullfile(OutputDir,'0_LOG');
1858    if ~exist(DirLog,'dir')
1859        [tild,msg1]=mkdir(DirLog);
1860        if ~strcmp(msg1,'')
1861            errormsg=['cannot create ' DirLog ': ' msg1];%error message for directory creation
1862            return
1863        end
1864    end
1865    %create the executable file
1866    file_exe_global=fullfile_uvmat('','',Param.InputTable{1,3},ExeExt,OutputNomType,...
1867        first_i,last_i,first_j,last_j);
1868    file_exe_global=fullfile(OutputDir,'0_EXE',file_exe_global);
1869    filelog_global=fullfile_uvmat('','',Param.InputTable{1,3},'.log',OutputNomType,...
1870        first_i,last_i,first_j,last_j);
1871    filelog_global=fullfile(OutputDir,'0_LOG',filelog_global);
1872   
1873   
1874    for iprocess=1:NbProcess
1875       
1876        %create the executable file
1877       
1878        batch_file_list{iprocess}=fullfile(OutputDir,'0_EXE',regexprep(extxml{iprocess},'.xml$',ExeExt));
1879%         [fid,message]=fopen(batch_file_list{iprocess},'w');% create the executable file
1880%         if isequal(fid,-1)
1881%             errormsg=['creation of ' batch_file_list{iprocess} ':' message];
1882%             return
1883%         end
1884       
1885        % set the log file name
1886        filelog{iprocess}=fullfile(OutputDir,'0_LOG',regexprep(extxml{iprocess},'.xml$','.log'));
1887       
1888    end
1889end
1890
1891%% launch the executable files for background or cluster processing
1892
1893switch RunMode
1894   
1895    case 'background'
1896        [fid,message]=fopen(file_exe_global,'w');
1897        if isequal(fid,-1)
1898            errormsg=['creation of ' file_exe_global ':' message];
1899            return
1900        end
1901        switch ActionExt
1902            case '.m'% Matlab function
1903                switch computer
1904                    case {'GLNX86','GLNXA64','MACI64'}
1905                        cmd=[...
1906                            '#!/bin/bash \n'...
1907                            '. /etc/sysprofile \n'...
1908                            'matlab -nodisplay -nosplash -nojvm -logfile ''' filelog_global ''' <<END_MATLAB \n'...
1909                            'addpath(''' path_series '''); \n'...
1910                            'addpath(''' Param.Action.ActionPath '''); \n'];
1911                        for iprocess=1:NbProcess
1912                            cmd=[cmd '' Param.Action.ActionName  '( ''' filexml{iprocess} '''); \n'];
1913                        end
1914                        cmd=[cmd  'exit \n' 'END_MATLAB \n'];
1915                        fprintf(fid,cmd);%fill the executable file with the  char string cmd
1916                        fclose(fid);% close the executable file
1917                        system(['chmod +x ' file_exe_global]);% set the file to executable
1918                    case {'PCWIN','PCWIN64'}
1919                        cmd=['matlab -automation -logfile ' regexprep(filelog{iprocess},'\\','\\\\')...
1920                            ' -r "addpath(''' regexprep(path_series,'\\','\\\\') ''');'...
1921                            'addpath(''' regexprep(Param.Action.ActionPath,'\\','\\\\') ''');'];
1922                        for iprocess=1:NbProcess
1923                            cmd=[cmd '' Param.Action.ActionName  '( ''' regexprep(filexml{iprocess},'\\','\\\\') ''');']
1924                        end
1925                        cmd=[cmd ';exit"'];
1926                        fprintf(fid,cmd);%fill the executable file with the  char string cmd
1927                        fclose(fid);% close the executable file
1928                end
1929                system([file_exe_global ' &'])% directly execute the command file
1930            case '.sh' % compiled Matlab function
1931                for iprocess=1:NbProcess
1932                    switch computer
1933                        case {'GLNX86','GLNXA64','MACI64'}
1934                            [fid,message]=fopen(batch_file_list{iprocess},'w');% create the executable file
1935                            if isequal(fid,-1)
1936                                errormsg=['creation of .bat file: ' message];
1937                                return
1938                            end
1939                            cmd=['#!/bin/bash \n '...
1940                                '#$ -cwd \n '...
1941                                'hostname && date \n '...
1942                                'umask 002 \n'...
1943                                fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml];%allow writting access to created files for user group
1944                            fprintf(fid,cmd);%fill the executable file with the  char string cmd
1945                            fclose(fid);% close the executable file
1946                            system(['chmod +x ' batch_file_list{iprocess}]);% set the file to executable
1947                            system([batch_file_list{iprocess} ' &'])% directly execute the command file
1948                        case {'PCWIN','PCWIN64'}
1949                            msgbox_uvmat('ERROR','option for compiled Matlab functions not implemented for Windows system')
1950                            return
1951                    end
1952                end
1953                msgbox_uvmat('CONFIRMATION',[ActionName ' launched in background: press STATUS to see results'])
1954        end
1955       
1956    case 'cluster_oar' % option 'oar-parexec' used
1957        %create subdirectory for oar commands
1958        for iprocess=1:NbProcess           
1959            [fid,message]=fopen(batch_file_list{iprocess},'w');% create the executable file
1960            if isequal(fid,-1)
1961                errormsg=['creation of .bat file: ' message];
1962                return
1963            end
1964            if  strcmp(ActionExt,'.sh')
1965            cmd=['#!/bin/bash \n '...
1966                '#$ -cwd \n '...
1967                'hostname && date \n '...
1968                'umask 002 \n'...
1969                fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml{iprocess}];%allow writting access to created files for user group
1970            else
1971                cmd=[...
1972                            '#!/bin/bash \n'...
1973                            '. /etc/sysprofile \n'...
1974                            'matlab -nodisplay -nosplash -nojvm -logfile ''' filelog{iprocess} ''' <<END_MATLAB \n'...
1975                            'addpath(''' path_series '''); \n'...
1976                            'addpath(''' Param.Action.ActionPath '''); \n'...
1977                            '' Param.Action.ActionName  '( ''' filexml{iprocess} '''); \n'...
1978                            'exit \n'...
1979                            'END_MATLAB \n'];
1980            end
1981            fprintf(fid,cmd);%fill the executable file with the  char string cmd
1982            fclose(fid);% close the executable file
1983            system(['chmod +x ' batch_file_list{iprocess}]);% set the file to executable
1984        end
1985        DirOAR=fullfile(OutputDir,'0_OAR');
1986        if exist(DirOAR,'dir')% delete the content of the dir 0_LOG to allow new input
1987            curdir=pwd;
1988            cd(DirOAR)
1989            delete('*')
1990            cd(curdir)
1991        else
1992            [tild,msg1]=mkdir(DirOAR);
1993            if ~strcmp(msg1,'')
1994                errormsg=['cannot create ' DirOAR ': ' msg1];%error message for directory creation
1995                return
1996            end
1997        end
1998        % create file containing the list of jobs
1999        filename_joblist=fullfile(DirOAR,'job_list.txt');% name of the file contqining the list of executables
2000        fid=fopen(filename_joblist,'w');%open it for writting
2001        for iprocess=1:length(batch_file_list)
2002            fprintf(fid,[batch_file_list{iprocess} '\n']);% write list of exe files
2003        end
2004        fclose(fid);
2005        system(['chmod +x ' filename_joblist]);% set the file to executable
2006       
2007        filename_log=fullfile(DirLog,'job_list.stdout');%file for output messages of the master oar process
2008        filename_errors=fullfile(DirLog,'job_list.stderr');%file for error messages of the master oar process
2009        % the command job_list.txt contains the list of NbProcess independent individual jobs
2010        % in which the total calculation has been split. Those are written as executable files .sh in the folder /O_EXE.
2011        %  These individual jobs are grouped by the system as oar jobs on the NbCore processors.
2012        %  For each processor, the oar job must stop after the walltime which has been set, which is limited to 24 h.
2013        %  However, the oar job is automatically restarted (option 'idempotent') provided the individual jobs are
2014        % shorter than the wall time: in the time interval 'checkpoint' (WallTimeOneJob) before the end of the allowed duration,
2015        %  the oar job restarts when an individual job ends.
2016        JobTime=CPUTime*BlockLength*nbfield_j;% estimated time for one individual job (in minutes)
2017        % wall time (in hours ) for each oar job, allowing 10 individual jobs, but limited to 23 h:
2018        WallTimeTotal=min(23,4*JobTime/60);
2019        %disp(['WallTimeTotal: ' num2str(WallTimeTotal) ' hours'])
2020        % estimated time of an individual job (in min), with a margin of error
2021        WallTimeOneJob=min(4*JobTime+10,WallTimeTotal*60/2);% estimated max time of an individual job for checkpoint
2022        disp(['WallTimeOneJob: ' num2str(WallTimeOneJob) ' minutes'])
2023        oar_command=['oarsub -n UVmat_' ActionName ' '...
2024            '-t idempotent --checkpoint ' num2str(WallTimeOneJob*60) ' '...
2025            '-l /core=' num2str(NbCore) ','...
2026            'walltime=' datestr(WallTimeTotal/24,13) ' '...
2027            '-E ' filename_errors ' '...
2028            '-O ' filename_log ' '...
2029            extra_oar ' '...
2030            '"oar-parexec -s -f ' filename_joblist ' '...
2031            '-l ' filename_joblist '.log"'];
2032        fprintf(oar_command);% display  system command on the Matlab command window
2033        [status,result]=system(oar_command)% execute system command and show the result (ID number of the launched job) on the Matlab command window
2034        filename_oarcommand=fullfile(DirOAR,'0_oar_command');% keep track of the command in file '0-OAR/0_oar_command'
2035        fid=fopen(filename_oarcommand,'w');
2036        fprintf(fid,oar_command); % store the command
2037        fprintf(fid,result);% store the result (job ID number)
2038        fclose(fid);
2039        msgbox_uvmat('CONFIRMATION',[ActionName ' launched as  ' num2str(NbProcess) ' processes in cluster: press STATUS to see results'])
2040       
2041    case 'cluster_pbs' % for LMFA Kepler machine
2042        %create subdirectory for pbs command and log files
2043        DirPBS=fullfile(OutputDir,'0_PBS'); %todo : common name OAR/PBS
2044        if exist(DirPBS,'dir')% delete the content of the dir 0_LOG to allow new input
2045            curdir=pwd;
2046            cd(DirPBS)
2047            delete('*')
2048            cd(curdir)
2049        else
2050            [tild,msg1]=mkdir(DirPBS);
2051            if ~strcmp(msg1,'')
2052                errormsg=['cannot create ' DirPBS ': ' msg1];%error message for directory creation
2053                return
2054            end
2055        end
2056        max_walltime=3600*20; % 20h max total calculation (cannot exceed 24 h)
2057        walltime_onejob=1800; % seconds, max estimated time for asingle file index value
2058        filename_joblist=fullfile(DirPBS,'job_list.txt');%create name of the global executable file
2059        fid=fopen(filename_joblist,'w');
2060        for iprocess=1:length(batch_file_list)
2061            fprintf(fid,[batch_file_list{iprocess} '\n']);% list of exe files
2062        end
2063        fclose(fid);
2064        system(['chmod +x ' filename_joblist]);% set the file to executable
2065        pbs_command=['qstat -n CIVX '...
2066            '-t idempotent --checkpoint ' num2str(walltime_onejob+60) ' '...
2067            '-l /core=' num2str(NbCore) ','...
2068            'walltime=' datestr(min(1.05*walltime_onejob/86400*max(NbProcess*BlockLength*nbfield_j,NbCore)/NbCore,max_walltime/86400),13) ' '...
2069            '-E ' regexprep(filename_joblist,'\.txt\>','.stderr') ' '...
2070            '-O ' regexprep(filename_joblist,'\.txt\>','.log') ' '...
2071            extra_oar ' '...
2072            '"oar-parexec -s -f ' filename_joblist ' '...
2073            '-l ' filename_joblist '.log"'];
2074        filename_oarcommand=fullfile(DirPBS,'pbs_command');
2075        fid=fopen(filename_oarcommand,'w');
2076        fprintf(fid,pbs_command);
2077        fclose(fid);
2078        fprintf(pbs_command);% display in command line
2079        %system(pbs_command);
2080        msgbox_uvmat('CONFIRMATION',[ActionName ' command ready to be launched in cluster'])
2081    case 'python'
2082        command = [
2083            'LD_LIBRARY_PATH=$(echo $LD_LIBRARY_PATH | pyp "p.split('':'') | [s for s in p if ''matlab'' not in s] | '':''.join(p)") ' ...
2084            'python -m fluiddyn.postproc.uvmat ' filexml{iprocess}];
2085        % fprintf(['command:\n' command '\n\n'])
2086        system(command, '-echo');
2087end
2088
2089%------------------------------------------------------------------------
2090function STOP_Callback(hObject, eventdata, handles)
2091%------------------------------------------------------------------------
2092set(handles.RUN, 'BusyAction','cancel')
2093set(handles.RUN,'BackgroundColor',[1 0 0])
2094set(handles.RUN,'enable','on')
2095set(handles.RUN, 'Value',0)
2096
2097
2098%------------------------------------------------------------------------
2099% --- read parameters from the GUI series
2100%------------------------------------------------------------------------
2101function Param=read_GUI_series(handles)
2102
2103%% read raw parameters from the GUI series
2104Param=read_GUI(handles.series);
2105
2106%% clean the output structure by removing unused information
2107if isfield(Param,'Pairs')
2108    Param=rmfield(Param,'Pairs'); %info Pairs not needed for output
2109end
2110if isfield(Param,'InputLine')
2111    Param=rmfield(Param,'InputLine');
2112end
2113if isfield(Param,'EditObject')
2114    Param=rmfield(Param,'EditObject');
2115end
2116Param.IndexRange.TimeSource=Param.IndexRange.TimeTable{end,1};
2117Param.IndexRange=rmfield(Param.IndexRange,'TimeTable');
2118empty_line=false(size(Param.InputTable,1),1);
2119for iline=1:size(Param.InputTable,1)
2120    empty_line(iline)=isempty(cell2mat(Param.InputTable(iline,1:3)));
2121end
2122Param.InputTable(empty_line,:)=[];
2123
2124%------------------------------------------------------------------------
2125% --- Executes on selection change in ActionName.
2126function ActionName_Callback(hObject, eventdata, handles)
2127%------------------------------------------------------------------------
2128
2129%% stop any ongoing series processing
2130if isequal(get(handles.RUN,'Value'),1)
2131    answer= msgbox_uvmat('INPUT_Y-N','stop current Action process?');
2132    if strcmp(answer,'Yes')
2133        STOP_Callback(hObject, eventdata, handles)
2134    else
2135        return
2136    end
2137end
2138set(handles.ActionName,'BackgroundColor',[1 1 0])
2139huigetfile=findobj(allchild(0),'tag','status_display');
2140if ~isempty(huigetfile)
2141    delete(huigetfile)
2142end
2143drawnow
2144
2145%% get Action name and path
2146NbBuiltinAction=get(handles.Action,'UserData'); %nbre of functions initially proposed in the menu ActionName (as defined in the Opening fct of series)
2147ActionList=get(handles.ActionName,'String');% list menu fields
2148ActionIndex=get(handles.ActionName,'Value');
2149if ~isequal(ActionIndex,1)% if we are not just opening series
2150    InputTable=get(handles.InputTable,'Data');
2151    if isempty(InputTable{1,4})
2152        msgbox_uvmat('ERROR','no input file available: use Open in the menu bar')
2153        return
2154    end
2155end
2156ActionName= ActionList{get(handles.ActionName,'Value')}; % selected function name
2157ActionPathList=get(handles.ActionName,'UserData');%list of recorded paths to functions of the list ActionName
2158
2159%% add a new function to the menu if 'more...' has been selected in the menu ActionName
2160if isequal(ActionName,'more...')
2161    [FileName, PathName] = uigetfile( ...
2162        {'*.m', ' (*.m)';
2163        '*.m',  '.m files '; ...
2164        '*.*', 'All Files (*.*)'}, ...
2165        'Pick a series processing function ',get(handles.ActionPath,'String'));
2166    if length(FileName)<2
2167        return
2168    end
2169    [tild,ActionName,ActionExt]=fileparts(FileName);
2170   
2171    % insert the choice in the menu ActionName
2172    ActionIndex=find(strcmp(ActionName,ActionList),1);% look for the selected function in the menu Action
2173    PathName=regexprep(PathName,'/$','');
2174    if ~isempty(ActionIndex) && ~strcmp(ActionPathList{ActionIndex},PathName)%compare the path to the existing fct
2175        ActionIndex=[]; % the selected path is different than the recorded one
2176    end
2177    if isempty(ActionIndex)%the qselected fct (with selected path) does not exist in the menu
2178        ActionIndex= length(ActionList);
2179        ActionList=[ActionList(1:end-1);{ActionName};ActionList(end)];% the selected function is appended in the menu, before the last item 'more...'
2180         ActionPathList=[ActionPathList; PathName];
2181    end
2182   
2183    % record the file extension and extend the path list if it is a new extension
2184    ActionExtList=get(handles.ActionExt,'String');
2185    ActionExtIndex=find(strcmp(ActionExt,ActionExtList), 1);
2186    if isempty(ActionExtIndex)
2187        set(handles.ActionExt,'String',[ActionExtList;{ActionExt}])
2188    end
2189
2190    % remove old Action options in the menu (keeping a menu length <nb_builtin_ACTION+5)
2191    if length(ActionList)>NbBuiltinAction+5; %nb_builtin_ACTION=nbre of functions always remaining in the initial menu
2192        nbremove=length(ActionList)-NbBuiltinAction-5;
2193        ActionList(NbBuiltinAction+1:end-5)=[];
2194        ActionPathList(NbBuiltinAction+1:end-4,:)=[];
2195        ActionIndex=ActionIndex-nbremove;
2196    end
2197   
2198    % record action menu, choice and path
2199    set(handles.ActionName,'Value',ActionIndex)
2200    set(handles.ActionName,'String',ActionList)
2201       set(handles.ActionName,'UserData',ActionPathList);
2202    set(handles.ActionExt,'Value',ActionExtIndex)
2203       
2204    %record the user defined menu additions in personal file profil_perso
2205    dir_perso=prefdir;
2206    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
2207    if NbBuiltinAction+1<=numel(ActionList)-1
2208        ActionListUser=ActionList(NbBuiltinAction+1:numel(ActionList)-1);
2209        ActionPathListUser=ActionPathList(NbBuiltinAction+1:numel(ActionList)-1);
2210        ActionExtListUser={};
2211        if numel(ActionExtList)>2
2212            ActionExtListUser=ActionExtList(3:end);
2213        end
2214        if exist(profil_perso,'file')
2215            save(profil_perso,'ActionListUser','ActionPathListUser','ActionExtListUser','-append')
2216        else
2217            save(profil_perso,'ActionListUser','ActionPathListUser','ActionExtListUser','-V6')
2218        end
2219    end
2220end
2221
2222%% check the current ActionPath to the selected function
2223ActionPath=ActionPathList{ActionIndex};%current recorded path
2224set(handles.ActionPath,'String',ActionPath); %show the path to the senlected function
2225
2226%% reinitialise the waitbar
2227update_waitbar(handles.Waitbar,0)
2228
2229%% create the function handle for Action
2230if ~exist(ActionPath,'dir')
2231    msgbox_uvmat('ERROR',['The prescribed function path ' ActionPath ' does not exist']);
2232    return
2233end
2234current_dir=pwd;%current working dir
2235cd(ActionPath)
2236h_fun=str2func(ActionName);
2237cd(current_dir)
2238
2239%
2240% checkaddpath=0;
2241% path_series=which('series');
2242% %eval(['spath=which(''' ActionName ''');']) %spath = current path of the selected function ACTION
2243% spath=fileparts(which(ActionName)); %spath = current path of the selected function ACTION
2244% if ~exist(ActionPath,'dir')
2245%     msgbox_uvmat('ERROR',['The prescribed function path ' ActionPath ' does not exist']);
2246%     return
2247% end
2248% if ~strcmp(spath,ActionPath)
2249%     if strcmp(pwd,spath)
2250%         msgbox_uvmat('ERROR',[ 'a function called ' ActionName ' on your working space oversets the selected one']);
2251%         return
2252%     else
2253%         addpath(ActionPath)% add the prescribed path if not the current one
2254%         checkaddpath=1;
2255%     end
2256% end
2257% eval(['h_fun=@' ActionName ';'])%create a function handle for ACTION
2258% if checkaddpath && ~isequal(ActionPath,path_series)
2259%     rmpath(ActionPath)% add the prescribed path if not the current one
2260% end
2261
2262%% Activate the Action fct to adapt the configuration of the GUI series and bring specific parameters in SeriesData
2263Param=read_GUI_series(handles);% read the parameters from the GUI series
2264ParamOut=h_fun(Param);%run the selected Action function to get the relevant input
2265
2266%% Put the first line of the selected Action fct as tooltip help
2267try
2268    [fid,errormsg] =fopen([ActionName '.m']);
2269    InputText=textscan(fid,'%s',1,'delimiter','\n');
2270    fclose(fid);
2271    set(handles.ActionName,'ToolTipString',InputText{1}{1})% put the first line of the selected function as tooltip help
2272end
2273
2274
2275%% Visibility of VelType and VelType_1 menus asked by ActionName
2276VelTypeRequest=1;%VelType requested by default
2277VelTypeRequest_1=1;%VelType requested by default
2278if isfield(ParamOut,'VelType')
2279    VelTypeRequest=ismember(ParamOut.VelType,{'on','one','two'});
2280    VelTypeRequest_1=strcmp( ParamOut.VelType,'two');
2281end
2282FieldNameRequest=0;  %hidden by default
2283FieldNameRequest_1=0;  %hidden by default
2284if isfield(ParamOut,'FieldName')
2285    FieldNameRequest=ismember(ParamOut.FieldName,{'on','one','two'});
2286    FieldNameRequest_1=strcmp( ParamOut.FieldName,'two');
2287end
2288
2289%% Detect the types of input files and set menus and default options in 'VelType'
2290SeriesData=get(handles.series,'UserData');% info on the input file series
2291iview_civ=find(strcmp('civx',SeriesData.FileType)|strcmp('civdata',SeriesData.FileType));
2292iview_netcdf=find(strcmp('netcdf',SeriesData.FileType)|strcmp('civx',SeriesData.FileType)|strcmp('civdata',SeriesData.FileType));% all nc files, icluding civ
2293FieldList=get(handles.FieldName,'String');% previous list as default
2294if ~iscell(FieldList),FieldList={FieldList};end
2295FieldList_1=get(handles.FieldName_1,'String');% previous list as default
2296if ~iscell(FieldList_1),FieldList_1={FieldList_1};end
2297%CheckList=0;% indicate whether FieldName has been updated
2298CheckList_1=1;% indicate whether FieldName_1 has been updated
2299handles_coord=[handles.Coord_x handles.Coord_y handles.Coord_z handles.Coord_x_title handles.Coord_y_title handles.Coord_z_title];
2300if VelTypeRequest && numel(iview_civ)>=1
2301    menu=set_veltype_display(SeriesData.FileInfo{iview_civ(1)}.CivStage,SeriesData.FileType{iview_civ(1)});
2302    set(handles.VelType,'Value',1)% set first choice by default
2303    set(handles.VelType,'String',[{'*'};menu])
2304    set(handles.VelType,'Visible','on')
2305    set(handles.VelType_title,'Visible','on')
2306    FieldList=[set_field_list('U','V');{'C'};{'get_field...'}];%standard menu for civx data
2307    %CheckList=1;
2308    set(handles.FieldName,'Value',1); %velocity vector choice by default
2309    if  VelTypeRequest_1 && numel(iview_civ)>=2
2310        menu=set_veltype_display(SeriesData.FileInfo{iview_civ(2)}.CivStage,SeriesData.FileType{iview_civ(2)});
2311        set(handles.VelType_1,'Value',1)% set first choice by default
2312        set(handles.VelType_1,'String',[{'*'};menu])
2313        set(handles.VelType_1,'Visible','on')
2314        set(handles.VelType_title_1,'Visible','on')
2315        FieldList_1=[set_field_list('U','V');{'C'};{'get_field...'}];%standard menu for civx data
2316        CheckList_1=1;
2317        set(handles.FieldName_1,'Value',1); %velocity vector choice by default
2318    else
2319        set(handles.VelType_1,'Visible','off')
2320        set(handles.VelType_title_1,'Visible','off')
2321    end
2322else
2323    set(handles.VelType,'Visible','off')
2324    set(handles.VelType_title,'Visible','off')
2325end   
2326
2327%% Detect the types of input files and set menus and default options in 'FieldName'
2328if FieldNameRequest && numel(iview_netcdf)>=1
2329    set(handles.InputFields,'Visible','on')
2330    %if CheckList==0        % not civ input made
2331        if isfield(SeriesData.FileInfo{iview_netcdf(1)},'ListVarName')
2332        ListVarName=SeriesData.FileInfo{iview_netcdf(1)}.ListVarName;
2333        ind_var=get(handles.FieldName,'Value');%indices of previously selected variables
2334        for ilist=1:numel(ind_var)
2335            if isempty(find(strcmp(FieldList{ind_var(ilist)},ListVarName)))
2336                FieldList={};% previous choice not consistent with new input field
2337                set(handles.FieldName,'Value',1)
2338                break
2339            end
2340        end
2341        if ~isempty(FieldList)
2342            if isempty(find(strcmp(get(handles.Coord_x,'String'),ListVarName)))||...
2343                    isempty(find(strcmp(get(handles.Coord_y,'String'),ListVarName)))
2344                FieldList={};
2345                set(handles.Coord_x,'String','')
2346                set(handles.Coord_y,'String','')
2347            end
2348            Coord_z=get(handles.Coord_z,'String');
2349            if ~isempty(Coord_z) && isempty(find(strcmp(Coord_z,ListVarName)))
2350                FieldList={};
2351                set(handles.Coord_z,'String','')
2352            end
2353        end
2354        set(handles_coord,'Visible','on')
2355        FieldList=[FieldList;{'get_field...'}];
2356        if FieldNameRequest_1 && numel(iview_netcdf)>=2
2357            set(handles.FieldName_1,'Visible','on')
2358            if CheckList_1==0        % not civ input made
2359                ListVarName=SeriesData.FileInfo{iview_netcdf(2)}.ListVarName;
2360                ind_var=get(handles.FieldName,'Value');%indices of previously selected variables
2361                for ilist=1:numel(ind_var)
2362                    if isempty(find(strcmp(FieldList{ind_var(ilist)},ListVarName)))
2363                        FieldList_1={};% previous choice not consistent with new input field
2364                        set(handles.FieldName_1,'Value',1)
2365                        break
2366                    end
2367                end
2368                warn_coord=0;
2369                if isempty(find(strcmp(get(handles.Coord_x,'String'),ListVarName)))||...
2370                        isempty(find(strcmp(get(handles.Coord_y,'String'),ListVarName)))
2371                    warn_coord=1;
2372                end
2373                if ~isempty(Coord_z) && isempty(find(strcmp(Coord_z,ListVarName)))
2374                    FieldList_1={};
2375                    warn_coord=1;
2376                end
2377                if warn_coord
2378                    msgbox_uvmat('WARNING','coordiante names do not exist in the second netcdf input file')
2379                end
2380                set(handles.FieldName,'String',[FieldList;{'get_field...'}])
2381                set(handles.FieldName_1,'Visible','on')
2382                set(handles.FieldName_1,'Value',1)
2383                set(handles.FieldName_1,'String',FieldList_1)
2384            end
2385        else
2386            set(handles.FieldName_1,'Visible','off')
2387        end
2388        end
2389%     else
2390%         set(handles_coord,'Visible','off')% no coord display for civ data
2391%     end
2392    set(handles.FieldName,'String',FieldList)
2393else
2394    set(handles.InputFields,'Visible','off')
2395end
2396
2397%% Introduce visibility of file overwrite option
2398if isfield(ParamOut,'CheckOverwriteVisible')&& strcmp(ParamOut.CheckOverwriteVisible,'on')
2399    set(handles.CheckOverwrite,'Visible','on')
2400else
2401    set(handles.CheckOverwrite,'Visible','off')
2402end
2403
2404%% Check whether alphabetical sorting of input Subdir is allowed by the Action fct  (for multiples series entries)
2405if isfield(ParamOut,'AllowInputSort')&&isequal(ParamOut.AllowInputSort,'on')&& size(Param.InputTable,1)>1
2406    [tild,iview]=sort(InputTable(:,2)); %subdirectories sorted in alphabetical order
2407    set(handles.InputTable,'Data',InputTable(iview,:));
2408    MinIndex_i=get(handles.MinIndex_i,'Data');
2409    MinIndex_j=get(handles.MinIndex_j,'Data');
2410    MaxIndex_i=get(handles.MaxIndex_i,'Data');
2411    MaxIndex_j=get(handles.MaxIndex_j,'Data');
2412    set(handles.MinIndex_i,'Data',MinIndex_i(iview,:));
2413    set(handles.MinIndex_j,'Data',MinIndex_j(iview,:));
2414    set(handles.MaxIndex_i,'Data',MaxIndex_i(iview,:));
2415    set(handles.MaxIndex_j,'Data',MaxIndex_j(iview,:));
2416    TimeTable=get(handles.TimeTable,'Data');
2417    set(handles.TimeTable,'Data',TimeTable(iview,:));
2418    PairString=get(handles.PairString,'Data');
2419    set(handles.PairString,'Data',PairString(iview,:));
2420end
2421
2422%% Impose the whole input file index range if requested
2423if isfield(ParamOut,'WholeIndexRange')&&isequal(ParamOut.WholeIndexRange,'on')
2424    MinIndex_i=get(handles.MinIndex_i,'Data');
2425    MinIndex_j=get(handles.MinIndex_j,'Data');
2426    MaxIndex_i=get(handles.MaxIndex_i,'Data');
2427    MaxIndex_j=get(handles.MaxIndex_j,'Data');
2428    set(handles.num_first_i,'String',num2str(MinIndex_i(1)))% set first as the min index (for the first line)
2429    set(handles.num_last_i,'String',num2str(MaxIndex_i(1)))% set last as the max index (for the first line)
2430    set(handles.num_incr_i,'String','1')
2431    set(handles.num_first_j,'String',num2str(MinIndex_j(1)))% set first as the min index (for the first line)
2432    set(handles.num_last_j,'String',num2str(MaxIndex_j(1)))% set last as the max index (for the first line)
2433    set(handles.num_incr_j,'String','1')
2434else  % check index ranges
2435    first_i=1;last_i=1;first_j=1;last_j=1;
2436    if isfield(Param.IndexRange,'first_i')
2437        first_i=Param.IndexRange.first_i;
2438        last_i=Param.IndexRange.last_i;
2439    end
2440    if isfield(Param.IndexRange,'first_j')
2441        first_j=Param.IndexRange.first_j;
2442        last_j=Param.IndexRange.last_j;
2443    end
2444    if last_i < first_i || last_j < first_j , msgbox_uvmat('ERROR','last field number must be larger than the first one'),...
2445            set(handles.RUN, 'Enable','On'), set(handles.RUN,'BackgroundColor',[1 0 0]),return,end;
2446end
2447
2448%% enable or desable j index visibility
2449status_j='on';%default
2450if isfield(ParamOut,'Desable_j_index')&&isequal(ParamOut.Desable_j_index,'on')
2451    status_j='off';
2452end
2453if isempty(find(~cellfun(@isempty,SeriesData.j1_series), 1)); % case of empty j indices
2454    status_j='off'; % no j index needed
2455elseif strcmp(get(handles.PairString,'Visible'),'on')
2456    check_burst=cellfun(@isempty,regexp(get(handles.PairString,'Data'),'^j'));%=0 for burst case, 1 otherwise
2457    if isempty(find(check_burst, 1))% if all pair string begins by j (burst)
2458        status_j='off'; % no j index needed for bust case
2459    end
2460end
2461enable_j(handles,status_j) % no j index needed
2462
2463
2464%% NbSlice visibility
2465%NbSliceVisible='off';%default
2466if isfield(ParamOut,'NbSlice') && (strcmp(ParamOut.NbSlice,'on')||isnumeric(ParamOut.NbSlice))
2467    set(handles.num_NbSlice,'Visible','on')
2468    set(handles.NbSlice_title,'Visible','on')
2469else
2470    set(handles.num_NbSlice,'Visible','off')
2471    set(handles.NbSlice_title,'Visible','off')
2472    %     set(handles.num_NbProcess,'String',get(handles.num_NbSlice,'String'))% the nbre of processes is imposed as the nbre of slices
2473    % else
2474    %     set(handles.num_NbProcess,'String','')% free nbre of processes
2475end
2476if isnumeric(ParamOut.NbSlice)
2477    set(handles.num_NbSlice,'String',num2str(ParamOut.NbSlice))
2478    set(handles.num_NbSlice,'Enable','off'); % NbSlice set by the activation of the Action function
2479else
2480    set(handles.num_NbSlice,'Enable','on'); % NbSlice can be modified on the GUI series
2481end
2482% set(handles.num_NbSlice,'Visible',NbSliceVisible)
2483% set(handles.NbSlice_title,'Visible',NbSliceVisible)
2484
2485
2486
2487%% Visibility of FieldTransform menu
2488FieldTransformVisible='off';  %hidden by default
2489if isfield(ParamOut,'FieldTransform')
2490    FieldTransformVisible=ParamOut.FieldTransform; 
2491    TransformName_Callback([],[], handles)
2492end
2493set(handles.FieldTransform,'Visible',FieldTransformVisible)
2494if isfield(ParamOut,'TransformPath')
2495    set(handles.ActionExt,'UserData',ParamOut.TransformPath)
2496else
2497    set(handles.ActionExt,'UserData',[])
2498end
2499
2500%% Visibility of projection object
2501ProjObjectVisible='off';  %hidden by default
2502if isfield(ParamOut,'ProjObject')
2503    ProjObjectVisible=ParamOut.ProjObject;
2504end
2505set(handles.CheckObject,'Visible',ProjObjectVisible)
2506if ~get(handles.CheckObject,'Value')
2507    ProjObjectVisible='off';
2508end
2509set(handles.ProjObject,'Visible',ProjObjectVisible)
2510set(handles.DeleteObject,'Visible',ProjObjectVisible)
2511set(handles.ViewObject,'Visible',ProjObjectVisible)
2512set(handles.EditObject,'Visible',ProjObjectVisible)
2513
2514%% Visibility of mask input
2515MaskVisible='off';  %hidden by default
2516if isfield(ParamOut,'Mask')
2517    MaskVisible=ParamOut.Mask;
2518end
2519set(handles.CheckMask,'Visible',MaskVisible);
2520
2521%% definition of the directory containing the output files
2522if  ~(isfield(SeriesData,'ActionName') && strcmp(ActionName,SeriesData.ActionName))
2523    OutputDirExt='.series'; %default
2524    if isfield(ParamOut,'OutputDirExt')&&~isempty(ParamOut.OutputDirExt)
2525        OutputDirExt=ParamOut.OutputDirExt;
2526    end
2527    set(handles.OutputDirExt,'String',OutputDirExt)
2528end
2529OutputDirVisible='off';
2530OutputSubDirMode='auto';%default
2531SubDirOut='';
2532if isfield(ParamOut,'OutputSubDirMode')
2533    OutputSubDirMode=ParamOut.OutputSubDirMode;
2534end
2535switch OutputSubDirMode
2536    case 'auto';%default
2537        OutputDirVisible='on';
2538        SubDir=InputTable(1:end,2); %set of subdirectories
2539        SubDirOut=SubDir{1};
2540        if numel(SubDir)>1
2541            for ilist=2:numel(SubDir)
2542                SubDirOut=[SubDirOut '-' regexprep(SubDir{ilist},'^/','')];
2543            end
2544        end
2545    case 'one'
2546        OutputDirVisible='on';
2547        SubDirOut=InputTable{1,2}; %use the first subdir name (+OutputDirExt) as output  subdirectory
2548    case 'two'
2549        OutputDirVisible='on';   
2550        SubDir=InputTable(1:2,2); %set of subdirectories
2551        SubDirOut=SubDir{1};
2552        if numel(SubDir)>1
2553                SubDirOut=[SubDirOut '-' regexprep(SubDir{2},'^/','')];
2554        end
2555    case 'last'
2556        OutputDirVisible='on';
2557        SubDirOut=InputTable{end,2}; %use the last subdir name (+OutputDirExt) as output  subdirectory
2558end
2559set(handles.OutputSubDir,'String',SubDirOut)
2560set(handles.OutputSubDir,'BackgroundColor',[1 1 1])% set edit box to white color to indicate refreshment
2561set(handles.OutputDirExt,'Visible',OutputDirVisible)
2562set(handles.OutputSubDir,'Visible',OutputDirVisible)
2563%set(handles.CheckOverwrite,'Visible',OutputDirVisible)
2564set(handles.OutputDir_title,'Visible',OutputDirVisible)
2565SeriesData.ActionName=ActionName;%record ActionName for next use
2566
2567
2568%% visibility of the run mode (local or background or cluster)
2569if strcmp(OutputSubDirMode,'none')
2570    RunModeVisible='off';% only local mode available if no output file is produced
2571else
2572    RunModeVisible='on';
2573end
2574set(handles.RunMode,'Visible',RunModeVisible)
2575set(handles.ActionExt,'Visible',RunModeVisible)
2576set(handles.RunMode_title,'Visible',RunModeVisible)
2577set(handles.ActionExt_title,'Visible',RunModeVisible)
2578
2579
2580%% Expected nbre of output files
2581if isfield(ParamOut,'OutputFileMode')
2582    StatusData.OutputFileMode=ParamOut.OutputFileMode;
2583    set(handles.status,'UserData',StatusData)
2584end
2585
2586%% definition of an additional parameter set, determined by an ancillary GUI
2587if isfield(ParamOut,'ActionInput')
2588    set(handles.ActionInput,'Visible','on')
2589    ParamOut.ActionInput.Program=ActionName; % record the program in ActionInput
2590    SeriesData.ActionInput=ParamOut.ActionInput;
2591else
2592    set(handles.ActionInput,'Visible','off')
2593    if isfield(SeriesData,'ActionInput')
2594        SeriesData=rmfield(SeriesData,'ActionInput');
2595    end
2596end
2597set(handles.series,'UserData',SeriesData)
2598set(handles.ActionName,'BackgroundColor',[1 1 1])
2599
2600%------------------------------------------------------------------------
2601% --- Executes on selection change in FieldName.
2602function FieldName_Callback(hObject, eventdata, handles)
2603%------------------------------------------------------------------------
2604field_str=get(handles.FieldName,'String');
2605field_index=get(handles.FieldName,'Value');
2606field=field_str{field_index(1)};
2607if isequal(field,'get_field...')
2608    SeriesData=get(handles.series,'UserData');
2609    % input line for which the field choice is relevant
2610    iview=find(ismember(SeriesData.FileType,{'netcdf','civx','civdata'}));% all nc files, icluding civ
2611    hget_field=findobj(allchild(0),'name','get_field');
2612    if ~isempty(hget_field)
2613        delete(hget_field)%delete opened versions of get_field
2614    end
2615    Param=read_GUI(handles.series);
2616    InputTable=Param.InputTable(iview,:);
2617    % check the existence of the first file in the series
2618    first_j=[];last_j=[];MinIndex_j=1;MaxIndex_j=1;%default setting for index j
2619    if isfield(Param.IndexRange,'first_j');% if index j is used     
2620        first_j=Param.IndexRange.first_j;
2621        last_j=Param.IndexRange.last_j;
2622        MinIndex_j=Param.IndexRange.MinIndex_j(iview);
2623        MaxIndex_j=Param.IndexRange.MaxIndex_j(iview);
2624    end
2625    PairString='';
2626    if isfield(Param.IndexRange,'PairString'); PairString=Param.IndexRange.PairString{iview}; end
2627    [i1,i2,j1,j2] = get_file_index(Param.IndexRange.first_i,first_j,PairString);
2628    LineIndex=iview(1);
2629    if numel(iview)>1     
2630        answer=msgbox_uvmat('INPUT_TXT',['select the line of the input table:' num2str(iview)] ,num2str(iview(1)));
2631        LineIndex=str2num(answer);
2632%         InputLine=str2num(get(handles.InputLine,'String'));
2633%         if ismember(InputLine,iview)
2634%             LineIndex=InputLine;
2635%         end
2636    end
2637    FirstFileName=fullfile_uvmat(InputTable{LineIndex,1},InputTable{LineIndex,2},InputTable{LineIndex,3},...
2638        InputTable{LineIndex,5},InputTable{LineIndex,4},i1,i2,j1,j2);
2639    if exist(FirstFileName,'file')
2640        ParamIn.Title='get_field: pick input variables and coordinates for series processing';
2641        ParamIn.SeriesInput=1;
2642        GetFieldData=get_field(FirstFileName,ParamIn);
2643        FieldList={};
2644        if isfield(GetFieldData,'FieldOption')% if a field has been selected
2645        switch GetFieldData.FieldOption
2646            case 'vectors'
2647                UName=GetFieldData.PanelVectors.vector_x;
2648                VName=GetFieldData.PanelVectors.vector_y;
2649                YName={GetFieldData.Coordinates.Coord_y};
2650                FieldList={['vec(' UName ',' VName ')'];...
2651                    ['norm(' UName ',' VName ')'];...
2652                    UName;VName};
2653            case {'scalar'}
2654                FieldList=GetFieldData.PanelScalar.scalar;
2655                YName={GetFieldData.Coordinates.Coord_y};
2656                if ischar(FieldList)
2657                    FieldList={FieldList};
2658                end
2659            case 'civdata...'
2660                FieldList=[set_field_list('U','V') ;{'C'}];
2661                set(handles.FieldName,'Value',1) % set menu to 'velocity
2662                XName='X';
2663                YName='y';
2664        end
2665        set(handles.FieldName,'Value',1)
2666        set(handles.FieldName,'String',[FieldList; {'get_field...'}]);
2667        if ~strcmp(GetFieldData.FieldOption,'civdata...')
2668           if ~isempty(regexp(FieldList{1},'^vec'))
2669                set(handles.FieldName,'Value',1)
2670           else
2671                set(handles.FieldName,'Value',1:numel(FieldList))%select all input fields by default
2672           end
2673            XName=GetFieldData.Coordinates.Coord_x;
2674            YName=GetFieldData.Coordinates.Coord_y;
2675            TimeNameStr=GetFieldData.Time.SwitchVarIndexTime;
2676            % get the time info                     
2677            TimeTable=get(handles.TimeTable,'Data');
2678            switch TimeNameStr
2679                case 'file index'
2680                    TimeName='';
2681                case 'attribute'
2682                    TimeName=['att:' GetFieldData.Time.TimeName];
2683                    % update the time table
2684                    TimeTable{LineIndex,2}=get_time(Param.IndexRange.MinIndex_i(LineIndex),MinIndex_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % Min time     
2685                    TimeTable{LineIndex,3}=get_time(Param.IndexRange.first_i,first_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % first time             
2686                    TimeTable{LineIndex,4}=get_time(Param.IndexRange.last_i,last_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % last time                     
2687                    TimeTable{LineIndex,5}=get_time(Param.IndexRange.MaxIndex_i(LineIndex),MaxIndex_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % Max time
2688                case 'variable'
2689                    set(handles.TimeName,'String',['var:' GetFieldData.Time.TimeName])
2690                    set(handles.NomType,'String','*')
2691                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])% A VERIFIER !!!!!!
2692                    set(handles.FileIndex,'String','')
2693                    ParamIn.TimeVarName=GetFieldData.Time.TimeName;
2694                case 'matrix_index'
2695                    TimeName=['dim:' GetFieldData.Time.TimeName];
2696                    set(handles.NomType,'String','*')
2697                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
2698                    set(handles.FileIndex,'String','')
2699                    ParamIn.TimeDimName=GetFieldData.Time.TimeName;
2700            end
2701            TimeTable{LineIndex,1}=TimeName;
2702            set(handles.TimeTable,'Data',TimeTable);
2703        end
2704        set(handles.Coord_x,'String',XName)
2705        set(handles.Coord_y,'String',YName)
2706        set(handles.Coord_x,'Visible','on')
2707        set(handles.Coord_y,'Visible','on')
2708        end
2709    else
2710        msgbox_uvmat('ERROR',[FirstFileName ' does not exist'])
2711    end
2712end
2713
2714function [TimeValue,DtValue]=get_time(ref_i,ref_j,PairString,InputTable,FileInfo,TimeName,DtName)
2715[i1,i2,j1,j2] = get_file_index(ref_i,ref_j,PairString);
2716FileName=fullfile_uvmat(InputTable{1},InputTable{2},InputTable{3},InputTable{5},InputTable{4},i1,i2,j1,j2);
2717Data=nc2struct(FileName,[]);
2718TimeValue=[];
2719DtValue=[];
2720if isequal(FileInfo.FileType,'civdata')
2721    if ismember(TimeName,{'civ1','filter1'})
2722        TimeValue=Data.Civ1_Time;
2723        DtValue=Data.Civ1_Dt;
2724    else
2725        TimeValue=Data.Civ2_Time;
2726        DtValue=Data.Civ2_Dt;
2727    end
2728else
2729    if ~isempty(TimeName)&& isfield(Data,TimeName)
2730        TimeValue=Data.(TimeName);
2731    end
2732    if exist('DtName','var') && isfield(Data,DtName)
2733        DtValue=Data.(DtName);
2734    end
2735end
2736
2737%------------------------------------------------------------------------
2738% --- Executes on selection change in FieldName_1.
2739function FieldName_1_Callback(hObject, eventdata, handles)
2740%------------------------------------------------------------------------
2741field_str=get(handles.FieldName_1,'String');
2742field_index=get(handles.FieldName_1,'Value');
2743field=field_str{field_index(1)};
2744if isequal(field,'get_field...')
2745    hget_field=findobj(allchild(0),'name','get_field');
2746    if ~isempty(hget_field)
2747        delete(hget_field)%delete opened versions of get_field
2748    end
2749    Param=read_GUI(handles.series);
2750    Param.InputTable=Param.InputTable(1,:);
2751    % check the existence of the first file in the series
2752    first_j=[];
2753    if isfield(Param.IndexRange,'first_j'); first_j=Param.IndexRange.first_j; end
2754    if isfield(Param.IndexRange,'last_j'); last_j=Param.IndexRange.last_j; end
2755    PairString='';
2756    if isfield(Param.IndexRange,'PairString'); PairString=Param.IndexRange.PairString; end
2757    [i1,i2,j1,j2] = get_file_index(Param.IndexRange.first_i,first_j,PairString);
2758    FirstFileName=fullfile_uvmat(Param.InputTable{1,1},Param.InputTable{1,2},Param.InputTable{1,3},...
2759        Param.InputTable{1,5},Param.InputTable{1,4},i1,i2,j1,j2);
2760    if exist(FirstFileName,'file')
2761        ParamIn.SeriesInput=1;
2762        GetFieldData=get_field(FirstFileName,ParamIn);
2763        FieldList={};
2764        switch GetFieldData.FieldOption
2765            case 'vectors'
2766                UName=GetFieldData.PanelVectors.vector_x;
2767                VName=GetFieldData.PanelVectors.vector_y;
2768                FieldList={['vec(' UName ',' VName ')'];...
2769                    ['norm(' UName ',' VName ')'];...
2770                    UName;VName};
2771            case {'scalar','pick variables'}
2772                FieldList=GetFieldData.PanelScalar.scalar;
2773                if ischar(FieldList)
2774                    FieldList={FieldList};
2775                end
2776            case '1D plot'
2777
2778            case 'civdata...'
2779                FieldList=set_field_list('U','V','C');
2780                set(handles.FieldName,'Value',2) % set menu to 'velocity
2781        end
2782        if ~strcmp(GetFieldData.FieldOption,'civdata...')
2783            TimeNameStr=GetFieldData.Time.SwitchVarIndexTime;
2784            switch TimeNameStr
2785                case 'file index'
2786                    set(handles.TimeName,'String','');
2787                case 'attribute'
2788                    set(handles.TimeName,'String',['att:' GetFieldData.Time.TimeName]);
2789                case 'variable'
2790                    set(handles.TimeName,'String',['var:' GetFieldData.Time.TimeName])
2791                    set(handles.NomType,'String','*')
2792                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])% A VERIFIER !!!!!!
2793                    set(handles.FileIndex,'String','')
2794                    ParamIn.TimeVarName=GetFieldData.Time.TimeName;
2795                case 'matrix_index'
2796                    set(handles.TimeName,'String',['dim:' GetFieldData.Time.TimeName]);
2797                    set(handles.NomType,'String','*')
2798                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
2799                    set(handles.FileIndex,'String','')
2800                    ParamIn.TimeDimName=GetFieldData.Time.TimeName;
2801            end
2802        end
2803        set(handles.FieldName_1,'Value',1)
2804        set(handles.FieldName_1,'String',[FieldList; {'get_field...'}]);
2805    end
2806end   
2807
2808
2809%%%%%%%%%%%%%
2810function [ind_remove]=find_pairs(dirpair,ind_i,last_i)
2811indsel=ind_i;
2812indiff=diff(ind_i); %test index increment to detect multiplets (several pairs with the same index ind_i) and holes in the series
2813indiff=[1 indiff last_i-ind_i(end)+1];%for testing gaps with the imposed bounds
2814if ~isempty(indiff)
2815    indiff2=diff(indiff);
2816    indiffp=[indiff2 1];
2817    indiffm=[1 indiff2];
2818    ind_multi_m=find((indiff==0)&(indiffm<0))-1;%indices of first members of multiplets
2819    ind_multi_p=find((indiff==0)&(indiffp>0));%indices of last members of multiplets
2820    %for each multiplet, select the most recent file
2821    ind_remove=[];
2822    for i=1:length(ind_multi_m)
2823        ind_pairs=ind_multi_m(i):ind_multi_p(i);
2824        for imulti=1:length(ind_pairs)
2825            datepair(imulti)=datenum(dirpair(ind_pairs(imulti)).date);%dates of creation
2826        end
2827        [datenew,indsort2]=sort(datepair); %sort the multiplet by creation date
2828        ind_s=indsort2(1:end-1);%
2829        ind_remove=[ind_remove ind_pairs(ind_s)];%remove these indices, leave the last one
2830    end
2831end
2832
2833%------------------------------------------------------------------------
2834% --- determine the list of index pairstring of processing file
2835function [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)
2836%------------------------------------------------------------------------
2837num_i1=num_i;% set of first image numbers by default
2838num_i2=num_i;
2839num_j1=num_j;
2840num_j2=num_j;
2841num_i_out=num_i;
2842num_j_out=num_j;
2843% if isequal (NomType,'_1-2_1') || isequal (NomType,'_1-2')
2844if isequal(mode,'series(Di)')
2845    num_i1_line=num_i+ind_shift(3);% set of first image numbers
2846    num_i2_line=num_i+ind_shift(4);
2847    % adjust the first and last field number
2848        indsel=find(num_i1_line >= 1);
2849    num_i_out=num_i(indsel);
2850    num_i1_line=num_i1_line(indsel);
2851    num_i2_line=num_i2_line(indsel);
2852    num_j1=meshgrid(num_j,ones(size(num_i1_line)));
2853    num_j2=meshgrid(num_j,ones(size(num_i1_line)));
2854    [xx,num_i1]=meshgrid(num_j,num_i1_line);
2855    [xx,num_i2]=meshgrid(num_j,num_i2_line);
2856elseif isequal (mode,'series(Dj)')||isequal (mode,'bursts')
2857    if isequal(mode,'bursts') %case of bursts (png_old or png_2D)
2858        num_j1=ind_shift(1)*ones(size(num_i));
2859        num_j2=ind_shift(2)*ones(size(num_i));
2860    else
2861        num_j1_col=num_j+ind_shift(1);% set of first image numbers
2862        num_j2_col=num_j+ind_shift(2);
2863        % adjust the first field number
2864        indsel=find((num_j1_col >= 1));   
2865        num_j_out=num_j(indsel);
2866        num_j1_col=num_j1_col(indsel);
2867        num_j2_col=num_j2_col(indsel);
2868        [num_i1,num_j1]=meshgrid(num_i,num_j1_col);
2869        [num_i2,num_j2]=meshgrid(num_i,num_j2_col);
2870    end   
2871end
2872
2873%------------------------------------------------------------------------
2874% --- Executes on button press in CheckObject.
2875function CheckObject_Callback(hObject, eventdata, handles)
2876%------------------------------------------------------------------------
2877hset_object=findobj(allchild(0),'tag','set_object');%find the set_object interface handle
2878if get(handles.CheckObject,'Value')
2879    SeriesData=get(handles.series,'UserData');
2880    if isfield(SeriesData,'ProjObject') && ~isempty(SeriesData.ProjObject)
2881        set(handles.ViewObject,'Value',1)
2882        ViewObject_Callback(hObject, eventdata, handles)
2883    else
2884        if ishandle(hset_object)
2885            uistack(hset_object,'top')% show the GUI set_object if opened
2886        else
2887            %get the object file
2888            InputTable=get(handles.InputTable,'Data');
2889            defaultname=InputTable{1,1};
2890            if isempty(defaultname)
2891                defaultname={''};
2892            end
2893            fileinput=uigetfile_uvmat('pick a xml object file (or use uvmat to create it)',defaultname,'.xml');
2894            if isempty(fileinput)% exit if no object file is selected
2895                set(handles.CheckObject,'Value',0)
2896                return
2897            end
2898            %read the file
2899            data=xml2struct(fileinput);
2900            if ~isfield(data,'Type')
2901                msgbox_uvmat('ERROR',[fileinput ' is not an object xml file'])
2902                set(handles.CheckObject,'Value',0)
2903                return
2904            end
2905            if ~isfield(data,'ProjMode')
2906                data.ProjMode='none';
2907            end
2908            hset_object=set_object(data);% call the set_object interface
2909            set(hset_object,'Name','set_object_series')% name to distinguish from set_object used with uvmat
2910        end
2911        ProjObject=read_GUI(hset_object);
2912        set(handles.ProjObject,'String',ProjObject.Name);%display the object name
2913        SeriesData=get(handles.series,'UserData');
2914        SeriesData.ProjObject=ProjObject;
2915        set(handles.series,'UserData',SeriesData);
2916    end
2917    set(handles.EditObject,'Visible','on');
2918    set(handles.DeleteObject,'Visible','on');
2919    set(handles.ViewObject,'Visible','on');
2920    set(handles.ProjObject,'Visible','on');
2921else
2922    set(handles.EditObject,'Visible','off');
2923    set(handles.DeleteObject,'Visible','off');
2924    set(handles.ViewObject,'Visible','off');
2925    if ~ishandle(hset_object)
2926        set(handles.ViewObject,'Value',0);
2927    end
2928    set(handles.ProjObject,'Visible','off');
2929end
2930
2931%------------------------------------------------------------------------
2932% --- Executes on button press in ViewObject.
2933%------------------------------------------------------------------------
2934function ViewObject_Callback(hObject, eventdata, handles)
2935
2936UserData=get(handles.series,'UserData');
2937hset_object=findobj(allchild(0),'Tag','set_object');
2938if ~isempty(hset_object)
2939    delete(hset_object)% refresh set_object if already opened
2940end
2941hset_object=set_object(UserData.ProjObject);
2942set(hset_object,'Name','view_object_series')
2943
2944
2945%------------------------------------------------------------------------
2946% --- Executes on button press in EditObject.
2947function EditObject_Callback(hObject, eventdata, handles)
2948%------------------------------------------------------------------------
2949if get(handles.EditObject,'Value')
2950    set(handles.ViewObject,'Value',0)
2951        UserData=get(handles.series,'UserData');
2952    hset_object=set_object(UserData.ProjObject);
2953    set(hset_object,'Name','edit_object_series')
2954    set(get(hset_object,'Children'),'Enable','on')
2955else
2956    hset_object=findobj(allchild(0),'Tag','set_object');
2957    if ~isempty(hset_object)
2958        set(get(hset_object,'Children'),'Enable','off')
2959    end
2960end
2961
2962%------------------------------------------------------------------------
2963% --- Executes on button press in DeleteObject.
2964function DeleteObject_Callback(hObject, eventdata, handles)
2965%------------------------------------------------------------------------
2966SeriesData=get(handles.series,'UserData');
2967SeriesData.ProjObject=[];
2968set(handles.series,'UserData',SeriesData)
2969set(handles.ProjObject,'String','')
2970set(handles.ProjObject,'Visible','off')
2971set(handles.CheckObject,'Value',0)
2972set(handles.ViewObject,'Visible','off')
2973set(handles.EditObject,'Visible','off')
2974hset_object=findobj(allchild(0),'name','set_object_series');
2975if ~isempty(hset_object)
2976    delete(hset_object)
2977end
2978set(handles.DeleteObject,'Visible','off')
2979
2980%------------------------------------------------------------------------
2981% --- Executed when CheckMask is activated
2982%------------------------------------------------------------------------
2983function CheckMask_Callback(hObject, eventdata, handles)
2984
2985if get(handles.CheckMask,'Value')
2986    InputTable=get(handles.InputTable,'Data');
2987    nbview=size(InputTable,1);
2988    MaskTable=cell(nbview,1);%default
2989    ListMask=cell(nbview,1);%default
2990    MaskData=get(handles.MaskTable,'Data');
2991    MaskData(size(MaskData,1):nbview,1)=cell(size(MaskData,1):nbview,1);%complement if undefined lines
2992    for iview=1:nbview
2993        ListMask{iview,1}=num2str(iview);
2994        RootPath=InputTable{iview,1};
2995        if ~isempty(RootPath)
2996            if isempty(MaskData{iview})
2997                SubDir=InputTable{iview,2};
2998                MaskPath=fullfile(RootPath,[regexprep(SubDir,'\..*','') '.mask']);%take the root part of SubDir, before the first dot '.'
2999                if exist(MaskPath,'dir')
3000                    ListStruct=dir(MaskPath);%look for a mask file
3001                    ListCells=struct2cell(ListStruct);% transform dir struct to a cell arrray
3002                    check_dir=cell2mat(ListCells(4,:));% =1 for directories, =0 for files
3003                    ListFiles=ListCells(1,:);%list of file and dri names
3004                    ListFiles=ListFiles(~check_dir);%list of file names (excluding dir)
3005                    mdetect=0;
3006                    if ~isempty(ListFiles)
3007                        for ifile=1:numel(ListFiles)
3008                            [tild,tild,MaskFile{ifile},i1_series,i2_series,j1_series,j2_series,MaskNomType,MaskFileType]=find_file_series(MaskPath,ListFiles{ifile},0);
3009                            if strcmp(MaskFileType,'image') && isempty(i2_series) && isempty(j2_series)
3010                                mdetect=1;
3011                                MaskName=ListFiles{ifile};
3012                            end
3013                            if ~strcmp(MaskFile{ifile},MaskFile{1})
3014                                mdetect=0;% cancel detection test in case of multiple masks, use the brower for selection
3015                                break
3016                            end
3017                        end
3018                    end
3019                    if mdetect==1
3020                        MaskName=fullfile(MaskPath,'mask_1.png');
3021                    else
3022                        MaskName=uigetfile_uvmat('select a mask file:',MaskPath,'image');
3023                    end
3024                else
3025                    MaskName=uigetfile_uvmat('select a mask file:',RootPath,'image');
3026                end
3027                MaskTable{iview,1}=MaskName ;
3028                ListMask{iview,1}=num2str(iview);
3029            end
3030        end
3031    end
3032    set(handles.MaskTable,'Data',MaskTable)
3033    set(handles.MaskTable,'Visible','on')
3034    set(handles.MaskBrowse,'Visible','on')
3035    set(handles.ListMask,'Visible','on')
3036    set(handles.ListMask,'String',ListMask)
3037    set(handles.ListMask,'Value',1)
3038else
3039    set(handles.MaskTable,'Visible','off')
3040    set(handles.MaskBrowse,'Visible','off')
3041    set(handles.ListMask,'Visible','off')
3042end
3043
3044%------------------------------------------------------------------------
3045% --- Executes on button press in MaskBrowse.
3046%------------------------------------------------------------------------
3047function MaskBrowse_Callback(hObject, eventdata, handles)
3048
3049InputTable=get(handles.InputTable,'Data');
3050iview=get(handles.ListMask,'Value');
3051RootPath=InputTable{iview,1};
3052MaskName=uigetfile_uvmat('select a mask file:',RootPath,'image');
3053if ~isempty(MaskName)
3054    MaskTable=get(handles.MaskTable,'Data');
3055    MaskTable{iview,1}=MaskName ;
3056    set(handles.MaskTable,'Data',MaskTable)
3057end
3058
3059%------------------------------------------------------------------------
3060% --- Executes when selected cell(s) is changed in MaskTable.
3061%------------------------------------------------------------------------
3062function MaskTable_CellSelectionCallback(hObject, eventdata, handles)
3063
3064if numel(eventdata.Indices)>=1
3065set(handles.ListMask,'Value',eventdata.Indices(1))
3066end
3067
3068%-------------------------------------------------------------------
3069function MenuHelp_Callback(hObject, eventdata, handles)
3070%-------------------------------------------------------------------
3071
3072
3073% path_to_uvmat=which ('uvmat');% check the path of uvmat
3074% pathelp=fileparts(path_to_uvmat);
3075% helpfile=fullfile(pathelp,'uvmat_doc','uvmat_doc.html');
3076% 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')
3077% else
3078%     addpath (fullfile(pathelp,'uvmat_doc'))
3079%     web([helpfile '#series'])
3080% end
3081
3082%-------------------------------------------------------------------
3083% --- Executes on selection change in TransformName.
3084function TransformName_Callback(hObject, eventdata, handles)
3085%----------------------------------------------------------------------
3086TransformList=get(handles.TransformName,'String');
3087TransformIndex=get(handles.TransformName,'Value');
3088TransformName=TransformList{TransformIndex};
3089TransformPathList=get(handles.TransformName,'UserData');
3090nb_builtin_transform=4;
3091if isequal(TransformName,'more...');     
3092    FileName=uigetfile_uvmat('Pick a transform function',get(handles.TransformPath,'String'),'.m');
3093    if isempty(FileName)
3094        return     %browser closed without choice
3095    end
3096    [TransformPath,TransformName,TransformExt]=fileparts(FileName);% removes extension .m
3097    if ~strcmp(TransformExt,'.m')
3098        msgbox_uvmat('ERROR','a Matlab function .m must be introduced');
3099        return
3100    end
3101     % insert the choice in the menu
3102    TransformIndex=find(strcmp(TransformName,TransformList),1);% look for the selected function in the menu Action
3103    if isempty(TransformIndex)%the input string does not exist in the menu
3104        TransformIndex= length(TransformList);
3105        TransformList=[TransformList(1:end-1);{TransformName};TransformList(end)];% the selected function is appended in the menu, before the last item 'more...'
3106        set(handles.TransformName,'String',TransformList)
3107        TransformPathList=[TransformPathList;{TransformPath}];
3108    else% the input function already exist, we update its path (possibly new)
3109        TransformPathList{TransformIndex}=TransformPath;%
3110        set(handles.TransformName,'Value',TransformIndex)
3111    end
3112   % save the new menu in the personal file 'uvmat_perso.mat'
3113   dir_perso=prefdir;%personal Matalb directory
3114   profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
3115   if exist(profil_perso,'file')
3116       for ilist=nb_builtin_transform+1:numel(TransformPathList)
3117           TransformListUser{ilist-nb_builtin_transform}=TransformList{ilist};
3118           TransformPathListUser{ilist-nb_builtin_transform}=TransformPathList{ilist};
3119       end
3120       TransformPathListUser=TransformPathListUser';
3121       TransformListUser=TransformListUser';
3122       save (profil_perso,'TransformPathListUser','TransformListUser','-append'); %store the root name for future opening of uvmat
3123   end
3124end
3125
3126%display the current function path
3127set(handles.TransformPath,'String',TransformPathList{TransformIndex}); %show the path to the senlected function
3128set(handles.TransformName,'UserData',TransformPathList);
3129
3130%% create the function handle of the selected fct
3131if ~isempty(TransformName)
3132    if ~exist(TransformPathList{TransformIndex},'dir')
3133        msgbox_uvmat('ERROR',['The prescribed transform function path ' TransformPathList{TransformIndex} ' does not exist']);
3134        return
3135    end
3136    current_dir=pwd;%current working dir
3137    cd(TransformPathList{TransformIndex})
3138    transform_handle=str2func(TransformName);
3139    cd(current_dir)
3140    Field.Action.RUN=0;% indicate that the transform fct is called only to get input param
3141    DataOut=feval(transform_handle,Field,[]);% execute the transform fct to get the required conditions
3142    if isfield(DataOut,'TransformInput')%  used to add transform parameters at selection of the transform fct
3143        SeriesData=get(handles.series,'UserData');
3144        SeriesData.TransformInput=DataOut.TransformInput;
3145        set(handles.series,'UserData',SeriesData)
3146    end
3147end
3148
3149%------------------------------------------------------------------------
3150% --- fct activated by the upper bar menu ExportConfig
3151%------------------------------------------------------------------------
3152function MenuDisplayConfig_Callback(hObject, eventdata, handles)
3153
3154global Param
3155Param=read_GUI_series(handles);
3156evalin('base','global Param')%make CurData global in the workspace
3157display('current series config :')
3158evalin('base','Param') %display CurData in the workspace
3159commandwindow; %brings the Matlab command window to the front
3160
3161%------------------------------------------------------------------------
3162% --- fct activated by the upper bar menu InportConfig: import
3163%     menu settings from an xml file (stored in /0_XML for each run)
3164%------------------------------------------------------------------------
3165function MenuImportConfig_Callback(hObject, eventdata, handles)
3166
3167%% use a browser to choose the xml file containing the processing config
3168InputTable=get(handles.InputTable,'Data');
3169oldfile=InputTable{1,1};%current path in InputTable
3170if isempty(oldfile)
3171    % use a file name stored in prefdir
3172    dir_perso=prefdir;
3173    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
3174    if exist(profil_perso,'file')
3175        h=load (profil_perso);
3176        if isfield(h,'RootPath') && ischar(h.RootPath)
3177            oldfile=h.RootPath;
3178        end
3179    end
3180end
3181filexml=uigetfile_uvmat('pick a xml parameter file',oldfile,'.xml');% get the xml file containing processing parameters
3182if isempty(filexml), return, end % quit function if an xml file has not been opened
3183
3184%% fill the GUI series with the content of the xml file
3185Param=xml2struct(filexml);% read the input xml file as a Matlab structure
3186
3187% ask to stop current Action if button RUN is in action (another process is already running)
3188if isequal(get(handles.RUN,'Value'),1)
3189    answer= msgbox_uvmat('INPUT_Y-N','stop current Action process?');
3190    if strcmp(answer,'Yes')
3191        STOP_Callback(hObject, eventdata, handles)
3192    else
3193        return
3194    end
3195end
3196Param.Action.RUN=0; %desactivate the input RUN=1
3197
3198fill_GUI(Param,handles.series)% fill the elements of the GUI series with the input parameters
3199SeriesData=get(handles.series,'UserData');
3200if isfield(Param,'InputFields')
3201    ListField=Param.InputFields.FieldName;
3202    if ischar(ListField),ListField={ListField}; end
3203    set(handles.FieldName,'String',[ListField;{'get-field...'}])
3204     set(handles.FieldName,'Value',1:numel(ListField))
3205     set(handles.FieldName,'Visible','on')
3206end       
3207if isfield(Param,'ActionInput')%  introduce  parameters specific to an Action fct, for instance PIV parameters
3208    set(handles.ActionInput,'Visible','on')
3209    set(handles.ActionInput,'Value',0)
3210    Param.ActionInput.ConfigSource=filexml;% record the source of config for future info
3211    SeriesData.ActionInput=Param.ActionInput;
3212end
3213if isfield(Param,'TransformInput')%  introduce  parameters specific to a transform fct
3214    SeriesData.TransformInput=Param.TransformInput;
3215end
3216if isfield(Param,'ProjObject') %introduce projection object if relevant
3217    SeriesData.ProjObject=Param.ProjObject;
3218end
3219set(handles.series,'UserData',SeriesData)
3220if isfield(Param,'CheckObject') && isequal(Param.CheckObject,1)
3221    set(handles.ProjObject,'String',Param.ProjObject.Name)
3222    set(handles.ViewObject,'Visible','on')
3223    set(handles.EditObject,'Visible','on')
3224    set(handles.DeleteObject,'Visible','on')
3225else     
3226    set(handles.ProjObject,'String','')
3227    set(handles.ProjObject,'Visible','off')
3228    set(handles.ViewObject,'Visible','off')
3229    set(handles.EditObject,'Visible','off')
3230    set(handles.DeleteObject,'Visible','off')     
3231end     
3232set(handles.REFRESH,'BackgroundColor',[1 0 1]); %paint REFRESH button in magenta to indicate that it should be activated
3233
3234
3235%------------------------------------------------------------------------
3236% --- Executes when the GUI series is resized.
3237%------------------------------------------------------------------------
3238function series_ResizeFcn(hObject, eventdata, handles)
3239
3240%% input table
3241set(handles.InputTable,'Unit','pixel')
3242Pos=get(handles.InputTable,'Position');
3243set(handles.InputTable,'Unit','normalized')
3244ColumnWidth=round([0.5 0.14 0.14 0.14 0.08]*(Pos(3)-52));
3245ColumnWidth=num2cell(ColumnWidth);
3246set(handles.InputTable,'ColumnWidth',ColumnWidth)
3247
3248%% MinIndex_j and MaxIndex_i
3249unit=get(handles.MinIndex_i,'Unit');
3250set(handles.MinIndex_i,'Unit','pixel')
3251Pos=get(handles.MinIndex_i,'Position');
3252set(handles.MinIndex_i,'Unit',unit)
3253set(handles.MinIndex_i,'ColumnWidth',{Pos(3)-18})
3254set(handles.MaxIndex_i,'ColumnWidth',{Pos(3)-18})
3255set(handles.MinIndex_j,'ColumnWidth',{Pos(3)-18})
3256set(handles.MaxIndex_j,'ColumnWidth',{Pos(3)-18})
3257
3258%% TimeTable
3259set(handles.TimeTable,'Unit','pixel')
3260Pos=get(handles.TimeTable,'Position');
3261set(handles.TimeTable,'Unit','normalized')
3262% ColumnWidth=get(handles.TimeTable,'ColumnWidth');
3263ColumnWidth=num2cell(floor([0.2 0.2 0.2 0.2 0.2]*(Pos(3)-20)));
3264set(handles.TimeTable,'ColumnWidth',ColumnWidth)
3265
3266
3267%% PairString
3268set(handles.PairString,'Unit','pixel')
3269Pos=get(handles.PairString,'Position');
3270set(handles.PairString,'Unit','normalized')
3271set(handles.PairString,'ColumnWidth',{Pos(3)-5})
3272
3273%% MaskTable
3274set(handles.MaskTable,'Unit','pixel')
3275Pos=get(handles.MaskTable,'Position');
3276set(handles.MaskTable,'Unit','normalized')
3277set(handles.MaskTable,'ColumnWidth',{Pos(3)-5})
3278
3279%------------------------------------------------------------------------
3280% --- Executes on button press in status.
3281%------------------------------------------------------------------------
3282function status_Callback(hObject, eventdata, handles)
3283
3284if get(handles.status,'Value')
3285    set(handles.status,'BackgroundColor',[1 1 0])
3286    drawnow
3287    Param=read_GUI(handles.series);
3288    RootPath=Param.InputTable{1,1};
3289    if ~isfield(Param,'OutputSubDir')   
3290        msgbox_uvmat('ERROR','no standard sub-directory definition for output files, use a browser to check the output')
3291        set(handles.status,'BackgroundColor',[0 1 0])
3292        return
3293    end
3294    OutputSubDir=[Param.OutputSubDir Param.OutputDirExt];% subdirectory for output files
3295    OutputDir=fullfile(RootPath,OutputSubDir);
3296    if exist(OutputDir,'dir')
3297        uigetfile_uvmat('status_display',OutputDir)
3298    else
3299        msgbox_uvmat('ERROR','output folder not created yet: calculation did not start')
3300        set(handles.status,'BackgroundColor',[0 1 0])
3301    end
3302else
3303    %% delete current display fig if selection is off
3304    set(handles.status,'BackgroundColor',[0 1 0])
3305    hfig=findobj(allchild(0),'name','status_display');
3306    if ~isempty(hfig)
3307        delete(hfig)
3308    end
3309    return
3310end
3311
3312
3313%------------------------------------------------------------------------   
3314% launched by selecting a file on the list
3315%------------------------------------------------------------------------
3316function view_file(hObject, eventdata)
3317
3318list=get(hObject,'String');
3319index=get(hObject,'Value');
3320rootroot=get(hObject,'UserData');
3321selectname=list{index};
3322ind_dot=regexp(selectname,'\.\.\.');
3323if ~isempty(ind_dot)
3324    selectname=selectname(1:ind_dot-1);
3325end
3326FullSelectName=fullfile(rootroot,selectname);
3327if exist(FullSelectName,'dir')% a directory has been selected
3328    ListFiles=dir(FullSelectName);
3329    ListDisplay=cell(numel(ListFiles),1);
3330    for ilist=2:numel(ListDisplay)% suppress the first line '.'
3331        ListDisplay{ilist-1}=ListFiles(ilist).name;
3332    end
3333    set(hObject,'Value',1)
3334    set(hObject,'String',ListDisplay)
3335    if strcmp(selectname,'..')
3336        FullSelectName=fileparts(fileparts(FullSelectName));
3337    end
3338    set(hObject,'UserData',FullSelectName)
3339    hfig=get(hObject,'parent');
3340    htitlebox=findobj(hfig,'tag','titlebox');   
3341    set(htitlebox,'String',FullSelectName)
3342elseif exist(FullSelectName,'file')%visualise the vel field if it exists
3343    FileInfo=get_file_info(FullSelectName);   
3344    if strcmp(FileInfo.FileType,'txt')
3345        edit(FullSelectName)
3346    elseif strcmp(FileInfo.FileType,'xml')
3347        editxml(FullSelectName)
3348    else
3349        uvmat(FullSelectName)
3350    end
3351    set(gcbo,'Value',1)
3352end
3353
3354
3355%------------------------------------------------------------------------   
3356% launched by refreshing the status figure
3357%------------------------------------------------------------------------
3358function refresh_GUI(hfig)
3359
3360htitlebox=findobj(hfig,'tag','titlebox');
3361hlist=findobj(hfig,'tag','list');
3362hseries=findobj(allchild(0),'tag','series');
3363hstatus=findobj(hseries,'tag','status');
3364StatusData=get(hstatus,'UserData');
3365OutputDir=get(htitlebox,'String');
3366if ischar(OutputDir),OutputDir={OutputDir};end
3367ListFiles=dir(OutputDir{1});
3368if numel(ListFiles)<1
3369    return
3370end
3371ListFiles(1)=[];%removes the first line ='.'
3372ListDisplay=cell(numel(ListFiles),1);
3373testrecent=0;
3374datnum=zeros(numel(ListDisplay),1);
3375for ilist=1:numel(ListDisplay)
3376    ListDisplay{ilist}=ListFiles(ilist).name;
3377      if ~ListFiles(ilist).isdir && isfield(ListFiles(ilist),'datenum')
3378            datnum(ilist)=ListFiles(ilist).datenum;%only available in recent matlab versions
3379            testrecent=1;
3380       end
3381end
3382set(hlist,'String',ListDisplay)
3383
3384%% Look at date of creation
3385ListDisplay=ListDisplay(datnum~=0);
3386datnum=datnum(datnum~=0);%keep the non zero values corresponding to existing files
3387NbOutputFile=[];
3388if isempty(datnum)
3389    if testrecent
3390        message='no civ result created yet';
3391    else
3392        message='';
3393    end
3394else
3395    [first,indfirst]=min(datnum);
3396    [last,indlast]=max(datnum);
3397    NbOutputFile_str='?';
3398    NbOutputFile=[];
3399    if isfield(StatusData,'NbOutputFile')
3400        NbOutputFile=StatusData.NbOutputFile;
3401        NbOutputFile_str=num2str(NbOutputFile);
3402    end
3403    message={[num2str(numel(datnum)) ' file(s) done over ' NbOutputFile_str] ;['oldest modification:  ' ListDisplay{indfirst} ' : ' datestr(first)];...
3404        ['latest modification:  ' ListDisplay{indlast} ' : ' datestr(last)]};
3405end
3406set(htitlebox,'String', [OutputDir{1};message])
3407
3408%% update the waitbar
3409hwaitbar=findobj(hfig,'tag','waitbar');
3410if ~isempty(NbOutputFile)
3411    BarPosition=get(hwaitbar,'Position');
3412    BarPosition(3)=0.9*numel(datnum)/NbOutputFile;
3413    set(hwaitbar,'Position',BarPosition)
3414end
3415
3416%------------------------------------------------------------------------
3417% --- Executes on selection change in ActionExt.
3418%------------------------------------------------------------------------
3419function ActionExt_Callback(hObject, eventdata, handles)
3420
3421ActionExtList=get(handles.ActionExt,'String');
3422ActionExt=ActionExtList{get(handles.ActionExt,'Value')};
3423if strcmp(ActionExt,'.py (in dev.)')
3424    set(handles.RunMode,'Value',2)
3425end
3426
3427%function num_NbProcess_Callback(hObject, eventdata, handles)
3428
3429
3430function num_NbSlice_Callback(hObject, eventdata, handles)
3431NbSlice=str2num(get(handles.num_NbSlice,'String'));
3432%set(handles.num_NbProcess,'String',num2str(NbSlice))
3433
3434%------------------------------------------------------------------------
3435% --- set the visibility of relevant velocity type menus:
3436function menu=set_veltype_display(Civ,FileType)
3437%------------------------------------------------------------------------
3438if ~exist('FileType','var')
3439    FileType='civx';
3440end
3441switch FileType
3442    case 'civx'
3443        menu={'civ1';'interp1';'filter1';'civ2';'interp2';'filter2'};
3444        if isequal(Civ,0)
3445            imax=0;
3446        elseif isequal(Civ,1) || isequal(Civ,2)
3447            imax=1;
3448        elseif isequal(Civ,3)
3449            imax=3;
3450        elseif isequal(Civ,4) || isequal(Civ,5)
3451            imax=4;
3452        elseif isequal(Civ,6) %patch2
3453            imax=6;
3454        end
3455    case 'civdata'
3456        menu={'civ1';'filter1';'civ2';'filter2'};
3457        if isequal(Civ,0)
3458            imax=0;
3459        elseif isequal(Civ,1) || isequal(Civ,2)
3460            imax=1;
3461        elseif isequal(Civ,3)
3462            imax=2;
3463        elseif isequal(Civ,4) || isequal(Civ,5)
3464            imax=3;
3465        else%if isequal(Civ,6) %patch2
3466            imax=4;
3467        end
3468end
3469menu=menu(1:imax);
3470
3471
3472% --- Executes on mouse motion over figure - except title and menu.
3473function series_WindowButtonMotionFcn(hObject, eventdata, handles)
3474set(hObject,'Pointer','arrow');
3475
3476
3477% --- Executes on button press in SetPairs.
3478function SetPairs_Callback(hObject, iview, handles)
3479
3480%% delete previous occurrence of 'set_pairs'
3481hfig=findobj(allchild(0),'Tag','set_pairs');
3482if ~isempty(hfig)
3483delete(hfig)
3484end
3485
3486%% create the GUI set_pairs
3487set(0,'Unit','points')
3488ScreenSize=get(0,'ScreenSize');% get the size of the screen, to put the fig on the upper right
3489Width=220;% fig width in points (1/72 inch)
3490Height=min(0.8*ScreenSize(4),300);
3491Left=ScreenSize(3)- Width-40; %right edge close to the right, with margin=40
3492Bottom=ScreenSize(4)-Height-40; %put fig at top right
3493hfig=findobj(allchild(0),'Tag','set_slice');
3494if ~isempty(hfig),delete(hfig), end; %delete existing version of the GUI
3495hfig=figure('name','set_pairs','tag','set_pairs','MenuBar','none','NumberTitle','off','Unit','points','Position',[Left,Bottom,Width,Height]);
3496BackgroundColor=get(hfig,'Color');
3497SeriesData=get(handles.series,'UserData');
3498TimeUnit=get(handles.TimeUnit,'String');
3499PairString=get(handles.PairString,'Data');
3500ListViewLines=find(cellfun('isempty',PairString)==0);%find list of non empty pairs
3501ListViewMenu=cell(numel(ListViewLines),1);
3502for ilist=1:numel(ListViewLines)
3503    ListViewMenu{ilist}=num2str(ListViewLines(ilist));
3504end
3505if isempty(iview)
3506    ListViewValue=numel(ListViewLines);% we work by default on the pair option for the last line which requires pairs
3507    iview=ListViewLines(end);
3508else
3509    ListViewValue=find(ListViewLines==iview);
3510end
3511ref_i=str2num(get(handles.num_first_i,'String'));
3512ref_j=1;%default
3513if strcmp(get(handles.num_first_j,'String'),'Visible')
3514    ref_j=str2num(get(handles.num_first_j,'String'));
3515end
3516[ModeMenu,ModeValue]=update_mode(SeriesData.i1_series{iview},SeriesData.i2_series{iview},SeriesData.j2_series{iview});
3517displ_pair=update_listpair(SeriesData.i1_series{iview},SeriesData.i2_series{iview},SeriesData.j1_series{iview},SeriesData.j2_series{iview},ModeMenu{ModeValue},...
3518                                                     SeriesData.Time{iview},TimeUnit,ref_i,ref_j,SeriesData.FileInfo{iview});
3519% first raw of the GUI
3520uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.88 0.5 0.1],'BackgroundColor',BackgroundColor,...
3521    'String','row to edit #','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','right');%title
3522uicontrol('Style','popupmenu','Units','normalized', 'Position', [0.54 0.8 0.3 0.2],'BackgroundColor',[1 1 1],...
3523    'Callback',@(hObject,eventdata)ListView_Callback(hObject,eventdata),'String',ListViewMenu,'Value',ListViewValue,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3524    'Tag','ListView','TooltipString','''ListView'':choice of the file series w for pair display');
3525% second raw of the GUI
3526uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.79 0.7 0.1],'BackgroundColor',BackgroundColor,...
3527    'String','mode of index pairing:','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','left');%title
3528uicontrol('Style','popupmenu','Units','normalized', 'Position', [0.05 0.62 0.9 0.2],'BackgroundColor',[1 1 1],...
3529    'Callback',@(hObject,eventdata)Mode_Callback(hObject,eventdata),'String',ModeMenu,'Value',ModeValue,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3530    'Tag','Mode','TooltipString','''Mode'': choice of the image pair mode');
3531% third raw
3532uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.6 0.7 0.1],'BackgroundColor',BackgroundColor,...
3533    'String','pair choice:','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','left');%title
3534uicontrol('Style','listbox','Units','normalized', 'Position', [0.05 0.42 0.9 0.2],'BackgroundColor',[1 1 1],...
3535    'Callback',@(hObject,eventdata)ListPair_Callback(hObject,eventdata),'String',displ_pair,'Value',1,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3536    'Tag','ListPair','TooltipString','''ListPair'': menu for selecting the image pair');
3537uicontrol('Style','text','Units','normalized', 'Position', [0.1 0.22 0.8 0.1],'BackgroundColor',BackgroundColor,...
3538    'String','ref_i           ref_j','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','center');%title
3539uicontrol('Style','edit','Units','normalized', 'Position', [0.15 0.17 0.3 0.08],'BackgroundColor',[1 1 1],...
3540    'Callback',@(hObject,eventdata)num_ref_i_Callback(hObject,eventdata),'String',num2str(ref_i),'FontUnits','points','FontSize',12,'FontWeight','bold',...
3541    'Tag','num_ref_i','TooltipString','''num_ref_i'': reference field index i used to display dt in ''list_pair_civ''');
3542uicontrol('Style','edit','Units','normalized', 'Position', [0.55 0.17 0.3 0.08],'BackgroundColor',[1 1 1],...
3543    'Callback',@(hObject,eventdata)num_ref_j_Callback(hObject,eventdata),'String',num2str(ref_j),'FontUnits','points','FontSize',12,'FontWeight','bold',...
3544    'Tag','num_ref_j','TooltipString','''num_ref_j'': reference field index i used to display dt in ''list_pair_civ''');
3545uicontrol('Style','pushbutton','Units','normalized', 'Position', [0.01 0.01 0.3 0.12],'BackgroundColor',[0 1 0],...
3546    'Callback',@(hObject,eventdata)OK_Callback(hObject,eventdata),'String','OK','FontUnits','points','FontSize',12,'FontWeight','bold',...
3547    'Tag','OK','TooltipString','''OK'': validate the choice');
3548%  last raw  of the GUI: pushbuttons
3549% 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),...
3550%     'FontWeight','bold','FontUnits','points','FontSize',12,'TooltipString','''OK'': apply the output to the current field series in uvmat');
3551drawnow
3552
3553%------------------------------------------------------------------------
3554function ListView_Callback(hObject,eventdata)
3555Mode_Callback(hObject,eventdata)
3556
3557%------------------------------------------------------------------------   
3558function Mode_Callback(hObject,eventdata)
3559%% get input info
3560hseries=findobj(allchild(0),'tag','series');%handles of the GUI series
3561hhseries=guidata(hseries);%handles of the elements in the GUI series
3562TimeUnit=get(hhseries.TimeUnit,'String');
3563SeriesData=get(hseries,'UserData');
3564mode_list=get(hObject,'String');
3565mode=mode_list{get(hObject,'Value')};
3566hListView=findobj(get(hObject,'parent'),'Tag','ListView');
3567iview=get(hListView,'Value');
3568i1_series=SeriesData.i1_series{iview};
3569i2_series=SeriesData.i2_series{iview};
3570j1_series=SeriesData.j1_series{iview};
3571j2_series=SeriesData.j2_series{iview};
3572
3573%% enable j index visibility after the new choice
3574status_j='on';%default
3575if isempty(find(~cellfun(@isempty,SeriesData.j1_series), 1)); % case of empty j indices
3576    status_j='off'; % no j index needed
3577elseif strcmp(get(handles.PairString,'Visible'),'on')
3578    check_burst=cellfun(@isempty,regexp(PairString,'^j'));%=0 for burst case, 1 otherwise
3579    if isempty(find(check_burst, 1))% if all pair string begins by j (burst)
3580        status_j='off'; % no j index needed for bust case
3581    end
3582end
3583enable_j(handles,status_j) % no j index needed
3584
3585%% get the reference indices for the time interval Dt
3586href_i=findobj(get(hObject,'parent'),'Tag','ref_i');
3587ref_i=[];ref_j=[];
3588if strcmp(get(href_i,'Visible'),'on')
3589    ref_i=str2num(get(href_i,'String'));
3590end
3591if isempty(ref_i)
3592    ref_i=1;
3593end
3594if isempty(ref_j)
3595    ref_j=1;
3596end
3597
3598%% update the menu ListPair
3599Menu=update_listpair(i1_series,i2_series,j1_series,j2_series,mode,SeriesData.Time{iview},TimeUnit,ref_i,ref_j,FileInfo);
3600hlist_pairs=findobj(get(hObject,'parent'),'Tag','ListPair');
3601set(hlist_pairs,'Value',1)% set the first choice by default in ListPair
3602set(hlist_pairs,'String',Menu)% set the menu in ListPair
3603ListPair_Callback(hlist_pairs,[])% apply the default choice in ListPair
3604
3605%-------------------------------------------------------------
3606% --- Executes on selection in ListPair.
3607function ListPair_Callback(hObject,eventdata)
3608%------------------------------------------------------------
3609list_pair=get(hObject,'String');%get the menu of image pairs
3610if isempty(list_pair)
3611    string='';
3612else
3613    string=list_pair{get(hObject,'Value')};
3614   % string=regexprep(string,',.*','');%removes time indication (after ',')
3615end
3616hseries=findobj(allchild(0),'tag','series');
3617hPairString=findobj(hseries,'tag','PairString');
3618PairString=get(hPairString,'Data');
3619hListView=findobj(get(hObject,'parent'),'Tag','ListView');
3620iview=get(hListView,'Value');
3621PairString{iview,1}=string;
3622% report the selected pair string to the table PairString
3623set(hPairString,'Data',PairString)
3624
3625
3626%------------------------------------------------------------------------
3627function num_ref_i_Callback(hObject, eventdata)
3628%------------------------------------------------------------------------
3629Mode_Callback([],[])
3630
3631%------------------------------------------------------------------------
3632function num_ref_j_Callback(hObject, eventdata)
3633%------------------------------------------------------------------------
3634Mode_Callback([],[])
3635
3636%------------------------------------------------------------------------
3637function OK_Callback(hObject, eventdata)
3638%------------------------------------------------------------------------
3639delete(get(hObject,'parent'))
3640
3641
3642%------------------------------------------------------------------------
3643% --- Executes on button press in ClearLine.
3644%------------------------------------------------------------------------
3645function ClearLine_Callback(hObject, eventdata, handles)
3646InputTable=get(handles.InputTable,'Data');
3647iline=str2double(get(handles.InputLine,'String'));
3648if size(InputTable,1)>1
3649    InputTable(iline,:)=[];% suppress the current line if not the first
3650    set(handles.InputTable,'Data',InputTable);
3651end
3652set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH button to magenta color to indicate that input refr
3653
3654
3655% --- Executes on button press in MonitorCluster.
3656function MonitorCluster_Callback(hObject, eventdata, handles)
3657web('https://www.legi.grenoble-inp.fr/servload/monika')
3658
3659
3660
3661function OutputSubDir_Callback(hObject, eventdata, handles)
3662set(handles.OutputSubDir,'BackgroundColor',[1 1 1])
3663
3664
3665% --- Executes on button press in CheckOverwrite.
3666function CheckOverwrite_Callback(hObject, eventdata, handles)
3667
3668
3669
3670% --- Executes on button press in TestCPUTime.
3671function TestCPUTime_Callback(hObject, eventdata, handles)
3672% hObject    handle to TestCPUTime (see GCBO)
3673% eventdata  reserved - to be defined in a future version of MATLAB
3674% handles    structure with handles and user data (see GUIDATA)
3675
3676
3677
3678
3679
Note: See TracBrowser for help on using the repository browser.