source: trunk/src/series.m @ 909

Last change on this file since 909 was 909, checked in by sommeria, 6 years ago

various bug repair

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