source: trunk/src/series.m @ 877

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

deformation modified in civ_series and bug corrections

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