source: trunk/src/series/merge_proj.m @ 457

Last change on this file since 457 was 457, checked in by sommeria, 12 years ago

merg_i_j transformed to the new standards.
Various improvements

File size: 29.3 KB
Line 
1%'merge_proj': project and concatene fieldsmerge_proj
2% can be used as a template for applying an operation (here projection and concateantion) on each field of an input series
3%------------------------------------------------------------------------
4% function GUI_config=merge_proj(Param)
5%------------------------------------------------------------------------
6
7%%%%%%%%%%% GENERAL TO ALL SERIES ACTION FCTS %%%%%%%%%%%%%%%%%%%%%%%%%%%
8%
9% This function is used in four modes by the GUI series:
10%           1) config GUI: with no input argument, the function determine the suitable GUI configuration
11%           2) interactive input: the function is used to interactively introduce input parameters, and then stops
12%           3) RUN: the function itself runs, when an appropriate input  structure Param has been introduced.
13%           4) BATCH: the function itself proceeds in BATCH mode, using an xml file 'Param' as input.
14%
15% This function is used in four modes by the GUI series:
16%           1) config GUI: with no input argument, the function determine the suitable GUI configuration
17%           2) interactive input: the function is used to interactively introduce input parameters, and then stops
18%           3) RUN: the function itself runs, when an appropriate input  structure Param has been introduced.
19%           4) BATCH: the function itself proceeds in BATCH mode, using an xml file 'Param' as input.
20%
21%OUTPUT
22% GUI_input=list of options in the GUI series.fig needed for the function
23%
24%INPUT:
25% In run mode, the input parameters are given as a Matlab structure Param copied from the GUI series.
26% In batch mode, Param is the name of the corresponding xml file containing the same information
27% In the absence of input (as activated when the current Action is selected
28% in series), the function ouput GUI_input set the activation of the needed GUI elements
29%
30% Param contains the elements:(use the menu bar command 'export/GUI config' in series to see the current structure Param)
31%    .InputTable: cell of input file names, (several lines for multiple input)
32%                      each line decomposed as {RootPath,SubDir,Rootfile,NomType,Extension}
33%    .OutputSubDir: name of the subdirectory for data outputs
34%    .OutputDir: directory for data outputs, including path
35%    .Action: .ActionName: name of the current activated function
36%             .ActionPath:   path of the current activated function
37%    .IndexRange: set the file or frame indices on which the action must be performed
38%    .FieldTransform: .TransformName: name of the selected transform function
39%                     .TransformPath:   path  of the selected transform function
40%                     .TransformHandle: corresponding function handle
41%    .InputFields: sub structure describing the input fields withfields
42%              .FieldName: name of the field
43%              .VelType: velocity type
44%              .FieldName_1: name of the second field in case of two input series
45%              .VelType_1: velocity type of the second field in case of two input series
46%    .ProjObject: %sub structure describing a projection object (read from ancillary GUI set_object)
47%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48
49function GUI_input=merge_proj(Param)
50
51%% set the input elements needed on the GUI series when the action is selected in the menu ActionName
52if ~exist('Param','var') % case with no input parameter
53    GUI_input={'NbViewMax';2;...% max nbre of input file series (default='' , no limitation)
54        'AllowInputSort';'off';...% allow alphabetic sorting of the list of input files (options 'off'/'on', 'off' by default)
55        'NbSlice';'on'; ...%nbre of slices ('off' by default)
56        'VelType';'two';...% menu for selecting the velocity type (options 'off'/'one'/'two',  'off' by default)
57        'FieldName';'two';...% menu for selecting the field (s) in the input file(options 'off'/'one'/'two', 'off' by default)
58        'FieldTransform'; 'on';...%can use a transform function
59        'ProjObject';'on';...%can use projection object(option 'off'/'on',
60        'Mask';'on';...%can use mask option   (option 'off'/'on', 'off' by default)
61        'OutputDirExt';'.proj';...%set the output dir extension
62               ''};
63        return
64end
65
66%%%%%%%%%%%% STANDARD PART (DO NOT EDIT) %%%%%%%%%%%%
67%% select different modes,  RUN, parameter input, BATCH
68% BATCH  case: read the xml file for batch case
69if ischar(Param)
70    if strcmp(Param,'input?')
71        checkrun=1;% will inly search input parameters (preparation of BATCH mode)
72    else
73        Param=xml2struct(Param);
74        checkrun=0;
75    end
76% RUN case: parameters introduced as the input structure Param
77else
78    hseries=guidata(Param.hseries);%handles of the GUI series
79    WaitbarPos=get(hseries.waitbar_frame,'Position');%position of the waitbar on the GUI series
80    checkrun=2; % indicate the RUN option is used
81end
82
83%% root input file(s) and type
84RootPath=Param.InputTable(:,1);
85RootFile=Param.InputTable(:,3);
86SubDir=Param.InputTable(:,2);
87NomType=Param.InputTable(:,4);
88FileExt=Param.InputTable(:,5);
89
90% get the set of input file names (cell array filecell), and the lists of
91% input file or frame indices i1_series,i2_series,j1_series,j2_series
92[filecell,i1_series,i2_series,j1_series,j2_series]=get_file_series(Param);
93% filecell{iview,fileindex}: cell array representing the list of file names
94%        iview: line in the table corresponding to a given file series
95%        fileindex: file index within  the file series,
96% 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
97% i1_series(iview,fileindex) expresses the same indices as a 1D array in file indices
98% set of frame indices used for movie or multimage input
99% numbers of slices and file indices
100
101NbSlice=1;%default
102if isfield(Param.IndexRange,'NbSlice')
103    NbSlice=Param.IndexRange.NbSlice;
104end
105nbview=numel(i1_series);%number of input file series (lines in InputTable)
106nbfield_j=size(i1_series{1},1); %nb of fields for the j index (bursts or volume slices)
107nbfield_i=size(i1_series{1},2); %nb of fields for the i index
108nbfield=nbfield_j*nbfield_i; %total number of fields
109nbfield_i=floor(nbfield/NbSlice);%total number of  indexes in a slice (adjusted to an integer number of slices)
110nbfield=nbfield_i*NbSlice; %total number of fields after adjustement
111
112%determine the file type on each line from the first input file
113ImageTypeOptions={'image','multimage','mmreader','video'};%allowed input file types(images)
114
115[FileType{1},FileInfo{1},MovieObject{1}]=get_file_type(filecell{1,1});
116CheckImage{1}=~isempty(find(strcmp(FileType,ImageTypeOptions)));% =1 for images
117if ~isempty(j1_series{1})
118    frame_index{1}=j1_series{1};
119else
120    frame_index{1}=i1_series{1};
121end
122
123%% calibration data and timing: read the ImaDoc files
124mode=''; %default
125timecell={};
126itime=0;
127NbSlice_calib={};
128for iview=1:nbview%Loop on views
129    XmlData{iview}=[];%default
130    filebase{iview}=fullfile(RootPath{iview},RootFile{iview});
131    if exist([filebase{iview} '.xml'],'file')
132        [XmlData{iview},error]=imadoc2struct([filebase{iview} '.xml']);
133        if isfield(XmlData{iview},'Time')
134            itime=itime+1;
135            timecell{itime}=XmlData{iview}.Time;
136        end
137        if isfield(XmlData{iview},'GeometryCalib') && isfield(XmlData{iview}.GeometryCalib,'SliceCoord')
138            NbSlice_calib{iview}=size(XmlData{iview}.GeometryCalib.SliceCoord,1);%nbre of slices for Zindex in phys transform
139            if ~isequal(NbSlice_calib{iview},NbSlice_calib{1})
140                msgbox_uvmat('WARNING','inconsistent number of Z indices for the two field series');
141            end
142        end
143    elseif exist([filebase{iview} '.civ'],'file')
144        [error,time,TimeUnit,mode,npx,npy,pxcmx,pxcmy]=read_imatext([filebase{iview} '.civ']);
145        itime=itime+1;
146        timecell{itime}=time;
147        XmlData{iview}.Time=time;
148        GeometryCalib.R=[pxcmx 0 0; 0 pxcmy 0;0 0 0];
149        GeometryCalib.Tx=0;
150        GeometryCalib.Ty=0;
151        GeometryCalib.Tz=1;
152        GeometryCalib.dpx=1;
153        GeometryCalib.dpy=1;
154        GeometryCalib.sx=1;
155        GeometryCalib.Cx=0;
156        GeometryCalib.Cy=0;
157        GeometryCalib.f=1;
158        GeometryCalib.kappa1=0;
159        GeometryCalib.CoordUnit='cm';
160        XmlData{iview}.GeometryCalib=GeometryCalib;
161        if error==1
162            msgbox_uvmat('WARNING','inconsistent number of fields in the .civ file');
163        end
164    end
165end
166
167%% check coincidence in time for several input file series
168multitime=0;
169if isempty(timecell)
170    time=[];
171elseif length(timecell)==1
172    time=timecell{1};
173elseif length(timecell)>1
174    multitime=1;
175    for icell=1:length(timecell)
176        if ~isequal(size(timecell{icell}),size(timecell{1}))
177            msgbox_uvmat('WARNING','inconsistent time array dimensions in ImaDoc fields, the time for the first series is used')
178            time=timecell{1};
179            multitime=0;
180            break
181        end
182    end
183end
184if multitime
185    for icell=1:length(timecell)
186        time(icell,:,:)=timecell{icell};
187    end
188    diff_time=max(max(diff(time)));
189    if diff_time>0
190        msgbox_uvmat('WARNING',['times of series differ by (max) ' num2str(diff_time)])
191    end   
192end
193if size(time,2) < i2_series{1}(end) || size(time,3) < j2_series{1}(end)% time array absent or too short in ImaDoc xml file'
194    time=[];
195end
196
197%% coordinate transform or other user defined transform
198transform_fct='';%default
199if isfield(Param,'FieldTransform')&&isfield(Param.FieldTransform,'TransformHandle')
200    transform_fct=Param.FieldTransform.TransformHandle;
201end
202%%%%%%%%%%%% END STANDARD PART  %%%%%%%%%%%%
203 % EDIT FROM HERE
204
205%% check the validity of  input file types
206if CheckImage{1}
207    FileExtOut='.png'; % write result as .png images for image inputs
208elseif CheckNc{1}
209    FileExtOut='.nc';% write result as .nc files for netcdf inputs
210else
211    msgbox_uvmat('ERROR',['invalid file type input ' FileType{1}])
212    return
213end
214if nbview==2 && ~isequal(CheckImage{1},CheckImage{2})
215        msgbox_uvmat('ERROR','input must be two image series or two netcdf file series')
216    return
217end
218NomTypeOut='_1-2_1';% output file index will indicate the first and last ref index in the series
219if NbSlice~=nbfield_j
220    answer=msgbox_uvmat('INPUT_Y-N',['will not average slice by slice: for so cancel and set NbSlice= ' num2str(nbfield_j)]);
221    if ~strcmp(answer,'Yes')
222        return
223    end
224end
225
226%% Set field names and velocity types
227InputFields{1}=[];%default (case of images)
228if isfield(Param,'InputFields')
229    InputFields{1}=Param.InputFields;
230end
231if nbview==2
232    InputFields{2}=[];%default (case of images)
233    if isfield(Param,'InputFields')
234        InputFields{2}=Param.InputFields{1};%default
235        if isfield(Param.InputFields,'FieldName_1')
236            InputFields{2}.FieldName=Param.InputFields.FieldName_1;
237            if isfield(Param.InputFields,'VelType_1')
238                InputFields{2}.VelType=Param.InputFields.VelType_1;
239            end
240        end
241    end
242end
243
244%% Initiate output fields
245%initiate the output structure as a copy of the first input one (reproduce fields)
246[DataOut,ParamOut,errormsg] = read_field(filecell{1,1},FileType{1},InputFields{1},1);
247if ~isempty(errormsg)
248    msgbox_uvmat('ERROR',['error reading ' filecell{1,1} ': ' errormsg])
249    return
250end
251time_1=[];
252if isfield(DataOut,'Time')
253    time_1=DataOut.Time(1);
254end
255if CheckNc{iview}
256    if isempty(strcmp('Conventions',DataOut.ListGlobalAttribute))
257        DataOut.ListGlobalAttribute=['Conventions' DataOut.ListGlobalAttribute];
258    end
259    DataOut.Conventions='uvmat';
260    DataOut.ListGlobalAttribute=[DataOut.ListGlobalAttribute {Param.Action}];
261    ActionKey='Action';
262    while isfield(DataOut,ActionKey)
263        ActionKey=[ActionKey '_1'];
264    end
265    DataOut.(ActionKey)=Param.Action;
266    DataOut.ListGlobalAttribute=[DataOut.ListGlobalAttribute {ActionKey}];
267    if isfield(DataOut,'Time')
268        DataOut.ListGlobalAttribute=[DataOut.ListGlobalAttribute {'Time','Time_end'}];
269    end
270end
271
272%% MAIN LOOP ON SLICES
273%%%%%%%%%%%%% STANDARD PART (DO NOT EDIT) %%%%%%%%%%%%
274for i_slice=1:NbSlice
275    index_slice=i_slice:NbSlice:nbfield;% select file indices of the slice
276    nbfiles=0;
277    nbmissing=0;
278   
279   %initiate result fields
280   for ivar=1:length(DataOut.ListVarName)
281       DataOut.(DataOut.ListVarName{ivar})=0; % initialise all fields to zero
282   end
283
284    %%%%%%%%%%%%%%%% loop on field indices %%%%%%%%%%%%%%%%
285    for index=index_slice
286        if checkrun
287            update_waitbar(hseries.waitbar_frame,WaitbarPos,index/(nbfield))
288            stopstate=get(hseries.RUN,'BusyAction');
289        else
290            stopstate='queue';
291        end
292%OUTPUT
293% GUI_input=list of options in the GUI series.fig needed for the function
294%
295%INPUT:
296% Param: structure containing all the parameters read on the GUI series
297%  or name of the xml file containing these parameters (BATCH case)
298%
299
300
301%% projection object
302test_object=get(hseries.GetObject,'Value');
303if test_object
304    hset_object=findobj(allchild(0),'tag','set_object');
305    %ProjObject=read_set_object(guidata(hset_object));
306    ProjObject=read_GUI(hset_object);
307    if ~isfield(ProjObject,'Type')
308            msgbox_uvmat('ERROR','Undefined projection object type')
309            return
310    end
311    if ~isequal(ProjObject.Type,'plane')|| isequal(ProjObject.ProjMode,'projection')
312            msgbox_uvmat('ERROR','The projection object must be a plane with projection mode interp or filter')
313            return
314    end
315    answeryes=msgbox_uvmat('INPUT_Y-N',['field series projected on ' ProjObject.Type]);
316    if ~isequal(answeryes,'Yes')
317        return
318    end
319end
320
321%% features of the input fields
322RootPath=Param.InputTable(:,1);
323RootFile=Param.InputTable(:,3);
324SubDir=Param.InputTable(:,2);
325NomType=Param.InputTable(:,4);
326FileExt=Param.InputTable(:,5);
327
328nbview=length(RootFile);%number of views (file series to merge)
329nbfield=size(i1_series{1},1)*size(i1_series{1},2);%number of fields in the time series
330hhh=which('mmreader');
331for iview=1:nbview
332    test_movie(iview)=0;
333    if ~isempty(hhh)
334        if isequal(lower(FileExt{iview}),'.avi')
335            MovieObject{iview}=mmreader(fullfile(RootPath{iview},[RootFile{iview} FileExt{iview}]));
336            test_movie(iview)=1;
337        end
338    end
339end
340
341%% Calibration data and timing: read the ImaDoc files
342timecell={};
343itime=0;
344NbSlice_calib={}; %test for z index
345for iview=1:nbview%Loop on views
346    XmlData{iview}=[];%default
347    filebase{iview}=fullfile(RootPath{iview},RootFile{iview});
348    if exist([filebase{iview} '.xml'],'file')
349        [XmlData{iview},error]=imadoc2struct([filebase{iview} '.xml']);
350        if isfield(XmlData{iview},'Time')
351            itime=itime+1;
352            timecell{itime}=XmlData{iview}.Time;
353        end
354        if isfield(XmlData{iview},'GeometryCalib') && isfield(XmlData{iview}.GeometryCalib,'SliceCoord')
355            NbSlice_calib{iview}=size(XmlData{iview}.GeometryCalib.SliceCoord,1);
356            if ~isequal(NbSlice_calib{iview},NbSlice_calib{1})
357                msgbox_uvmat('WARNING','inconsistent number of Z indices for the two field series');
358            end
359        end   
360    elseif exist([filebase{iview} '.civ'],'file')
361        [error,time,TimeUnit,mode,npx,npy,pxcmx,pxcmy]=read_imatext([filebase{iview} '.civ']);
362        itime=itime+1;
363        timecell{itime}=time;
364        XmlData{iview}.Time=time;
365        GeometryCalib.R=[pxcmx 0 0; 0 pxcmy 0;0 0 0];
366        GeometryCalib.Tx=0;
367        GeometryCalib.Ty=0;
368        GeometryCalib.Tz=1;
369        GeometryCalib.dpx=1;
370        GeometryCalib.dpy=1;
371        GeometryCalib.sx=1;
372        GeometryCalib.Cx=0;
373        GeometryCalib.Cy=0;
374        GeometryCalib.f=1;
375        GeometryCalib.kappa1=0;
376        GeometryCalib.CoordUnit='cm';
377        XmlData{iview}.GeometryCalib=GeometryCalib;
378        if error==1
379            msgbox_uvmat('WARNING','inconsistent number of fields in the .civ file');
380        end
381    end
382end
383
384%% check coincidence in time
385multitime=0;
386if isempty(timecell)
387    time=[];
388elseif length(timecell)==1
389    time=timecell{1};
390elseif length(timecell)>1
391    multitime=1;
392    for icell=1:length(timecell)
393        if ~isequal(size(timecell{icell}),size(timecell{1}))
394            msgbox_uvmat('WARNING','inconsistent time array dimensions in ImaDoc fields, the time for the first series is used')
395            time=timecell{1};
396            multitime=0;
397            break
398        end
399    end
400end
401if multitime
402    for icell=1:length(timecell)
403        time(icell,:,:)=timecell{icell};
404    end
405    diff_time=max(max(diff(time)));
406    if diff_time>0
407        msgbox_uvmat('WARNING',['times of series differ by more than ' num2str(diff_time)])
408    end   
409    time=sqeeze(mean(time,1));
410end
411% if size(time,2) < i2_series{1}(end) || size(time,3) < j2_series{1}(end)% ime array absent or too short in ImaDoc xml file'
412%     time=[];
413% end
414
415%% Field and velocity type (the same for all views)
416FieldName='';
417if isfield(Param,'InputFields')&&isfield(Param.InputFields,'FieldMenu') 
418    FieldName=Param.InputFields.FieldMenu;%the same set of fields for all views
419    VelType=Param.InputFields.VelTypeMenu;
420end
421% if strcmp(get(hseries.FieldMenu,'Visible'),'on')
422%     Field_str=get(hseries.FieldMenu,'String');
423%     val=get(hseries.FieldMenu,'Value');
424%     FieldName=Field_str(val);%the same set of fields for all views
425%     VelType_str=get(hseries.VelTypeMenu,'String');
426%     VelType_val=get(hseries.VelTypeMenu,'Value');
427%     VelType=VelType_str{VelType_val}; %the same for all views
428    if strcmp(FieldName,'')
429        msgbox_uvmat('ERROR','no input field defined in FieldMenu')
430    elseif strcmp(FieldName,'get_field...')
431        hget_field=findobj(allchild(0),'Name','get_field');%find the get_field... GUI
432        SubField=get_field('read_get_field',hObject,eventdata,hget_field); %read the names of the variables to plot in the get_field GUI
433    end
434% end
435%detect whether all the files are 'images' or 'netcdf'
436testima=0;
437testvol=0;
438testcivx=0;
439testnc=0;
440for iview=1:nbview
441     ext=FileExt{iview};
442     form=imformats(ext(2:end));
443     if isequal(lower(ext),'.vol')
444         testvol=testvol+1;
445     elseif ~isempty(form)||isequal(lower(ext),'.avi')% if the extension corresponds to an image format recognized by Matlab
446         testima=testima+1;
447     elseif isequal(ext,'.nc')
448         testnc=testnc+1;
449     end
450end
451if testvol
452    msgbox_uvmat('ERROR','volume images not implemented yet')
453    return
454end
455if testnc~=nbview && testima~=nbview && testvol~=nbview
456    msgbox_uvmat('ERROR','need a set of images or a set of netcdf files with the same fields as input')
457    return
458end
459if ~isequal(FieldName,'get_field...')
460    testcivx=testnc;
461end
462
463%% name of output files and directory:
464ProjectDir=fileparts(fileparts(RootPath{1}));% preoject directory (GERK)
465prompt={['result directory (in' ProjectDir ')']};
466% RootPath=get(hseries.RootPath,'String');
467% SubDir=get(hseries.SubDir,'String');
468if isequal(length(RootPath),1)
469    fulldir=RootPath{1};
470    subdir='merge_proj';
471    res_subdir=fullfile(fulldir,subdir);
472else
473    def={fullfile(ProjectDir,'0_RESULTS')};
474    dlgTitle='result directory';
475    lineNo=1;
476    answer=msgbox_uvmat('INPUT_TXT',dlgTitle,def);
477    fulldir=answer{1};
478    subdir=[];
479    dirlist=sort(RootFile);
480    for iview=1:nbview
481        if ~isempty(subdir)
482            subdir=[subdir '-'];
483        end
484        subdir=[subdir dirlist{iview}];
485    end 
486    res_subdir=fullfile(fulldir,subdir);
487end
488ext=FileExt{1};
489if ~exist(fulldir,'dir')
490    msgbox_uvmat('ERROR',['directory ' fulldir ' needs to be created'])
491    return
492end
493if ~exist(res_subdir,'dir')
494    dircur=pwd;
495    cd(fulldir);
496    succeed=mkdir(subdir);
497    if succeed
498        [xx,msg2] = fileattrib(res_subdir,'+w','g'); %yield writing access (+w) to user group (g)
499        if ~strcmp(msg2,'')
500            msgbox_uvmat('ERROR',['pb of permission for ' res_subdir ': ' msg2])%error message for directory creation
501            cd(dircur)
502            return
503        end
504        cd(dircur);
505    else
506        msgbox_uvmat('ERROR',['Cannot create directory ' fulldir])
507        return
508    end
509end
510filebasesub=fullfile(res_subdir,RootFile{1});
511%filebase_merge=fullfile(res_subdir,'merged');%root name for the merged files
512
513%% MAIN LOOP
514for ifile=1:nbfield               
515    stopstate=get(hseries.RUN,'BusyAction');
516    if isequal(stopstate,'queue')% enable STOP command from the 'series' interface
517         update_waitbar(hseries.waitbar,WaitbarPos,ifile/nbfield)
518         
519        %% ----------LOOP ON VIEWS----------------------
520        nbtime=0;
521        for iview=1:nbview
522         %name of the current file
523         filename=filecell{iview,ifile};
524          %  filename=name_generator(filebase{iview},i1_series{iview}(ifile),j1_series{iview}(ifile),FileExt{iview},NomType{iview},1,i2_series{iview}(ifile),j2_series{iview}(ifile),SubDir{iview});
525            if ~exist(filename,'file')
526                msgbox_uvmat('ERROR',['missing input file' filename])
527                break
528            end
529            timeread(iview)=0;
530         %reading the current file
531            if testima
532                if test_movie(iview)
533                    Field{iview}.A=read(MovieObject{iview},i1_series{iview}(ifile));
534                else
535                    Field{iview}.A=imread(filename);
536                end % TODO: introduce ListVarName
537                npxy=size(Field{iview}.A);
538                Field{iview}.ListVarName={'AX','AY','A'};
539                Field{iview}.VarDimName={'AX','AY',{'AY','AX'}};
540                Field{iview}.AX=[0.5 npxy(2)-0.5]; % coordinates of the first and last pixel centers
541                Field{iview}.AY=[npxy(1)-0.5 0.5];
542                Field{iview}.CoordUnit='pixel';
543                Field{iview}.AName='image';
544            else
545                if testcivx
546                    [Field{iview},VelTypeOut]=read_civxdata(filename,FieldName,VelType);
547                else
548                    [Field{iview},var_detect]=nc2struct(filename,SubField.ListVarName); %read the corresponding input data               
549                    Field{iview}.VarAttribute=SubField.VarAttribute;
550                end
551                if isfield(Field{iview},'Txt')
552                    msgbox_uvmat('ERROR',Field{iview}.Txt)
553                    return
554                end
555                if isfield(Field{iview},'Time')
556                    timeread(iview)=Field{iview}.Time;
557                    nbtime=nbtime+1;
558                end
559            end
560            if ~isempty(NbSlice_calib)
561                Field{iview}.ZIndex=mod(i1_series{iview}(ifile)-1,NbSlice_calib{1})+1;
562            end
563         %transform the input field (e.g; phys) if requested
564            if ~isempty(transform_fct)
565                Field{iview}=transform_fct(Field{iview},XmlData{iview});  %transform to phys if requested
566            end
567            if testcivx
568                Field{iview}=calc_field(FieldName,Field{iview});
569            end
570         %projection on object (gridded plane)
571            if test_object
572                [Field{iview},errormsg]=proj_field(Field{iview},ProjObject);
573                if ~isempty(errormsg)
574                    msgbox_uvmat('ERROR',['error in merge_proge/proj_field: ' errormsg])
575                    return
576                end
577            end
578        end   
579        %----------END LOOP ON VIEWS----------------------
580         
581        %% merge the nbview fields
582        MergeData=merge_field(Field);
583        if isfield(MergeData,'Txt')
584            msgbox_uvmat('ERROR',MergeData.Txt)
585            return
586        end       
587     % generating the name of the merged field
588     if testima
589         ResultExt='.png';
590     else
591         ResultExt=FileExt{iview};
592     end
593     i1=i1_series{iview}(ifile);
594     if ~isempty(i2_series{iview})
595         i2=i2_series{iview}(ifile);
596     else
597         i2=i1;
598     end
599     j1=1;
600     j2=1;
601     if ~isempty(j1_series{iview})
602         j1=j1_series{iview}(ifile);
603          if ~isempty(j2_series{iview})
604              j2=j2_series{iview}(ifile);
605          else
606              j2=j1;
607          end
608     end
609     mergename=fullfile_uvmat(res_subdir,'','merged',ResultExt,NomType{iview},i1,i2,j1,j2);
610    % mergename=name_generator(filebase_merge,i1,j1_series{iview}(ifile),ResultExt,NomType{iview},1,i2_series{iview}(ifile),j2_series{iview}(ifile));
611       
612     % time of the merged field:
613        time_i=0;%default
614        if isempty(time)% time from ImaDoc prevails
615            time_i=sum(timeread)/nbtime;
616        else
617           % time_i=i1;
618            time_i=(time(i1,j1)+time(i2,j2))/2; %TODO: upgrade
619        end
620       
621     % recording the merged field
622        if testima    %in case of input images an image is produced   
623            if isa(MergeData.A,'uint8')
624                bitdepth=8;
625            elseif isa(MergeData.A,'uint16')
626                bitdepth=16;
627            end
628            imwrite(MergeData.A,mergename,'BitDepth',bitdepth);
629            %write xml calibration file
630            siz=size(MergeData.A);
631            npy=siz(1);
632            npx=siz(2);
633            if isfield(MergeData,'VarAttribute')&&isfield(MergeData.VarAttribute{1},'Coord_2')&&isfield(MergeData.VarAttribute{1},'Coord_1')
634                Rangx=MergeData.VarAttribute{1}.Coord_2;
635                Rangy=MergeData.VarAttribute{1}.Coord_1;
636            elseif isfield(MergeData,'AX')&& isfield(MergeData,'AY')
637                Rangx=[MergeData.AX(1) MergeData.AX(end)];
638                Rangy=[MergeData.AY(1) MergeData.AY(end)];
639            else
640                Rangx=[0.5 npx-0.5];
641                Rangy=[npy-0.5 0.5];%default
642            end
643            pxcmx=(npx-1)/(Rangx(2)-Rangx(1));
644            pxcmy=(npy-1)/(Rangy(1)-Rangy(2));
645            T_x=-pxcmx*Rangx(1)+0.5;
646            T_y=-pxcmy*Rangy(2)+0.5;
647            GeometryCal.focal=1;
648            GeometryCal.R=[pxcmx,0,0;0,pxcmy,0;0,0,1];
649            GeometryCal.Tx_Ty_Tz=[T_x T_y 1];
650            ImaDoc.GeometryCalib=GeometryCal;
651            t=struct2xml(ImaDoc);
652            t=set(t,1,'name','ImaDoc');
653            save(t,[filebase_merge '.xml'])     
654            display([filebase_merge '.xml saved'])
655        else
656            MergeData.ListGlobalAttribute={'Conventions','Project','InputFile_1','InputFile_end','nb_coord','nb_dim','dt','Time','civ'};       
657            MergeData.Conventions='uvmat';
658            MergeData.nb_coord=2;
659            MergeData.nb_dim=2;
660            dt=[];
661            if isfield(Field{1},'dt')&& isnumeric(Field{1}.dt)
662                dt=Field{1}.dt;
663            end
664            for iview =2:numel(Field)
665                if ~(isfield(Field{iview},'dt')&& isequal(Field{iview}.dt,dt))
666                    dt=[];%dt not the same for all fields
667                end
668            end
669            if isempty(dt)
670                MergeData.ListGlobalAttribute(6)=[];
671            else
672               MergeData.dt=dt;
673            end
674            MergeData.Time=time_i;
675            error=struct2nc(mergename,MergeData);%save result file
676            if isempty(error)
677                display(['output file ' mergename ' written'])
678            else
679                display(error)
680            end
681        end
682    end
683end
684
685%'merge_field': concatene fields
686%------------------------------------------------------------------------
687function MergeData=merge_field(Data)
688%% default output
689if isempty(Data)||~iscell(Data)
690    MergeData=[];
691    return
692end
693MergeData=Data{1};%default
694error=0;
695nbview=length(Data);
696if nbview==1
697    return
698end
699
700%% group the variables (fields of 'FieldData') in cells of variables with the same dimensions
701[CellVarIndex,NbDim,VarTypeCell]=find_field_indices(Data{1});
702%LOOP ON GROUPS OF VARIABLES SHARING THE SAME DIMENSIONS
703% CellVarIndex=cells of variable index arrays
704ivar_new=0; % index of the current variable in the projected field
705for icell=1:length(CellVarIndex)
706    if NbDim(icell)==1
707        continue
708    end
709    VarIndex=CellVarIndex{icell};%  indices of the selected variables in the list FieldData.ListVarName
710    VarType=VarTypeCell{icell};
711    ivar_X=VarType.coord_x;
712    ivar_Y=VarType.coord_y;
713    ivar_FF=VarType.errorflag;
714    if isempty(ivar_X)
715        test_grid=1;%test for input data on regular grid (e.g. image)coordinates
716    else
717        if length(ivar_Y)~=1
718                msgbox_uvmat('ERROR','y coordinate missing in proj_field.m')
719                return
720        end
721        test_grid=0;
722    end
723    %case of input fields with unstructured coordinates
724    if ~test_grid
725        for ivar=VarIndex
726            VarName=MergeData.ListVarName{ivar};
727            for iview=1:nbview
728                eval(['MergeData.' VarName '=[MergeData.' VarName '; Data{iview}.' VarName '];'])
729            end
730        end
731    %case of fields defined on a structured  grid
732    else 
733        testFF=0;
734        for iview=2:nbview
735            for ivar=VarIndex
736                VarName=MergeData.ListVarName{ivar};
737                if isfield(MergeData,'VarAttribute')
738                    if length(MergeData.VarAttribute)>=ivar && isfield(MergeData.VarAttribute{ivar},'Role') && isequal(MergeData.VarAttribute{ivar}.Role,'errorflag')
739                        testFF=1;
740                    end
741                end
742                eval(['MergeData.' VarName '=MergeData.' VarName '+ Data{iview}.' VarName ';'])
743            end
744        end
745        if testFF
746            nbaver=nbview-MergeData.FF;
747            indgood=find(nbaver>0);
748            for ivar=VarIndex
749                VarName=MergeData.ListVarName{ivar};
750                eval(['MergeData.' VarName '(indgood)=double(MergeData.' VarName '(indgood))./nbaver(indgood);'])
751            end
752        else
753            for ivar=VarIndex
754                VarName=MergeData.ListVarName{ivar};
755                eval(['MergeData.' VarName '=double(MergeData.' VarName ')./nbview;'])
756            end   
757        end
758    end
759end
760
761   
Note: See TracBrowser for help on using the repository browser.