source: trunk/src/series.m @ 983

Last change on this file since 983 was 983, checked in by g7moreau, 7 years ago
  • Add Matlab load module with the good version
File size: 161.8 KB
RevLine 
[867]1%'series': master function associated to the GUI series.m for analysis field series 
2%------------------------------------------------------------------------
3% function varargout = series(varargin)
4% associated with the GUI series.fig
5%
6%INPUT
7% param: structure with input parameters (link with the GUI uvmat)
8%      .menu_coord_str: string for the TransformName (menu for coordinate transforms)
9%      .menu_coord_val: value for TransformName (menu for coordinate transforms)
10%      .FileName: input file name
11%      .FileName_1: second input file name
12%      .list_field: menu of input fields
13%      .index_fields: chosen index
14%      .civ1=0 or 1, .interp1,  ... : input civ field type
15%
[924]16
17%=======================================================================
[977]18% Copyright 2008-2017, LEGI UMR 5519 / CNRS UGA G-INP, Grenoble, France
[924]19%   http://www.legi.grenoble-inp.fr
20%   Joel.Sommeria - Joel.Sommeria (A) legi.cnrs.fr
21%
[867]22%     This file is part of the toolbox UVMAT.
[924]23%
[867]24%     UVMAT is free software; you can redistribute it and/or modify
[924]25%     it under the terms of the GNU General Public License as published
26%     by the Free Software Foundation; either version 2 of the license,
27%     or (at your option) any later version.
28%
[867]29%     UVMAT is distributed in the hope that it will be useful,
30%     but WITHOUT ANY WARRANTY; without even the implied warranty of
31%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
[924]32%     GNU General Public License (see LICENSE.txt) for more details.
33%=======================================================================
[867]34
35%------------------------------------------------------------------------
36%------------------------------------------------------------------------
37%  I - MAIN FUNCTION series
38%------------------------------------------------------------------------
39%------------------------------------------------------------------------
40function varargout = series(varargin)
41
42% Begin initialization code - DO NOT EDIT
43gui_Singleton = 1;
44gui_State = struct('gui_Name',       mfilename, ...
45                   'gui_Singleton',  gui_Singleton, ...
46                   'gui_OpeningFcn', @series_OpeningFcn, ...
47                   'gui_OutputFcn',  @series_OutputFcn, ...
48                   'gui_LayoutFcn',  [] , ...
49                   'gui_Callback',   []);
50if nargin && ischar(varargin{1})
51    gui_State.gui_Callback = str2func(varargin{1});
52end
53
54if nargout
55    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
56else
57    gui_mainfcn(gui_State, varargin{:});
58end
59% End initialization code - DO NOT EDIT
60
61%--------------------------------------------------------------------------
62% --- Executes just before series is made visible.
63%--------------------------------------------------------------------------
64function series_OpeningFcn(hObject, eventdata, handles,Param)
65
66% Choose default command line output for series
67handles.output = hObject;
68% Update handles structure
69guidata(hObject, handles);
70
71%% initial settings
72% position and  size of the GUI at opening
73set(0,'Unit','points')
74ScreenSize=get(0,'ScreenSize');%size of the current screen, in points (1/72 inch)
75Width=900;% prefered width of the GUI in points (1/72 inch)
76Height=624;% prefered height of the GUI in points (1/72 inch)
77%adjust to screen size (reduced by a min margin)
78RescaleFactor=min((ScreenSize(3)-80)/Width,(ScreenSize(4)-80)/Height);
79if RescaleFactor>1
80    RescaleFactor=min(RescaleFactor,1);
81end
82Width=Width*RescaleFactor;
83Height=Height*RescaleFactor;
84LeftX=80*RescaleFactor;%position of the left fig side, in pixels (put to the left side, with some margin)
85LowY=round(ScreenSize(4)/2-Height/2); % put at the middle height on the screen
86set(hObject,'Units','points')
87set(hObject,'Position',[LeftX LowY Width Height])% position and size of the GUI at opening
88
89% settings of table MinIndex_j
90set(handles.MinIndex_i,'ColumnFormat',{'numeric'})
91set(handles.MinIndex_i,'ColumnEditable',false)
92set(handles.MinIndex_i,'ColumnName',{'i min'})
93set(handles.MinIndex_i,'Data',[])% initiate Data to double (not cell)
94
95% settings of table MinIndex_j
96set(handles.MinIndex_j,'ColumnFormat',{'numeric'})
97set(handles.MinIndex_j,'ColumnEditable',false)
98set(handles.MinIndex_j,'ColumnName',{'j min'})
99set(handles.MinIndex_j,'Data',[])% initiate Data to double (not cell)
100
101% settings of table MaxIndex_i
102set(handles.MaxIndex_i,'ColumnFormat',{'numeric'})
103set(handles.MaxIndex_i,'ColumnEditable',false)
104set(handles.MaxIndex_i,'ColumnName',{'i max'})
105set(handles.MaxIndex_i,'Data',[])% initiate Data to double (not cell)
106
107% settings of table MaxIndex_j
108set(handles.MaxIndex_j,'ColumnFormat',{'numeric'})
109set(handles.MaxIndex_j,'ColumnEditable',false)
110set(handles.MaxIndex_j,'ColumnName',{'j max'})
111set(handles.MaxIndex_j,'Data',[])% initiate Data to double (not cell)
112
113% settings of table PairString
114set(handles.PairString,'ColumnName',{'pairs'})
115set(handles.PairString,'ColumnEditable',false)
116set(handles.PairString,'ColumnFormat',{'char'})
117set(handles.PairString,'Data',{''})
118
119% settings of table MaskTable
120set(handles.MaskTable,'ColumnName',{'mask name'})
121set(handles.PairString,'ColumnEditable',false)
122set(handles.PairString,'ColumnFormat',{'char'})
123set(handles.PairString,'Data',{''})
124
125series_ResizeFcn(hObject, eventdata, handles)%resize table according to series GUI size
126set(hObject,'WindowButtonDownFcn',{'mouse_down'})%allows mouse action with right button (zoom for uicontrol display)
127set(hObject,'DeleteFcn',{@closefcn})%
128
129% check default input data
130if ~exist('Param','var')
131    Param=[]; %default
132end
133
134%% list of builtin functions in the mebu ActionName
135ActionList={'check_data_files';'aver_stat';'time_series';'civ_series';'merge_proj'};% WARNING: fits with nb_builtin_ACTION=4 in ActionName_callback
136NbBuiltinAction=numel(ActionList);
137set(handles.Action,'UserData',NbBuiltinAction)
138[path_series,name,ext]=fileparts(which('series'));% path to the GUI series
139path_series_fct=fullfile(path_series,'series');%path of the functions in subdirectroy 'series'
[872]140[code, message] = system...
[942]141    ('LD_LIBRARY_PATH=$(echo $LD_LIBRARY_PATH | pyp "p.split('':'') |... [s for s in p if ''matlab'' not in s] | '':''.join(p)") python -c "import fluidimage"');
[872]142if code==0
143    ActionExtList={'.m';'.sh';'.py (in dev.)'};% default choice of extensions (Matlab fct .m or compiled version .sh
144else
[880]145    ActionExtList={'.m';'.sh'};  % python options not installed
[872]146end
[867]147ActionPathList=cell(NbBuiltinAction,1);%initiate the cell matrix of Action fct paths
148ActionPathList(:)={path_series_fct}; %set the default path to series fcts to all list members
149RunModeList={'local';'background'};% default choice of extensions (Matlab fct .m or compiled version .sh)
150[s,w]=system('oarstat');% look for cluster system 'oar'
151if isequal(s,0)
152    RunModeList=[RunModeList;{'cluster_oar'}];
[880]153    set(handles.MonitorCluster,'Visible','on'); % make visible button for access to Monika
[914]154    set(handles.num_CPUTime,'Visible','on'); % make visible button for access to Monika
155    set(handles.CPUTime_txt,'Visible','on'); % make visible button for access to Monika
[867]156end
[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
[975]1585            answer=inputdlg({'Number of cores (max 36)','extra oar options'},'oarsub parameter',1,{'16',''});
[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
[979]1824                        system([ActionFullName ' ' RunTime ' ' filexml{iprocess}]);% TODO: adapt to DOS system
[867]1825                    case {'GLNX86','GLNXA64','MACI64'}%Linux  system
[979]1826                        system([ActionFullName ' ' RunTime ' ' filexml{iprocess}]);
[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'}
[983]1894                        matlab_ver = ver('MATLAB');
1895                        matlab_version = matlab_ver.Version;
[867]1896                        cmd=[...
1897                            '#!/bin/bash \n'...
[973]1898                            'source /etc/profile \n'...
[983]1899                            'module load matlab/''' matlab_version ''' \n'...% CHOICE OF MATLAB VERSION
[918]1900                            'matlab -nodisplay -nosplash -nojvm -logfile ''' filelog_global ''' <<END_MATLAB \n'...
[867]1901                            'addpath(''' path_series '''); \n'...
[917]1902                            'addpath(''' Param.Action.ActionPath '''); \n'];
1903                        for iprocess=1:NbProcess
1904                            cmd=[cmd '' Param.Action.ActionName  '( ''' filexml{iprocess} '''); \n'];
1905                        end
1906                        cmd=[cmd  'exit \n' 'END_MATLAB \n'];
[867]1907                        fprintf(fid,cmd);%fill the executable file with the  char string cmd
1908                        fclose(fid);% close the executable file
[918]1909                        system(['chmod +x ' file_exe_global]);% set the file to executable
[867]1910                    case {'PCWIN','PCWIN64'}
[917]1911                        cmd=['matlab -automation -logfile ' regexprep(filelog{iprocess},'\\','\\\\')...
[867]1912                            ' -r "addpath(''' regexprep(path_series,'\\','\\\\') ''');'...
[917]1913                            'addpath(''' regexprep(Param.Action.ActionPath,'\\','\\\\') ''');'];
1914                        for iprocess=1:NbProcess
[918]1915                            cmd=[cmd '' Param.Action.ActionName  '( ''' regexprep(filexml{iprocess},'\\','\\\\') ''');']
[917]1916                        end
1917                        cmd=[cmd ';exit"'];
1918                        fprintf(fid,cmd);%fill the executable file with the  char string cmd
[867]1919                        fclose(fid);% close the executable file
1920                end
[918]1921                system([file_exe_global ' &'])% directly execute the command file
[867]1922            case '.sh' % compiled Matlab function
[918]1923                for iprocess=1:NbProcess
1924                    switch computer
1925                        case {'GLNX86','GLNXA64','MACI64'}
1926                            [fid,message]=fopen(batch_file_list{iprocess},'w');% create the executable file
1927                            if isequal(fid,-1)
1928                                errormsg=['creation of .bat file: ' message];
1929                                return
1930                            end
1931                            cmd=['#!/bin/bash \n '...
1932                                '#$ -cwd \n '...
1933                                'hostname && date \n '...
1934                                'umask 002 \n'...
[934]1935                                ActionFullName ' ' RunTime ' ' filexml{iprocess}];%allow writting access to created files for user group
[918]1936                            fprintf(fid,cmd);%fill the executable file with the  char string cmd
1937                            fclose(fid);% close the executable file
1938                            system(['chmod +x ' batch_file_list{iprocess}]);% set the file to executable
1939                            system([batch_file_list{iprocess} ' &'])% directly execute the command file
1940                        case {'PCWIN','PCWIN64'}
1941                            msgbox_uvmat('ERROR','option for compiled Matlab functions not implemented for Windows system')
1942                            return
1943                    end
[867]1944                end
[922]1945                msgbox_uvmat('CONFIRMATION',[ActionFullName ' launched in background: press STATUS to see results'])
[867]1946        end
[918]1947       
1948    case 'cluster_oar' % option 'oar-parexec' used
1949        %create subdirectory for oar commands
[932]1950        for iprocess=1:NbProcess
[918]1951            [fid,message]=fopen(batch_file_list{iprocess},'w');% create the executable file
1952            if isequal(fid,-1)
1953                errormsg=['creation of .bat file: ' message];
1954                return
1955            end
1956            if  strcmp(ActionExt,'.sh')
[932]1957                cmd=['#!/bin/bash \n '...
1958                    '#$ -cwd \n '...
1959                    'hostname && date \n '...
1960                    'umask 002 \n'...
1961                    ActionFullName ' ' RunTime ' ' filexml{iprocess}];%allow writting access to created files for user group
[918]1962            else
[973]1963                matlab_ver = ver('MATLAB');
1964                matlab_version = matlab_ver.Version;
[918]1965                cmd=[...
[932]1966                    '#!/bin/bash \n'...
[973]1967                    'source /etc/profile \n'...
1968                    'module load matlab/''' matlab_version ''' \n'...% CHOICE OF MATLAB VERSION
1969                    'matlab -nodisplay -nosplash -nojvm -singleCompThread -logfile ''' filelog{iprocess} ''' <<END_MATLAB \n'...
[932]1970                    'addpath(''' path_series '''); \n'...
1971                    'addpath(''' Param.Action.ActionPath '''); \n'...
1972                    '' Param.Action.ActionName  '( ''' filexml{iprocess} '''); \n'...
1973                    'exit \n'...
1974                    'END_MATLAB \n'];
[918]1975            end
1976            fprintf(fid,cmd);%fill the executable file with the  char string cmd
1977            fclose(fid);% close the executable file
1978            system(['chmod +x ' batch_file_list{iprocess}]);% set the file to executable
1979        end
1980        DirOAR=fullfile(OutputDir,'0_OAR');
1981        if exist(DirOAR,'dir')% delete the content of the dir 0_LOG to allow new input
1982            curdir=pwd;
1983            cd(DirOAR)
1984            delete('*')
1985            cd(curdir)
1986        else
1987            [tild,msg1]=mkdir(DirOAR);
1988            if ~strcmp(msg1,'')
1989                errormsg=['cannot create ' DirOAR ': ' msg1];%error message for directory creation
1990                return
1991            end
1992        end
1993        % create file containing the list of jobs
[932]1994        filename_joblist=fullfile(DirOAR,'job_list.txt');% name of the file containing the list of executables
[918]1995        fid=fopen(filename_joblist,'w');%open it for writting
1996        for iprocess=1:length(batch_file_list)
1997            fprintf(fid,[batch_file_list{iprocess} '\n']);% write list of exe files
1998        end
1999        fclose(fid);
2000        system(['chmod +x ' filename_joblist]);% set the file to executable
2001       
2002        filename_log=fullfile(DirLog,'job_list.stdout');%file for output messages of the master oar process
2003        filename_errors=fullfile(DirLog,'job_list.stderr');%file for error messages of the master oar process
2004        % the command job_list.txt contains the list of NbProcess independent individual jobs
2005        % in which the total calculation has been split. Those are written as executable files .sh in the folder /O_EXE.
2006        %  These individual jobs are grouped by the system as oar jobs on the NbCore processors.
2007        %  For each processor, the oar job must stop after the walltime which has been set, which is limited to 24 h.
2008        %  However, the oar job is automatically restarted (option 'idempotent') provided the individual jobs are
2009        % shorter than the wall time: in the time interval 'checkpoint' (WallTimeOneJob) before the end of the allowed duration,
2010        %  the oar job restarts when an individual job ends.
2011        JobTime=CPUTime*BlockLength*nbfield_j;% estimated time for one individual job (in minutes)
2012        % wall time (in hours ) for each oar job, allowing 10 individual jobs, but limited to 23 h:
2013        WallTimeTotal=min(23,4*JobTime/60);
2014        %disp(['WallTimeTotal: ' num2str(WallTimeTotal) ' hours'])
2015        % estimated time of an individual job (in min), with a margin of error
2016        WallTimeOneJob=min(4*JobTime+10,WallTimeTotal*60/2);% estimated max time of an individual job for checkpoint
2017        disp(['WallTimeOneJob: ' num2str(WallTimeOneJob) ' minutes'])
[922]2018        oar_command=['oarsub -n UVmat_' ActionFullName ' '...
[918]2019            '-t idempotent --checkpoint ' num2str(WallTimeOneJob*60) ' '...
2020            '-l /core=' num2str(NbCore) ','...
2021            'walltime=' datestr(WallTimeTotal/24,13) ' '...
2022            '-E ' filename_errors ' '...
2023            '-O ' filename_log ' '...
2024            extra_oar ' '...
[932]2025            '"oar-parexec -s -f ' filename_joblist ' '...
[918]2026            '-l ' filename_joblist '.log"'];
[922]2027       
[918]2028        fprintf(oar_command);% display  system command on the Matlab command window
2029        [status,result]=system(oar_command)% execute system command and show the result (ID number of the launched job) on the Matlab command window
2030        filename_oarcommand=fullfile(DirOAR,'0_oar_command');% keep track of the command in file '0-OAR/0_oar_command'
2031        fid=fopen(filename_oarcommand,'w');
2032        fprintf(fid,oar_command); % store the command
2033        fprintf(fid,result);% store the result (job ID number)
2034        fclose(fid);
[922]2035        msgbox_uvmat('CONFIRMATION',[ActionFullName ' launched as  ' num2str(NbProcess) ' processes in cluster: press STATUS to see results'])
[918]2036       
2037    case 'cluster_pbs' % for LMFA Kepler machine
2038        %create subdirectory for pbs command and log files
2039        DirPBS=fullfile(OutputDir,'0_PBS'); %todo : common name OAR/PBS
2040        if exist(DirPBS,'dir')% delete the content of the dir 0_LOG to allow new input
2041            curdir=pwd;
2042            cd(DirPBS)
2043            delete('*')
2044            cd(curdir)
2045        else
2046            [tild,msg1]=mkdir(DirPBS);
2047            if ~strcmp(msg1,'')
2048                errormsg=['cannot create ' DirPBS ': ' msg1];%error message for directory creation
2049                return
2050            end
2051        end
2052        max_walltime=3600*20; % 20h max total calculation (cannot exceed 24 h)
2053        walltime_onejob=1800; % seconds, max estimated time for asingle file index value
2054        filename_joblist=fullfile(DirPBS,'job_list.txt');%create name of the global executable file
2055        fid=fopen(filename_joblist,'w');
2056        for iprocess=1:length(batch_file_list)
2057            fprintf(fid,[batch_file_list{iprocess} '\n']);% list of exe files
2058        end
2059        fclose(fid);
2060        system(['chmod +x ' filename_joblist]);% set the file to executable
2061        pbs_command=['qstat -n CIVX '...
2062            '-t idempotent --checkpoint ' num2str(walltime_onejob+60) ' '...
2063            '-l /core=' num2str(NbCore) ','...
2064            'walltime=' datestr(min(1.05*walltime_onejob/86400*max(NbProcess*BlockLength*nbfield_j,NbCore)/NbCore,max_walltime/86400),13) ' '...
2065            '-E ' regexprep(filename_joblist,'\.txt\>','.stderr') ' '...
2066            '-O ' regexprep(filename_joblist,'\.txt\>','.log') ' '...
2067            extra_oar ' '...
2068            '"oar-parexec -s -f ' filename_joblist ' '...
2069            '-l ' filename_joblist '.log"'];
2070        filename_oarcommand=fullfile(DirPBS,'pbs_command');
2071        fid=fopen(filename_oarcommand,'w');
2072        fprintf(fid,pbs_command);
2073        fclose(fid);
2074        fprintf(pbs_command);% display in command line
2075        %system(pbs_command);
[922]2076        msgbox_uvmat('CONFIRMATION',[ActionFullName ' command ready to be launched in cluster'])
[918]2077    case 'python'
2078        command = [
2079            'LD_LIBRARY_PATH=$(echo $LD_LIBRARY_PATH | pyp "p.split('':'') | [s for s in p if ''matlab'' not in s] | '':''.join(p)") ' ...
[942]2080            'python -m fluidimage.run_from_xml ' filexml{iprocess}];
[918]2081        % fprintf(['command:\n' command '\n\n'])
2082        system(command, '-echo');
[867]2083end
[932]2084if exist(OutputDir,'dir')
[935]2085    [SUCCESS,MESSAGE,MESSAGEID] = fileattrib (OutputDir)
2086    if MESSAGE.GroupWrite~=1
[932]2087    [success,msg] = fileattrib(OutputDir,'+w','g','s');% allow writing access for the group of users, recursively in the folder
2088    if success==0
[935]2089        msgbox_uvmat('WARNING',{['unable to set group write access to ' OutputDir ':']; msg});%error message for directory creation
[932]2090    end
[935]2091    end
[932]2092end
[934]2093
[867]2094%------------------------------------------------------------------------
2095function STOP_Callback(hObject, eventdata, handles)
2096%------------------------------------------------------------------------
2097set(handles.RUN, 'BusyAction','cancel')
2098set(handles.RUN,'BackgroundColor',[1 0 0])
2099set(handles.RUN,'enable','on')
2100set(handles.RUN, 'Value',0)
2101
2102%------------------------------------------------------------------------
2103% --- read parameters from the GUI series
2104%------------------------------------------------------------------------
2105function Param=read_GUI_series(handles)
2106
2107%% read raw parameters from the GUI series
2108Param=read_GUI(handles.series);
2109
2110%% clean the output structure by removing unused information
2111if isfield(Param,'Pairs')
2112    Param=rmfield(Param,'Pairs'); %info Pairs not needed for output
2113end
2114if isfield(Param,'InputLine')
2115    Param=rmfield(Param,'InputLine');
2116end
2117if isfield(Param,'EditObject')
2118    Param=rmfield(Param,'EditObject');
2119end
2120Param.IndexRange.TimeSource=Param.IndexRange.TimeTable{end,1};
2121Param.IndexRange=rmfield(Param.IndexRange,'TimeTable');
2122empty_line=false(size(Param.InputTable,1),1);
2123for iline=1:size(Param.InputTable,1)
2124    empty_line(iline)=isempty(cell2mat(Param.InputTable(iline,1:3)));
2125end
2126Param.InputTable(empty_line,:)=[];
2127
2128%------------------------------------------------------------------------
2129% --- Executes on selection change in ActionName.
2130function ActionName_Callback(hObject, eventdata, handles)
2131%------------------------------------------------------------------------
2132
2133%% stop any ongoing series processing
2134if isequal(get(handles.RUN,'Value'),1)
2135    answer= msgbox_uvmat('INPUT_Y-N','stop current Action process?');
2136    if strcmp(answer,'Yes')
2137        STOP_Callback(hObject, eventdata, handles)
2138    else
2139        return
2140    end
2141end
2142set(handles.ActionName,'BackgroundColor',[1 1 0])
2143huigetfile=findobj(allchild(0),'tag','status_display');
2144if ~isempty(huigetfile)
2145    delete(huigetfile)
2146end
2147drawnow
2148
2149%% get Action name and path
2150NbBuiltinAction=get(handles.Action,'UserData'); %nbre of functions initially proposed in the menu ActionName (as defined in the Opening fct of series)
2151ActionList=get(handles.ActionName,'String');% list menu fields
2152ActionIndex=get(handles.ActionName,'Value');
2153if ~isequal(ActionIndex,1)% if we are not just opening series
2154    InputTable=get(handles.InputTable,'Data');
2155    if isempty(InputTable{1,4})
2156        msgbox_uvmat('ERROR','no input file available: use Open in the menu bar')
2157        return
2158    end
2159end
2160ActionName= ActionList{get(handles.ActionName,'Value')}; % selected function name
2161ActionPathList=get(handles.ActionName,'UserData');%list of recorded paths to functions of the list ActionName
2162
2163%% add a new function to the menu if 'more...' has been selected in the menu ActionName
2164if isequal(ActionName,'more...')
2165    [FileName, PathName] = uigetfile( ...
2166        {'*.m', ' (*.m)';
2167        '*.m',  '.m files '; ...
2168        '*.*', 'All Files (*.*)'}, ...
2169        'Pick a series processing function ',get(handles.ActionPath,'String'));
2170    if length(FileName)<2
2171        return
2172    end
2173    [tild,ActionName,ActionExt]=fileparts(FileName);
2174   
2175    % insert the choice in the menu ActionName
2176    ActionIndex=find(strcmp(ActionName,ActionList),1);% look for the selected function in the menu Action
2177    PathName=regexprep(PathName,'/$','');
2178    if ~isempty(ActionIndex) && ~strcmp(ActionPathList{ActionIndex},PathName)%compare the path to the existing fct
2179        ActionIndex=[]; % the selected path is different than the recorded one
2180    end
2181    if isempty(ActionIndex)%the qselected fct (with selected path) does not exist in the menu
2182        ActionIndex= length(ActionList);
2183        ActionList=[ActionList(1:end-1);{ActionName};ActionList(end)];% the selected function is appended in the menu, before the last item 'more...'
2184         ActionPathList=[ActionPathList; PathName];
2185    end
2186   
2187    % record the file extension and extend the path list if it is a new extension
[886]2188    ActionExtList=get(handles.ActionExt,'String');
2189    ActionExtIndex=find(strcmp(ActionExt,ActionExtList), 1);
2190    if isempty(ActionExtIndex)
2191        set(handles.ActionExt,'String',[ActionExtList;{ActionExt}])
2192    end
[867]2193
2194    % remove old Action options in the menu (keeping a menu length <nb_builtin_ACTION+5)
2195    if length(ActionList)>NbBuiltinAction+5; %nb_builtin_ACTION=nbre of functions always remaining in the initial menu
2196        nbremove=length(ActionList)-NbBuiltinAction-5;
2197        ActionList(NbBuiltinAction+1:end-5)=[];
2198        ActionPathList(NbBuiltinAction+1:end-4,:)=[];
2199        ActionIndex=ActionIndex-nbremove;
2200    end
2201   
2202    % record action menu, choice and path
2203    set(handles.ActionName,'Value',ActionIndex)
2204    set(handles.ActionName,'String',ActionList)
2205       set(handles.ActionName,'UserData',ActionPathList);
2206    set(handles.ActionExt,'Value',ActionExtIndex)
2207       
2208    %record the user defined menu additions in personal file profil_perso
2209    dir_perso=prefdir;
2210    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
2211    if NbBuiltinAction+1<=numel(ActionList)-1
2212        ActionListUser=ActionList(NbBuiltinAction+1:numel(ActionList)-1);
2213        ActionPathListUser=ActionPathList(NbBuiltinAction+1:numel(ActionList)-1);
[886]2214        ActionExtListUser={};
2215        if numel(ActionExtList)>2
2216            ActionExtListUser=ActionExtList(3:end);
2217        end
[867]2218        if exist(profil_perso,'file')
2219            save(profil_perso,'ActionListUser','ActionPathListUser','ActionExtListUser','-append')
2220        else
2221            save(profil_perso,'ActionListUser','ActionPathListUser','ActionExtListUser','-V6')
2222        end
2223    end
2224end
2225
2226%% check the current ActionPath to the selected function
2227ActionPath=ActionPathList{ActionIndex};%current recorded path
2228set(handles.ActionPath,'String',ActionPath); %show the path to the senlected function
2229
2230%% reinitialise the waitbar
2231update_waitbar(handles.Waitbar,0)
2232
2233%% create the function handle for Action
[897]2234if ~exist(ActionPath,'dir')
2235    msgbox_uvmat('ERROR',['The prescribed function path ' ActionPath ' does not exist']);
2236    return
[867]2237end
[897]2238current_dir=pwd;%current working dir
2239cd(ActionPath)
2240h_fun=str2func(ActionName);
2241cd(current_dir)
[867]2242
[897]2243%
2244% checkaddpath=0;
2245% path_series=which('series');
2246% %eval(['spath=which(''' ActionName ''');']) %spath = current path of the selected function ACTION
2247% spath=fileparts(which(ActionName)); %spath = current path of the selected function ACTION
2248% if ~exist(ActionPath,'dir')
2249%     msgbox_uvmat('ERROR',['The prescribed function path ' ActionPath ' does not exist']);
2250%     return
2251% end
2252% if ~strcmp(spath,ActionPath)
2253%     if strcmp(pwd,spath)
2254%         msgbox_uvmat('ERROR',[ 'a function called ' ActionName ' on your working space oversets the selected one']);
2255%         return
2256%     else
2257%         addpath(ActionPath)% add the prescribed path if not the current one
2258%         checkaddpath=1;
2259%     end
2260% end
2261% eval(['h_fun=@' ActionName ';'])%create a function handle for ACTION
2262% if checkaddpath && ~isequal(ActionPath,path_series)
2263%     rmpath(ActionPath)% add the prescribed path if not the current one
2264% end
2265
[867]2266%% Activate the Action fct to adapt the configuration of the GUI series and bring specific parameters in SeriesData
2267Param=read_GUI_series(handles);% read the parameters from the GUI series
2268ParamOut=h_fun(Param);%run the selected Action function to get the relevant input
2269
2270%% Put the first line of the selected Action fct as tooltip help
2271try
2272    [fid,errormsg] =fopen([ActionName '.m']);
2273    InputText=textscan(fid,'%s',1,'delimiter','\n');
2274    fclose(fid);
2275    set(handles.ActionName,'ToolTipString',InputText{1}{1})% put the first line of the selected function as tooltip help
2276end
2277
2278
2279%% Visibility of VelType and VelType_1 menus asked by ActionName
2280VelTypeRequest=1;%VelType requested by default
2281VelTypeRequest_1=1;%VelType requested by default
2282if isfield(ParamOut,'VelType')
2283    VelTypeRequest=ismember(ParamOut.VelType,{'on','one','two'});
2284    VelTypeRequest_1=strcmp( ParamOut.VelType,'two');
2285end
2286FieldNameRequest=0;  %hidden by default
2287FieldNameRequest_1=0;  %hidden by default
2288if isfield(ParamOut,'FieldName')
2289    FieldNameRequest=ismember(ParamOut.FieldName,{'on','one','two'});
2290    FieldNameRequest_1=strcmp( ParamOut.FieldName,'two');
2291end
2292
2293%% Detect the types of input files and set menus and default options in 'VelType'
2294SeriesData=get(handles.series,'UserData');% info on the input file series
2295iview_civ=find(strcmp('civx',SeriesData.FileType)|strcmp('civdata',SeriesData.FileType));
2296iview_netcdf=find(strcmp('netcdf',SeriesData.FileType)|strcmp('civx',SeriesData.FileType)|strcmp('civdata',SeriesData.FileType));% all nc files, icluding civ
2297FieldList=get(handles.FieldName,'String');% previous list as default
2298if ~iscell(FieldList),FieldList={FieldList};end
2299FieldList_1=get(handles.FieldName_1,'String');% previous list as default
2300if ~iscell(FieldList_1),FieldList_1={FieldList_1};end
[897]2301%CheckList=0;% indicate whether FieldName has been updated
[867]2302CheckList_1=1;% indicate whether FieldName_1 has been updated
2303handles_coord=[handles.Coord_x handles.Coord_y handles.Coord_z handles.Coord_x_title handles.Coord_y_title handles.Coord_z_title];
[954]2304if VelTypeRequest && numel(iview_civ)>=1
[867]2305    menu=set_veltype_display(SeriesData.FileInfo{iview_civ(1)}.CivStage,SeriesData.FileType{iview_civ(1)});
2306    set(handles.VelType,'Value',1)% set first choice by default
2307    set(handles.VelType,'String',[{'*'};menu])
2308    set(handles.VelType,'Visible','on')
2309    set(handles.VelType_title,'Visible','on')
2310    FieldList=[set_field_list('U','V');{'C'};{'get_field...'}];%standard menu for civx data
[897]2311    %CheckList=1;
[867]2312    set(handles.FieldName,'Value',1); %velocity vector choice by default
[954]2313    if  VelTypeRequest_1 && numel(iview_civ)>=2
[867]2314        menu=set_veltype_display(SeriesData.FileInfo{iview_civ(2)}.CivStage,SeriesData.FileType{iview_civ(2)});
2315        set(handles.VelType_1,'Value',1)% set first choice by default
2316        set(handles.VelType_1,'String',[{'*'};menu])
2317        set(handles.VelType_1,'Visible','on')
2318        set(handles.VelType_title_1,'Visible','on')
2319        FieldList_1=[set_field_list('U','V');{'C'};{'get_field...'}];%standard menu for civx data
2320        CheckList_1=1;
2321        set(handles.FieldName_1,'Value',1); %velocity vector choice by default
2322    else
2323        set(handles.VelType_1,'Visible','off')
2324        set(handles.VelType_title_1,'Visible','off')
2325    end
2326else
2327    set(handles.VelType,'Visible','off')
2328    set(handles.VelType_title,'Visible','off')
[954]2329end
[867]2330
2331%% Detect the types of input files and set menus and default options in 'FieldName'
[940]2332if (FieldNameRequest || VelTypeRequest) && numel(iview_netcdf)>=1
[954]2333    set(handles.InputFields,'Visible','on')% set the frame InputFields visible
[940]2334    if FieldNameRequest && isfield(SeriesData.FileInfo{iview_netcdf(1)},'ListVarName')
2335        set(handles.FieldName,'Visible','on')
[867]2336        ListVarName=SeriesData.FileInfo{iview_netcdf(1)}.ListVarName;
2337        ind_var=get(handles.FieldName,'Value');%indices of previously selected variables
2338        for ilist=1:numel(ind_var)
2339            if isempty(find(strcmp(FieldList{ind_var(ilist)},ListVarName)))
2340                FieldList={};% previous choice not consistent with new input field
2341                set(handles.FieldName,'Value',1)
2342                break
2343            end
2344        end
2345        if ~isempty(FieldList)
2346            if isempty(find(strcmp(get(handles.Coord_x,'String'),ListVarName)))||...
2347                    isempty(find(strcmp(get(handles.Coord_y,'String'),ListVarName)))
2348                FieldList={};
2349                set(handles.Coord_x,'String','')
2350                set(handles.Coord_y,'String','')
2351            end
2352            Coord_z=get(handles.Coord_z,'String');
2353            if ~isempty(Coord_z) && isempty(find(strcmp(Coord_z,ListVarName)))
2354                FieldList={};
2355                set(handles.Coord_z,'String','')
2356            end
2357        end
[954]2358    end
2359   
2360    set(handles_coord,'Visible','on')
2361    FieldList=[FieldList;{'get_field...'}];
2362    if FieldNameRequest_1 && numel(iview_netcdf)>=2
2363        set(handles.FieldName_1,'Visible','on')
2364        if CheckList_1==0        % not civ input made
2365            ListVarName=SeriesData.FileInfo{iview_netcdf(2)}.ListVarName;
2366            ind_var=get(handles.FieldName,'Value');%indices of previously selected variables
2367            for ilist=1:numel(ind_var)
2368                if isempty(find(strcmp(FieldList{ind_var(ilist)},ListVarName)))
2369                    FieldList_1={};% previous choice not consistent with new input field
2370                    set(handles.FieldName_1,'Value',1)
2371                    break
[867]2372                end
2373            end
[954]2374            warn_coord=0;
2375            if isempty(find(strcmp(get(handles.Coord_x,'String'),ListVarName)))||...
2376                    isempty(find(strcmp(get(handles.Coord_y,'String'),ListVarName)))
2377                warn_coord=1;
2378            end
2379            if ~isempty(Coord_z) && isempty(find(strcmp(Coord_z,ListVarName)))
2380                FieldList_1={};
2381                warn_coord=1;
2382            end
2383            if warn_coord
2384                msgbox_uvmat('WARNING','coordiante names do not exist in the second netcdf input file')
2385            end
2386           
2387            set(handles.FieldName_1,'Visible','on')
2388            set(handles.FieldName_1,'Value',1)
2389            set(handles.FieldName_1,'String',FieldList_1)
[867]2390        end
[940]2391    else
[954]2392        set(handles.FieldName_1,'Visible','off')
2393    end
2394    if isempty(FieldList)
[940]2395        set(handles.FieldName,'Visible','off')
[954]2396    else
2397        set(handles.FieldName,'Visible','on')
2398        set(handles.FieldName,'String',FieldList)
[940]2399    end
[867]2400else
2401    set(handles.InputFields,'Visible','off')
2402end
2403
[904]2404%% Introduce visibility of file overwrite option
2405if isfield(ParamOut,'CheckOverwriteVisible')&& strcmp(ParamOut.CheckOverwriteVisible,'on')
2406    set(handles.CheckOverwrite,'Visible','on')
2407else
2408    set(handles.CheckOverwrite,'Visible','off')
2409end
[867]2410
2411%% Check whether alphabetical sorting of input Subdir is allowed by the Action fct  (for multiples series entries)
2412if isfield(ParamOut,'AllowInputSort')&&isequal(ParamOut.AllowInputSort,'on')&& size(Param.InputTable,1)>1
2413    [tild,iview]=sort(InputTable(:,2)); %subdirectories sorted in alphabetical order
2414    set(handles.InputTable,'Data',InputTable(iview,:));
2415    MinIndex_i=get(handles.MinIndex_i,'Data');
2416    MinIndex_j=get(handles.MinIndex_j,'Data');
2417    MaxIndex_i=get(handles.MaxIndex_i,'Data');
2418    MaxIndex_j=get(handles.MaxIndex_j,'Data');
2419    set(handles.MinIndex_i,'Data',MinIndex_i(iview,:));
2420    set(handles.MinIndex_j,'Data',MinIndex_j(iview,:));
2421    set(handles.MaxIndex_i,'Data',MaxIndex_i(iview,:));
2422    set(handles.MaxIndex_j,'Data',MaxIndex_j(iview,:));
2423    TimeTable=get(handles.TimeTable,'Data');
2424    set(handles.TimeTable,'Data',TimeTable(iview,:));
2425    PairString=get(handles.PairString,'Data');
2426    set(handles.PairString,'Data',PairString(iview,:));
2427end
2428
2429%% Impose the whole input file index range if requested
2430if isfield(ParamOut,'WholeIndexRange')&&isequal(ParamOut.WholeIndexRange,'on')
2431    MinIndex_i=get(handles.MinIndex_i,'Data');
2432    MinIndex_j=get(handles.MinIndex_j,'Data');
2433    MaxIndex_i=get(handles.MaxIndex_i,'Data');
2434    MaxIndex_j=get(handles.MaxIndex_j,'Data');
2435    set(handles.num_first_i,'String',num2str(MinIndex_i(1)))% set first as the min index (for the first line)
2436    set(handles.num_last_i,'String',num2str(MaxIndex_i(1)))% set last as the max index (for the first line)
2437    set(handles.num_incr_i,'String','1')
2438    set(handles.num_first_j,'String',num2str(MinIndex_j(1)))% set first as the min index (for the first line)
2439    set(handles.num_last_j,'String',num2str(MaxIndex_j(1)))% set last as the max index (for the first line)
2440    set(handles.num_incr_j,'String','1')
2441else  % check index ranges
2442    first_i=1;last_i=1;first_j=1;last_j=1;
2443    if isfield(Param.IndexRange,'first_i')
2444        first_i=Param.IndexRange.first_i;
2445        last_i=Param.IndexRange.last_i;
2446    end
2447    if isfield(Param.IndexRange,'first_j')
2448        first_j=Param.IndexRange.first_j;
2449        last_j=Param.IndexRange.last_j;
2450    end
2451    if last_i < first_i || last_j < first_j , msgbox_uvmat('ERROR','last field number must be larger than the first one'),...
2452            set(handles.RUN, 'Enable','On'), set(handles.RUN,'BackgroundColor',[1 0 0]),return,end;
2453end
2454
2455%% enable or desable j index visibility
2456status_j='on';%default
2457if isfield(ParamOut,'Desable_j_index')&&isequal(ParamOut.Desable_j_index,'on')
2458    status_j='off';
2459end
2460if isempty(find(~cellfun(@isempty,SeriesData.j1_series), 1)); % case of empty j indices
2461    status_j='off'; % no j index needed
2462elseif strcmp(get(handles.PairString,'Visible'),'on')
2463    check_burst=cellfun(@isempty,regexp(get(handles.PairString,'Data'),'^j'));%=0 for burst case, 1 otherwise
2464    if isempty(find(check_burst, 1))% if all pair string begins by j (burst)
2465        status_j='off'; % no j index needed for bust case
2466    end
2467end
2468enable_j(handles,status_j) % no j index needed
2469
2470
2471%% NbSlice visibility
[897]2472%NbSliceVisible='off';%default
2473if isfield(ParamOut,'NbSlice') && (strcmp(ParamOut.NbSlice,'on')||isnumeric(ParamOut.NbSlice))
2474    set(handles.num_NbSlice,'Visible','on')
2475    set(handles.NbSlice_title,'Visible','on')
[867]2476else
[897]2477    set(handles.num_NbSlice,'Visible','off')
2478    set(handles.NbSlice_title,'Visible','off')
2479    %     set(handles.num_NbProcess,'String',get(handles.num_NbSlice,'String'))% the nbre of processes is imposed as the nbre of slices
2480    % else
2481    %     set(handles.num_NbProcess,'String','')% free nbre of processes
[867]2482end
[897]2483if isnumeric(ParamOut.NbSlice)
2484    set(handles.num_NbSlice,'String',num2str(ParamOut.NbSlice))
2485    set(handles.num_NbSlice,'Enable','off'); % NbSlice set by the activation of the Action function
2486else
2487    set(handles.num_NbSlice,'Enable','on'); % NbSlice can be modified on the GUI series
2488end
2489% set(handles.num_NbSlice,'Visible',NbSliceVisible)
2490% set(handles.NbSlice_title,'Visible',NbSliceVisible)
[867]2491
2492
2493
2494%% Visibility of FieldTransform menu
2495FieldTransformVisible='off';  %hidden by default
2496if isfield(ParamOut,'FieldTransform')
2497    FieldTransformVisible=ParamOut.FieldTransform; 
2498    TransformName_Callback([],[], handles)
2499end
2500set(handles.FieldTransform,'Visible',FieldTransformVisible)
2501if isfield(ParamOut,'TransformPath')
2502    set(handles.ActionExt,'UserData',ParamOut.TransformPath)
2503else
2504    set(handles.ActionExt,'UserData',[])
2505end
2506
2507%% Visibility of projection object
2508ProjObjectVisible='off';  %hidden by default
2509if isfield(ParamOut,'ProjObject')
2510    ProjObjectVisible=ParamOut.ProjObject;
2511end
2512set(handles.CheckObject,'Visible',ProjObjectVisible)
2513if ~get(handles.CheckObject,'Value')
2514    ProjObjectVisible='off';
2515end
2516set(handles.ProjObject,'Visible',ProjObjectVisible)
2517set(handles.DeleteObject,'Visible',ProjObjectVisible)
2518set(handles.ViewObject,'Visible',ProjObjectVisible)
2519set(handles.EditObject,'Visible',ProjObjectVisible)
2520
2521%% Visibility of mask input
2522MaskVisible='off';  %hidden by default
2523if isfield(ParamOut,'Mask')
2524    MaskVisible=ParamOut.Mask;
2525end
2526set(handles.CheckMask,'Visible',MaskVisible);
2527
2528%% definition of the directory containing the output files
2529if  ~(isfield(SeriesData,'ActionName') && strcmp(ActionName,SeriesData.ActionName))
2530    OutputDirExt='.series'; %default
2531    if isfield(ParamOut,'OutputDirExt')&&~isempty(ParamOut.OutputDirExt)
2532        OutputDirExt=ParamOut.OutputDirExt;
2533    end
2534    set(handles.OutputDirExt,'String',OutputDirExt)
2535end
2536OutputDirVisible='off';
2537OutputSubDirMode='auto';%default
2538SubDirOut='';
2539if isfield(ParamOut,'OutputSubDirMode')
2540    OutputSubDirMode=ParamOut.OutputSubDirMode;
2541end
2542switch OutputSubDirMode
2543    case 'auto';%default
2544        OutputDirVisible='on';
2545        SubDir=InputTable(1:end,2); %set of subdirectories
2546        SubDirOut=SubDir{1};
2547        if numel(SubDir)>1
2548            for ilist=2:numel(SubDir)
2549                SubDirOut=[SubDirOut '-' regexprep(SubDir{ilist},'^/','')];
2550            end
2551        end
2552    case 'one'
2553        OutputDirVisible='on';
2554        SubDirOut=InputTable{1,2}; %use the first subdir name (+OutputDirExt) as output  subdirectory
2555    case 'two'
2556        OutputDirVisible='on';   
2557        SubDir=InputTable(1:2,2); %set of subdirectories
2558        SubDirOut=SubDir{1};
2559        if numel(SubDir)>1
2560                SubDirOut=[SubDirOut '-' regexprep(SubDir{2},'^/','')];
2561        end
2562    case 'last'
2563        OutputDirVisible='on';
2564        SubDirOut=InputTable{end,2}; %use the last subdir name (+OutputDirExt) as output  subdirectory
2565end
2566set(handles.OutputSubDir,'String',SubDirOut)
[883]2567set(handles.OutputSubDir,'BackgroundColor',[1 1 1])% set edit box to white color to indicate refreshment
[867]2568set(handles.OutputDirExt,'Visible',OutputDirVisible)
2569set(handles.OutputSubDir,'Visible',OutputDirVisible)
[904]2570%set(handles.CheckOverwrite,'Visible',OutputDirVisible)
[867]2571set(handles.OutputDir_title,'Visible',OutputDirVisible)
2572SeriesData.ActionName=ActionName;%record ActionName for next use
2573
2574
2575%% visibility of the run mode (local or background or cluster)
2576if strcmp(OutputSubDirMode,'none')
2577    RunModeVisible='off';% only local mode available if no output file is produced
2578else
2579    RunModeVisible='on';
2580end
2581set(handles.RunMode,'Visible',RunModeVisible)
2582set(handles.ActionExt,'Visible',RunModeVisible)
2583set(handles.RunMode_title,'Visible',RunModeVisible)
2584set(handles.ActionExt_title,'Visible',RunModeVisible)
2585
2586
2587%% Expected nbre of output files
2588if isfield(ParamOut,'OutputFileMode')
2589    StatusData.OutputFileMode=ParamOut.OutputFileMode;
2590    set(handles.status,'UserData',StatusData)
2591end
2592
2593%% definition of an additional parameter set, determined by an ancillary GUI
2594if isfield(ParamOut,'ActionInput')
2595    set(handles.ActionInput,'Visible','on')
2596    ParamOut.ActionInput.Program=ActionName; % record the program in ActionInput
2597    SeriesData.ActionInput=ParamOut.ActionInput;
2598else
2599    set(handles.ActionInput,'Visible','off')
2600    if isfield(SeriesData,'ActionInput')
2601        SeriesData=rmfield(SeriesData,'ActionInput');
2602    end
2603end
2604set(handles.series,'UserData',SeriesData)
2605set(handles.ActionName,'BackgroundColor',[1 1 1])
2606
2607%------------------------------------------------------------------------
2608% --- Executes on selection change in FieldName.
2609function FieldName_Callback(hObject, eventdata, handles)
2610%------------------------------------------------------------------------
2611field_str=get(handles.FieldName,'String');
2612field_index=get(handles.FieldName,'Value');
2613field=field_str{field_index(1)};
2614if isequal(field,'get_field...')
2615    SeriesData=get(handles.series,'UserData');
2616    % input line for which the field choice is relevant
2617    iview=find(ismember(SeriesData.FileType,{'netcdf','civx','civdata'}));% all nc files, icluding civ
2618    hget_field=findobj(allchild(0),'name','get_field');
2619    if ~isempty(hget_field)
2620        delete(hget_field)%delete opened versions of get_field
2621    end
2622    Param=read_GUI(handles.series);
2623    InputTable=Param.InputTable(iview,:);
2624    % check the existence of the first file in the series
2625    first_j=[];last_j=[];MinIndex_j=1;MaxIndex_j=1;%default setting for index j
2626    if isfield(Param.IndexRange,'first_j');% if index j is used     
2627        first_j=Param.IndexRange.first_j;
2628        last_j=Param.IndexRange.last_j;
2629        MinIndex_j=Param.IndexRange.MinIndex_j(iview);
2630        MaxIndex_j=Param.IndexRange.MaxIndex_j(iview);
2631    end
2632    PairString='';
2633    if isfield(Param.IndexRange,'PairString'); PairString=Param.IndexRange.PairString{iview}; end
2634    [i1,i2,j1,j2] = get_file_index(Param.IndexRange.first_i,first_j,PairString);
2635    LineIndex=iview(1);
2636    if numel(iview)>1     
2637        answer=msgbox_uvmat('INPUT_TXT',['select the line of the input table:' num2str(iview)] ,num2str(iview(1)));
2638        LineIndex=str2num(answer);
2639%         InputLine=str2num(get(handles.InputLine,'String'));
2640%         if ismember(InputLine,iview)
2641%             LineIndex=InputLine;
2642%         end
2643    end
2644    FirstFileName=fullfile_uvmat(InputTable{LineIndex,1},InputTable{LineIndex,2},InputTable{LineIndex,3},...
2645        InputTable{LineIndex,5},InputTable{LineIndex,4},i1,i2,j1,j2);
2646    if exist(FirstFileName,'file')
2647        ParamIn.Title='get_field: pick input variables and coordinates for series processing';
2648        ParamIn.SeriesInput=1;
2649        GetFieldData=get_field(FirstFileName,ParamIn);
2650        FieldList={};
[876]2651        if isfield(GetFieldData,'FieldOption')% if a field has been selected
[867]2652        switch GetFieldData.FieldOption
2653            case 'vectors'
2654                UName=GetFieldData.PanelVectors.vector_x;
2655                VName=GetFieldData.PanelVectors.vector_y;
2656                YName={GetFieldData.Coordinates.Coord_y};
2657                FieldList={['vec(' UName ',' VName ')'];...
2658                    ['norm(' UName ',' VName ')'];...
2659                    UName;VName};
2660            case {'scalar'}
2661                FieldList=GetFieldData.PanelScalar.scalar;
2662                YName={GetFieldData.Coordinates.Coord_y};
2663                if ischar(FieldList)
2664                    FieldList={FieldList};
2665                end
2666            case 'civdata...'
2667                FieldList=[set_field_list('U','V') ;{'C'}];
2668                set(handles.FieldName,'Value',1) % set menu to 'velocity
2669                XName='X';
2670                YName='y';
2671        end
2672        set(handles.FieldName,'Value',1)
2673        set(handles.FieldName,'String',[FieldList; {'get_field...'}]);
2674        if ~strcmp(GetFieldData.FieldOption,'civdata...')
2675           if ~isempty(regexp(FieldList{1},'^vec'))
2676                set(handles.FieldName,'Value',1)
2677           else
2678                set(handles.FieldName,'Value',1:numel(FieldList))%select all input fields by default
2679           end
2680            XName=GetFieldData.Coordinates.Coord_x;
2681            YName=GetFieldData.Coordinates.Coord_y;
2682            TimeNameStr=GetFieldData.Time.SwitchVarIndexTime;
2683            % get the time info                     
2684            TimeTable=get(handles.TimeTable,'Data');
2685            switch TimeNameStr
2686                case 'file index'
2687                    TimeName='';
2688                case 'attribute'
2689                    TimeName=['att:' GetFieldData.Time.TimeName];
2690                    % update the time table
2691                    TimeTable{LineIndex,2}=get_time(Param.IndexRange.MinIndex_i(LineIndex),MinIndex_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % Min time     
2692                    TimeTable{LineIndex,3}=get_time(Param.IndexRange.first_i,first_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % first time             
2693                    TimeTable{LineIndex,4}=get_time(Param.IndexRange.last_i,last_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % last time                     
2694                    TimeTable{LineIndex,5}=get_time(Param.IndexRange.MaxIndex_i(LineIndex),MaxIndex_j,PairString,InputTable,SeriesData.FileInfo{LineIndex},GetFieldData.Time.TimeName);  % Max time
2695                case 'variable'
2696                    set(handles.TimeName,'String',['var:' GetFieldData.Time.TimeName])
2697                    set(handles.NomType,'String','*')
2698                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])% A VERIFIER !!!!!!
2699                    set(handles.FileIndex,'String','')
2700                    ParamIn.TimeVarName=GetFieldData.Time.TimeName;
2701                case 'matrix_index'
2702                    TimeName=['dim:' GetFieldData.Time.TimeName];
2703                    set(handles.NomType,'String','*')
2704                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
2705                    set(handles.FileIndex,'String','')
2706                    ParamIn.TimeDimName=GetFieldData.Time.TimeName;
2707            end
2708            TimeTable{LineIndex,1}=TimeName;
2709            set(handles.TimeTable,'Data',TimeTable);
2710        end
2711        set(handles.Coord_x,'String',XName)
2712        set(handles.Coord_y,'String',YName)
2713        set(handles.Coord_x,'Visible','on')
2714        set(handles.Coord_y,'Visible','on')
[876]2715        end
[867]2716    else
2717        msgbox_uvmat('ERROR',[FirstFileName ' does not exist'])
2718    end
2719end
2720
[972]2721
[867]2722function [TimeValue,DtValue]=get_time(ref_i,ref_j,PairString,InputTable,FileInfo,TimeName,DtName)
2723[i1,i2,j1,j2] = get_file_index(ref_i,ref_j,PairString);
2724FileName=fullfile_uvmat(InputTable{1},InputTable{2},InputTable{3},InputTable{5},InputTable{4},i1,i2,j1,j2);
2725Data=nc2struct(FileName,[]);
2726TimeValue=[];
2727DtValue=[];
2728if isequal(FileInfo.FileType,'civdata')
2729    if ismember(TimeName,{'civ1','filter1'})
[970]2730        if isfield(Data,'Civ1_Time')
[867]2731        TimeValue=Data.Civ1_Time;
[970]2732        end
2733        if isfield(Data,'Civ1_Dt')
[867]2734        DtValue=Data.Civ1_Dt;
[970]2735        end
[867]2736    else
[970]2737        if isfield(Data,'Civ2_Time')
[867]2738        TimeValue=Data.Civ2_Time;
[970]2739        end
2740        if isfield(Data,'Civ2_Dt')
[867]2741        DtValue=Data.Civ2_Dt;
[970]2742        end
[867]2743    end
2744else
2745    if ~isempty(TimeName)&& isfield(Data,TimeName)
2746        TimeValue=Data.(TimeName);
2747    end
2748    if exist('DtName','var') && isfield(Data,DtName)
2749        DtValue=Data.(DtName);
2750    end
2751end
2752
2753%------------------------------------------------------------------------
2754% --- Executes on selection change in FieldName_1.
2755function FieldName_1_Callback(hObject, eventdata, handles)
2756%------------------------------------------------------------------------
2757field_str=get(handles.FieldName_1,'String');
2758field_index=get(handles.FieldName_1,'Value');
2759field=field_str{field_index(1)};
2760if isequal(field,'get_field...')
2761    hget_field=findobj(allchild(0),'name','get_field');
2762    if ~isempty(hget_field)
2763        delete(hget_field)%delete opened versions of get_field
2764    end
2765    Param=read_GUI(handles.series);
2766    Param.InputTable=Param.InputTable(1,:);
2767    % check the existence of the first file in the series
2768    first_j=[];
2769    if isfield(Param.IndexRange,'first_j'); first_j=Param.IndexRange.first_j; end
2770    if isfield(Param.IndexRange,'last_j'); last_j=Param.IndexRange.last_j; end
2771    PairString='';
2772    if isfield(Param.IndexRange,'PairString'); PairString=Param.IndexRange.PairString; end
2773    [i1,i2,j1,j2] = get_file_index(Param.IndexRange.first_i,first_j,PairString);
2774    FirstFileName=fullfile_uvmat(Param.InputTable{1,1},Param.InputTable{1,2},Param.InputTable{1,3},...
2775        Param.InputTable{1,5},Param.InputTable{1,4},i1,i2,j1,j2);
2776    if exist(FirstFileName,'file')
2777        ParamIn.SeriesInput=1;
2778        GetFieldData=get_field(FirstFileName,ParamIn);
2779        FieldList={};
2780        switch GetFieldData.FieldOption
2781            case 'vectors'
2782                UName=GetFieldData.PanelVectors.vector_x;
2783                VName=GetFieldData.PanelVectors.vector_y;
2784                FieldList={['vec(' UName ',' VName ')'];...
2785                    ['norm(' UName ',' VName ')'];...
2786                    UName;VName};
2787            case {'scalar','pick variables'}
2788                FieldList=GetFieldData.PanelScalar.scalar;
2789                if ischar(FieldList)
2790                    FieldList={FieldList};
2791                end
2792            case '1D plot'
2793
2794            case 'civdata...'
2795                FieldList=set_field_list('U','V','C');
2796                set(handles.FieldName,'Value',2) % set menu to 'velocity
2797        end
2798        if ~strcmp(GetFieldData.FieldOption,'civdata...')
2799            TimeNameStr=GetFieldData.Time.SwitchVarIndexTime;
2800            switch TimeNameStr
2801                case 'file index'
2802                    set(handles.TimeName,'String','');
2803                case 'attribute'
2804                    set(handles.TimeName,'String',['att:' GetFieldData.Time.TimeName]);
2805                case 'variable'
2806                    set(handles.TimeName,'String',['var:' GetFieldData.Time.TimeName])
2807                    set(handles.NomType,'String','*')
2808                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])% A VERIFIER !!!!!!
2809                    set(handles.FileIndex,'String','')
2810                    ParamIn.TimeVarName=GetFieldData.Time.TimeName;
2811                case 'matrix_index'
2812                    set(handles.TimeName,'String',['dim:' GetFieldData.Time.TimeName]);
2813                    set(handles.NomType,'String','*')
2814                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
2815                    set(handles.FileIndex,'String','')
2816                    ParamIn.TimeDimName=GetFieldData.Time.TimeName;
2817            end
2818        end
2819        set(handles.FieldName_1,'Value',1)
2820        set(handles.FieldName_1,'String',[FieldList; {'get_field...'}]);
2821    end
2822end   
2823
2824
2825%%%%%%%%%%%%%
2826function [ind_remove]=find_pairs(dirpair,ind_i,last_i)
2827indsel=ind_i;
2828indiff=diff(ind_i); %test index increment to detect multiplets (several pairs with the same index ind_i) and holes in the series
2829indiff=[1 indiff last_i-ind_i(end)+1];%for testing gaps with the imposed bounds
2830if ~isempty(indiff)
2831    indiff2=diff(indiff);
2832    indiffp=[indiff2 1];
2833    indiffm=[1 indiff2];
2834    ind_multi_m=find((indiff==0)&(indiffm<0))-1;%indices of first members of multiplets
2835    ind_multi_p=find((indiff==0)&(indiffp>0));%indices of last members of multiplets
2836    %for each multiplet, select the most recent file
2837    ind_remove=[];
2838    for i=1:length(ind_multi_m)
2839        ind_pairs=ind_multi_m(i):ind_multi_p(i);
2840        for imulti=1:length(ind_pairs)
2841            datepair(imulti)=datenum(dirpair(ind_pairs(imulti)).date);%dates of creation
2842        end
2843        [datenew,indsort2]=sort(datepair); %sort the multiplet by creation date
2844        ind_s=indsort2(1:end-1);%
2845        ind_remove=[ind_remove ind_pairs(ind_s)];%remove these indices, leave the last one
2846    end
2847end
2848
2849%------------------------------------------------------------------------
2850% --- determine the list of index pairstring of processing file
2851function [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)
2852%------------------------------------------------------------------------
2853num_i1=num_i;% set of first image numbers by default
2854num_i2=num_i;
2855num_j1=num_j;
2856num_j2=num_j;
2857num_i_out=num_i;
2858num_j_out=num_j;
2859% if isequal (NomType,'_1-2_1') || isequal (NomType,'_1-2')
2860if isequal(mode,'series(Di)')
2861    num_i1_line=num_i+ind_shift(3);% set of first image numbers
2862    num_i2_line=num_i+ind_shift(4);
2863    % adjust the first and last field number
2864        indsel=find(num_i1_line >= 1);
2865    num_i_out=num_i(indsel);
2866    num_i1_line=num_i1_line(indsel);
2867    num_i2_line=num_i2_line(indsel);
2868    num_j1=meshgrid(num_j,ones(size(num_i1_line)));
2869    num_j2=meshgrid(num_j,ones(size(num_i1_line)));
2870    [xx,num_i1]=meshgrid(num_j,num_i1_line);
2871    [xx,num_i2]=meshgrid(num_j,num_i2_line);
2872elseif isequal (mode,'series(Dj)')||isequal (mode,'bursts')
2873    if isequal(mode,'bursts') %case of bursts (png_old or png_2D)
2874        num_j1=ind_shift(1)*ones(size(num_i));
2875        num_j2=ind_shift(2)*ones(size(num_i));
2876    else
2877        num_j1_col=num_j+ind_shift(1);% set of first image numbers
2878        num_j2_col=num_j+ind_shift(2);
2879        % adjust the first field number
2880        indsel=find((num_j1_col >= 1));   
2881        num_j_out=num_j(indsel);
2882        num_j1_col=num_j1_col(indsel);
2883        num_j2_col=num_j2_col(indsel);
2884        [num_i1,num_j1]=meshgrid(num_i,num_j1_col);
2885        [num_i2,num_j2]=meshgrid(num_i,num_j2_col);
2886    end   
2887end
2888
2889%------------------------------------------------------------------------
2890% --- Executes on button press in CheckObject.
2891function CheckObject_Callback(hObject, eventdata, handles)
2892%------------------------------------------------------------------------
2893hset_object=findobj(allchild(0),'tag','set_object');%find the set_object interface handle
2894if get(handles.CheckObject,'Value')
2895    SeriesData=get(handles.series,'UserData');
2896    if isfield(SeriesData,'ProjObject') && ~isempty(SeriesData.ProjObject)
2897        set(handles.ViewObject,'Value',1)
2898        ViewObject_Callback(hObject, eventdata, handles)
2899    else
2900        if ishandle(hset_object)
2901            uistack(hset_object,'top')% show the GUI set_object if opened
2902        else
2903            %get the object file
2904            InputTable=get(handles.InputTable,'Data');
2905            defaultname=InputTable{1,1};
2906            if isempty(defaultname)
2907                defaultname={''};
2908            end
2909            fileinput=uigetfile_uvmat('pick a xml object file (or use uvmat to create it)',defaultname,'.xml');
2910            if isempty(fileinput)% exit if no object file is selected
2911                set(handles.CheckObject,'Value',0)
2912                return
2913            end
2914            %read the file
2915            data=xml2struct(fileinput);
2916            if ~isfield(data,'Type')
2917                msgbox_uvmat('ERROR',[fileinput ' is not an object xml file'])
2918                set(handles.CheckObject,'Value',0)
2919                return
2920            end
2921            if ~isfield(data,'ProjMode')
2922                data.ProjMode='none';
2923            end
2924            hset_object=set_object(data);% call the set_object interface
2925            set(hset_object,'Name','set_object_series')% name to distinguish from set_object used with uvmat
2926        end
2927        ProjObject=read_GUI(hset_object);
2928        set(handles.ProjObject,'String',ProjObject.Name);%display the object name
2929        SeriesData=get(handles.series,'UserData');
2930        SeriesData.ProjObject=ProjObject;
2931        set(handles.series,'UserData',SeriesData);
2932    end
2933    set(handles.EditObject,'Visible','on');
2934    set(handles.DeleteObject,'Visible','on');
2935    set(handles.ViewObject,'Visible','on');
2936    set(handles.ProjObject,'Visible','on');
2937else
2938    set(handles.EditObject,'Visible','off');
2939    set(handles.DeleteObject,'Visible','off');
2940    set(handles.ViewObject,'Visible','off');
2941    if ~ishandle(hset_object)
2942        set(handles.ViewObject,'Value',0);
2943    end
2944    set(handles.ProjObject,'Visible','off');
2945end
2946
2947%------------------------------------------------------------------------
2948% --- Executes on button press in ViewObject.
2949%------------------------------------------------------------------------
2950function ViewObject_Callback(hObject, eventdata, handles)
2951
2952UserData=get(handles.series,'UserData');
2953hset_object=findobj(allchild(0),'Tag','set_object');
2954if ~isempty(hset_object)
2955    delete(hset_object)% refresh set_object if already opened
2956end
2957hset_object=set_object(UserData.ProjObject);
2958set(hset_object,'Name','view_object_series')
2959
2960
2961%------------------------------------------------------------------------
2962% --- Executes on button press in EditObject.
2963function EditObject_Callback(hObject, eventdata, handles)
2964%------------------------------------------------------------------------
2965if get(handles.EditObject,'Value')
2966    set(handles.ViewObject,'Value',0)
2967        UserData=get(handles.series,'UserData');
2968    hset_object=set_object(UserData.ProjObject);
2969    set(hset_object,'Name','edit_object_series')
2970    set(get(hset_object,'Children'),'Enable','on')
2971else
2972    hset_object=findobj(allchild(0),'Tag','set_object');
2973    if ~isempty(hset_object)
2974        set(get(hset_object,'Children'),'Enable','off')
2975    end
2976end
2977
2978%------------------------------------------------------------------------
2979% --- Executes on button press in DeleteObject.
2980function DeleteObject_Callback(hObject, eventdata, handles)
2981%------------------------------------------------------------------------
2982SeriesData=get(handles.series,'UserData');
2983SeriesData.ProjObject=[];
2984set(handles.series,'UserData',SeriesData)
2985set(handles.ProjObject,'String','')
2986set(handles.ProjObject,'Visible','off')
2987set(handles.CheckObject,'Value',0)
2988set(handles.ViewObject,'Visible','off')
2989set(handles.EditObject,'Visible','off')
2990hset_object=findobj(allchild(0),'name','set_object_series');
2991if ~isempty(hset_object)
2992    delete(hset_object)
2993end
2994set(handles.DeleteObject,'Visible','off')
2995
2996%------------------------------------------------------------------------
2997% --- Executed when CheckMask is activated
2998%------------------------------------------------------------------------
2999function CheckMask_Callback(hObject, eventdata, handles)
3000
3001if get(handles.CheckMask,'Value')
3002    InputTable=get(handles.InputTable,'Data');
3003    nbview=size(InputTable,1);
3004    MaskTable=cell(nbview,1);%default
3005    ListMask=cell(nbview,1);%default
3006    MaskData=get(handles.MaskTable,'Data');
3007    MaskData(size(MaskData,1):nbview,1)=cell(size(MaskData,1):nbview,1);%complement if undefined lines
3008    for iview=1:nbview
3009        ListMask{iview,1}=num2str(iview);
3010        RootPath=InputTable{iview,1};
3011        if ~isempty(RootPath)
3012            if isempty(MaskData{iview})
3013                SubDir=InputTable{iview,2};
3014                MaskPath=fullfile(RootPath,[regexprep(SubDir,'\..*','') '.mask']);%take the root part of SubDir, before the first dot '.'
3015                if exist(MaskPath,'dir')
3016                    ListStruct=dir(MaskPath);%look for a mask file
3017                    ListCells=struct2cell(ListStruct);% transform dir struct to a cell arrray
3018                    check_dir=cell2mat(ListCells(4,:));% =1 for directories, =0 for files
3019                    ListFiles=ListCells(1,:);%list of file and dri names
3020                    ListFiles=ListFiles(~check_dir);%list of file names (excluding dir)
3021                    mdetect=0;
3022                    if ~isempty(ListFiles)
3023                        for ifile=1:numel(ListFiles)
3024                            [tild,tild,MaskFile{ifile},i1_series,i2_series,j1_series,j2_series,MaskNomType,MaskFileType]=find_file_series(MaskPath,ListFiles{ifile},0);
3025                            if strcmp(MaskFileType,'image') && isempty(i2_series) && isempty(j2_series)
3026                                mdetect=1;
3027                                MaskName=ListFiles{ifile};
3028                            end
3029                            if ~strcmp(MaskFile{ifile},MaskFile{1})
3030                                mdetect=0;% cancel detection test in case of multiple masks, use the brower for selection
3031                                break
3032                            end
3033                        end
3034                    end
3035                    if mdetect==1
3036                        MaskName=fullfile(MaskPath,'mask_1.png');
3037                    else
3038                        MaskName=uigetfile_uvmat('select a mask file:',MaskPath,'image');
3039                    end
3040                else
3041                    MaskName=uigetfile_uvmat('select a mask file:',RootPath,'image');
3042                end
3043                MaskTable{iview,1}=MaskName ;
3044                ListMask{iview,1}=num2str(iview);
3045            end
3046        end
3047    end
3048    set(handles.MaskTable,'Data',MaskTable)
3049    set(handles.MaskTable,'Visible','on')
3050    set(handles.MaskBrowse,'Visible','on')
3051    set(handles.ListMask,'Visible','on')
3052    set(handles.ListMask,'String',ListMask)
3053    set(handles.ListMask,'Value',1)
3054else
3055    set(handles.MaskTable,'Visible','off')
3056    set(handles.MaskBrowse,'Visible','off')
3057    set(handles.ListMask,'Visible','off')
3058end
3059
3060%------------------------------------------------------------------------
3061% --- Executes on button press in MaskBrowse.
3062%------------------------------------------------------------------------
3063function MaskBrowse_Callback(hObject, eventdata, handles)
3064
3065InputTable=get(handles.InputTable,'Data');
3066iview=get(handles.ListMask,'Value');
3067RootPath=InputTable{iview,1};
3068MaskName=uigetfile_uvmat('select a mask file:',RootPath,'image');
3069if ~isempty(MaskName)
3070    MaskTable=get(handles.MaskTable,'Data');
3071    MaskTable{iview,1}=MaskName ;
3072    set(handles.MaskTable,'Data',MaskTable)
3073end
3074
3075%------------------------------------------------------------------------
3076% --- Executes when selected cell(s) is changed in MaskTable.
3077%------------------------------------------------------------------------
3078function MaskTable_CellSelectionCallback(hObject, eventdata, handles)
3079
3080if numel(eventdata.Indices)>=1
3081set(handles.ListMask,'Value',eventdata.Indices(1))
3082end
3083
3084%-------------------------------------------------------------------
3085function MenuHelp_Callback(hObject, eventdata, handles)
3086%-------------------------------------------------------------------
3087
3088
3089% path_to_uvmat=which ('uvmat');% check the path of uvmat
3090% pathelp=fileparts(path_to_uvmat);
3091% helpfile=fullfile(pathelp,'uvmat_doc','uvmat_doc.html');
3092% 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')
3093% else
3094%     addpath (fullfile(pathelp,'uvmat_doc'))
3095%     web([helpfile '#series'])
3096% end
3097
3098%-------------------------------------------------------------------
3099% --- Executes on selection change in TransformName.
3100function TransformName_Callback(hObject, eventdata, handles)
3101%----------------------------------------------------------------------
3102TransformList=get(handles.TransformName,'String');
3103TransformIndex=get(handles.TransformName,'Value');
3104TransformName=TransformList{TransformIndex};
3105TransformPathList=get(handles.TransformName,'UserData');
3106nb_builtin_transform=4;
3107if isequal(TransformName,'more...');     
3108    FileName=uigetfile_uvmat('Pick a transform function',get(handles.TransformPath,'String'),'.m');
3109    if isempty(FileName)
3110        return     %browser closed without choice
3111    end
3112    [TransformPath,TransformName,TransformExt]=fileparts(FileName);% removes extension .m
3113    if ~strcmp(TransformExt,'.m')
3114        msgbox_uvmat('ERROR','a Matlab function .m must be introduced');
3115        return
3116    end
3117     % insert the choice in the menu
3118    TransformIndex=find(strcmp(TransformName,TransformList),1);% look for the selected function in the menu Action
3119    if isempty(TransformIndex)%the input string does not exist in the menu
3120        TransformIndex= length(TransformList);
3121        TransformList=[TransformList(1:end-1);{TransformName};TransformList(end)];% the selected function is appended in the menu, before the last item 'more...'
3122        set(handles.TransformName,'String',TransformList)
3123        TransformPathList=[TransformPathList;{TransformPath}];
3124    else% the input function already exist, we update its path (possibly new)
3125        TransformPathList{TransformIndex}=TransformPath;%
3126        set(handles.TransformName,'Value',TransformIndex)
3127    end
3128   % save the new menu in the personal file 'uvmat_perso.mat'
3129   dir_perso=prefdir;%personal Matalb directory
3130   profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
3131   if exist(profil_perso,'file')
3132       for ilist=nb_builtin_transform+1:numel(TransformPathList)
3133           TransformListUser{ilist-nb_builtin_transform}=TransformList{ilist};
3134           TransformPathListUser{ilist-nb_builtin_transform}=TransformPathList{ilist};
3135       end
3136       TransformPathListUser=TransformPathListUser';
3137       TransformListUser=TransformListUser';
3138       save (profil_perso,'TransformPathListUser','TransformListUser','-append'); %store the root name for future opening of uvmat
3139   end
3140end
3141
3142%display the current function path
3143set(handles.TransformPath,'String',TransformPathList{TransformIndex}); %show the path to the senlected function
3144set(handles.TransformName,'UserData',TransformPathList);
3145
[883]3146%% create the function handle of the selected fct
3147if ~isempty(TransformName)
[897]3148    if ~exist(TransformPathList{TransformIndex},'dir')
3149        msgbox_uvmat('ERROR',['The prescribed transform function path ' TransformPathList{TransformIndex} ' does not exist']);
3150        return
3151    end
[883]3152    current_dir=pwd;%current working dir
3153    cd(TransformPathList{TransformIndex})
3154    transform_handle=str2func(TransformName);
3155    cd(current_dir)
3156    Field.Action.RUN=0;% indicate that the transform fct is called only to get input param
3157    DataOut=feval(transform_handle,Field,[]);% execute the transform fct to get the required conditions
3158    if isfield(DataOut,'TransformInput')%  used to add transform parameters at selection of the transform fct
3159        SeriesData=get(handles.series,'UserData');
3160        SeriesData.TransformInput=DataOut.TransformInput;
3161        set(handles.series,'UserData',SeriesData)
3162    end
3163end
3164
[867]3165%------------------------------------------------------------------------
3166% --- fct activated by the upper bar menu ExportConfig
3167%------------------------------------------------------------------------
3168function MenuDisplayConfig_Callback(hObject, eventdata, handles)
3169
3170global Param
3171Param=read_GUI_series(handles);
3172evalin('base','global Param')%make CurData global in the workspace
3173display('current series config :')
3174evalin('base','Param') %display CurData in the workspace
3175commandwindow; %brings the Matlab command window to the front
3176
3177%------------------------------------------------------------------------
3178% --- fct activated by the upper bar menu InportConfig: import
3179%     menu settings from an xml file (stored in /0_XML for each run)
3180%------------------------------------------------------------------------
3181function MenuImportConfig_Callback(hObject, eventdata, handles)
3182
3183%% use a browser to choose the xml file containing the processing config
3184InputTable=get(handles.InputTable,'Data');
3185oldfile=InputTable{1,1};%current path in InputTable
3186if isempty(oldfile)
3187    % use a file name stored in prefdir
3188    dir_perso=prefdir;
3189    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
3190    if exist(profil_perso,'file')
3191        h=load (profil_perso);
3192        if isfield(h,'RootPath') && ischar(h.RootPath)
3193            oldfile=h.RootPath;
3194        end
3195    end
3196end
3197filexml=uigetfile_uvmat('pick a xml parameter file',oldfile,'.xml');% get the xml file containing processing parameters
3198if isempty(filexml), return, end % quit function if an xml file has not been opened
3199
3200%% fill the GUI series with the content of the xml file
3201Param=xml2struct(filexml);% read the input xml file as a Matlab structure
3202
3203% ask to stop current Action if button RUN is in action (another process is already running)
3204if isequal(get(handles.RUN,'Value'),1)
3205    answer= msgbox_uvmat('INPUT_Y-N','stop current Action process?');
3206    if strcmp(answer,'Yes')
3207        STOP_Callback(hObject, eventdata, handles)
3208    else
3209        return
3210    end
3211end
3212Param.Action.RUN=0; %desactivate the input RUN=1
3213
3214fill_GUI(Param,handles.series)% fill the elements of the GUI series with the input parameters
3215SeriesData=get(handles.series,'UserData');
3216if isfield(Param,'InputFields')
3217    ListField=Param.InputFields.FieldName;
3218    if ischar(ListField),ListField={ListField}; end
3219    set(handles.FieldName,'String',[ListField;{'get-field...'}])
3220     set(handles.FieldName,'Value',1:numel(ListField))
3221     set(handles.FieldName,'Visible','on')
3222end       
3223if isfield(Param,'ActionInput')%  introduce  parameters specific to an Action fct, for instance PIV parameters
3224    set(handles.ActionInput,'Visible','on')
3225    set(handles.ActionInput,'Value',0)
3226    Param.ActionInput.ConfigSource=filexml;% record the source of config for future info
3227    SeriesData.ActionInput=Param.ActionInput;
3228end
[883]3229if isfield(Param,'TransformInput')%  introduce  parameters specific to a transform fct
3230    SeriesData.TransformInput=Param.TransformInput;
3231end
[867]3232if isfield(Param,'ProjObject') %introduce projection object if relevant
3233    SeriesData.ProjObject=Param.ProjObject;
3234end
3235set(handles.series,'UserData',SeriesData)
3236if isfield(Param,'CheckObject') && isequal(Param.CheckObject,1)
3237    set(handles.ProjObject,'String',Param.ProjObject.Name)
3238    set(handles.ViewObject,'Visible','on')
3239    set(handles.EditObject,'Visible','on')
3240    set(handles.DeleteObject,'Visible','on')
3241else     
3242    set(handles.ProjObject,'String','')
3243    set(handles.ProjObject,'Visible','off')
3244    set(handles.ViewObject,'Visible','off')
3245    set(handles.EditObject,'Visible','off')
3246    set(handles.DeleteObject,'Visible','off')     
3247end     
3248set(handles.REFRESH,'BackgroundColor',[1 0 1]); %paint REFRESH button in magenta to indicate that it should be activated
3249
3250
3251%------------------------------------------------------------------------
3252% --- Executes when the GUI series is resized.
3253%------------------------------------------------------------------------
3254function series_ResizeFcn(hObject, eventdata, handles)
3255
3256%% input table
3257set(handles.InputTable,'Unit','pixel')
3258Pos=get(handles.InputTable,'Position');
3259set(handles.InputTable,'Unit','normalized')
3260ColumnWidth=round([0.5 0.14 0.14 0.14 0.08]*(Pos(3)-52));
3261ColumnWidth=num2cell(ColumnWidth);
3262set(handles.InputTable,'ColumnWidth',ColumnWidth)
3263
3264%% MinIndex_j and MaxIndex_i
3265unit=get(handles.MinIndex_i,'Unit');
3266set(handles.MinIndex_i,'Unit','pixel')
3267Pos=get(handles.MinIndex_i,'Position');
3268set(handles.MinIndex_i,'Unit',unit)
3269set(handles.MinIndex_i,'ColumnWidth',{Pos(3)-18})
3270set(handles.MaxIndex_i,'ColumnWidth',{Pos(3)-18})
3271set(handles.MinIndex_j,'ColumnWidth',{Pos(3)-18})
3272set(handles.MaxIndex_j,'ColumnWidth',{Pos(3)-18})
3273
3274%% TimeTable
3275set(handles.TimeTable,'Unit','pixel')
3276Pos=get(handles.TimeTable,'Position');
3277set(handles.TimeTable,'Unit','normalized')
3278% ColumnWidth=get(handles.TimeTable,'ColumnWidth');
3279ColumnWidth=num2cell(floor([0.2 0.2 0.2 0.2 0.2]*(Pos(3)-20)));
3280set(handles.TimeTable,'ColumnWidth',ColumnWidth)
3281
3282
3283%% PairString
3284set(handles.PairString,'Unit','pixel')
3285Pos=get(handles.PairString,'Position');
3286set(handles.PairString,'Unit','normalized')
3287set(handles.PairString,'ColumnWidth',{Pos(3)-5})
3288
3289%% MaskTable
3290set(handles.MaskTable,'Unit','pixel')
3291Pos=get(handles.MaskTable,'Position');
3292set(handles.MaskTable,'Unit','normalized')
3293set(handles.MaskTable,'ColumnWidth',{Pos(3)-5})
3294
3295%------------------------------------------------------------------------
3296% --- Executes on button press in status.
3297%------------------------------------------------------------------------
3298function status_Callback(hObject, eventdata, handles)
3299
3300if get(handles.status,'Value')
3301    set(handles.status,'BackgroundColor',[1 1 0])
3302    drawnow
3303    Param=read_GUI(handles.series);
3304    RootPath=Param.InputTable{1,1};
3305    if ~isfield(Param,'OutputSubDir')   
3306        msgbox_uvmat('ERROR','no standard sub-directory definition for output files, use a browser to check the output')
3307        set(handles.status,'BackgroundColor',[0 1 0])
3308        return
3309    end
3310    OutputSubDir=[Param.OutputSubDir Param.OutputDirExt];% subdirectory for output files
3311    OutputDir=fullfile(RootPath,OutputSubDir);
3312    if exist(OutputDir,'dir')
3313        uigetfile_uvmat('status_display',OutputDir)
3314    else
3315        msgbox_uvmat('ERROR','output folder not created yet: calculation did not start')
3316        set(handles.status,'BackgroundColor',[0 1 0])
3317    end
3318else
3319    %% delete current display fig if selection is off
3320    set(handles.status,'BackgroundColor',[0 1 0])
3321    hfig=findobj(allchild(0),'name','status_display');
3322    if ~isempty(hfig)
3323        delete(hfig)
3324    end
3325    return
3326end
3327
3328
3329%------------------------------------------------------------------------   
3330% launched by selecting a file on the list
3331%------------------------------------------------------------------------
3332function view_file(hObject, eventdata)
3333
3334list=get(hObject,'String');
3335index=get(hObject,'Value');
3336rootroot=get(hObject,'UserData');
3337selectname=list{index};
3338ind_dot=regexp(selectname,'\.\.\.');
3339if ~isempty(ind_dot)
3340    selectname=selectname(1:ind_dot-1);
3341end
3342FullSelectName=fullfile(rootroot,selectname);
3343if exist(FullSelectName,'dir')% a directory has been selected
3344    ListFiles=dir(FullSelectName);
3345    ListDisplay=cell(numel(ListFiles),1);
3346    for ilist=2:numel(ListDisplay)% suppress the first line '.'
3347        ListDisplay{ilist-1}=ListFiles(ilist).name;
3348    end
3349    set(hObject,'Value',1)
3350    set(hObject,'String',ListDisplay)
3351    if strcmp(selectname,'..')
3352        FullSelectName=fileparts(fileparts(FullSelectName));
3353    end
3354    set(hObject,'UserData',FullSelectName)
3355    hfig=get(hObject,'parent');
3356    htitlebox=findobj(hfig,'tag','titlebox');   
3357    set(htitlebox,'String',FullSelectName)
3358elseif exist(FullSelectName,'file')%visualise the vel field if it exists
3359    FileInfo=get_file_info(FullSelectName);   
3360    if strcmp(FileInfo.FileType,'txt')
3361        edit(FullSelectName)
3362    elseif strcmp(FileInfo.FileType,'xml')
3363        editxml(FullSelectName)
3364    else
3365        uvmat(FullSelectName)
3366    end
3367    set(gcbo,'Value',1)
3368end
3369
3370
3371%------------------------------------------------------------------------   
3372% launched by refreshing the status figure
3373%------------------------------------------------------------------------
3374function refresh_GUI(hfig)
3375
3376htitlebox=findobj(hfig,'tag','titlebox');
3377hlist=findobj(hfig,'tag','list');
3378hseries=findobj(allchild(0),'tag','series');
3379hstatus=findobj(hseries,'tag','status');
3380StatusData=get(hstatus,'UserData');
3381OutputDir=get(htitlebox,'String');
3382if ischar(OutputDir),OutputDir={OutputDir};end
3383ListFiles=dir(OutputDir{1});
3384if numel(ListFiles)<1
3385    return
3386end
3387ListFiles(1)=[];%removes the first line ='.'
3388ListDisplay=cell(numel(ListFiles),1);
3389testrecent=0;
3390datnum=zeros(numel(ListDisplay),1);
3391for ilist=1:numel(ListDisplay)
3392    ListDisplay{ilist}=ListFiles(ilist).name;
3393      if ~ListFiles(ilist).isdir && isfield(ListFiles(ilist),'datenum')
3394            datnum(ilist)=ListFiles(ilist).datenum;%only available in recent matlab versions
3395            testrecent=1;
3396       end
3397end
3398set(hlist,'String',ListDisplay)
3399
3400%% Look at date of creation
3401ListDisplay=ListDisplay(datnum~=0);
3402datnum=datnum(datnum~=0);%keep the non zero values corresponding to existing files
3403NbOutputFile=[];
3404if isempty(datnum)
3405    if testrecent
3406        message='no civ result created yet';
3407    else
3408        message='';
3409    end
3410else
3411    [first,indfirst]=min(datnum);
3412    [last,indlast]=max(datnum);
3413    NbOutputFile_str='?';
3414    NbOutputFile=[];
3415    if isfield(StatusData,'NbOutputFile')
3416        NbOutputFile=StatusData.NbOutputFile;
3417        NbOutputFile_str=num2str(NbOutputFile);
3418    end
3419    message={[num2str(numel(datnum)) ' file(s) done over ' NbOutputFile_str] ;['oldest modification:  ' ListDisplay{indfirst} ' : ' datestr(first)];...
3420        ['latest modification:  ' ListDisplay{indlast} ' : ' datestr(last)]};
3421end
3422set(htitlebox,'String', [OutputDir{1};message])
3423
3424%% update the waitbar
3425hwaitbar=findobj(hfig,'tag','waitbar');
3426if ~isempty(NbOutputFile)
3427    BarPosition=get(hwaitbar,'Position');
3428    BarPosition(3)=0.9*numel(datnum)/NbOutputFile;
3429    set(hwaitbar,'Position',BarPosition)
3430end
3431
3432%------------------------------------------------------------------------
3433% --- Executes on selection change in ActionExt.
3434%------------------------------------------------------------------------
3435function ActionExt_Callback(hObject, eventdata, handles)
3436
3437ActionExtList=get(handles.ActionExt,'String');
3438ActionExt=ActionExtList{get(handles.ActionExt,'Value')};
3439if strcmp(ActionExt,'.py (in dev.)')
3440    set(handles.RunMode,'Value',2)
3441end
3442
[897]3443%function num_NbProcess_Callback(hObject, eventdata, handles)
[867]3444
3445
3446function num_NbSlice_Callback(hObject, eventdata, handles)
3447NbSlice=str2num(get(handles.num_NbSlice,'String'));
[897]3448%set(handles.num_NbProcess,'String',num2str(NbSlice))
[867]3449
3450%------------------------------------------------------------------------
3451% --- set the visibility of relevant velocity type menus:
3452function menu=set_veltype_display(Civ,FileType)
3453%------------------------------------------------------------------------
3454if ~exist('FileType','var')
3455    FileType='civx';
3456end
3457switch FileType
3458    case 'civx'
3459        menu={'civ1';'interp1';'filter1';'civ2';'interp2';'filter2'};
3460        if isequal(Civ,0)
3461            imax=0;
3462        elseif isequal(Civ,1) || isequal(Civ,2)
3463            imax=1;
3464        elseif isequal(Civ,3)
3465            imax=3;
3466        elseif isequal(Civ,4) || isequal(Civ,5)
3467            imax=4;
3468        elseif isequal(Civ,6) %patch2
3469            imax=6;
3470        end
3471    case 'civdata'
3472        menu={'civ1';'filter1';'civ2';'filter2'};
3473        if isequal(Civ,0)
3474            imax=0;
3475        elseif isequal(Civ,1) || isequal(Civ,2)
3476            imax=1;
3477        elseif isequal(Civ,3)
3478            imax=2;
3479        elseif isequal(Civ,4) || isequal(Civ,5)
3480            imax=3;
[912]3481        else%if isequal(Civ,6) %patch2
[867]3482            imax=4;
3483        end
3484end
3485menu=menu(1:imax);
3486
3487
3488% --- Executes on mouse motion over figure - except title and menu.
3489function series_WindowButtonMotionFcn(hObject, eventdata, handles)
3490set(hObject,'Pointer','arrow');
3491
3492
3493% --- Executes on button press in SetPairs.
[972]3494function SetPairs_Callback(hObject, eventdata, handles)
[867]3495
3496%% delete previous occurrence of 'set_pairs'
3497hfig=findobj(allchild(0),'Tag','set_pairs');
3498if ~isempty(hfig)
3499delete(hfig)
3500end
3501
3502%% create the GUI set_pairs
3503set(0,'Unit','points')
3504ScreenSize=get(0,'ScreenSize');% get the size of the screen, to put the fig on the upper right
3505Width=220;% fig width in points (1/72 inch)
3506Height=min(0.8*ScreenSize(4),300);
3507Left=ScreenSize(3)- Width-40; %right edge close to the right, with margin=40
3508Bottom=ScreenSize(4)-Height-40; %put fig at top right
3509hfig=findobj(allchild(0),'Tag','set_slice');
3510if ~isempty(hfig),delete(hfig), end; %delete existing version of the GUI
3511hfig=figure('name','set_pairs','tag','set_pairs','MenuBar','none','NumberTitle','off','Unit','points','Position',[Left,Bottom,Width,Height]);
3512BackgroundColor=get(hfig,'Color');
3513SeriesData=get(handles.series,'UserData');
3514TimeUnit=get(handles.TimeUnit,'String');
3515PairString=get(handles.PairString,'Data');
3516ListViewLines=find(cellfun('isempty',PairString)==0);%find list of non empty pairs
3517ListViewMenu=cell(numel(ListViewLines),1);
[972]3518iview=get(handles.PairString,'Value');
[867]3519for ilist=1:numel(ListViewLines)
3520    ListViewMenu{ilist}=num2str(ListViewLines(ilist));
3521end
3522if isempty(iview)
3523    ListViewValue=numel(ListViewLines);% we work by default on the pair option for the last line which requires pairs
3524    iview=ListViewLines(end);
3525else
3526    ListViewValue=find(ListViewLines==iview);
3527end
3528ref_i=str2num(get(handles.num_first_i,'String'));
3529ref_j=1;%default
3530if strcmp(get(handles.num_first_j,'String'),'Visible')
3531    ref_j=str2num(get(handles.num_first_j,'String'));
3532end
3533[ModeMenu,ModeValue]=update_mode(SeriesData.i1_series{iview},SeriesData.i2_series{iview},SeriesData.j2_series{iview});
3534displ_pair=update_listpair(SeriesData.i1_series{iview},SeriesData.i2_series{iview},SeriesData.j1_series{iview},SeriesData.j2_series{iview},ModeMenu{ModeValue},...
3535                                                     SeriesData.Time{iview},TimeUnit,ref_i,ref_j,SeriesData.FileInfo{iview});
3536% first raw of the GUI
3537uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.88 0.5 0.1],'BackgroundColor',BackgroundColor,...
3538    'String','row to edit #','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','right');%title
3539uicontrol('Style','popupmenu','Units','normalized', 'Position', [0.54 0.8 0.3 0.2],'BackgroundColor',[1 1 1],...
3540    'Callback',@(hObject,eventdata)ListView_Callback(hObject,eventdata),'String',ListViewMenu,'Value',ListViewValue,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3541    'Tag','ListView','TooltipString','''ListView'':choice of the file series w for pair display');
3542% second raw of the GUI
3543uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.79 0.7 0.1],'BackgroundColor',BackgroundColor,...
3544    'String','mode of index pairing:','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','left');%title
3545uicontrol('Style','popupmenu','Units','normalized', 'Position', [0.05 0.62 0.9 0.2],'BackgroundColor',[1 1 1],...
3546    'Callback',@(hObject,eventdata)Mode_Callback(hObject,eventdata),'String',ModeMenu,'Value',ModeValue,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3547    'Tag','Mode','TooltipString','''Mode'': choice of the image pair mode');
3548% third raw
3549uicontrol('Style','text','Units','normalized', 'Position', [0.05 0.6 0.7 0.1],'BackgroundColor',BackgroundColor,...
3550    'String','pair choice:','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','left');%title
3551uicontrol('Style','listbox','Units','normalized', 'Position', [0.05 0.42 0.9 0.2],'BackgroundColor',[1 1 1],...
3552    'Callback',@(hObject,eventdata)ListPair_Callback(hObject,eventdata),'String',displ_pair,'Value',1,'FontUnits','points','FontSize',12,'FontWeight','bold',...
3553    'Tag','ListPair','TooltipString','''ListPair'': menu for selecting the image pair');
3554uicontrol('Style','text','Units','normalized', 'Position', [0.1 0.22 0.8 0.1],'BackgroundColor',BackgroundColor,...
3555    'String','ref_i           ref_j','FontUnits','points','FontSize',12,'FontWeight','bold','ForegroundColor','blue','HorizontalAlignment','center');%title
3556uicontrol('Style','edit','Units','normalized', 'Position', [0.15 0.17 0.3 0.08],'BackgroundColor',[1 1 1],...
3557    'Callback',@(hObject,eventdata)num_ref_i_Callback(hObject,eventdata),'String',num2str(ref_i),'FontUnits','points','FontSize',12,'FontWeight','bold',...
3558    'Tag','num_ref_i','TooltipString','''num_ref_i'': reference field index i used to display dt in ''list_pair_civ''');
3559uicontrol('Style','edit','Units','normalized', 'Position', [0.55 0.17 0.3 0.08],'BackgroundColor',[1 1 1],...
3560    'Callback',@(hObject,eventdata)num_ref_j_Callback(hObject,eventdata),'String',num2str(ref_j),'FontUnits','points','FontSize',12,'FontWeight','bold',...
3561    'Tag','num_ref_j','TooltipString','''num_ref_j'': reference field index i used to display dt in ''list_pair_civ''');
[880]3562uicontrol('Style','pushbutton','Units','normalized', 'Position', [0.01 0.01 0.3 0.12],'BackgroundColor',[0 1 0],...
3563    'Callback',@(hObject,eventdata)OK_Callback(hObject,eventdata),'String','OK','FontUnits','points','FontSize',12,'FontWeight','bold',...
3564    'Tag','OK','TooltipString','''OK'': validate the choice');
[867]3565%  last raw  of the GUI: pushbuttons
3566% 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),...
3567%     'FontWeight','bold','FontUnits','points','FontSize',12,'TooltipString','''OK'': apply the output to the current field series in uvmat');
3568drawnow
3569
3570%------------------------------------------------------------------------
3571function ListView_Callback(hObject,eventdata)
3572Mode_Callback(hObject,eventdata)
3573
3574%------------------------------------------------------------------------   
3575function Mode_Callback(hObject,eventdata)
3576%% get input info
3577hseries=findobj(allchild(0),'tag','series');%handles of the GUI series
3578hhseries=guidata(hseries);%handles of the elements in the GUI series
3579TimeUnit=get(hhseries.TimeUnit,'String');
3580SeriesData=get(hseries,'UserData');
3581mode_list=get(hObject,'String');
3582mode=mode_list{get(hObject,'Value')};
3583hListView=findobj(get(hObject,'parent'),'Tag','ListView');
3584iview=get(hListView,'Value');
3585i1_series=SeriesData.i1_series{iview};
3586i2_series=SeriesData.i2_series{iview};
3587j1_series=SeriesData.j1_series{iview};
3588j2_series=SeriesData.j2_series{iview};
3589
3590%% enable j index visibility after the new choice
3591status_j='on';%default
3592if isempty(find(~cellfun(@isempty,SeriesData.j1_series), 1)); % case of empty j indices
3593    status_j='off'; % no j index needed
3594elseif strcmp(get(handles.PairString,'Visible'),'on')
3595    check_burst=cellfun(@isempty,regexp(PairString,'^j'));%=0 for burst case, 1 otherwise
3596    if isempty(find(check_burst, 1))% if all pair string begins by j (burst)
3597        status_j='off'; % no j index needed for bust case
3598    end
3599end
3600enable_j(handles,status_j) % no j index needed
3601
3602%% get the reference indices for the time interval Dt
3603href_i=findobj(get(hObject,'parent'),'Tag','ref_i');
3604ref_i=[];ref_j=[];
3605if strcmp(get(href_i,'Visible'),'on')
3606    ref_i=str2num(get(href_i,'String'));
3607end
3608if isempty(ref_i)
3609    ref_i=1;
3610end
3611if isempty(ref_j)
3612    ref_j=1;
3613end
3614
3615%% update the menu ListPair
3616Menu=update_listpair(i1_series,i2_series,j1_series,j2_series,mode,SeriesData.Time{iview},TimeUnit,ref_i,ref_j,FileInfo);
3617hlist_pairs=findobj(get(hObject,'parent'),'Tag','ListPair');
3618set(hlist_pairs,'Value',1)% set the first choice by default in ListPair
3619set(hlist_pairs,'String',Menu)% set the menu in ListPair
3620ListPair_Callback(hlist_pairs,[])% apply the default choice in ListPair
3621
3622%-------------------------------------------------------------
3623% --- Executes on selection in ListPair.
3624function ListPair_Callback(hObject,eventdata)
3625%------------------------------------------------------------
3626list_pair=get(hObject,'String');%get the menu of image pairs
3627if isempty(list_pair)
3628    string='';
3629else
3630    string=list_pair{get(hObject,'Value')};
3631   % string=regexprep(string,',.*','');%removes time indication (after ',')
3632end
3633hseries=findobj(allchild(0),'tag','series');
3634hPairString=findobj(hseries,'tag','PairString');
3635PairString=get(hPairString,'Data');
3636hListView=findobj(get(hObject,'parent'),'Tag','ListView');
3637iview=get(hListView,'Value');
3638PairString{iview,1}=string;
3639% report the selected pair string to the table PairString
3640set(hPairString,'Data',PairString)
3641
3642
3643%------------------------------------------------------------------------
3644function num_ref_i_Callback(hObject, eventdata)
3645%------------------------------------------------------------------------
3646Mode_Callback([],[])
3647
3648%------------------------------------------------------------------------
3649function num_ref_j_Callback(hObject, eventdata)
3650%------------------------------------------------------------------------
3651Mode_Callback([],[])
3652
3653%------------------------------------------------------------------------
[880]3654function OK_Callback(hObject, eventdata)
3655%------------------------------------------------------------------------
3656delete(get(hObject,'parent'))
3657
3658
3659%------------------------------------------------------------------------
[867]3660% --- Executes on button press in ClearLine.
3661%------------------------------------------------------------------------
3662function ClearLine_Callback(hObject, eventdata, handles)
3663InputTable=get(handles.InputTable,'Data');
3664iline=str2double(get(handles.InputLine,'String'));
3665if size(InputTable,1)>1
3666    InputTable(iline,:)=[];% suppress the current line if not the first
3667    set(handles.InputTable,'Data',InputTable);
3668end
[883]3669set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH button to magenta color to indicate that input refr
[880]3670
3671
3672% --- Executes on button press in MonitorCluster.
3673function MonitorCluster_Callback(hObject, eventdata, handles)
[975]3674web('https://www.legi.grenoble-inp.fr/servfill/monika')
[880]3675
3676function OutputSubDir_Callback(hObject, eventdata, handles)
3677set(handles.OutputSubDir,'BackgroundColor',[1 1 1])
[904]3678
3679
3680% --- Executes on button press in CheckOverwrite.
3681function CheckOverwrite_Callback(hObject, eventdata, handles)
[880]3682
[904]3683
3684
3685% --- Executes on button press in TestCPUTime.
3686function TestCPUTime_Callback(hObject, eventdata, handles)
3687% hObject    handle to TestCPUTime (see GCBO)
3688% eventdata  reserved - to be defined in a future version of MATLAB
3689% handles    structure with handles and user data (see GUIDATA)
3690
3691
3692
3693
3694
Note: See TracBrowser for help on using the repository browser.