Revision ea88b3bc868dd0753ff90f2adda0aaca4474e7fb authored by Niklas Neubrand on 18 July 2024, 08:33:01 UTC, committed by GitHub on 18 July 2024, 08:33:01 UTC
Update Links to DREAM challenges. The domain changed.
1 parent 3f56245
arLoadData.m
% arLoadData(name, [m], [extension], [removeEmptyObs], [opts])
%
% Load data set to next free slot(s)
%
% name filename of data definition file
% m target position (int) for modelor: model
% name (string)
% [last loaded model]
% extension data file name-extension: 'xls', 'csv',
% 'none' = don't load data
% ['xls']
% removeEmptyObs remove observation without data
% [false]
% opts additional option flags
%
% Optional option flags are:
% 'RemoveConditions' This flag followed by a list of conditions will
% allow you to filter the data that you load. Note
% that the function takes both values, strings
% or function handles. When you provide a function
% handle, the function will be evaluated for each
% condition value (in this case input_dcf). You
% should make the function return 1 if the condition
% is to be removed. Note that the input to the
% function is a *string* not a number.
% Example:
% arLoadData( 'mydata', 1, 'csv', true, 'RemoveConditions', ...
% {'input_il6', '0', 'input_dcf', @(dcf)str2num(dcf)>0};
% 'RemoveEmptyConds' This flag allows you to remove conditions that have
% no data points.
% 'ResampleDoseResponse' This flag allows you to increase the resolution
% of dose responses for plotting purposes. Note
% that this makes model evaluation and
% compilation much more time intensive (hence it
% is off by default).
% 'ResamplingResolution' Number of extra points to interpolate dose
% response (default: 25)
% 'RefineLog' Perform the refinement on a log scale
% 'expsplit' Split replicate specific parameters based on the
% column identifier specified in the next argument
% Example:
% arLoadData('mRNA/mRNA_pretreatment', 1, 'csv', true, 'expsplit', 'nExpID');
% will recognize parameters with nExpID in the name
% and replace them with nExpID0, nExpID1 etc. if
% the excel data file has a column named nExpID
% which specifies these values.
%
% 'RemoveObservables' This can be used to omit observables. Simply pass a
% cell array with names of observables that should be
% ignored in the data.
%
% 'IgnoreInputs' Ignore input overrides. Simply pass a cell array
% with names of inputs that should be ignored (the
% model default will be used instead).
%
% 'DataPath' Path to the data files.
% Default: DataPath = 'Data/'
%
% The data file specification is as follows:
%
% In the first column
% 1) Measurement time points (are allowed to occur multiple times).
%
% In the following columns (in any order):
% 2) Experimental conditions (e.g. "input_IL6" and "input_IL1").
% 3) The data points for the individual observables (e.g. "P_p38_rel").
%
% Note:
% 1) No mathematical symbols are allowed in the column headers (e.g. "+")
% 2) I have always used input_ as a prefix for stimulations. Regarding
% observables, the suffixes "_rel" and "_au" refer to relative
% phosphorylation and arbitrary units.
%
% Defining the measurement noise in the data sheet:
% Instead of using a parametrized function for the measurement noise,
% the amount of noise can be put value in the data sheet with column
% header same as the observable name but with the addition _std
% (e.g. tSTAT5_au_std and pSTAT5_au_std). These values will be
% interpreted as standard deviation of the data not as variance!
%
% The following flags controll how the experimental noise enters
% calculations and how it is plotted:
% ar.config.fiterror 0: Data is plotted as fitted (ar.config.fiterors).
% -1: Plot prediction bands as calculated by PPL.
% -2: Do not plot errors
% ar.config.fiterrors -1: Only experimental error bars used for fitting.
% 0: Use experimental errors by default and revert
% to the error model for data points that have no
% experimental error specified.
% 1: Only the error model is used for fitting.
% Experimental errors specified in the data sheet
% are ignored.
% ar.config.ploterrors 0: Observables are plotted as fitted.
% 1: Data uncertainty is plotted as error bar.
% 2: Only error bands are plotted.
%
% See wiki page about loading data: https://github.com/Data2Dynamics/d2d/wiki/Setting%20up%20models#2-data-definition-file
%
% See also arInit, arLoadModel
function arLoadData(name, m, extension, removeEmptyObs, varargin)
global ar
arFprintf( 3, 'Parsing input arguments...\n' );
if(isempty(ar))
error('please initialize by arInit')
end
switches = { 'dppershoot', 'removeconditions', 'removeobservables', 'splitconditions',...
'removeemptyconds', 'expsplit', 'resampledoseresponse', 'resamplingresolution',...
'refinelog', 'ignoreinputs', 'detectionlimit', 'datapath', 'delimiter'};
extraArgs = [ 1, 1, 1, 1, ...
0, 1, 0, 1, ...
0, 1, 1, 1, 1];
description = { ...
{'', 'Multiple shooting on'} ...
{'', 'Ignoring specific conditions'} ...
{'', 'Ignoring specific observables'} ...
{'', 'Split data set into specific conditions'}, ...
{'', 'Removing conditions without data'}, ...
{'', 'Splitting conditions by specific data column'}, ...
{'', 'Resampling dose response'}, ...
{'', 'Resampling with custom resolution'}, ...
{'', 'Resampling on log scale'}, ...
{'', 'Ignoring specific inputs'}, ...
{'', 'Working with detection limit'}, ...
{'', 'Path to the data files'}, ...
{'', 'Setting custom Delimiter for csv file'}};
opts = argSwitch( switches, extraArgs, description, 1, varargin );
if isempty(opts.datapath_args)
DataPath = 'Data/';
else
DataPath = opts.datapath_args;
if DataPath(end)~='/' && DataPath(end)~='\'
DataPath = [DataPath,'/'];
end
end
% Set Delimiter for csv files
if ~isempty(opts.delimiter_args)
Delimiter = opts.delimiter_args;
end
% load model from mat-file
if(~exist(DataPath,'dir'))
error('folder %s does not exist',DataPath)
end
if strcmp(strrep(name,' ',''),name)~=1
name
error('File names should not contain empty spaces. Please remove it.');
end
if(~exist([DataPath, name, '.def'],'file'))
if(~exist([DataPath, name '.xls'],'file') && ~exist([DataPath, name '.csv'],'file') && ~exist([DataPath, name '.xlsx'],'file'))
error('data definition file %s.def does not exist in folder %s', name,DataPath)
else
arFprintf(1, '\ncreating generic .def file for %s/%s ...\n', DataPath, name);
copyfile(which('data_template.def'),[DataPath, name, '.def']);
end
else
if(~exist([DataPath, name '.xls'],'file') && ~exist([DataPath, name '.csv'],'file') && ~exist([DataPath, name '.xlsx'],'file'))
warning('data file corresponding to %s.def does not exist in folder %s/', DataPath, name)
end
end
if(~exist('m','var') || isempty(m))
m = length(ar.model);
end
if(exist('m','var') && ischar(m))
for jm=1:length(ar.model)
if(strcmp(m, ar.model(jm).name))
m = jm;
end
end
if(ischar(m))
error('Model %s was not found', m);
end
end
if(exist('extension','var') && isnumeric(extension) && ...
~(isempty(extension) && nargin>3))
error(['arLoadData(name, m, d, ...) input argument d is deprecated !!! ' ...
'Please see new usage arLoadModel(name, m, extension, removeEmptyObs) and function help text.']);
end
if(isfield(ar.model(m), 'data'))
d = length(ar.model(m).data) + 1;
else
ar.model(m).data = [];
d = 1;
end
if(~exist('extension','var') || isempty(extension))
extension = 'xls';
% auto-select extension if not specified
if exist([DataPath, name '.xlsx'],'file')
extension = 'xlsx';
elseif exist([DataPath, name '.xls'],'file')
extension = 'xls';
elseif exist([DataPath, name '.csv'],'file')
extension = 'csv';
end
end
if(~exist('removeEmptyObs','var'))
removeEmptyObs = false;
else
if(ischar(removeEmptyObs))
error(['arLoadData(name, m, d, ...) input argument d is deprecated !!! ' ...
'Please see new usage arLoadModel(name, m, extension, removeEmptyObs) and function help text.']);
end
end
%%
if ( opts.resampledoseresponse )
if ( ~isnumeric( opts.resamplingresolution_args ) || isempty( opts.resamplingresolution_args ) )
opts.resamplingresolution = 25;
else
opts.resamplingresolution = opts.resamplingresolution_args(1);
end
end
if( opts.dppershoot )
if( opts.dppershoot_args>0 )
if(~isfield(ar,'ms_count_snips'))
ar.model(m).ms_count = 0;
ar.ms_count_snips = 0;
ar.ms_strength = 0;
ar.ms_threshold = 1e-5;
ar.ms_violation = [];
end
dpPerShoot = opts.dppershoot_args;
end
else
dpPerShoot = 0;
end
% initial setup
ar.model(m).data(d).name = strrep(strrep(strrep(strrep(name,'=','_'),'.',''),'-','_'),'/','_');
ar.model(m).data(d).path = [pwd,filesep,DataPath];
ar.model(m).data(d).uNames = {};
arFprintf(1, '\nloading data #%i, from file %s%s.def...', d, DataPath, name);
% Disable this if you are having problems because of the preprocessor
preprocessor = 1;
if ( ~preprocessor )
fid = fopen([DataPath, name, '.def'], 'r');
else
% Load into a struct
fid.fn = [DataPath name '.def'];
fid.str = fileread([DataPath name '.def']);
fid.pos = 1;
arFprintf( 3, 'Running preprocessor...' );
fid = arPreProcessor(fid);
arFprintf( 3, ' [ OK ]\n' );
end
% DESCRIPTION
arFprintf( 3, 'Start parsing...' );
[str, fid] = arTextScan(fid, '%s', 1, 'CommentStyle', ar.config.comment_string);
if(~strcmp(str{1},'DESCRIPTION'))
arParsingError( fid, 'parsing data %s for DESCRIPTION', name);
end
% check version
if(strcmp(str{1},'DESCRIPTION'))
% def_version = 1;
elseif(strcmp(str{1},'DESCRIPTION-V2'))
arParsingError( fid, 'DESCRIPTION-V2 not supported yet');
else
arParsingError( fid, 'invalid version identifier: %s', cell2mat(str{1}));
end
% read comments
arFprintf( 3, '[ OK ]\nReading description' );
[str, fid] = arTextScan(fid, '%q', 1, 'CommentStyle', ar.config.comment_string);
ar.model(m).data(d).description = {};
while(~strcmp(str{1},'PREDICTOR') && ~strcmp(str{1},'PREDICTOR-DOSERESPONSE'))
arFprintf( 3, '.' );
ar.model(m).data(d).description(end+1,1) = str{1}; %#ok<*AGROW>
[str, fid] = arTextScan(fid, '%q', 1, 'CommentStyle', ar.config.comment_string);
end
% PREDICTOR
arFprintf( 3, '[ OK ]\nReading predictor...\n' );
if(strcmp(str{1},'PREDICTOR-DOSERESPONSE'))
ar.model(m).data(d).doseresponse = true;
[str, fid] = arTextScan(fid, '%s', 1, 'CommentStyle', ar.config.comment_string);
ar.model(m).data(d).response_parameter = cell2mat(str{1});
arFprintf(2, 'dose-response to %s\n', ar.model(m).data(d).response_parameter);
else
ar.model(m).data(d).doseresponse = false;
ar.model(m).data(d).response_parameter = '';
arFprintf(2, '\n');
end
[C, fid] = arTextScan(fid, '%s %s %q %q %n %n %n %n\n',1, 'CommentStyle', ar.config.comment_string);
ar.model(m).data(d).t = cell2mat(C{1});
ar.model(m).data(d).tUnits(1) = C{2};
ar.model(m).data(d).tUnits(2) = C{3};
ar.model(m).data(d).tUnits(3) = C{4};
ar.model(m).data(d).tLim = [checkNum(C{5}, 0) checkNum(C{6}, 10)];
ar.model(m).data(d).tLimExp = [checkNum(C{7}, ar.model(m).tLim(1)), checkNum(C{8}, ar.model(m).tLim(2))];
% INPUTS
arFprintf( 3, 'Reading inputs...' );
[str, fid] = arTextScan(fid, '%s', 1, 'CommentStyle', ar.config.comment_string);
if(~strcmp(str{1},'INPUTS'))
arParsingError( fid, 'parsing data %s for INPUTS', name);
end
[C, fid] = arTextScan(fid, '%s %q %q\n',1, 'CommentStyle', ar.config.comment_string);
ar.model(m).data(d).fu = ar.model(m).fu;
while(~strcmp(C{1},'OBSERVABLES'))
arFprintf( 3, '.' );
qu = ismember(ar.model(m).u, C{1}); %R2013a compatible
if(sum(qu)~=1)
arParsingError( fid, 'unknown input %s', cell2mat(C{1}));
end
% Ignore this replacement?
ignoreInput = 0;
if (opts.ignoreinputs)
if ismember(C{1}, opts.ignoreinputs_args)
ignoreInput = 1;
end
end
if ( ~ignoreInput )
% Input replacement description
ar.model(m).data(d).fu(qu) = C{2};
if(~isempty(cell2mat(C{3})))
ar.model(m).data(d).uNames(end+1) = C{3};
else
ar.model(m).data(d).uNames{end+1} = '';
end
end
[C, fid] = arTextScan(fid, '%s %q %q\n',1, 'CommentStyle', ar.config.comment_string);
end
% input parameters
varlist = cellfun(@symvar, ar.model(m).data(d).fu, 'UniformOutput', false);
ar.model(m).data(d).pu = setdiff(vertcat(varlist{:}), {ar.model(m).t, ''}); %R2013a compatible
% OBSERVABLES
arFprintf( 3, '[ OK ]\nReading observables' );
if(isfield(ar.model(m),'y'))
ar.model(m).data(d).y = ar.model(m).y;
ar.model(m).data(d).yNames = ar.model(m).yNames;
ar.model(m).data(d).yUnits = ar.model(m).yUnits;
ar.model(m).data(d).normalize = ar.model(m).normalize;
ar.model(m).data(d).logfitting = ar.model(m).logfitting;
ar.model(m).data(d).logplotting = ar.model(m).logplotting;
ar.model(m).data(d).fy = ar.model(m).fy;
else
ar.model(m).data(d).y = {};
ar.model(m).data(d).yNames = {};
ar.model(m).data(d).yUnits = {};
ar.model(m).data(d).normalize = [];
ar.model(m).data(d).logfitting = [];
ar.model(m).data(d).logplotting = [];
ar.model(m).data(d).fy = {};
end
[C, fid] = arTextScan(fid, '%s %q %q %q %n %n %q %q\n',1, 'CommentStyle', ar.config.comment_string);
while(~strcmp(C{1},'ERRORS'))
arFprintf( 3, '.' );
qyindex = ismember(ar.model(m).data(d).y, C{1});
if(sum(qyindex)==1)
yindex = find(qyindex);
elseif(sum(qyindex)==0)
yindex = length(ar.model(m).data(d).y) + 1;
else
arParsingError( fid, 'multiple matches for %s', cell2mat(C{1}))
end
if length(C)<7
celldisp(C)
warning('Did you miss yunits or flags in the data def file?')
end
ar.model(m).data(d).y(yindex) = C{1};
ar.model(m).data(d).yUnits(yindex,1) = C{2};
ar.model(m).data(d).yUnits(yindex,2) = C{3};
ar.model(m).data(d).yUnits(yindex,3) = C{4};
ar.model(m).data(d).normalize(yindex) = C{5};
ar.model(m).data(d).logfitting(yindex) = C{6};
ar.model(m).data(d).logplotting(yindex) = C{6};
ar.model(m).data(d).fy(yindex,1) = C{7};
if(~isempty(cell2mat(C{8})))
ar.model(m).data(d).yNames(yindex) = C{8};
else
ar.model(m).data(d).yNames(yindex) = ar.model(m).data(d).y(yindex);
end
[C, fid] = arTextScan(fid, '%s %q %q %q %n %n %q %q\n',1, 'CommentStyle', ar.config.comment_string);
if(sum(ismember(ar.model(m).x, ar.model(m).data(d).y{yindex}))>0) %R2013a compatible
arParsingError( fid, '%s already defined in STATES', ar.model(m).data(d).y{yindex});
end
if(sum(ismember(ar.model(m).u, ar.model(m).data(d).y{end}))>0) %R2013a compatible
arParsingError( fid, '%s already defined in INPUTS', ar.model(m).data(d).y{end});
end
if(sum(ismember(ar.model(m).z, ar.model(m).data(d).y{end}))>0) %R2013a compatible
arParsingError( fid, '%s already defined in DERIVED', ar.model(m).data(d).y{end});
end
if(sum(ismember(ar.model(m).p, ar.model(m).data(d).y{end}))>0) %R2013a compatible
arParsingError( fid, '%s already defined as parameter', ar.model(m).data(d).y{end});
end
end
% observation parameters
arFprintf( 3, '[ OK ]\nComputing observation parameters...' );
varlist = cellfun(@symvar, ar.model(m).data(d).fy, 'UniformOutput', false);
ar.model(m).data(d).py = setdiff(setdiff(vertcat(varlist{:}), union(union(ar.model(m).x, ar.model(m).u), ar.model(m).z)), {ar.model(m).t, ''}); %R2013a compatible
if(isempty(ar.model(m).data(d).fy))
arParsingError( fid, 'No OBSERVABLE specified. Specify an OBSERVABLE in the model or data definition file. See "Defining the OBSERVABLES".');
end
for j=1:length(ar.model(m).data(d).fy)
varlist = symvar(ar.model(m).data(d).fy{j});
ar.model(m).data(d).py_sep(j).pars = setdiff(setdiff(varlist, union(union(ar.model(m).x, ar.model(m).u), ar.model(m).z)), {ar.model(m).t, ''}); %R2013a compatible
% exclude parameters form model definition
ar.model(m).data(d).py_sep(j).pars = setdiff(ar.model(m).data(d).py_sep(j).pars, ar.model(m).px);
ar.model(m).data(d).py_sep(j).pars = setdiff(ar.model(m).data(d).py_sep(j).pars, ar.model(m).pu);
end
% ERRORS
arFprintf( 3, '[ OK ]\nReading error models' );
if(isfield(ar.model(m),'y'))
ar.model(m).data(d).fystd = ar.model(m).fystd;
else
ar.model(m).data(d).fystd = cell(0);
end
[C, fid] = arTextScan(fid, '%s %q\n',1, 'CommentStyle', ar.config.comment_string);
while(~strcmp(C{1},'INVARIANTS') && ~strcmp(C{1},'DERIVED') && ~strcmp(C{1},'CONDITIONS') && ~strcmp(C{1},'SUBSTITUTIONS'))
arFprintf( 3, '.' );
qyindex = ismember(ar.model(m).data(d).y, C{1});
if ( qyindex == 0 )
arParsingError( fid, 'Specified error model for non existent observable %s', C{1}{1} );
end
y_var_name = setdiff(symvar(ar.model(m).data(d).fy{qyindex}),ar.model(m).data(d).py);
reg_string = ['((?<=\W)|^)(',C{1}{1},'|'];
for jreg = 1:length(y_var_name)
if(jreg<length(y_var_name))
reg_string = [reg_string ,y_var_name{jreg},'|'];
else
reg_string = [reg_string ,y_var_name{jreg},')'];
end
end
reg_string = [reg_string '((?=\W)|$)'];
if(~isempty(regexp(C{2}{1},reg_string,'ONCE')) && ar.model(m).data(d).logfitting(qyindex))
warning(['You are trying to set up a relative error model within a log transformation. \n%s' ...
'Comment out this error if you want to proceed anyway. To implement an absolute error in log, \n' ...
'you can try the approach: \nyObs = sd_yObs + 1/2 * (a+sqrt((a)^2)), a = (offset - yObs-sd_yObs) \n, with hard set or fitted offset (on log-scale) \n'],C{2}{1})
arParsingError( fid, 'Revise error model')
end
if(sum(qyindex)==1)
yindex = find(qyindex);
elseif(sum(qyindex)==0)
yindex = length(ar.model(m).data(d).y) + 1;
warning('Specified error without specifying observation function (%s in %s). Proceed with caution!', C{1}{1}, ar.model(m).data(d).name);
else
arParsingError( fid, 'multiple matches for %s', cell2mat(C{1}))
end
ar.model(m).data(d).fystd(yindex) = C{2};
[C, fid] = arTextScan(fid, '%s %q\n',1, 'CommentStyle', ar.config.comment_string);
if ( isempty( C{1} ) )
arParsingError( fid, 'Unexpected end of file after error model (did you forget CONDITIONS?)')
end
end
if(length(ar.model(m).data(d).fystd)<length(ar.model(m).data(d).fy))
arParsingError( fid, 'some observables do not have an error model defined');
end
% Drop certain observables
if (opts.removeobservables)
arFprintf( 3, '[ OK ]\nDropping specific observables...\n' );
if ischar( opts.removeobservables_args )
opts.removeobservables_args = {opts.removeobservables_args};
end
for a = 1 : length( opts.removeobservables_args )
jo = 1;
while( jo <= length( ar.model(m).data(d).y ) )
jind = ismember( ar.model(m).data(d).y{jo}, opts.removeobservables_args );
if ( sum(jind) > 0 )
warning( '>> Explicitly removing %s!\n', ar.model(m).data(d).y{jo} );
ar.model(m).data(d).y(jo) = [];
ar.model(m).data(d).yUnits(jo,:) = [];
ar.model(m).data(d).normalize(jo) = [];
ar.model(m).data(d).logfitting(jo) = [];
ar.model(m).data(d).logplotting(jo) = [];
ar.model(m).data(d).fy(jo) = [];
ar.model(m).data(d).yNames(jo) = [];
ar.model(m).data(d).fystd(jo) = [];
else
jo = jo + 1;
end
end
end
end
% error parameters
arFprintf( 3, 'Compute error parameters...' );
varlist = cellfun(@symvar, ar.model(m).data(d).fystd, 'UniformOutput', false);
ar.model(m).data(d).pystd = setdiff(vertcat(varlist{:}), union(union(union(union(ar.model(m).x, ar.model(m).u), ar.model(m).z), ... %R2013a compatible
ar.model(m).data(d).y), ar.model(m).t));
for j=1:length(ar.model(m).data(d).fystd)
varlist = symvar(ar.model(m).data(d).fystd{j});
ar.model(m).data(d).py_sep(j).pars = union(ar.model(m).data(d).py_sep(j).pars, ... %R2013a compatible
setdiff(varlist, union(union(union(ar.model(m).x, ar.model(m).u), ar.model(m).z), ar.model(m).data(d).y))); %R2013a compatible
% exclude parameters form model definition
ar.model(m).data(d).py_sep(j).pars = setdiff(ar.model(m).data(d).py_sep(j).pars, ar.model(m).px);
ar.model(m).data(d).py_sep(j).pars = setdiff(ar.model(m).data(d).py_sep(j).pars, ar.model(m).pu);
end
% DERIVED
if(strcmp(C{1},'DERIVED'))
arParsingError( fid, ['There is no need for a section DERIVED in data definition file! ' ...
'Please remove and see usage in: ' ...
'https://github.com/Data2Dynamics/d2d/wiki/Setting%20up%20models']);
end
% INVARIANTS
if(strcmp(C{1},'INVARIANTS'))
arParsingError( fid, ['Section INVARIANTS in data definition file is deprecated! ' ...
'Please remove and see usage in: ' ...
'https://github.com/Data2Dynamics/d2d/wiki/Setting%20up%20models']);
end
% collect parameters needed for OBS
ptmp = union(ar.model(m).px, ar.model(m).pu);
ar.model(m).data(d).p = union(ptmp, union(ar.model(m).data(d).pu, ar.model(m).data(d).py)); %R2013a compatible
ar.model(m).data(d).pystd = setdiff(ar.model(m).data(d).pystd, ar.model(m).data(d).p); %Remove dynamic variables from error model parameters, e.g. scaling parameters if sd propto scale*x.
ar.model(m).data(d).p = union(ar.model(m).data(d).p, ar.model(m).data(d).pystd); %R2013a compatible
% Union's behaviour is different when first arg is empty. In this case, a
% flip of the parameter vector is typically required.
if ( size( ar.model(m).data(d).p, 1 ) ~= 1 )
ar.model(m).data(d).p = ar.model(m).data(d).p.';
end
% replace filename
ar.model(m).data(d).p = strrep(ar.model(m).data(d).p, '_filename', ['_' ar.model(m).data(d).name]);
ar.model(m).data(d).fy = strrep(ar.model(m).data(d).fy, '_filename', ['_' ar.model(m).data(d).name]);
ar.model(m).data(d).py = strrep(ar.model(m).data(d).py, '_filename', ['_' ar.model(m).data(d).name]);
ar.model(m).data(d).fystd = strrep(ar.model(m).data(d).fystd, '_filename', ['_' ar.model(m).data(d).name]);
ar.model(m).data(d).pystd = strrep(ar.model(m).data(d).pystd, '_filename', ['_' ar.model(m).data(d).name]);
for j=1:length(ar.model(m).data(d).py_sep)
ar.model(m).data(d).py_sep(j).pars = strrep(ar.model(m).data(d).py_sep(j).pars, '_filename', ['_' ar.model(m).data(d).name]);
end
% SUBSTITUTIONS (beta)
substitutions = 0;
matVer = arVer;
if ( strcmp(C{1},'SUBSTITUTIONS') )
arFprintf( 3, '[ OK ]\nReading substitutions' );
if(str2double(matVer.Version)>=8.4)
[C, fid] = arTextScan(fid, '%s %q\n',1, 'CommentStyle', ar.config.comment_string);
else
[C, fid] = arTextScan(fid, '%s %q\n',1, 'CommentStyle', ar.config.comment_string, 'BufSize', 2^16);
end
% Substitutions
fromSubs = {};
toSubs = {};
ismodelpar = [];
% Fetch desired substitutions
while(~isempty(C{1}) && ~strcmp(C{1},'CONDITIONS'))
arFprintf( 3, '.' );
fromSubs(end+1) = C{1}; %#OK<AGROW>
toSubs(end+1) = C{2}; %#OK<AGROW>
ismodelpar(end+1) = sum(ismember(ar.model(m).p, C{1})); %#OK<AGROW>
if(str2double(matVer.Version)>=8.4)
[C, fid] = arTextScan(fid, '%s %q\n',1, 'CommentStyle', ar.config.comment_string);
else
[C, fid] = arTextScan(fid, '%s %q\n',1, 'CommentStyle', ar.config.comment_string, 'BufSize', 2^16-1);
end
end
if ( sum(ismodelpar) > 0 )
s = sprintf( '%s\n', fromSubs{ismodelpar>0} );
arParsingError( fid, 'Cannot substitute model parameters. These following parameters belong under CONDITIONS:\n%s', s );
end
% Perform selfsubstitutions
arFprintf( 3, '[ OK ]\nPerforming self substitutions...' );
if ( ~isempty(fromSubs) )
substitutions = 1;
toSubs = arSubsRepeated( toSubs, fromSubs, toSubs, str2double(matVer.Version) );
end
arFprintf( 3, '[ OK ]\n' );
end
% CONDITIONS
arFprintf( 3, 'Reading conditions' );
[C, fid] = arTextScan(fid, '%s %q\n',1, 'CommentStyle', ar.config.comment_string);
ar.model(m).data(d).fp = transpose(ar.model(m).data(d).p);
ptmp = ar.model(m).p;
qcondparamodel = ismember(ar.model(m).data(d).p, strrep(ptmp, '_filename', ['_' ar.model(m).data(d).name])); %R2013a compatible
qmodelparacond = ismember(strrep(ptmp, '_filename', ['_' ar.model(m).data(d).name]), ar.model(m).data(d).p); %R2013a compatible
ar.model(m).data(d).fp(qcondparamodel) = strrep(ar.model(m).fp(qmodelparacond), '_filename', ['_' ar.model(m).data(d).name]);
if ( substitutions == 1 )
% Substitution code path (beta)
from = {};
to = {};
ismodelpar = [];
% Fetch desired substitutions
while(~isempty(C{1}) && ~strcmp(C{1},'RANDOM'))
arFprintf( 3, '.' );
from(end+1) = C{1}; %#OK<AGROW>
to(end+1) = C{2}; %#OK<AGROW>
ismodelpar(end+1) = sum(ismember(ar.model(m).data(d).p, C{1})); %#OK<AGROW>
if(str2double(matVer.Version)>=8.4)
[C, fid] = arTextScan(fid, '%s %q\n',1, 'CommentStyle', ar.config.comment_string);
else
[C, fid] = arTextScan(fid, '%s %q\n',1, 'CommentStyle', ar.config.comment_string, 'BufSize', 2^16-1);
end
end
% Perform selfsubstitutions
to = arSubsRepeated( to, fromSubs, toSubs, str2double(matVer.Version) );
% Store substitutions in ar structure
for a = 1 : length( from )
qcondpara = ismember(ar.model(m).data(d).p, from{a}); %R2013a compatible
if(sum(qcondpara)>0)
ar.model(m).data(d).fp{qcondpara} = ['(' to{a} ')'];
else
warning('unknown parameter in conditions: %s (did you mean to place it under SUBSTITUTIONS?)', from{a}); %#ok<WNTAG>
end
end
else
% old code path
while(~isempty(C{1}) && ~strcmp(C{1},'RANDOM'))
arFprintf( 3, '.' );
qcondpara = ismember(ar.model(m).data(d).p, C{1}); %R2013a compatible
if(sum(qcondpara)>0)
ar.model(m).data(d).fp{qcondpara} = ['(' cell2mat(C{2}) ')'];
elseif(strcmp(cell2mat(C{1}),'PARAMETERS'))
else
warning('unknown parameter in conditions %s', cell2mat(C{1}));
end
[C, fid] = arTextScan(fid, '%s %q\n',1, 'CommentStyle', ar.config.comment_string);
end
end
% extra conditional parameters
varlist = cellfun(@symvar, ar.model(m).data(d).fp, 'UniformOutput', false);
ar.model(m).data(d).pcond = setdiff(vertcat(varlist{:}), ar.model(m).data(d).p); %R2013a compatible
% collect parameters conditions
pcond = union(ar.model(m).data(d).p, ar.model(m).data(d).pcond); %R2013a compatible
% RANDOM
arFprintf( 3, '[ OK ]\nReading randoms' );
if ~isempty( ar.model(m).prand )
ar.model(m).data(d).prand = ar.model(m).prand;
ar.model(m).data(d).rand_type = ar.model(m).rand_type;
else
ar.model(m).data(d).prand = {};
ar.model(m).data(d).rand_type = [];
end
[C, fid] = arTextScan(fid, '%s %s\n',1, 'CommentStyle', ar.config.comment_string);
while(~isempty(C{1}) && ~strcmp(C{1},'PARAMETERS'))
arFprintf( 3, '.' );
ar.model(m).data(d).prand{end+1} = cell2mat(C{1});
if(strcmp(C{2}, 'INDEPENDENT'))
ar.model(m).data(d).rand_type(end+1) = 0;
elseif(strcmp(C{2}, 'NORMAL'))
ar.model(m).data(d).rand_type(end+1) = 1;
else
warning('unknown random type %s', cell2mat(C{2})); %#ok<WNTAG>
end
[C, fid] = arTextScan(fid, '%s %s\n',1, 'CommentStyle', ar.config.comment_string);
end
if ( opts.expsplit )
ar.model(m).data(d).rand_type(end+1) = 0;
ar.model(m).data(d).prand{end+1} = opts.expsplit_args;
end
% PARAMETERS
arFprintf( 3, '[ OK ]\nReading parameters...' );
if(~isfield(ar, 'pExternLabels'))
ar.pExternLabels = {};
ar.pExtern = [];
ar.qFitExtern = [];
ar.qLog10Extern = [];
ar.lbExtern = [];
ar.ubExtern = [];
end
[C, fid] = arTextScan(fid, '%s %f %n %n %n %n\n',1, 'CommentStyle', ar.config.comment_string);
while(~isempty(C{1}))
% Why is this info stored at the level of ar? Then it is overwritten if
% the same info is in another data file!
ar.pExternLabels(end+1) = C{1};
ar.pExtern(end+1) = C{2};
ar.qFitExtern(end+1) = C{3};
ar.qLog10Extern(end+1) = C{4};
ar.lbExtern(end+1) = C{5};
ar.ubExtern(end+1) = C{6};
[C, fid] = arTextScan(fid, '%s %f %n %n %n %n\n',1, 'CommentStyle', ar.config.comment_string);
end
% plot setup
arFprintf( 3, '[ OK ]\nPlot setup...' );
if(isfield(ar.model(m).data(d), 'response_parameter') && ...
~isempty(ar.model(m).data(d).response_parameter))
if(sum(ismember(ar.model(m).data(d).p ,ar.model(m).data(d).response_parameter))==0 && ... %R2013a compatible
sum(ismember(ar.model(m).data(d).pcond ,ar.model(m).data(d).response_parameter))==0) %R2013a compatible
arParsingError( fid, 'invalid response parameter %s', ar.model(m).data(d).response_parameter);
end
end
if(~isfield(ar.model(m), 'plot'))
ar.model(m).plot(1).name = strrep(strrep(strrep(strrep(name,'=','_'),'.',''),'-','_'),'/','_');
else
ar.model(m).plot(end+1).name = strrep(strrep(strrep(strrep(name,'=','_'),'.',''),'-','_'),'/','_');
end
ar.model(m).plot(end).doseresponse = ar.model(m).data(d).doseresponse;
ar.model(m).plot(end).doseresponselog10xaxis = true;
ar.model(m).plot(end).dLink = d;
ar.model(m).plot(end).ny = length(ar.model(m).data(d).y);
ar.model(m).plot(end).condition = {};
jplot = length(ar.model(m).plot);
if ( ~isstruct( fid ) )
fclose(fid);
end
% XLS file
arFprintf( 3, 'Read def file [ OK ]\n' );
if(~strcmp(extension,'none') && ( ...
(exist([DataPath, name '.xlsx'],'file') && strcmp(extension,'xlsx')) ||...
(exist([DataPath, name '.xls'],'file') && strcmp(extension,'xls')) || ...
(exist([DataPath, name '.csv'],'file') && strcmp(extension,'csv'))))
arFprintf(2, 'loading data #%i, from file %s%s.%s...\n', d, DataPath, name, extension);
dataFound = true;
% read from file
if(contains(extension, 'xls'))
warntmp = warning;
warning('off','all')
arFprintf( 3, '[ OK ]\nBegin reading data (xls) ...' );
try
[data, Cstr] = xlsread([DataPath name '.' extension]);
catch
% especially on linux and mac there can be some encoding
% problems that deprecated function 'xlsread' cannot handle.
% use 'readtable' function instead and mimic excpected output
% 'data' is arrays of all numeric values
% 'Cstr' is cell of all strings
dataTable = readtable([DataPath name '.' extension]);
textColumns = arrayfun(@(col) iscell(dataTable{:, col}), 1:width(dataTable));
Cstr = dataTable.Properties.VariableNames;
if any(textColumns)
% create cell array of all text cells in the excel file
Cstr = [Cstr; repmat({''}, size(dataTable))];
Cstr(2:end, textColumns) = dataTable{:, textColumns};
% replace all the text fields by NaN for the data array
for col=1:width(dataTable)
if textColumns(col)
colName = dataTable.Properties.VariableNames{col};
dataTable.(colName) = NaN(height(dataTable), 1);
end
end
end
data = table2array(dataTable);
end
arFprintf( 3, '[ OK ]\n' );
if(length(data(1,:))>length(Cstr(1,:)))
data = data(:,1:length(Cstr(1,:)));
end
warning(warntmp);
timevar = Cstr(1,1);
header = Cstr(1,2:end);
header = strrep(header,' ',''); % remove spaces which are sometimes in the column header by accident
times = data(:,1);
qtimesnonnan = ~isnan(times);
times = times(qtimesnonnan);
data = data(qtimesnonnan,2:end);
if(size(data,2)<length(header))
data = [data nan(size(data,1),length(header)-size(data,2))];
end
Cstr = Cstr(2:end,2:end);
dataCell = cell(size(data));
for j1 = 1:size(data,1)
for j2 = 1:size(data,2)
if(isnan(data(j1,j2)))
if(j1<=size(Cstr,1) && j2<=size(Cstr,2) && ~isempty(Cstr{j1,j2}))
dataCell{j1,j2} = Cstr{j1,j2};
else
dataCell{j1,j2} = header{j2};
end
else
dataCell{j1,j2} = num2str(data(j1,j2));
end
end
end
elseif(strcmp(extension,'csv'))
arFprintf( 3, '[ OK ]\nBegin reading data (csv) ...' );
if ~exist('Delimiter','var')
[header, data, dataCell] = arReadCSVHeaderFile([DataPath, name '.csv'], ',', true);
else
[header, data, dataCell] = arReadCSVHeaderFile([DataPath, name '.csv'], Delimiter, true);
end
arFprintf( 3, '[ OK ]\n' );
timevar = strtrim(header(1));
header = header(2:end);
times = data(:,1);
data = data(:,2:end);
dataCell = dataCell(:,2:end);
end
% remove time points that we don't want
if ( opts.removeconditions )
arFprintf( 3, 'Removing undesired time points...' );
selected = true(1, size(times,1));
if ( opts.removeconditions )
for a = 1 : 2 : length( opts.removeconditions_args )
if ( strcmp( timevar, opts.removeconditions_args{a} ) )
% If the argument is a function handle, we evaluate them
% for each element
val = opts.removeconditions_args{a+1};
if ( isa(val, 'function_handle') )
for jv = 1 : length( times )
accepted(jv) = val(num2str(times(jv)));
end
else
arParsingError( fid, 'Filter argument for removecondition is of the wrong type' );
end
selected = selected & ~accepted;
end
end
end
times = times(selected);
data = data(selected,:);
dataCell = dataCell(selected,:);
end
% random effects
arFprintf( 3, 'Processing random effects...' );
prand = ar.model(m).data(d).prand;
if(opts.splitconditions)
prand = union(prand, opts.splitconditions_args);
end
qrandis = ismember(header, prand); %R2013a compatible
if(sum(qrandis) > 0)
qobs = ismember(header, ar.model(m).data(d).y); %R2013a compatible
randis_header = header(qrandis);
qrandis_header_nosplit = ismember(randis_header, ar.model(m).data(d).prand);
if ~isempty(dataCell)
[randis, ~, jrandis] = uniqueRowsCA(dataCell(:,qrandis));
else
[randis, ~, jrandis] = unique(data(:,qrandis),'rows');
randis = cellstr(num2str(randis));
end
for j=1:size(randis,1)
qvals = jrandis == j;
tmpdata = data(qvals,qobs);
if(sum(~isnan(tmpdata(:)))>0 || ~removeEmptyObs)
arFprintf(2, 'local random effect #%i:\n', j)
if(j < size(randis,1))
ar.model(m).data(d+1) = ar.model(m).data(d);
ar.model(m).plot(jplot+1) = ar.model(m).plot(jplot);
end
pcondmod = pcond;
for jj=1:size(randis,2)
if(qrandis_header_nosplit(jj))
arFprintf(2, '\t%20s = %s\n', randis_header{jj}, randis{j,jj})
ar.model(m).plot(jplot).name = [ar.model(m).plot(jplot).name '_' ...
randis_header{jj} randis{j,jj}];
ar.model(m).data(d).name = [ar.model(m).data(d).name '_' ...
randis_header{jj} randis{j,jj}];
ar.model(m).data(d).fprand = randis{j,jj};
ar.model(m).data(d).fy = strrep(ar.model(m).data(d).fy, ...
randis_header{jj}, [randis_header{jj} randis{j,jj}]);
ar.model(m).data(d).py = strrep(ar.model(m).data(d).py, ...
randis_header{jj}, [randis_header{jj} randis{j,jj}]);
ar.model(m).data(d).fystd = strrep(ar.model(m).data(d).fystd, ...
randis_header{jj}, [randis_header{jj} randis{j,jj}]);
ar.model(m).data(d).pystd = strrep(ar.model(m).data(d).pystd, ...
randis_header{jj}, [randis_header{jj} randis{j,jj}]);
% ar.model(m).data(d).p = strrep(ar.model(m).data(d).p, ...
% randis_header{jj}, [randis_header{jj} randis{j,jj}]);
ar.model(m).data(d).fp = strrep(ar.model(m).data(d).fp, ...
randis_header{jj}, [randis_header{jj} randis{j,jj}]);
ar.model(m).data(d).pcond = strrep(ar.model(m).data(d).pcond, ...
randis_header{jj}, [randis_header{jj} randis{j,jj}]);
for jjj=1:length(ar.model(m).data(d).py_sep)
ar.model(m).data(d).py_sep(jjj).pars = strrep(ar.model(m).data(d).py_sep(jjj).pars, ...
randis_header{jj}, [randis_header{jj} randis{j,jj}]);
end
pcondmod = strrep(pcondmod, randis_header{jj}, [randis_header{jj} randis{j,jj}]);
else
arFprintf(2, '\t%20s (split only)\n', randis_header{jj})
ar.model(m).plot(jplot).name = [ar.model(m).plot(jplot).name '_' ...
randis_header{jj} randis{j,jj}];
end
end
arFprintf( 4, 'Setting conditions ...\n' );
if ~isempty(dataCell)
[ar,d,fail] = setConditions(fid, ar, m, d, jplot, header, times(qvals), data(qvals,:), dataCell(qvals,:), ...
pcondmod, removeEmptyObs, dpPerShoot, opts);
else
[ar,d,fail] = setConditions(fid, ar, m, d, jplot, header, times(qvals), data(qvals,:), dataCell, ...
pcondmod, removeEmptyObs, dpPerShoot, opts);
end
arFprintf( 4, 'Condition set ... [ OK ]\n' );
% Only increment if some data was actually set.
if (~fail)
if(j < size(randis,1))
d = d + 1;
jplot = jplot + 1;
ar.model(m).plot(jplot).dLink = d;
end
% Check whether the user specified any variables with reserved words.
checkReserved(m, d);
else
% Remove file which failed to provide any data
fprintf(2, 'local random effect #%i: no matching data (%d), removed\n', j ,d);
ar.model.data(d) = [];
ar.model(m).plot(jplot) = [];
end
else
arFprintf(2, 'local random effect #%i: no matching data, skipped\n', j);
end
end
else
arFprintf( 4, 'Setting conditions ...\n' );
ar = setConditions(fid, ar, m, d, jplot, header, times, data, dataCell, pcond, removeEmptyObs, dpPerShoot, opts);
arFprintf( 4, 'Condition set ... [ OK ]\n' );
% Check whether the user specified any variables with reserved words.
checkReserved(m, d);
end
else
dataFound = false;
warning('Cannot find data file corresponding to %s', name);
ar.model(m).data(d).condition = [];
end
% remember the function call
ar.setup.commands{end+1} = mfilename; % this file name
ar.setup.arguments{end+1} = {name,m,extension, removeEmptyObs, varargin{:}}; %
if dataFound
ar.setup.datafiles{end+1} = {[DataPath,name,'.def'],[DataPath,name,'.',extension]};
else
ar.setup.datafiles{end+1} = {[DataPath,name,'.def'],''};
end
ar.setup.modelfiles{end+1} = '';
% sort fields
ar = orderfields(ar);
ar.model = orderfields(ar.model);
ar.model(m).data = orderfields(ar.model(m).data);
ar.model(m).plot = orderfields(ar.model(m).plot);
function checkReserved(m, d)
global ar;
% Check whether the user specified any variables with reserved words.
for a = 1 : length( ar.model(m).data(d).fu )
arCheckReservedWords( symvar(ar.model(m).data(d).fu{a}), sprintf( 'input function of %s', ar.model(m).data(d).name ), ar.model(m).u{a} );
end
for a = 1 : length( ar.model(m).data(d).fy )
arCheckReservedWords( symvar(ar.model(m).data(d).fy{a}), sprintf( 'observation function of %s', ar.model(m).data(d).name ), ar.model(m).data(d).y{a} );
end
for a = 1 : length( ar.model(m).data(d).fystd )
arCheckReservedWords( symvar(ar.model(m).data(d).fystd{a}), sprintf( 'observation standard deviation function of %s', ar.model(m).data(d).name ), ar.model(m).data(d).y{a} );
end
for a = 1 : length( ar.model(m).data(d).fp )
arCheckReservedWords( symvar(ar.model(m).data(d).fp{a}), sprintf( 'condition parameter transformations of %s', ar.model(m).data(d).name ), ar.model(m).data(d).p{a} );
end
arCheckReservedWords( ar.model(m).data(d).p, 'parameters' );
arCheckReservedWords( ar.model(m).data(d).y, 'observable names' );
function [ar,d, fail] = setConditions(fid, ar, m, d, jplot, header, times, data, dataCell, pcond, removeEmptyObs, dpPerShoot, opts)
% matVer = arVer;
% normalization of columns
fail = 0;
nfactor = max(data, [], 1);
qobs = ismember(header, ar.model(m).data(d).y) & sum(~isnan(data),1)>0; %R2013a compatible
qhasdata = ismember(ar.model(m).data(d).y, header(qobs)); %R2013a compatible
% conditions
if (~opts.removeconditions)
qcond = ismember(header, pcond); %R2013a compatible
else
% Add the condi's we force filtering over (override)
qcond = ismember(header, pcond) | ismember(header, opts.removeconditions_args(1:2:end)); %R2013a compatible
end
% Refine dose responses if requested
if ( opts.resampledoseresponse )
resolution = opts.resamplingresolution;
if ( ar.model(m).data(d).doseresponse == true )
responsePar = ismember( header, ar.model(m).data(d).response_parameter );
if ( sum( responsePar ) )
fprintf( ' => Refining dose response for %s\n', ar.model(m).data(d).response_parameter );
if ( sum( responsePar ) > 1 )
arParsingError( fid, 'Response parameter ambiguous during dose response refinement' );
end
% Which columns define the conditions
conds = qcond & ~responsePar;
% Grab unique conditions (note the inclusion of time)
[uniqueCondi, ~, ib] = unique( [times data( :, qcond & ~responsePar ) ], 'rows' );
nConditions = size(uniqueCondi, 1);
% For each unique condition determine the maximum and minimum value
% of the response parameter
extraData = NaN(nConditions*resolution, size(data,2));
extraTimes = NaN(nConditions*resolution, 1);
for jui = 1 : size( uniqueCondi, 1 )
dataChunk = data( ib == jui, responsePar );
mi = min( dataChunk );
ma = max( dataChunk );
extraPoints = mi : (ma-mi)/(resolution-1) : ma;
if ( opts.refinelog )
mi = log10( max( [mi, 1e-8] ) );
ma = log10( max( [ma, 1e-8] ) );
extraPoints = 10.^(mi : (ma-mi)/(resolution-1) : ma);
end
% Fix to make sure the length is correct for the next
% assignment. This is ok, since the unique will remove
% these points again at a later stage.
if ( mi == ma )
extraPoints = repmat( mi, 1, resolution );
end
% Fill extra data with current condition
condition = uniqueCondi(jui,:);
extraData((jui-1)*resolution+1:jui*resolution, conds) = repmat(condition(2:end), resolution, 1);
extraTimes((jui-1)*resolution+1:jui*resolution) = repmat(condition(1), resolution, 1);
% Fill the dependent variable with the new dependent variable values
extraData((jui-1)*resolution+1:jui*resolution, responsePar) = extraPoints;
end
end
data = [ data ; extraData ];
dataCell = [ dataCell; cellfun(@num2str,num2cell(extraData), 'UniformOutput', false) ];
times = [ times ; extraTimes ];
end
end
if(sum(qcond) > 0)
condi_header = header(qcond);
if ~isempty(dataCell)
[condis, ind, jcondis] = uniqueRowsCA(dataCell(:,qcond));
else
[condis, ind, jcondis] = unique(data(:,qcond),'rows');
condis = mymat2cell(condis);
end
if (opts.removeconditions || opts.removeemptyconds)
selected = true(1, size(condis,1));
if ( opts.removeconditions )
for a = 1 : 2 : length( opts.removeconditions_args )
cc = ismember( condi_header, opts.removeconditions_args{a} );
if ( sum( cc ) > 0 )
values = condis(:,cc);
% If the argument is a function handle, we evaluate them
% for each element
val = opts.removeconditions_args{a+1};
if ( isa(val, 'function_handle') )
for jv = 1 : length( values )
accepted(jv) = val(values{jv});
end
else
if (isnumeric(val))
val = num2str(val);
end
if ~ischar(val)
arParsingError( fid, 'Filter argument for removecondition is of the wrong type' );
end
accepted = ismember(values, val).';
end
selected = selected & ~accepted;
end
end
end
if(opts.removeemptyconds)
% Find out for which conditions we actually have data
hasD = max(~isnan(data(ind,qobs)), [], 2);
selected(hasD==0) = false;
end
condis = condis(selected,:);
% Recompute jcondi's (list which points which data row corresponds
% to which condition.
mapTo = cumsum(selected);
mapTo(~selected) = -1;
jcondis = mapTo(jcondis);
end
% exit if no data left
if(size(condis,1)==0)
fail = 1;
return
end
active_condi = false(size(condis(1,:)));
tmpcondi = condis(1,:);
for j1=2:size(condis,1)
for j2=1:size(condis,2)
active_condi(j2) = active_condi(j2) | (~strcmp(tmpcondi{j2}, condis{j1,j2}));
end
end
for j=1:size(condis,1)
arFprintf(2, 'local condition #%i:\n', j)
if(j < size(condis,1))
if(length(ar.model(m).data) > d)
ar.model(m).data(d+2) = ar.model(m).data(d+1);
end
ar.model(m).data(d+1) = ar.model(m).data(d);
end
% remove obs without data
if(removeEmptyObs)
for jj=find(~qhasdata)
arFprintf(2, '\t%20s no data, removed\n', ar.model(m).data(d).y{jj});
jjjs = find(ismember(ar.model(m).data(d).p, ar.model(m).data(d).py_sep(jj).pars)); %R2013a compatible
jjjs = jjjs(:)';
for jjj=jjjs
remove = 1;
for jjjj = find(qhasdata)
if sum(ismember(ar.model(m).data(d).py_sep(jjjj).pars, ar.model(m).data(d).p(jjj))) > 0 %R2013a compatible
remove = 0;
end
end
if remove
ar.model(m).data(d).fp{jjj} = '0';
end
end
end
ar.model(m).data(d).y = ar.model(m).data(d).y(qhasdata);
ar.model(m).data(d).yNames = ar.model(m).data(d).yNames(qhasdata);
ar.model(m).data(d).yUnits = ar.model(m).data(d).yUnits(qhasdata,:);
ar.model(m).data(d).normalize = ar.model(m).data(d).normalize(qhasdata);
ar.model(m).data(d).logfitting = ar.model(m).data(d).logfitting(qhasdata);
ar.model(m).data(d).logplotting = ar.model(m).data(d).logplotting(qhasdata);
ar.model(m).data(d).fy = ar.model(m).data(d).fy(qhasdata);
ar.model(m).data(d).fystd = ar.model(m).data(d).fystd(qhasdata);
ar.model(m).data(d).py_sep = ar.model(m).data(d).py_sep(qhasdata);
end
for jj=1:size(condis,2)
if(~isempty(condis{j,jj}))
arFprintf(2, '\t%20s = %s\n', condi_header{jj}, condis{j,jj})
qcondjj = ismember(ar.model(m).data(d).p, condi_header{jj}); %R2013a compatible
if(sum(qcondjj)>0)
ar.model(m).data(d).fp{qcondjj} = ['(' condis{j,jj} ')'];
end
qcondjj = ~strcmp(ar.model(m).data(d).p, ar.model(m).data(d).fp');
if(~isnan(str2double(condis{j,jj})))
% ar.model(m).data(d).fp(qcondjj) = strrep(ar.model(m).data(d).fp(qcondjj), ...
% condi_header{jj}, condis{j,jj});
ar.model(m).data(d).fp(qcondjj) = regexprep(ar.model(m).data(d).fp(qcondjj),...
sprintf('\\<%s\\>', condi_header{jj}),condis{j,jj});
% tmpfp = subs(sym(ar.model(m).data(d).fp(qcondjj)), ...
% sym(condi_header{jj}), sym(condis{j,jj}));
% jps = find(qcondjj);
% for jp = 1:length(jps)
% ar.model(m).data(d).fp{jps(jp)} = char(tmpfp(jp));
% end
end
ar.model(m).data(d).condition(jj).parameter = condi_header{jj};
ar.model(m).data(d).condition(jj).value = condis{j,jj};
% plot
if(active_condi(jj))
if(ar.model(m).data(d).doseresponse==0 || ~strcmp(condi_header{jj}, ar.model(m).data(d).response_parameter))
if(length(ar.model(m).plot(jplot).condition) >= j && ~isempty(ar.model(m).plot(jplot).condition{j}))
ar.model(m).plot(jplot).condition{j} = [ar.model(m).plot(jplot).condition{j} ' & ' ...
ar.model(m).data(d).condition(jj).parameter '=' ...
ar.model(m).data(d).condition(jj).value];
else
ar.model(m).plot(jplot).condition{j} = [ar.model(m).data(d).condition(jj).parameter '=' ...
ar.model(m).data(d).condition(jj).value];
end
end
end
end
end
qvals = jcondis == j;
ar = setValues(fid, ar, m, d, header, nfactor, data(qvals,:), times(qvals));
ar.model(m).data(d).tLim(2) = round(max(times)*1.1);
if(dpPerShoot~=0)
[ar,d] = doMS(ar,m,d,jplot,dpPerShoot);
end
if(j < size(condis,1))
d = d + 1;
ar.model(m).plot(jplot).dLink(end+1) = d;
end
end
else
ar.model(m).data(d).condition = [];
% remove obs without data
if(removeEmptyObs)
for jj=find(~qhasdata)
arFprintf(2, '\t%20s no data, removed\n', ar.model(m).data(d).y{jj});
jjjs = find(ismember(ar.model(m).data(d).p, ar.model(m).data(d).py_sep(jj).pars)); %R2013a compatible
jjjs = jjjs(:)';
for jjj=jjjs
remove = 1;
for jjjj = find(qhasdata)
if sum(ismember(ar.model(m).data(d).py_sep(jjjj).pars, ar.model(m).data(d).p(jjj))) > 0 %R2013a compatible
remove = 0;
end
end
if(remove==1)
ar.model(m).data(d).fp{jjj} = '0';
end
end
end
ar.model(m).data(d).y = ar.model(m).data(d).y(qhasdata);
ar.model(m).data(d).yNames = ar.model(m).data(d).yNames(qhasdata);
ar.model(m).data(d).yUnits = ar.model(m).data(d).yUnits(qhasdata,:);
ar.model(m).data(d).normalize = ar.model(m).data(d).normalize(qhasdata);
ar.model(m).data(d).logfitting = ar.model(m).data(d).logfitting(qhasdata);
ar.model(m).data(d).logplotting = ar.model(m).data(d).logplotting(qhasdata);
ar.model(m).data(d).fy = ar.model(m).data(d).fy(qhasdata);
ar.model(m).data(d).fystd = ar.model(m).data(d).fystd(qhasdata);
ar.model(m).data(d).py_sep = ar.model(m).data(d).py_sep(qhasdata);
end
ar = setValues(fid, ar, m, d, header, nfactor, data, times);
ar.model(m).data(d).tLim(2) = round(max(times)*1.1);
if(dpPerShoot~=0)
[ar,d] = doMS(ar,m,d,jplot,dpPerShoot);
end
end
function C = mymat2cell(D)
C = cell(size(D));
for j=1:size(D,1)
for jj=1:size(D,2)
C{j,jj} = num2str(D(j,jj));
end
end
function [ar,d] = doMS(ar,m,d,jplot,dpPerShoot)
tExp = ar.model(m).data(d).tExp;
if(dpPerShoot ~= 1)
nints = ceil(length(tExp) / dpPerShoot);
tboarders = linspace(min(tExp),max(tExp),nints+1);
else
tboarders = union(0,tExp); %R2013a compatible
nints = length(tboarders)-1;
end
if(nints==1)
return;
end
arFprintf(2, 'using %i shooting intervals\n', nints);
ar.model(m).ms_count = ar.model(m).ms_count + 1;
ar.model(m).data(d).ms_index = ar.model(m).ms_count;
for j=1:nints
ar.model(m).data(d).ms_snip_index = j;
if(j<nints)
ar.model(m).data(end+1) = ar.model(m).data(d);
ar.model(m).plot(jplot).dLink(end+1) = d+1;
end
if(j>1)
ar.ms_count_snips = ar.ms_count_snips + 1;
qtodo = ismember(ar.model(m).data(d).p, ar.model(m).px0); %R2013a compatible
ar.model(m).data(d).fp(qtodo) = strrep(ar.model(m).data(d).p(qtodo), 'init_', sprintf('init_MS%i_', ar.ms_count_snips));
end
if(j<nints)
ar.model(m).data(d).tExp = ar.model(m).data(d).tExp(tExp>=tboarders(j) & tExp<tboarders(j+1));
ar.model(m).data(d).yExp = ar.model(m).data(d).yExp(tExp>=tboarders(j) & tExp<tboarders(j+1),:);
ar.model(m).data(d).yExpStd = ar.model(m).data(d).yExpStd(tExp>=tboarders(j) & tExp<tboarders(j+1),:);
else
ar.model(m).data(d).tExp = ar.model(m).data(d).tExp(tExp>=tboarders(j) & tExp<=tboarders(j+1));
ar.model(m).data(d).yExp = ar.model(m).data(d).yExp(tExp>=tboarders(j) & tExp<=tboarders(j+1),:);
ar.model(m).data(d).yExpStd = ar.model(m).data(d).yExpStd(tExp>=tboarders(j) & tExp<=tboarders(j+1),:);
end
ar.model(m).data(d).tLim = [tboarders(j) tboarders(j+1)];
ar.model(m).data(d).tLimExp = ar.model(m).data(d).tLim;
if(j<nints)
d = d + 1;
end
end
function ar = setValues(fid, ar, m, d, header, nfactor, data, times)
ar.model(m).data(d).tExp = times;
ar.model(m).data(d).yExp = nan(length(times), length(ar.model(m).data(d).y));
ar.model(m).data(d).yExpStd = nan(length(times), length(ar.model(m).data(d).y));
ar.model(m).data(d).yExpRaw = nan(length(times), length(ar.model(m).data(d).y));
ar.model(m).data(d).yExpStdRaw = nan(length(times), length(ar.model(m).data(d).y));
for j=1:length(ar.model(m).data(d).y)
q = ismember(header, ar.model(m).data(d).y{j}); %R2013a compatible
if(sum(q)==1)
ar.model(m).data(d).yExp(:,j) = data(:,q);
ar.model(m).data(d).yExpRaw(:,j) = data(:,q);
arFprintf(2, '\t%20s -> %4i data-points assigned', ar.model(m).data(d).y{j}, sum(~isnan(data(:,q))));
% normalize data
if(ar.model(m).data(d).normalize(j))
ar.model(m).data(d).yExp(:,j) = ar.model(m).data(d).yExp(:,j) / nfactor(q);
arFprintf(2, ' normalized');
end
% log-fitting
if(ar.model(m).data(d).logfitting(j))
qdatapos = ar.model(m).data(d).yExp(:,j)>0;
nancount = sum(isnan(ar.model(m).data(d).yExp(:,j)));
ar.model(m).data(d).yExp(qdatapos,j) = log10(ar.model(m).data(d).yExp(qdatapos,j));
ar.model(m).data(d).yExp(~qdatapos,j) = nan;
if(sum(~qdatapos)==0)
arFprintf(2, ' for log-fitting');
else
arFprintf(2, ' for log-fitting (%i values <=0 removed, %i NaN values removed)', sum(~qdatapos)-nancount, nancount);
end
end
% empirical stds
qstd = ismember(header, [ar.model(m).data(d).y{j} '_std']); %R2013a compatible
if(sum(qstd)==1)
ar.model(m).data(d).yExpStdRaw(:,j) = data(:,qstd);
ar.model(m).data(d).yExpStd(:,j) = data(:,qstd);
arFprintf(2, ' with stds');
if(ar.model(m).data(d).normalize(j))
ar.model(m).data(d).yExpStd(:,j) = ar.model(m).data(d).yExpStd(:,j) / nfactor(q);
arFprintf(2, ' normalized');
end
elseif(sum(qstd)>1)
arParsingError( fid, 'multiple std colums for observable %s', ar.model(m).data(d).y{j})
end
elseif(sum(q)==0)
arFprintf(2, '*\t%20s -> not assigned', ar.model(m).data(d).y{j});
else
arParsingError( fid, 'multiple data colums for observable %s', ar.model(m).data(d).y{j})
end
arFprintf(1, '\n');
end
function num = checkNum( num, defaultValue )
if ( ~isnumeric( num ) || isempty( num ) || isnan( num ) )
num = defaultValue;
end
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...