source: trunk/src/series.m @ 928

Last change on this file since 928 was 928, checked in by sommeria, 5 years ago

corrections

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