Code covered by the BSD License  

Highlights from
Statistical Learning Toolbox

from Statistical Learning Toolbox by Dahua Lin
Functions for statistical learning, pattern recognition and computer vision, covering many topics.

edl_readexpdefs(filename)
function ED = edl_readexpdefs(filename)
%EDL_READEXPDEFS Reads in an experiment definition from XML file
%
% $ Syntax $
%   - ED = edl_readexpdefs(filename)
%
% $ Arguments $
%   - filename:     the filename of the experiment definition XML
%   - ED:           the read experiment definition struct
%
% $ Description $
%   - ED = edl_readexpdefs(filename) reads in an experiment definition
%     struct from an XML file. The format of XML can be referred to 
%     the edl.spec.txt. The struct ED has following fields:
%
%       - name: the experiment definition name
%       - selfpath: the absolute path of the experiment definition self
%       - envconf: the filename of environment configuration
%       - env:     the environment configuration struct
%       - scriptdir: the script directory
%       - reportdir: the report directory
%       - mfiledir:  the m-files directory
%       - logfile:   the path of log file
%       - logger:    the logger
%
%       - variables: a struct of all variables, 
%           using variable names as field names
%           using variable values as field values
%       - scripts: the struct of scripts
%           - using name as fieldnames, each field is a struct with
%               - func:     the scripting function
%               - path:     the path of the script file
%               - ctrlpath: the path of the control file
%               - params:   the other parameters
%               - refs:     the struct array of referenced scripts
%                   using role as field name
%                   using script name as field value
%               - refreps:  the struct array of referenced reports
%                   using role as field name
%                   using report name as field value            
%               - refpaths: the struct array of referenced paths
%                   using role as field name
%                   using xml path of (script or report) as field value
%               - refscopes: the struct array of scope names of references
%                            (scripts | reports)
%                   using role as field name
%                   using scope names as field values
%       - experiments: the struct of experiments
%           - using name as fieldnames, each field is a struct with
%               - func:         the experiment function
%               - script:       the script name
%               - scriptpath:   the script filepath
%               - ctrlpath:     the control filepath
%       - reports: the struct array of reports
%           similar to scripts, except for that there is no ctrlpath
%       
% $ History $
%   - Created by Dahua Lin, on Aug 12nd, 2006
%

%% Read file

xdoc = xmlread(filename);
edparent = slfilepart(filename, 'parent');
docelem = xdoc.getDocumentElement;


%% Read Header

headerfns = { ...
    'name', ...
    'envconf', ...
    'scriptdir', ...
    'reportdir', ...
    'mfiledir', ...
    'logfile'};
ED = cell2struct(cell(1, length(headerfns)), headerfns, 2);
headers = xml_getattribs(docelem);
ED = slparseprops(ED, headers);

if slisabspath(filename)
    ED.selfpath = filename;
else
    ED.selfpath = sladdpath(filename, cd());
end

if isempty(ED.envconf)
    ED.env = [];
else
    envpath = sladdpath(ED.envconf, edparent);
    ED.env = edl_readenvvars(envpath);
end

if isempty(ED.env) || ~isfield(ED.env, 'envname')
    error('edl:parseerror', ...
        'The environment must has variable named %s', 'envname');
end
envname = ED.env.envname;

ED.logger = sllog('rootpath', edparent);
if ~isempty(ED.logfile)
    ED.logfile = [ED.logfile, '.', envname, '.log'];
    ED.logger = addfiles(ED.logger, ED.logfile);
end

%% First-Pass Parsing
% 1. Build variable table progressively
% 2. Build basic structures
% 3. Translate variables

ED.variables = [];
ED.scripts = [];
ED.experiments = [];
ED.reports = [];

ED = first_pass(ED, docelem, struct('workdir', ''));


%% Second-Pass Parsing
% 1. Extract paths from cross-references
%   (a) build refpaths for scripts and reports
%   (b) build scriptpath and ctrlpath for experiments
%

% 1.(a)
ED.scripts = build_refpaths(ED, ED.scripts);
ED.reports = build_refpaths(ED, ED.reports);

% 1.(b)
ED.experiments = build_exppaths(ED, ED.experiments);



%% Core function for First-Pass (recursive invoking)

function ED = first_pass(ED, xelem, groupvars)

nodeList = xelem.getChildNodes;
n = nodeList.getLength;

for i = 1 : n   % enumerate all children
    
    node = nodeList.item(i-1);    
    if (node.getNodeType == node.ELEMENT_NODE)       
        tag = char(node.getTagName);
        
        switch tag
            
            case 'Var'
                [varname, varval] = parse_var(ED, node);
                ED.variables.(varname) = varval;
                
            case 'Script'
                [scriptname, scriptstruct] = parse_script(ED, node);
                scriptstruct.params = weak_update(scriptstruct.params, groupvars);
                ED.scripts.(scriptname) = scriptstruct;
            
            case 'Report'
                [reportname, reportstruct] = parse_report(ED, node);
                ED.reports.(reportname) = reportstruct;
                
            case 'Experiment'
                [expname, expstruct] = parse_experiment(ED, node);
                ED.experiments.(expname) = expstruct; 
                
            case 'Group'                
                subgroupvars = parse_group(ED, groupvars, node);
                ED = first_pass(ED, node, subgroupvars);
                
            otherwise
                error('edl:parseerror', ...
                    'Invalid element with tag name %s', tag);                            
        end
                
    end
    
end


%% Core functions for Second-Pass

function S = build_refpaths(ED, S)

fns = fieldnames(S);
n = length(fns);

for i = 1 : n
    fn = fns{i};
    
    S.(fn) = build_refpaths_fortype(ED, fn, S.(fn), 'scripts', 'refs');
    S.(fn) = build_refpaths_fortype(ED, fn, S.(fn), 'reports', 'refreps');
        
end


function S = build_refpaths_fortype(ED, name, S, typeset, typefield)

if ~isfield(S, 'refpaths')
    S.refpaths = [];
end
if ~isfield(S, 'refscopes')
    S.refscopes = [];
end

curset = S.(typefield);
if isempty(curset)
    return;
end

fns = fieldnames(curset);
n = length(fns);
pool = ED.(typeset);

for i = 1 : n
    role = fns{i};    
    refname = curset.(role);
    if ~isfield(pool, refname)
        error('edl:parseerror', ...
            'The reference with role %s (name = %s) in %s is not found in pool %s', ...
            role, refname, name, typeset);
    end
    
    S.refpaths.(role) = pool.(refname).path;    
    S.refscopes.(role) = typeset;
end


function ES = build_exppaths(ED, ES)

if isempty(ES)
    return;
end

fns = fieldnames(ES);
n = length(fns);

for i = 1 : n
    fn = fns{i};
    scriptname = ES.(fn).script;
    if ~isfield(ED.scripts, scriptname)
        error('edl:parseerror', ...
            'The referred script named %s for %s is not found', ...
            scriptname, fn);
    end
    
    curscript = ED.scripts.(scriptname);
    
    ES.(fn).scriptpath = curscript.path;
    ES.(fn).ctrlpath = curscript.ctrlpath;
end



%% Node Parsing functions

% variable parsing

function [vname, vval] = parse_var(ED, xelem)

vname = make_name(ED, 'variables', xelem);
vval = get_tattrib(ED, xelem, 'variables', vname, 'val');


% script parsing

function [sname, scr] = parse_script(ED, xelem)

sname = make_name(ED, 'scripts', xelem);

scr.func = get_tattrib(ED, xelem, 'scripts', sname, 'func');
scr.func = sladdpath(scr.func, ED.mfiledir);

scr.path = '';
scr.ctrlpath = '';
scr = update_fields(ED, scr, xelem, {'path', 'ctrlpath'});
scr.params = get_tattribs(ED, xelem, ...
    'exclude', {'name', 'func', 'path', 'ctrlpath'});

if isempty(scr.path)
    scr.path = [sname, '.script.xml'];
end
if isempty(scr.ctrlpath)
    scrfiletitle = slfilepart(scr.path, 'title');
    scr.ctrlpath = slchangefilepart(scr.path, 'title', [scrfiletitle, '.control']);
end

scr.path = sladdpath(scr.path, ED.scriptdir);

scr = build_reftables(ED, scr, xelem);


% report parsing

function [rname, rep] = parse_report(ED, xelem)

rname = make_name(ED, 'reports', xelem);

rep.func = get_tattrib(ED, xelem, 'reports', rname, 'func');
rep.func = sladdpath(rep.func, ED.mfiledir);

rep.path = '';
rep = update_fields(ED, rep, xelem, {'path'});
rep.params = get_tattribs(ED, xelem, ...
    'exclude', {'name', 'func', 'path', 'ctrlpath'});

if isempty(rep.path)
    rep.path = [rname, '.report.xml'];
end
rep.path = sladdpath(rep.path, ED.reportdir);

rep = build_reftables(ED, rep, xelem);


% experiment parsing

function [expname, es] = parse_experiment(ED, xelem)

expname = make_name(ED, 'experiments', xelem);

es.func = get_tattrib(ED, xelem, 'experiments', expname, 'func'); 
es.func = sladdpath(es.func, ED.mfiledir);

es.script = '';
es = update_fields(ED, es, xelem, {'script'});

if isempty(es.script)
    es.script = expname;
end


% group parsing

function newvars = parse_group(ED, gvars, xelem)

newvars = get_tattribs(ED, xelem, 'exclude', {'title'});

if ~isfield(newvars, 'workdir') || isempty(newvars.workdir)
    newvars.workdir = gvars.workdir;
else
    newvars.workdir = sladdpath(newvars.workdir, gvars.workdir);
end

newvars = weak_update(newvars, gvars);






%% Auxiliary functions


function val = translate_attribval(ED, attrval)

val = attrval;
if length(val) > 1 && val(1) == '$'
    varname = val(2:end);
    if ~isfield(ED.variables, varname)
        error('edl:parseerror', ...
            'The variable %s is not found', varname);
    end
    val = ED.variables.(varname);
end


function aval = get_tattrib(ED, xelem, scope, elemname, attrname)

if xelem.hasAttribute(attrname)
    aval = char(xelem.getAttribute(attrname));
    aval = translate_attribval(ED, aval);
else
    error('edl:parseerror', ...
        'The attribute %s is not found in %s of %s', attrname, elemname, scope);
end


function A = get_tattribs(ED, xelem, varargin)

A = xml_getattribs(xelem, varargin{:});

if ~isempty(A)
    fns = fieldnames(A);
    n = length(fns);
    for i = 1 : n
        fn = fns{i};
        A.(fn) = translate_attribval(ED, A.(fn));
    end
end    


function name = make_name(ED, scope, xelem)

if xelem.hasAttribute('name')
    name = char(xelem.getAttribute('name'));
    if isfield(ED.(scope), name)
        error('edl:parseerror', ...
            'Redefinition of %s in %s', name, scope);
    end
else
    error('edl:parseerror', ...
        'Encounter an element without name in %s', scope);
end


function S = update_fields(ED, S, xelem, fns)

S = slparseprops(S, get_tattribs(ED, xelem, ...
    'select', fns, ...
    'forceexist', false));


function S = weak_update(S, Scomp)

fns = fieldnames(Scomp);
n = length(fns);
for i = 1 : n
    fn = fns{i};
    if ~isfield(S, fn)
        S.(fn) = Scomp.(fn);
    end
end


function S = build_reftables(ED, S, xelem)

refNodes = xelem.getElementsByTagName('Ref');
nrs = refNodes.getLength;

S.refs = [];
S.refreps = [];

for i = 1 : nrs
    curnode = refNodes.item(i-1);
    cur = get_tattribs(ED, curnode, 'select', {'role', 'name'});
    S.refs.(cur.role) = cur.name;
end

refrepNodes = xelem.getElementsByTagName('RefReport');
nrr = refrepNodes.getLength;

for i = 1 : nrr
    curnode = refrepNodes.item(i-1);
    cur = get_tattribs(ED, curnode, 'select', {'role', 'name'});
    S.refreps.(cur.role) = cur.name;
end








Contact us at files@mathworks.com