Ignore:
Timestamp:
11/29/11 16:03:56 (13 years ago)
Author:
Mathieu Morlighem
Message:

Improvement: marshall is now a method of all model fields, removed unnecessary model fields (numcontrols... etc)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk-jpl/src/m/model/marshall.m

    r9725 r10969  
    11function marshall(md)
    2 %MARSHALL - output JPL-package compatible binary file from @model md, for certain solution type.
     2%MARSHALL - output compatible binary file from @model md, for certain solution type.
    33%
    4 %   The routine creates a JPL-package compatible binary file from @model md
     4%   The routine creates a compatible binary file from @model md
    55%   This binary file will be used for parallel runs in JPL-package
    66%
     
    1616end
    1717
    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
     19fields=properties(md);
     20for 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);
     36end
    2137
    2238%close file
     
    2541        error(['marshall error message: could not close file ' [md.miscellaneous.name '.bin']]);
    2642end
    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 call
    34                 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                 else
    39                         fieldvalue=object.(fieldname);
    40                 end
    41 
    42                 %Capitalize for enums
    43                 fieldnamecap=fieldname;
    44                 fieldnamecap(1)=upper(fieldname(1));
    45                 prefixcap=prefix;
    46                 if ~isempty(prefix), prefixcap(1)=upper(prefix(1)); end
    47 
    48                 %Write Data
    49                 WriteData(fid,[prefixcap fieldnamecap],fieldvalue,template.(fieldname));
    50         end
    51 end
    52         % }}}
    53 function WriteData(fid,fieldname,fieldvalue,fieldprop) % {{{
    54 %WRITEDATA - write model field in binary file
    55 %
    56 %   Usage:
    57 %      WriteData(fid,fieldname,fieldvalue,fieldprop)
    58 %
    59 
    60 %first recover data, enum of the data and type of data
    61 data=fieldvalue;
    62 if fieldprop.enum==NoneEnum,
    63         enum=BuildEnum(fieldname);
    64 else
    65         %Field enum overloaded
    66         enum=fieldprop.enum;
    67 end
    68 data_type=fieldprop.format;
    69 
    70 if issparse(data),
    71         data=full(data);
    72 end
    73 
    74 %Ok! write the enum (name) to identify this record uniquely
    75 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!']); end
    80 
    81         %first write length of record
    82         fwrite(fid,4+4,'int');  %1 bool (disguised as an int)+code
    83 
    84         %write data code:
    85         fwrite(fid,TypeToCode(data_type),'int');
    86 
    87         %now write integer
    88         fwrite(fid,data,'int');  %send an int, not easy to send a bool
    89         % }}}
    90 elseif strcmpi(data_type,'Integer'), % {{{
    91         if(numel(data)~=1), error(['field ' field ' cannot be marshalled as it has more than one element!']); end
    92 
    93         %first write length of record
    94         fwrite(fid,4+4,'int');  %1 integer + code
    95 
    96         %write data code:
    97         fwrite(fid,TypeToCode(data_type),'int');
    98 
    99         %now write integer
    100         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!']); end
    104 
    105         %first write length of record
    106         fwrite(fid,8+4,'int');  %1 double+code
    107 
    108         %write data code:
    109         fwrite(fid,TypeToCode(data_type),'int');
    110 
    111         %now write double
    112         fwrite(fid,data,'double');
    113         % }}}
    114 elseif strcmpi(data_type,'String'), % {{{
    115         %first write length of record
    116         fwrite(fid,length(data)+4+4,'int');  %string + string size + code
    117 
    118         %write data code:
    119         fwrite(fid,TypeToCode(data_type),'int');
    120 
    121         %now write string
    122         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 size
    131         s=size(data);
    132         %if matrix = NaN, then do not write anything
    133         if (s(1)==1 & s(2)==1 & isnan(data)),
    134                 s(1)=0; s(2)=0;
    135         end
    136 
    137         %first write length of record
    138         fwrite(fid,4+4+8*s(1)*s(2)+4+4,'int');  %2 integers (32 bits) + the double matrix + code + matrix type
    139 
    140         %write data code and matrix type:
    141         fwrite(fid,TypeToCode(data_type),'int');
    142         fwrite(fid,mattype,'int');
    143 
    144         %now write matrix
    145         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 transpose
    149         end
    150         % }}}
    151 elseif strcmpi(data_type,'IntMat'), % {{{
    152 
    153         %matrix type:
    154         mattype=fieldtype{2};
    155 
    156         %Get size
    157         s=size(data);
    158         %if matrix = NaN, then do not write anything
    159         if (s(1)==1 & s(2)==1 & isnan(data)),
    160                 s(1)=0; s(2)=0;
    161         end
    162 
    163         %first write length of record
    164         fwrite(fid,4+4+8*s(1)*s(2)+4+4,'int');  %2 integers (32 bits) + the double matrix + code + matrix type
    165 
    166         %write data code and matrix type:
    167         fwrite(fid,TypeToCode(data_type),'int');
    168         fwrite(fid,mattype,'int');
    169 
    170         %now write matrix
    171         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 transpose
    175         end
    176         % }}}
    177 elseif strcmpi(data_type,'DoubleMat'), % {{{
    178 
    179         %matrix type:
    180         mattype=fieldprop.mattype;
    181 
    182         %Get size
    183         s=size(data);
    184         %if matrix = NaN, then do not write anything
    185         if (s(1)==1 & s(2)==1 & isnan(data)),
    186                 s(1)=0; s(2)=0;
    187         end
    188 
    189         %first write length of record
    190         fwrite(fid,4+4+8*s(1)*s(2)+4+4,'int');  %2 integers (32 bits) + the double matrix + code + matrix type
    191 
    192         %write data code and matrix type:
    193         fwrite(fid,TypeToCode(data_type),'int');
    194         fwrite(fid,mattype,'int');
    195 
    196         %now write matrix
    197         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 transpose
    201         end
    202         % }}}
    203 elseif strcmpi(data_type,'MatArray'), % {{{
    204 
    205         numrecords=numel(data);
    206 
    207         %first get length of record
    208         recordlength=4+4; %number of records + code
    209         for i=1:numrecords,
    210                 matrix=data{i};
    211                 s=size(matrix);
    212                 recordlength=recordlength+4*2+... %row and col of matrix
    213                         s(1)*s(2)*8; %matrix of doubles
    214         end
    215 
    216         %write length of record
    217         fwrite(fid,recordlength,'int');
    218 
    219         %write data code:
    220         fwrite(fid,TypeToCode(data_type),'int');
    221 
    222         %write data, first number of records
    223         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         end
    233         % }}}
    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 + code
    240         for i=1:num,
    241                 string=data{i};
    242                 recordlength=recordlength+4+length(string); %for each string
    243         end
    244 
    245         %write length of record
    246         fwrite(fid,recordlength,'int');
    247 
    248         %write data code:
    249         fwrite(fid,TypeToCode(data_type),'int');
    250 
    251         %now write length of string array
    252         fwrite(fid,num,'int');
    253 
    254         %now write the strings
    255         for i=1:num,
    256                 string=data{i};
    257                 fwrite(fid,length(string),'int');
    258                 fwrite(fid,string,'char');
    259         end
    260         % }}}
    261 else
    262         error(['WriteData error message: data type: ' num2str(data_type) ' not supported yet! (' EnumToString(enum) ')']);
    263 end
    264 % }}}
    265 function enum=BuildEnum(string) % {{{
    266 %BUILDENUM - build enum out of string
    267 %
    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         end
    276         string(indices)=[];
    277 end
    278 
    279 %take first letter of string and make it uppercase:
    280 string(1)=upper(string(1));
    281 
    282 %Get Enum
    283 enum=eval([string 'Enum']);
    284 % }}}
    285 function code=TypeToCode(data_type) % {{{1
    286 %This routine takes the data_type string, and hardcodes it into an integer, which
    287 %is passed along the record, in order to identify the nature of the dataset being
    288 %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 else
    308         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 future
    312 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         else
    324                 numrifts=numel(in);
    325         end
    326         numpairs=0;
    327         for i=1:numrifts,
    328                 numpairs=numpairs+size(in(i).penaltypairs,1);
    329         end
    330 
    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         end
    344 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         end
    360 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.