source: trunk/src/series.m @ 883

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

bugs corrected in series, transform functions with input parameters introduced, civ/deformation corrected (sign)

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