source: trunk/src/series.m @ 591

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

various updates, in particular modification of series to do calculations in the cluster

File size: 104.9 KB
Line 
1%'series': master function associated to the GUI series.m for analysis field series 
2%------------------------------------------------------------------------
3% function varargout = series(varargin)
4% associated with the GUI series.fig
5%
6%INPUT
7% param: structure with input parameters (link with the GUI uvmat)
8%      .menu_coord_str: string for the TransformName (menu for coordinate transforms)
9%      .menu_coord_val: value for TransformName (menu for coordinate transforms)
10%      .FileName: input file name
11%      .FileName_1: second input file name
12%      .list_field: menu of input fields
13%      .index_fields: chosen index
14%      .civ1=0 or 1, .interp1,  ... : input civ field type
15%
16%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
17%  Copyright Joel Sommeria, 2008, LEGI / CNRS-UJF-INPG, sommeria@coriolis-legi.org.
18%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
19%     This file is part of the toolbox UVMAT.
20%
21%     UVMAT is free software; you can redistribute it and/or modify
22%     it under the terms of the GNU General Public License as published by
23%     the Free Software Foundation; either version 2 of the License, or
24%     (at your option) any later version.
25%
26%     UVMAT is distributed in the hope that it will be useful,
27%     but WITHOUT ANY WARRANTY; without even the implied warranty of
28%     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29%     GNU General Public License (file UVMAT/COPYING.txt) for more details.
30%AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
31
32%------------------------------------------------------------------------
33%------------------------------------------------------------------------
34%  I - MAIN FUNCTION series
35%------------------------------------------------------------------------
36%------------------------------------------------------------------------
37function varargout = series(varargin)
38
39% Begin initialization code - DO NOT EDIT
40gui_Singleton = 1;
41gui_State = struct('gui_Name',       mfilename, ...
42                   'gui_Singleton',  gui_Singleton, ...
43                   'gui_OpeningFcn', @series_OpeningFcn, ...
44                   'gui_OutputFcn',  @series_OutputFcn, ...
45                   'gui_LayoutFcn',  [] , ...
46                   'gui_Callback',   []);
47if nargin && ischar(varargin{1})
48    gui_State.gui_Callback = str2func(varargin{1});
49end
50
51if nargout
52    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
53else
54    gui_mainfcn(gui_State, varargin{:});
55end
56% End initialization code - DO NOT EDIT
57
58%--------------------------------------------------------------------------
59% --- Executes just before series is made visible.
60%--------------------------------------------------------------------------
61function series_OpeningFcn(hObject, eventdata, handles,Param)
62
63% Choose default command line output for series
64handles.output = hObject;
65% Update handles structure
66guidata(hObject, handles);
67
68%% initial settings
69drawnow
70set(hObject,'Units','pixels')
71set(handles.PairString,'ColumnName',{'pairs'})
72set(handles.PairString,'ColumnEditable',logical(0))
73set(handles.PairString,'ColumnFormat',{'char'})
74set(handles.PairString,'Data',{''})
75series_ResizeFcn(hObject, eventdata, handles)%resize table according to series GUI size
76set(hObject,'WindowButtonDownFcn',{'mouse_down'})%allows mouse action with right button (zoom for uicontrol display)
77% check default input data
78if ~exist('Param','var')
79    Param=[]; %default
80end
81
82%% default list of functions in the mebu ActionName
83ActionList={'check_data_files';'aver_stat';'time_series';'merge_proj'};% WARNING: fits with nb_builtin_ACTION=4 in ActionName_callback
84[path_series,name,ext]=fileparts(which('series'));% path to the GUI series
85path_series_fct=fullfile(path_series,'series');%path of the functions in subdirectroy 'series'
86path_bin=fullfile(path_series,'bin');%path of the binary functions (compiled)
87ActionPathList=regexprep(ActionList,'^.+$',path_series_fct);% set path=path_series to each function in the list ('^.+$'=any non empty nbre of char form beginning to end of char string)
88ActionPathList=[ActionPathList regexprep(ActionList,'^.+$',path_bin)];% set path to compiled functions
89ActionExtList={'.m';'.sh'};% default choice of extensions (Matlab fct .m or compiled version .sh)
90RunModeList={'local';'background'};% default choice of extensions (Matlab fct .m or compiled version .sh)
91[s,w]=system('oarstat');% look for cluster system 'oar'
92if isequal(s,0)
93    RunModeList=[RunModeList;{'cluster_oar'}];
94end
95[s,w]=system('qstat');% look for cluster system 'sge'
96if isequal(s,0)
97    RunModeList=[RunModeList;{'cluster_sge'}];
98end
99set(handles.RunMode,'String',RunModeList)
100
101%% default list of functions in the mebu TransformName
102TransformList={'';'sub_field';'phys';'phys_polar'};% WARNING: must fit with the corresponding menu in uvmat and nb_builtin_transform=4 in  TransformName_callback
103path_transform_fct=fullfile(path_series,'transform_field');
104TransformPathList=regexprep(TransformList,'^.+$',path_transform_fct);% set path=path_transform_fct to each function in the list ('^.+$'=any non empty nbre of char form beginning to end of char string)
105
106%% load the personal file uvmat_perso.mat
107dir_perso=prefdir;
108profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
109if exist(profil_perso,'file')
110    h=load (profil_perso);
111    %get the list of previous input files in the upper bar menu Open
112    if isfield(h,'MenuFile')
113        for ifile=1:min(length(h.MenuFile),5)
114            eval(['set(handles.MenuFile_' num2str(ifile) ',''Label'',h.MenuFile{ifile});'])
115        end
116    end
117    %get the menu of actions
118    if isfield(h,'ActionExtListUser') && iscell(h.ActionExtListUser)
119        ActionExtList=[ActionExtList; h.ActionExtListUser];
120    end
121    if isfield(h,'ActionListUser') && iscell(h.ActionListUser) && isfield(h,'ActionPathListUser') && iscell(h.ActionPathListUser)
122        ActionList=[ActionList;h.ActionListUser];
123        ActionPathList=[ActionPathList;h.ActionPathListUser];
124    end
125    %get the menu of transform fct
126    if isfield(h,'TransformListUser') && iscell(h.TransformListUser) && isfield(h,'TransformPathListUser') && iscell(h.TransformPathListUser)
127        TransformList=[TransformList;h.TransformListUser];
128        TransformPathList=[TransformPathList;h.TransformPathListUser];
129    end
130end
131
132%% selection of the input Action fct
133ActionCheckExist=false(size(ActionList));
134for ilist=1:numel(ActionList)
135    ActionCheckExist(ilist)=exist(fullfile(ActionPathList{ilist},[ActionList{ilist} '.m']),'file');
136end
137ActionPathList=ActionPathList(ActionCheckExist,:);
138ActionList=ActionList(ActionCheckExist);
139set(handles.ActionName,'String',[ActionList;{'more...'}])
140set(handles.ActionName,'UserData',ActionPathList)
141ActionIndex=[];
142if isfield(Param,'ActionName')% copy the selected menu index transferred in Param from uvmat
143    ActionIndex=find(strcmp(Param.ActionName,ActionList),1);
144end
145if isempty(ActionIndex)
146    ActionIndex=1;
147end
148set(handles.ActionName,'Value',ActionIndex)
149set(handles.ActionPath,'String',ActionPathList{ActionIndex})
150set(handles.ActionExt,'Value',1)
151set(handles.ActionExt,'String',ActionExtList)
152
153%% selection of the input transform fct
154TransformCheckExist=false(size(TransformList));
155TransformCheckExist(1)=1;%the first option is blank: no transform, always allowed
156for ilist=2:numel(TransformList)
157    TransformCheckExist(ilist)=exist(fullfile(TransformPathList{ilist},[TransformList{ilist} '.m']),'file');
158end
159TransformPathList=TransformPathList(TransformCheckExist);
160TransformList=TransformList(TransformCheckExist);
161set(handles.TransformName,'String',[TransformList;{'more...'}])
162set(handles.TransformName,'UserData',TransformPathList)
163TransformIndex=[];
164if isfield(Param,'TransformName')% copy the selected menu index transferred in Param from uvmat
165    TransformIndex=find(strcmp(Param.TransformName,TransformList),1);
166end
167if isempty(TransformIndex)
168    TransformIndex=1;
169end
170set(handles.TransformName,'Value',TransformIndex)
171set(handles.TransformPath,'String',TransformPathList{TransformIndex})
172   
173%% fields input initialisation
174if isfield(Param,'list_fields')&& isfield(Param,'index_fields') &&~isempty(Param.list_fields) &&~isempty(Param.index_fields)
175    set(handles.FieldName,'String',Param.list_fields);% list menu fields
176    set(handles.FieldName,'Value',Param.index_fields);% selected string index
177end
178if isfield(Param,'Coord_x_str')&& isfield(Param,'Coord_x_val')
179        set(handles.Coord_x,'String',Param.Coord_x_str);% list menu fields
180    set(handles.Coord_x,'Value',Param.Coord_x_val);% selected string index
181end
182if isfield(Param,'Coord_y_str')&& isfield(Param,'Coord_y_val')
183        set(handles.Coord_y,'String',Param.Coord_y_str);% list menu fields
184    set(handles.Coord_y,'Value',Param.Coord_y_val);% selected string index
185end
186
187%% Adjust the GUI according to the binaries available in PARAM.xml
188path_uvmat=fileparts(which('uvmat')); %path to civ
189addpath (path_uvmat) ; %add the path to civ, (useful in case of change of working directory after civ has been s opened in the working directory)
190errormsg=[];%default error message
191xmlfile='PARAM.xml';
192if exist(xmlfile,'file')
193    try
194        t=xmltree(xmlfile);
195        sparam=convert(t);
196    catch ME
197        errormsg={' Unable to read the file PARAM.xml defining the  binaries:';ME.message};
198    end
199else
200    errormsg=[xmlfile ' not found: path to binaries undefined'];
201end
202if ~isempty(errormsg)
203    msgbox_uvmat('WARNING',errormsg);
204end
205test_batch=0;%default: ,no batch mode available
206if isfield(sparam,'BatchParam') && isfield(sparam.BatchParam,'BatchMode')
207    test_batch=strcmp(sparam.BatchParam.BatchMode,'sge'); %sge is currently the only implemented batch mod
208end
209RUNVal=get(handles.RunMode,'Value');
210if test_batch==0
211   if RUNVal>2
212       set(handles.RunMode,'Value',1)
213   end
214   set(handles.RunMode,'String',{'local';'background'})
215else
216    set(handles.RunMode,'String',{'local';'background';'cluster'})
217end
218
219%% introduce the input file name(s) if defined from input Param
220if isfield(Param,'FileName')
221    InputTable={'','','','',''}; % refresh the file input table
222    set(handles.InputTable,'Data',InputTable)
223    if isfield(Param,'FileName_1')
224        display_file_name(handles,Param.FileName_1,0)
225        display_file_name(handles,Param.FileName,1)
226    else
227        display_file_name(handles,Param.FileName,0)
228    end
229end 
230if isfield(Param,'incr_i')
231    set(handles.num_incr_i,'String',num2str(Param.incr_i))
232end
233if isfield(Param,'incr_j')
234    set(handles.num_incr_j,'String',num2str(Param.incr_j))
235end
236
237
238%------------------------------------------------------------------------
239% --- Outputs from this function are returned to the command line.
240function varargout = series_OutputFcn(hObject, eventdata, handles)
241%------------------------------------------------------------------------
242% varargout  cell array for returning output args (see VARARGOUT);
243% hObject    handle to figure
244% eventdata  reserved - to be defined in a future version of MATLAB
245% handles    structure with handles and user data (see GUIDATA)
246% Get default command line output from handles structure
247varargout{1} = handles.output;
248
249%------------------------------------------------------------------------
250%------------------------------------------------------------------------
251%  II - FUNCTIONS FOR INTRODUCING THE INPUT FILES
252% automatically sets the global properties when the rootfile name is introduced
253% then activate the view-field actionname if selected
254% it is activated either by clicking on the RootPath window or by the
255% browser
256%------------------------------------------------------------------------
257%------------------------------------------------------------------------
258function MenuBrowse_Callback(hObject, eventdata, handles)
259%------------------------------------------------------------------------   
260InputTable=get(handles.InputTable,'Data');
261if isempty(InputTable)
262    RootPathCell={};
263else
264    RootPathCell=InputTable(:,1);
265end
266oldfile=''; %default
267if isempty(RootPathCell)||isequal(RootPathCell,{''})%loads the previously stored file name and set it as default in the file_input box
268     dir_perso=prefdir;
269     profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
270     if exist(profil_perso,'file')
271          h=load (profil_perso);
272         if isfield(h,'filebase')&&ischar(h.filebase)
273                 oldfile=h.filebase;
274         end
275         if isfield(h,'RootPath')&&ischar(h.RootPath)
276                 oldfile=h.RootPath;
277         end
278     end
279else
280     SubDirCell=InputTable(:,2);
281    RootFileCell=InputTable(:,3);
282     oldfile=fullfile(RootPathCell{1},SubDirCell{1},RootFileCell{1});
283 end
284[FileName, PathName, filterindex] = uigetfile( ...
285       {'*.xml;*.xls;*.png;*.tif;*.avi;*.AVI;*.nc', ' (*.xml,*.xls, *.png,*.tif, *.avi,*.nc)';
286       '*.xml',  '.xml files '; ...
287        '*.xls',  '.xls files '; ...
288        '*.png','.png image files'; ...
289        '*.tif','.tif image files'; ...
290        '*.avi;*.AVI','.avi movie files'; ...
291        '*.nc','.netcdf files'; ...
292        '*.*',  'All Files (*.*)'}, ...
293        'Pick a file',oldfile);
294fileinput=[PathName FileName];%complete file name
295if isempty(fileinput),return;end %abandon if no file is introduced by the browser
296[path,name,ext]=fileparts(fileinput);
297if isequal(ext,'.xml')
298    [Param,Heading]=xml2struct(fileinput);
299    if ~strcmp(Heading,'Series')
300        msg_box_uvmat('ERROR','xml file heading is not <Series>')
301    else
302        fill_GUI(Param,handles.series);%fill the GUI with the parameters retrieved from the xml file
303        if isfield(Param,'CheckObject')&& Param.CheckObject
304            set_object(Param.ProjObject)
305        end
306        set(handles.REFRESH,'UserData',[1:size(Param.InputTable,1)])
307        REFRESH_Callback([],[], handles)
308        return
309    end
310elseif isequal(ext,'.xls')
311    msg_box_uvmat('ERROR','input file type not implemented')%A Faire: ouvrir le fichier pour naviguer
312else
313    display_file_name(handles,fileinput,0)
314end
315
316% --------------------------------------------------------------------
317function MenuFile_1_Callback(hObject, eventdata, handles)
318fileinput=get(handles.MenuFile_1,'Label');
319display_file_name(handles,fileinput,0)
320
321% --------------------------------------------------------------------
322function MenuFile_2_Callback(hObject, eventdata, handles)
323fileinput=get(handles.MenuFile_2,'Label');
324display_file_name(handles,fileinput,0)
325
326% --------------------------------------------------------------------
327function MenuFile_3_Callback(hObject, eventdata, handles)
328fileinput=get(handles.MenuFile_3,'Label');
329display_file_name( handles,fileinput,0)
330
331% --------------------------------------------------------------------
332function MenuFile_4_Callback(hObject, eventdata, handles)
333fileinput=get(handles.MenuFile_4,'Label');
334display_file_name(handles,fileinput,0)
335
336% --------------------------------------------------------------------
337function MenuFile_5_Callback(hObject, eventdata, handles)
338fileinput=get(handles.MenuFile_5,'Label');
339display_file_name(handles,fileinput,0)
340
341% --------------------------------------------------------------------
342function MenuBrowse_insert_Callback(hObject, eventdata, handles)
343InputTable=get(handles.InputTable,'Data');
344RootPathCell=InputTable(:,1);
345SubDirCell=InputTable(:,3);
346RootFileCell=InputTable(:,2);
347oldfile=''; %default
348if isempty(RootPathCell)||isequal(RootPathCell,{''})%loads the previously stored file name and set it as default in the file_input box
349     dir_perso=prefdir;
350     profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
351     if exist(profil_perso,'file')
352          h=load (profil_perso);
353         if isfield(h,'filebase')&ischar(h.filebase)
354                 oldfile=h.filebase;
355         end
356         if isfield(h,'RootPath')&ischar(h.RootPath)
357                 oldfile=h.RootPath;
358         end
359     end
360 else
361     oldfile=fullfile(RootPathCell{1},RootFileCell{1});
362 end
363[FileName, PathName, filterindex] = uigetfile( ...
364       {'*.xml;*.xls;*.png;*.avi;*.AVI;*.nc', ' (*.xml,*.xls, *.png, *.avi,*.nc)';
365       '*.xml',  '.xml files '; ...
366        '*.xls',  '.xls files '; ...
367        '*.png','.png image files'; ...
368        '*.avi;*.AVI','.avi movie files'; ...
369        '*.nc','.netcdf files'; ...
370        '*.*',  'All Files (*.*)'}, ...
371        'Pick a file',oldfile);
372fileinput=[PathName FileName];%complete file name
373sizf=size(fileinput);
374if (~ischar(fileinput)|~isequal(sizf(1),1)),return;end
375[path,name,ext]=fileparts(fileinput);
376if isequal(ext,'.xml')
377    msgbox_uvmat('ERROR','input file type not implemented')%A Faire: ouvrir le fichier pour naviguer
378elseif isequal(ext,'.xls')
379    msgbox_uvmat('ERROR','input file type not implemented')%A Faire: ouvrir le fichier pour naviguer
380else
381    display_file_name(handles,fileinput,'append')
382end
383
384% --------------------------------------------------------------------
385function MenuFile_insert_1_Callback(hObject, eventdata, handles)
386% --------------------------------------------------------------------   
387fileinput=get(handles.MenuFile_insert_1,'Label');
388display_file_name(handles,fileinput,'append')
389
390% --------------------------------------------------------------------
391function MenuFile_insert_2_Callback(hObject, eventdata, handles)
392% --------------------------------------------------------------------   
393fileinput=get(handles.MenuFile_insert_2,'Label');
394display_file_name(handles,fileinput,'append')
395
396% --------------------------------------------------------------------
397function MenuFile_insert_3_Callback(hObject, eventdata, handles)
398% --------------------------------------------------------------------   
399fileinput=get(handles.MenuFile_insert_3,'Label');
400display_file_name( handles,fileinput,'append')
401
402% --------------------------------------------------------------------
403function MenuFile_insert_4_Callback(hObject, eventdata, handles)
404% --------------------------------------------------------------------   
405fileinput=get(handles.MenuFile_insert_4,'Label');
406display_file_name( handles,fileinput,'append')
407
408% --------------------------------------------------------------------
409function MenuFile_insert_5_Callback(hObject, eventdata, handles)
410% --------------------------------------------------------------------   
411fileinput=get(handles.MenuFile_insert_5,'Label');
412display_file_name(handles,fileinput,'append')
413
414%------------------------------------------------------------------------
415% --- Executes when entered data in editable cell(s) in InputTable.
416function InputTable_CellEditCallback(hObject, eventdata, handles)
417%------------------------------------------------------------------------
418set(handles.REFRESH,'Visible','on')
419iview=eventdata.Indices(1);
420view_set=get(handles.REFRESH,'UserData');
421if isempty(find(view_set==iview))
422    set(handles.REFRESH,'UserData',[view_set iview])
423end
424%% enable other menus and uicontrols
425set(handles.MenuOpen_insert,'Enable','on')
426set(handles.MenuFile_insert_1,'Enable','on')
427set(handles.MenuFile_insert_2,'Enable','on')
428set(handles.MenuFile_insert_3,'Enable','on')
429set(handles.MenuFile_insert_4,'Enable','on')
430set(handles.MenuFile_insert_5,'Enable','on')
431set(handles.RUN, 'Enable','On')
432set(handles.RUN,'BackgroundColor',[1 0 0])% set RUN button to red
433
434%update the output dir
435% SubDir=sort(InputTable(:,2)); %set of subdirectories sorted in alphabetical order
436% SubDirOut=SubDir{1};
437% if numel(SubDir)>1
438%     for ilist=2:numel(SubDir)
439%         SubDirOut=[SubDirOut '-' SubDir{ilist}];
440%     end
441% end
442% set(handles.OutputSubDir,'String',SubDirOut)
443
444%------------------------------------------------------------------------
445% --- Executes on button press in REFRESH.
446function REFRESH_Callback(hObject, eventdata, handles)
447%------------------------------------------------------------------------
448InputTable=get(handles.InputTable,'Data');
449view_set=get(handles.REFRESH,'UserData');
450set(handles.REFRESH,'BackgroundColor',[0.7 0.7 0.7])% set REFRESH  button to grey color
451drawnow
452for iview=view_set
453    RootPath=fullfile(InputTable{iview,1},InputTable{iview,2});
454    if ~exist(RootPath,'dir')
455        i1_series=[];
456        RootPath=fileparts(RootPath); %will try the upped forldr
457    else
458        [RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,tild,FileType,MovieObject]=...
459            find_file_series(fullfile(InputTable{iview,1},InputTable{iview,2}),[InputTable{iview,3} InputTable{iview,4} InputTable{iview,5}]);
460    end
461    if isempty(i1_series)
462        [FileName, PathName, filterindex] = uigetfile( ...
463            {'*.xml;*.xls;*.png;*.tif;*.avi;*.AVI;*.nc', ' (*.xml,*.xls, *.png,*.tif, *.avi,*.nc)';
464            '*.xml',  '.xml files '; ...
465            '*.xls',  '.xls files '; ...
466            '*.png','.png image files'; ...
467            '*.tif','.tif image files'; ...
468            '*.avi;*.AVI','.avi movie files'; ...
469            '*.nc','.netcdf files'; ...
470            '*.*',  'All Files (*.*)'}, ...
471            ['unvalid entry at line ' num2str(iview) ', pick a file'],RootPath);
472        fileinput=[PathName FileName];%complete file name
473        if isempty(fileinput),return;end %abandon if the operation has been cancelled: no input from browser
474        [path,name,ext]=fileparts(fileinput);
475        display_file_name(handles,fileinput,iview)
476    else
477        update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,MovieObject,iview)
478    end
479end
480set(handles.REFRESH,'BackgroundColor',[1 0 0])% set REFRESH  button to grey color
481set(handles.REFRESH,'Visible','off')
482set(handles.REFRESH,'UserData',[])
483
484%------------------------------------------------------------------------
485% --- Function called when a new file is opened, either by series_OpeningFcn or by the browser
486function display_file_name(handles,fileinput,iview)
487%------------------------------------------------------------------------ 
488%
489% INPUT:
490% handles: handles of elements in the GUI
491% fielinput: input file name, including path
492% append =0 (refresh the Input table with the new file), ='append' append a new line in the table
493
494%% get the input root name, indices, file extension and nomenclature NomType
495if ~exist(fileinput,'file')
496    msgbox_uvmat('ERROR',['input file ' fileinput  ' does not exist'])
497    return
498end
499
500%% enable other menus and uicontrols
501set(handles.MenuOpen_insert,'Enable','on')
502set(handles.MenuFile_insert_1,'Enable','on')
503set(handles.MenuFile_insert_2,'Enable','on')
504set(handles.MenuFile_insert_3,'Enable','on')
505set(handles.MenuFile_insert_4,'Enable','on')
506set(handles.MenuFile_insert_5,'Enable','on')
507set(handles.RUN, 'Enable','On')
508set(handles.RUN,'BackgroundColor',[1 0 0])% set RUN button to red
509set(handles.InputTable,'BackgroundColor',[1 1 0]) % set RootPath edit box  to yellow
510drawnow
511
512%% detect root name, nomenclature and indices in the input file name:
513[FilePath,FileName,FileExt]=fileparts(fileinput);
514% detect the file type, get the movie object if relevant, and look for the corresponding file series:
515% the root name and indices may be corrected by including the first index i1 if a corresponding xml file exists
516[RootPath,SubDir,RootFile,i1_series,i2_series,j1_series,j2_series,NomType,FileType,MovieObject,i1,i2,j1,j2]=find_file_series(FilePath,[FileName FileExt]);
517if isempty(RootFile)&&isempty(i1_series)
518    errormsg='no input file in the series';
519    return
520end
521
522%% fill the list of file series
523InputTable=get(handles.InputTable,'Data');
524if strcmp(iview,'append') % display the input data as a new line in the table
525     iview=size(InputTable,1);
526     InputTable(iview+1,:)={'','','','',''};
527     InputTable(iview,:)=[{RootPath},{SubDir},{RootFile},{NomType},{FileExt}];
528elseif iview==0 % or re-initialise the list of  input  file series
529    iview=1;
530    InputTable=[{'','','','',''};{'','','','',''}];
531     InputTable(iview,:)=[{RootPath},{SubDir},{RootFile},{NomType},{FileExt}];
532    set(handles.TimeTable,'Data',[{[]},{[]},{[]},{[]}])
533    set(handles.MinIndex,'Data',[{[]},{[]}])
534    set(handles.MaxIndex,'Data',[{[]},{[]}])
535    set(handles.ListView,'Value',1)
536    set(handles.ListView,'String',{'1'})
537end
538nbview=size(InputTable,1);
539set(handles.ListView,'String',mat2cell((1:nbview)',ones(nbview,1)))
540set(handles.ListView,'Value',iview)
541set(handles.InputTable,'Data',InputTable)
542
543%% determine the selected reference field indices for pair display
544ref_i=1; %default ref_i is a reference frame index used to find existing pairs from PIV
545if ~isempty(i1)
546    ref_i=i1;
547    if ~isempty(i2)
548        ref_i=floor((ref_i+i2)/2);% reference image number corresponding to the file
549    end
550end
551set(handles.num_ref_i,'String',num2str(ref_i));
552ref_j=1; %default  ref_j is a reference frame index used to find existing pairs from PIV
553if ~isempty(j1)
554    ref_j=j1;
555    if ~isempty(j2)
556        ref_j=floor((j1+j2)/2);
557    end         
558end
559set(handles.num_ref_j,'String',num2str(ref_j));
560
561%% update the list of recent files in the menubar and save it for future opening
562MenuFile=[{get(handles.MenuFile_1,'Label')};{get(handles.MenuFile_2,'Label')};...
563    {get(handles.MenuFile_3,'Label')};{get(handles.MenuFile_4,'Label')};{get(handles.MenuFile_5,'Label')}];
564str_find=strcmp(fileinput,MenuFile);
565if isempty(find(str_find,1))
566    MenuFile=[{fileinput};MenuFile];%insert the current file if not already in the list
567end
568for ifile=1:min(length(MenuFile),5)
569    eval(['set(handles.MenuFile_' num2str(ifile) ',''Label'',MenuFile{ifile});'])
570    eval(['set(handles.MenuFile_insert_' num2str(ifile) ',''Label'',MenuFile{ifile});'])
571end
572dir_perso=prefdir;
573profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
574if exist(profil_perso,'file')
575    save (profil_perso,'MenuFile','-append'); %store the file names for future opening of uvmat
576else
577    save (profil_perso,'MenuFile','-V6'); %store the file names for future opening of uvmat
578end
579
580set(handles.InputTable,'BackgroundColor',[1 1 1])
581
582%% initiate input file series and refresh the current field view:     
583update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,MovieObject,iview);
584
585%------------------------------------------------------------------------
586% --- Update information about a new field series (indices to scan, timing,
587%     calibration from an xml file
588function update_rootinfo(handles,i1_series,i2_series,j1_series,j2_series,FileType,VideoObject,iview)
589%------------------------------------------------------------------------
590%% update the output dir
591InputTable=get(handles.InputTable,'Data');
592SubDir=sort(InputTable(1:end-1,2)); %set of subdirectories sorted in alphabetical order
593SubDirOut=SubDir{1};
594if numel(SubDir)>1
595    for ilist=2:numel(SubDir)
596        SubDirOut=[SubDirOut '-' SubDir{ilist}];
597    end
598end
599set(handles.OutputSubDir,'String',SubDirOut)
600
601%% display the min and max indices for the file series
602if size(i1_series,2)==2 && min(min(i1_series(:,1,:)))==0
603    MinIndex_j=1;
604    MaxIndex_j=1;
605    MinIndex_i=find(i1_series(:,2,:), 1 )-1;
606    MaxIndex_i=find(i1_series(:,2,:), 1, 'last' )-1;
607else
608    pair_max=squeeze(max(i1_series,[],1)); %max on pair index
609    j_max=max(pair_max,[],1);
610    %i_sum=sum(sum(i1_series,2),1);%sum of i1_series on the last index
611    MaxIndex_i=find(j_max, 1, 'last' )-1;% max ref index i
612    MinIndex_i=find(j_max, 1 )-1;% min ref index i
613    diff_i_max=diff(j_max);
614    if isequal (diff_i_max,diff_i_max(1)*ones(size(diff_i_max)))
615        set(handles.num_incr_i,'String',num2str(diff_i_max(1)))
616    end
617    i_max=max(pair_max,[],2);
618    MaxIndex_j=max(find(i_max))-1;% max ref index i
619    MinIndex_j=min(find(i_max))-1;% min ref index i
620    diff_j_max=diff(i_max);
621    if isequal (diff_j_max,diff_j_max(1)*ones(size(diff_j_max)))
622        set(handles.num_incr_j,'String',num2str(diff_j_max(1)))
623    end
624end
625MinIndex=get(handles.MinIndex,'Data');%retrieve the min indices in the table MinIndex
626MaxIndex=get(handles.MaxIndex,'Data');%retrieve the max indices in the table MaxIndex
627if isequal(MinIndex_i,-1)
628    MinIndex_i=0;
629end
630if isequal(MinIndex_j,-1)
631    MinIndex_j=0;
632end
633MinIndex{iview,1}=MinIndex_i;
634MinIndex{iview,2}=MinIndex_j;
635MaxIndex{iview,1}=MaxIndex_i;
636MaxIndex{iview,2}=MaxIndex_j;
637
638set(handles.MinIndex,'Data',MinIndex)%display the min indices in the table MinIndex
639set(handles.MaxIndex,'Data',MaxIndex)%display the max indices in the table MaxIndex
640
641%% adjust the first and last indices if requested by the bounds
642first_i=str2num(get(handles.num_first_i,'String'));
643ref_i=str2num(get(handles.num_ref_i,'String'));
644ref_j=str2num(get(handles.num_ref_j,'String'));
645if isempty(first_i)
646    first_i=ref_i;
647elseif first_i < MinIndex_i
648    first_i=MinIndex_i;
649elseif first_i >MaxIndex_i
650    first_i=MinIndex_i;
651end
652first_j=str2num(get(handles.num_first_j,'String'));
653if isempty(first_j)
654    first_j=ref_j;
655elseif first_j<MinIndex_j
656    first_j=MinIndex_j;
657elseif first_j >MaxIndex_j
658    first_j=MinIndex_j;
659end
660last_i=str2num(get(handles.num_last_i,'String'));
661if isempty(last_i)
662    last_i=ref_i;
663elseif last_i > MaxIndex_i
664    last_i=MaxIndex_i;
665elseif last_i<first_i
666    last_i=first_i;
667end
668last_j=str2num(get(handles.num_first_j,'String'));
669if isempty(last_j)
670    last_j=ref_j;
671elseif last_j>MaxIndex_j
672    last_j=MaxIndex_j;
673elseif last_i<first_i
674    last_i=first_i;
675end
676set(handles.num_first_i,'String',num2str(first_i));
677set(handles.num_first_j,'String',num2str(first_j));
678set(handles.num_last_i,'String',num2str(last_i));
679set(handles.num_last_j,'String',num2str(last_j));
680
681%% read timing and total frame number from the current file (movie files) may be overrid by xml file
682InputTable=get(handles.InputTable,'Data');
683FileBase=fullfile(InputTable{iview,1},InputTable{iview,3});
684time=[];%default
685% case of movies
686if strcmp(InputTable{iview,4},'*')
687    if ~isempty(VideoObject)
688        imainfo=get(VideoObject);
689        time=(0:1/imainfo.FrameRate:(imainfo.NumberOfFrames-1)/imainfo.FrameRate)';
690       % set(handles.Dt_txt,'String',['Dt=' num2str(1000/imainfo.FrameRate) 'ms']);%display the elementary time interval in millisec
691        ColorType='truecolor';
692    elseif ~isempty(imformats(regexprep(InputTable{iview,5},'^.',''))) || isequal(InputTable{iview,5},'.vol')%&& isequal(NomType,'*')% multi-frame image
693        if ~isempty(InputTable{iview,2})
694            imainfo=imfinfo(fullfile(InputTable{iview,1},InputTable{iview,2},[InputTable{iview,3} InputTable{iview,5}]));
695        else
696            imainfo=imfinfo([FileBase InputTable{iview,5}]);
697        end
698        ColorType=imainfo.ColorType;%='truecolor' for color images
699        if length(imainfo) >1 %case of image with multiple frames
700            nbfield=length(imainfo);
701            nbfield_j=1;
702        end
703    end
704end
705
706%%  read image documentation file  if found%%%%%%%%%%%%%%%%%%%%%%%%%%%
707XmlData=[];
708NbSlice_calib={};
709XmlFileName=find_imadoc(InputTable{iview,1},InputTable{iview,2},InputTable{iview,3},InputTable{iview,5});
710if ~isempty(XmlFileName)
711        [XmlData,warntext]=imadoc2struct(XmlFileName);
712        if isfield(XmlData,'Heading') && isfield(XmlData.Heading,'ImageName') && ischar(XmlData.Heading.ImageName)
713            [PP,FF,ext_ima_read]=fileparts(XmlData.Heading.ImageName);
714        end
715        if isfield(XmlData,'Time')
716            time=XmlData.Time;
717        end
718        if isfield(XmlData,'Camera')
719            if isfield(XmlData.Camera,'NbSlice')&& ~isempty(XmlData.Camera.NbSlice)
720                NbSlice_calib{iview}=XmlData.Camera.NbSlice;% Nbre of slices for Zindex in phys transform
721                if ~isequal(NbSlice_calib{iview},NbSlice_calib{1})
722                    msgbox_uvmat('WARNING','inconsistent number of Z indices for the two field series');
723                end
724            end
725            if isfield(XmlData.Camera,'TimeUnit')&& ~isempty(XmlData.Camera.TimeUnit)
726                TimeUnit=XmlData.Camera.TimeUnit;
727            end
728        end
729        if ~isempty(warntext)
730            msgbox_uvmat('WARNING',warntext)
731        end 
732end
733
734%% update time table
735if ~isempty(time)
736    TimeTable=get(handles.TimeTable,'Data');
737    first_i=str2num(get(handles.num_first_i,'String'));
738    last_i=str2num(get(handles.num_last_i,'String'));
739    first_j=str2num(get(handles.num_first_j,'String'));
740    last_j=str2num(get(handles.num_last_j,'String'));
741    MinIndexTable=get(handles.MinIndex,'Data');
742    MinIndex_i=MinIndexTable{iview,1};
743    MinIndex_j=MinIndexTable{iview,2};
744    MaxIndexTable=get(handles.MaxIndex,'Data');
745    MaxIndex_i=MaxIndexTable{iview,1};
746    MaxIndex_j=MaxIndexTable{iview,2};
747    if isempty(MinIndex_j)% only i index
748        if MinIndex_i>0
749            TimeTable{iview,1}=time(MinIndex_i);
750        end
751        TimeTable{iview,2}=time(first_i);
752        TimeTable{iview,3}=time(last_i);
753        TimeTable{iview,4}=time(MaxIndex_i);
754    elseif ~isempty(time)
755        if MinIndex_i>0
756            TimeTable{iview,1}=time(MinIndex_i,MinIndex_j);
757        end
758        if size(time)>=[last_i last_j]
759            TimeTable{iview,2}=time(first_i,first_j);
760            TimeTable{iview,3}=time(last_i,last_j);
761        end
762        if size(time)>=[MaxIndex_i MaxIndex_j];
763            TimeTable{iview,4}=time(MaxIndex_i,MaxIndex_j);
764        end
765    end
766    set(handles.TimeTable,'Data',TimeTable)
767end
768
769%% number of slices
770NbSlice=1;%default
771if isfield(XmlData,'GeometryCalib') && isfield(XmlData.GeometryCalib,'SliceCoord')
772    siz=size(XmlData.GeometryCalib.SliceCoord);
773    if siz(1)>1
774        NbSlice=siz(1);
775    end
776end
777set(handles.num_NbSlice,'String',num2str(NbSlice))
778   
779%% update pair menus
780set(handles.Pairs,'Visible','on')
781set(handles.PairString,'Visible','on')
782ListView=get(handles.ListView,'String');
783ListView{iview}=num2str(iview);
784set(handles.ListView,'String',ListView);
785set(handles.ListView,'Value',iview)
786update_mode(handles,i1_series,i2_series,j1_series,j2_series,time)
787
788%% update the series info in 'UserData'
789SeriesData=get(handles.series,'UserData');
790SeriesData.i1_series{iview}=i1_series;
791SeriesData.i2_series{iview}=i2_series;
792SeriesData.j1_series{iview}=j1_series;
793SeriesData.j2_series{iview}=j2_series;
794SeriesData.FileType{iview}=FileType;
795SeriesData.Time{iview}=time;
796set(handles.series,'UserData',SeriesData)
797
798%% enable j index visibilitycellfun(@isempty,regexp(PairString,'^j'))
799% state='off';
800check_jindex=~cellfun(@isempty,SeriesData.j1_series); %look for non empty j indices
801if isempty(find(check_jindex))
802    enable_j(handles,'off') % no j index needed
803else
804    PairString=get(handles.PairString,'Data');
805    if isempty(find(cellfun(@isempty,regexp(PairString,'^j'))))% if all pair string begins by j (burst)
806        enable_j(handles,'off') % no j index needed
807    else
808        enable_j(handles,'on')
809    end
810end
811
812%% display the set of existing files as an image
813set(handles.FileStatus,'Units','pixels')
814Position=get(handles.FileStatus,'Position');
815set(handles.FileStatus,'Units','normalized')
816xI=0.5:Position(3)-0.5;
817nbview=numel(SeriesData.i1_series);
818pair_max=cell(1,nbview);
819for iview=1:nbview
820    pair_max{iview}=squeeze(max(SeriesData.i1_series{iview},[],1)); %max on pair index
821    if (strcmp(get(handles.num_first_j,'Visible'),'off')&& size(pair_max{iview},2)~=1)
822        pair_max{iview}=squeeze(max(pair_max{iview},[],1)); % consider only the i index
823    end
824    index_min(iview)=find(pair_max{iview}>0, 1 );
825    index_max(iview)=find(pair_max{iview}>0, 1, 'last' );
826end
827index_min=min(index_min);
828index_max=max(index_max);
829range_index=index_max-index_min+1;
830scale_y=Position(4)/nbview;
831scale_x=Position(3)/range_index;
832x=(0.5:range_index-0.5)*Position(3)/range_index;
833% y=(0.5:nbview-0.5)*Position(4)/nbview;
834range_y=max(1,floor(Position(4)/nbview));
835CData=zeros(nbview*range_y,Position(3));
836for iview=1:nbview
837    ind_y=1+(iview-1)*range_y:iview*range_y;
838    LineData=zeros(1,range_index);
839    x_index=find(pair_max{iview}>0)-index_min+1;
840    LineData(x_index)=1;
841    if numel(x)>1
842    LineData=interp1(x,LineData,xI,'nearest');
843    CData(ind_y,:)=ones(size(ind_y'))*LineData;
844    end
845end
846CData=cat(3,zeros(size(CData)),CData,zeros(size(CData)));
847set(handles.FileStatus,'CData',CData);
848
849
850%% enable field and veltype menus, in accordance with the current action
851ActionName_Callback([],[], handles)
852
853%% check for pair display
854check_pairs=0;
855for iview=1:numel(SeriesData.i2_series)
856    if ~isempty(SeriesData.i2_series{iview})||~isempty(SeriesData.j2_series{iview})
857        check_pairs=1;
858    end
859end
860if check_pairs
861    set(handles.Pairs,'Visible','on')
862    set(handles.PairString,'Visible','on')
863else
864    set(handles.Pairs,'Visible','off')
865    set(handles.PairString,'Visible','off')
866end
867
868%% set length of waitbar
869displ_time(handles)
870
871
872%% set default options in menu 'Fields'
873switch FileType
874    case {'civx','civdata'}
875        [FieldList,ColorList]=calc_field;
876        set(handles.FieldName,'String',[{'image'};FieldList;{'get_field...'}]);%standard menu for civx data
877        set(handles.FieldName,'Value',2) % set menu to 'velocity
878        set(handles.Coord_x,'Value',1);
879        set(handles.Coord_x,'String',{'X'});
880        set(handles.Coord_y,'Value',1);
881        set(handles.Coord_y,'String',{'Y'});
882    case 'netcdf'
883        set(handles.FieldName,'Value',1)
884        set(handles.FieldName,'String',{'get_field...'})
885        if isempty(i2_series)
886            i2=[];
887        else
888            i2=i2_series(1,ref_j+1,ref_i+1);
889        end
890        if isempty(j1_series)
891            j1=[];j2=[];
892        else
893            j1=j1_series(1,ref_j+1,ref_i+1);
894            if isempty(j2_series)
895                j2=[];
896            else
897                j2=j2_series(1,ref_j+1,ref_i+1);
898            end
899        end
900        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);
901        hget_field=get_field(FileName);
902        hhget_field=guidata(hget_field);
903        get_field('RUN_Callback',hhget_field.RUN,[],hhget_field);
904    otherwise
905        set(handles.FieldName,'Value',1) % set menu to 'image'
906        set(handles.FieldName,'String',{'image'})
907        set(handles.Coord_x,'Value',1);
908        set(handles.Coord_x,'String',{'AX'});
909        set(handles.Coord_y,'Value',1);
910        set(handles.Coord_y,'String',{'AY'});
911end
912
913%------------------------------------------------------------------------
914function num_first_i_Callback(hObject, eventdata, handles)
915%------------------------------------------------------------------------
916num_last_i_Callback(hObject, eventdata, handles)
917
918%------------------------------------------------------------------------
919function num_last_i_Callback(hObject, eventdata, handles)
920%------------------------------------------------------------------------
921SeriesData=get(handles.series,'UserData');
922if ~isfield(SeriesData,'Time')
923    SeriesData.Time{1}=[];
924end
925displ_time(handles);
926
927%------------------------------------------------------------------------
928function num_first_j_Callback(hObject, eventdata, handles)
929%------------------------------------------------------------------------
930 num_last_j_Callback(hObject, eventdata, handles)
931
932%------------------------------------------------------------------------
933function num_last_j_Callback(hObject, eventdata, handles)
934%------------------------------------------------------------------------
935first_j=str2num(get(handles.num_first_j,'String'));
936last_j=str2num(get(handles.num_last_j,'String'));
937ref_j=ceil((first_j+last_j)/2);
938set(handles.num_ref_j,'String', num2str(ref_j))
939num_ref_j_Callback(hObject, eventdata, handles)
940SeriesData=get(handles.series,'UserData');
941if ~isfield(SeriesData,'Time')
942    SeriesData.Time{1}=[];
943end
944displ_time(handles);
945
946
947%------------------------------------------------------------------------
948% ---- find the times corresponding to the first and last indices of a series
949function displ_time(handles)
950%------------------------------------------------------------------------
951SeriesData=get(handles.series,'UserData');%
952ref_i=[str2num(get(handles.num_first_i,'String')) str2num(get(handles.num_last_i,'String'))];
953ref_j=[str2num(get(handles.num_first_j,'String')) str2num(get(handles.num_last_j,'String'))];
954TimeTable=get(handles.TimeTable,'Data');
955Pairs=get(handles.PairString,'Data');
956for iview=1:size(TimeTable,1)
957    if size(SeriesData.Time,1)<iview
958        break
959    end
960    i1=ref_i;
961    j1=ref_j;
962    i2=ref_i;
963    j2=ref_j;
964    % case of pairs
965    if ~isempty(Pairs{iview,1})
966        r=regexp(Pairs{iview,1},'(?<mode>(Di=)|(Dj=)) -*(?<num1>\d+)\|(?<num2>\d+)','names');
967        if isempty(r)
968            r=regexp(Pairs{iview,1},'(?<num1>\d+)(?<mode>-)(?<num2>\d+)','names');
969        end
970        switch r.mode
971            case 'Di='  %  case 'series(Di)')
972                i1=ref_i-str2num(r.num1);
973                i2=ref_i+str2num(r.num2);
974            case 'Dj='  %  case 'series(Dj)'
975                j1=ref_j-str2num(r.num1);
976                j2=ref_j+str2num(r.num2);
977            case '-'  % case 'bursts'
978                j1=str2num(r.num1)*ones(size(ref_i));
979                j2=str2num(r.num2)*ones(size(ref_i));
980        end
981    end
982    TimeTable{iview,2}=[];
983    TimeTable{iview,3}=[];
984    if size(SeriesData.Time{iview},1)>=i2(2)&&size(SeriesData.Time{iview},1)>=j2(2)
985        if isempty(ref_j)
986            time_first=(SeriesData.Time{iview}(i1(1))+SeriesData.Time{iview}(i2(1)))/2;
987            time_last=(SeriesData.Time{iview}(i1(2))+SeriesData.Time{iview}(i2(2)))/2;
988        else
989            time_first=(SeriesData.Time{iview}(i1(1),j1(1))+SeriesData.Time{iview}(i2(1),j2(1)))/2;
990            time_last=(SeriesData.Time{iview}(i1(2),j1(2))+SeriesData.Time{iview}(i2(2),j2(2)))/2;
991        end
992        TimeTable{iview,2}=time_first; %TODO: take into account pairs
993        TimeTable{iview,3}=time_last; %TODO: take into account pairs
994    end
995end
996set(handles.TimeTable,'Data',TimeTable)
997
998%% set the waitbar position with respect to the min and max in the series
999for iview=1:numel(SeriesData.i1_series)
1000    pair_max{iview}=squeeze(max(SeriesData.i1_series{iview},[],1)); %max on pair index
1001    if (strcmp(get(handles.num_first_j,'Visible'),'off')&& size(pair_max{iview},2)~=1)
1002        pair_max{iview}=squeeze(max(pair_max{iview},[],1)); % consider only the i index
1003    end
1004    pair_max{iview}=reshape(pair_max{iview},1,[]);
1005    index_min(iview)=find(pair_max{iview}>0, 1 );
1006    index_max(iview)=find(pair_max{iview}>0, 1, 'last' );
1007end
1008[index_min,iview_min]=min(index_min);
1009[index_max,iview_max]=min(index_max);
1010if size(SeriesData.i1_series{iview_min},2)==1% movie
1011    index_first=ref_i(1);
1012    index_last=ref_i(2);
1013else
1014    index_first=(ref_i(1)-1)*(size(SeriesData.i1_series{iview_min},1))+ref_j(1)+1;
1015    index_last=(ref_i(2)-1)*(size(SeriesData.i1_series{iview_max},1))+ref_j(2)+1;
1016end
1017range=index_max-index_min+1;
1018coeff_min=(index_first-index_min)/range;
1019coeff_max=(index_last-index_min+1)/range;
1020Position=get(handles.Waitbar,'Position');% position of the waitbar:= [ x,y, width, height]
1021Position_status=get(handles.FileStatus,'Position');
1022Position(1)=coeff_min*Position_status(3)+Position_status(1);
1023Position(3)=Position_status(3)*(coeff_max-coeff_min);
1024set(handles.Waitbar,'Position',Position)
1025update_waitbar(handles.Waitbar,0)
1026
1027%------------------------------------------------------------------------
1028% --- Executes when selected cell(s) is changed in PairString.
1029function PairString_CellSelectionCallback(hObject, eventdata, handles)
1030%------------------------------------------------------------------------   
1031set(handles.ListView,'Value',eventdata.Indices(1))% detect the selected raw index
1032ListView_Callback ([],[],handles) % update the list of available pairs
1033
1034%------------------------------------------------------------------------
1035%------------------------------------------------------------------------
1036%  III - FUNCTIONS ASSOCIATED TO THE FRAME SET PAIRS
1037%------------------------------------------------------------------------
1038%------------------------------------------------------------------------
1039% --- Executes on selection change in ListView.
1040function ListView_Callback(hObject, eventdata, handles)
1041%------------------------------------------------------------------------   
1042SeriesData=get(handles.series,'UserData');
1043i2_series=[];
1044j2_series=[];
1045iview=get(handles.ListView,'Value');
1046if ~isempty(SeriesData.i2_series{iview})
1047    i2_series=SeriesData.i2_series{iview};
1048end
1049if ~isempty(SeriesData.j2_series{iview})
1050    j2_series=SeriesData.j2_series{iview};
1051end
1052update_mode(handles,SeriesData.i1_series{iview},SeriesData.i2_series{iview},...
1053    SeriesData.j1_series{iview},SeriesData.j2_series{iview},SeriesData.Time{iview})
1054
1055%------------------------------------------------------------------------
1056% --- Executes on button press in mode.
1057function mode_Callback(hObject, eventdata, handles)
1058%------------------------------------------------------------------------       
1059SeriesData=get(handles.series,'UserData');
1060iview=get(handles.ListView,'Value');
1061mode_list=get(handles.mode,'String');
1062mode=mode_list{get(handles.mode,'Value')};
1063if isequal(mode,'bursts')
1064    enable_i(handles,'On')
1065    enable_j(handles,'Off') %do not display j index scanning in burst mode (j is fixed by the burst choice)
1066else
1067    enable_i(handles,'On')
1068    enable_j(handles,'Off')
1069end
1070fill_ListPair(handles,SeriesData.i1_series{iview},SeriesData.i2_series{iview},...
1071    SeriesData.j1_series{iview},SeriesData.j2_series{iview},SeriesData.Time{iview})
1072ListPairs_Callback([],[],handles)
1073
1074%-------------------------------------------------------------
1075% --- Executes on selection in ListPairs.
1076function ListPairs_Callback(hObject,eventdata,handles)
1077%------------------------------------------------------------
1078list_pair=get(handles.ListPairs,'String');%get the menu of image pairs
1079if isempty(list_pair)
1080    string='';
1081else
1082    string=list_pair{get(handles.ListPairs,'Value')};
1083    string=regexprep(string,',.*','');%removes time indication (after ',')
1084end
1085PairString=get(handles.PairString,'Data');
1086iview=get(handles.ListView,'Value');
1087PairString{iview,1}=string;
1088% report the selected pair string to the table PairString
1089set(handles.PairString,'Data',PairString)
1090
1091%------------------------------------------------------------------------
1092function num_ref_i_Callback(hObject, eventdata, handles)
1093%------------------------------------------------------------------------
1094mode_list=get(handles.mode,'String');
1095mode=mode_list{get(handles.mode,'Value')};
1096SeriesData=get(handles.series,'UserData');
1097iview=get(handles.ListView,'Value');
1098fill_ListPair(handles,SeriesData.i1_series{iview},SeriesData.i2_series{iview},...
1099    SeriesData.j1_series{iview},SeriesData.j2_series{iview},SeriesData.Time{iview});% update the menu of pairs depending on the available netcdf files
1100ListPairs_Callback([],[],handles)
1101
1102%------------------------------------------------------------------------
1103function num_ref_j_Callback(hObject, eventdata, handles)
1104%------------------------------------------------------------------------
1105num_ref_i_Callback(hObject, eventdata, handles)
1106
1107%------------------------------------------------------------------------
1108function update_mode(handles,i1_series,i2_series,j1_series,j2_series,time)
1109%------------------------------------------------------------------------   
1110% check_burst=0;
1111if isempty(j2_series)% no j pair
1112    if isempty(i2_series)
1113        set(handles.mode,'Value',1)
1114        set(handles.mode,'String',{''})% no pair menu to display
1115    else   
1116        set(handles.mode,'Value',1)
1117        set(handles.mode,'String',{'series(Di)'}) % pair menu with only option Di
1118    end
1119else %existence of j pairs
1120    pair_max=squeeze(max(i1_series,[],1)); %max on pair index
1121    j_max=max(pair_max,[],1);
1122    MaxIndex_i=max(find(j_max))-1;% max ref index i
1123    MinIndex_i=min(find(j_max))-1;% min ref index i
1124    i_max=max(pair_max,[],2);
1125    MaxIndex_j=max(find(i_max))-1;% max ref index i
1126    MinIndex_j=min(find(i_max))-1;% min ref index i
1127    if MaxIndex_j==MinIndex_j
1128        set(handles.mode,'Value',1);
1129        set(handles.mode,'String',{'bursts'})
1130%         check_burst=1;
1131    elseif MaxIndex_i==MinIndex_i
1132        set(handles.mode,'Value',1);
1133        set(handles.mode,'String',{'series(Dj)'})
1134    else
1135        set(handles.mode,'String',{'bursts';'series(Dj)'})
1136        if (MaxIndex_j-MinIndex_j)>10
1137            set(handles.mode,'Value',2);%set mode to series(Dj) if more than 10 j values
1138        else
1139            set(handles.mode,'Value',1);
1140%             check_burst=1;
1141        end
1142    end
1143end
1144% if check_burst
1145%     enable_i(handles,'On')
1146%     enable_j(handles,'Off') %do not display j index scanning in burst mode (j is fixed by the burst choice)
1147% else
1148%     enable_i(handles,'On')
1149%     if isempty(j1_series)
1150%          enable_j(handles,'Off')
1151%     else
1152%         enable_j(handles,'On')
1153%     end
1154% end
1155fill_ListPair(handles,i1_series,i2_series,j1_series,j2_series,time)
1156ListPairs_Callback([],[],handles)
1157
1158%--------------------------------------------------------------
1159% determine the menu for civ1 pairstring depending on existing netcdf files
1160% with the reference indices num_ref_i and num_ref_j
1161%----------------------------------------------------------------
1162function fill_ListPair(handles,i1_series,i2_series,j1_series,j2_series,time)
1163
1164mode_list=get(handles.mode,'String');
1165mode=mode_list{get(handles.mode,'Value')};
1166ref_i=str2num(get(handles.num_ref_i,'String'));
1167if isempty(ref_i)
1168    ref_i=1;
1169end
1170if strcmp(get(handles.num_ref_j,'Visible'),'on')
1171    ref_j=str2num(get(handles.num_ref_j,'String'));
1172    if isempty(ref_j)
1173        ref_j=1;
1174    end
1175else
1176    ref_j=1;
1177end
1178TimeUnit=get(handles.TimeUnit,'String');
1179if length(TimeUnit)>=1
1180    dtunit=['m' TimeUnit];
1181else
1182    dtunit='e-03';
1183end
1184
1185displ_pair={};
1186if strcmp(mode,'series(Di)')
1187    if isempty(i2_series)
1188        msgbox_uvmat('ERROR','no i1-i2 pair available')
1189        return
1190    end
1191    diff_i=i2_series-i1_series;
1192    min_diff=min(diff_i(diff_i>0));
1193    max_diff=max(diff_i(diff_i>0));
1194    for ipair=min_diff:max_diff
1195        if numel(diff_i(diff_i==ipair))>0
1196            pair_string=['Di= ' num2str(-floor(ipair/2)) '|' num2str(ceil(ipair/2)) ];
1197            if ~isempty(time)
1198                if ref_i<=floor(ipair/2)
1199                    ref_i=floor(ipair/2)+1;% shift ref_i to get the first pair
1200                end
1201                Dt=time(ref_i+ceil(ipair/2),ref_j)-time(ref_i-floor(ipair/2),ref_j);
1202                pair_string=[pair_string ', Dt=' num2str(Dt) ' ' dtunit];
1203            end
1204            displ_pair=[displ_pair;{pair_string}];
1205        end
1206    end
1207    if ~isempty(displ_pair)
1208        displ_pair=[displ_pair;{'Di=*|*'}];
1209    end
1210elseif strcmp(mode,'series(Dj)')
1211    if isempty(j2_series)
1212        msgbox_uvmat('ERROR','no j1-j2 pair available')
1213        return
1214    end
1215    diff_j=j2_series-j1_series;
1216    min_diff=min(diff_j(diff_j>0));
1217    max_diff=max(diff_j(diff_j>0));
1218    for ipair=min_diff:max_diff
1219        if numel(diff_j(diff_j==ipair))>0
1220            pair_string=['Dj= ' num2str(-floor(ipair/2)) '|' num2str(ceil(ipair/2)) ];
1221            if ~isempty(time)
1222                if ref_j<=floor(ipair/2)
1223                    ref_j=floor(ipair/2)+1;% shift ref_i to get the first pair
1224                end
1225                Dt=time(ref_i,ref_j+ceil(ipair/2))-time(ref_i,ref_j-floor(ipair/2));
1226                pair_string=[pair_string ', Dt=' num2str(Dt) ' ' dtunit];
1227            end
1228            displ_pair=[displ_pair;{pair_string}];
1229        end
1230    end
1231    if ~isempty(displ_pair)
1232        displ_pair=[displ_pair;{'Dj=*|*'}];
1233    end
1234elseif strcmp(mode,'bursts')
1235    if isempty(j2_series)
1236        msgbox_uvmat('ERROR','no j1-j2 pair available')
1237        return
1238    end
1239    diff_j=j2_series-j1_series;
1240    min_j1=min(j1_series(j1_series>0));
1241    max_j1=max(j1_series(j1_series>0));
1242    min_j2=min(j2_series(j2_series>0));
1243    max_j2=max(j2_series(j2_series>0));
1244    for pair1=min_j1:min(max_j1,min_j1+20)
1245        for pair2=min_j2:min(max_j2,min_j2+20)
1246        if numel(j1_series(j1_series==pair1))>0 && numel(j2_series(j2_series==pair2))>0
1247            displ_pair=[displ_pair;{['j= ' num2str(pair1) '-' num2str(pair2)]}];
1248        end
1249        end
1250    end
1251    if ~isempty(displ_pair)
1252        displ_pair=[displ_pair;{'j=*-*'}];
1253    end
1254end
1255set(handles.num_ref_i,'String',num2str(ref_i)) % update ref_i and ref_j
1256set(handles.num_ref_j,'String',num2str(ref_j))
1257
1258%% display list of pairstring
1259displ_pair_list=get(handles.ListPairs,'String');
1260NewVal=[];
1261if ~isempty(displ_pair_list)
1262Val=get(handles.ListPairs,'Value');
1263NewVal=find(strcmp(displ_pair_list{Val},displ_pair),1);% look at the previous display in the new menu displ_pï¿œir
1264end
1265if ~isempty(NewVal)
1266    set(handles.ListPairs,'Value',NewVal)
1267else
1268    set(handles.ListPairs,'Value',1)
1269end
1270set(handles.ListPairs,'String',displ_pair)
1271
1272%-------------------------------------
1273function enable_i(handles,state)
1274set(handles.i_txt,'Visible',state)
1275set(handles.num_first_i,'Visible',state)
1276set(handles.num_last_i,'Visible',state)
1277set(handles.num_incr_i,'Visible',state)
1278% set(handles.num_MaxIndex_i,'Visible',state)
1279set(handles.num_ref_i,'Visible',state)
1280set(handles.ref_i_text,'Visible',state)
1281
1282%-----------------------------------
1283function enable_j(handles,state)
1284set(handles.j_txt,'Visible',state)
1285set(handles.num_first_j,'Visible',state)
1286set(handles.num_last_j,'Visible',state)
1287set(handles.num_incr_j,'Visible',state)
1288set(handles.num_ref_j,'Visible',state)
1289set(handles.ref_j_text,'Visible',state)
1290% if strcmp(state,'off')
1291%     set(handles.MinIndex,'ColumnName',{'imax'})
1292% set(handles.MinIndex,'ColumnEditable',logical(0))
1293% else
1294%         set(handles.MinIndex,'ColumnName',{'imax','jmax'})
1295% end
1296
1297
1298%%%%%%%%%%%%%%%%%%%%
1299%%  MAIN ActionName FUNCTIONS
1300%%%%%%%%%%%%%%%%%%%%
1301%------------------------------------------------------------------------
1302% --- Executes on button press in RUN.
1303function RUN_Callback(hObject, eventdata, handles)
1304%------------------------------------------------------------------------
1305set(handles.RUN,'BusyAction','queue');
1306set(0,'CurrentFigure',handles.series)
1307set(handles.RUN, 'Enable','Off')
1308set(handles.RUN,'BackgroundColor',[0.831 0.816 0.784])
1309drawnow
1310[h_fun,Series,filexml,errormsg]=prepare_jobs(handles);
1311if ~isempty(errormsg)
1312    msgbox_uvmat('ERROR',errormsg)
1313    return
1314end
1315RunModeList=get(handles.RunMode,'String');
1316RunMode=RunModeList{get(handles.RunMode,'Value')};
1317ActionExtList=get(handles.ActionExt,'String');
1318ActionExt=ActionExtList{get(handles.ActionExt,'Value')};% '.m' or '.sh' (compiled)
1319ActionPath=get(handles.ActionPath,'String');
1320ActionList=get(handles.ActionName,'String');
1321ActionName=ActionList{get(handles.ActionName,'Value')};
1322
1323%% set nbre of processes
1324if isfield(Series,'NbSlice')&&~isempty(Series.NbSlice)
1325    NbProcess=Series.NbSlice;
1326else
1327    switch RunMode
1328        case {'local','background'}
1329         NbCore=1;% no need to split the calculation
1330        case 'cluster'
1331            if strcmp(Series.Action.ActionExt,'.m')% case of Matlab function (uncompiled)
1332                NbCore=1;% one core used only (limitation of Matlab licences)
1333                msgbox_uvmat('WARNING','Number of cores =1: select the compiled version civ_matlab.sh for multi-core processing');
1334            else
1335            answer=inputdlg({'Number of cores (max 36)','extra oar options'},'oarsub parameter',1,{'12',''});
1336            NbCore=str2double(answer{1});
1337            end
1338    end
1339    NbProcess=NbCore;% choose one process per core
1340end
1341for iprocess=1:NbProcess% TOD0
1342%     split the input files
1343%     adjust Param
1344%     create xmlfile and batfile
1345end
1346switch RunMode
1347    case 'local'
1348        switch ActionExt
1349            case '.m'
1350                for iprocess=1:NbProcess
1351                    if ~isempty(filexml)
1352                        t=struct2xml(Series);
1353                        t=set(t,1,'name','Series');
1354                        save(t,filexml);
1355                    end
1356                    Series.RUNHandle=handles.RUN;
1357                    Series.WaitbarHandle=handles.Waitbar;
1358                    Series=h_fun(Series);
1359                end
1360            case '.sh'
1361                for iprocess=1:NbProcess
1362                    CivmBin=fullfile(ActionPath,[ActionName '.sh']); %path to the source directory of uvmat
1363                    switch computer
1364                        case {'PCWIN','PCWIN64'}
1365                            filename=regexprep(filename,'\\','\\\\');% add '\' so that '\' are left as characters
1366                            % TODO launch command in DOS
1367                        case {'GLNX86','GLNXA64','MACI64'}
1368                            cmd=['#!/bin/bash \n '...
1369                                '#$ -cwd \n '...
1370                                'hostname && date \n '...
1371                                'umask 002 \n'...
1372                                CivmBin ' ' Param.xml.RunTime ' ' regexprep(filename,'(.+)([/\\])(.+$)','$1$20_XML$2$3.xml') ' ' Param.OutputFile '.nc'];%allow writting access to created files for user group
1373                    end
1374                end
1375        end
1376    case 'background'
1377        if isempty(filexml)
1378            Series=h_fun(Series);% no background in the absence of output file
1379        else
1380            % update the xml file after interactive input with the function
1381%             Series.Specific='?';
1382%             Series=h_fun(Series);
1383            t=struct2xml(Series);
1384            t=set(t,1,'name','Series');
1385            save(t,filexml);
1386            path_uvmat=fileparts(which('uvmat'));
1387           
1388            filename_bat=regexprep(filexml,'.xml$','.bat');% create executable file to run program in background
1389            [fid,message]=fopen(filename_bat,'w');
1390            if isequal(fid,-1)
1391                msgbox_uvmat('ERROR', ['creation of .bat file: ' message]);
1392                return
1393            end
1394            %ActionPath=get(handles.ActionPath,'String');
1395            filelog=regexprep(filexml,'.xml$','.log');
1396       
1397            switch computer
1398                case {'GLNX86','GLNXA64','MACI64'}
1399                    text_matlabscript=[...
1400                        '#!/bin/bash \n'...
1401                        '. /etc/sysprofile \n'...
1402                        'matlab -nodisplay -nosplash -nojvm -logfile ''' filelog ''' <<END_MATLAB \n'...
1403                        'addpath(''' path_uvmat '''); \n'...
1404                        'addpath(''' Series.Action.ActionPath '''); \n'...
1405                        '' Series.Action.ActionName  '( ''' filexml '''); \n'...
1406                        'exit \n'...
1407                        'END_MATLAB \n'];
1408                    fprintf(fid,text_matlabscript);
1409                    fclose(fid);
1410                    system(['chmod +x ' filename_bat]);% set the file to executable
1411                    system(['. ' filename_bat ' &']);%execute fct
1412                   
1413                case {'PCWIN','PCWIN64'}
1414                    text_matlabscript=['matlab -automation -logfile ' regexprep(filelog,'\\','\\\\')...
1415                        ' -r "addpath(''' regexprep(path_uvmat,'\\','\\\\') ''');'...
1416                        'addpath(''' regexprep(Series.Action.ActionPath,'\\','\\\\') ''');'...
1417                        '' Series.Action.ActionName  '( ''' regexprep(filexml,'\\','\\\\') ''');exit"'];
1418                    fprintf(fid,text_matlabscript);
1419                    fclose(fid);
1420                    dos([filename_bat ' &']);
1421            end
1422        end
1423        update_waitbar(handles.Waitbar,1); % put the waitbar to end position to indicate launching is finished
1424     case 'cluster' %NOT YET READY
1425        switch batch_mode
1426            case 'sge' %at the moment only psmn ENS Lyon uses it
1427                for p=1:length(batch_file_list)
1428                    cmd=['!qsub -q piv1,piv2,piv3 '...
1429                        '-e ' regexprep(batch_file_list{p},'.bat','.errors') ' -o ' regexprep(batch_file_list{p},'.bat','.log ')...
1430                        ' -v ' 'LD_LIBRARY_PATH=/home/sjoubaud/matlab_sylvain/civx/lib ' batch_file_list{p}];
1431                    display(cmd);eval(cmd);
1432                end
1433            case 'oar'
1434                max_walltime=3600*12; % 12h max
1435                oar_modes={'oar-parexec','oar-dispatch','mpilauncher'};
1436                text={'Batch processing on servcalcul3 LEGI';...
1437                    'Please choose one of the followint modes';...
1438                    '* oar-parexec : default and best choice';...
1439                    '* oar-dispatch : jobs in a container of several cores';...
1440                    '* mpilauncher : one single parallel mpi job using several cores';...
1441                    '**********************************'...
1442                    };
1443                [S,v]=listdlg('PromptString',text,'ListString',oar_modes,...
1444                    'SelectionMode','single','ListSize',[400 100],'Name','LEGI job mode');
1445                switch oar_modes{S}
1446                    case 'oar-parexec' %oar-dispatch.pl
1447%                         if strcmp(Series.Action.ActionExt,'.m')% case of Matlab function (uncompiled)
1448%                             ncores=1;% one core used only (limitation of Matlab licences)
1449%                             msgbox_uvmat('WARNING','Number of cores =1: select the compiled version civ_matlab.sh for multi-core processing');
1450%                         else
1451%                         answer=inputdlg({'Number of cores (max 36)','extra oar options'},'oarsub parameter',1,{'12',''});
1452%                         ncores=str2double(answer{1});
1453%                         end
1454
1455                        extra_oar=answer{2};
1456                        walltime_onejob=600;%seconds
1457                        filename_joblist=fullfile(RootBat,'job_list.txt');
1458                        fid=fopen(filename_joblist,'w');
1459                        for p=1:length(batch_file_list)
1460                            fprintf(fid,[batch_file_list{p} '\n']);% list of exe files (TODO: create them)
1461                        end
1462                        fclose(fid);
1463                        oar_command=['oarsub -n CIVX '...
1464                            '-t idempotent --checkpoint ' num2str(walltime_onejob+60) ' '...
1465                            '-l /core=' num2str(ncores) ','...
1466                            'walltime=' datestr(min(1.05*walltime_onejob/86400*max(length(batch_file_list),ncores)/ncores,max_walltime/86400),13) ' '...
1467                            '-E ' regexprep(filename_joblist,'\.txt\>','.stderr') ' '...
1468                            '-O ' regexprep(filename_joblist,'\.txt\>','.stdout') ' '...
1469                            extra_oar ' '...
1470                            '"oar-parexec -s -f ' filename_joblist ' '...
1471                            '-l ' filename_joblist '.log"\n'];
1472                        filename_oarcommand=fullfile(RootBat,'oar_command');
1473                        fid=fopen(filename_oarcommand,'w');
1474                        fprintf(fid,oar_command);
1475                        fclose(fid);
1476                        fprintf(oar_command);% display in command line
1477                        system(oar_command);
1478                    case 'oar-dispatch' %oar-dispatch.pl
1479                        ncores=str2double(...
1480                            inputdlg('Number of cores (max 36)','oarsub parameter',1,{'6'})...
1481                            );
1482                        walltime_onejob=600;%seconds
1483                        filename_joblist=fullfile(RootBat,'job_list.txt');
1484                        fid=fopen(filename_joblist,'w');
1485                        for p=1:length(batch_file_list)
1486                            oar_command=['oarsub -n CIVX '...
1487                                '-E ' regexprep(batch_file_list{p},'\.bat\>','.stderr') ' -O ' regexprep(batch_file_list{p},'\.bat\>','.stdout ')...
1488                                '-l "/core=1,walltime=' datestr(walltime_onejob/86400,13) '"   ' batch_file_list{p}];
1489                            fprintf(fid,[oar_command '\n']);
1490                        end
1491                        fclose(fid);
1492                        oar_command=['oarsub -t container -n civx-container '...
1493                            '-l /core=' num2str(ncores)...
1494                            ',walltime=' datestr(1.05*walltime_onejob/86400*max(length(batch_file_list),ncores)/ncores,13) ' '...
1495                            '-E ' regexprep(filename_joblist,'\.txt\>','.stderr') ' '...
1496                            '-O ' regexprep(filename_joblist,'\.txt\>','.stdout') ' '...
1497                            '"oar-dispatch -f ' filename_joblist '"'];
1498                        filename_oarcommand=fullfile(RootBat,'oar_command');
1499                        fid=fopen(filename_oarcommand,'w');
1500                        fprintf(fid,[oar_command '\n']);
1501                        fclose(fid);
1502                        display(oar_command);
1503                        eval(['! . ' filename_oarcommand])
1504                    case 'mpilauncher'
1505                        filename_joblist=fullfile(RootBat,'job_list.txt');
1506                        fid=fopen(filename_joblist,'w');
1507                       
1508                        for p=1:length(batch_file_list)
1509                            fprintf(fid,[batch_file_list{p} '\n']);
1510                        end
1511                        fclose(fid)
1512                        text_oarscript=[...
1513                            '#!/bin/bash \n'...
1514                            '#OAR -n Mylauncher \n'...
1515                            '#OAR -l node=4/core=5,walltime=0:15:00 \n'...
1516                            '#OAR -E ' fullfile(RootBat,'stderrfile.log') ' \n'...
1517                            '#OAR -O ' fullfile(RootBat,'stdoutfile.log') ' \n'...
1518                            '# ========================================================= \n'...
1519                            '# This simple program launch a multinode parallel OpenMPI mpilauncher \n'...
1520                            '# application for coriolis PIV post-processing. \n'...
1521                            '# OAR uses oarshmost wrapper to propagate the user environement. \n'...
1522                            '# This wrapper assert that the user has the same environment on all the \n'...
1523                            '# allocated nodes (basic behavior needed by most MPI applications).  \n'...
1524                            '# \n'...
1525                            '# REQUIREMENT: \n'...
1526                            '# the oarshmost wrapper should be installed in $HOME/bin directory. \n'...
1527                            '# If a different location is used, change the line following the comment "Bidouille" \n'...
1528                            '# ========================================================= \n'...
1529                            '#   USER should only modify these 2 lines  \n'...
1530                            'WORKDIR=' pwd ' \n'...
1531                            'COMMANDE="mpilauncher  -f ' filename_joblist '" \n'...
1532                            '# ========================================================= \n'...
1533                            '# DO NOT MODIFY the FOLOWING LINES. (or be carefull) \n'...
1534                            'echo "job starting on: "`hostname` \n'...
1535                            'MPINODES="-host `tr [\\\\\\n] [,] <$OAR_NODEFILE |sed -e "s/,$/ /"`" \n'...
1536                            'NCPUS=`cat $OAR_NODEFILE |wc -l` \n'...
1537                            '#========== Bidouille ============== \n'...
1538                            'export OMPI_MCA_plm_rsh_agent=oar-envsh \n'...%                     'cd $WORKDIR \n'...
1539                            'CMD="mpirun -np $NCPUS -wdir $WORKDIR $MPINODES $COMMANDE" \n'...
1540                            'echo "I run: $CMD"  \n'...
1541                            '$CMD \n'...
1542                            'echo "job ending" \n'...
1543                            ];
1544                        filename_oarscript=fullfile(RootBat,'oar_command');
1545                        fid=fopen(filename_oarscript,'w');
1546                        fprintf(fid,[text_oarscript]);
1547                        fclose(fid);
1548                        eval(['!chmod +x  ' filename_oarscript]);
1549                        eval(['!oarsub -S ' filename_oarscript]);
1550                end
1551        end
1552end
1553
1554set(handles.RUN, 'Enable','On')
1555set(handles.RUN,'BackgroundColor',[1 0 0])
1556set(handles.RUN, 'Value',0)
1557
1558%------------------------------------------------------------------------
1559function STOP_Callback(hObject, eventdata, handles)
1560%------------------------------------------------------------------------
1561set(handles.RUN, 'BusyAction','cancel')
1562set(handles.RUN,'BackgroundColor',[1 0 0])
1563set(handles.RUN,'enable','on')
1564set(handles.RUN, 'Value',0)
1565
1566% %------------------------------------------------------------------------
1567% % --- Executes on button press in BIN.
1568% function BIN_Callback(hObject, eventdata, handles)
1569% %------------------------------------------------------------------------
1570%     cmd=['#!/bin/bash \n '...
1571%         '#$ -cwd \n '...
1572%         'hostname && date \n '...
1573%         'umask 002 \n'...
1574%         Param.xml.CivmBin ' ' Param.xml.RunTime ' ' filename_xml ' ' OutputFile '.nc'];
1575%     
1576%------------------------------------------------------------------------
1577% --- Main launch command, called by RUN and BATCH
1578
1579function [h_fun,Series,filexml,errormsg]=prepare_jobs(handles,run)
1580%INPUT:
1581% handles: handles of graphic objects on the GUI series
1582% run=0, just to display parameters for MenuExport/GUI config
1583% run=1 (default) prepare the computation
1584
1585%------------------------------------------------------------------------
1586h_fun=[];
1587filexml='';
1588errormsg='';
1589if ~exist('run','var')
1590    run=1;
1591end
1592%% Read parameters from series
1593Series=read_GUI(handles.series);
1594if isfield(Series,'Pairs')
1595    Series=rmfield(Series,'Pairs'); %info Pairs not needed for output
1596end
1597
1598%% read index ranges
1599first_i=1;
1600last_i=1;
1601incr_i=1;
1602first_j=1;
1603last_j=1;
1604incr_j=1;
1605if isfield(Series.IndexRange,'first_i')
1606    first_i=Series.IndexRange.first_i;
1607    incr_i=Series.IndexRange.incr_i;
1608    last_i=Series.IndexRange.last_i;
1609end
1610if isfield(Series.IndexRange,'first_j')
1611    first_j=Series.IndexRange.first_j;
1612    incr_j=Series.IndexRange.incr_j;
1613    last_j=Series.IndexRange.last_j;
1614end
1615
1616%% read input file parameters and set menus
1617menu_coord_state=get(handles.TransformName,'Visible');
1618if isequal(menu_coord_state,'on')
1619    menu_index=get(handles.TransformName,'Value');
1620    transform_list=get(handles.TransformName,'UserData');
1621    Series.FieldTransform.TransformHandle=transform_list{menu_index};% transform function handles
1622end
1623
1624if last_i < first_i || last_j < first_j , msgbox_uvmat('ERROR','last field number must be larger than the first one'),...
1625    set(handles.RUN, 'Enable','On'), set(handles.RUN,'BackgroundColor',[1 0 0]),return,end;
1626
1627%% projection object
1628if isfield(Series,'CheckObject')
1629    if Series.CheckObject
1630        hset_object=findobj(allchild(0),'tag','set_object');
1631        Series.ProjObject=read_GUI(hset_object);
1632        CheckObject_Callback([], [], handles)
1633    end
1634else
1635    Series.CheckObject=0;
1636end
1637
1638%% get_field GUI
1639if isfield(Series,'InputFields')&&isfield(Series.InputFields,'Field')
1640    if strcmp(Series.InputFields.Field,'get_field...')
1641        hget_field=findobj(allchild(0),'name','get_field');
1642        Series.GetField=read_GUI(hget_field);
1643    end
1644end
1645
1646if ~run
1647    return
1648end
1649
1650%% defining the ActionName function handle
1651list_action=get(handles.ActionName,'String');% list menu action
1652index=get(handles.ActionName,'Value');
1653action= list_action{index}; % selected string
1654%Series.hseries=handles.series; % handles to the series GUI
1655path_series=which('series');
1656ActionPathList=get(handles.ActionName,'UserData');
1657ActionPath=ActionPathList{index}; %path stored for the function ACTION
1658if ~isequal(ActionPath,path_series)
1659    eval(['spath=which(''' action ''');']) %spath = current path of the selected function ACTION
1660    if ~exist(ActionPath,'dir')
1661        errormsg=['The prescribed function path ' ActionPath ' does not exist'];
1662        return
1663    end
1664    if ~isequal(spath,ActionPath)
1665        addpath(ActionPath)% add the prescribed path if not the current one
1666    end
1667end
1668eval(['h_fun=@' action ';'])%create a function handle for ACTION
1669if ~isequal(ActionPath,path_series)
1670        rmpath(ActionPath)% add the prescribed path if not the current one   
1671end
1672
1673%% create the output data directory and write in it the xml file from the GUI config
1674%determine the root file corresponding to the first sub dir
1675if get(handles.RUN,'value') && isfield(Series,'OutputSubDir')
1676    SubDirOut=[get(handles.OutputSubDir,'String') Series.OutputDirExt];
1677    SubDirOutNew=SubDirOut;
1678    iview=1;
1679    SeriesData=get(handles.series,'UserData');
1680    if size(Series.InputTable,1)>1 && isfield(SeriesData,'AllowInputSort') && SeriesData.AllowInputSort
1681        [tild,iview]=sort(Series.InputTable(:,2)); %subdirectories sorted in alphabetical order
1682        Series.InputTable=Series.InputTable(iview,:);
1683    end
1684    detect=exist(fullfile(Series.InputTable{1,1},SubDirOutNew),'dir');% test if  the dir  already exist
1685    check_create=1; %need to create the result directory by default
1686    while detect
1687        answer=msgbox_uvmat('INPUT_Y-N',['use existing ouput directory: ' fullfile(Series.InputTable{1,1},SubDirOutNew) ', possibly delete previous data']);
1688        if isequal(answer,'Yes')
1689            detect=0;
1690            check_create=0;
1691        else
1692            r=regexp(SubDirOutNew,'(?<root>.*\D)(?<num1>\d+)$','names');%detect whether name ends by a number
1693            if isempty(r)
1694                r(1).root=[SubDirOutNew '_'];
1695                r(1).num1='0';
1696            end
1697            SubDirOutNew=[r(1).root num2str(str2num(r(1).num1)+1)];%increment the index by 1 or put 1
1698            detect=exist(fullfile(Series.InputTable{1,1},SubDirOutNew),'dir');% test if  the dir  already exists   
1699            check_create=1;
1700        end
1701    end
1702    Series.OutputDirExt=regexprep(SubDirOutNew,Series.OutputSubDir,'');
1703    Series.OutputRootFile=Series.InputTable{1,3};% the first sorted RootFile taken for output
1704    set(handles.OutputDirExt,'String',Series.OutputDirExt)
1705    % create output directory
1706    OutputDir=fullfile(Series.InputTable{1,1},[Series.OutputSubDir Series.OutputDirExt]);
1707    if check_create
1708        [tild,msg1]=mkdir(OutputDir);
1709        if ~strcmp(msg1,'')
1710            errormsg=['cannot create ' OutputDir ': ' msg1];%error message for directory creation
1711            return
1712        end
1713    end
1714    filexml=fullfile(OutputDir,[Series.InputTable{1,3} '.xml']);% name of the parameter xml file set in this directory
1715end
1716%removes redondant information
1717Series.IndexRange=rmfield(Series.IndexRange,'TimeTable');
1718Series.IndexRange=rmfield(Series.IndexRange,'MinIndex');
1719Series.IndexRange=rmfield(Series.IndexRange,'MaxIndex');
1720%removes empty lines of InputTable
1721empty_line=false(size(Series.InputTable,1),1);
1722for iline=1:size(Series.InputTable,1)
1723    empty_line(iline)=isequal(Series.InputTable(iline,1:3),{'','',''});
1724end
1725Series.InputTable(empty_line,:)=[];
1726
1727%------------------------------------------------------------------------
1728% --- Executes on selection change in ActionName.
1729function ActionName_Callback(hObject, eventdata, handles)
1730%------------------------------------------------------------------------
1731%% stop any ongoing series processing
1732if isequal(get(handles.RUN,'Value'),1)
1733    answer= msgbox_uvmat('INPUT_Y-N','stop current Action process?');
1734    if strcmp(answer,'Yes')
1735        STOP_Callback(hObject, eventdata, handles)
1736    else
1737        return
1738    end
1739end
1740
1741%% get Action name and path
1742nb_builtin_ACTION=4; %nbre of functions initially proposed in the menu ActionName (as defined in the Opening fct of series)
1743ActionList=get(handles.ActionName,'String');% list menu fields
1744ActionIndex=get(handles.ActionName,'Value');
1745if ~isequal(ActionIndex,1)
1746    InputTable=get(handles.InputTable,'Data');
1747    if isempty(InputTable{1,4})
1748        msgbox_uvmat('ERROR','no input file available: use Open in the menu bar')
1749        return
1750    end
1751end
1752ActionName= ActionList{get(handles.ActionName,'Value')}; % selected function name
1753ActionPathList=get(handles.ActionName,'UserData');%list of recorded paths to functions of the list ActionName
1754
1755%% add a new function to the menu if 'more...' has been selected in the menu ActionName
1756if isequal(ActionName,'more...')
1757    [FileName, PathName] = uigetfile( ...
1758        {'*.m', ' (*.m)';
1759        '*.m',  '.m files '; ...
1760        '*.*', 'All Files (*.*)'}, ...
1761        'Pick a series processing function ',get(handles.ActionPath,'String'));
1762    if length(FileName)<2
1763        return
1764    end
1765    [ActionPath,ActionName,ActionExt]=fileparts(FileName);
1766    % insert the choice in the menu
1767    ActionIndex=find(strcmp(ActionName,ActionList),1);% look for the selected function in the menu Action
1768    if isempty(ActionIndex)%the input string does not exist in the menu
1769        ActionIndex= length(ActionList);
1770        ActionList=[ActionList(1:end-1);{ActionName};ActionList(end)];% the selected function is appended in the menu, before the last item 'more...'
1771        set(handles.ActionName,'String',ActionList)
1772    end
1773    %set(handles.ActionName,'Value',ActionIndex)
1774    %list_path{ActionIndex}=PathName;
1775    % remove old Action options in the menu (keeping a menu length <nb_builtin_ACTION+5)
1776    if length(ActionList)>nb_builtin_ACTION+5; %nb_builtin=nbre of functions always remaining in the initial menu
1777        nbremove=length(ActionList)-nb_builtin_ACTION-5;
1778        ActionList(nb_builtin_ACTION+1:end-5)=[];
1779        ActionPathList(nb_builtin_ACTION+1:end-4)=[];
1780        ActionIndex=ActionIndex-nbremove;
1781    end
1782    set(handles.ActionName,'Value',ActionIndex)
1783    set(handles.ActionName,'String',ActionList)
1784    ActionPathList{ActionIndex}=PathName;
1785    set(handles.ActionPath,'enable','inactive')% indicate that the current path is accessible (not 'off')
1786   
1787    % record the file extension and update the paths in userdata
1788    ActionExtList=get(handles.ActionExt,'String');
1789    ActionExtIndex=find(strcmp(ActionExt,ActionExtList), 1);
1790    if isempty(ActionExtIndex)
1791        set(handles.ActionExt,'String',[ActionExtList;{ActionExt}])
1792        set(handles.ActionExt,'Value',numel(ActionExtList)+1)
1793        ActionPathNew=cell(size(ActionPathList,1),1);%new column of ActionPath
1794        ActionPathNew{ActionIndex}=ActionPath;
1795        ActionPathList=[ActionPathList ActionPathNew];
1796    end
1797    set(handles.ActionName,'UserData',ActionPathList);
1798   
1799    %record the current menu in personal file profil_perso
1800    dir_perso=prefdir;
1801    profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
1802    if nb_builtin_ACTION+1<=length(ActionList)-1
1803        ActionListUser=ActionList(nb_builtin_ACTION+1:numel(ActionList)-1);
1804        ActionPathListUser=ActionPathList(nb_builtin_ACTION+1:numel(ActionList)-1,:);
1805        ActionExtListUser={};
1806        if numel(ActionExtList)>2
1807            ActionExtListUser=ActionExtList(3:end);
1808        end
1809        if exist(profil_perso,'file')
1810            save(profil_perso,'ActionListUser','ActionPathListUser','ActionExtListUser','-append')
1811        else
1812            save(profil_perso,'ActionListUser','ActionPathListUser','ActionExtListUser','-V6')
1813        end
1814    end
1815end
1816
1817%% check the current ActionPath to the selected function
1818PathName=ActionPathList{ActionIndex};%current recorded path
1819set(handles.ActionPath,'String',PathName); %show the path to the senlected function
1820
1821%% reinitialise the waitbar
1822update_waitbar(handles.Waitbar,0)
1823
1824%% default setting for the visibility of the GUI elements
1825set(handles.FieldTransform,'Visible','off')
1826set(handles.CheckObject,'Visible','off');
1827set(handles.ProjObject,'Visible','off');
1828set(handles.CheckMask,'Visible','off')
1829set(handles.Mask,'Visible','off')
1830
1831%% run the current action function to prepare the input GUI
1832[h_fun,Series,tild,errormsg]=prepare_jobs(handles);
1833if ~isempty(errormsg)
1834    msgbox_uvmat('ERROR',errormsg)
1835    return
1836end
1837ParamOut=h_fun(Series);
1838
1839%% Put the first line of the selected Action fct as tootip help
1840try
1841    [fid,errormsg] =fopen([ActionName '.m']);
1842    InputText=textscan(fid,'%s',1,'delimiter','\n');
1843    fclose(fid);
1844    set(handles.ActionName,'ToolTipString',InputText{1}{1})% put the first line of the selected function as tooltip help
1845end
1846% if ~isequal(path_series,PathName)
1847%     rmpath(PathName)
1848% end
1849Param_list={};
1850
1851%% Detect the types of input files
1852SeriesData=get(handles.series,'UserData');
1853nb_civ=0;nb_netcdf=0;
1854if ~isempty(SeriesData)
1855    nb_civ=numel(find(strcmp('civx',SeriesData.FileType)|strcmp('civdata',SeriesData.FileType)));
1856    nb_netcdf=numel(find(strcmp('netcdf',SeriesData.FileType)));
1857end
1858
1859%% Check whether alphabetical sorting of input Subdir is alowed by the Action fct  (for multiples series entries)
1860SeriesData.AllowInputSort=0;%default
1861if isfield(ParamOut,'AllowInputSort')&&isequal(ParamOut.AllowInputSort,'on')
1862    SeriesData.AllowInputSort=1;
1863end
1864
1865%% Impose the whole input file index range if requested
1866if isfield(ParamOut,'WholeIndexRange')&&isequal(ParamOut.WholeIndexRange,'on')
1867    MinIndex=get(handles.MinIndex,'Data');
1868    MaxIndex=get(handles.MaxIndex,'Data');
1869    if ~isempty(MinIndex)
1870        set(handles.num_first_i,'String',num2str(MinIndex{1}))
1871        set(handles.num_last_i,'String',num2str(MaxIndex{1}))
1872        set(handles.num_incr_i,'String','1')
1873        if size(MinIndex,2)>=2
1874            set(handles.num_first_j,'String',num2str(MinIndex{1,2}))
1875            set(handles.num_last_j,'String',num2str(MaxIndex{1,2}))
1876            set(handles.num_incr_j,'String','1')
1877        end
1878    end
1879end
1880
1881%% NbSlice visibility
1882NbSliceVisible='off';%default
1883if isfield(ParamOut,'NbSlice') && isequal(ParamOut.NbSlice,'on')
1884    NbSliceVisible='on';
1885    set(handles.num_NbProcess,'String',get(handles.num_NbSlice,'String'))% the nbre of processes is imposed as the nbre of slices
1886else
1887    set(handles.num_NbProcess,'String','')% free nbre of processes
1888end
1889set(handles.num_NbSlice,'Visible',NbSliceVisible)
1890set(handles.NbSlice_title,'Visible',NbSliceVisible)
1891
1892%% Visibility of VelType and VelType_1 menus
1893VelTypeVisible='off';  %hidden by default
1894VelType_1Visible='off';
1895InputFieldsVisible='off';%visibility of the frame Fields
1896if isfield(ParamOut,'VelType')
1897    if strcmp( ParamOut.VelType,'one')||strcmp( ParamOut.VelType,'two')
1898        if nb_civ>=1
1899            VelTypeVisible='on';
1900            InputFieldsVisible='on';
1901        end
1902    end
1903    if strcmp( ParamOut.VelType,'two')
1904        if nb_civ>=2
1905            VelType_1Visible='on';
1906        end
1907    end
1908end
1909set(handles.VelType,'Visible',VelTypeVisible)
1910set(handles.VelType_text,'Visible',VelTypeVisible);
1911set(handles.VelType_1,'Visible',VelType_1Visible)
1912set(handles.VelType_text_1,'Visible',VelType_1Visible);
1913
1914%% Visibility of FieldName and FieldName_1 menus
1915FieldNameVisible='off';  %hidden by default
1916FieldName_1Visible='off';  %hidden by default
1917if isfield(ParamOut,'FieldName')
1918    if strcmp( ParamOut.FieldName,'one')||strcmp( ParamOut.FieldName,'two')
1919        if (nb_civ+nb_netcdf)>=1
1920            InputFieldsVisible='on';
1921            FieldNameVisible='on';
1922        end
1923    end
1924    if strcmp( ParamOut.FieldName,'two')
1925        if (nb_civ+nb_netcdf)>=1
1926            FieldName_1Visible='on';
1927        end
1928    end
1929end
1930set(handles.InputFields,'Visible',InputFieldsVisible)
1931set(handles.FieldName,'Visible',FieldNameVisible) % test for MenuBorser
1932set(handles.FieldName_1,'Visible',FieldName_1Visible)
1933
1934%% Visibility of FieldTransform menu
1935FieldTransformVisible='off';  %hidden by default
1936if isfield(ParamOut,'FieldTransform')
1937    FieldTransformVisible=ParamOut.FieldTransform; 
1938    TransformName_Callback([],[], handles)
1939end
1940set(handles.FieldTransform,'Visible',FieldTransformVisible)
1941
1942%% Visibility of projection object
1943ProjObjectVisible='off';  %hidden by default
1944if isfield(ParamOut,'ProjObject')
1945    ProjObjectVisible=ParamOut.ProjObject;
1946end
1947set(handles.CheckObject,'Visible',ProjObjectVisible)
1948if ~get(handles.CheckObject,'Value')
1949    ProjObjectVisible='off';
1950end
1951set(handles.ProjObject,'Visible',ProjObjectVisible)
1952set(handles.DeleteObject,'Visible',ProjObjectVisible)
1953set(handles.ViewObject,'Visible',ProjObjectVisible)
1954
1955
1956%% Visibility of mask input
1957MaskVisible='off';  %hidden by default
1958if isfield(ParamOut,'Mask')
1959    MaskVisible=ParamOut.Mask;
1960end
1961set(handles.Mask,'Visible',MaskVisible)
1962set(handles.CheckMask,'Visible',MaskVisible);
1963
1964%% definition of the directory containing the output files
1965OutputDirVisible='off';
1966if isfield(ParamOut,'OutputDirExt')&&~isempty(ParamOut.OutputDirExt)
1967    set(handles.OutputDirExt,'String',ParamOut.OutputDirExt)
1968    OutputDirVisible='on';
1969end
1970set(handles.OutputDirExt,'Visible',OutputDirVisible)
1971set(handles.OutputSubDir,'Visible',OutputDirVisible)
1972set(handles.OutputDir_title,'Visible',OutputDirVisible)
1973set(handles.RunMode,'Visible',OutputDirVisible)
1974set(handles.ActionExt,'Visible',OutputDirVisible)
1975set(handles.RunMode_title,'Visible',OutputDirVisible)
1976set(handles.ActionExt_title,'Visible',OutputDirVisible)
1977
1978%% definition of an additional parameter set, determined by an ancillary GUI
1979if isfield(ParamOut,'ActionInput')
1980    set(handles.ActionInput,'Visible','on')
1981    set(handles.ActionInput_title,'Visible','on')
1982    set(handles.ActionInput,'String',ActionName)
1983    SeriesData.ActionInput=ParamOut.ActionInput;
1984else
1985    set(handles.ActionInput,'Visible','off')
1986    set(handles.ActionInput_title,'Visible','off')
1987    if isfield(SeriesData,'ActionInput')
1988    SeriesData=rmfield(SeriesData,'ActionInput');
1989    end
1990end   
1991set(handles.series,'UserData',SeriesData)
1992
1993%------------------------------------------------------------------------
1994% --- Executes on selection change in FieldName.
1995function FieldName_Callback(hObject, eventdata, handles)
1996%------------------------------------------------------------------------
1997field_str=get(handles.FieldName,'String');
1998field_index=get(handles.FieldName,'Value');
1999field=field_str{field_index(1)};
2000if isequal(field,'get_field...')   
2001     hget_field=findobj(allchild(0),'name','get_field');
2002     if ~isempty(hget_field)
2003         delete(hget_field)%delete opened versions of get_field
2004     end
2005     filecell=get_file_series(read_GUI(handles.series));
2006     if exist(filecell{1,1},'file')
2007        get_field(filecell{1,1})
2008     end
2009elseif isequal(field,'more...')
2010    str=calc_field;
2011    [ind_answer,v] = listdlg('PromptString','Select a file:',...
2012                'SelectionMode','single',...
2013                'ListString',str);
2014       % edit the choice in the fields and actionname menu
2015     scalar=cell2mat(str(ind_answer));
2016     update_menu(handles.FieldName,scalar)
2017end
2018
2019%------------------------------------------------------------------------
2020% --- Executes on selection change in FieldName_1.
2021function FieldName_1_Callback(hObject, eventdata, handles)
2022%------------------------------------------------------------------------
2023field_str=get(handles.FieldName_1,'String');
2024field_index=get(handles.FieldName_1,'Value');
2025field=field_str{field_index};
2026if isequal(field,'get_field...')   
2027     hget_field=findobj(allchild(0),'name','get_field_1');
2028     if ~isempty(hget_field)
2029         delete(hget_field)
2030     end
2031     SeriesData=get(handles.series,'UserData');
2032     filename=SeriesData.CurrentInputFile_1;
2033     if exist(filename,'file')
2034        hget_field=get_field(filename);
2035        set(hget_field,'name','get_field_1')
2036     end
2037elseif isequal(field,'more...')
2038    str=calc_field;
2039    [ind_answer,v] = listdlg('PromptString','Select a file:',...
2040                'SelectionMode','single',...
2041                'ListString',str);
2042       % edit the choice in the fields and actionname menu
2043     scalar=cell2mat(str(ind_answer));
2044     update_menu(handles.FieldName_1,scalar)
2045end   
2046
2047
2048%%%%%%%%%%%%%
2049function [ind_remove]=find_pairs(dirpair,ind_i,last_i)
2050indsel=ind_i;
2051indiff=diff(ind_i); %test index increment to detect multiplets (several pairs with the same index ind_i) and holes in the series
2052indiff=[1 indiff last_i-ind_i(end)+1];%for testing gaps with the imposed bounds
2053if ~isempty(indiff)
2054    indiff2=diff(indiff);
2055    indiffp=[indiff2 1];
2056    indiffm=[1 indiff2];
2057    ind_multi_m=find((indiff==0)&(indiffm<0))-1;%indices of first members of multiplets
2058    ind_multi_p=find((indiff==0)&(indiffp>0));%indices of last members of multiplets
2059    %for each multiplet, select the most recent file
2060    ind_remove=[];
2061    for i=1:length(ind_multi_m)
2062        ind_pairs=ind_multi_m(i):ind_multi_p(i);
2063        for imulti=1:length(ind_pairs)
2064            datepair(imulti)=datenum(dirpair(ind_pairs(imulti)).date);%dates of creation
2065        end
2066        [datenew,indsort2]=sort(datepair); %sort the multiplet by creation date
2067        ind_s=indsort2(1:end-1);%
2068        ind_remove=[ind_remove ind_pairs(ind_s)];%remove these indices, leave the last one
2069    end
2070end
2071
2072%------------------------------------------------------------------------
2073% --- determine the list of index pairstring of processing file
2074function [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)
2075%------------------------------------------------------------------------
2076num_i1=num_i;% set of first image numbers by default
2077num_i2=num_i;
2078num_j1=num_j;
2079num_j2=num_j;
2080num_i_out=num_i;
2081num_j_out=num_j;
2082% if isequal (NomType,'_1-2_1') || isequal (NomType,'_1-2')
2083if isequal(mode,'series(Di)')
2084    num_i1_line=num_i+ind_shift(3);% set of first image numbers
2085    num_i2_line=num_i+ind_shift(4);
2086    % adjust the first and last field number
2087        indsel=find(num_i1_line >= 1);
2088    num_i_out=num_i(indsel);
2089    num_i1_line=num_i1_line(indsel);
2090    num_i2_line=num_i2_line(indsel);
2091    num_j1=meshgrid(num_j,ones(size(num_i1_line)));
2092    num_j2=meshgrid(num_j,ones(size(num_i1_line)));
2093    [xx,num_i1]=meshgrid(num_j,num_i1_line);
2094    [xx,num_i2]=meshgrid(num_j,num_i2_line);
2095elseif isequal (mode,'series(Dj)')||isequal (mode,'bursts')
2096    if isequal(mode,'bursts') %case of bursts (png_old or png_2D)
2097        num_j1=ind_shift(1)*ones(size(num_i));
2098        num_j2=ind_shift(2)*ones(size(num_i));
2099    else
2100        num_j1_col=num_j+ind_shift(1);% set of first image numbers
2101        num_j2_col=num_j+ind_shift(2);
2102        % adjust the first field number
2103        indsel=find((num_j1_col >= 1));   
2104        num_j_out=num_j(indsel);
2105        num_j1_col=num_j1_col(indsel);
2106        num_j2_col=num_j2_col(indsel);
2107        [num_i1,num_j1]=meshgrid(num_i,num_j1_col);
2108        [num_i2,num_j2]=meshgrid(num_i,num_j2_col);
2109    end   
2110end
2111
2112%------------------------------------------------------------------------
2113% --- Executes on button press in CheckObject.
2114function CheckObject_Callback(hObject, eventdata, handles)
2115%------------------------------------------------------------------------
2116value=get(handles.CheckObject,'Value');
2117if value
2118     set(handles.CheckObject,'BackgroundColor',[1 1 0])%put unactivated buttons to yellow
2119     hset_object=findobj(allchild(0),'tag','set_object');%find the set_object interface handle
2120     if ishandle(hset_object)
2121         uistack(hset_object,'top')% show the GUI set_object if opened
2122     else
2123         %get the object file
2124         InputTable=get(handles.InputTable,'Data');
2125         defaultname=InputTable{1,1};
2126         if isempty(defaultname)
2127            defaultname={''};
2128         end
2129        [FileName, PathName, filterindex] = uigetfile( ...
2130       {'*.xml;*.mat', ' (*.xml,*.mat)';
2131       '*.xml',  '.xml files '; ...
2132        '*.mat',  '.mat matlab files '}, ...
2133        'Pick an xml object file (or use uvmat to create it)',defaultname);
2134        fileinput=[PathName FileName];%complete file name
2135        sizf=size(fileinput);
2136        if (~ischar(fileinput)||~isequal(sizf(1),1)),return;end
2137        %read the file
2138        data=xml2struct(fileinput);
2139        if ~isfield(data,'Type')
2140             msgbox_uvmat('ERROR',[fileinput ' is not an object xml file'])
2141             return
2142        end
2143        if ~isfield(data,'ProjMode')
2144             data.ProjMode='none';
2145        end
2146        hset_object=set_object(data);% call the set_object interface
2147     end
2148     ProjObject=read_GUI(hset_object);
2149     set(handles.ProjObject,'String',ProjObject.Name);%display the object name
2150     SeriesData=get(handles.series,'UserData');
2151     SeriesData.ProjObject=ProjObject;
2152     set(handles.series,'UserData',SeriesData);
2153     set(handles.DeleteObject,'Visible','on');
2154     set(handles.ViewObject,'Visible','on');
2155else
2156    set(handles.CheckObject,'BackgroundColor',[0.7 0.7 0.7])%put activated buttons to green
2157end
2158%set(handles.series,'UserData',SeriesData)
2159
2160%--------------------------------------------------------------
2161function CheckMask_Callback(hObject, eventdata, handles)
2162value=get(handles.CheckMask,'Value');
2163if value
2164    msgbox_uvmat('ERROR','not implemented yet')
2165end
2166%--------------------------------------------------------------
2167
2168%-------------------------------------------------------------------
2169%'uv_ncbrowser': interactively calls the netcdf file browser 'get_field.m'
2170function ncbrowser_uvmat(hObject, eventdata)
2171%-------------------------------------------------------------------
2172     bla=get(gcbo,'String');
2173     ind=get(gcbo,'Value');
2174     filename=cell2mat(bla(ind));
2175      blank=find(filename==' ');
2176      filename=filename(1:blank-1);
2177     get_field(filename)
2178
2179% ------------------------------------------------------------------
2180function MenuHelp_Callback(hObject, eventdata, handles)
2181%-------------------------------------------------------------------
2182path_to_uvmat=which ('uvmat');% check the path of uvmat
2183pathelp=fileparts(path_to_uvmat);
2184helpfile=fullfile(pathelp,'uvmat_doc','uvmat_doc.html');
2185if isempty(dir(helpfile)), msgbox_uvmat('ERROR','Please put the help file uvmat_doc.html in the sub-directory /uvmat_doc of the UVMAT package')
2186else
2187    addpath (fullfile(pathelp,'uvmat_doc'))
2188    web([helpfile '#series'])
2189end
2190
2191%-------------------------------------------------------------------
2192% --- Executes on selection change in TransformName.
2193function TransformName_Callback(hObject, eventdata, handles)
2194%----------------------------------------------------------------------
2195TransformList=get(handles.TransformName,'String');
2196TransformIndex=get(handles.TransformName,'Value');
2197TransformName=TransformList{TransformIndex};
2198TransformPathList=get(handles.TransformName,'UserData');
2199nb_builtin_transform=4;
2200% ff=functions(list_transform{end});
2201if isequal(TransformName,'more...');
2202%     coord_fct='';
2203%     prompt = {'Enter the name of the transform function'};
2204%     dlg_title = 'user defined transform';
2205%     num_lines= 1;
2206    [FileName, PathName] = uigetfile( ...
2207       {'*.m', ' (*.m)';
2208        '*.m',  '.m files '; ...
2209        '*.*', 'All Files (*.*)'}, ...
2210        'Pick a transform function',get(handles.TransformPath,'String'));
2211    if isequal(FileName,0)
2212        return     %browser closed without choice
2213    end
2214    if isequal(PathName(end),'/')||isequal(PathName(end),'\')
2215        PathName(end)=[];
2216    end
2217    [TransformPath,TransformName,TransformExt]=fileparts(FileName);% removes extension .m
2218    if ~strcmp(TransformExt,'.m')
2219        msgbox_uvmat('ERROR','a Matlab function .m must be introduced');
2220        return
2221    end
2222     % insert the choice in the menu
2223    TransformIndex=find(strcmp(TransformName,TransformList),1);% look for the selected function in the menu Action
2224    if isempty(TransformIndex)%the input string does not exist in the menu
2225        TransformIndex= length(TransformList);
2226        TransformList=[TransformList(1:end-1);{TransformnName};TransformList(end)];% the selected function is appended in the menu, before the last item 'more...'
2227        set(handles.TransformName,'String',TransformList)
2228        TransformPathList=[TransformPathList;{TransformPath}];
2229    end
2230   % save the new menu in the personal file 'uvmat_perso.mat'
2231   dir_perso=prefdir;%personal Matalb directory
2232   profil_perso=fullfile(dir_perso,'uvmat_perso.mat');
2233   if exist(profil_perso,'file')
2234       for ilist=nb_builtin_transform+1:numel(TransformPathList)
2235           TransformListUser{ilist-nb_builtin_transform}=TransformList{ilist};
2236           TransformPathListUser{ilist-nb_builtin_transform}=TransformPathList{ilist};
2237       end
2238       save (profil_perso,'TransformPathListUser','TransformListUser','-append'); %store the root name for future opening of uvmat
2239   end
2240end
2241
2242%display the current function path
2243set(handles.TransformPath,'String',TransformPathList{TransformIndex}); %show the path to the senlected function
2244set(handles.TransformName,'UserData',TransformPathList);
2245
2246
2247% --------------------------------------------------------------------
2248function MenuExportConfig_Callback(hObject, eventdata, handles)
2249global Series
2250[tild,Series,errormsg]=prepare_jobs(handles,0);
2251% Series=read_GUI(handles.series);
2252
2253evalin('base','global Series')%make CurData global in the workspace
2254display('current series config :')
2255evalin('base','Series') %display CurData in the workspace
2256commandwindow; %brings the Matlab command window to the front
2257
2258
2259% --- Executes on selection change in RunMode.
2260function RunMode_Callback(hObject, eventdata, handles)
2261
2262% --- Executes on selection change in Coord_x.
2263function Coord_x_Callback(hObject, eventdata, handles)
2264
2265
2266% --- Executes on selection change in Coord_y.
2267function Coord_y_Callback(hObject, eventdata, handles)
2268
2269
2270
2271% --- Executes when series is resized.
2272function series_ResizeFcn(hObject, eventdata, handles)
2273%% input table
2274set(handles.InputTable,'Unit','pixel')
2275Pos=get(handles.InputTable,'Position');
2276set(handles.InputTable,'Unit','normalized')
2277ColumnWidth=round([0.5 0.14 0.14 0.14 0.08]*(Pos(3)-52));
2278ColumnWidth=num2cell(ColumnWidth);
2279set(handles.InputTable,'ColumnWidth',ColumnWidth)
2280
2281%% MinIndex and MaxIndex
2282set(handles.MinIndex,'Unit','pixel')
2283Pos=get(handles.MinIndex,'Position');
2284set(handles.MinIndex,'Unit','normalized')
2285ColumnWidth=get(handles.MinIndex,'ColumnWidth');
2286if numel(ColumnWidth)==2
2287    ColumnWidth=num2cell(floor([0.5 0.5]*(Pos(3)-20)));
2288else
2289    ColumnWidth={Pos(3)-5};
2290end   
2291set(handles.MinIndex,'ColumnWidth',ColumnWidth)
2292set(handles.MaxIndex,'ColumnWidth',ColumnWidth)
2293
2294%% TimeTable
2295set(handles.TimeTable,'Unit','pixel')
2296Pos=get(handles.TimeTable,'Position');
2297set(handles.TimeTable,'Unit','normalized')
2298ColumnWidth=get(handles.TimeTable,'ColumnWidth');
2299ColumnWidth=num2cell(floor([0.25 0.25 0.25 0.25]*(Pos(3)-20)));
2300set(handles.TimeTable,'ColumnWidth',ColumnWidth)
2301
2302
2303%% PairString
2304set(handles.PairString,'Unit','pixel')
2305Pos=get(handles.PairString,'Position');
2306set(handles.PairString,'Unit','normalized')
2307set(handles.PairString,'ColumnWidth',{Pos(3)-5})
2308
2309
2310% --- Executes on button press in status.
2311function status_Callback(hObject, eventdata, handles)
2312val=get(handles.status,'Value');
2313
2314%% delete current display fig if selection is off
2315if val==0
2316    set(handles.status,'BackgroundColor',[0 1 0])
2317    hfig=findobj(allchild(0),'name','series_status');
2318    if ~isempty(hfig)
2319        delete(hfig)
2320    end
2321    return
2322end
2323set(handles.status,'BackgroundColor',[1 1 0])
2324drawnow
2325% listtype={'civ1','fix1','patch1','civ2','fix2','patch2'};
2326% Param.CheckCiv1=get(handles.CheckCiv1,'Value');
2327% Param.CheckFix1=get(handles.CheckFix1,'Value');
2328% Param.CheckPatch1=get(handles.CheckPatch1,'Value');
2329% Param.CheckCiv2=get(handles.CheckCiv2,'Value');
2330% Param.CheckFix2=get(handles.CheckFix2,'Value');
2331% Param.CheckPatch2=get(handles.CheckPatch2,'Value');
2332% box_test=[Param.CheckCiv1 Param.CheckFix1 Param.CheckPatch1 Param.CheckCiv2 Param.CheckFix2 Param.CheckPatch2];
2333%
2334% option_civ=find(box_test,1,'last');%last selected option (non-zero index of box_test)
2335% filecell=get(handles.civ,'UserData');%retrieve the list of output files expected for PIV
2336% test_new=0;
2337% if ~isfield(filecell,'nc')
2338%     test_new=1;
2339%     [ref_i,ref_j,errormsg]=find_ref_indices(handles);
2340%     if ~isempty(errormsg)
2341%         msgbox_uvmat('ERROR',errormsg)
2342%         return
2343%     end
2344%     filecell=set_civ_filenames(handles,ref_i,ref_j,box_test);%determine the output file expected from the GUI status
2345% end
2346% if ~isequal(box_test(4:6),[0 0 0])
2347%     civ_files=filecell.nc.civ2;%case of civ2 operations
2348% else
2349%     civ_files=filecell.nc.civ1;
2350% end
2351% InputTable=get(handles.InputTable,'Data');
2352% OutputDir=fullfile(InputTable{1,1},[get(handles.OutputSubDir,'String') get(handles.OutputDirExt,'String')]);
2353StatusData.time_ref=get(handles.RUN,'UserData');% get the time of launch
2354% StatusData.option_civ=option_civ;
2355Param=read_GUI(handles.series);
2356RootPath=Param.InputTable{1,1};
2357%SubDir=Param.InputTable{1,2};
2358OutputSubDir=[Param.OutputSubDir Param.OutputDirExt];% subdirectory for output files
2359OutputDir=fullfile(RootPath,OutputSubDir);
2360% set(hlist,'UserData',OutputDir)
2361hfig=findobj(allchild(0),'name','series_status');
2362if isempty(hfig)
2363    hfig=figure('DeleteFcn',@stop_status);
2364    set(hfig,'MenuBar','none')% suppress the menu bar
2365    set(hfig,'NumberTitle','off')%suppress the fig number in the title
2366    set(hfig,'name','series_status')
2367    set(hfig,'tag','series_status')
2368%    set(hfig,'UserData',civ_files)
2369    hlist= uicontrol('Style','listbox','Units','normalized', 'Position',[0.05 0.09 0.9 0.71], 'Callback', {'open_uvmat'},'tag','list','UserData',OutputDir);
2370    uicontrol('Style','edit','Units','normalized', 'Position', [0.05 0.87 0.9 0.1],'tag','msgbox','Max',2,'String',OutputDir);
2371    uicontrol('Style','frame','Units','normalized', 'Position', [0.05 0.81 0.9 0.05]);
2372    %uicontrol('Style','pushbutton','Units','normalized', 'Position', [0.7 0.01 0.2 0.07],'String','Close','FontWeight','bold','FontUnits','points','FontSize',11,'Callback',@close_GUI);
2373    uicontrol('Style','pushbutton','Units','normalized', 'Position', [0.7 0.01 0.2 0.07],'String','Close','FontWeight','bold','FontUnits','points','FontSize',11,'Callback',@stop_status);
2374    hrefresh=uicontrol('Style','pushbutton','Units','normalized', 'Position', [0.1 0.01 0.2 0.07],'String','Refresh','FontWeight','bold','FontUnits','points','FontSize',11,'Callback',@refresh_GUI);
2375    set(hrefresh,'UserData',StatusData)
2376    BarPosition=[0.05 0.81 0.01 0.05];
2377    uicontrol('Style','frame','Units','normalized', 'Position',BarPosition ,'BackgroundColor',[1 0 0],'tag','waitbar');
2378    drawnow
2379end
2380
2381refresh_GUI(hrefresh,[])
2382%------------------------------------------------------------------------   
2383% launched by refreshing the status figure
2384function refresh_GUI(hObject, eventdata)
2385%------------------------------------------------------------------------
2386% Tabchar={};
2387% BarPosition=[0.05 0.81 0.01 0.05];
2388hfig=get(hObject,'parent');
2389hmsgbox=findobj(hfig,'tag','msgbox');
2390hlist=findobj(hfig,'tag','list');
2391% StatusData=get(hObject,'UserData');
2392OutputDir=get(hmsgbox,'String');
2393ListFiles=dir(OutputDir);
2394ListDisplay=cell(numel(ListFiles),1);
2395for ilist=1:numel(ListDisplay)
2396    ListDisplay{ilist}=ListFiles(ilist).name;
2397end
2398set(hlist,'String',ListDisplay)
2399% civ_files=get(hfig,'UserData');
2400
2401% [filepath,filename,ext]=fileparts(civ_files{1});
2402% [tild,SubDir,extdir]=fileparts(filepath);
2403% SubDir=[SubDir extdir];
2404% option_civ=StatusData.option_civ;
2405% nbfiles=numel(civ_files);
2406% testrecent=0;
2407% count=0;
2408% datnum=zeros(1,nbfiles);
2409% filefound=cell(1,nbfiles);
2410% for ifile=1:nbfiles
2411%     detect=exist(civ_files{ifile},'file'); % check the existence of the file
2412%     option=0;
2413%     if detect==0
2414%         option_str='not created';
2415%     else
2416%         datfile=dir(civ_files{ifile});
2417%         if isfield(datfile,'datenum')
2418%             datnum(ifile)=datfile.datenum;%only available in recent matlab versions
2419%             testrecent=1;
2420%         end
2421%         filefound(ifile)={datfile.name};
2422%         
2423%         % check the content  netcdf file
2424%         Data=nc2struct(civ_files{ifile},'ListGlobalAttribute','CivStage','patch2','fix2','civ2','patch','fix');
2425%         option_list={'civ1','fix1','patch1','civ2','fix2','patch2'};
2426%         if ~isempty(Data.CivStage)
2427%             option=Data.CivStage;%case of Matlab civ
2428%         else
2429%             if ~isempty(Data.patch2) && isequal(Data.patch2,1)
2430%                 option=6;
2431%             elseif ~isempty(Data.fix2) && isequal(Data.fix2,1)
2432%                 option=5;
2433%             elseif ~isempty(Data.civ2) && isequal(Data.civ2,1);
2434%                 option=4;
2435%             elseif ~isempty(Data.patch) && isequal(Data.patch,1);
2436%                 option=3;
2437%             elseif ~isempty(Data.fix) && isequal(Data.fix,1);
2438%                 option=2;
2439%             else
2440%                 option=1;
2441%             end
2442%         end
2443%         option_str=option_list{option};
2444%         if datnum(ifile)<StatusData.time_ref
2445%             option_str=[option_str '  --OLD--'];
2446%         end
2447%     end
2448%     if option >= option_civ
2449%         count=count+1;
2450%     end
2451%     [filepath,filename,ext]=fileparts(civ_files{ifile});
2452%     Tabchar{ifile,1}=[fullfile(SubDir,filename) ext  '...' option_str];
2453% end
2454% datnum=datnum(datnum~=0);%keep the non zero values corresponding to existing files
2455% if isempty(datnum)
2456%     if testrecent
2457%         message='no civ result created yet';
2458%     else
2459%         message='';
2460%     end
2461% else
2462%     datnum=datnum(datnum~=0);%keep the non zero values corresponding to existing files
2463%     [first,ind]=min(datnum);
2464%     [last,indlast]=max(datnum);
2465%     message={[num2str(count) ' file(s) done over ' num2str(nbfiles)] ;['oldest modification:  ' cell2mat(filefound(ind)) ' : ' datestr(first)];...
2466%         ['latest modification:  ' cell2mat(filefound(indlast)) ' : ' datestr(last)]};
2467% end
2468% hlist=findobj(hfig,'tag','list');
2469% hmsgbox=findobj(hfig,'tag','msgbox');
2470% hwaitbar=findobj(hfig,'tag','waitbar');
2471% set(hlist,'String',Tabchar)
2472% set(hmsgbox,'String', message)
2473% if count>0 %&& ~test_new
2474%     BarPosition(3)=0.9*count/nbfiles;
2475%     set(hwaitbar,'Position',BarPosition)
2476% end
2477%------------------------------------------------------------------------   
2478% launched by deleting the status figure
2479function stop_status(hObject, eventdata)
2480%------------------------------------------------------------------------
2481hciv=findobj(allchild(0),'tag','series');
2482hhciv=guidata(hciv);
2483set(hhciv.status,'value',0) %reset the status uicontrol in the GUI civ
2484set(hhciv.status,'BackgroundColor',[0 1 0])
2485delete(gcbf)
2486
2487% --- Executes on selection change in ActionExt.
2488function ActionExt_Callback(hObject, eventdata, handles)
2489ActionExtList=get(handles.ActionExt,'String');
2490ActionExt=ActionExtList{get(handles.ActionExt,'Value')};
2491ActionList=get(handles.ActionName,'String');
2492ActionName=ActionList{get(handles.ActionName,'Value')};
2493if strcmp(ActionExt,'.sh')
2494    ActionFullName=fullfile(get(handles.ActionPath,'String'),[ActionName ActionExt]);
2495    if ~exist(ActionFullName,'file')
2496        answer=msgbox_uvmat('INPUT_Y-N','compiled version has not been created: compile now?');
2497        if strcmp(answer,'Yes')
2498            currentdir=pwd;
2499            cd(get(handles.ActionPath,'String'))
2500            compile(ActionName)
2501            cd(currentdir)
2502        end
2503    end
2504end
2505
2506
2507function ActionInput_Callback(hObject, eventdata, handles)
2508
2509
2510% --- Executes on button press in DeleteObject.
2511function DeleteObject_Callback(hObject, eventdata, handles)
2512if get(handles.DeleteObject,'Value')
2513        SeriesData=get(handles.series,'UserData');
2514    SeriesData.ProjObject=[];
2515    set(handles.series,'UserData',SeriesData)
2516    set(handles.ProjObject,'String','')
2517    set(handles.CheckObject,'Value',0)
2518    set(handles.DeleteObject,'Visible','off')
2519    set(handles.ViewObject,'Visible','off')
2520end
2521
2522% --- Executes on button press in ViewObject.
2523function ViewObject_Callback(hObject, eventdata, handles)
2524if get(handles.ViewObject,'Value')
2525        UserData=get(handles.series,'UserData');
2526    set_object(UserData.ProjObject)
2527else
2528    hset_object=findobj(allchild(0),'Tag','set_object');
2529    if ~isempty(hset_object)
2530        delete(hset_object)
2531    end
2532end
2533
2534
2535function num_NbProcess_Callback(hObject, eventdata, handles)
2536
2537
2538function num_NbSlice_Callback(hObject, eventdata, handles)
2539NbSlice=str2num(get(handles.num_NbSlice,'String'));
2540set(handles.num_NbProcess,'String',num2str(NbSlice))
Note: See TracBrowser for help on using the repository browser.