source: trunk/src/series.m @ 690

Last change on this file since 690 was 682, checked in by sommeria, 11 years ago

various bugs repaired

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