source: trunk/src/series.m @ 936

Last change on this file since 936 was 935, checked in by sommeria, 8 years ago

various improvments

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