source: trunk/src/imadoc2struct.m @ 560

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

imadoc2struct corrected with the use of the more general function xml2struct. This allows to get all the content of the xml file in XmlData?

File size: 15.8 KB
Line 
1%'imadoc2struct': reads the xml file for image documentation
2%------------------------------------------------------------------------
3% function [s,errormsg]=imadoc2struct(ImaDoc,option)
4%
5% OUTPUT:
6% s: structure representing ImaDoc
7%   s.Heading: information about the data hierarchical structure
8%   s.Time: matrix of times
9%   s.TimeUnit
10%  s.GeometryCalib: substructure containing the parameters for geometric calibration
11% errormsg: error message
12%
13% INPUT:
14% ImaDoc: full name of the xml input file with head key ImaDoc
15% varargin: optional list of strings to restrict the reading to a selection of subtrees, for instance 'GeometryCalib' (save time)
16
17function [s,errormsg]=imadoc2struct(ImaDoc,varargin)
18%% default input and output
19errormsg=[];%default
20s.Heading=[];%default
21s.Time=[]; %default
22s.TimeUnit=[]; %default
23s.GeometryCalib=[];
24% tsai=[];%default
25
26%% opening the xml file
27[tild,tild,FileExt]=fileparts(ImaDoc);
28%% case of .civ files (obsolete)
29if strcmp(FileExt,'.civ')
30    [errormsg,time,TimeUnit,mode,npx,npy,s.GeometryCalib]=read_imatext(ImaDoc);
31    return
32end
33
34%% case of xml files
35if nargin >1
36    [s,Heading]=xml2struct(ImaDoc,varargin);% convert the xml file in a structure s, keeping only the subtree defined in input
37else
38    [s,Heading]=xml2struct(ImaDoc);% convert the whole xml file in a structure s
39end
40if ~strcmp(Heading,'ImaDoc')
41    errormsg='the input xml file is not ImaDoc';
42    return
43end
44%% reading timing
45Timing=s.Camera.BurstTiming;
46if ~iscell(Timing)
47    Timing={Timing};
48end
49s.Time=[];
50for k=1:length(Timing)
51    Frequency=1;
52    if isfield(Timing{k},'Frequency')
53        Frequency=Timing{k}.FrameFrequency;
54    end
55    Dtj=[];
56    if isfield(Timing{k},'Dtj')
57        Dtj=Timing{k}.Dtj/Frequency;%Dtj converted from frame unit to TimeUnit (e.g. 's');
58    end
59    NbDtj=1;
60    if isfield(Timing{k},'NbDtj')
61        NbDtj=Timing{k}.NbDtj;
62    end
63    Dti=[];
64    if isfield(Timing{k},'Dti')
65        Dti=Timing{k}.Dti/Frequency;%Dti converted from frame unit to TimeUnit (e.g. 's');
66    end
67    NbDti=1;
68    if isfield(Timing{k},'NbDti')
69        NbDti=Timing{k}.NbDti;
70    end
71    Time_val=Timing{k}.Time;%time in TimeUnit
72    if ~isempty(Dti)
73        Dti=reshape(Dti'*ones(1,NbDti),NbDti*numel(Dti),1); %concatene Dti vector NbDti times
74        Time_val=[Time_val;Time_val(end)+cumsum(Dti)];%append the times defined by the intervals  Dti
75    end
76    if ~isempty(Dtj)
77        Dtj=reshape(Dtj'*ones(1,NbDtj),1,NbDtj*numel(Dtj)); %concatene Dtj vector NbDtj times
78        Dtj=[0 Dtj];
79        Time_val=Time_val*ones(1,numel(Dtj))+ones(numel(Time_val),1)*cumsum(Dtj);% produce a time matrix with Dtj
80    end
81    % reading Dtk
82    Dtk=[];%default
83    NbDtk=1;%default
84    if isfield(Timing,'Dtk')
85        Dtk=Timing{k}.Dtk;
86    end
87    if isfield(Timing,'NbDtk')
88        NbDtk=Timing{k}.NbDtk;
89    end
90    if isempty(Dtk)
91        s.Time=[s.Time;Time_val];
92    else
93        for kblock=1:NbDtk+1
94            Time_val_k=Time_val+(kblock-1)*Dtk;
95            s.Time=[s.Time;Time_val_k];
96        end
97    end
98end
99           
100
101% try
102%     t=xmltree(ImaDoc);
103% catch ME
104%     errormsg={['error reading ' ImaDoc ': ']; ME.message};
105%     display(errormsg);
106%     return
107% end
108% uid_root=find(t,'/ImaDoc');
109% if isempty(uid_root), return; end;%not an ImaDoc .xml file
110
111% %% Heading
112% uid_Heading=find(t,'/ImaDoc/Heading');
113% if ~isempty(uid_Heading),
114%     uid_Campaign=find(t,'/ImaDoc/Heading/Campaign');
115%     uid_Exp=find(t,'/ImaDoc/Heading/Experiment');
116%     uid_Device=find(t,'/ImaDoc/Heading/Device');
117%     uid_Record=find(t,'/ImaDoc/Heading/Record');
118%     uid_FirstImage=find(t,'/ImaDoc/Heading/ImageName');
119%     s.Heading.Campaign=get(t,children(t,uid_Campaign),'value');
120%     s.Heading.Experiment=get(t,children(t,uid_Exp),'value');
121%     s.Heading.Device=get(t,children(t,uid_Device),'value');
122%     if ~isempty(uid_Record)
123%         s.Heading.Record=get(t,children(t,uid_Record),'value');
124%     end
125%     s.Heading.ImageName=get(t,children(t,uid_FirstImage),'value');
126% end
127
128%% Camera  and timing
129% if strcmp(option,'*') || strcmp(option,'Camera')
130%     uid_Camera=find(t,'/ImaDoc/Camera');
131%     if ~isempty(uid_Camera)
132%         uid_ImageSize=find(t,'/ImaDoc/Camera/ImageSize');
133%         if ~isempty(uid_ImageSize);
134%             ImageSize=get(t,children(t,uid_ImageSize),'value');
135%             xindex=findstr(ImageSize,'x');
136%             if length(xindex)>=2
137%                 s.Npx=str2double(ImageSize(1:xindex(1)-1));
138%                 s.Npy=str2double(ImageSize(xindex(1)+1:xindex(2)-1));
139%             end
140%         end
141%         uid_TimeUnit=find(t,'/ImaDoc/Camera/TimeUnit');
142%         if ~isempty(uid_TimeUnit)
143%             s.TimeUnit=get(t,children(t,uid_TimeUnit),'value');
144%         end
145%         uid_BurstTiming=find(t,'/ImaDoc/Camera/BurstTiming');
146%         if ~isempty(uid_BurstTiming)
147%             for k=1:length(uid_BurstTiming)
148%                 subt=branch(t,uid_BurstTiming(k));%subtree under BurstTiming
149%                 % reading Dtk
150%                 Frequency=get_value(subt,'/BurstTiming/FrameFrequency',1);
151%                 Dtj=get_value(subt,'/BurstTiming/Dtj',[]);
152%                 Dtj=Dtj/Frequency;%Dtj converted from frame unit to TimeUnit (e.g. 's')
153%                 NbDtj=get_value(subt,'/BurstTiming/NbDtj',1);
154%                 Dti=get_value(subt,'/BurstTiming/Dti',[]);
155%                 Dti=Dti/Frequency;%Dtj converted from frame unit to TimeUnit (e.g. 's')
156%                 NbDti=get_value(subt,'/BurstTiming/NbDti',1);
157%                 Time_val=get_value(subt,'/BurstTiming/Time',0);%time in TimeUnit
158%                 if ~isempty(Dti)
159%                     Dti=reshape(Dti'*ones(1,NbDti),NbDti*numel(Dti),1); %concatene Dti vector NbDti times
160%                     Time_val=[Time_val;Time_val(end)+cumsum(Dti)];%append the times defined by the intervals  Dti
161%                 end
162%                 if ~isempty(Dtj)
163%                     Dtj=reshape(Dtj'*ones(1,NbDtj),1,NbDtj*numel(Dtj)); %concatene Dtj vector NbDtj times
164%                     Dtj=[0 Dtj];
165%                     Time_val=Time_val*ones(1,numel(Dtj))+ones(numel(Time_val),1)*cumsum(Dtj);% produce a time matrix with Dtj
166%                 end
167%                 % reading Dtk
168%                 Dtk=get_value(subt,'/BurstTiming/Dtk',[]);
169%                 NbDtk=get_value(subt,'/BurstTiming/NbDtk',1);
170%                 if isempty(Dtk)
171%                     s.Time=[s.Time;Time_val];
172%                 else
173%                     for kblock=1:NbDtk+1
174%                         Time_val_k=Time_val+(kblock-1)*Dtk;
175%                         s.Time=[s.Time;Time_val_k];
176%                     end
177%                 end
178%             end
179%         end
180%     end
181% end
182
183%% motor
184% if strcmp(option,'*') || strcmp(option,'GeometryCalib')
185%     uid_subtree=find(t,'/ImaDoc/TranslationMotor');
186%     if length(uid_subtree)==1
187%         subt=branch(t,uid_subtree);%subtree under GeometryCalib
188%        [s.TranslationMotor,errormsg]=read_subtree(subt,{'Nbslice','ZStart','ZEnd'},[1 1 1],[1 1 1]);
189%     end
190% end
191%%  geometric calibration
192% if strcmp(option,'*') || strcmp(option,'GeometryCalib')
193%     uid_GeometryCalib=find(t,'/ImaDoc/GeometryCalib');
194%     if ~isempty(uid_GeometryCalib)
195%         if length(uid_GeometryCalib)>1
196%             errormsg=['More than one GeometryCalib in ' filecivxml];
197%             return
198%         end
199%         subt=branch(t,uid_GeometryCalib);%subtree under GeometryCalib
200%         cont=get(subt,1,'contents');
201%         if ~isempty(cont)
202%             uid_CalibrationType=find(subt,'/GeometryCalib/CalibrationType');
203%             if isequal(length(uid_CalibrationType),1)
204%                 tsai.CalibrationType=get(subt,children(subt,uid_CalibrationType),'value');
205%             end
206%             uid_CoordUnit=find(subt,'/GeometryCalib/CoordUnit');
207%             if isequal(length(uid_CoordUnit),1)
208%                 tsai.CoordUnit=get(subt,children(subt,uid_CoordUnit),'value');
209%             end
210%             uid_fx_fy=find(subt,'/GeometryCalib/fx_fy');
211%             focal=[];%default fro old convention (Reg Wilson)
212%             if isequal(length(uid_fx_fy),1)
213%                 tsai.fx_fy=str2num(get(subt,children(subt,uid_fx_fy),'value'));
214%             else %old convention (Reg Wilson)
215%                 uid_focal=find(subt,'/GeometryCalib/focal');
216%                 uid_dpx_dpy=find(subt,'/GeometryCalib/dpx_dpy');
217%                 uid_sx=find(subt,'/GeometryCalib/sx');
218%                 if ~isempty(uid_focal) && ~isempty(uid_dpx_dpy) && ~isempty(uid_sx)
219%                     dpx_dpy=str2num(get(subt,children(subt,uid_dpx_dpy),'value'));
220%                     sx=str2num(get(subt,children(subt,uid_sx),'value'));
221%                     focal=str2num(get(subt,children(subt,uid_focal),'value'));
222%                     tsai.fx_fy(1)=sx*focal/dpx_dpy(1);
223%                     tsai.fx_fy(2)=focal/dpx_dpy(2);
224%                 end
225%             end
226%             uid_Cx_Cy=find(subt,'/GeometryCalib/Cx_Cy');
227%             if ~isempty(uid_Cx_Cy)
228%                 tsai.Cx_Cy=str2num(get(subt,children(subt,uid_Cx_Cy),'value'));
229%             end
230%             uid_kc=find(subt,'/GeometryCalib/kc');
231%             if ~isempty(uid_kc)
232%                 tsai.kc=str2double(get(subt,children(subt,uid_kc),'value'));
233%             else %old convention (Reg Wilson)
234%                 uid_kappa1=find(subt,'/GeometryCalib/kappa1');
235%                 if ~isempty(uid_kappa1)&& ~isempty(focal)
236%                     kappa1=str2double(get(subt,children(subt,uid_kappa1),'value'));
237%                     tsai.kc=-kappa1*focal*focal;
238%                 end
239%             end
240%             uid_Tx_Ty_Tz=find(subt,'/GeometryCalib/Tx_Ty_Tz');
241%             if ~isempty(uid_Tx_Ty_Tz)
242%                 tsai.Tx_Ty_Tz=str2num(get(subt,children(subt,uid_Tx_Ty_Tz),'value'));
243%             end
244%             uid_R=find(subt,'/GeometryCalib/R');
245%             if ~isempty(uid_R)
246%                 RR=get(subt,children(subt,uid_R),'value');
247%                 if length(RR)==3
248%                     tsai.R=[str2num(RR{1});str2num(RR{2});str2num(RR{3})];
249%                 end
250%             end
251%             
252%             %look for laser plane definitions
253%             uid_Angle=find(subt,'/GeometryCalib/PlaneAngle');
254%             uid_Pos=find(subt,'/GeometryCalib/SliceCoord');
255%             if isempty(uid_Pos)
256%                 uid_Pos=find(subt,'/GeometryCalib/PlanePos');%old convention
257%             end
258%             if ~isempty(uid_Angle)
259%                 tsai.PlaneAngle=str2num(get(subt,children(subt,uid_Angle),'value'));
260%             end
261%             if ~isempty(uid_Pos)
262%                 for j=1:length(uid_Pos)
263%                     tsai.SliceCoord(j,:)=str2num(get(subt,children(subt,uid_Pos(j)),'value'));
264%                 end
265%                 uid_DZ=find(subt,'/GeometryCalib/SliceDZ');
266%                 uid_NbSlice=find(subt,'/GeometryCalib/NbSlice');
267%                 if ~isempty(uid_DZ) && ~isempty(uid_NbSlice)
268%                     DZ=str2double(get(subt,children(subt,uid_DZ),'value'));
269%                     NbSlice=get(subt,children(subt,uid_NbSlice),'value');
270%                     if isequal(NbSlice,'volume')
271%                         tsai.NbSlice='volume';
272%                         NbSlice=NbDtj+1;
273%                     else
274%                         tsai.NbSlice=str2double(NbSlice);
275%                     end
276%                     tsai.SliceCoord=ones(NbSlice,1)*tsai.SliceCoord+DZ*(0:NbSlice-1)'*[0 0 1];
277%                 end
278%             end   
279%             tsai.SliceAngle=get_value(subt,'/GeometryCalib/SliceAngle',[0 0 0]);
280%             tsai.VolumeScan=get_value(subt,'/GeometryCalib/VolumeScan','n');
281%             tsai.InterfaceCoord=get_value(subt,'/GeometryCalib/InterfaceCoord',[0 0 0]);
282%             tsai.RefractionIndex=get_value(subt,'/GeometryCalib/RefractionIndex',1);
283%             
284%             if strcmp(option,'GeometryCalib')
285%                 tsai.PointCoord=get_value(subt,'/GeometryCalib/SourceCalib/PointCoord',[0 0 0 0 0]);
286%             end
287%             s.GeometryCalib=tsai;
288%         end
289%     end
290% end
291
292%--------------------------------------------------
293%  read a subtree
294% INPUT:
295% t: xltree
296% head_element: head elelemnt of the subtree
297% Data, structure containing
298%    .Key: element name
299%    .Type: type of element ('charg', 'float'....)
300%    .NbOccur: nbre of occurrence, NaN for un specified number
301function [s,errormsg]=read_subtree(subt,Data,NbOccur,NumTest)
302%--------------------------------------------------
303s=[];%default
304errormsg='';
305head_element=get(subt,1,'name');
306    cont=get(subt,1,'contents');
307    if ~isempty(cont)
308        for ilist=1:length(Data)
309            uid_key=find(subt,[head_element '/' Data{ilist}]);
310            if ~isequal(length(uid_key),NbOccur(ilist))
311                errormsg=['wrong number of occurence for ' Data{ilist}];
312                return
313            end
314            for ival=1:length(uid_key)
315                val=get(subt,children(subt,uid_key(ival)),'value');
316                if ~NumTest(ilist)
317                    eval(['s.' Data{ilist} '=val;']);
318                else
319                    eval(['s.' Data{ilist} '=str2double(val);'])
320                end
321            end
322        end
323    end
324
325
326%--------------------------------------------------
327%  read an xml element
328function val=get_value(t,label,default)
329%--------------------------------------------------
330val=default;
331uid=find(t,label);%find the element iud(s)
332if ~isempty(uid) %if the element named label exists
333   uid_child=children(t,uid);%find the children
334   if ~isempty(uid_child)
335       data=get(t,uid_child,'type');%get the type of child
336       if iscell(data)% case of multiple element
337           for icell=1:numel(data)
338               val_read=str2num(get(t,uid_child(icell),'value'));
339               if ~isempty(val_read)
340                   val(icell,:)=val_read;
341               end
342           end
343%           val=val';
344       else % case of unique element value
345           val_read=str2num(get(t,uid_child,'value'));
346           if ~isempty(val_read)
347               val=val_read;
348           else
349              val=get(t,uid_child,'value');%char string data
350           end
351       end
352   end
353end
354
355%------------------------------------------------------------------------
356%'read_imatext': reads the .civ file for image documentation (obsolete)
357% fileinput: name of the documentation file
358% time: matrix of times for the set of images
359%pxcmx: scale along x in pixels/cm
360%pxcmy: scale along y in pixels/cm
361function [error,time,TimeUnit,mode,npx,npy,GeometryCalib]=read_imatext(fileinput)
362%------------------------------------------------------------------------
363error='';%default
364time=[]; %default
365TimeUnit='s';
366mode='pairs';
367npx=[]; %default
368npy=[]; %default
369GeometryCalib=[];
370if ~exist(fileinput,'file'), error=['image doc file ' fileinput ' does not exist']; return;end;%input file does not exist
371dotciv=textread(fileinput);
372sizdot=size(dotciv);
373if ~isequal(sizdot(1)-8,dotciv(1,1));
374    error=1; %inconsistent number of bursts
375end
376nbfield=sizdot(1)-8;
377npx=(dotciv(2,1));
378npy=(dotciv(2,2));
379pxcmx=(dotciv(6,1));% pixels/cm in the .civ file
380pxcmy=(dotciv(6,2));
381% nburst=dotciv(3,1); % nbre of bursts
382abs_time1=dotciv([9:nbfield+8],2);
383dtime=dotciv(5,1)*(dotciv([9:nbfield+8],[3:end-1])+1);
384timeshift=[abs_time1 dtime];
385time=cumsum(timeshift,2);
386GeometryCalib.CalibrationType='rescale';
387GeometryCalib.R=[pxcmx 0 0; 0 pxcmy 0;0 0 0];
388GeometryCalib.Tx=0;
389GeometryCalib.Ty=0;
390GeometryCalib.Tz=1;
391GeometryCalib.dpx=1;
392GeometryCalib.dpy=1;
393GeometryCalib.sx=1;
394GeometryCalib.Cx=0;
395GeometryCalib.Cy=0;
396GeometryCalib.f=1;
397GeometryCalib.kappa1=0;
398GeometryCalib.CoordUnit='cm';
Note: See TracBrowser for help on using the repository browser.