source: trunk/src/series/relabel_i_j.m @ 478

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

series fcts updated to fit with new waitbar fct and background run mode, and various bug repairs

File size: 28.6 KB
Line 
1%'relabel_i_j': relabel an image series with two indices, and correct errors from the RDvision transfer program
2%------------------------------------------------------------------------
3% function GUI_config=relabel_i_j(Param)
4%------------------------------------------------------------------------
5
6%%%%%%%%%%% GENERAL TO ALL SERIES ACTION FCTS %%%%%%%%%%%%%%%%%%%%%%%%%%%
7%
8% This function is used in four modes by the GUI series:
9%           1) config GUI: with no input argument, the function determine the suitable GUI configuration
10%           2) interactive input: the function is used to interactively introduce input parameters, and then stops
11%           3) RUN: the function itself runs, when an appropriate input  structure Param has been introduced.
12%           4) BATCH: the function itself proceeds in BATCH mode, using an xml file 'Param' as input.
13%
14% This function is used in four modes by the GUI series:
15%           1) config GUI: with no input argument, the function determine the suitable GUI configuration
16%           2) interactive input: the function is used to interactively introduce input parameters, and then stops
17%           3) RUN: the function itself runs, when an appropriate input  structure Param has been introduced.
18%           4) BATCH: the function itself proceeds in BATCH mode, using an xml file 'Param' as input.
19%
20%OUTPUT
21% GUI_input=list of options in the GUI series.fig needed for the function
22%
23%INPUT:
24% In run mode, the input parameters are given as a Matlab structure Param copied from the GUI series.
25% In batch mode, Param is the name of the corresponding xml file containing the same information
26% In the absence of input (as activated when the current Action is selected
27% in series), the function ouput GUI_input set the activation of the needed GUI elements
28%
29% Param contains the elements:(use the menu bar command 'export/GUI config' in series to see the current structure Param)
30%    .InputTable: cell of input file names, (several lines for multiple input)
31%                      each line decomposed as {RootPath,SubDir,Rootfile,NomType,Extension}
32%    .OutputSubDir: name of the subdirectory for data outputs
33%    .OutputDir: directory for data outputs, including path
34%    .Action: .ActionName: name of the current activated function
35%             .ActionPath:   path of the current activated function
36%    .IndexRange: set the file or frame indices on which the action must be performed
37%    .FieldTransform: .TransformName: name of the selected transform function
38%                     .TransformPath:   path  of the selected transform function
39%                     .TransformHandle: corresponding function handle
40%    .InputFields: sub structure describing the input fields withfields
41%              .FieldName: name of the field
42%              .VelType: velocity type
43%              .FieldName_1: name of the second field in case of two input series
44%              .VelType_1: velocity type of the second field in case of two input series
45%    .ProjObject: %sub structure describing a projection object (read from ancillary GUI set_object)
46%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
47
48function GUI_config=relabel_i_j(Param)
49
50%% set the input elements needed on the GUI series when the action is selected in the menu ActionName
51if ~exist('Param','var') % case with no input parameter
52    GUI_config={'NbViewMax';1;...% max nbre of input file series (default='' , no limitation)
53        'AllowInputSort';'off';...% allow alphabetic sorting of the list of input files (options 'off'/'on', 'off' by default)
54        'WholeIndexRange';'on';...% prescribes the file index ranges from min to max (options 'off'/'on', 'off' by default)
55        'NbSlice';'off'; ...%nbre of slices ('off' by default)
56        'VelType';'off';...% menu for selecting the velocity type (options 'off'/'one'/'two',  'off' by default)
57        'FieldName';'off';...% menu for selecting the field (s) in the input file(options 'off'/'one'/'two', 'off' by default)
58        'FieldTransform'; 'off';...%can use a transform function
59        'ProjObject';'off';...%can use projection object(option 'off'/'on',
60        'Mask';'off';...%can use mask option   (option 'off'/'on', 'off' by default)
61        'OutputDirExt';'';...%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        Param=xml2struct(Param);
71        checkrun=0;
72% RUN case: parameters introduced as the input structure Param
73else
74    hseries=guidata(Param.hseries);%handles of the GUI series
75    if isfield(Param,'Specific')&& strcmp(Param.Specific,'?')
76        checkrun=1;% will only search interactive input parameters (preparation of BATCH mode)
77    else
78        checkrun=2; % indicate the RUN option is used
79    end
80end
81ParamOut=Param; %default output
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')&&~isempty(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'};
114NcTypeOptions={'netcdf','civx','civdata'};
115for iview=1:nbview
116    if ~exist(filecell{iview,1}','file')
117        msgbox_uvmat('ERROR',['the first input file ' filecell{iview,1} ' does not exist'])
118        return
119    end
120    [FileType{iview},FileInfo{iview},MovieObject{iview}]=get_file_type(filecell{iview,1});
121    CheckImage{iview}=~isempty(find(strcmp(FileType{iview},ImageTypeOptions)));% =1 for images
122    CheckNc{iview}=~isempty(find(strcmp(FileType{iview},NcTypeOptions)));% =1 for netcdf files
123    if ~isempty(j1_series{iview})
124        frame_index{iview}=j1_series{iview};
125    else
126        frame_index{iview}=i1_series{iview};
127    end
128end
129
130%% calibration data and timing: read the ImaDoc files
131mode=''; %default
132timecell={};
133itime=0;
134NbSlice_calib={};
135XmlData=cell(1,nbview);%initiate the structures containing the data from the xml file (calibration and timing)
136for iview=1:nbview%Loop on views
137    SubDirBase=regexprep(SubDir{iview},'\..*','');%take the root part of SubDir, before the first dot '.'
138    filexml=[fullfile(RootPath{iview},SubDirBase) '.xml'];%new convention: xml at the level of the image folder
139    if ~exist(filexml,'file')
140        filexml=[fullfile(RootPath{iview},SubDir{iview},RootFile{iview}) '.xml']; % old convention: xml inside the image folder
141        if ~exist(filexml,'file')
142            filexml=[fullfile(RootPath{iview},SubDir{iview},RootFile{iview}) '.civ']; % very old convention: .civ file
143            if ~exist(filexml,'file')
144                filexml='';
145            end
146        end
147    end
148    if ~isempty(filexml)
149        [XmlData{iview},error]=imadoc2struct_special(filexml);
150    end
151    if isfield(XmlData{iview},'Time')
152        itime=itime+1;
153        timecell{itime}=XmlData{iview}.Time;
154    end
155    if isfield(XmlData{iview},'GeometryCalib') && isfield(XmlData{iview}.GeometryCalib,'SliceCoord')
156        NbSlice_calib{iview}=size(XmlData{iview}.GeometryCalib.SliceCoord,1);%nbre of slices for Zindex in phys transform
157        if ~isequal(NbSlice_calib{iview},NbSlice_calib{1})
158            msgbox_uvmat('WARNING','inconsistent number of Z indices for the two field series');
159        end
160    end
161end
162
163%% check coincidence in time for several input file series
164% not relevant
165
166%% coordinate transform or other user defined transform
167%not relevant
168%%%%%%%%%%%% END STANDARD PART  %%%%%%%%%%%%
169 % EDIT FROM HERE
170
171%% check the validity of  input file types
172if CheckImage{1}
173    FileExtOut='.png'; % write result as .png images for image inputs
174elseif CheckNc{1}
175    FileExtOut='.nc';% write result as .nc files for netcdf inputs
176else
177    msgbox_uvmat('ERROR',['invalid file type input ' FileType{1}])
178    return
179end
180if nbview==2 && ~isequal(CheckImage{1},CheckImage{2})
181        msgbox_uvmat('ERROR','input must be two image series or two netcdf file series')
182    return
183end
184NomTypeOut='_1-2_1';% output file index will indicate the first and last ref index in the series
185if NbSlice~=nbfield_j
186    answer=msgbox_uvmat('INPUT_Y-N',['will not average slice by slice: for so cancel and set NbSlice= ' num2str(nbfield_j)]);
187    if ~strcmp(answer,'Yes')
188        return
189    end
190end
191
192%% Set field names and velocity types
193% not relevant here
194
195%% Initiate output fields
196% not relevant here
197
198%% interactive input of specific parameters (for RDvision system)
199display('RDvision system')
200first_label=0; %image numbers start from 0
201if ~strcmp(NomType{1},'_000001')
202    msgbox_uvmat('WARNING','the input is not a file from RDvision: this function relabel_i_j has no action');%error message for directory creation
203    return
204else
205    answer=msgbox_uvmat('','this function will relabel the file series from RDvision from  and correct the xml file');%error message for directory creation
206    if ~strcmp(answer,'Yes')
207        return
208    end
209end
210
211%% read imadoc
212% RootPath=get(hseries.RootPath,'String');
213% RootFile=get(hseries.RootFile,'String');
214% if ~iscell(RootFile)
215%     msgbox_uvmat('ERROR','please enter an input image series from RDVision system')%error message for xml file reading
216%     return
217% end
218% basename=fullfile(RootPath{1},RootFile{1});
219% [XmlData,warntext]=imadoc2struct_special([basename '.xml']);% read the xml file appended to the present function (containing bug corrections)
220% if ~isempty(warntext)
221%     msgbox_uvmat('ERROR',warntext)%error message for xml file reading
222% end
223% nbfield1=size(XmlData.Time,1);
224% nbfield2=size(XmlData.Time,2);
225% set(hseries.first_i,'String',num2str(first_label))% display the first image in the process
226% set(hseries.last_i,'String',num2str(nbfield1*nbfield2-1+first_label))% display the last image in the process
227% set(hseries.nb_field,'String',{num2str(nbfield1*nbfield2-1+first_label)})% display the total nbre of images
228% SeriesData=get(hGUI,'UserData');
229
230
231%% stop program there when it is selected in the menu (no run action)
232% if ~exist('num_i1','var')
233%     return
234% end
235% if nbfield2>=2
236% answer=msgbox_uvmat('',[num2str(nbfield1) ' bursts containing ' num2str(nbfield2) ' images each']);%error message for directory creation
237% nomtype='_i_j';
238% else
239%     answer=msgbox_uvmat('',['image series with ' num2str(nbfield1) ' images']);%error message for directory creation
240%     nomtype='_i';
241% end
242% if ~strcmp(answer,'Yes')
243%     return
244% end
245
246%% copy and adapt the xml file
247if ~isempty(XmlData{1})
248
249%     if exist([basename '.xml'],'file')
250%         try
251%             copyfile([basename '.xml'],[basename '.xml~']);% backup the xml file
252%         catch ME
253%             msgbox_uvmat('ERROR',ME.message);
254%             return
255%         end
256%         filexml=[filebase{1} '.xml']
257        t=xmltree(filexml);
258       
259        %update information on the first image name in the series
260        uid_Heading=find(t,'ImaDoc/Heading');
261        if isempty(uid_Heading)
262            [t,uid_Heading]=add(t,1,'element','Heading');
263        end
264        uid_ImageName=find(t,'ImaDoc/Heading/ImageName');
265        j1=[];
266        if ~isempty(j1_series{1})
267            j1=j1_series{1};
268        end
269        ImageName=fullfile_uvmat(RootPath{1},SubDir{1},RootFile{1},FileExt{1},'_1_1',i1_series{1}(1),[],j);
270%         ImageName=name_generator(basename,1,1,'.png','_i_j');
271        [pth,ImageName]=fileparts(ImageName);
272        ImageName=[ImageName '.png'];
273        if isempty(uid_ImageName)
274            [t,uid_ImageName]=add(t,uid_Heading,'element','ImageName');
275        end
276        uid_value=children(t,uid_ImageName);
277        if isempty(uid_value)
278            t=add(t,uid_ImageName,'chardata',ImageName);%indicate  name of the first image, with ;png extension
279        else
280            t=set(t,uid_value(1),'value',ImageName);%indicate  name of the first image, with ;png extension
281        end
282       
283        %%%% correction RDvision %%%%
284        if isfield(XmlData,'NbDtj')
285            uid_NbDtj=find(t,'ImaDoc/Camera/BurstTiming/NbDtj');
286            uid_value=children(t,uid_NbDtj);
287            if ~isempty(uid_value)
288                t=set(t,uid_value(1),'value',num2str(XmlData.NbDtj));
289            end
290        end
291        if isfield(XmlData,'NbDtk')
292            uid_NbDtk=find(t,'ImaDoc/Camera/BurstTiming/NbDtk');
293            uid_value=children(t,uid_NbDtk);
294            if ~isempty(uid_value)
295                t=set(t,uid_value(1),'value',num2str(XmlData.NbDtk));
296            end
297        end
298        if isempty(j1_series{1}) && isfield(XmlData,'NbDti')
299            uid_Dti=find(t,'ImaDoc/Camera/BurstTiming/Dti');
300            t=add(t,uid_Dti,'chardata',num2str(XmlData.Dti));
301            uid_NbDti=find(t,'ImaDoc/Camera/BurstTiming/NbDti');
302            t=add(t,uid_NbDti,'chardata',num2str(XmlData.NbDti));
303            uid_NbDtj=find(t,'ImaDoc/Camera/BurstTiming/NbDtj');
304            uid_NbDtk=find(t,'ImaDoc/Camera/BurstTiming/NbDtk');
305            t=delete(t,uid_NbDtj);
306            t=delete(t,uid_NbDtk);
307            uid_Dtj=find(t,'ImaDoc/Camera/BurstTiming/Dtj');
308            uid_Dtk=find(t,'ImaDoc/Camera/BurstTiming/Dtk');
309            t=delete(t,uid_Dtj);
310            t=delete(t,uid_Dtk);
311        end
312            SubDirBase=regexprep(SubDir{1},'\..*','');%take the root part of SubDir, before the first dot '.'
313    filexml_new=[fullfile(RootPath{1},SubDirBase) '.xml'];
314        save(t,filexml_new)
315%     end
316end
317
318%% main loop on images
319%j1=[];%default
320nbfield2=size(XmlData{1}.Time,2);
321for ifile=1:nbfield
322    if checkrun
323        update_waitbar(hseries.Waitbar,ifile/nbfield)
324        stopstate=get(hseries.RUN,'BusyAction');
325    else
326        stopstate='queue';
327    end
328    if isequal(stopstate,'queue') % enable STOP command
329        filename=fullfile_uvmat(RootPath{1},SubDir{1},RootFile{1},FileExt{1},NomType{1},i1_series{1}(ifile));
330        j1=mod(ifile-1+first_label,nbfield2)+1;
331        i1=floor((ifile-1+first_label)/nbfield2)+1;
332        %         filename_new=name_generator(basename,num_i,num_j,'.png',nomtype);
333        filename_new=fullfile_uvmat(RootPath{1},SubDir{1},RootFile{1},FileExt{1},'_1_1',i1,[],j1);
334        try
335            movefile(filename,filename_new);
336            [s,errormsg] = fileattrib(filename_new,'-w','a'); %set images to read only '-w' for all users ('a')
337            if ~s
338                msgbox_uvmat('ERROR',errormsg);
339                return
340            end
341        catch ME
342            msgbox_uvmat('ERROR',ME.message);
343            return
344        end
345    end
346end
347
348%'imadoc2struct_special': reads the xml file for image documentation
349%------------------------------------------------------------------------
350% function [s,errormsg]=imadoc2struct_special(ImaDoc,option)
351%
352% OUTPUT:
353% s: structure representing ImaDoc
354%   s.Heading: information about the data hierarchical structure
355%   s.Time: matrix of times
356%   s.TimeUnit
357%  s.GeometryCalib: substructure containing the parameters for geometric calibration
358% errormsg: error message
359%
360% INPUT:
361% ImaDoc: full name of the xml input file with head key ImaDoc
362% option: ='GeometryCalib': read  the data of GeometryCalib, including source point coordinates
363
364function [s,errormsg]=imadoc2struct_special(ImaDoc,option)
365
366%% default input and output
367if ~exist('option','var')
368    option='*';
369end
370errormsg=[];%default
371s.Heading=[];%default
372s.Time=[]; %default
373s.TimeUnit=[]; %default
374s.GeometryCalib=[];
375tsai=[];%default
376
377%% opening the xml file
378if exist(ImaDoc,'file')~=2, errormsg=[ ImaDoc ' does not exist']; return;end;%input file does not exist
379try
380    t=xmltree(ImaDoc);
381catch
382    errormsg={[ImaDoc ' is not a valid xml file']; lasterr};
383    display(errormsg);
384    return
385end
386uid_root=find(t,'/ImaDoc');
387if isempty(uid_root), errormsg=[ImaDoc ' is not an image documentation file ImaDoc']; return; end;%not an ImaDoc .xml file
388
389
390%% Heading
391uid_Heading=find(t,'/ImaDoc/Heading');
392if ~isempty(uid_Heading),
393    uid_Campaign=find(t,'/ImaDoc/Heading/Campaign');
394    uid_Exp=find(t,'/ImaDoc/Heading/Experiment');
395    uid_Device=find(t,'/ImaDoc/Heading/Device');
396    uid_Record=find(t,'/ImaDoc/Heading/Record');
397    uid_FirstImage=find(t,'/ImaDoc/Heading/ImageName');
398    s.Heading.Campaign=get(t,children(t,uid_Campaign),'value');
399    s.Heading.Experiment=get(t,children(t,uid_Exp),'value');
400    s.Heading.Device=get(t,children(t,uid_Device),'value');
401    if ~isempty(uid_Record)
402        s.Heading.Record=get(t,children(t,uid_Record),'value');
403    end
404    s.Heading.ImageName=get(t,children(t,uid_FirstImage),'value');
405end
406
407%% Camera  and timing
408if strcmp(option,'*') || strcmp(option,'Camera')
409    uid_Camera=find(t,'/ImaDoc/Camera');
410    if ~isempty(uid_Camera)
411        uid_ImageSize=find(t,'/ImaDoc/Camera/ImageSize');
412        if ~isempty(uid_ImageSize);
413            ImageSize=get(t,children(t,uid_ImageSize),'value');
414            xindex=findstr(ImageSize,'x');
415            if length(xindex)>=2
416                s.Npx=str2double(ImageSize(1:xindex(1)-1));
417                s.Npy=str2double(ImageSize(xindex(1)+1:xindex(2)-1));
418            end
419        end
420        uid_TimeUnit=find(t,'/ImaDoc/Camera/TimeUnit');
421        if ~isempty(uid_TimeUnit)
422            s.TimeUnit=get(t,children(t,uid_TimeUnit),'value');
423        end
424        uid_BurstTiming=find(t,'/ImaDoc/Camera/BurstTiming');
425        if ~isempty(uid_BurstTiming)
426            for k=1:length(uid_BurstTiming)
427                subt=branch(t,uid_BurstTiming(k));%subtree under BurstTiming
428                % reading Dtk
429                Frequency=get_value(subt,'/BurstTiming/FrameFrequency',1);
430                Dtj=get_value(subt,'/BurstTiming/Dtj',[]);
431                Dtj=Dtj/Frequency;%Dtj converted from frame unit to TimeUnit (e.g. 's')
432                NbDtj=get_value(subt,'/BurstTiming/NbDtj',1);
433                %%%% correction RDvision %%%%
434%                 NbDtj=NbDtj/numel(Dtj);
435%                 s.NbDtj=NbDtj;
436%                 %%%%
437                Dti=get_value(subt,'/BurstTiming/Dti',[]);
438                NbDti=get_value(subt,'/BurstTiming/NbDti',1);
439                 %%%% correction RDvision %%%%
440                if isempty(Dti)% series
441                     Dti=Dtj;
442                      NbDti=NbDtj;
443                     Dtj=[];
444                     s.Dti=Dti;
445                else
446                    % NbDtj=NbDtj/numel(Dtj);%bursts
447                    s.NbDtj=NbDtj;
448                end
449                %%%% %%%%
450                Dti=Dti/Frequency;%Dtj converted from frame unit to TimeUnit (e.g. 's')
451
452                Time_val=get_value(subt,'/BurstTiming/Time',0);%time in TimeUnit
453                if ~isempty(Dti)
454                    Dti=reshape(Dti'*ones(1,NbDti),NbDti*numel(Dti),1); %concatene Dti vector NbDti times
455                    Time_val=[Time_val;Time_val(end)+cumsum(Dti)];%append the times defined by the intervals  Dti
456                end
457                if ~isempty(Dtj)
458                    Dtj=reshape(Dtj'*ones(1,NbDtj),1,NbDtj*numel(Dtj)); %concatene Dtj vector NbDtj times
459                    Dtj=[0 Dtj];
460                    Time_val=Time_val*ones(1,numel(Dtj))+ones(numel(Time_val),1)*cumsum(Dtj);% produce a time matrix with Dtj
461                end
462                % reading Dtk
463                Dtk=get_value(subt,'/BurstTiming/Dtk',[]);
464                NbDtk=get_value(subt,'/BurstTiming/NbDtk',1);
465                %%%% correction RDvision %%%%
466                if ~isequal(NbDtk,1)
467                    NbDtk=-1+(NbDtk+1)/(NbDti+1);
468                end
469                s.NbDtk=NbDtk;
470                %%%%%
471                if isempty(Dtk)
472                    s.Time=[s.Time;Time_val];
473                else
474                    for kblock=1:NbDtk+1
475                        Time_val_k=Time_val+(kblock-1)*Dtk;
476                        s.Time=[s.Time;Time_val_k];
477                    end
478                end
479            end
480        end
481    end
482end
483
484%% motor
485if strcmp(option,'*') || strcmp(option,'GeometryCalib')
486    uid_subtree=find(t,'/ImaDoc/TranslationMotor');
487    if length(uid_subtree)==1
488        subt=branch(t,uid_subtree);%subtree under GeometryCalib
489       [s.TranslationMotor,errormsg]=read_subtree(subt,{'Nbslice','ZStart','ZEnd'},[1 1 1],[1 1 1]);
490    end
491end
492%%  geometric calibration
493if strcmp(option,'*') || strcmp(option,'GeometryCalib')
494    uid_GeometryCalib=find(t,'/ImaDoc/GeometryCalib');
495    if ~isempty(uid_GeometryCalib)
496        if length(uid_GeometryCalib)>1
497            errormsg=['More than one GeometryCalib in ' filecivxml];
498            return
499        end
500        subt=branch(t,uid_GeometryCalib);%subtree under GeometryCalib
501        cont=get(subt,1,'contents');
502        if ~isempty(cont)
503            uid_CalibrationType=find(subt,'/GeometryCalib/CalibrationType');
504            if isequal(length(uid_CalibrationType),1)
505                tsai.CalibrationType=get(subt,children(subt,uid_CalibrationType),'value');
506            end
507            uid_CoordUnit=find(subt,'/GeometryCalib/CoordUnit');
508            if isequal(length(uid_CoordUnit),1)
509                tsai.CoordUnit=get(subt,children(subt,uid_CoordUnit),'value');
510            end
511            uid_fx_fy=find(subt,'/GeometryCalib/fx_fy');
512            focal=[];%default fro old convention (Reg Wilson)
513            if isequal(length(uid_fx_fy),1)
514                tsai.fx_fy=str2num(get(subt,children(subt,uid_fx_fy),'value'));
515            else %old convention (Reg Wilson)
516                uid_focal=find(subt,'/GeometryCalib/focal');
517                uid_dpx_dpy=find(subt,'/GeometryCalib/dpx_dpy');
518                uid_sx=find(subt,'/GeometryCalib/sx');
519                if ~isempty(uid_focal) && ~isempty(uid_dpx_dpy) && ~isempty(uid_sx)
520                    dpx_dpy=str2num(get(subt,children(subt,uid_dpx_dpy),'value'));
521                    sx=str2num(get(subt,children(subt,uid_sx),'value'));
522                    focal=str2num(get(subt,children(subt,uid_focal),'value'));
523                    tsai.fx_fy(1)=sx*focal/dpx_dpy(1);
524                    tsai.fx_fy(2)=focal/dpx_dpy(2);
525                end
526            end
527            uid_Cx_Cy=find(subt,'/GeometryCalib/Cx_Cy');
528            if ~isempty(uid_Cx_Cy)
529                tsai.Cx_Cy=str2num(get(subt,children(subt,uid_Cx_Cy),'value'));
530            end
531            uid_kc=find(subt,'/GeometryCalib/kc');
532            if ~isempty(uid_kc)
533                tsai.kc=str2double(get(subt,children(subt,uid_kc),'value'));
534            else %old convention (Reg Wilson)
535                uid_kappa1=find(subt,'/GeometryCalib/kappa1');
536                if ~isempty(uid_kappa1)&& ~isempty(focal)
537                    kappa1=str2double(get(subt,children(subt,uid_kappa1),'value'));
538                    tsai.kc=-kappa1*focal*focal;
539                end
540            end
541            uid_Tx_Ty_Tz=find(subt,'/GeometryCalib/Tx_Ty_Tz');
542            if ~isempty(uid_Tx_Ty_Tz)
543                tsai.Tx_Ty_Tz=str2num(get(subt,children(subt,uid_Tx_Ty_Tz),'value'));
544            end
545            uid_R=find(subt,'/GeometryCalib/R');
546            if ~isempty(uid_R)
547                RR=get(subt,children(subt,uid_R),'value');
548                if length(RR)==3
549                    tsai.R=[str2num(RR{1});str2num(RR{2});str2num(RR{3})];
550                end
551            end
552           
553            %look for laser plane definitions
554            uid_Angle=find(subt,'/GeometryCalib/PlaneAngle');
555            uid_Pos=find(subt,'/GeometryCalib/SliceCoord');
556            if isempty(uid_Pos)
557                uid_Pos=find(subt,'/GeometryCalib/PlanePos');%old convention
558            end
559            if ~isempty(uid_Angle)
560                tsai.PlaneAngle=str2num(get(subt,children(subt,uid_Angle),'value'));
561            end
562            if ~isempty(uid_Pos)
563                for j=1:length(uid_Pos)
564                    tsai.SliceCoord(j,:)=str2num(get(subt,children(subt,uid_Pos(j)),'value'));
565                end
566                uid_DZ=find(subt,'/GeometryCalib/SliceDZ');
567                uid_NbSlice=find(subt,'/GeometryCalib/NbSlice');
568                if ~isempty(uid_DZ) && ~isempty(uid_NbSlice)
569                    DZ=str2double(get(subt,children(subt,uid_DZ),'value'));
570                    NbSlice=get(subt,children(subt,uid_NbSlice),'value');
571                    if isequal(NbSlice,'volume')
572                        tsai.NbSlice='volume';
573                        NbSlice=NbDtj+1;
574                    else
575                        tsai.NbSlice=str2double(NbSlice);
576                    end
577                    tsai.SliceCoord=ones(NbSlice,1)*tsai.SliceCoord+DZ*(0:NbSlice-1)'*[0 0 1];
578                end
579            end   
580            tsai.SliceAngle=get_value(subt,'/GeometryCalib/SliceAngle',[0 0 0]);
581            tsai.VolumeScan=get_value(subt,'/GeometryCalib/VolumeScan','n');
582            tsai.InterfaceCoord=get_value(subt,'/GeometryCalib/InterfaceCoord',[0 0 0]);
583            tsai.RefractionIndex=get_value(subt,'/GeometryCalib/RefractionIndex',1);
584           
585            if strcmp(option,'GeometryCalib')
586                tsai.PointCoord=get_value(subt,'/GeometryCalib/SourceCalib/PointCoord',[0 0 0 0 0]);
587            end
588            s.GeometryCalib=tsai;
589        end
590    end
591end
592
593%--------------------------------------------------
594%  read a subtree
595% INPUT:
596% t: xltree
597% head_element: head elelemnt of the subtree
598% Data, structure containing
599%    .Key: element name
600%    .Type: type of element ('charg', 'float'....)
601%    .NbOccur: nbre of occurrence, NaN for un specified number
602function [s,errormsg]=read_subtree(subt,Data,NbOccur,NumTest)
603%--------------------------------------------------
604s=[];%default
605errormsg='';
606head_element=get(subt,1,'name');
607    cont=get(subt,1,'contents');
608    if ~isempty(cont)
609        for ilist=1:length(Data)
610            uid_key=find(subt,[head_element '/' Data{ilist}]);
611            if ~isequal(length(uid_key),NbOccur(ilist))
612                errormsg=['wrong number of occurence for ' Data{ilist}];
613                return
614            end
615            for ival=1:length(uid_key)
616                val=get(subt,children(subt,uid_key(ival)),'value');
617                if ~NumTest(ilist)
618                    eval(['s.' Data{ilist} '=val;']);
619                else
620                    eval(['s.' Data{ilist} '=str2double(val);'])
621                end
622            end
623        end
624    end
625
626
627%--------------------------------------------------
628%  read an xml element
629function val=get_value(t,label,default)
630%--------------------------------------------------
631val=default;
632uid=find(t,label);%find the element iud(s)
633if ~isempty(uid) %if the element named label exists
634   uid_child=children(t,uid);%find the children
635   if ~isempty(uid_child)
636       data=get(t,uid_child,'type');%get the type of child
637       if iscell(data)% case of multiple element
638           for icell=1:numel(data)
639               val_read=str2num(get(t,uid_child(icell),'value'));
640               if ~isempty(val_read)
641                   val(icell,:)=val_read;
642               end
643           end
644%           val=val';
645       else % case of unique element value
646           val_read=str2num(get(t,uid_child,'value'));
647           if ~isempty(val_read)
648               val=val_read;
649           else
650              val=get(t,uid_child,'value');%char string data
651           end
652       end
653   end
654end
Note: See TracBrowser for help on using the repository browser.