valid_inv_model

PURPOSE ^

[pass, err_str] = valid_fwd_model(imdl)

SYNOPSIS ^

function [pass, err_str] = valid_inv_model(imdl)

DESCRIPTION ^

 [pass, err_str] = valid_fwd_model(imdl)

 Confirms that a valid forward model structure exists or
 explain why a model is not valid.

 If called without an output argument (nargout=0), will
 error out if invalid. Otherwise the function is silent,
 returning an explaination of failures in err_str.

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [pass, err_str] = valid_inv_model(imdl)
0002 % [pass, err_str] = valid_fwd_model(imdl)
0003 %
0004 % Confirms that a valid forward model structure exists or
0005 % explain why a model is not valid.
0006 %
0007 % If called without an output argument (nargout=0), will
0008 % error out if invalid. Otherwise the function is silent,
0009 % returning an explaination of failures in err_str.
0010 
0011 % (C) 2015 Alistair Boyle. License: GPL version 2 or version 3
0012 % $Id: valid_inv_model.m 7068 2024-12-09 01:52:36Z aadler $
0013 
0014 if ischar(imdl) && strcmp(imdl,'UNIT_TEST'); do_unit_test; return; end
0015 
0016 pass = 1;
0017 err_str = '';
0018 
0019 % it's a struct with fields
0020 if ~isstruct(imdl)
0021    pass = 0;
0022    err_str = [err_str '- not a struct\n'];
0023 end
0024 
0025 % required fields
0026 %      field         type
0027 f = {'name',        'char', ...
0028      'fwd_model',   'struct', ...
0029      'solve',       'function', ...
0030      'reconst_type','char', ... % 'absolute' or 'difference'
0031      'type',        'char'};
0032 %     'hyperparameter', 'numeric', ... % struct, func, or numeric?
0033 %     'RtR_prior',   'function', ... % function OR numeric
0034 %    'jacobian_bkgnd', 'struct', ... % struct OR numeric
0035 for i=1:length(f)/2
0036    x=2*(i-1)+1;
0037    y=x+1;
0038    if ~isfield(imdl, f{x})
0039       pass = 0;
0040       err_str = [err_str '- missing required field: "' f{x} '"\n'];
0041    elseif strcmp(f{y},'function')
0042       if ~isfunc(imdl.(f{x}))
0043          pass = 0;
0044          err_str = [err_str '- expected function (pointer or string): "' f{x} '"\n'];
0045       end
0046    elseif ~isa(imdl.(f{x}), f{y})
0047       pass = 0;
0048       err_str = [err_str '- required field "' f{x} '" is not a ' f{y} '\n'];
0049    end
0050 end
0051 % check the fwd_model
0052 [pass_local, err_str_local] = valid_fwd_model(imdl.fwd_model);
0053 if ~pass_local
0054    pass = 0;
0055    disp(err_str_local);
0056    err_str_local = strrep(err_str_local, ' "', ' "fwd_model.');
0057    err_str = [err_str err_str_local];
0058 end
0059 clear err_str_local pass_local;
0060 % check for correct 'type'
0061 if ~strcmp(imdl.type, 'inv_model')
0062    pass = 0;
0063    err_str = [err_str '- field "type" must be "inv_model"\n'];
0064 end
0065 
0066 % optional fields
0067 %      field       type
0068 f = {'rec_model',   'struct'};
0069 for i=1:length(f)/2
0070    x=2*(i-1)+1;
0071    y=x+1;
0072    if isfield(imdl, f{x}) && ~isa(imdl.(f{x}), f{y})
0073       pass = 0;
0074       err_str = [err_str '- optional field "' f{x} '" is not a ' f{y} '\n'];
0075    end
0076 end
0077 % check the rec_model
0078 if isfield(imdl, 'rec_model')
0079    [pass_local, err_str_local] = valid_fwd_model(imdl.rec_model, 'rec_model');
0080    if ~pass_local
0081       pass = 0;
0082       disp(err_str_local);
0083       err_str_local = strrep(err_str_local, ' "', ' "rec_model.');
0084       err_str = [err_str err_str_local];
0085    end
0086    clear err_str_local pass_local;
0087 end
0088 
0089 % illegal fields
0090 %      field
0091 f = {'inv_model', ... % no recursion
0092      'fmdl', ... % no short forms
0093      'fwd_mdl'};
0094 for i=1:length(f)
0095    x=i;
0096    if isfield(imdl, f{x})
0097       pass = 0;
0098       err_str = [err_str '- illegal field "' f{x} '" found\n'];
0099    end
0100 end
0101 
0102 % result
0103 if ~pass
0104    err_str = err_str(1:end-2); % drop last \n
0105 end
0106 if ( nargout == 0 ) && ~pass
0107    error(sprintf(['Reasons:\n' err_str]));
0108 end
0109 
0110 function t=isfunc(f)
0111 t=isa(f, 'function_handle') || isa(f, 'char');
0112 
0113 function do_unit_test
0114    imdl = mk_common_model('a2c0',2);
0115    pass=1; 
0116    try   [pass, err_str] = valid_inv_model(imdl);
0117    catch pass=0; 
0118    end
0119    unit_test_cmp('valid_inv_model 1',pass,1);
0120 
0121    imdl= rmfield(imdl,'solve');
0122    try   [pass, err_str] = valid_inv_model(imdl);
0123    catch pass=0; 
0124    end
0125    unit_test_cmp('valid_inv_model 2',pass,0);

Generated on Sun 29-Dec-2024 11:41:59 by m2html © 2005