source: trunk/src/series.m @ 989

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