source: trunk/src/series.m @ 973

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