source: trunk/src/series.m @ 896

Last change on this file since 896 was 896, checked in by sommeria, 9 years ago

bug corrected in civ_series/patch

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