source: trunk/src/series.m @ 889

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

bug on memory increase solved for civ_series and stereo_civ, corrections for Matlab2014b

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