source: trunk/src/series.m @ 901

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