Changeset 10969 for issm/trunk-jpl/src/m/model/marshall.m
- Timestamp:
- 11/29/11 16:03:56 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
issm/trunk-jpl/src/m/model/marshall.m
r9725 r10969 1 1 function marshall(md) 2 %MARSHALL - output JPL-packagecompatible binary file from @model md, for certain solution type.2 %MARSHALL - output compatible binary file from @model md, for certain solution type. 3 3 % 4 % The routine creates a JPL-packagecompatible binary file from @model md4 % The routine creates a compatible binary file from @model md 5 5 % This binary file will be used for parallel runs in JPL-package 6 6 % … … 16 16 end 17 17 18 %automatically marshall model md, using template information available from an empty model class. 19 template=model.template(); 20 MarshallObject(fid,template,md,''); 18 %Go through al model field check that it is a class and call checkconsistency 19 fields=properties(md); 20 for i=1:length(fields), 21 field=fields{i}; 22 23 %Some properties do not need to be marshalled 24 if ismember(field,{'results' 'debug' 'radaroverlay' 'solver' 'cluster' 'flaim' 'private'}), 25 continue; 26 end 27 28 %Check that current field is an object 29 if ~isobject(md.(field)) 30 checkmessage(['field ''' char(field) ''' is not an object']); 31 end 32 33 %Marshall current object 34 %disp(['marshalling ' field '...']); 35 md.(field).marshall(fid); 36 end 21 37 22 38 %close file … … 25 41 error(['marshall error message: could not close file ' [md.miscellaneous.name '.bin']]); 26 42 end 27 28 function MarshallObject(fid,template,object,prefix) % {{{29 fields=fieldnames(template);30 for i=1:length(fields),31 fieldname=fields{i};32 if ~isa(template.(fieldname),'modelfield'),33 %Recursive call34 MarshallObject(fid,template.(fieldname),object.(fieldname),[prefix fieldname])35 elseif template.(fieldname).marshall,36 if ~isempty(template.(fieldname).preprocess),37 eval(['fieldvalue=' template.(fieldname).preprocess '(object.(fieldname));']);38 else39 fieldvalue=object.(fieldname);40 end41 42 %Capitalize for enums43 fieldnamecap=fieldname;44 fieldnamecap(1)=upper(fieldname(1));45 prefixcap=prefix;46 if ~isempty(prefix), prefixcap(1)=upper(prefix(1)); end47 48 %Write Data49 WriteData(fid,[prefixcap fieldnamecap],fieldvalue,template.(fieldname));50 end51 end52 % }}}53 function WriteData(fid,fieldname,fieldvalue,fieldprop) % {{{54 %WRITEDATA - write model field in binary file55 %56 % Usage:57 % WriteData(fid,fieldname,fieldvalue,fieldprop)58 %59 60 %first recover data, enum of the data and type of data61 data=fieldvalue;62 if fieldprop.enum==NoneEnum,63 enum=BuildEnum(fieldname);64 else65 %Field enum overloaded66 enum=fieldprop.enum;67 end68 data_type=fieldprop.format;69 70 if issparse(data),71 data=full(data);72 end73 74 %Ok! write the enum (name) to identify this record uniquely75 fwrite(fid,enum,'int');76 77 %Now, write the data itself.78 if strcmpi(data_type,'Boolean'),% {{{79 if(numel(data)~=1), error(['field ' field ' cannot be marshalled as it has more than one element!']); end80 81 %first write length of record82 fwrite(fid,4+4,'int'); %1 bool (disguised as an int)+code83 84 %write data code:85 fwrite(fid,TypeToCode(data_type),'int');86 87 %now write integer88 fwrite(fid,data,'int'); %send an int, not easy to send a bool89 % }}}90 elseif strcmpi(data_type,'Integer'), % {{{91 if(numel(data)~=1), error(['field ' field ' cannot be marshalled as it has more than one element!']); end92 93 %first write length of record94 fwrite(fid,4+4,'int'); %1 integer + code95 96 %write data code:97 fwrite(fid,TypeToCode(data_type),'int');98 99 %now write integer100 fwrite(fid,data,'int');101 % }}}102 elseif strcmpi(data_type,'Double'), % {{{103 if(numel(data)~=1), error(['field ' field ' cannot be marshalled as it has more than one element!']); end104 105 %first write length of record106 fwrite(fid,8+4,'int'); %1 double+code107 108 %write data code:109 fwrite(fid,TypeToCode(data_type),'int');110 111 %now write double112 fwrite(fid,data,'double');113 % }}}114 elseif strcmpi(data_type,'String'), % {{{115 %first write length of record116 fwrite(fid,length(data)+4+4,'int'); %string + string size + code117 118 %write data code:119 fwrite(fid,TypeToCode(data_type),'int');120 121 %now write string122 fwrite(fid,length(data),'int');123 fwrite(fid,data,'char');124 % }}}125 elseif strcmpi(data_type,'BooleanMat'), % {{{126 127 %matrix type:128 mattype=fieldprop.mattype;129 130 %Get size131 s=size(data);132 %if matrix = NaN, then do not write anything133 if (s(1)==1 & s(2)==1 & isnan(data)),134 s(1)=0; s(2)=0;135 end136 137 %first write length of record138 fwrite(fid,4+4+8*s(1)*s(2)+4+4,'int'); %2 integers (32 bits) + the double matrix + code + matrix type139 140 %write data code and matrix type:141 fwrite(fid,TypeToCode(data_type),'int');142 fwrite(fid,mattype,'int');143 144 %now write matrix145 fwrite(fid,s(1),'int');146 fwrite(fid,s(2),'int');147 if s(1)*s(2),148 fwrite(fid,data','double'); %get to the "c" convention, hence the transpose149 end150 % }}}151 elseif strcmpi(data_type,'IntMat'), % {{{152 153 %matrix type:154 mattype=fieldtype{2};155 156 %Get size157 s=size(data);158 %if matrix = NaN, then do not write anything159 if (s(1)==1 & s(2)==1 & isnan(data)),160 s(1)=0; s(2)=0;161 end162 163 %first write length of record164 fwrite(fid,4+4+8*s(1)*s(2)+4+4,'int'); %2 integers (32 bits) + the double matrix + code + matrix type165 166 %write data code and matrix type:167 fwrite(fid,TypeToCode(data_type),'int');168 fwrite(fid,mattype,'int');169 170 %now write matrix171 fwrite(fid,s(1),'int');172 fwrite(fid,s(2),'int');173 if s(1)*s(2),174 fwrite(fid,data','double'); %get to the "c" convention, hence the transpose175 end176 % }}}177 elseif strcmpi(data_type,'DoubleMat'), % {{{178 179 %matrix type:180 mattype=fieldprop.mattype;181 182 %Get size183 s=size(data);184 %if matrix = NaN, then do not write anything185 if (s(1)==1 & s(2)==1 & isnan(data)),186 s(1)=0; s(2)=0;187 end188 189 %first write length of record190 fwrite(fid,4+4+8*s(1)*s(2)+4+4,'int'); %2 integers (32 bits) + the double matrix + code + matrix type191 192 %write data code and matrix type:193 fwrite(fid,TypeToCode(data_type),'int');194 fwrite(fid,mattype,'int');195 196 %now write matrix197 fwrite(fid,s(1),'int');198 fwrite(fid,s(2),'int');199 if s(1)*s(2),200 fwrite(fid,data','double'); %get to the "c" convention, hence the transpose201 end202 % }}}203 elseif strcmpi(data_type,'MatArray'), % {{{204 205 numrecords=numel(data);206 207 %first get length of record208 recordlength=4+4; %number of records + code209 for i=1:numrecords,210 matrix=data{i};211 s=size(matrix);212 recordlength=recordlength+4*2+... %row and col of matrix213 s(1)*s(2)*8; %matrix of doubles214 end215 216 %write length of record217 fwrite(fid,recordlength,'int');218 219 %write data code:220 fwrite(fid,TypeToCode(data_type),'int');221 222 %write data, first number of records223 fwrite(fid,numrecords,'int');224 225 %write each matrix:226 for i=1:numrecords,227 matrix=data{i};228 s=size(matrix);229 fwrite(fid,s(1),'int');230 fwrite(fid,s(2),'int');231 fwrite(fid,matrix','double');232 end233 % }}}234 elseif strcmpi(data_type,'StringArray'), % {{{235 236 %first get length of string array:237 num=numel(data);238 %now get length of record:239 recordlength=4+4; %for length of array + code240 for i=1:num,241 string=data{i};242 recordlength=recordlength+4+length(string); %for each string243 end244 245 %write length of record246 fwrite(fid,recordlength,'int');247 248 %write data code:249 fwrite(fid,TypeToCode(data_type),'int');250 251 %now write length of string array252 fwrite(fid,num,'int');253 254 %now write the strings255 for i=1:num,256 string=data{i};257 fwrite(fid,length(string),'int');258 fwrite(fid,string,'char');259 end260 % }}}261 else262 error(['WriteData error message: data type: ' num2str(data_type) ' not supported yet! (' EnumToString(enum) ')']);263 end264 % }}}265 function enum=BuildEnum(string) % {{{266 %BUILDENUM - build enum out of string267 %268 % Usage:269 % enum=BuildEnum(string)270 271 if findstr(string,'_'),272 indices=findstr(string,'_');273 for i=1:length(indices),274 string(indices(i)+1)=upper(string(indices(i)+1));275 end276 string(indices)=[];277 end278 279 %take first letter of string and make it uppercase:280 string(1)=upper(string(1));281 282 %Get Enum283 enum=eval([string 'Enum']);284 % }}}285 function code=TypeToCode(data_type) % {{{1286 %This routine takes the data_type string, and hardcodes it into an integer, which287 %is passed along the record, in order to identify the nature of the dataset being288 %sent.289 if strcmpi(data_type,'Boolean'),290 code=1;291 elseif strcmpi(data_type,'Integer'),292 code=2;293 elseif strcmpi(data_type,'Double'),294 code=3;295 elseif strcmpi(data_type,'String'),296 code=4;297 elseif strcmpi(data_type,'BooleanMat'),298 code=5;299 elseif strcmpi(data_type,'IntMat'),300 code=6;301 elseif strcmpi(data_type,'DoubleMat'),302 code=7;303 elseif strcmpi(data_type,'MatArray'),304 code=8;305 elseif strcmpi(data_type,'StringArray'),306 code=9;307 else308 error('TypeToCode error message: data type not supported yet!');309 end% }}}310 311 %FIXME Some processing, should be moved to the corresponding classes in the future312 function out=marshallverbose(in)313 out = VerboseToBinary(in);314 function out=marshallicefront(in)315 out=in;316 pos=find(in(:,end)==0); out(pos,end)=AirEnum;317 pos=find(in(:,end)==1); out(pos,end)=WaterEnum;318 pos=find(in(:,end)==2); out(pos,end)=IceEnum;319 320 function out=marshallrifts(in)321 if isempty(in) | isnans(in),322 numrifts=0;323 else324 numrifts=numel(in);325 end326 numpairs=0;327 for i=1:numrifts,328 numpairs=numpairs+size(in(i).penaltypairs,1);329 end330 331 out=zeros(numpairs,12); % 2 for nodes + 2 for elements+ 2 for normals + 1 for length + 1 for fill + 1 for friction + 1 for fraction + 1 for fractionincrement + 1 for state.332 333 count=1;334 for i=1:numrifts,335 numpairsforthisrift=size(in(i).penaltypairs,1);336 out(count:count+numpairsforthisrift-1,1:7)=in(i).penaltypairs;337 out(count:count+numpairsforthisrift-1,8)=in(i).fill;338 out(count:count+numpairsforthisrift-1,9)=in(i).friction;339 out(count:count+numpairsforthisrift-1,10)=in(i).fraction;340 out(count:count+numpairsforthisrift-1,11)=in(i).fractionincrement;341 out(count:count+numpairsforthisrift-1,12)=in(i).state;342 count=count+numpairsforthisrift;343 end344 function out=marshallapproximations(in),345 out=in;346 pos=find(in==0); out(pos,end)=NoneApproximationEnum;347 pos=find(in==1); out(pos,end)=HutterApproximationEnum;348 pos=find(in==2); out(pos,end)=MacAyealApproximationEnum;349 pos=find(in==3); out(pos,end)=PattynApproximationEnum;350 pos=find(in==4); out(pos,end)=StokesApproximationEnum;351 pos=find(in==5); out(pos,end)=MacAyealPattynApproximationEnum;352 pos=find(in==6); out(pos,end)=MacAyealStokesApproximationEnum;353 pos=find(in==7); out(pos,end)=PattynStokesApproximationEnum;354 355 function out=marshallcontroltype(in)356 out=zeros(1,numel(in));357 for i=1:numel(in),358 out(i)=StringToEnum(in{i});359 end360 function out=marshallcmresponses(in),361 out=in;362 pos=find(in==101); out(pos)=SurfaceAbsVelMisfitEnum;363 pos=find(in==102); out(pos)=SurfaceRelVelMisfitEnum;364 pos=find(in==103); out(pos)=SurfaceLogVelMisfitEnum;365 pos=find(in==104); out(pos)=SurfaceLogVxVyMisfitEnum;366 pos=find(in==105); out(pos)=SurfaceAverageVelMisfitEnum;367 pos=find(in==201); out(pos)=ThicknessAbsMisfitEnum;368 pos=find(in==501); out(pos)=DragCoefficientAbsGradientEnum;369 pos=find(in==502); out(pos)=RheologyBbarAbsGradientEnum;370 pos=find(in==503); out(pos)=ThicknessAbsGradientEnum;
Note:
See TracChangeset
for help on using the changeset viewer.