source: trunk/src/series.m @ 991

Last change on this file since 991 was 991, checked in by sommeria, 7 years ago

various

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