source: trunk/src/series.m @ 748

Last change on this file since 748 was 748, checked in by sommeria, 10 years ago

update for 3D plots, panel Coordiantes introduces, while coordiantes now called Axes

File size: 125.0 KB
Line 
1%'series': master function associated to the GUI series.m for analysis field series 
2%------------------------------------------------------------------------
3% function varargout = series(varargin)
4% associated with the GUI series.fig
5%
6%INPUT
7% param: structure with input parameters (link with the GUI uvmat)
8%      .menu_coord_str: string for the TransformName (menu for coordinate transforms)
9%      .menu_coord_val: value for TransformName (menu for coordinate transforms)
10%      .FileName: input file name
11%      .FileName_1: second input file name
12%      .list_field: menu of input fields
13%      .index_fields: chosen index
14%      .civ1=0 or 1, .interp1,  ... : input civ field type
15%
16%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
17%  Copyright Joel Sommeria, 2008, LEGI / CNRS-UJF-INPG, sommeria@coriolis-legi.org.
18%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
19%     This file is part of the toolbox UVMAT.
20%
21%     UVMAT is free software; you can redistribute it and/or modify
22%     it under the terms of the GNU General Public License as published by
23%     the Free Software Foundation; either version 2 of the License, or
24%     (at your option) any later version.
25%
26%     UVMAT is distributed in the hope that it will be useful,
27%     but WITHOUT ANY WARRANTY; without even the implied warranty of
28%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29%     GNU General Public License (file UVMAT/COPYING.txt) for more details.
30%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
31
32%------------------------------------------------------------------------
33%------------------------------------------------------------------------
34%  I - MAIN FUNCTION series
35%------------------------------------------------------------------------
36%------------------------------------------------------------------------
37function varargout = series(varargin)
38
39% Begin initialization code - DO NOT EDIT
40gui_Singleton = 1;
41gui_State = struct('gui_Name',       mfilename, ...
42                   'gui_Singleton',  gui_Singleton, ...
43                   'gui_OpeningFcn', @series_OpeningFcn, ...
44                   'gui_OutputFcn',  @series_OutputFcn, ...
45                   'gui_LayoutFcn',  [] , ...
46                   'gui_Callback',   []);
47if nargin && ischar(varargin{1})
48    gui_State.gui_Callback = str2func(varargin{1});
49end
50
51if nargout
52    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
53else
54    gui_mainfcn(gui_State, varargin{:});
55end
56% End initialization code - DO NOT EDIT
57
58%--------------------------------------------------------------------------
59% --- Executes just before series is made visible.
60%--------------------------------------------------------------------------
61function series_OpeningFcn(hObject, eventdata, handles,Param)
62
63% Choose default command line output for series
64handles.output = hObject;
65% Update handles structure
66guidata(hObject, handles);
67
68%% initial settings
69% position and  size of the GUI at opening
70set(0,'Unit','points')
71ScreenSize=get(0,'ScreenSize');%size of the current screen, in points (1/72 inch)
72Width=900;% prefered width of the GUI in points (1/72 inch)
73Height=624;% prefered height of the GUI in points (1/72 inch)
74%adjust to screen size (reduced by a min margin)
75RescaleFactor=min((ScreenSize(3)-80)/Width,(ScreenSize(4)-80)/Height);
76if RescaleFactor>1
77    RescaleFactor=min(RescaleFactor,1);
78end
79Width=Width*RescaleFactor;
80Height=Height*RescaleFactor;
81LeftX=80*RescaleFactor;%position of the left fig side, in pixels (put to the left side, with some margin)
82LowY=round(ScreenSize(4)/2-Height/2); % put at the middle height on the screen
83set(hObject,'Units','points')
84set(hObject,'Position',[LeftX LowY Width Height])% position and size of the GUI at opening
85
86% settings of table MinIndex_j
87set(handles.MinIndex_i,'ColumnFormat',{'numeric'})
88set(handles.MinIndex_i,'ColumnEditable',false)
89set(handles.MinIndex_i,'ColumnName',{'i min'})
90set(handles.MinIndex_i,'Data',[])% initiate Data to double (not cell)
91
92% settings of table MinIndex_j
93set(handles.MinIndex_j,'ColumnFormat',{'numeric'})
94set(handles.MinIndex_j,'ColumnEditable',false)
95set(handles.MinIndex_j,'ColumnName',{'j min'})
96set(handles.MinIndex_j,'Data',[])% initiate Data to double (not cell)
97
98% settings of table MaxIndex_i
99set(handles.MaxIndex_i,'ColumnFormat',{'numeric'})
100set(handles.MaxIndex_i,'ColumnEditable',false)
101set(handles.MaxIndex_i,'ColumnName',{'i max'})
102set(handles.MaxIndex_i,'Data',[])% initiate Data to double (not cell)
103
104% settings of table MaxIndex_j
105set(handles.MaxIndex_j,'ColumnFormat',{'numeric'})
106set(handles.MaxIndex_j,'ColumnEditable',false)
107set(handles.MaxIndex_j,'ColumnName',{'j max'})
108set(handles.MaxIndex_j,'Data',[])% initiate Data to double (not cell)
109
110% settings of table PairString
111set(handles.PairString,'ColumnName',{'pairs'})
112set(handles.PairString,'ColumnEditable',false)
113set(handles.PairString,'ColumnFormat',{'char'})
114set(handles.PairString,'Data',{''})
115
116% settings of table MaskTable
117set(handles.MaskTable,'ColumnName',{'mask name'})
118set(handles.PairString,'ColumnEditable',false)
119set(handles.PairString,'ColumnFormat',{'char'})
120set(handles.PairString,'Data',{''})
121
122series_ResizeFcn(hObject, eventdata, handles)%resize table according to series GUI size
123set(hObject,'WindowButtonDownFcn',{'mouse_down'})%allows mouse action with right button (zoom for uicontrol display)
124set(handles.InputTable,'KeyPressFcn',{@key_press_fcn,handles})%set keyboard action function (allow action on uvmat when set_object is in front)
125set(hObject,'DeleteFcn',{@closefcn})%
126
127% check default input data
128if ~exist('Param','var')
129    Param=[]; %default
130end
131
132%% list of builtin functions in the mebu ActionName
133ActionList={'check_data_files';'aver_stat';'time_series';'civ_series';'merge_proj'};% WARNING: fits with nb_builtin_ACTION=4 in ActionName_callback
134NbBuiltinAction=numel(ActionList);
135[path_series,name,ext]=fileparts(which('series'));% path to the GUI series
136path_series_fct=fullfile(path_series,'series');%path of the functions in subdirectroy 'series'
137ActionExtList={'.m';'.sh'};% default choice of extensions (Matlab fct .m or compiled version .sh
138ActionPathList=cell(NbBuiltinAction,numel(ActionExtList));%initiate the cell matrix of Action fct paths
139ActionPathList(:)={path_series_fct}; %set the default path to series fcts to all list members
140RunModeList={'local';'background'};% default choice of extensions (Matlab fct .m or compiled version .sh)
141[s,w]=system('oarstat');% look for cluster system 'oar'
142if isequal(s,0)
143    RunModeList=[RunModeList;{'cluster_oar'}];
144end
145[s,w]=system('qstat');% look for cluster system 'sge'
146if isequal(s,0)
147    RunModeList=[RunModeList;{'cluster_sge'}];
148end
149set(handles.RunMode,'String',RunModeList)
150
151%% list of builtin transform functions in the mebu TransformName
152TransformList={'';'sub_field';'phys';'phys_polar'};% WARNING: must fit with the corresponding menu in uvmat and nb_builtin_transform=4 in  TransformName_callback
153NbBuiltinTransform=numel(TransformList);
154path_transform_fct=fullfile(path_series,'transform_field');
155TransformPathList=cell(NbBuiltinTransform,1);%initiate the cell matrix of Action fct paths
156TransformPathList(:)={path_transform_fct}; %set the default path to series fcts to all list members
157
158%% get the user defined functions stored in the personal file uvmat_perso.mat
159dir_perso=prefdir;
160profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
161if exist(profil_perso,'file')
162    h=load (profil_perso);
163    %get the list of previous input files in the upper bar menu Open
164    if isfield(h,'MenuFile')
165        for ifile=1:min(length(h.MenuFile),5)
166            set(handles.(['MenuFile_' num2str(ifile)]),'Label',h.MenuFile{ifile});
167            set(handles.(['MenuFile_' num2str(ifile+5)]),'Label',h.MenuFile{ifile});
168        end
169    end
170    %get the list of previous camapigns in the upper bar menu Open campaign
171    if isfield(h,'MenuCampaign')
172        for ifile=1:min(length(h.MenuCampaign),5)
173            set(handles.(['MenuCampaign_' num2str(ifile)]),'Label',h.MenuCampaign{ifile});
174        end
175    end
176    %get the menu of actions
177    if isfield(h,'ActionExtListUser') && iscell(h.ActionExtListUser)
178        ActionExtList=[ActionExtList; h.ActionExtListUser];
179    end
180    if isfield(h,'ActionListUser') && iscell(h.ActionListUser) && isfield(h,'ActionPathListUser') && iscell(h.ActionPathListUser)
181        ActionList=[ActionList;h.ActionListUser];
182        ActionPathList=[ActionPathList;h.ActionPathListUser];
183    end
184    %get the menu of transform fct
185    if isfield(h,'TransformListUser') && iscell(h.TransformListUser) && isfield(h,'TransformPathListUser') && iscell(h.TransformPathListUser)
186        TransformList=[TransformList;h.TransformListUser];
187        TransformPathList=[TransformPathList;h.TransformPathListUser];
188    end
189end
190
191%% selection of the input Action fct
192ActionCheckExist=true(size(ActionList));%initiate the check of the path to the listed action fct
193for ilist=NbBuiltinAction+1:numel(ActionList)%check  the validity of the path of the user defined Action fct
194    ActionCheckExist(ilist)=exist(fullfile(ActionPathList{ilist},[ActionList{ilist} '.m']),'file');
195end
196ActionPathList=ActionPathList(ActionCheckExist,:);% suppress the menu options which are not valid anymore
197ActionList=ActionList(ActionCheckExist);
198set(handles.ActionName,'String',[ActionList;{'more...'}])
199set(handles.ActionName,'UserData',ActionPathList)
200ActionIndex=[];
201if isfield(Param,'ActionName')% copy the selected menu index transferred in Param from uvmat
202    ActionIndex=find(strcmp(Param.ActionName,ActionList),1);
203end
204if isempty(ActionIndex)
205    ActionIndex=1;
206end
207set(handles.ActionName,'Value',ActionIndex)
208set(handles.ActionPath,'String',ActionPathList{ActionIndex})
209set(handles.ActionExt,'Value',1)
210set(handles.ActionExt,'String',ActionExtList)
211
212%% selection of the input transform fct
213TransformCheckExist=true(size(TransformList));
214for ilist=NbBuiltinTransform+1:numel(TransformList)
215    TransformCheckExist(ilist)=exist(fullfile(TransformPathList{ilist},[TransformList{ilist} '.m']),'file');
216end
217TransformPathList=TransformPathList(TransformCheckExist);
218TransformList=TransformList(TransformCheckExist);
219set(handles.TransformName,'String',[TransformList;{'more...'}])
220set(handles.TransformName,'UserData',TransformPathList)
221TransformIndex=[];
222if isfield(Param,'TransformName')% copy the selected menu index transferred in Param from uvmat
223    TransformIndex=find(strcmp(Param.TransformName,TransformList),1);
224end
225if isempty(TransformIndex)
226    TransformIndex=1;
227end
228set(handles.TransformName,'Value',TransformIndex)
229set(handles.TransformPath,'String',TransformPathList{TransformIndex})
230   
231%% fields input initialisation
232if isfield(Param,'list_fields')&& isfield(Param,'index_fields') &&~isempty(Param.list_fields) &&~isempty(Param.index_fields)
233    set(handles.FieldName,'String',Param.list_fields);% list menu fields
234    set(handles.FieldName,'Value',Param.index_fields);% selected string index
235end
236if isfield(Param,'Coord_x_str')&& isfield(Param,'Coord_x_val')
237        set(handles.Coord_x,'String',Param.Coord_x_str);% list menu fields
238    set(handles.Coord_x,'Value',Param.Coord_x_val);% selected string index
239end
240if isfield(Param,'Coord_y_str')&& isfield(Param,'Coord_y_val')
241        set(handles.Coord_y,'String',Param.Coord_y_str);% list menu fields
242    set(handles.Coord_y,'Value',Param.Coord_y_val);% selected string index
243end
244
245%% introduce the input file name(s) if defined from input Param
246if isfield(Param,'FileName')&&~isempty(Param.FileName)
247    InputTable={};
248    set(handles.InputTable,'Data',InputTable)
249    if isfield(Param,'FileName_1')
250        display_file_name(handles,Param.FileName,'one')%refresh the input table
251        display_file_name(handles,Param.FileName_1,1)
252    else
253        display_file_name(handles,Param.FileName,'one')%refresh the input table
254    end
255end 
256if isfield(Param,'incr_i')
257    set(handles.num_incr_i,'String',num2str(Param.incr_i))
258end
259if isfield(Param,'incr_j')
260    set(handles.num_incr_j,'String',num2str(Param.incr_j))
261end
262set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH button to magenta color to indicate that input refresh is needed
263
264%------------------------------------------------------------------------
265% --- Outputs from this function are returned to the command line.
266function varargout = series_OutputFcn(hObject, eventdata, handles)
267%------------------------------------------------------------------------
268varargout{1} = handles.output;
269
270%------------------------------------------------------------------------
271% --- executed when closing uvmat: delete or desactivate the associated figures if exist
272function closefcn(gcbo,eventdata)
273%------------------------------------------------------------------------
274
275% delete set_object_series if detected
276hh=findobj(allchild(0),'name','view_object_series');
277if ~isempty(hh)
278    delete(hh)
279end
280hh=findobj(allchild(0),'name','edit_object_series');
281if ~isempty(hh)
282    delete(hh)
283end
284
285%delete the bowser if detected
286hh=findobj(allchild(0),'tag','browser');
287if ~isempty(hh)
288    delete(hh)
289end
290
291
292%------------------------------------------------------------------------
293%------------------------------------------------------------------------
294%  II - FUNCTIONS FOR INTRODUCING THE INPUT FILES
295% automatically sets the global properties when the rootfile name is introduced
296% then activate the view-field actionname if selected
297% it is activated either by clicking on the RootPath window or by the
298% browser
299%------------------------------------------------------------------------
300%------------------------------------------------------------------------
301% --- fct activated by the browser under 'Open'
302%------------------------------------------------------------------------ 
303function MenuBrowse_Callback(hObject, eventdata, handles)
304%% look for the previously opened file 'oldfile'
305InputTable=get(handles.InputTable,'Data');
306oldfile=InputTable{1,1};
307if isempty(oldfile)
308    % use a file name stored in prefdir
309    dir_perso=prefdir;
310    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
311    if exist(profil_perso,'file')
312        h=load (profil_perso);
313        if isfield(h,'RootPath') && ischar(h.RootPath)
314            oldfile=h.RootPath;
315        end
316    end
317end
318%% launch the browser
319fileinput=uigetfile_uvmat('pick an input file in the series',oldfile);
320hh=dir(fileinput);
321if numel(hh)>1
322    msgbox_uvmat('ERROR','invalid input, probably a broken link');
323else
324    if ~isempty(fileinput)
325        display_file_name(handles,fileinput,'one')
326    end
327end
328
329% --------------------------------------------------------------------
330function MenuBrowseAppend_Callback(hObject, eventdata, handles)
331
332%% look for the previously opened file 'oldfile'
333InputTable=get(handles.InputTable,'Data');
334RootPathCell=InputTable(:,1);
335if isempty(RootPathCell{1})% no input file in the table
336     MenuBrowse_Callback(hObject, eventdata, handles)%refresh the input table, not append
337     return
338end
339SubDirCell=InputTable(:,2);
340oldfile=fullfile(RootPathCell{1},SubDirCell{1});
341
342%% use a file name stored in prefdir
343dir_perso=prefdir;
344profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
345if exist(profil_perso,'file')
346    h=load (profil_perso);
347    if isfield(h,'RootPath') && ischar(h.RootPath)
348        oldfile=h.RootPath;
349    end
350end
351
352%% launch the browser
353fileinput=uigetfile_uvmat('pick a file to append in the input table',oldfile);
354hh=dir(fileinput);
355if numel(hh)>1
356    msgbox_uvmat('ERROR','invalid input, probably a broken link');
357else
358    if ~isempty(fileinput)
359        display_file_name(handles,fileinput,'append')
360    end
361end
362
363%------------------------------------------------------------------------
364% --- fct activated by selecting a previous file under the menu Open
365%------------------------------------------------------------------------
366function MenuFile_Callback(hObject, eventdata, handles)
367
368errormsg=display_file_name(handles,get(hObject,'Label'),'one');
369if ~isempty(errormsg)
370    set(hObject,'Label','')
371    MenuFile=[{get(handles.MenuFile_1,'Label')};{get(handles.MenuFile_2,'Label')};...
372        {get(handles.MenuFile_3,'Label')};{get(handles.MenuFile_4,'Label')};{get(handles.MenuFile_5,'Label')}];
373    str_find=strcmp(get(hObject,'Label'),MenuFile);
374    MenuFile(str_find)=[];% suppress the input file to the list
375    for ifile=1:numel(MenuFile)
376        set(handles.(['MenuFile_' num2str(ifile)]),'Label',MenuFile{ifile});
377    end
378end
379
380%------------------------------------------------------------------------
381% --- fct activated by selecting a previous file under the menu Open/append
382%------------------------------------------------------------------------
383function MenuFile_append_Callback(hObject, eventdata, handles)
384
385InputTable=get(handles.InputTable,'Data');
386if isempty(InputTable{1,1})% no input file in the table
387    display_file_name(handles,get(hObject,'Label'),'one') %refresh the input table, not append
388else
389    display_file_name(handles,get(hObject,'Label'),'append')% append the selected file to the current list of InputTable
390end
391
392%------------------------------------------------------------------------
393% --- fct activated by the browser under 'Open campaign'
394%------------------------------------------------------------------------
395function MenuBrowseCampaign_Callback(hObject, eventdata, handles)
396
397set(handles.MenuOpenCampaign,'ForegroundColor',[1 1 0])
398drawnow
399InputTable=get(handles.InputTable,'Data');
400RootPath=InputTable{1,1};
401CampaignPath=fileparts(fileparts(RootPath));
402DirFull=uigetfile_uvmat('define this path as the Campaign folder:',CampaignPath,'uigetdir');
403if ~ischar(DirFull)|| ~exist(DirFull,'dir')
404    return
405end
406OutPut=browse_data(DirFull);% open the GUI browse_data to get select a campaign dir, experiment and device
407if ~isfield(OutPut,'Campaign')
408    return
409end
410DirName=fullfile(OutPut.Campaign,OutPut.Experiment{1},OutPut.DataSeries{1});
411ListStruct=dir(DirName); %list files and the dir DataSeries
412% select the first appropriate file in the dir
413FileName='';
414for ilist=1:numel(ListStruct)
415    if ~isequal(ListStruct(ilist).isdir,1)%look for files, not dir
416        FileName=ListStruct(ilist).name;
417        FileType=get_file_type(fullfile(DirName,FileName));
418        switch FileType
419            case {'image','multimage','civx','civdata','netcdf'}
420                break
421        end
422    end
423end
424if isempty(FileName)
425    msgbox_uvmat('ERROR',['no appropriate input file in the DataSeries folder ' fullfile(DirName)])
426    return
427end
428
429%% update the list of campaigns in the menubar
430MenuCampaign=[{get(handles.MenuCampaign_1,'Label')};{get(handles.MenuCampaign_2,'Label')};...
431    {get(handles.MenuCampaign_3,'Label')};{get(handles.MenuCampaign_4,'Label')};{get(handles.MenuCampaign_5,'Label')}];
432check_dir=isempty(find(strcmp(DirFull,MenuCampaign)));
433if check_dir %insert the new campaign in the list if it is not found
434    MenuCampaign(end)=[]; %suppress the last item
435    MenuCampaign=[{DirFull};MenuCampaign];%insert the new campaign
436    for ilist=1:numel(MenuCampaign)
437        set(handles.(['MenuCampaign_' num2str(ilist)]),'Label',MenuCampaign{ilist})
438    end
439    % save the list for future opening:
440    dir_perso=prefdir;
441    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
442    if exist(profil_perso,'file')
443        save (profil_perso,'MenuCampaign','RootPath','-append'); %store the file names for future opening of uvmat
444    else
445        save (profil_perso,'MenuCampaign','RootPath','-V6'); %store the file names for future opening of uvmat
446    end
447end
448
449%% display the selected field and related information
450if get(handles.CheckAppend,'Value')
451    display_file_name(handles,fullfile(DirName,FileName),'append')
452else
453    display_file_name(handles,fullfile(DirName,FileName),'one')
454end
455set(handles.MenuOpenCampaign,'ForegroundColor',[0 0 0])
456
457% --------------------------------------------------------------------
458function MenuCampaign_Callback(hObject, eventdata, handles)
459% --------------------------------------------------------------------
460set(handles.MenuOpenCampaign,'ForegroundColor',[1 1 0])
461OutPut=browse_data(get(hObject,'Label'));% open the GUI browse_data to get select a campaign dir, experiment and device
462if ~isfield(OutPut,'Campaign')
463    return
464end
465DirName=fullfile(OutPut.Campaign,OutPut.Experiment{1},OutPut.DataSeries{1});
466hdir=dir(DirName); %list files and dirs
467for ilist=1:numel(hdir)
468    if ~isequal(hdir(ilist).isdir,1)%look for files, not dir
469        FileName=hdir(ilist).name;
470        FileType=get_file_type(fullfile(DirName,FileName));
471        switch FileType
472            case {'image','multimage','civx','civdata','netcdf'}
473            break
474        end
475    end
476end
477if get(handles.CheckAppend,'Value')
478    display_file_name(handles,fullfile(DirName,FileName),'append')
479else
480    display_file_name(handles,fullfile(DirName,FileName),'one')
481end
482set(handles.MenuOpenCampaign,'ForegroundColor',[0 0 0])
483
484
485
486%------------------------------------------------------------------------
487% --- Executes when entered data in editable cell(s) in InputTable.
488function InputTable_CellEditCallback(hObject, eventdata, handles)
489%------------------------------------------------------------------------
490set(handles.REFRESH,'BackgroundColor',[1 0 1])% set REFRESH button to magenta color to indicate that input refresh is needed
491% set(handles.REFRESH_title,'Visible','on')
492iview=eventdata.Indices(1);
493view_set=get(handles.REFRESH,'UserData');
494if isempty(find(view_set==iview))
495    set(handles.REFRESH,'UserData',[view_set iview])
496end
497%% enable other menus and uicontrols
498set(handles.MenuOpenCampaign,'Enable','on')
499set(handles.MenuCampaign_1,'Enable','on')
500set(handles.MenuCampaign_2,'Enable','on')
501set(handles.MenuCampaign_3,'Enable','on')
502set(handles.MenuCampaign_4,'Enable','on')
503set(handles.MenuCampaign_5,'Enable','on')
504set(handles.RUN, 'Enable','On')
505set(handles.RUN,'BackgroundColor',[1 0 0])% set RUN button to red
506
507%------------------------------------------------------------------------
508% --- 'key_press_fcn:' function activated when a key is pressed on the keyboard
509%------------------------------------------------------------------------
510function key_press_fcn(hObject,eventdata,handles)
511
512xx=double(get(handles.series,'CurrentCharacter')); %get the keyboard character
513if ismember(xx,[8 127 31])%backspace or delete, or downward
514    InputTable=get(handles.InputTable,'Data');
515    iline=get(handles.InputTable,'UserData');
516            if isequal(xx, 31)
517                if isequal(iline,size(InputTable,1))% arrow downward
518                InputTable=[InputTable;cell(1,size(InputTable,2))];
519                end
520            else
521    InputTable(iline,:)=[];% suppress the current line
522            end
523    set(handles.InputTable,'Data',InputTable);
524end
525
526
527%------------------------------------------------------------------------
528% --- Executes on button press in REFRESH.
529function REFRESH_Callback(hObject, eventdata, handles)
530%------------------------------------------------------------------------
531InputTable=get(handles.InputTable,'Data');
532set(handles.series,'Pointer','watch') % set the mouse pointer to 'watch'
533set(handles.REFRESH,'BackgroundColor',[1 1 0])% set REFRESH  button to yellow color (indicate activation)
534drawnow
535empty_line=false(size(InputTable,1),1);
536for iline=1:size(InputTable,1)
537    empty_line(iline)= isempty(cell2mat(InputTable(iline,1:3)));
538end
539InputTable(empty_line,:)=[];%remove empty lines
540set(handles.InputTable,'Data',InputTable)
541for iview=1:size(InputTable,1)
542    RootPath=fullfile(InputTable{iview,1},InputTable{iview,2});
543    if ~exist(RootPath,'dir')
544        i1_series=[];
545        RootPath=fileparts(RootPath); %will try the upper folder
546    else %scan the input folder
547        [RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,tild,FileType,FileInfo,MovieObject]=...
548            find_file_series(fullfile(InputTable{iview,1},InputTable{iview,2}),[InputTable{iview,3} InputTable{iview,4} InputTable{iview,5}]);
549    end
550    % if no file is found, open a browser
551    if isempty(i1_series)
552        fileinput=uigetfile_uvmat(['wrong input at line ' num2str(iview) ':pick a new input file'],RootPath);
553        if isempty(fileinput)
554            set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  back to red color
555            return
556        else
557            display_file_name(handles,fileinput,iview)
558        end
559    else
560       update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,FileInfo,MovieObject,iview)
561    end
562end
563set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (indicate activation finished)
564set(handles.series,'Pointer','arrow') % set the mouse pointer to 'watch'
565
566%------------------------------------------------------------------------
567% --- Function called when a new file is opened, either by series_OpeningFcn or by the browser
568function errormsg=display_file_name(handles,fileinput,iview)
569%------------------------------------------------------------------------ 
570%
571% INPUT:
572% handles: handles of elements in the GUI
573% fileinput: input file name, including path
574% iview: line index in the input table
575%       or 'one': refresh the list
576%         'append': add a new line to the input table
577set(handles.REFRESH,'BackgroundColor',[1 1 0])% set REFRESH  button to yellow color (indicate activation)
578drawnow
579errormsg='';%default
580%% get the input root name, indices, file extension and nomenclature NomType
581if ~exist(fileinput,'file')
582    errormsg=['input file ' fileinput  ' does not exist'];
583    msgbox_uvmat('ERROR',errormsg)
584    set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (end of activation)
585    return
586end
587
588%% detect root name, nomenclature and indices in the input file name:
589[FilePath,FileName,FileExt]=fileparts(fileinput);
590% detect the file type, get the movie object if relevant, and look for the corresponding file series:
591% the root name and indices may be corrected by including the first index i1 if a corresponding xml file exists
592[RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,NomType,FileType,FileInfo,MovieObject,i1,i2,j1,j2]=find_file_series(FilePath,[FileName FileExt]);
593if isempty(RootFile)&&isempty(i1_series)
594    errormsg='no input file in the series';
595    msgbox_uvmat('ERROR',errormsg)
596    set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (end of activation)
597    return
598end
599if strcmp(FileType,'txt')
600    edit(fileinput)
601    set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (end of activation)
602    return
603elseif strcmp(FileType,'xml')
604    editxml(fileinput)
605    set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (end of activation)
606     return
607elseif strcmp(FileType,'figure')
608    open(fileinput)
609    set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (end of activation)
610     return
611end
612
613%% enable other menus and uicontrols
614set(handles.MenuOpenCampaign,'Enable','on')
615set(handles.MenuCampaign_1,'Enable','on')
616set(handles.MenuCampaign_2,'Enable','on')
617set(handles.MenuCampaign_3,'Enable','on')
618set(handles.MenuCampaign_4,'Enable','on')
619set(handles.MenuCampaign_5,'Enable','on')
620set(handles.RUN, 'Enable','On')
621set(handles.RUN,'BackgroundColor',[1 0 0])% set RUN button to red
622set(handles.InputTable,'BackgroundColor',[1 1 0]) % set RootPath edit box  to yellow
623drawnow
624
625
626
627%% fill the list of file series
628InputTable=get(handles.InputTable,'Data');
629SeriesData=get(handles.series,'UserData');
630if strcmp(iview,'append') % display the input data as a new line in the table
631    iview=size(InputTable,1)+1;% the next line in InputTable becomes the current line
632    %InputTable(iview+1,:)={'','','','',''};
633    InputTable(iview,:)=[{RootPath},{SubDir},{RootFile},{NomType},{FileExt}];
634elseif strcmp(iview,'one') % refresh the list of  input  file series
635    iview=1; %the first line in InputTable becomes the current line
636    InputTable={'','','','',''};
637    %InputTable=[{'','','','',''};{'','','','',''}];
638    InputTable(iview,:)=[{RootPath},{SubDir},{RootFile},{NomType},{FileExt}];
639    set(handles.TimeTable,'Data',[{[]},{[]},{[]},{[]}])
640    set(handles.MinIndex_i,'Data',[])
641    set(handles.MaxIndex_i,'Data',[])
642    set(handles.MinIndex_j,'Data',[])
643    set(handles.MaxIndex_j,'Data',[])
644    set(handles.ListView,'Value',1)
645    set(handles.ListView,'String',{'1'})
646    set(handles.PairString,'Data',{''})
647    SeriesData.i1_series={};
648    SeriesData.i2_series={};
649    SeriesData.j1_series={};
650    SeriesData.j2_series={};
651    SeriesData.FileType={};
652    SeriesData.FileInfo={};
653    SeriesData.Time={};
654end
655%nbview=size(InputTable,1)-1;% rmq: the last line is set blank to allow manual addition of a line
656nbview=size(InputTable,1);
657set(handles.ListView,'String',mat2cell((1:nbview)',ones(nbview,1)))
658set(handles.ListView,'Value',iview)
659set(handles.InputTable,'Data',InputTable)
660
661%% determine the selected reference field indices for pair display
662if isempty(i1)
663    i1=1;
664end
665if isempty(i2)
666    i2=i1;
667end
668ref_i=floor((i1+i2)/2);% reference image number corresponding to the file
669set(handles.num_ref_i,'String',num2str(ref_i));
670% set(handles.num_ref_i,'UserData',[i1 i2])%store the indices for future opening
671if isempty(j1)
672    j1=1;
673end
674if isempty(j2)
675    j2=j1;
676end
677ref_j=floor((j1+j2)/2);% reference image number corresponding to the file
678set(handles.num_ref_j,'String',num2str(ref_j));
679
680%% update first and last indices if they do not exist
681Param=read_GUI(handles.series);
682first_j=[];
683if isfield(Param.IndexRange,'first_j'); first_j=Param.IndexRange.first_j; end
684last_j=[];
685if isfield(Param.IndexRange,'last_j'); last_j=Param.IndexRange.last_j; end
686PairString='';
687if isfield(Param.IndexRange,'PairString'); PairString=Param.IndexRange.PairString; end
688[i1,i2,j1,j2] = get_file_index(Param.IndexRange.first_i,first_j,PairString);
689FirstFileName=fullfile_uvmat(Param.InputTable{1,1},Param.InputTable{1,2},Param.InputTable{1,3},...
690    Param.InputTable{1,5},Param.InputTable{1,4},i1,i2,j1,j2);
691if ~exist(FirstFileName,'file')
692    set(handles.num_first_i,'String',num2str(ref_i))
693    set(handles.num_first_j,'String',num2str(ref_j))
694end
695[i1,i2,j1,j2] = get_file_index(Param.IndexRange.last_i,last_j,PairString);
696LastFileName=fullfile_uvmat(Param.InputTable{1,1},Param.InputTable{1,2},Param.InputTable{1,3},...
697    Param.InputTable{1,5},Param.InputTable{1,4},i1,i2,j1,j2);
698if ~exist(LastFileName,'file')
699    set(handles.num_last_i,'String',num2str(ref_i))
700    set(handles.num_last_j,'String',num2str(ref_j))
701end
702
703%% update the list of recent files in the menubar and save it for future opening
704MenuFile=[{get(handles.MenuFile_1,'Label')};{get(handles.MenuFile_2,'Label')};...
705    {get(handles.MenuFile_3,'Label')};{get(handles.MenuFile_4,'Label')};{get(handles.MenuFile_5,'Label')}];
706str_find=strcmp(fileinput,MenuFile);
707if isempty(find(str_find,1))
708    MenuFile=[{fileinput};MenuFile];%insert the current file if not already in the list
709end
710for ifile=1:min(length(MenuFile),5)
711    eval(['set(handles.MenuFile_' num2str(ifile) ',''Label'',MenuFile{ifile});'])
712end
713dir_perso=prefdir;
714profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
715if exist(profil_perso,'file')
716    save (profil_perso,'MenuFile','-append'); %store the file names for future opening of uvmat
717else
718    save (profil_perso,'MenuFile','-V6'); %store the file names for future opening of uvmat
719end
720% save the opened file to initiate future opening
721SeriesData.RefFile{iview}=fileinput;% reference opening file for line iview
722SeriesData.Ref_i1=i1;
723SeriesData.Ref_i2=i2;
724SeriesData.Ref_j1=j1;
725SeriesData.Ref_j2=j2;
726set(handles.series,'UserData',SeriesData)
727
728set(handles.InputTable,'BackgroundColor',[1 1 1])
729
730%% initiate input file series and refresh the current field view:     
731update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,FileInfo,MovieObject,iview);
732set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to red color (end of activation)
733
734%------------------------------------------------------------------------
735% --- Update information about a new field series (indices to scan, timing,
736%     calibration from an xml file
737function update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,FileInfo,VideoObject,iview)
738%------------------------------------------------------------------------
739InputTable=get(handles.InputTable,'Data');
740
741%% display the min and max indices for the whole file series
742if size(i1_series,2)==2 && min(min(i1_series(:,1,:)))==0
743    MinIndex_j=1;% index j set to 1 by default
744    MaxIndex_j=1;
745    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)
746    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)
747else
748    ref_i=squeeze(max(i1_series(1,:,:),[],2));% select ref_j index for each ref_i
749    ref_j=squeeze(max(j1_series(1,:,:),[],3));% select ref_i index for each ref_j
750     MinIndex_i=min(find(ref_i))-1;
751     MaxIndex_i=max(find(ref_i))-1;
752     MaxIndex_j=max(find(ref_j))-1;
753     MinIndex_j=min(find(ref_j))-1;
754    diff_j_max=diff(ref_j);
755    diff_i_max=diff(ref_i);
756    if ~isempty(diff_i_max) && isequal (diff_i_max,diff_i_max(1)*ones(size(diff_i_max)))
757        set(handles.num_incr_i,'String',num2str(diff_i_max(1)))% detect an increment to dispaly by default
758    end
759    if isequal (diff_j_max,diff_j_max(1)*ones(size(diff_j_max)))
760        set(handles.num_incr_j,'String',num2str(diff_j_max(1)))
761    end
762end
763if isequal(MinIndex_i,-1)
764    MinIndex_i=0;
765end
766if isequal(MinIndex_j,-1)
767    MinIndex_j=0;
768end
769MinIndex_i_table=get(handles.MinIndex_i,'Data');%retrieve the min indices in the table MinIndex
770MinIndex_j_table=get(handles.MinIndex_j,'Data');%retrieve the min indices in the table MinIndex
771MaxIndex_i_table=get(handles.MaxIndex_i,'Data');%retrieve the min indices in the table MinIndex
772MaxIndex_j_table=get(handles.MaxIndex_j,'Data');%retrieve the min indices in the table MinIndex
773MinIndex_i_table(iview,1)=MinIndex_i;
774MinIndex_j_table(iview,1)=MinIndex_j;
775MaxIndex_i_table(iview,1)=MaxIndex_i;
776MaxIndex_j_table(iview,1)=MaxIndex_j;
777set(handles.MinIndex_i,'Data',MinIndex_i_table)%display the min indices in the table MinIndex
778set(handles.MinIndex_j,'Data',MinIndex_j_table)%display the max indices in the table MaxIndex
779set(handles.MaxIndex_i,'Data',MaxIndex_i_table)%display the min indices in the table MinIndex
780set(handles.MaxIndex_j,'Data',MaxIndex_j_table)%display the max indices in the table MaxIndex
781
782%% adjust the first and last indices for the selected series, only if requested by the bounds
783% i index, compare input to min index i
784first_i=str2num(get(handles.num_first_i,'String'));%retrieve previous first i
785ref_i=str2num(get(handles.num_ref_i,'String'));%index i given by the input field
786if isempty(first_i)
787    first_i=ref_i;% first_i updated by the input value
788elseif first_i < MinIndex_i
789    first_i=MinIndex_i; % first_i set to the min i index (restricted by oter input lines)
790elseif first_i >MaxIndex_i
791    first_i=MaxIndex_i;% first_i set to the max i index (restricted by oter input lines)
792end
793% j index,  compare input to min index j
794first_j=str2num(get(handles.num_first_j,'String'));
795ref_j=str2num(get(handles.num_ref_j,'String'));%index j given by the input field
796if isempty(first_j)
797    first_j=ref_j;% first_j updated by the input value
798elseif first_j<MinIndex_j
799    first_j=MinIndex_j; % first_j set to the min j index (restricted by oter input lines)
800elseif first_j >MaxIndex_j
801    first_j=MaxIndex_j; % first_j set to the max j index (restricted by oter input lines)
802end
803% i index, compare input to max index i
804last_i=str2num(get(handles.num_last_i,'String'));
805if isempty(last_i)
806    last_i=ref_i;
807elseif last_i > MaxIndex_i
808    last_i=MaxIndex_i;
809elseif last_i<first_i
810    last_i=first_i;
811end
812% j index, compare input to max index j
813last_j=str2num(get(handles.num_last_j,'String'));
814if isempty(last_j)
815    last_j=ref_j;
816elseif last_j>MaxIndex_j
817    last_j=MaxIndex_j;
818elseif last_j<first_j
819    last_j=first_j;
820end
821set(handles.num_first_i,'String',num2str(first_i));
822set(handles.num_first_j,'String',num2str(first_j));
823set(handles.num_last_i,'String',num2str(last_i));
824set(handles.num_last_j,'String',num2str(last_j));
825
826%% number of slices set by default
827NbSlice=1;%default
828% read  value set by the first series for the checkappend mode (iwiew >1)
829if iview>1 && strcmp(get(handles.num_NbSlice,'Visible'),'on')
830    NbSlice=str2num(get(handles.num_NbSlice,'String'));
831end
832
833%% default time unit
834TimeUnit='';
835% read  value set by the first series for the checkappend mode (iwiew >1)
836if iview>1
837    TimeUnit=get(handles.TimeUnit,'String');
838end
839TimeSource='';
840Time=[];%default
841
842%%  read image documentation file if found
843XmlData=[];
844check_calib=0;
845XmlFileName=find_imadoc(InputTable{iview,1},InputTable{iview,2},InputTable{iview,3},InputTable{iview,5});
846if ~isempty(XmlFileName)
847    [XmlData,errormsg]=imadoc2struct(XmlFileName);
848    if ~isempty(errormsg)
849         msgbox_uvmat('WARNING',['error in reading ' XmlFileName ': ' errormsg]);
850    end
851    % read time if available
852    if isfield(XmlData,'Time')
853        Time=XmlData.Time;
854        TimeSource='xml';
855    end
856    if isfield(XmlData,'Camera')
857        if isfield(XmlData.Camera,'NbSlice')&& ~isempty(XmlData.Camera.NbSlice)
858            if iview>1 && ~isempty(NbSlice) && ~strcmp(NbSlice,XmlData.Camera.NbSlice)
859                msgbox_uvmat('WARNING','inconsistent number of slices with the first field series');
860            end
861            NbSlice=XmlData.Camera.NbSlice;% Nbre of slices from camera
862        end
863        if isfield(XmlData.Camera,'TimeUnit')&& ~isempty(XmlData.Camera.TimeUnit)
864            if iview>1 && ~isempty(TimeUnit) && ~strcmp(TimeUnit,XmlData.Camera.TimeUnit)
865                msgbox_uvmat('WARNING','inconsistent time unit with the first field series');
866            end
867            TimeUnit=XmlData.Camera.TimeUnit;
868        end
869    end
870    % number of slices
871    if isfield(XmlData,'GeometryCalib')
872        check_calib=1;
873        if isfield(XmlData.GeometryCalib,'SliceCoord')
874            siz=size(XmlData.GeometryCalib.SliceCoord);
875            if siz(1)>1
876                if iview>1 && ~isempty(NbSlice) && ~strcmp(NbSlice,siz(1))
877                    msgbox_uvmat('WARNING','inconsistent number of Z indices with the first field series');
878                end
879                NbSlice=siz(1);
880            end
881        end
882    end
883    set(handles.num_NbSlice,'String',num2str(NbSlice))
884end
885
886%% read timing and total frame number from the current file (movie files) if not already set by the xml file (prioritary)
887InputTable=get(handles.InputTable,'Data');
888
889% case of movies
890if isempty(Time)
891    if ~isempty(VideoObject)
892        imainfo=get(VideoObject);
893        if isempty(j1_series); %frame index along i
894            Time=zeros(imainfo.NumberOfFrames+1,2);
895            Time(:,2)=(0:1/imainfo.FrameRate:(imainfo.NumberOfFrames)/imainfo.FrameRate)';
896        else
897            Time=[0;ones(size(i1_series,3)-1,1)]*(0:1/imainfo.FrameRate:(imainfo.NumberOfFrames)/imainfo.FrameRate);
898        end
899        TimeSource='video';
900    end
901end
902
903%% update time table
904if ~isempty(Time)
905    TimeTable=get(handles.TimeTable,'Data');
906    TimeTable{iview,1}=Time(MinIndex_i+1,MinIndex_j+1);
907    if size(Time)>=[first_i+1 first_j+1]
908        TimeTable{iview,2}=Time(first_i+1,first_j+1);
909    end
910    if size(Time)>=[last_i+1 last_j+1]
911        TimeTable{iview,3}=Time(last_i+1,last_j+1);
912    end
913    if size(Time)>=[MaxIndex_i+1 MaxIndex_j+1];
914        TimeTable{iview,4}=Time(MaxIndex_i+1,MaxIndex_j+1);
915    end
916    set(handles.TimeTable,'Data',TimeTable)
917end
918
919%% update the series info in 'UserData'
920SeriesData=get(handles.series,'UserData');
921SeriesData.i1_series{iview}=i1_series;
922SeriesData.i2_series{iview}=i2_series;
923SeriesData.j1_series{iview}=j1_series;
924SeriesData.j2_series{iview}=j2_series;
925SeriesData.FileType{iview}=FileType;
926SeriesData.FileInfo{iview}=FileInfo;
927SeriesData.Time{iview}=Time;
928if ~isempty(TimeSource)
929    SeriesData.TimeSource=TimeSource;
930end
931% if ~isempty(TimeUnit)
932%     SeriesData.TimeUnit=TimeUnit;
933% end
934if check_calib
935    SeriesData.GeometryCalib{iview}=XmlData.GeometryCalib;
936end
937set(handles.series,'UserData',SeriesData)
938
939%% update pair menus
940ListView=get(handles.ListView,'String');
941ListView{iview}=num2str(iview);
942set(handles.ListView,'String',ListView);
943set(handles.ListView,'Value',iview)
944update_mode(handles,i1_series,i2_series,j1_series,j2_series,Time)
945
946%% enable j index visibility
947status_j='on';%default
948if isempty(find(~cellfun(@isempty,SeriesData.j1_series), 1)); % case of empty j indices
949    status_j='off'; % no j index needed
950elseif strcmp(get(handles.PairString,'Visible'),'on')
951    PairString=get(handles.PairString,'Data');
952    check_burst=cellfun(@isempty,regexp(PairString,'^j'));%=0 for burst case, 1 otherwise
953    if isempty(find(check_burst, 1))% if all pair string begins by j (burst)
954        status_j='off'; % no j index needed for bust case
955    end
956end
957enable_j(handles,status_j) % no j index needed
958
959%% display the set of existing files as an image
960set(handles.FileStatus,'Units','pixels')
961Position=get(handles.FileStatus,'Position');
962set(handles.FileStatus,'Units','normalized')
963%xI=0.5:Position(3)-0.5;
964nbview=numel(SeriesData.i1_series);
965j_max=cell(1,nbview);
966MaxIndex_i=ones(1,nbview);%default
967MinIndex_i=ones(1,nbview);%default
968for iview=1:nbview
969    pair_max=squeeze(max(SeriesData.i1_series{iview},[],1)); %max on pair index
970    j_max{iview}=max(pair_max,[],1);%max on j index
971    MaxIndex_i(iview)=max(find(j_max{iview}))-1;% max ref index i
972    MinIndex_i(iview)=min(find(j_max{iview}))-1;% min ref index i
973end
974MinIndex_i=min(MinIndex_i);
975MaxIndex_i=max(MaxIndex_i);
976range_index=MaxIndex_i-MinIndex_i+1;
977% scale_y=Position(4)/nbview;
978% scale_x=Position(3)/range_index;
979%x=(0.5:range_index-0.5)*Position(3)/range_index;% set of abscissa representing the whole i index range
980% y=(0.5:nbview-0.5)*Position(4)/nbview;
981range_y=max(1,floor(Position(4)/nbview));
982npx=floor(Position(3));
983file_indices=MinIndex_i+floor(((0.5:npx-0.5)/npx)*range_index)+1;
984CData=zeros(nbview*range_y,npx);% initiate the image representing the existing files
985for iview=1:nbview
986    ind_y=1+(iview-1)*range_y:iview*range_y;
987    LineData=zeros(size(file_indices));
988    file_select=file_indices(file_indices<=numel(j_max{iview}));
989    ind_select=find(file_indices<=numel(j_max{iview}));
990    LineData(ind_select)=j_max{iview}(file_select)~=0;
991    CData(ind_y,:)=ones(size(ind_y'))*LineData;
992end
993CData=cat(3,zeros(size(CData)),CData,zeros(size(CData)));%make color images r=0,g,b=0
994set(handles.FileStatus,'CData',CData);
995
996%% check for pair display
997check_pairs=0;
998for iview=1:numel(SeriesData.i2_series)
999    if ~isempty(SeriesData.i2_series{iview})||~isempty(SeriesData.j2_series{iview})
1000        check_pairs=1;
1001    end
1002end
1003if check_pairs
1004    set(handles.Pairs,'Visible','on')
1005    set(handles.PairString,'Visible','on')
1006else
1007    set(handles.Pairs,'Visible','off')
1008    set(handles.PairString,'Visible','off')
1009end
1010
1011
1012%% enable field and veltype menus, in accordance with the current action
1013ActionName_Callback([],[], handles)
1014
1015%% set length of waitbar
1016displ_time(handles)
1017
1018%% set default options in menu 'Fields'
1019switch FileType
1020    case {'civx','civdata'}
1021        [FieldList,ColorList]=set_field_list('U','V','C');
1022        set(handles.FieldName,'String',[{'image'};FieldList;{'get_field...'}]);%standard menu for civx data
1023        set(handles.FieldName,'Value',2) % set menu to 'velocity
1024        set(handles.Coord_x,'Value',1);
1025        set(handles.Coord_x,'String',{'X'});
1026        set(handles.Coord_y,'Value',1);
1027        set(handles.Coord_y,'String',{'Y'});
1028    case 'netcdf'
1029        set(handles.FieldName,'Value',1)
1030        set(handles.FieldName,'String',{'get_field...'})
1031        if isempty(i2_series)
1032            i2=[];
1033        else
1034            i2=i2_series(1,ref_j+1,ref_i+1);
1035        end
1036        if isempty(j1_series)
1037            j1=[];j2=[];
1038        else
1039            j1=j1_series(1,ref_j+1,ref_i+1);
1040            if isempty(j2_series)
1041                j2=[];
1042            else
1043                j2=j2_series(1,ref_j+1,ref_i+1);
1044            end
1045        end
1046                FieldName_Callback([], [], handles)
1047       % FileName=fullfile_uvmat(InputTable{iview,1},InputTable{iview,2},InputTable{iview,3},InputTable{iview,5},InputTable{iview,4},i1_series(1,ref_j+1,ref_i+1),i2,j1,j2);
1048%         hget_field=get_field(FileName);
1049%         hhget_field=guidata(hget_field);
1050%         get_field('RUN_Callback',hhget_field.RUN,[],hhget_field);
1051    otherwise
1052        set(handles.FieldName,'Value',1) % set menu to 'image'
1053        set(handles.FieldName,'String',{'image'})
1054        set(handles.Coord_x,'Value',1);
1055        set(handles.Coord_x,'String',{'AX'});
1056        set(handles.Coord_y,'Value',1);
1057        set(handles.Coord_y,'String',{'AY'});
1058end
1059
1060%------------------------------------------------------------------------
1061function num_first_i_Callback(hObject, eventdata, handles)
1062%------------------------------------------------------------------------
1063num_last_i_Callback(hObject, eventdata, handles)
1064
1065%------------------------------------------------------------------------
1066function num_last_i_Callback(hObject, eventdata, handles)
1067%------------------------------------------------------------------------
1068SeriesData=get(handles.series,'UserData');
1069if ~isfield(SeriesData,'Time')
1070    SeriesData.Time{1}=[];
1071end
1072displ_time(handles);
1073
1074%------------------------------------------------------------------------
1075function num_first_j_Callback(hObject, eventdata, handles)
1076%------------------------------------------------------------------------
1077 num_last_j_Callback(hObject, eventdata, handles)
1078
1079%------------------------------------------------------------------------
1080function num_last_j_Callback(hObject, eventdata, handles)
1081%------------------------------------------------------------------------
1082first_j=str2num(get(handles.num_first_j,'String'));
1083last_j=str2num(get(handles.num_last_j,'String'));
1084ref_j=ceil((first_j+last_j)/2);
1085set(handles.num_ref_j,'String', num2str(ref_j))
1086num_ref_j_Callback(hObject, eventdata, handles)
1087SeriesData=get(handles.series,'UserData');
1088if ~isfield(SeriesData,'Time')
1089    SeriesData.Time{1}=[];
1090end
1091displ_time(handles);
1092
1093
1094%------------------------------------------------------------------------
1095% ---- find the times corresponding to the first and last indices of a series
1096function displ_time(handles)
1097%------------------------------------------------------------------------
1098SeriesData=get(handles.series,'UserData');%
1099PairString=get(handles.PairString,'Data');
1100ref_i_1=str2num(get(handles.num_first_i,'String'));%first reference index
1101ref_i_2=str2num(get(handles.num_last_i,'String'));%last reference index
1102ref_j_1=[];ref_j_2=[];
1103if strcmp(get(handles.num_first_j,'Visible'),'on')
1104ref_j_1=str2num(get(handles.num_first_j,'String'));
1105ref_j_2=str2num(get(handles.num_last_j,'String'));
1106end
1107[i1_1,i2_1,j1_1,j2_1] = get_file_index(ref_i_1,ref_j_1,PairString);
1108[i1_2,i2_2,j1_2,j2_2] = get_file_index(ref_i_2,ref_j_2,PairString);
1109TimeTable=get(handles.TimeTable,'Data');
1110
1111%Pairs=get(handles.PairString,'Data');
1112for iview=1:size(TimeTable,1)
1113    if size(SeriesData.Time,1)<iview
1114        break
1115    end
1116    TimeTable{iview,2}=[];
1117    TimeTable{iview,3}=[];
1118    if size(SeriesData.Time{iview},1)>=i2_2+1 && (isempty(ref_j_1)||size(SeriesData.Time{iview},2)>=j2_2+1)
1119        if isempty(ref_j_1)
1120            time_first=(SeriesData.Time{iview}(i1_1+1,2)+SeriesData.Time{iview}(i2_1+1,2))/2;
1121            time_last=(SeriesData.Time{iview}(i1_2+1,2)+SeriesData.Time{iview}(i2_2+1,2))/2;
1122        else
1123            time_first=(SeriesData.Time{iview}(i1_1+1,j1_1+1)+SeriesData.Time{iview}(i2_1+1,j2_1+1))/2;
1124            time_last=(SeriesData.Time{iview}(i1_2+1,j1_2+1)+SeriesData.Time{iview}(i2_2+1,j2_1+1))/2;
1125        end
1126        TimeTable{iview,2}=time_first; %TODO: take into account pairs
1127        TimeTable{iview,3}=time_last; %TODO: take into account pairs
1128    end
1129end
1130set(handles.TimeTable,'Data',TimeTable)
1131
1132%% set the waitbar position with respect to the min and max in the series
1133MinIndex_i=min(get(handles.MinIndex_i,'Data'));
1134MaxIndex_i=max(get(handles.MaxIndex_i,'Data'));
1135pos_first=(ref_i_1-MinIndex_i)/(MaxIndex_i-MinIndex_i+1);
1136pos_last=(ref_i_2-MinIndex_i+1)/(MaxIndex_i-MinIndex_i+1);
1137Position=get(handles.Waitbar,'Position');% position of the waitbar:= [ x,y, width, height]
1138Position_status=get(handles.FileStatus,'Position');
1139Position(1)=Position_status(1)+Position_status(3)*pos_first;
1140Position(3)=Position_status(3)*(pos_last-pos_first);
1141set(handles.Waitbar,'Position',Position)
1142update_waitbar(handles.Waitbar,0)
1143
1144%------------------------------------------------------------------------
1145% --- Executes when selected cell(s) is changed in PairString.
1146function PairString_CellSelectionCallback(hObject, eventdata, handles)
1147%------------------------------------------------------------------------   
1148if numel(eventdata.Indices)>=1
1149set(handles.ListView,'Value',eventdata.Indices(1))% detect the selected raw index
1150ListView_Callback ([],[],handles) % update the list of available pairs
1151end
1152
1153%------------------------------------------------------------------------
1154%------------------------------------------------------------------------
1155%  III - FUNCTIONS ASSOCIATED TO THE FRAME SET PAIRS
1156%------------------------------------------------------------------------
1157%------------------------------------------------------------------------
1158% --- Executes on selection change in ListView.
1159function ListView_Callback(hObject, eventdata, handles)
1160%------------------------------------------------------------------------   
1161SeriesData=get(handles.series,'UserData');
1162i2_series=[];
1163j2_series=[];
1164iview=get(handles.ListView,'Value');
1165if ~isempty(SeriesData.i2_series{iview})
1166    i2_series=SeriesData.i2_series{iview};
1167end
1168if ~isempty(SeriesData.j2_series{iview})
1169    j2_series=SeriesData.j2_series{iview};
1170end
1171update_mode(handles,SeriesData.i1_series{iview},SeriesData.i2_series{iview},...
1172    SeriesData.j1_series{iview},SeriesData.j2_series{iview},SeriesData.Time{iview})
1173
1174%------------------------------------------------------------------------
1175% --- Executes on button press in mode.
1176function mode_Callback(hObject, eventdata, handles)
1177%------------------------------------------------------------------------       
1178SeriesData=get(handles.series,'UserData');
1179iview=get(handles.ListView,'Value');
1180mode_list=get(handles.mode,'String');
1181mode=mode_list{get(handles.mode,'Value')};
1182if isequal(mode,'bursts')
1183    enable_i(handles,'On')
1184    enable_j(handles,'Off') %do not display j index scanning in burst mode (j is fixed by the burst choice)
1185else
1186    enable_i(handles,'On')
1187    enable_j(handles,'Off')
1188end
1189fill_ListPair(handles,SeriesData.i1_series{iview},SeriesData.i2_series{iview},...
1190    SeriesData.j1_series{iview},SeriesData.j2_series{iview},SeriesData.Time{iview})
1191ListPairs_Callback([],[],handles)
1192
1193%-------------------------------------------------------------
1194% --- Executes on selection in ListPairs.
1195function ListPairs_Callback(hObject,eventdata,handles)
1196%------------------------------------------------------------
1197list_pair=get(handles.ListPairs,'String');%get the menu of image pairs
1198if isempty(list_pair)
1199    string='';
1200else
1201    string=list_pair{get(handles.ListPairs,'Value')};
1202    string=regexprep(string,',.*','');%removes time indication (after ',')
1203end
1204PairString=get(handles.PairString,'Data');
1205iview=get(handles.ListView,'Value');
1206PairString{iview,1}=string;
1207% report the selected pair string to the table PairString
1208set(handles.PairString,'Data',PairString)
1209
1210%------------------------------------------------------------------------
1211function num_ref_i_Callback(hObject, eventdata, handles)
1212%------------------------------------------------------------------------
1213mode_list=get(handles.mode,'String');
1214mode=mode_list{get(handles.mode,'Value')};
1215SeriesData=get(handles.series,'UserData');
1216iview=get(handles.ListView,'Value');
1217fill_ListPair(handles,SeriesData.i1_series{iview},SeriesData.i2_series{iview},...
1218    SeriesData.j1_series{iview},SeriesData.j2_series{iview},SeriesData.Time{iview});% update the menu of pairs depending on the available netcdf files
1219ListPairs_Callback([],[],handles)
1220
1221%------------------------------------------------------------------------
1222function num_ref_j_Callback(hObject, eventdata, handles)
1223%------------------------------------------------------------------------
1224num_ref_i_Callback(hObject, eventdata, handles)
1225
1226%------------------------------------------------------------------------
1227function update_mode(handles,i1_series,i2_series,j1_series,j2_series,time)
1228%------------------------------------------------------------------------   
1229% check_burst=0;
1230if isempty(j2_series)% no j pair
1231    if isempty(i2_series)
1232        set(handles.mode,'Value',1)
1233        set(handles.mode,'String',{''})% no pair menu to display
1234    else   
1235        set(handles.mode,'Value',1)
1236        set(handles.mode,'String',{'series(Di)'}) % pair menu with only option Di
1237    end
1238else %existence of j pairs
1239    pair_max=squeeze(max(i1_series,[],1)); %max on pair index
1240    j_max=max(pair_max,[],1);
1241    MaxIndex_i=max(find(j_max))-1;% max ref index i
1242    MinIndex_i=min(find(j_max))-1;% min ref index i
1243    i_max=max(pair_max,[],2);
1244    MaxIndex_j=max(find(i_max))-1;% max ref index i
1245    MinIndex_j=min(find(i_max))-1;% min ref index i
1246    if MaxIndex_j==MinIndex_j
1247        set(handles.mode,'Value',1);
1248        set(handles.mode,'String',{'bursts'})
1249%         check_burst=1;
1250    elseif MaxIndex_i==MinIndex_i
1251        set(handles.mode,'Value',1);
1252        set(handles.mode,'String',{'series(Dj)'})
1253    else
1254        set(handles.mode,'String',{'bursts';'series(Dj)'})
1255        if (MaxIndex_j-MinIndex_j)>10
1256            set(handles.mode,'Value',2);%set mode to series(Dj) if more than 10 j values
1257        else
1258            set(handles.mode,'Value',1);
1259%             check_burst=1;
1260        end
1261    end
1262end
1263fill_ListPair(handles,i1_series,i2_series,j1_series,j2_series,time)
1264ListPairs_Callback([],[],handles)
1265
1266%--------------------------------------------------------------
1267% determine the menu for pairstring depending on existing netcdf files
1268% with the reference indices num_ref_i and num_ref_j
1269%----------------------------------------------------------------
1270function fill_ListPair(handles,i1_series,i2_series,j1_series,j2_series,time)
1271
1272mode_list=get(handles.mode,'String');
1273mode=mode_list{get(handles.mode,'Value')};
1274ref_i=str2num(get(handles.num_ref_i,'String'));
1275if isempty(ref_i)
1276    ref_i=1;
1277end
1278if strcmp(get(handles.num_ref_j,'Visible'),'on')
1279    ref_j=str2num(get(handles.num_ref_j,'String'));
1280    if isempty(ref_j)
1281        ref_j=1;
1282    end
1283else
1284    ref_j=1;
1285end
1286TimeUnit=get(handles.TimeUnit,'String');
1287if length(TimeUnit)>=1
1288    dtunit=['m' TimeUnit];
1289else
1290    dtunit='e-03';
1291end
1292
1293displ_pair={};
1294if strcmp(mode,'series(Di)')
1295    if isempty(i2_series)
1296        msgbox_uvmat('ERROR','no i1-i2 pair available')
1297        return
1298    end
1299    diff_i=i2_series-i1_series;
1300    min_diff=min(diff_i(diff_i>0));
1301    max_diff=max(diff_i(diff_i>0));
1302    for ipair=min_diff:max_diff
1303        if numel(diff_i(diff_i==ipair))>0
1304            pair_string=['Di= ' num2str(-floor(ipair/2)) '|' num2str(ceil(ipair/2)) ];
1305            if ~isempty(time)
1306                if ref_i<=floor(ipair/2)
1307                    ref_i=floor(ipair/2)+1;% shift ref_i to get the first pair
1308                end
1309                Dt=time(ref_i+ceil(ipair/2),ref_j)-time(ref_i-floor(ipair/2),ref_j);
1310                pair_string=[pair_string ', Dt=' num2str(Dt) ' ' dtunit];
1311            end
1312            displ_pair=[displ_pair;{pair_string}];
1313        end
1314    end
1315    if ~isempty(displ_pair)
1316        displ_pair=[displ_pair;{'Di=*|*'}];
1317    end
1318elseif strcmp(mode,'series(Dj)')
1319    if isempty(j2_series)
1320        msgbox_uvmat('ERROR','no j1-j2 pair available')
1321        return
1322    end
1323    diff_j=j2_series-j1_series;
1324    min_diff=min(diff_j(diff_j>0));
1325    max_diff=max(diff_j(diff_j>0));
1326    for ipair=min_diff:max_diff
1327        if numel(diff_j(diff_j==ipair))>0
1328            pair_string=['Dj= ' num2str(-floor(ipair/2)) '|' num2str(ceil(ipair/2)) ];
1329            if ~isempty(time)
1330                if ref_j<=floor(ipair/2)
1331                    ref_j=floor(ipair/2)+1;% shift ref_i to get the first pair
1332                end
1333                Dt=time(ref_i,ref_j+ceil(ipair/2))-time(ref_i,ref_j-floor(ipair/2));
1334                pair_string=[pair_string ', Dt=' num2str(Dt) ' ' dtunit];
1335            end
1336            displ_pair=[displ_pair;{pair_string}];
1337        end
1338    end
1339    if ~isempty(displ_pair)
1340        displ_pair=[displ_pair;{'Dj=*|*'}];
1341    end
1342elseif strcmp(mode,'bursts')
1343    if isempty(j2_series)
1344        msgbox_uvmat('ERROR','no j1-j2 pair available')
1345        return
1346    end
1347    diff_j=j2_series-j1_series;
1348    min_j1=min(j1_series(j1_series>0));
1349    max_j1=max(j1_series(j1_series>0));
1350    min_j2=min(j2_series(j2_series>0));
1351    max_j2=max(j2_series(j2_series>0));
1352    for pair1=min_j1:min(max_j1,min_j1+20)
1353        for pair2=min_j2:min(max_j2,min_j2+20)
1354        if numel(j1_series(j1_series==pair1))>0 && numel(j2_series(j2_series==pair2))>0
1355            displ_pair=[displ_pair;{['j= ' num2str(pair1) '-' num2str(pair2)]}];
1356        end
1357        end
1358    end
1359    if ~isempty(displ_pair)
1360        displ_pair=[displ_pair;{'j=*-*'}];
1361    end
1362end
1363set(handles.num_ref_i,'String',num2str(ref_i)) % update ref_i and ref_j
1364set(handles.num_ref_j,'String',num2str(ref_j))
1365
1366%% display list of pairstring
1367displ_pair_list=get(handles.ListPairs,'String');
1368NewVal=[];
1369if ~isempty(displ_pair_list)
1370Val=get(handles.ListPairs,'Value');
1371NewVal=find(strcmp(displ_pair_list{Val},displ_pair),1);% look at the previous display in the new menu displ_pï¿œir
1372end
1373if ~isempty(NewVal)
1374    set(handles.ListPairs,'Value',NewVal)
1375else
1376    set(handles.ListPairs,'Value',1)
1377end
1378set(handles.ListPairs,'String',displ_pair)
1379
1380%-------------------------------------
1381function enable_i(handles,state)
1382set(handles.i_txt,'Visible',state)
1383set(handles.num_first_i,'Visible',state)
1384set(handles.num_last_i,'Visible',state)
1385set(handles.num_incr_i,'Visible',state)
1386set(handles.num_ref_i,'Visible',state)
1387set(handles.ref_i_text,'Visible',state)
1388
1389%-----------------------------------
1390function enable_j(handles,state)
1391set(handles.j_txt,'Visible',state)
1392set(handles.num_first_j,'Visible',state)
1393set(handles.num_last_j,'Visible',state)
1394set(handles.num_incr_j,'Visible',state)
1395set(handles.num_ref_j,'Visible',state)
1396set(handles.ref_j_text,'Visible',state)
1397set(handles.MinIndex_j,'Visible',state)
1398set(handles.MaxIndex_j,'Visible',state)
1399
1400
1401%%%%%%%%%%%%%%%%%%%%
1402%%  MAIN ActionName FUNCTIONS
1403%%%%%%%%%%%%%%%%%%%%
1404%------------------------------------------------------------------------
1405% --- Executes on button press in RUN.
1406%------------------------------------------------------------------------
1407function RUN_Callback(hObject, eventdata, handles)
1408
1409%% settings of the button RUN
1410set(handles.RUN,'BusyAction','queue');% activation of STOP button will set BusyAction to 'cancel'
1411set(handles.RUN, 'Enable','Off')% avoid further RUN action until the current one is finished
1412set(handles.RUN,'BackgroundColor',[1 1 0])%show activation of RUN by yellow color
1413drawnow
1414set(handles.status,'Value',0)% desable status display if relevant
1415status_Callback(hObject, eventdata, handles)
1416
1417%% read the data on the GUI series
1418Param=read_GUI_series(handles);%displayed parameters
1419SeriesData=get(handles.series,'UserData');%hidden parameters
1420
1421%% create the output data directory if needed
1422if isfield(Param,'OutputSubDir')
1423    SubDirOut=[get(handles.OutputSubDir,'String') Param.OutputDirExt];
1424    SubDirOutNew=SubDirOut;
1425    detect=exist(fullfile(Param.InputTable{1,1},SubDirOutNew),'dir');% test if  the dir  already exist
1426    check_create=1; %need to create the result directory by default
1427    while detect
1428        answer=msgbox_uvmat('INPUT_Y-N',['use existing ouput directory: ' fullfile(Param.InputTable{1,1},SubDirOutNew) ', possibly delete previous data']);
1429        if strcmp(answer,'Cancel')
1430            errormsg='Cancel';
1431            return
1432        elseif strcmp(answer,'Yes')
1433            detect=0;
1434            check_create=0;
1435        else
1436            r=regexp(SubDirOutNew,'(?<root>.*\D)(?<num1>\d+)$','names');%detect whether name ends by a number
1437            if isempty(r)
1438                r(1).root=[SubDirOutNew '_'];
1439                r(1).num1='0';
1440            end
1441            SubDirOutNew=[r(1).root num2str(str2num(r(1).num1)+1)];%increment the index by 1 or put 1
1442            detect=exist(fullfile(Param.InputTable{1,1},SubDirOutNew),'dir');% test if  the dir  already exists
1443            check_create=1;
1444        end
1445    end
1446    Param.OutputDirExt=regexprep(SubDirOutNew,Param.OutputSubDir,'');
1447    Param.OutputRootFile=Param.InputTable{1,3};% the first sorted RootFile taken for output
1448    set(handles.OutputDirExt,'String',Param.OutputDirExt)
1449    OutputDir=fullfile(Param.InputTable{1,1},[Param.OutputSubDir Param.OutputDirExt]);% full name (with path) of output directory
1450    if check_create    % create output directory if it does not exist
1451        [tild,msg1]=mkdir(OutputDir);
1452        if ~strcmp(msg1,'')
1453            msgbox_uvmat('ERROR',['cannot create ' OutputDir ': ' msg1]);%error message for directory creation
1454            return
1455        end
1456        [success,msg] = fileattrib(OutputDir,'+w','g','s');% allow writing access for the group of users, recursively in the folder 
1457        if success==0
1458            msgbox_uvmat('WARNING',{['unable to set group write access to ' OutputDir ':']; msg1});%error message for directory creation
1459            return
1460        end
1461    end
1462    OutputNomType=nomtype2pair(Param.InputTable{1,4});% nomenclature for output files
1463    DirXml=fullfile(OutputDir,'0_XML');
1464    if ~exist(DirXml,'dir')
1465        [tild,msg1]=mkdir(DirXml);
1466        if ~strcmp(msg1,'')
1467            msgbox_uvmat('ERROR',['cannot create ' DirXml ': ' msg1]);%error message for directory creation
1468            return
1469        end
1470                [success,msg] = fileattrib(DirXml,'+w','g','s');% allow writing access for the group of users, recursively in the folder 
1471        if success==0
1472            msgbox_uvmat('WARNING',{['unable to set group write access to ' DirXml ':']; msg1});%error message for directory creation
1473            return
1474        end
1475    end
1476end
1477
1478%% select the Action mode, 'local', 'background' or 'cluster' (if available)
1479RunMode='local';%default (needed for first opening of the GUI series)
1480if isfield(Param.Action,'RunMode')
1481    RunMode=Param.Action.RunMode;
1482end
1483ActionExt='.m';%default
1484if isfield(Param.Action,'ActionExt')
1485    ActionExt=Param.Action.ActionExt;% '.m' or '.sh' (compiled)
1486end
1487ActionName=Param.Action.ActionName;
1488ActionPath=Param.Action.ActionPath;
1489path_series=fileparts(which('series'));
1490
1491%% create the Action fct handle if RunMode option = 'local'
1492if strcmp(RunMode,'local')
1493    if ~isequal(ActionPath,path_series)
1494        eval(['spath=which(''' ActionName ''');']) %spath = current path of the selected function ACTION
1495        if ~exist(ActionPath,'dir')
1496            msgbox_uvmat('ERROR',['The prescribed function path ' ActionPath ' does not exist']);
1497            return
1498        end
1499        if ~isequal(spath,ActionPath)
1500            addpath(ActionPath)% add the prescribed path if not the current one
1501        end
1502    end
1503    eval(['h_fun=@' ActionName ';'])%create a function handle for ACTION
1504    if ~isequal(ActionPath,path_series)
1505        rmpath(ActionPath)% add the prescribed path if not the current one
1506    end
1507end
1508
1509%% Get RunTime code from the file PARAM.xml (needed to run compiled functions)
1510errormsg='';%default error message
1511xmlfile=fullfile(path_series,'PARAM.xml');
1512test_batch=0;%default: ,no batch mode available
1513if ~exist(xmlfile,'file')
1514    [success,message]=copyfile(fullfile(path_series,'PARAM.xml.default'),xmlfile);
1515end
1516RunTime='';
1517if strcmp(ActionExt,'.sh')
1518    if exist(xmlfile,'file')
1519        s=xml2struct(xmlfile);
1520        if strcmp(RunMode,'cluster_oar') && isfield(s,'BatchParam')
1521            if isfield(s.BatchParam,'RunTime')
1522                RunTime=s.BatchParam.RunTime;
1523            end
1524            if isfield(s.BatchParam,'NbCore')
1525                NbCore=s.BatchParam.NbCore;
1526            end
1527        elseif (strcmp(RunMode,'background')||strcmp(RunMode,'local')) && isfield(s,'RunParam')
1528            if isfield(s.RunParam,'RunTime')
1529                RunTime=s.RunParam.RunTime;
1530            end
1531            if isfield(s.RunParam,'NbCore')
1532                NbCore=s.RunParam.NbCore;
1533            end
1534        end
1535    end
1536    if isempty(RunTime) && strcmp(RunMode,'cluster_oar')
1537        msgbox_uvmat('ERROR','RunTime name not found in PARAM.xml, compiled version .sh cannot run on cluster')
1538        return
1539    end
1540end
1541
1542%% set nbre of cluster cores and processes
1543switch RunMode
1544    case {'local','background'}
1545        NbCore=1;% no need to split the calculation
1546    case 'cluster_oar'
1547        if strcmp(Param.Action.ActionExt,'.m')% case of Matlab function (uncompiled)
1548            NbCore=1;% one core used only (limitation of Matlab licences)
1549            msgbox_uvmat('WARNING','Number of cores =1: select the compiled version civ_matlab.sh for multi-core processing');
1550            extra_oar='';
1551        else
1552            answer=inputdlg({'Number of cores (max 36)','extra oar options'},'oarsub parameter',1,{'12',''});
1553            NbCore=str2double(answer{1});
1554            extra_oar=answer{2};
1555        end
1556end
1557if ~isfield(Param.IndexRange,'NbSlice')
1558    Param.IndexRange.NbSlice=[];
1559end
1560if isempty(Param.IndexRange.NbSlice)
1561    NbProcess=NbCore;% choose one process per core
1562else
1563    NbProcess=Param.IndexRange.NbSlice;% the nbre of run processes is equal to the number of slices
1564    NbCore=min(NbCore,NbProcess);% at least one process per core
1565end
1566       
1567%% get the set of reference field indices
1568first_i=1;
1569last_i=1;
1570incr_i=1;
1571first_j=1;
1572last_j=1;
1573incr_j=1;
1574if isfield(Param.IndexRange,'first_i')
1575    first_i=Param.IndexRange.first_i;
1576    incr_i=Param.IndexRange.incr_i;
1577    last_i=Param.IndexRange.last_i;
1578end
1579if isfield(Param.IndexRange,'first_j')
1580    first_j=Param.IndexRange.first_j;
1581    last_j=Param.IndexRange.last_j;
1582    incr_j=Param.IndexRange.incr_j;
1583end
1584if last_i < first_i || last_j < first_j
1585    msgbox_uvmat('ERROR', 'series/Run_Callback:last field index must be larger or equal to the first one')
1586    set(handles.RUN, 'Enable','On'),
1587    set(handles.RUN,'BackgroundColor',[1 0 0])
1588    return
1589end
1590%incr_i must be defined, =1 by default, if NbSlice is active
1591if isempty(incr_i)&& ~isempty(Param.IndexRange.NbSlice)
1592    incr_i=1;
1593    set(handles.num_incr_i,'String','1')
1594end
1595if isempty(incr_i)
1596    if isempty(incr_j)
1597        [ref_j,ref_i]=find(squeeze(SeriesData.i1_series{1}(1,:,:)));
1598        ref_j=ref_j(ref_j>=first_j & ref_j<=last_j);
1599        ref_i=ref_i(ref_i>=first_i & ref_i<=last_i);
1600        ref_j=ref_j-1;
1601        ref_i=ref_i-1;
1602    else
1603        ref_j=first_j:incr_j:last_j;
1604        [tild,ref_i]=find(squeeze(SeriesData.i1_series{1}(1,:,:)));
1605        ref_i=ref_i-1;
1606        ref_i=ref_i(ref_i>=first_i & ref_i<=last_i);
1607    end
1608else
1609    ref_i=first_i:incr_i:last_i;
1610    if isempty(incr_j)
1611    [ref_j,tild]=find(squeeze(SeriesData.i1_series{1}(1,:,:)));
1612    ref_j=ref_j-1;
1613    ref_j=ref_j(ref_j>=first_j & ref_j<=last_j);
1614    else
1615        ref_j=first_j:incr_j:last_j;
1616    end
1617end
1618BlockLength=ceil(numel(ref_i)/NbProcess);
1619nbfield_j=numel(ref_j);
1620
1621%% record nbre of output files and starting time for computation for status
1622StatusData=get(handles.status,'UserData');
1623if isfield(StatusData,'OutputFileMode')
1624    switch StatusData.OutputFileMode
1625        case 'NbInput'
1626            StatusData.NbOutputFile=numel(ref_i)*nbfield_j;
1627        case 'NbInput_i'
1628            StatusData.NbOutputFile=numel(ref_i);
1629        case 'NbSlice'   
1630            StatusData.NbOutputFile=str2num(get(handles.num_NbSlice,'String'));
1631    end
1632end
1633StatusData.TimeStart=now;
1634set(handles.status,'UserData',StatusData)
1635
1636%% direct processing on the current Matlab session
1637if strcmp (RunMode,'local')
1638    for iprocess=1:NbProcess
1639        if isempty(Param.IndexRange.NbSlice)
1640            %Param.IndexRange.first_i=first_i+(iprocess-1)*BlockLength*incr_i;
1641            Param.IndexRange.first_i=ref_i(1+(iprocess-1)*BlockLength);
1642            if Param.IndexRange.first_i>last_i
1643                break
1644            end
1645            Param.IndexRange.last_i=min(ref_i(iprocess*BlockLength),last_i);
1646            %Param.IndexRange.last_i=min(first_i+(iprocess)*BlockLength*incr_i-1,last_i);
1647        else %multislices (then incr_i is not empty)
1648             Param.IndexRange.first_i= first_i+incr_i*(iprocess-1);
1649             Param.IndexRange.incr_i=incr_i*Param.IndexRange.NbSlice;
1650        end
1651        if isfield(Param,'OutputSubDir')
1652        t=struct2xml(Param);
1653        t=set(t,1,'name','Series');
1654        filexml=fullfile_uvmat(DirXml,'',Param.InputTable{1,3},'.xml',OutputNomType,...
1655            Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1656        save(t,filexml);
1657        end
1658        switch ActionExt
1659            case '.m'
1660                h_fun(Param);
1661            case '.sh'
1662                switch computer
1663                    case {'PCWIN','PCWIN64'} %Windows system
1664                        filexml=regexprep(filexml,'\\','\\\\');% add '\' so that '\' are left as characters
1665                        system([fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml]);% TODO: adapt to DOS system
1666                    case {'GLNX86','GLNXA64','MACI64'}%Linux  system
1667                        system([fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml]);
1668                end
1669        end
1670    end
1671elseif strcmp(get(handles.OutputDirExt,'Visible'),'off')
1672    msgbox_uvmat('ERROR',['no output file for Action ' ActionName ', use run mode = local']);% a output dir is needed for background option
1673    return
1674else
1675    %% processing on a different session of the same computer (background) or cluster, create executable files
1676    batch_file_list=cell(NbProcess,1);% initiate the list of executable files
1677    DirBat=fullfile(OutputDir,'0_EXE');
1678    switch computer
1679        case {'PCWIN','PCWIN64'} %Windows system
1680            ExeExt='.bat';
1681        case {'GLNX86','GLNXA64','MACI64'}%Linux  system
1682           ExeExt='.sh';
1683    end
1684    %create subdirectory for executable files
1685    if ~exist(DirBat,'dir')
1686        [tild,msg1]=mkdir(DirBat);
1687        if ~strcmp(msg1,'')
1688            msgbox_uvmat('ERROR',['cannot create ' DirBat ': ' msg1]);%error message for directory creation
1689            return
1690        end
1691    end
1692    %create subdirectory for log files
1693    DirLog=fullfile(OutputDir,'0_LOG');
1694    if ~exist(DirLog,'dir')
1695        [tild,msg1]=mkdir(DirLog);
1696        if ~strcmp(msg1,'')
1697            msgbox_uvmat('ERROR',['cannot create ' DirLog ': ' msg1]);%error message for directory creation
1698            return
1699        end
1700    end
1701    for iprocess=1:NbProcess
1702        if isempty(Param.IndexRange.NbSlice)% process by blocks of i index
1703            Param.IndexRange.first_i=first_i+(iprocess-1)*BlockLength*incr_i;
1704            if Param.IndexRange.first_i>last_i
1705                NbProcess=iprocess-1;
1706                break% leave the loop, we are at the end of the calculation
1707            end
1708            Param.IndexRange.last_i=min(last_i,first_i+(iprocess)*BlockLength*incr_i-1);
1709        else% process by slices of i index if NbSlice is defined, computation in a single process if NbSlice =1
1710            Param.IndexRange.first_i= first_i+iprocess-1;
1711            Param.IndexRange.incr_i=incr_i*Param.IndexRange.NbSlice;
1712        end
1713       
1714        % create, fill and save the xml parameter file
1715        t=struct2xml(Param);
1716        t=set(t,1,'name','Series');
1717        filexml=fullfile_uvmat(DirXml,'',Param.InputTable{1,3},'.xml',OutputNomType,...
1718            Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1719        save(t,filexml);% save the parameter file
1720       
1721        %create the executable file
1722         filebat=fullfile_uvmat(DirBat,'',Param.InputTable{1,3},ExeExt,OutputNomType,...
1723           Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1724        batch_file_list{iprocess}=filebat;
1725        [fid,message]=fopen(filebat,'w');% create the executable file
1726        if isequal(fid,-1)
1727            msgbox_uvmat('ERROR', ['creation of .bat file: ' message]);
1728            return
1729        end
1730       
1731        % set the log file name
1732        filelog=fullfile_uvmat(DirLog,'',Param.InputTable{1,3},'.log',OutputNomType,...
1733            Param.IndexRange.first_i,Param.IndexRange.last_i,first_j,last_j);
1734       
1735        % fill and save the executable file
1736        switch ActionExt
1737            case '.m'% Matlab function
1738                switch computer
1739                    case {'GLNX86','GLNXA64','MACI64'}
1740                        cmd=[...
1741                            '#!/bin/bash \n'...
1742                            '. /etc/sysprofile \n'...
1743                            'matlab -nodisplay -nosplash -nojvm -logfile ''' filelog ''' <<END_MATLAB \n'...
1744                            'addpath(''' path_series '''); \n'...
1745                            'addpath(''' Param.Action.ActionPath '''); \n'...
1746                            '' Param.Action.ActionName  '( ''' filexml '''); \n'...
1747                            'exit \n'...
1748                            'END_MATLAB \n'];
1749                        fprintf(fid,cmd);%fill the executable file with the  char string cmd
1750                        fclose(fid);% close the executable file
1751                        system(['chmod +x ' filebat]);% set the file to executable
1752                    case {'PCWIN','PCWIN64'}
1753                        text_matlabscript=['matlab -automation -logfile ' regexprep(filelog,'\\','\\\\')...
1754                            ' -r "addpath(''' regexprep(path_series,'\\','\\\\') ''');'...
1755                            'addpath(''' regexprep(Param.Action.ActionPath,'\\','\\\\') ''');'...
1756                            '' Param.Action.ActionName  '( ''' regexprep(filexml,'\\','\\\\') ''');exit"'];
1757                        fprintf(fid,text_matlabscript);%fill the executable file with the  char string cmd
1758                        fclose(fid);% close the executable file
1759                end
1760            case '.sh' % compiled Matlab function
1761                switch computer
1762                    case {'GLNX86','GLNXA64','MACI64'}
1763                        cmd=['#!/bin/bash \n '...
1764                            '#$ -cwd \n '...
1765                            'hostname && date \n '...
1766                            'umask 002 \n'...
1767                            fullfile(ActionPath,[ActionName '.sh']) ' ' RunTime ' ' filexml];%allow writting access to created files for user group
1768                        fprintf(fid,cmd);%fill the executable file with the  char string cmd
1769                        fclose(fid);% close the executable file
1770                        system(['chmod +x ' filebat]);% set the file to executable
1771                       
1772                    case {'PCWIN','PCWIN64'}    %       TODO: adapt to Windows system
1773                        %                                 cmd=['matlab -automation -logfile ' regexprep(filelog,'\\','\\\\')...
1774                        %                                     ' -r "addpath(''' regexprep(path_series,'\\','\\\\') ''');'...
1775                        %                                     'addpath(''' regexprep(Param.Action.ActionPath,'\\','\\\\') ''');'...
1776                        %                                     '' Param.Action.ActionName  '( ''' regexprep(filexml,'\\','\\\\') ''');exit"'];
1777                        fprintf(fid,cmd);
1778                        fclose(fid);
1779                        %                               dos([filebat ' &']);
1780                end
1781        end
1782    end
1783end
1784
1785%% launch the executable files for background or cluster processing
1786switch RunMode
1787    case 'background'
1788        for iprocess=1:NbProcess
1789            system([batch_file_list{iprocess} ' &'])% directly execute the command file for each process
1790            msgbox_uvmat('CONFIRMATION',[ActionName 'launched in background: press STATUS to see results'])
1791        end
1792    case 'cluster_oar' % option 'oar-parexec' used
1793        %create subdirectory for oar command and log files
1794        DirOAR=fullfile(OutputDir,'0_OAR');
1795        if exist(DirOAR,'dir')% delete the content of the dir 0_OAR to allow new input
1796            curdir=pwd;
1797            cd(DirOAR)
1798            delete('*')
1799            cd(curdir)
1800        else
1801            [tild,msg1]=mkdir(DirOAR);
1802            if ~strcmp(msg1,'')
1803                msgbox_uvmat('ERROR',['cannot create ' DirOAR ': ' msg1]);%error message for directory creation
1804                return
1805            end
1806        end
1807        max_walltime=3600*12; % 12h max total calculation
1808        walltime_onejob=600;%seconds, max estimated time for asingle file index value
1809        filename_joblist=fullfile(DirOAR,'job_list.txt');%create name of the global executable file
1810        fid=fopen(filename_joblist,'w');
1811        for p=1:length(batch_file_list)
1812            fprintf(fid,[batch_file_list{p} '\n']);% list of exe files
1813        end
1814        fclose(fid);
1815        system(['chmod +x ' filename_joblist]);% set the file to executable
1816        oar_command=['oarsub -n CIVX '...
1817            '-t idempotent --checkpoint ' num2str(walltime_onejob+60) ' '...
1818            '-l /core=' num2str(NbCore) ','...
1819            'walltime=' datestr(min(1.05*walltime_onejob/86400*max(NbProcess*BlockLength*nbfield_j,NbCore)/NbCore,max_walltime/86400),13) ' '...
1820            '-E ' regexprep(filename_joblist,'\.txt\>','.stderr') ' '...
1821            '-O ' regexprep(filename_joblist,'\.txt\>','.stdout') ' '...
1822            extra_oar ' '...
1823            '"oar-parexec -s -f ' filename_joblist ' '...
1824            '-l ' filename_joblist '.log"\n'];
1825        filename_oarcommand=fullfile(DirOAR,'oar_command');
1826        fid=fopen(filename_oarcommand,'w');
1827        fprintf(fid,oar_command);
1828        fclose(fid);
1829        fprintf(oar_command);% display in command line
1830        system(oar_command); 
1831        msgbox_uvmat('CONFIRMATION',[ActionName ' launched in cluster: press STATUS to see results'])
1832end
1833
1834%% reset the GUI series
1835update_waitbar(handles.Waitbar,1); % put the waitbar to end position to indicate launching is finished
1836set(handles.RUN, 'Enable','On')
1837set(handles.RUN,'BackgroundColor',[1 0 0])
1838set(handles.RUN, 'Value',0)
1839
1840%------------------------------------------------------------------------
1841function STOP_Callback(hObject, eventdata, handles)
1842%------------------------------------------------------------------------
1843set(handles.RUN, 'BusyAction','cancel')
1844set(handles.RUN,'BackgroundColor',[1 0 0])
1845set(handles.RUN,'enable','on')
1846set(handles.RUN, 'Value',0)
1847
1848
1849%------------------------------------------------------------------------
1850% --- read parameters from the GUI series
1851%------------------------------------------------------------------------
1852function Param=read_GUI_series(handles)
1853
1854%% read raw parameters from the GUI series
1855Param=read_GUI(handles.series);
1856
1857%% clean the output structure by removing unused information
1858if isfield(Param,'Pairs')
1859    Param=rmfield(Param,'Pairs'); %info Pairs not needed for output
1860end
1861Param.IndexRange=rmfield(Param.IndexRange,'TimeTable');
1862empty_line=false(size(Param.InputTable,1),1);
1863for iline=1:size(Param.InputTable,1)
1864    empty_line(iline)=isempty(cell2mat(Param.InputTable(iline,1:3)));
1865end
1866Param.InputTable(empty_line,:)=[];
1867
1868%------------------------------------------------------------------------
1869% --- Executes on selection change in ActionName.
1870function ActionName_Callback(hObject, eventdata, handles)
1871%------------------------------------------------------------------------
1872
1873%% stop any ongoing series processing
1874if isequal(get(handles.RUN,'Value'),1)
1875    answer= msgbox_uvmat('INPUT_Y-N','stop current Action process?');
1876    if strcmp(answer,'Yes')
1877        STOP_Callback(hObject, eventdata, handles)
1878    else
1879        return
1880    end
1881end
1882set(handles.ActionName,'BackgroundColor',[1 1 0])
1883huigetfile=findobj(allchild(0),'tag','status_display');
1884if ~isempty(huigetfile)
1885    delete(huigetfile)
1886end
1887drawnow
1888
1889%% get Action name and path
1890nb_builtin_ACTION=4; %nbre of functions initially proposed in the menu ActionName (as defined in the Opening fct of series)
1891ActionList=get(handles.ActionName,'String');% list menu fields
1892ActionIndex=get(handles.ActionName,'Value');
1893if ~isequal(ActionIndex,1)% if we are not just opening series
1894    InputTable=get(handles.InputTable,'Data');
1895    if isempty(InputTable{1,4})
1896        msgbox_uvmat('ERROR','no input file available: use Open in the menu bar')
1897        return
1898    end
1899end
1900ActionName= ActionList{get(handles.ActionName,'Value')}; % selected function name
1901ActionPathList=get(handles.ActionName,'UserData');%list of recorded paths to functions of the list ActionName
1902
1903%% add a new function to the menu if 'more...' has been selected in the menu ActionName
1904if isequal(ActionName,'more...')
1905    [FileName, PathName] = uigetfile( ...
1906        {'*.m', ' (*.m)';
1907        '*.m',  '.m files '; ...
1908        '*.*', 'All Files (*.*)'}, ...
1909        'Pick a series processing function ',get(handles.ActionPath,'String'));
1910    if length(FileName)<2
1911        return
1912    end
1913    [ActionPath,ActionName,ActionExt]=fileparts(FileName);
1914   
1915    % insert the choice in the menu ActionName
1916    ActionIndex=find(strcmp(ActionName,ActionList),1);% look for the selected function in the menu Action
1917    if isempty(ActionIndex)%the input string does not exist in the menu
1918        ActionIndex= length(ActionList);
1919        ActionList=[ActionList(1:end-1);{ActionName};ActionList(end)];% the selected function is appended in the menu, before the last item 'more...'
1920        set(handles.ActionName,'String',ActionList)
1921    end
1922   
1923    % record the file extension and extend the path list if it is a new extension
1924    ActionExtList=get(handles.ActionExt,'String');
1925    ActionExtIndex=find(strcmp(ActionExt,ActionExtList), 1);
1926    if isempty(ActionExtIndex)
1927        set(handles.ActionExt,'String',[ActionExtList;{ActionExt}])
1928        ActionExtIndex=numel(ActionExtList)+1;
1929        ActionPathNew=cell(size(ActionPathList,1),1);%new column of ActionPath
1930        ActionPathList=[ActionPathList ActionPathNew];
1931    end
1932    set(handles.ActionName,'UserData',ActionPathList);
1933
1934    % remove old Action options in the menu (keeping a menu length <nb_builtin_ACTION+5)
1935    if length(ActionList)>nb_builtin_ACTION+5; %nb_builtin=nbre of functions always remaining in the initial menu
1936        nbremove=length(ActionList)-nb_builtin_ACTION-5;
1937        ActionList(nb_builtin_ACTION+1:end-5)=[];
1938        ActionPathList(nb_builtin_ACTION+1:end-4,:)=[];
1939        ActionIndex=ActionIndex-nbremove;
1940    end
1941   
1942    % record action menu, choice and path
1943    set(handles.ActionName,'Value',ActionIndex)
1944    set(handles.ActionName,'String',ActionList)
1945    set(handles.ActionExt,'Value',ActionExtIndex)
1946    ActionPathList{ActionIndex,ActionExtIndex}=PathName;
1947       
1948    %record the user defined menu additions in personal file profil_perso
1949    dir_perso=prefdir;
1950    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
1951    if nb_builtin_ACTION+1<=numel(ActionList)-1
1952        ActionListUser=ActionList(nb_builtin_ACTION+1:numel(ActionList)-1);
1953        ActionPathListUser=ActionPathList(nb_builtin_ACTION+1:numel(ActionList)-1,:);
1954        ActionExtListUser={};
1955        if numel(ActionExtList)>2
1956            ActionExtListUser=ActionExtList(3:end);
1957        end
1958        if exist(profil_perso,'file')
1959            save(profil_perso,'ActionListUser','ActionPathListUser','ActionExtListUser','-append')
1960        else
1961            save(profil_perso,'ActionListUser','ActionPathListUser','ActionExtListUser','-V6')
1962        end
1963    end
1964end
1965
1966%% check the current ActionPath to the selected function
1967ActionPath=ActionPathList{ActionIndex};%current recorded path
1968set(handles.ActionPath,'String',ActionPath); %show the path to the senlected function
1969
1970%% reinitialise the waitbar
1971update_waitbar(handles.Waitbar,0)
1972
1973%% create the function handle for Action
1974path_series=which('series');
1975if ~isequal(ActionPath,path_series)
1976    eval(['spath=which(''' ActionName ''');']) %spath = current path of the selected function ACTION
1977    if ~exist(ActionPath,'dir')
1978        errormsg=['The prescribed function path ' ActionPath ' does not exist'];
1979        return
1980    end
1981    if ~isequal(spath,ActionPath)
1982        addpath(ActionPath)% add the prescribed path if not the current one
1983    end
1984end
1985eval(['h_fun=@' ActionName ';'])%create a function handle for ACTION
1986if ~isequal(ActionPath,path_series)
1987        rmpath(ActionPath)% add the prescribed path if not the current one   
1988end
1989
1990%% Activate the Action fct
1991Param=read_GUI_series(handles);% read the parameters from the GUI series
1992ParamOut=h_fun(Param);%run the selected Action function to get the relevant input
1993
1994%% Put the first line of the selected Action fct as tooltip help
1995try
1996    [fid,errormsg] =fopen([ActionName '.m']);
1997    InputText=textscan(fid,'%s',1,'delimiter','\n');
1998    fclose(fid);
1999    set(handles.ActionName,'ToolTipString',InputText{1}{1})% put the first line of the selected function as tooltip help
2000end
2001
2002%% Detect the types of input files
2003SeriesData=get(handles.series,'UserData');
2004iview_civ=[];nb_netcdf=0;
2005if ~isempty(SeriesData)&&isfield(SeriesData,'FileType')
2006    iview_civ=find(strcmp('civx',SeriesData.FileType)|strcmp('civdata',SeriesData.FileType));
2007    nb_netcdf=numel(find(strcmp('netcdf',SeriesData.FileType)));
2008end
2009if numel(iview_civ)>=1
2010    menu=set_veltype_display(SeriesData.FileInfo{iview_civ(1)}.CivStage,SeriesData.FileType{iview_civ(1)});
2011    set(handles.VelType,'String',[{'*'};menu])
2012    if numel(iview_civ)>=2
2013        menu=set_veltype_display(SeriesData.FileInfo{iview_civ(2)}.CivStage,SeriesData.FileType{iview_civ(2)});
2014        set(handles.VelType_1,'String',[{'*'};menu])
2015    end
2016end       
2017
2018%% Check whether alphabetical sorting of input Subdir is allowed by the Action fct  (for multiples series entries)
2019if isfield(ParamOut,'AllowInputSort')&&isequal(ParamOut.AllowInputSort,'on')&& size(Param.InputTable,1)>1
2020    [tild,iview]=sort(InputTable(:,2)); %subdirectories sorted in alphabetical order
2021    set(handles.InputTable,'Data',InputTable(iview,:));
2022    MinIndex_i=get(handles.MinIndex_i,'Data');
2023    MinIndex_j=get(handles.MinIndex_j,'Data');
2024    MaxIndex_i=get(handles.MaxIndex_i,'Data');
2025    MaxIndex_j=get(handles.MaxIndex_j,'Data');
2026    set(handles.MinIndex_i,'Data',MinIndex_i(iview,:));
2027    set(handles.MinIndex_j,'Data',MinIndex_j(iview,:));
2028    set(handles.MaxIndex_i,'Data',MaxIndex_i(iview,:));
2029    set(handles.MaxIndex_j,'Data',MaxIndex_j(iview,:));
2030    TimeTable=get(handles.TimeTable,'Data');
2031    set(handles.TimeTable,'Data',TimeTable(iview,:));
2032    PairString=get(handles.PairString,'Data');
2033    set(handles.PairString,'Data',PairString(iview,:));
2034end
2035
2036%% Impose the whole input file index range if requested
2037if isfield(ParamOut,'WholeIndexRange')&&isequal(ParamOut.WholeIndexRange,'on')
2038    MinIndex_i=get(handles.MinIndex_i,'Data');
2039    MinIndex_j=get(handles.MinIndex_j,'Data');
2040    MaxIndex_i=get(handles.MaxIndex_i,'Data');
2041    MaxIndex_j=get(handles.MaxIndex_j,'Data');
2042    set(handles.num_first_i,'String',num2str(MinIndex_i(1)))% set first as the min index (for the first line)
2043    set(handles.num_last_i,'String',num2str(MaxIndex_i(1)))% set last as the max index (for the first line)
2044    set(handles.num_incr_i,'String','1')
2045    set(handles.num_first_j,'String',num2str(MinIndex_j(1)))% set first as the min index (for the first line)
2046    set(handles.num_last_j,'String',num2str(MaxIndex_j(1)))% set last as the max index (for the first line)
2047    set(handles.num_incr_j,'String','1')
2048else  % check index ranges
2049    first_i=1;last_i=1;first_j=1;last_j=1;
2050    if isfield(Param.IndexRange,'first_i')
2051        first_i=Param.IndexRange.first_i;
2052       % incr_i=Param.IndexRange.incr_i;
2053        last_i=Param.IndexRange.last_i;
2054    end
2055    if isfield(Param.IndexRange,'first_j')
2056        first_j=Param.IndexRange.first_j;
2057       % incr_j=Param.IndexRange.incr_j;
2058        last_j=Param.IndexRange.last_j;
2059    end
2060    if last_i < first_i || last_j < first_j , msgbox_uvmat('ERROR','last field number must be larger than the first one'),...
2061            set(handles.RUN, 'Enable','On'), set(handles.RUN,'BackgroundColor',[1 0 0]),return,end;
2062end
2063
2064%% desable j index if if set by the civ_input GUI
2065if isfield(ParamOut,'Desable_j_index')&&isequal(ParamOut.Desable_j_index,'on')
2066    set(handles.num_first_j,'Enable','off')
2067    set(handles.num_last_j,'Enable','off')
2068    set(handles.num_incr_j,'Enable','off')
2069    set(handles.num_incr_j,'String','')
2070else
2071   set(handles.num_first_j,'Enable','on')
2072    set(handles.num_last_j,'Enable','on')
2073    set(handles.num_incr_j,'Enable','on')
2074end
2075
2076%% NbSlice visibility
2077NbSliceVisible='off';%default
2078if isfield(ParamOut,'NbSlice') && isequal(ParamOut.NbSlice,'on')
2079    NbSliceVisible='on';
2080    set(handles.num_NbProcess,'String',get(handles.num_NbSlice,'String'))% the nbre of processes is imposed as the nbre of slices
2081else
2082    set(handles.num_NbProcess,'String','')% free nbre of processes
2083end
2084set(handles.num_NbSlice,'Visible',NbSliceVisible)
2085set(handles.NbSlice_title,'Visible',NbSliceVisible)
2086
2087%% Visibility of VelType and VelType_1 menus
2088VelTypeVisible='off';  %hidden by default
2089VelType_1Visible='off';
2090InputFieldsVisible='off';%visibility of the frame Fields
2091if isfield(ParamOut,'VelType')
2092    if strcmp( ParamOut.VelType,'on')||strcmp(ParamOut.VelType,'one')||strcmp( ParamOut.VelType,'two')
2093        if numel(iview_civ)>=1
2094            VelTypeVisible='on';
2095            InputFieldsVisible='on';
2096        end
2097    end
2098    if strcmp( ParamOut.VelType,'two')
2099        if numel(iview_civ)>=2
2100            VelType_1Visible='on';
2101        end
2102    end
2103end
2104set(handles.VelType,'Visible',VelTypeVisible)
2105set(handles.VelType_text,'Visible',VelTypeVisible);
2106set(handles.VelType_1,'Visible',VelType_1Visible)
2107set(handles.VelType_text_1,'Visible',VelType_1Visible);
2108
2109%% Visibility of FieldName and FieldName_1 menus
2110FieldNameVisible='off';  %hidden by default
2111FieldName_1Visible='off';  %hidden by default
2112if isfield(ParamOut,'FieldName')
2113    if strcmp( ParamOut.FieldName,'on') || strcmp(ParamOut.FieldName,'one')||strcmp( ParamOut.FieldName,'two')
2114        if (numel(iview_civ)+nb_netcdf)>=1
2115            InputFieldsVisible='on';
2116            FieldNameVisible='on';
2117        end
2118    end
2119    if strcmp( ParamOut.FieldName,'two')
2120        if (numel(iview_civ)+nb_netcdf)>=1
2121            FieldName_1Visible='on';
2122        end
2123    end
2124end
2125set(handles.InputFields,'Visible',InputFieldsVisible)
2126set(handles.FieldName,'Visible',FieldNameVisible) % test for MenuBorser
2127set(handles.FieldName_1,'Visible',FieldName_1Visible)
2128
2129%% Visibility of FieldTransform menu
2130FieldTransformVisible='off';  %hidden by default
2131if isfield(ParamOut,'FieldTransform')
2132    FieldTransformVisible=ParamOut.FieldTransform; 
2133    TransformName_Callback([],[], handles)
2134end
2135set(handles.FieldTransform,'Visible',FieldTransformVisible)
2136if isfield(ParamOut,'TransformPath')
2137    set(handles.ActionExt,'UserData',ParamOut.TransformPath)
2138else
2139    set(handles.ActionExt,'UserData',[])
2140end
2141
2142%% Visibility of projection object
2143ProjObjectVisible='off';  %hidden by default
2144if isfield(ParamOut,'ProjObject')
2145    ProjObjectVisible=ParamOut.ProjObject;
2146end
2147set(handles.CheckObject,'Visible',ProjObjectVisible)
2148if ~get(handles.CheckObject,'Value')
2149    ProjObjectVisible='off';
2150end
2151set(handles.ProjObject,'Visible',ProjObjectVisible)
2152set(handles.DeleteObject,'Visible',ProjObjectVisible)
2153set(handles.ViewObject,'Visible',ProjObjectVisible)
2154set(handles.EditObject,'Visible',ProjObjectVisible)
2155
2156%% Visibility of mask input
2157MaskVisible='off';  %hidden by default
2158if isfield(ParamOut,'Mask')
2159    MaskVisible=ParamOut.Mask;
2160end
2161%set(handles.Mask,'Visible',MaskVisible)
2162set(handles.CheckMask,'Visible',MaskVisible);
2163
2164%% definition of the directory containing the output files
2165OutputDirVisible='off';
2166if isfield(ParamOut,'OutputDirExt')&&~isempty(ParamOut.OutputDirExt)
2167    OutputSubDirMode='all';%default
2168    if isfield(ParamOut,'OutputSubDirMode')
2169        OutputSubDirMode=ParamOut.OutputSubDirMode;
2170    end
2171    set(handles.OutputDirExt,'String',ParamOut.OutputDirExt)
2172    OutputDirVisible='on';
2173    SubDir=InputTable(1:end,2); %set of subdirectories sorted in alphabetical order
2174    if strcmp(OutputSubDirMode,'last')
2175        SubDirOut=SubDir{end};
2176    else
2177        SubDirOut=SubDir{1};
2178        if ~strcmp(OutputSubDirMode,'first')  && numel(SubDir)>1
2179            for ilist=2:numel(SubDir)
2180                SubDirOut=[SubDirOut '-' SubDir{ilist}];
2181            end
2182        end
2183    end
2184    set(handles.OutputSubDir,'String',SubDirOut)
2185end
2186set(handles.OutputDirExt,'Visible',OutputDirVisible)
2187set(handles.OutputSubDir,'Visible',OutputDirVisible)
2188set(handles.OutputDir_title,'Visible',OutputDirVisible)
2189set(handles.RunMode,'Visible',OutputDirVisible)
2190set(handles.ActionExt,'Visible',OutputDirVisible)
2191set(handles.RunMode_title,'Visible',OutputDirVisible)
2192set(handles.ActionExt_title,'Visible',OutputDirVisible)
2193
2194
2195%% Expected nbre of output files
2196if isfield(ParamOut,'OutputFileMode')
2197    StatusData.OutputFileMode=ParamOut.OutputFileMode;
2198    set(handles.status,'UserData',StatusData)
2199end
2200
2201%% definition of an additional parameter set, determined by an ancillary GUI
2202if isfield(ParamOut,'ActionInput')
2203%     set(handles.ActionInput,'Visible','on')
2204%     set(handles.ActionInput_title,'Visible','on')
2205    set(handles.ActionInput,'Visible','on')
2206 %   set(handles.ActionInput,'Value',0)
2207%     set(handles.ActionInput,'String',ActionName)
2208    ParamOut.ActionInput.Program=ActionName; % record the program in ActionInput
2209    SeriesData.ActionInput=ParamOut.ActionInput;
2210else
2211%     set(handles.ActionInput,'Visible','off')
2212%     set(handles.ActionInput_title,'Visible','off')
2213    set(handles.ActionInput,'Visible','off')
2214    if isfield(SeriesData,'ActionInput')
2215    SeriesData=rmfield(SeriesData,'ActionInput');
2216    end
2217end   
2218set(handles.series,'UserData',SeriesData)
2219set(handles.ActionName,'BackgroundColor',[1 1 1])
2220
2221%------------------------------------------------------------------------
2222% --- Executes on button press in ActionInput.
2223function ActionInput_Callback(hObject, eventdata, handles)
2224%------------------------------------------------------------------------
2225% if get(handles.ActionInput,'Value')
2226ActionName_Callback(hObject, eventdata, handles)
2227% end
2228
2229%------------------------------------------------------------------------
2230% --- Executes on selection change in FieldName.
2231function FieldName_Callback(hObject, eventdata, handles)
2232%------------------------------------------------------------------------
2233field_str=get(handles.FieldName,'String');
2234field_index=get(handles.FieldName,'Value');
2235field=field_str{field_index(1)};
2236if isequal(field,'get_field...')
2237    hget_field=findobj(allchild(0),'name','get_field');
2238    if ~isempty(hget_field)
2239        delete(hget_field)%delete opened versions of get_field
2240    end
2241    Param=read_GUI(handles.series);
2242    Param.InputTable=Param.InputTable(1,:);
2243     % check the existence of the first file in the series
2244    first_j=[];
2245    if isfield(Param.IndexRange,'first_j'); first_j=Param.IndexRange.first_j; end
2246    last_j=[];
2247    if isfield(Param.IndexRange,'last_j'); last_j=Param.IndexRange.last_j; end
2248    PairString='';
2249    if isfield(Param.IndexRange,'PairString'); PairString=Param.IndexRange.PairString; end
2250    [i1,i2,j1,j2] = get_file_index(Param.IndexRange.first_i,first_j,PairString);
2251    FirstFileName=fullfile_uvmat(Param.InputTable{1,1},Param.InputTable{1,2},Param.InputTable{1,3},...
2252        Param.InputTable{1,5},Param.InputTable{1,4},i1,i2,j1,j2);
2253%     filecell=get_file_series(Param);
2254%     
2255    if exist(FirstFileName,'file')
2256        ParamIn.SeriesInput=1;
2257        GetFieldData=get_field(FirstFileName,ParamIn);
2258        FieldList={};
2259        switch GetFieldData.FieldOption
2260            case 'vectors'
2261                UName=GetFieldData.PanelVectors.vector_x;
2262                VName=GetFieldData.PanelVectors.vector_y;
2263                YName={GetFieldData.Coordinates.Coord_y};
2264                CName=GetFieldData.PanelVectors.vec_color;
2265                FieldList={['vec(' UName ',' VName ')'];...
2266                    ['norm(' UName ',' VName ')'];...
2267                    UName;VName};
2268                VecColorList={['norm(' UName ',' VName ')'];...
2269                    UName;VName};
2270                if ~isempty(CName)
2271                    VecColorList=[{CName};VecColorList];
2272                end
2273            case 'scalar'
2274                FieldList=GetFieldData.PanelScalar.scalar;
2275                YName={GetFieldData.Coordinates.Coord_y};
2276                if ischar(FieldList)
2277                FieldList={FieldList};
2278                end
2279            case '1D plot'
2280                YName=GetFieldData.PanelOrdinate.ordinate;
2281%             case 'civdata...'%reinitiate input, return to automatic civ data reading
2282%                 display_file_name(handles,FileName,1)
2283        end
2284        if ~strcmp(GetFieldData.FieldOption,'civdata...')
2285            XName=GetFieldData.Coordinates.Coord_x;
2286            TimeNameStr=GetFieldData.Time.SwitchVarIndexTime;
2287            switch TimeNameStr
2288                case 'file index'
2289                    set(handles.TimeName,'String','');
2290                case 'attribute'
2291                    set(handles.TimeName,'String',['att:' GetFieldData.Time.TimeName]);
2292                case 'variable'
2293                    set(handles.TimeName,'String',['var:' GetFieldData.Time.TimeName])
2294                    set(handles.NomType,'String','*')
2295                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])% A VERIFIER !!!!!!
2296                    set(handles.FileIndex,'String','')
2297                    ParamIn.TimeVarName=GetFieldData.Time.TimeName;
2298                case 'matrix_index'
2299                    set(handles.TimeName,'String',['dim:' GetFieldData.Time.TimeName]);
2300                    set(handles.NomType,'String','*')
2301                    set(handles.RootFile,'String',[get(handles.RootFile,'String') get(handles.FileIndex,'String')])
2302                    set(handles.FileIndex,'String','')
2303                    ParamIn.TimeDimName=GetFieldData.Time.TimeName;
2304            end
2305            set(handles.Coord_x,'String',{XName})
2306            set(handles.Coord_y,'String',YName)
2307            set(handles.FieldName,'Value',1)
2308            set(handles.FieldName,'String',[FieldList; {'get_field...'}]);
2309        end
2310    end
2311end
2312
2313%------------------------------------------------------------------------
2314% --- Executes on selection change in FieldName_1.
2315function FieldName_1_Callback(hObject, eventdata, handles)
2316%------------------------------------------------------------------------
2317field_str=get(handles.FieldName_1,'String');
2318field_index=get(handles.FieldName_1,'Value');
2319field=field_str{field_index};
2320if isequal(field,'get_field...')   
2321     hget_field=findobj(allchild(0),'name','get_field_1');
2322     if ~isempty(hget_field)
2323         delete(hget_field)
2324     end
2325     SeriesData=get(handles.series,'UserData');
2326     filename=SeriesData.CurrentInputFile_1;
2327     if exist(filename,'file')
2328        hget_field=get_field(filename);
2329        set(hget_field,'name','get_field_1')
2330     end
2331% elseif isequal(field,'more...')
2332%     str=calc_field;
2333%     [ind_answer,v] = listdlg('PromptString','Select a file:',...
2334%                 'SelectionMode','single',...
2335%                 'ListString',str);
2336%        % edit the choice in the fields and actionname menu
2337%      scalar=cell2mat(str(ind_answer));
2338%      update_menu(handles.FieldName_1,scalar)
2339end   
2340
2341
2342%%%%%%%%%%%%%
2343function [ind_remove]=find_pairs(dirpair,ind_i,last_i)
2344indsel=ind_i;
2345indiff=diff(ind_i); %test index increment to detect multiplets (several pairs with the same index ind_i) and holes in the series
2346indiff=[1 indiff last_i-ind_i(end)+1];%for testing gaps with the imposed bounds
2347if ~isempty(indiff)
2348    indiff2=diff(indiff);
2349    indiffp=[indiff2 1];
2350    indiffm=[1 indiff2];
2351    ind_multi_m=find((indiff==0)&(indiffm<0))-1;%indices of first members of multiplets
2352    ind_multi_p=find((indiff==0)&(indiffp>0));%indices of last members of multiplets
2353    %for each multiplet, select the most recent file
2354    ind_remove=[];
2355    for i=1:length(ind_multi_m)
2356        ind_pairs=ind_multi_m(i):ind_multi_p(i);
2357        for imulti=1:length(ind_pairs)
2358            datepair(imulti)=datenum(dirpair(ind_pairs(imulti)).date);%dates of creation
2359        end
2360        [datenew,indsort2]=sort(datepair); %sort the multiplet by creation date
2361        ind_s=indsort2(1:end-1);%
2362        ind_remove=[ind_remove ind_pairs(ind_s)];%remove these indices, leave the last one
2363    end
2364end
2365
2366%------------------------------------------------------------------------
2367% --- determine the list of index pairstring of processing file
2368function [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)
2369%------------------------------------------------------------------------
2370num_i1=num_i;% set of first image numbers by default
2371num_i2=num_i;
2372num_j1=num_j;
2373num_j2=num_j;
2374num_i_out=num_i;
2375num_j_out=num_j;
2376% if isequal (NomType,'_1-2_1') || isequal (NomType,'_1-2')
2377if isequal(mode,'series(Di)')
2378    num_i1_line=num_i+ind_shift(3);% set of first image numbers
2379    num_i2_line=num_i+ind_shift(4);
2380    % adjust the first and last field number
2381        indsel=find(num_i1_line >= 1);
2382    num_i_out=num_i(indsel);
2383    num_i1_line=num_i1_line(indsel);
2384    num_i2_line=num_i2_line(indsel);
2385    num_j1=meshgrid(num_j,ones(size(num_i1_line)));
2386    num_j2=meshgrid(num_j,ones(size(num_i1_line)));
2387    [xx,num_i1]=meshgrid(num_j,num_i1_line);
2388    [xx,num_i2]=meshgrid(num_j,num_i2_line);
2389elseif isequal (mode,'series(Dj)')||isequal (mode,'bursts')
2390    if isequal(mode,'bursts') %case of bursts (png_old or png_2D)
2391        num_j1=ind_shift(1)*ones(size(num_i));
2392        num_j2=ind_shift(2)*ones(size(num_i));
2393    else
2394        num_j1_col=num_j+ind_shift(1);% set of first image numbers
2395        num_j2_col=num_j+ind_shift(2);
2396        % adjust the first field number
2397        indsel=find((num_j1_col >= 1));   
2398        num_j_out=num_j(indsel);
2399        num_j1_col=num_j1_col(indsel);
2400        num_j2_col=num_j2_col(indsel);
2401        [num_i1,num_j1]=meshgrid(num_i,num_j1_col);
2402        [num_i2,num_j2]=meshgrid(num_i,num_j2_col);
2403    end   
2404end
2405
2406%------------------------------------------------------------------------
2407% --- Executes on button press in CheckObject.
2408function CheckObject_Callback(hObject, eventdata, handles)
2409%------------------------------------------------------------------------
2410hset_object=findobj(allchild(0),'tag','set_object');%find the set_object interface handle
2411if get(handles.CheckObject,'Value')
2412    SeriesData=get(handles.series,'UserData');
2413    if isfield(SeriesData,'ProjObject') && ~isempty(SeriesData.ProjObject)
2414        set(handles.ViewObject,'Value',1)
2415        ViewObject_Callback(hObject, eventdata, handles)
2416    else
2417        if ishandle(hset_object)
2418            uistack(hset_object,'top')% show the GUI set_object if opened
2419        else
2420            %get the object file
2421            InputTable=get(handles.InputTable,'Data');
2422            defaultname=InputTable{1,1};
2423            if isempty(defaultname)
2424                defaultname={''};
2425            end
2426            fileinput=uigetfile_uvmat('pick a xml object file (or use uvmat to create it)',defaultname,'.xml');
2427            if isempty(fileinput)% exit if no object file is selected
2428                set(handles.CheckObject,'Value',0)
2429                return
2430            end
2431            %read the file
2432            data=xml2struct(fileinput);
2433            if ~isfield(data,'Type')
2434                msgbox_uvmat('ERROR',[fileinput ' is not an object xml file'])
2435                set(handles.CheckObject,'Value',0)
2436                return
2437            end
2438            if ~isfield(data,'ProjMode')
2439                data.ProjMode='none';
2440            end
2441            hset_object=set_object(data);% call the set_object interface
2442            set(hset_object,'Name','set_object_series')% name to distinguish from set_object used with uvmat
2443        end
2444        ProjObject=read_GUI(hset_object);
2445        set(handles.ProjObject,'String',ProjObject.Name);%display the object name
2446        SeriesData=get(handles.series,'UserData');
2447        SeriesData.ProjObject=ProjObject;
2448        set(handles.series,'UserData',SeriesData);
2449    end
2450    set(handles.EditObject,'Visible','on');
2451    set(handles.DeleteObject,'Visible','on');
2452    set(handles.ViewObject,'Visible','on');
2453    set(handles.ProjObject,'Visible','on');
2454else
2455    set(handles.EditObject,'Visible','off');
2456    set(handles.DeleteObject,'Visible','off');
2457    set(handles.ViewObject,'Visible','off');
2458    if ~ishandle(hset_object)
2459        set(handles.ViewObject,'Value',0);
2460    end
2461    set(handles.ProjObject,'Visible','off');
2462end
2463
2464%------------------------------------------------------------------------
2465% --- Executes on button press in ViewObject.
2466%------------------------------------------------------------------------
2467function ViewObject_Callback(hObject, eventdata, handles)
2468
2469UserData=get(handles.series,'UserData');
2470hset_object=findobj(allchild(0),'Tag','set_object');
2471if ~isempty(hset_object)
2472    delete(hset_object)% refresh set_object if already opened
2473end
2474hset_object=set_object(UserData.ProjObject);
2475set(hset_object,'Name','view_object_series')
2476
2477
2478%------------------------------------------------------------------------
2479% --- Executes on button press in EditObject.
2480function EditObject_Callback(hObject, eventdata, handles)
2481%------------------------------------------------------------------------
2482if get(handles.EditObject,'Value')
2483    set(handles.ViewObject,'Value',0)
2484        UserData=get(handles.series,'UserData');
2485    hset_object=set_object(UserData.ProjObject);
2486    set(hset_object,'Name','edit_object_series')
2487    set(get(hset_object,'Children'),'Enable','on')
2488else
2489    hset_object=findobj(allchild(0),'Tag','set_object');
2490    if ~isempty(hset_object)
2491        set(get(hset_object,'Children'),'Enable','off')
2492    end
2493end
2494
2495%------------------------------------------------------------------------
2496% --- Executes on button press in DeleteObject.
2497function DeleteObject_Callback(hObject, eventdata, handles)
2498%------------------------------------------------------------------------
2499SeriesData=get(handles.series,'UserData');
2500SeriesData.ProjObject=[];
2501set(handles.series,'UserData',SeriesData)
2502set(handles.ProjObject,'String','')
2503set(handles.ProjObject,'Visible','off')
2504set(handles.CheckObject,'Value',0)
2505set(handles.ViewObject,'Visible','off')
2506set(handles.EditObject,'Visible','off')
2507hset_object=findobj(allchild(0),'name','set_object_series');
2508if ~isempty(hset_object)
2509    delete(hset_object)
2510end
2511set(handles.DeleteObject,'Visible','off')
2512
2513%------------------------------------------------------------------------
2514% --- Executed when CheckMask is activated
2515%------------------------------------------------------------------------
2516function CheckMask_Callback(hObject, eventdata, handles)
2517
2518if get(handles.CheckMask,'Value')
2519    InputTable=get(handles.InputTable,'Data');
2520    nbview=size(InputTable,1);
2521    MaskTable=cell(nbview,1);%default
2522    ListMask=cell(nbview,1);%default
2523    MaskData=get(handles.MaskTable,'Data');
2524    MaskData(size(MaskData,1):nbview,1)=cell(size(MaskData,1):nbview,1);%complement if undefined lines
2525    for iview=1:nbview
2526        ListMask{iview,1}=num2str(iview);
2527        RootPath=InputTable{iview,1};
2528        if ~isempty(RootPath)
2529            if isempty(MaskData{iview})
2530                SubDir=InputTable{iview,2};
2531                MaskPath=fullfile(RootPath,[regexprep(SubDir,'\..*','') '.mask']);%take the root part of SubDir, before the first dot '.'
2532                if exist(MaskPath,'dir')
2533                    ListStruct=dir(MaskPath);%look for a mask file
2534                    ListCells=struct2cell(ListStruct);% transform dir struct to a cell arrray
2535                    check_dir=cell2mat(ListCells(4,:));% =1 for directories, =0 for files
2536                    ListFiles=ListCells(1,:);%list of file and dri names
2537                    ListFiles=ListFiles(~check_dir);%list of file names (excluding dir)
2538                    mdetect=0;
2539                    if ~isempty(ListFiles)
2540                        for ifile=1:numel(ListFiles)
2541                            [tild,tild,MaskFile{ifile},i1_series,i2_series,j1_series,j2_series,MaskNomType,MaskFileType]=find_file_series(MaskPath,ListFiles{ifile},0);
2542                            if strcmp(MaskFileType,'image') && isempty(i2_series) && isempty(j2_series)
2543                                mdetect=1;
2544                                MaskName=ListFiles{ifile};
2545                            end
2546                            if ~strcmp(MaskFile{ifile},MaskFile{1})
2547                                mdetect=0;% cancel detection test in case of multiple masks, use the brower for selection
2548                                break
2549                            end
2550                        end
2551                    end
2552                    if mdetect==1
2553                        MaskName=fullfile(MaskPath,'mask_1.png');
2554                    else
2555                        MaskName=uigetfile_uvmat('select a mask file:',MaskPath,'image');
2556                    end
2557                else
2558                    MaskName=uigetfile_uvmat('select a mask file:',RootPath,'image');
2559                end
2560                MaskTable{iview,1}=MaskName ;
2561                ListMask{iview,1}=num2str(iview);
2562            end
2563        end
2564    end
2565    set(handles.MaskTable,'Data',MaskTable)
2566    set(handles.MaskTable,'Visible','on')
2567    set(handles.MaskBrowse,'Visible','on')
2568    set(handles.ListMask,'Visible','on')
2569    set(handles.ListMask,'String',ListMask)
2570    set(handles.ListMask,'Value',1)
2571else
2572    set(handles.MaskTable,'Visible','off')
2573    set(handles.MaskBrowse,'Visible','off')
2574    set(handles.ListMask,'Visible','off')
2575end
2576
2577%------------------------------------------------------------------------
2578% --- Executes on button press in MaskBrowse.
2579%------------------------------------------------------------------------
2580function MaskBrowse_Callback(hObject, eventdata, handles)
2581
2582InputTable=get(handles.InputTable,'Data');
2583iview=get(handles.ListMask,'Value');
2584RootPath=InputTable{iview,1};
2585MaskName=uigetfile_uvmat('select a mask file:',RootPath,'image');
2586if ~isempty(MaskName)
2587    MaskTable=get(handles.MaskTable,'Data');
2588    MaskTable{iview,1}=MaskName ;
2589    set(handles.MaskTable,'Data',MaskTable)
2590end
2591
2592%------------------------------------------------------------------------
2593% --- Executes when selected cell(s) is changed in MaskTable.
2594%------------------------------------------------------------------------
2595function MaskTable_CellSelectionCallback(hObject, eventdata, handles)
2596
2597if numel(eventdata.Indices)>=1
2598set(handles.ListMask,'Value',eventdata.Indices(1))
2599end
2600
2601%-------------------------------------------------------------------
2602function MenuHelp_Callback(hObject, eventdata, handles)
2603%-------------------------------------------------------------------
2604path_to_uvmat=which ('uvmat');% check the path of uvmat
2605pathelp=fileparts(path_to_uvmat);
2606helpfile=fullfile(pathelp,'uvmat_doc','uvmat_doc.html');
2607if isempty(dir(helpfile)), msgbox_uvmat('ERROR','Please put the help file uvmat_doc.html in the sub-directory /uvmat_doc of the UVMAT package')
2608else
2609    addpath (fullfile(pathelp,'uvmat_doc'))
2610    web([helpfile '#series'])
2611end
2612
2613%-------------------------------------------------------------------
2614% --- Executes on selection change in TransformName.
2615function TransformName_Callback(hObject, eventdata, handles)
2616%----------------------------------------------------------------------
2617TransformList=get(handles.TransformName,'String');
2618TransformIndex=get(handles.TransformName,'Value');
2619TransformName=TransformList{TransformIndex};
2620TransformPathList=get(handles.TransformName,'UserData');
2621nb_builtin_transform=4;
2622if isequal(TransformName,'more...');     
2623    FileName=uigetfile_uvmat('Pick a transform function',get(handles.TransformPath,'String'),'.m');
2624    if isempty(FileName)
2625        return     %browser closed without choice
2626    end
2627    [TransformPath,TransformName,TransformExt]=fileparts(FileName);% removes extension .m
2628    if ~strcmp(TransformExt,'.m')
2629        msgbox_uvmat('ERROR','a Matlab function .m must be introduced');
2630        return
2631    end
2632     % insert the choice in the menu
2633    TransformIndex=find(strcmp(TransformName,TransformList),1);% look for the selected function in the menu Action
2634    if isempty(TransformIndex)%the input string does not exist in the menu
2635        TransformIndex= length(TransformList);
2636        TransformList=[TransformList(1:end-1);{TransformName};TransformList(end)];% the selected function is appended in the menu, before the last item 'more...'
2637        set(handles.TransformName,'String',TransformList)
2638        TransformPathList=[TransformPathList;{TransformPath}];
2639    else% the input function already exist, we update its path (possibly new)
2640        TransformPathList{TransformIndex}=TransformPath;%
2641        set(handles.TransformName,'Value',TransformIndex)
2642    end
2643   % save the new menu in the personal file 'uvmat_perso.mat'
2644   dir_perso=prefdir;%personal Matalb directory
2645   profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
2646   if exist(profil_perso,'file')
2647       for ilist=nb_builtin_transform+1:numel(TransformPathList)
2648           TransformListUser{ilist-nb_builtin_transform}=TransformList{ilist};
2649           TransformPathListUser{ilist-nb_builtin_transform}=TransformPathList{ilist};
2650       end
2651       TransformPathListUser=TransformPathListUser';
2652       TransformListUser=TransformListUser';
2653       save (profil_perso,'TransformPathListUser','TransformListUser','-append'); %store the root name for future opening of uvmat
2654   end
2655end
2656
2657%display the current function path
2658set(handles.TransformPath,'String',TransformPathList{TransformIndex}); %show the path to the senlected function
2659set(handles.TransformName,'UserData',TransformPathList);
2660
2661%------------------------------------------------------------------------
2662% --- fct activated by the upper bar menu ExportConfig
2663%------------------------------------------------------------------------
2664function MenuExportConfig_Callback(hObject, eventdata, handles)
2665
2666global Param
2667Param=read_GUI_series(handles);
2668evalin('base','global Param')%make CurData global in the workspace
2669display('current series config :')
2670evalin('base','Param') %display CurData in the workspace
2671commandwindow; %brings the Matlab command window to the front
2672
2673%------------------------------------------------------------------------
2674% --- fct activated by the upper bar menu InportConfig: import
2675%     menu settings from an xml file (stored in /0_XML for each run)
2676%------------------------------------------------------------------------
2677function MenuImportConfig_Callback(hObject, eventdata, handles)
2678% SeriesData=get(handles.series,'UserData');
2679% if isfield(SeriesData,'RefFile')
2680%     oldfile=SeriesData.RefFile{1};
2681% end
2682%% use a strating file name for browserr
2683InputTable=get(handles.InputTable,'Data');
2684oldfile=InputTable{1,1};
2685if isempty(oldfile)
2686    % use a file name stored in prefdir
2687    dir_perso=prefdir;
2688    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
2689    if exist(profil_perso,'file')
2690        h=load (profil_perso);
2691        if isfield(h,'RootPath') && ischar(h.RootPath)
2692            oldfile=h.RootPath;
2693        end
2694    end
2695end
2696filexml=uigetfile_uvmat('pick a xml parameter file',oldfile,'.xml');% get the xml file containing processing parameters
2697%proceed only if a file has been introduced by the browser
2698if ~isempty(filexml)
2699    Param=xml2struct(filexml);% read the input xml file as a Matlab structure
2700    % ask to stop current Action if button RUN is in action (another process is already running)
2701    if isequal(get(handles.RUN,'Value'),1)
2702        answer= msgbox_uvmat('INPUT_Y-N','stop current Action process?');
2703        if strcmp(answer,'Yes')
2704            STOP_Callback(hObject, eventdata, handles)
2705        else
2706            return
2707        end
2708    end
2709    Param.Action.RUN=0; %desactivate the input RUN=1
2710    fill_GUI(Param,handles.series)% fill the elements of the GUI series with the input parameters
2711    SeriesData=get(handles.series,'UserData');
2712    if isfield(Param,'ActionInput')%  introduce  parameters specific to an Action fct, for instance PIV parameters
2713        set(handles.ActionInput,'Visible','on')
2714        set(handles.ActionInput,'Value',0)
2715        SeriesData.ActionInput=Param.ActionInput;
2716    end
2717    if isfield(Param,'ProjObject') %introduce projection object if relevant
2718        SeriesData.ProjObject=Param.ProjObject;
2719    end
2720    set(handles.series,'UserData',SeriesData)
2721    if isfield(Param,'CheckObject') && isequal(Param.CheckObject,1)
2722        set(handles.ProjObject,'String',Param.ProjObject.Name)
2723        set(handles.ViewObject,'Visible','on')
2724        set(handles.EditObject,'Visible','on')
2725        set(handles.DeleteObject,'Visible','on')
2726    else     
2727        set(handles.ProjObject,'String','')
2728        set(handles.ProjObject,'Visible','off')
2729        set(handles.ViewObject,'Visible','off')
2730        set(handles.EditObject,'Visible','off')
2731        set(handles.DeleteObject,'Visible','off')     
2732    end     
2733    set(handles.REFRESH,'BackgroundColor',[1 0 1]); %paint REFRESH button in magenta to indicate that it should be activated
2734end
2735
2736%------------------------------------------------------------------------
2737% --- Executes when the GUI series is resized.
2738%------------------------------------------------------------------------
2739function series_ResizeFcn(hObject, eventdata, handles)
2740
2741%% input table
2742set(handles.InputTable,'Unit','pixel')
2743Pos=get(handles.InputTable,'Position');
2744set(handles.InputTable,'Unit','normalized')
2745ColumnWidth=round([0.5 0.14 0.14 0.14 0.08]*(Pos(3)-52));
2746ColumnWidth=num2cell(ColumnWidth);
2747set(handles.InputTable,'ColumnWidth',ColumnWidth)
2748
2749%% MinIndex_j and MaxIndex_i
2750unit=get(handles.MinIndex_i,'Unit');
2751set(handles.MinIndex_i,'Unit','pixel')
2752Pos=get(handles.MinIndex_i,'Position');
2753set(handles.MinIndex_i,'Unit',unit)
2754set(handles.MinIndex_i,'ColumnWidth',{Pos(3)-18})
2755set(handles.MaxIndex_i,'ColumnWidth',{Pos(3)-18})
2756set(handles.MinIndex_j,'ColumnWidth',{Pos(3)-18})
2757set(handles.MaxIndex_j,'ColumnWidth',{Pos(3)-18})
2758
2759%% TimeTable
2760set(handles.TimeTable,'Unit','pixel')
2761Pos=get(handles.TimeTable,'Position');
2762set(handles.TimeTable,'Unit','normalized')
2763% ColumnWidth=get(handles.TimeTable,'ColumnWidth');
2764ColumnWidth=num2cell(floor([0.25 0.25 0.25 0.25]*(Pos(3)-20)));
2765set(handles.TimeTable,'ColumnWidth',ColumnWidth)
2766
2767
2768%% PairString
2769set(handles.PairString,'Unit','pixel')
2770Pos=get(handles.PairString,'Position');
2771set(handles.PairString,'Unit','normalized')
2772set(handles.PairString,'ColumnWidth',{Pos(3)-5})
2773
2774%% MaskTable
2775set(handles.MaskTable,'Unit','pixel')
2776Pos=get(handles.MaskTable,'Position');
2777set(handles.MaskTable,'Unit','normalized')
2778set(handles.MaskTable,'ColumnWidth',{Pos(3)-5})
2779
2780%------------------------------------------------------------------------
2781% --- Executes on button press in status.
2782%------------------------------------------------------------------------
2783function status_Callback(hObject, eventdata, handles)
2784
2785if get(handles.status,'Value')
2786    set(handles.status,'BackgroundColor',[1 1 0])
2787    drawnow
2788    Param=read_GUI(handles.series);
2789    RootPath=Param.InputTable{1,1};
2790    if ~isfield(Param,'OutputSubDir')   
2791        msgbox_uvmat('ERROR','no directory defined for output files')
2792        return
2793    end
2794    OutputSubDir=[Param.OutputSubDir Param.OutputDirExt];% subdirectory for output files
2795    OutputDir=fullfile(RootPath,OutputSubDir);
2796    if exist(OutputDir,'dir')
2797        uigetfile_uvmat('status_display',OutputDir)
2798    else
2799        msgbox_uvmat('ERROR','output folder not created yet: calculation did not start')
2800        set(handles.status,'BackgroundColor',[0 1 0])
2801    end
2802else
2803    %% delete current display fig if selection is off
2804    set(handles.status,'BackgroundColor',[0 1 0])
2805    hfig=findobj(allchild(0),'name','status_display');
2806    if ~isempty(hfig)
2807        delete(hfig)
2808    end
2809    return
2810end
2811
2812
2813%------------------------------------------------------------------------   
2814% launched by selecting a file on the list
2815%------------------------------------------------------------------------
2816function view_file(hObject, eventdata)
2817
2818list=get(hObject,'String');
2819index=get(hObject,'Value');
2820rootroot=get(hObject,'UserData');
2821selectname=list{index};
2822ind_dot=regexp(selectname,'\.\.\.');
2823if ~isempty(ind_dot)
2824    selectname=selectname(1:ind_dot-1);
2825end
2826FullSelectName=fullfile(rootroot,selectname);
2827if exist(FullSelectName,'dir')% a directory has been selected
2828    ListFiles=dir(FullSelectName);
2829    ListDisplay=cell(numel(ListFiles),1);
2830    for ilist=2:numel(ListDisplay)% suppress the first line '.'
2831        ListDisplay{ilist-1}=ListFiles(ilist).name;
2832    end
2833    set(hObject,'Value',1)
2834    set(hObject,'String',ListDisplay)
2835    if strcmp(selectname,'..')
2836        FullSelectName=fileparts(fileparts(FullSelectName));
2837    end
2838    set(hObject,'UserData',FullSelectName)
2839    hfig=get(hObject,'parent');
2840    htitlebox=findobj(hfig,'tag','titlebox');   
2841    set(htitlebox,'String',FullSelectName)
2842elseif exist(FullSelectName,'file')%visualise the vel field if it exists
2843    FileType=get_file_type(FullSelectName);
2844    if strcmp(FileType,'txt')
2845        edit(FullSelectName)
2846    elseif strcmp(FileType,'xml')
2847        editxml(FullSelectName)
2848    else
2849        uvmat(FullSelectName)
2850    end
2851    set(gcbo,'Value',1)
2852end
2853
2854
2855%------------------------------------------------------------------------   
2856% launched by refreshing the status figure
2857%------------------------------------------------------------------------
2858function refresh_GUI(hfig)
2859
2860htitlebox=findobj(hfig,'tag','titlebox');
2861hlist=findobj(hfig,'tag','list');
2862hseries=findobj(allchild(0),'tag','series');
2863hstatus=findobj(hseries,'tag','status');
2864StatusData=get(hstatus,'UserData');
2865OutputDir=get(htitlebox,'String');
2866if ischar(OutputDir),OutputDir={OutputDir};end
2867ListFiles=dir(OutputDir{1});
2868if numel(ListFiles)<1
2869    return
2870end
2871ListFiles(1)=[];%removes the first line ='.'
2872ListDisplay=cell(numel(ListFiles),1);
2873testrecent=0;
2874datnum=zeros(numel(ListDisplay),1);
2875for ilist=1:numel(ListDisplay)
2876    ListDisplay{ilist}=ListFiles(ilist).name;
2877      if ~ListFiles(ilist).isdir && isfield(ListFiles(ilist),'datenum')
2878            datnum(ilist)=ListFiles(ilist).datenum;%only available in recent matlab versions
2879            testrecent=1;
2880       end
2881end
2882set(hlist,'String',ListDisplay)
2883
2884%% Look at date of creation
2885ListDisplay=ListDisplay(datnum~=0);
2886datnum=datnum(datnum~=0);%keep the non zero values corresponding to existing files
2887NbOutputFile=[];
2888if isempty(datnum)
2889    if testrecent
2890        message='no civ result created yet';
2891    else
2892        message='';
2893    end
2894else
2895    [first,indfirst]=min(datnum);
2896    [last,indlast]=max(datnum);
2897    NbOutputFile_str='?';
2898    NbOutputFile=[];
2899    if isfield(StatusData,'NbOutputFile')
2900        NbOutputFile=StatusData.NbOutputFile;
2901        NbOutputFile_str=num2str(NbOutputFile);
2902    end
2903    message={[num2str(numel(datnum)) ' file(s) done over ' NbOutputFile_str] ;['oldest modification:  ' ListDisplay{indfirst} ' : ' datestr(first)];...
2904        ['latest modification:  ' ListDisplay{indlast} ' : ' datestr(last)]};
2905end
2906set(htitlebox,'String', [OutputDir{1};message])
2907
2908%% update the waitbar
2909hwaitbar=findobj(hfig,'tag','waitbar');
2910if ~isempty(NbOutputFile)
2911    BarPosition=get(hwaitbar,'Position');
2912    BarPosition(3)=0.9*numel(datnum)/NbOutputFile;
2913    set(hwaitbar,'Position',BarPosition)
2914end
2915
2916%------------------------------------------------------------------------
2917% --- Executes on selection change in ActionExt.
2918%------------------------------------------------------------------------
2919function ActionExt_Callback(hObject, eventdata, handles)
2920
2921ActionExtList=get(handles.ActionExt,'String');
2922ActionExt=ActionExtList{get(handles.ActionExt,'Value')};
2923ActionList=get(handles.ActionName,'String');
2924ActionName=ActionList{get(handles.ActionName,'Value')};
2925TransformPath='';
2926if ~isempty(get(handles.ActionExt,'UserData'))
2927    TransformPath=get(handles.ActionExt,'UserData');
2928end
2929if strcmp(ActionExt,'.sh')
2930    set(handles.series,'Pointer','watch') % set the mouse pointer to 'watch'
2931    set(handles.ActionExt,'BackgroundColor',[1 1 0])
2932    ActionFullName=fullfile(get(handles.ActionPath,'String'),[ActionName '.sh']);
2933    if ~exist(ActionFullName,'file')
2934        answer=msgbox_uvmat('INPUT_Y-N','compiled version has not been created: compile now?');
2935        if strcmp(answer,'Yes')
2936            set(handles.ActionExt,'BackgroundColor',[1 1 0])
2937            path_uvmat=fileparts(which('series'));
2938            currentdir=pwd;
2939            cd(get(handles.ActionPath,'String'))% go to the directory of Action
2940            %  addpath(get(handles.TransformPath,'String'))
2941            addpath(path_uvmat)% add the path to uvmat to run the fct 'compile'
2942           % addpath(fullfile(path_uvmat,'transform_field'))% add the path to uvmat to run the fct 'compile'
2943            compile(ActionName,TransformPath)
2944            cd(currentdir)
2945        end       
2946    else
2947        sh_file_info=dir(fullfile(get(handles.ActionPath,'String'),[ActionName '.sh']));
2948        m_file_info=dir(fullfile(get(handles.ActionPath,'String'),[ActionName '.m']));
2949        if isfield(m_file_info,'datenum') && m_file_info.datenum>sh_file_info.datenum
2950            set(handles.ActionExt,'BackgroundColor',[1 1 0])
2951            drawnow
2952            answer=msgbox_uvmat('INPUT_Y-N',[ActionName '.sh needs to be updated: recompile now?']);
2953            if strcmp(answer,'Yes')
2954                path_uvmat=fileparts(which('series'));
2955                currentdir=pwd;
2956                cd(get(handles.ActionPath,'String'))% go to the directory of Action
2957                %  addpath(get(handles.TransformPath,'String'))
2958                addpath(path_uvmat)% add the path to uvmat to run the fct 'compile'
2959                addpath(fullfile(path_uvmat,'transform_field'))% add the path to uvmat to run the fct 'compile'
2960                compile(ActionName,TransformPath)
2961                cd(currentdir)
2962            end
2963        end
2964    end
2965    set(handles.ActionExt,'BackgroundColor',[1 1 1])
2966     set(handles.series,'Pointer','arrow') % set the mouse pointer to 'watch
2967end
2968
2969
2970
2971
2972function num_NbProcess_Callback(hObject, eventdata, handles)
2973
2974
2975function num_NbSlice_Callback(hObject, eventdata, handles)
2976NbSlice=str2num(get(handles.num_NbSlice,'String'));
2977set(handles.num_NbProcess,'String',num2str(NbSlice))
2978
2979%------------------------------------------------------------------------
2980% --- set the visibility of relevant velocity type menus:
2981function menu=set_veltype_display(Civ,FileType)
2982%------------------------------------------------------------------------
2983if ~exist('FileType','var')
2984    FileType='civx';
2985end
2986switch FileType
2987    case 'civx'
2988        menu={'civ1';'interp1';'filter1';'civ2';'interp2';'filter2'};
2989        if isequal(Civ,0)
2990            imax=0;
2991        elseif isequal(Civ,1) || isequal(Civ,2)
2992            imax=1;
2993        elseif isequal(Civ,3)
2994            imax=3;
2995        elseif isequal(Civ,4) || isequal(Civ,5)
2996            imax=4;
2997        elseif isequal(Civ,6) %patch2
2998            imax=6;
2999        end
3000    case 'civdata'
3001        menu={'civ1';'filter1';'civ2';'filter2'};
3002        if isequal(Civ,0)
3003            imax=0;
3004        elseif isequal(Civ,1) || isequal(Civ,2)
3005            imax=1;
3006        elseif isequal(Civ,3)
3007            imax=2;
3008        elseif isequal(Civ,4) || isequal(Civ,5)
3009            imax=3;
3010        elseif isequal(Civ,6) %patch2
3011            imax=4;
3012        end
3013end
3014menu=menu(1:imax);
3015
3016
3017% --- Executes on mouse motion over figure - except title and menu.
3018function series_WindowButtonMotionFcn(hObject, eventdata, handles)
3019set(hObject,'Pointer','arrow');
Note: See TracBrowser for help on using the repository browser.