source: trunk/src/series/aver_stat.m @ 76

Last change on this file since 76 was 76, checked in by sommeria, 14 years ago

minor bug repairs. Projection on any abject inside the main uvmat axes is now possible
aver_stat, time_series, merge_proj: set_object now called by tag instead of name (which depends on the object)

File size: 19.7 KB
Line 
1function GUI_input=aver_stat(num_i1,num_i2,num_j1,num_j2,Series)
2%----------------------------------------------------------------------
3% --- make average on a series of files
4%----------------------------------------------------------------------
5%INPUT:
6%num_i1: series of first indices i (given from the series interface as first_i:incr_i:last_i, mode and list_pair_civ)
7%num_i2: series of second indices i (given from the series interface as first_i:incr_i:last_i, mode and list_pair_civ)
8%num_j1: series of first indices j (given from the series interface as first_j:incr_j:last_j, mode and list_pair_civ )
9%num_j2: series of second indices j (given from the series interface as first_j:incr_j:last_j, mode and list_pair_civ)
10%OTHER INPUTS given by the structure Series
11%  Series.Time:
12%  Series.GeometryCalib:%requests for the visibility of input windows in the GUI series  (activated directly by the selection in the menu ACTION)
13if ~exist('num_i1','var')
14    GUI_input={'RootPath';'two';...%nbre of possible input series (options 'on'/'two'/'many', default:'one')
15        'SubDir';'on';... % subdirectory of derived files (PIV fields), ('on' by default)
16        'RootFile';'on';... %root input file name ('on' by default)
17        'FileExt';'on';... %input file extension ('on' by default)
18        'NomType';'on';...%type of file indexing ('on' by default)
19        'NbSlice';'on'; ...%nbre of slices ('off' by default)
20        'VelTypeMenu';'two';...% menu for selecting the velocity type (options 'off'/'one'/'two',  'off' by default)
21        'FieldMenu';'two';...% menu for selecting the field (s) in the input file(options 'off'/'one'/'two', 'off' by default)
22        'CoordType'; 'on';...%can use a transform function
23        'GetObject';'on';...%can use projection object(option 'off'/'one'/'two',
24        %'GetMask';'on'...%can use mask option   
25        %'PARAMETER'; %options: name of the user defined parameter',repeat a line for each parameter
26               ''};
27        return
28end
29
30%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31hseries=guidata(Series.hseries);%handles of the GUI series
32WaitbarPos=get(hseries.waitbar_frame,'Position');
33%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34
35%projection object
36test_object=get(hseries.GetObject,'Value');
37if test_object%isfield(Series,'sethandles')
38    hset_object=findobj(allchild(0),'tag','set_object');
39    ProjObject=read_set_object(guidata(hset_object));
40    %answeryes=questdlg({['field series projected on ' Series.ProjObject.Style]});
41    answeryes=msgbox_uvmat('INPUT_Y-N',['field series projected on ' ProjObject.Style ' before averaging']);
42    if ~isequal(answeryes,'Yes')
43        return
44    end
45end
46
47%root input file and type
48if ~iscell(Series.RootPath)% case of a single input field series
49    num_i1={num_i1};num_j1={num_j1};num_i2={num_i2};num_j2={num_j2};
50    RootPath={Series.RootPath};
51    RootFile={Series.RootFile};
52    SubDir={Series.SubDir};
53    FileExt={Series.FileExt};
54    NomType={Series.NomType};
55else
56    RootPath=Series.RootPath;
57    RootFile=Series.RootFile;
58    SubDir=Series.SubDir;
59    NomType=Series.NomType;
60    FileExt=Series.FileExt;
61end   
62ext=FileExt{1};
63form=imformats(ext([2:end]));%test valid Matlab image formats
64testima=0;
65if ~isempty(form)||isequal(lower(ext),'.avi')||isequal(lower(ext),'.vol')
66    testima(1)=1;
67end
68if length(FileExt)>=2
69    ext_1=FileExt{2};
70    form=imformats(ext_1([2:end]));%test valid Matlab image formats
71    if ~isempty(form)||isequal(lower(ext_1),'.avi')||isequal(lower(ext_1),'.vol')
72        testima(2)=1;
73    end
74    if testima(2)~=testima(1)
75        msgbox_uvmat('ERROR','images and netcdf files cannot be compared')
76        return
77    end
78end
79
80%Number of input series: this function  accepts two input file series at most (then it operates on the difference of fields)
81nbview=length(RootPath);
82if nbview>2 
83    RootPath=RootPath(1:2);
84    set(hseries.RootPath,'String',RootPath)
85    SubDir=SubDir(1:2);
86    set(hseries.SubDir,'String',SubDir)
87    RootFile=RootFile(1:2);
88    set(hseries.RootFile,'String',RootFile)
89    NomType=NomType(1:2);
90    FileExt=FileExt(1:2);
91    set(hseries.FileExt,'String',FileExt)
92    nbview=2;
93end
94
95%determine image type
96hhh=which('mmreader');
97for iview=1:nbview
98    if isequal(FileExt{iview},'.nc')||isequal(FileExt{iview},'.cdf')
99        FileType{iview}='netcdf';
100    elseif isequal(lower(FileExt{iview}),'.avi')
101        if ~isequal(hhh,'')&& mmreader.isPlatformSupported()
102            MovieObject{iview}=mmreader(fullfile(RootPath{iview},[RootFile{iview} FileExt{iview}]));
103            FileType{iview}='movie';
104        else
105            FileType{iview}='avi';
106        end
107    elseif isequal(lower(FileExt{iview}),'.vol')
108        FileType{iview}='vol';
109    else
110       form=imformats(FileExt{iview}(2:end));
111       if ~isempty(form)% if the extension corresponds to an image format recognized by Matlab
112           if isequal(NomType{iview},'*');
113               FileType{iview}='multimage';
114           else
115               FileType{iview}='image';
116           end
117       end
118    end
119end
120
121% number of slices
122NbSlice=str2num(get(hseries.NbSlice,'String'));
123if isempty(NbSlice)
124    NbSlice=1;
125end
126NbSlice_name=num2str(NbSlice);
127
128% Field and velocity type (the same for the two views)
129Field_str=get(hseries.FieldMenu,'String');
130FieldName=[]; %default
131testfield=get(hseries.FieldMenu,'Visible');
132if isequal(testfield,'on')
133    val=get(hseries.FieldMenu,'Value');
134    FieldName=Field_str(val);%the same set of fields for all views
135    if isequal(FieldName,{'get_field...'})
136        hget_field=findobj(allchild(0),'name','get_field');%find the get_field... GUI
137        if length(hget_field)>1
138            delete(hget_field(2:end))
139        elseif isempty(hget_field)
140           filename=...
141                 name_generator(fullfile(RootPath{1},RootFile{1}),num_i1{1}(1),num_j1{1}(1),FileExt{1},NomType{1},1,num_i2{1}(1),num_j2{1}(1),SubDir{1});
142           get_field(filename);
143           return
144        end
145        %hhget_field=guidata(hget_field);%handles of GUI elements in get_field
146        SubField=read_get_field(hget_field); %read the names of the variables to plot in the get_field GUI
147    end
148end
149%detect whether the two files are 'images' or 'netcdf'
150% testima=0;
151% testvol=0;
152testcivx=0;
153% testnc=0;
154FileExt=get(hseries.FileExt,'String');
155% test_movie=0;
156% for iview=1:nbview
157%      ext=FileExt{iview};
158%      form=imformats(ext([2:end]));
159%      if isequal(lower(ext),'.vol')
160%          testvol=testvol+1;
161%      elseif ~isempty(form)||isequal(lower(ext),'.avi')% if the extension corresponds to an image format recognized by Matlab
162%          testima=testima+1;
163%      elseif isequal(ext,'.nc')
164%          testnc=testnc+1;
165%      end
166% end
167% if testvol
168%     msgbox_uvmat('ERROR','volume images not implemented yet')
169%     return
170% end
171% if testnc~=nbview && testima~=nbview && testvol~=nbview
172%     msgbox_uvmat('ERROR','compare two image series or two netcdf files with the same fields as input')
173%     return
174% end
175if ~isequal(FieldName,{'get_field...'})
176    testcivx=isequal(FileType{1},'netcdf');
177end
178% if ~isequal(FieldName,{'get_field...'})
179%     if isequal(FieldName,{''}) && ~testima
180%         msgbox_uvmat('ERROR','an input field needs to be selected')
181%         return
182%     end
183%     testcivx=testnc;
184% end
185
186if testcivx
187    VelType_str=get(hseries.VelTypeMenu,'String');
188    VelType_val=get(hseries.VelTypeMenu,'Value');
189    VelType{1}=VelType_str{VelType_val};
190    if nbview==2
191        VelType_str=get(hseries.VelTypeMenu_1,'String');
192        VelType_val=get(hseries.VelTypeMenu_1,'Value');
193        VelType{2}=VelType_str{VelType_val};
194    end
195end
196
197%Calibration data and timing: read the ImaDoc files
198mode=''; %default
199timecell={};
200itime=0;
201NbSlice_calib={};
202for iview=1:nbview%Loop on views
203    XmlData{iview}=[];%default
204    filebase{iview}=fullfile(RootPath{iview},RootFile{iview});
205    if exist([filebase{iview} '.xml'],'file')
206        [XmlData{iview},error]=imadoc2struct([filebase{iview} '.xml']);
207        if isfield(XmlData{iview},'Time')
208            itime=itime+1;
209            timecell{itime}=XmlData{iview}.Time;
210        end
211        if isfield(XmlData{iview},'GeometryCalib') && isfield(XmlData{iview}.GeometryCalib,'SliceCoord')
212            NbSlice_calib{iview}=size(XmlData{iview}.GeometryCalib.SliceCoord,1);%nbre of slices for Zindex in phys transform
213            if ~isequal(NbSlice_calib{iview},NbSlice_calib{1})
214                msgbox_uvmat('WARNING','inconsistent number of Z indices for the two field series');
215            end
216        end
217    elseif exist([filebase{iview} '.civ'],'file')
218        [error,time,TimeUnit,mode,npx,npy,pxcmx,pxcmy]=read_imatext([filebase{iview} '.civ']);
219        itime=itime+1;
220        timecell{itime}=time;
221        XmlData{iview}.Time=time;
222        GeometryCalib.R=[pxcmx 0 0; 0 pxcmy 0;0 0 0];
223        GeometryCalib.Tx=0;
224        GeometryCalib.Ty=0;
225        GeometryCalib.Tz=1;
226        GeometryCalib.dpx=1;
227        GeometryCalib.dpy=1;
228        GeometryCalib.sx=1;
229        GeometryCalib.Cx=0;
230        GeometryCalib.Cy=0;
231        GeometryCalib.f=1;
232        GeometryCalib.kappa1=0;
233        GeometryCalib.CoordUnit='cm';
234        XmlData{iview}.GeometryCalib=GeometryCalib;
235        if error==1
236            msgbox_uvmat('WARNING','inconsistent number of fields in the .civ file');
237        end
238    end
239end
240
241%check coincidence in time
242multitime=0;
243if isempty(timecell)
244    time=[];
245elseif length(timecell)==1
246    time=timecell{1};
247elseif length(timecell)>1
248    multitime=1;
249    for icell=1:length(timecell)
250        if ~isequal(size(timecell{icell}),size(timecell{1}))
251            msgbox_uvmat('WARNING','inconsistent time array dimensions in ImaDoc fields, the time for the first series is used')
252            time=timecell{1};
253            multitime=0;
254            break
255        end
256    end
257end
258if multitime
259    for icell=1:length(timecell)
260        time(icell,:,:)=timecell{icell};
261    end
262    diff_time=max(max(diff(time)));
263    if diff_time>0
264        msgbox_uvmat('WARNING',['times of series differ by more than ' num2str(diff_time)])
265    end   
266end
267if size(time,2) < num_i2{1}(end) || size(time,3) < num_j2{1}(end)% ime array absent or too short in ImaDoc xml file'
268    time=[];
269end
270
271% Root name of output files (TO GENERALISE FOR TWO INPUT SERIES)
272subdir_result='aver_stat';
273if ~exist(fullfile(RootPath{1},subdir_result),'dir')
274    dircur=pwd; %record current working directory
275    cd(RootPath{1})% goes to the iamge directory
276    [m1,m2,m3]=mkdir(subdir_result);
277    if ~isequal(m2,'')
278         msgbox_uvmat('CONFIRMATION',m2);%error message for directory creation
279    end
280    cd(dircur) %back to the initial working directory
281end
282filebase_out=filebase{1};
283NomTypeOut=nomtype2pair(NomType{1},num_i2{end}(end)-num_i1{1}(1),num_j2{end}(end)-num_j1{1}(1));
284
285% coordinate transform or other user defined transform
286transform_fct=[];%default
287if isfield(Series,'transform_fct')
288    transform_fct=Series.transform_fct;
289end
290
291%slice loop
292siz=size(num_i1{1});
293lengthtot=siz(1)*siz(2);
294nbfield=floor(lengthtot/(siz(1)*NbSlice));%total number of i indexes (adjusted to an integer number of slices)
295nbfield_slice=nbfield*siz(1);% number of fields per slice
296
297for i_slice=1:NbSlice
298   S=0; %initiate the image sum S
299   nbfiles=0;
300   nbmissing=0;
301    %averaging loop
302   for ifile=i_slice:NbSlice:lengthtot
303        stopstate=get(hseries.RUN,'BusyAction');
304        if isequal(stopstate,'queue') % enable STOP command
305             update_waitbar(hseries.waitbar,WaitbarPos,ifile/lengthtot)
306             for iview=1:nbview
307                [filename]=...
308                           name_generator(filebase{iview},num_i1{iview}(ifile),num_j1{iview}(ifile),FileExt{iview},NomType{iview},1,num_i2{iview}(ifile),num_j2{iview}(ifile),SubDir{iview});
309                if ~isequal(FileType{iview},'netcdf')               
310                    Data{iview}.ListVarName={'A'};
311                    Data{iview}.AName='image';
312                    switch FileType{iview}
313                        case 'movie'
314                            A=read(MovieObject{iview},num_i1{iview}(ifile));
315                        case 'avi'
316                            mov=aviread(filename,num_i1{iview}(ifile));
317                            A=frame2im(mov(1));
318                        case 'vol'
319                            A=imread(filename);
320                        case 'multimage'
321                            A=imread(filename,num_i1{iview}(ifile));
322                        case 'image'
323                            A=imread(filename);
324                    end
325                    Data{iview}.ListVarName={'coord_y','coord_x','A'}; %
326                    Atype{iview}=class(A);
327                    npy=size(A,1);
328                    npx=size(A,2);
329                    nbcolor=size(A,3);
330                    if nbcolor==3
331                         Data{iview}.VarDimName={'coord_y','coord_x',{'coord_y','coord_x','rgb'}};
332                    else
333                         Data{iview}.VarDimName={'coord_y','coord_x',{'coord_y','coord_x'}};
334                    end 
335                    Data{iview}.coord_y=[npy-0.5 0.5];
336                    Data{iview}.coord_x=[0.5 npx-0.5];
337                    Data{iview}.A=double(A);
338                    Data{iview}.CoordType='px';
339                elseif testcivx
340                    [Data{iview},VelTypeOut]=read_civxdata(filename,FieldName,VelType);
341                else
342                    [Data{iview},var_detect]=nc2struct(filename,SubField.ListVarName); %read the corresponding input data               
343                    Data{iview}.VarAttribute=SubField.VarAttribute;
344                end
345                if isfield(Data{iview},'Txt')
346                    msgbox_uvmat('ERROR',['error of input reading: ' Data{iview}.Txt])
347                    return
348                end
349             end   
350             % coordinate transform (or other user defined transform)
351             if ~isempty(transform_fct)
352                 % z index
353                if ~isempty(NbSlice_calib)
354                    Data{iview}.ZIndex=mod(num_i1{iview}(ifile)-1,NbSlice_calib{1})+1;%Zindex for phys transform
355                end
356                if nbview==2
357                    [Data{1},Data{2}]=transform_fct(Data{1},XmlData{1},Data{2},XmlData{2});
358                    if isempty(Data{2})
359                        Data(2)=[];
360                    end
361                else
362                    Data{1}=transform_fct(Data{1},XmlData);
363                end
364             end     
365            if testcivx
366                    Data{iview}=calc_field(FieldName,Data{iview});%calculate field (vort..)
367            end
368            if length(Data)==2
369                [Field,errormsg]=sub_field(Data{1},Data{2}); %substract the two fields
370                if ~isempty(errormsg)
371                    msgbox_uvmat('ERROR',['error in aver_stat/sub_field:' errormsg])
372                    return
373                end
374            else
375                Field=Data{1};
376            end
377            if test_object
378                [Field,errormsg]=proj_field(Field,ProjObject);
379                 if ~isempty(errormsg)
380                    msgbox_uvmat('ERROR',['error in aver_stat/proj_field:' errormsg])
381                    return
382                end
383             end                                                       
384                nbfiles=nbfiles+1;
385                if nbfiles==1 %first field
386                    time_1=[];
387                    if isfield(Field,'Time')
388                        time_1=Field.Time(1);
389                    end
390                    DataMean=Field;%default
391                else
392                    for ivar=1:length(Field.ListVarName)
393                        VarName=Field.ListVarName{ivar};
394                        eval(['sizmean=size(DataMean.' VarName ');']);
395                        eval(['siz=size(Field.' VarName ');']);
396                        if ~isequal(siz,sizmean)
397                           msgbox_uvmat('ERROR',['unequal size of input field ' VarName ', need to interpolate on a grid'])
398                           return
399                        else
400                            eval(['DataMean.' VarName '=DataMean.' VarName '+ Field.' VarName ';']); % update the sum
401                        end
402                    end
403                end
404%             else
405%                 nbmissing=nbmissing+1;
406%             end
407        end
408    end %end averaging loop
409    for ivar=1:length(Field.ListVarName)
410        VarName=Field.ListVarName{ivar};
411        eval(['DataMean.' VarName '=DataMean.' VarName '/nbfiles;']); % normalize the mean
412    end
413    if nbmissing~=0
414        msgbox_uvmat('WARNING',[num2str(nbmissing) ' input files are missing or skipted'])
415    end
416    if isempty(time) % time read from files  prevails
417        time_end=[];
418        if isfield(Field,'Time')
419            time_end=Field.Time(1);%last time read
420            if ~isempty(time_1)
421                DataMean.Time=time_1;
422                DataMean.Time_end=time_end;
423            end
424        end
425    else  % time from ImaDoc prevails
426        DataMean.Time=time(1,num_i1{1}(1),num_j1{1}(1));
427        DataMean.Time_end=time(end,num_i1{end}(end),num_j1{end}(end));
428    end
429   
430    %writing the result file
431   if testima   
432%        if NbSlice==1
433        [filemean]=name_generator(filebase_out,num_i1{1}(1),num_j1{1}(1),'.png',NomTypeOut,1,num_i2{end}(end),num_j2{end}(end),subdir_result);
434%        else % label the file number by the slice # for simplicity
435%           [filemean]=name_generator(filebase_out,i_slice,1,'.png','_i');
436%        end
437        if exist(filemean,'file')
438            backupfile=filemean;
439            testexist=2;
440            while testexist==2
441                backupfile=[backupfile(1:end-4) '~.png'];
442                testexist=exist(backupfile,'file');
443            end
444            [success,message]=copyfile(filemean,backupfile);%make backup
445            if ~isequal(success,1)
446                msgbox_uvmat('ERROR',['previous file result ' filemean ' already exists, problem in backup'])
447                return
448            end
449        end
450        if isequal(Atype{1},'uint16')
451            imwrite(uint16(DataMean.A),filemean,'BitDepth',16);
452        else
453            imwrite(uint8(DataMean.A),filemean,'BitDepth',8);
454        end
455        display([filemean ' written']);
456    else %case of netcdf input file , determine global attributes
457        DataMean.ListGlobalAttribute=[DataMean.ListGlobalAttribute {Series.Action}];
458        ActionKey='Action';
459        while isfield(DataMean,ActionKey)
460            ActionKey=[ActionKey '_1'];
461        end
462        eval(['DataMean.' ActionKey '=Series.Action;'])
463        DataMean.ListGlobalAttribute=[DataMean.ListGlobalAttribute {ActionKey}];
464        if isfield(DataMean,'Time')
465            DataMean.ListGlobalAttribute=[DataMean.ListGlobalAttribute {'Time','Time_end'}];
466        end 
467%         if NbSlice==1
468          filemean=name_generator(filebase_out,num_i1{1}(1),num_j1{1}(1),'.nc',NomTypeOut,1,num_i2{end}(end),num_j2{end}(end),subdir_result);
469%         else % label the file number by the slice # for simplicity
470%           [filemean]=name_generator(filebase_out,i_slice,1,'.nc','_i');
471%         end
472        if exist(filemean,'file')
473            backupfile=filemean;
474            testexist=2;
475            while testexist==2
476                backupfile=[backupfile(1:end-3) '~.nc'];
477                testexist=exist(backupfile,'file');
478            end
479            [success,message]=copyfile(filemean,backupfile);%make backup
480            if ~isequal(success,1)
481                msgbox_uvmat('ERROR',['previous file result ' filemean ' already exists, problem in backup'])
482                display(['previous file result ' filemean ' already exists, problem in backup'])
483                return
484            end
485        end
486        errormsg=struct2nc(filemean,DataMean); %save result file
487        if isempty(errormsg)
488            display([filemean ' written']);
489        else
490            msgbox_uvmat('ERROR',['error in writting result file: ' errormsg])
491            display(errormsg)
492        end
493   end
494end
495
496hget_field=findobj(allchild(0),'name','get_field');%find the get_field... GUI
497delete(hget_field)
498uvmat(filemean)
Note: See TracBrowser for help on using the repository browser.