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

Last change on this file since 624 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
RevLine 
[572]1%'time_series': extract a time series after projection on an object (points , line..)
[457]2% this function can be used as a template for applying a global operation on a series of input fields
[169]3%------------------------------------------------------------------------
[374]4% function GUI_input=time_series(Param)
[169]5%
[457]6%%%%%%%%%%% GENERAL TO ALL SERIES ACTION FCTS %%%%%%%%%%%%%%%%%%%%%%%%%%%
7%
[169]8%OUTPUT
[596]9% ParamOut: sets options in the GUI series.fig needed for the function
[169]10%
11%INPUT:
[457]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
[596]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
[169]16%
[596]17% Param contains the elements:(use the menu bar command 'export/GUI config' in series to
18% see the current structure Param)
[457]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
[474]22%    .OutputDirExt: directory extension for data outputs
[457]23%    .Action: .ActionName: name of the current activated function
24%             .ActionPath:   path of the current activated function
[596]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%             
[457]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
[596]33%              .FieldName: name(s) of the field
[457]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
[596]37%              .Coord_y: name of y coordinate variable
38%              .Coord_x: name of x coordinate variable
[457]39%    .ProjObject: %sub structure describing a projection object (read from ancillary GUI set_object)
40%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[596]41
[457]42function ParamOut=time_series(Param)
[27]43
[606]44%% set the input elements needed on the GUI series when the action is selected in the menu ActionName or InputTable refreshed
[592]45if isstruct(Param) && isequal(Param.Action.RUN,0)
[605]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
[606]52    ParamOut.TransformPath=fullfile(fileparts(which('uvmat')),'transform_field');% path to transform functions (needed for compilation only)
[605]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
[599]63    return
[27]64end
65
[526]66%%%%%%%%%%%% STANDARD PART  %%%%%%%%%%%%
[624]67ParamOut=[]; %default output
[592]68%% read input parameters from an xml file if input is a file name (batch mode)
69checkrun=1;
[457]70if ischar(Param)
[592]71    Param=xml2struct(Param);% read Param as input file (batch case)
72    checkrun=0;
[374]73end
[624]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
[592]77
[624]78%% define the directory for result file (with path=RootPath{1})
[474]79OutputDir=[Param.OutputSubDir Param.OutputDirExt];
[457]80
[609]81%% root input file(s) name, type and index series
[457]82RootPath=Param.InputTable(:,1);
83RootFile=Param.InputTable(:,3);
84SubDir=Param.InputTable(:,2);
85NomType=Param.InputTable(:,4);
86FileExt=Param.InputTable(:,5);
[374]87[filecell,i1_series,i2_series,j1_series,j2_series]=get_file_series(Param);
[526]88%%%%%%%%%%%%
89% The cell array filecell is the list of input file names, while
90% filecell{iview,fileindex}:
[457]91%        iview: line in the table corresponding to a given file series
[599]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
[457]94% i1_series(iview,fileindex) expresses the same indices as a 1D array in file indices
[526]95%%%%%%%%%%%%
[457]96nbview=numel(i1_series);%number of input file series (lines in InputTable)
[606]97nbfield_j=size(j1_series{1},1); %nb of fields for the j index (bursts or volume slices)
[457]98nbfield_i=size(i1_series{1},2); %nb of fields for the i index
99nbfield=nbfield_j*nbfield_i; %total number of fields
[609]100[first_i,tild,last_i,first_j,tild,last_j,errormsg]=get_index_range(Param.IndexRange);
101if ~isempty(errormsg),display(errormsg),return,end
[374]102
[609]103%% determine the file type on each line from the first input file
[457]104ImageTypeOptions={'image','multimage','mmreader','video'};
105NcTypeOptions={'netcdf','civx','civdata'};
106for iview=1:nbview
107    if ~exist(filecell{iview,1}','file')
[474]108        displ_uvmat('ERROR',['the first input file ' filecell{iview,1} ' does not exist'],checkrun)
[27]109        return
110    end
[457]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
[27]119end
120
[457]121%% calibration data and timing: read the ImaDoc files
[470]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
[457]124    diff_time=max(max(diff(time)));
125    if diff_time>0
[474]126        displ_uvmat('WARNING',['times of series differ by (max) ' num2str(diff_time)],checkrun)
[599]127    end
[531]128    time=time(1,:);% choose the time data from the first sequence
[457]129end
[27]130
[457]131%% coordinate transform or other user defined transform
[526]132transform_fct=[];%default
[478]133if isfield(Param,'FieldTransform')&&~isempty(Param.FieldTransform.TransformName)
[474]134    addpath(Param.FieldTransform.TransformPath)
135    transform_fct=str2func(Param.FieldTransform.TransformName);
136    rmpath(Param.FieldTransform.TransformPath)
[457]137end
[474]138
[457]139%%%%%%%%%%%% END STANDARD PART  %%%%%%%%%%%%
[599]140% EDIT FROM HERE
[27]141
[526]142%% check the validity of  ctinput file types
[457]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
[599]147else
[474]148    displ_uvmat('ERROR',['invalid file type input ' FileType{1}],checkrun)
[457]149    return
[27]150end
[457]151if nbview==2 && ~isequal(CheckImage{1},CheckImage{2})
[599]152    displ_uvmat('ERROR','input must be two image series or two netcdf file series',checkrun)
[259]153    return
154end
[609]155NomTypeOut=nomtype2pair(NomType{1});% determine the index nomenclature type for the output file
[457]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
[27]174
[457]175%% Initiate output fields
176%initiate the output structure as a copy of the first input one (reproduce fields)
[464]177[DataOut,tild,errormsg] = read_field(filecell{1,1},FileType{1},InputFields{1},1);
[457]178if ~isempty(errormsg)
[474]179    displ_uvmat('ERROR',['error reading ' filecell{1,1} ': ' errormsg],checkrun)
[457]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
[330]203nbmissing=0; %number of undetected files
[599]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
[624]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
[599]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
[442]227        end
[599]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
[526]241                        Field=transform_fct(Data{1},XmlData{1});
[599]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});
[474]253            end
[599]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
[474]267            end
[599]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
[474]277            end
[599]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
[27]293                        end
[599]294                        if isequal(var_role,'warnflag')
295                            testsum(ivar)=0;  % not recorded variable
296                            eval(['DataOut=rmfield(DataOut,''' Field.ListVarName{ivar} ''');']);%remove variable
[27]297                        end
[599]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
[474]301                        end
[27]302                    end
[599]303                    % check whether the variable ivar is a dimension variable
304                    DimCell=Field.VarDimName{ivar};
305                    if ischar(DimCell)
306                        DimCell={DimCell};
[474]307                    end
[599]308                    if numel(DimCell)==1 && isequal(Field.ListVarName{ivar},DimCell{1})%detect dimension variables
309                        testsum(ivar)=1;
310                    end
[474]311                end
312            end
[599]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
[27]331                        end
[599]332                        VarVal=mean(VarVal,1);
[330]333                    end
[599]334                    VarVal=shiftdim(VarVal,-1); %shift dimension
335                    DataOut.(VarName)=cat(1,DataOut.(VarName),VarVal);%concanete the current field to the time series
[474]336                else
[599]337                    DataOut.(VarName)=cat(1,DataOut.(VarName),0);% put each variable to 0 in case of input reading error
[330]338                end
[599]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
[27]345            end
[599]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
[474]354            end
[599]355        else % time from ImaDoc prevails  TODO: correct
356            DataOut.Time(nbfile,1)=time(index);%
[27]357        end
[599]358       
359        % record the number of missing input fields
360        if ~isempty(errormsg)
361            nbmissing=nbmissing+1;
362            display(['index=' num2str(index) ':' errormsg])
[27]363        end
[330]364    end
365   
[599]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;
[330]387    end
[599]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)=[];
[330]395    end
[27]396end
[107]397
[599]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
[609]414%% name of result file
415OutputFile=fullfile_uvmat(RootPath{1},OutputDir,RootFile{1},FileExtOut,NomTypeOut,first_i,last_i,first_j,last_j);
[599]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
[330]423%% plot the time series (the last one in case of multislices)
[474]424if checkrun
[478]425    figure
426    haxes=axes;
427    plot_field(DataOut,haxes)
[599]428   
[478]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)
[474]435end
[27]436
437
Note: See TracBrowser for help on using the repository browser.