source: trunk/src/series/time_series.m @ 627

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

waitbar system for series improved to aloow use as stand alone fcts.

to add at the head of series fcts:
hseries=findobj(allchild(0),'Tag','series');
RUNHandle=findobj(hseries,'Tag','RUN');%handle of RUN button in GUI series
WaitbarHandle?=findobj(hseries,'Tag','Waitbar');%handle of waitbar in GUI series

call to waitbar:

update_waitbar(WaitbarHandle?,index/nbfield)
if ishandle(RUNHandle) && ~strcmp(get(RUNHandle,'BusyAction?'),'queue')

disp('program stopped by user')
break

end

File size: 18.6 KB
Line 
1%'time_series': extract a time series after projection on an object (points , line..)
2% this function can be used as a template for applying a global operation on a series of input fields
3%------------------------------------------------------------------------
4% function GUI_input=time_series(Param)
5%
6%%%%%%%%%%% GENERAL TO ALL SERIES ACTION FCTS %%%%%%%%%%%%%%%%%%%%%%%%%%%
7%
8%OUTPUT
9% ParamOut: sets options in the GUI series.fig needed for the function
10%
11%INPUT:
12% In run mode, the input parameters are given as a Matlab structure Param copied from the GUI series.
13% In batch mode, Param is the name of the corresponding xml file containing the same information
14% when Param.Action.RUN=0 (as activated when the current Action is selected
15% in series), the function ouput paramOut set the activation of the needed GUI elements
16%
17% Param contains the elements:(use the menu bar command 'export/GUI config' in series to
18% see the current structure Param)
19%    .InputTable: cell of input file names, (several lines for multiple input)
20%                      each line decomposed as {RootPath,SubDir,Rootfile,NomType,Extension}
21%    .OutputSubDir: name of the subdirectory for data outputs
22%    .OutputDirExt: directory extension for data outputs
23%    .Action: .ActionName: name of the current activated function
24%             .ActionPath:   path of the current activated function
25%             .ActionExt: fct extension ('.m', Matlab fct, '.sh', compiled   Matlab fct
26%             .RUN =0 for GUI input, =1 for function activation
27%             .RunMode='local','background', 'cluster': type of function  use
28%             
29%    .IndexRange: set the file or frame indices on which the action must be performed
30%    .FieldTransform: .TransformName: name of the selected transform function
31%                     .TransformPath:   path  of the selected transform function
32%    .InputFields: sub structure describing the input fields withfields
33%              .FieldName: name(s) of the field
34%              .VelType: velocity type
35%              .FieldName_1: name of the second field in case of two input series
36%              .VelType_1: velocity type of the second field in case of two input series
37%              .Coord_y: name of y coordinate variable
38%              .Coord_x: name of x coordinate variable
39%    .ProjObject: %sub structure describing a projection object (read from ancillary GUI set_object)
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41
42function ParamOut=time_series(Param)
43
44%% set the input elements needed on the GUI series when the action is selected in the menu ActionName or InputTable refreshed
45if isstruct(Param) && isequal(Param.Action.RUN,0)
46    ParamOut.AllowInputSort='off';% allow alphabetic sorting of the list of input file SubDir (options 'off'/'on', 'off' by default)
47    ParamOut.WholeIndexRange='off';% prescribes the file index ranges from min to max (options 'off'/'on', 'off' by default)
48    ParamOut.NbSlice='on'; %nbre of slices ('off' by default)
49    ParamOut.VelType='two';% menu for selecting the velocity type (options 'off'/'one'/'two',  'off' by default)
50    ParamOut.FieldName='two';% menu for selecting the field (s) in the input file(options 'off'/'one'/'two', 'off' by default)
51    ParamOut.FieldTransform = 'on';%can use a transform function
52    ParamOut.TransformPath=fullfile(fileparts(which('uvmat')),'transform_field');% path to transform functions (needed for compilation only)
53    ParamOut.ProjObject='on';%can use projection object(option 'off'/'on',
54    ParamOut.Mask='off';%can use mask option   (option 'off'/'on', 'off' by default)
55    ParamOut.OutputDirExt='.tseries';%set the output dir extension
56    ParamOut.OutputFileMode='NbSlice';% '=NbInput': 1 output file per input file index, '=NbInput_i': 1 file per input file index i, '=NbSlice': 1 file per slice
57    filecell=get_file_series(Param);%check existence of the first input file
58    if ~exist(filecell{1,1},'file')
59        msgbox_uvmat('WARNING','the first input file does not exist')
60    elseif isequal(size(Param.InputTable,1),1) && ~isfield(Param,'ProjObject')
61        msgbox_uvmat('WARNING','a projection object  needs to be introduced for time_series')
62    end
63    return
64end
65
66%%%%%%%%%%%% STANDARD PART  %%%%%%%%%%%%
67ParamOut=[]; %default output
68%% read input parameters from an xml file if input is a file name (batch mode)
69checkrun=1;
70if ischar(Param)
71    Param=xml2struct(Param);% read Param as input file (batch case)
72    checkrun=0;
73end
74hseries=findobj(allchild(0),'Tag','series');
75RUNHandle=findobj(hseries,'Tag','RUN');%handle of RUN button in GUI series
76WaitbarHandle=findobj(hseries,'Tag','Waitbar');%handle of waitbar in GUI series
77
78%% define the directory for result file (with path=RootPath{1})
79OutputDir=[Param.OutputSubDir Param.OutputDirExt];
80
81%% root input file(s) name, type and index series
82RootPath=Param.InputTable(:,1);
83RootFile=Param.InputTable(:,3);
84SubDir=Param.InputTable(:,2);
85NomType=Param.InputTable(:,4);
86FileExt=Param.InputTable(:,5);
87[filecell,i1_series,i2_series,j1_series,j2_series]=get_file_series(Param);
88%%%%%%%%%%%%
89% The cell array filecell is the list of input file names, while
90% filecell{iview,fileindex}:
91%        iview: line in the table corresponding to a given file series
92%        fileindex: file index within  the file series,
93% i1_series(iview,ref_j,ref_i)... are the corresponding arrays of indices i1,i2,j1,j2, depending on the input line iview and the two reference indices ref_i,ref_j
94% i1_series(iview,fileindex) expresses the same indices as a 1D array in file indices
95%%%%%%%%%%%%
96nbview=numel(i1_series);%number of input file series (lines in InputTable)
97nbfield_j=size(j1_series{1},1); %nb of fields for the j index (bursts or volume slices)
98nbfield_i=size(i1_series{1},2); %nb of fields for the i index
99nbfield=nbfield_j*nbfield_i; %total number of fields
100[first_i,tild,last_i,first_j,tild,last_j,errormsg]=get_index_range(Param.IndexRange);
101if ~isempty(errormsg),display(errormsg),return,end
102
103%% determine the file type on each line from the first input file
104ImageTypeOptions={'image','multimage','mmreader','video'};
105NcTypeOptions={'netcdf','civx','civdata'};
106for iview=1:nbview
107    if ~exist(filecell{iview,1}','file')
108        displ_uvmat('ERROR',['the first input file ' filecell{iview,1} ' does not exist'],checkrun)
109        return
110    end
111    [FileType{iview},FileInfo{iview},MovieObject{iview}]=get_file_type(filecell{iview,1});
112    CheckImage{iview}=~isempty(find(strcmp(FileType{iview},ImageTypeOptions)));% =1 for images
113    CheckNc{iview}=~isempty(find(strcmp(FileType{iview},NcTypeOptions)));% =1 for netcdf files
114    if ~isempty(j1_series{iview})
115        frame_index{iview}=j1_series{iview};
116    else
117        frame_index{iview}=i1_series{iview};
118    end
119end
120
121%% calibration data and timing: read the ImaDoc files
122[XmlData,NbSlice_calib,time,errormsg]=read_multimadoc(RootPath,SubDir,RootFile,FileExt,i1_series,i2_series,j1_series,j2_series);
123if size(time,1)>1
124    diff_time=max(max(diff(time)));
125    if diff_time>0
126        displ_uvmat('WARNING',['times of series differ by (max) ' num2str(diff_time)],checkrun)
127    end
128    time=time(1,:);% choose the time data from the first sequence
129end
130
131%% coordinate transform or other user defined transform
132transform_fct=[];%default
133if isfield(Param,'FieldTransform')&&~isempty(Param.FieldTransform.TransformName)
134    addpath(Param.FieldTransform.TransformPath)
135    transform_fct=str2func(Param.FieldTransform.TransformName);
136    rmpath(Param.FieldTransform.TransformPath)
137end
138
139%%%%%%%%%%%% END STANDARD PART  %%%%%%%%%%%%
140% EDIT FROM HERE
141
142%% check the validity of  ctinput file types
143if CheckImage{1}
144    FileExtOut='.png'; % write result as .png images for image inputs
145elseif CheckNc{1}
146    FileExtOut='.nc';% write result as .nc files for netcdf inputs
147else
148    displ_uvmat('ERROR',['invalid file type input ' FileType{1}],checkrun)
149    return
150end
151if nbview==2 && ~isequal(CheckImage{1},CheckImage{2})
152    displ_uvmat('ERROR','input must be two image series or two netcdf file series',checkrun)
153    return
154end
155NomTypeOut=nomtype2pair(NomType{1});% determine the index nomenclature type for the output file
156
157%% Set field names and velocity types
158InputFields{1}=[];%default (case of images)
159if isfield(Param,'InputFields')
160    InputFields{1}=Param.InputFields;
161end
162if nbview==2
163    InputFields{2}=[];%default (case of images)
164    if isfield(Param,'InputFields')
165        InputFields{2}=Param.InputFields{1};%default
166        if isfield(Param.InputFields,'FieldName_1')
167            InputFields{2}.FieldName=Param.InputFields.FieldName_1;
168            if isfield(Param.InputFields,'VelType_1')
169                InputFields{2}.VelType=Param.InputFields.VelType_1;
170            end
171        end
172    end
173end
174
175%% Initiate output fields
176%initiate the output structure as a copy of the first input one (reproduce fields)
177[DataOut,tild,errormsg] = read_field(filecell{1,1},FileType{1},InputFields{1},1);
178if ~isempty(errormsg)
179    displ_uvmat('ERROR',['error reading ' filecell{1,1} ': ' errormsg],checkrun)
180    return
181end
182time_1=[];
183if isfield(DataOut,'Time')
184    time_1=DataOut.Time(1);
185end
186if CheckNc{iview}
187    if isempty(strcmp('Conventions',DataOut.ListGlobalAttribute))
188        DataOut.ListGlobalAttribute=['Conventions' DataOut.ListGlobalAttribute];
189    end
190    DataOut.Conventions='uvmat';
191    DataOut.ListGlobalAttribute=[DataOut.ListGlobalAttribute {Param.Action}];
192    ActionKey='Action';
193    while isfield(DataOut,ActionKey)
194        ActionKey=[ActionKey '_1'];
195    end
196    DataOut.(ActionKey)=Param.Action;
197    DataOut.ListGlobalAttribute=[DataOut.ListGlobalAttribute {ActionKey}];
198    if isfield(DataOut,'Time')
199        DataOut.ListGlobalAttribute=[DataOut.ListGlobalAttribute {'Time','Time_end'}];
200    end
201end
202
203nbmissing=0; %number of undetected files
204% for i_slice=1:NbSlice
205%index_slice=i_slice:NbSlice:nbfield;% select file indices of the slice
206nbfile=0;
207nbmissing=0;
208
209%%%%%%%%%%%%%%%% loop on field indices %%%%%%%%%%%%%%%%
210for index=1:nbfield
211            update_waitbar(WaitbarHandle,index/nbfield)
212    if ishandle(RUNHandle) && ~strcmp(get(RUNHandle,'BusyAction'),'queue')
213        disp('program stopped by user')
214        break % leave the loop if stop is ordered
215    end
216    Data=cell(1,nbview);%initiate the set Data;
217    nbtime=0;
218    dt=[];
219    %%%%%%%%%%%%%%%% loop on views (input lines) %%%%%%%%%%%%%%%%
220    for iview=1:nbview
221        % reading input file(s)
222        [Data{iview},tild,errormsg] = read_field(filecell{iview,index},FileType{iview},InputFields{iview},frame_index{iview}(index));
223        if ~isempty(errormsg)
224            errormsg=['time_series / read_field / ' errormsg];
225            display(errormsg)
226            break
227        end
228        if ~isempty(NbSlice_calib)
229            Data{iview}.ZIndex=mod(i1_series{iview}(index)-1,NbSlice_calib{iview})+1;%Zindex for phys transform
230        end
231    end
232    if isempty(errormsg)
233        Field=Data{1}; % default input field structure
234        % coordinate transform (or other user defined transform)
235        if ~isempty(transform_fct)
236            switch nargin(transform_fct)
237                case 4
238                    if length(Data)==2
239                        Field=transform_fct(Data{1},XmlData{1},Data{2},XmlData{2});
240                    else
241                        Field=transform_fct(Data{1},XmlData{1});
242                    end
243                case 3
244                    if length(Data)==2
245                        Field=transform_fct(Data{1},XmlData{1},Data{2});
246                    else
247                        Field=transform_fct(Data{1},XmlData{1});
248                    end
249                case 2
250                    Field=transform_fct(Data{1},XmlData{1});
251                case 1
252                    Field=transform_fct(Data{1});
253            end
254        end
255       
256        % calculate tps coefficients if needed
257        if isfield(Param.ProjObject,'ProjMode')&& strcmp(Param.ProjObject.ProjMode,'interp_tps')
258            Field=tps_coeff_field(Field,check_proj_tps);
259        end
260       
261        %field projection on an object
262        if Param.CheckObject
263            [Field,errormsg]=proj_field(Field,Param.ProjObject);
264            if ~isempty(errormsg)
265                msgbox_uvmat('ERROR',['time_series / proj_field / ' errormsg])
266                return
267            end
268        end
269        nbfile=nbfile+1;
270       
271        % initiate the time series at the first iteration
272        if nbfile==1
273            % stop program if the first field reading is in error
274            if ~isempty(errormsg)
275                displ_uvmat('ERROR',['time_series / sub_field / ' errormsg],checkrun)
276                return
277            end
278            DataOut=Field;%default
279            DataOut.NbDim=Field.NbDim+1; %add the time dimension for plots
280            nbvar=length(Field.ListVarName);
281            if nbvar==0
282                displ_uvmat('ERROR','no input variable selected',checkrun)
283                return
284            end
285            testsum=2*ones(1,nbvar);%initiate flag for action on each variable
286            if isfield(Field,'VarAttribute') % look for coordinate and flag variables
287                for ivar=1:nbvar
288                    if length(Field.VarAttribute)>=ivar && isfield(Field.VarAttribute{ivar},'Role')
289                        var_role=Field.VarAttribute{ivar}.Role;%'role' of the variable
290                        if isequal(var_role,'errorflag')
291                            displ_uvmat('ERROR','do not handle error flags in time series',checkrun)
292                            return
293                        end
294                        if isequal(var_role,'warnflag')
295                            testsum(ivar)=0;  % not recorded variable
296                            eval(['DataOut=rmfield(DataOut,''' Field.ListVarName{ivar} ''');']);%remove variable
297                        end
298                        if isequal(var_role,'coord_x')| isequal(var_role,'coord_y')|...
299                                isequal(var_role,'coord_z')|isequal(var_role,'coord')
300                            testsum(ivar)=1; %constant coordinates, record without time evolution
301                        end
302                    end
303                    % check whether the variable ivar is a dimension variable
304                    DimCell=Field.VarDimName{ivar};
305                    if ischar(DimCell)
306                        DimCell={DimCell};
307                    end
308                    if numel(DimCell)==1 && isequal(Field.ListVarName{ivar},DimCell{1})%detect dimension variables
309                        testsum(ivar)=1;
310                    end
311                end
312            end
313            for ivar=1:nbvar
314                if testsum(ivar)==2
315                    eval(['DataOut.' Field.ListVarName{ivar} '=[];'])
316                end
317            end
318            DataOut.ListVarName=[{'Time'} DataOut.ListVarName];
319        end
320       
321        % add data to the current field
322        for ivar=1:length(Field.ListVarName)
323            VarName=Field.ListVarName{ivar};
324            VarVal=Field.(VarName);
325            if testsum(ivar)==2% test for recorded variable
326                if isempty(errormsg)
327                    if isequal(Param.ProjObject.ProjMode,'inside')% take the average in the domain for 'inside' mode
328                        if isempty(VarVal)
329                            displ_uvmat('ERROR',['empty result at frame index ' num2str(i1_series{iview}(index))],checkrun)
330                            return
331                        end
332                        VarVal=mean(VarVal,1);
333                    end
334                    VarVal=shiftdim(VarVal,-1); %shift dimension
335                    DataOut.(VarName)=cat(1,DataOut.(VarName),VarVal);%concanete the current field to the time series
336                else
337                    DataOut.(VarName)=cat(1,DataOut.(VarName),0);% put each variable to 0 in case of input reading error
338                end
339            elseif testsum(ivar)==1% variable representing fixed coordinates
340                VarInit=DataOut.(VarName);
341                if isempty(errormsg) && ~isequal(VarVal,VarInit)
342                    displ_uvmat('ERROR',['time series requires constant coordinates ' VarName],checkrun)
343                    return
344                end
345            end
346        end
347       
348        % record the time:
349        if isempty(time)% time not set by xml filer(s)
350            if isfield(Data{1},'Time')
351                DataOut.Time(nbfile,1)=Field.Time;
352            else
353                DataOut.Time(nbfile,1)=index;%default
354            end
355        else % time from ImaDoc prevails  TODO: correct
356            DataOut.Time(nbfile,1)=time(index);%
357        end
358       
359        % record the number of missing input fields
360        if ~isempty(errormsg)
361            nbmissing=nbmissing+1;
362            display(['index=' num2str(index) ':' errormsg])
363        end
364    end
365   
366end
367%%%%%%% END OF LOOP WITHIN A SLICE
368
369%remove time for global attributes if exists
370Time_index=find(strcmp('Time',DataOut.ListGlobalAttribute));
371if ~isempty(Time_index)
372    DataOut.ListGlobalAttribute(Time_index)=[];
373end
374DataOut.Conventions='uvmat';
375for ivar=1:numel(DataOut.ListVarName)
376    VarName=DataOut.ListVarName{ivar};
377    eval(['DataOut.' VarName '=squeeze(DataOut.' VarName ');']) %remove singletons
378end
379
380% add time dimension
381for ivar=1:length(Field.ListVarName)
382    DimCell=Field.VarDimName(ivar);
383    if testsum(ivar)==2%variable used as time series
384        DataOut.VarDimName{ivar}=[{'Time'} DimCell];
385    elseif testsum(ivar)==1
386        DataOut.VarDimName{ivar}=DimCell;
387    end
388end
389indexremove=find(~testsum);
390if ~isempty(indexremove)
391    DataOut.ListVarName(1+indexremove)=[];
392    DataOut.VarDimName(indexremove)=[];
393    if isfield(DataOut,'Role') && ~isempty(DataOut.Role{1})%generaliser aus autres attributs
394        DataOut.Role(1+indexremove)=[];
395    end
396end
397
398%shift variable attributes
399if isfield(DataOut,'VarAttribute')
400    DataOut.VarAttribute=[{[]} DataOut.VarAttribute];
401end
402DataOut.VarDimName=[{'Time'} DataOut.VarDimName];
403DataOut.Action=Param.Action;%name of the processing programme
404test_time=diff(DataOut.Time)>0;% test that the readed time is increasing (not constant)
405if ~test_time
406    DataOut.Time=1:filecounter;
407end
408
409% display nbmissing
410if ~isequal(nbmissing,0)
411    displ_uvmat('WARNING',[num2str(nbmissing) ' files skipped: missing files or bad input, see command window display'],checkrun)
412end
413
414%% name of result file
415OutputFile=fullfile_uvmat(RootPath{1},OutputDir,RootFile{1},FileExtOut,NomTypeOut,first_i,last_i,first_j,last_j);
416errormsg=struct2nc(OutputFile,DataOut); %save result file
417if isempty(errormsg)
418    display([OutputFile ' written'])
419else
420    displ_uvmat('ERROR',['error in Series/struct2nc: ' errormsg],checkrun)
421end
422
423%% plot the time series (the last one in case of multislices)
424if checkrun
425    figure
426    haxes=axes;
427    plot_field(DataOut,haxes)
428   
429    %% display the result file using the GUI get_field
430    hget_field=findobj(allchild(0),'name','get_field');
431    if ~isempty(hget_field)
432        delete(hget_field)
433    end
434    get_field(OutputFile,DataOut)
435end
436
437
Note: See TracBrowser for help on using the repository browser.