function data = dsModifications2Vary(data,modifications,options,modifications_set,sim)
% Adds fields tmpdata.varied and tmpdata.(varied{1}) ...
% tmpdata.varied({N}) to tmpdata. This contains information about
% parameters varied across each sim.
%
% Usage:
% data = modifications2Vary(data,modifications)
% data = modifications2Vary(data,modifications,options)
% data = modifications2Vary(data,modifications,options,modifications_set,sim)
%
% Inputs:
% data: DynaSim data structure
% modifications: modifications to make to specification structure
% {X,Y,Z; X,Y,Z; ...}
% X = population name or connection source->target
% Y = thing to modify ('name', 'size', or parameter name)
% set Y=Z if Y = name, size, or value
% Note: (X1,X2) or (Y1,Y2): modify these simultaneously in the same way
% Note: modifications is often found in options.modifications
%
%
% Inputs (Optional):
% options : Options structure containing experiment
% fields (see dsSimulate)
% modifications_set : Additional modifications, produced by
% dsVary2Modifications(options.vary,model);
% sim : simulation number
%
% Outputs:
% data: DynaSim data structure
%
% Examples:
% tmpdata = dsModifications2Vary(tmpdata,options.modifications,options,modifications_set,sim);
% tmp_data = dsModifications2Vary(tmp_data,modifications);
%
%
% Author: Dave Stanley; based on prepare_varied_metadata by ??? (Jason
% Sherfey?); Boston University; 2017
%
% See also: dsVary2Modifications
% add things varied to tmpdata
mods={};
if ~isempty(modifications)
mods=cat(1,mods,expand_modifications(modifications));
end
if nargin > 3
if ~isempty(modifications_set{sim})
tmp_mods=expand_modifications(modifications_set{sim});
mods=cat(1,mods,tmp_mods);
end
end
if nargin > 2
if isa(options.experiment,'function_handle')
for j=1:length(data)
data(j).simulator_options.modifications=mods;
end
end
end
if ~isempty(mods)
if isfield(data,'varied')
varied=data(1).varied;
else
varied={};
end
for ii=1:size(mods,1)
% prepare valid field name for thing varied:
fld=[mods{ii,1} '_' mods{ii,2}];
% convert arrows and periods to underscores
fld=regexprep(fld,'(->)|(<-)|(-)|(\.)','_');
% replace initial condition parens with underscores
fld = strrep(fld, '(0)','_0_');
% remove brackets and parentheses
fld=regexprep(fld,'[\[\]\(\)\{\}]','');
% remove spaces
fld=regexprep(fld,'[\ ]','');
for j=1:length(data)
data(j).(fld)=mods{ii,3};
end
if ~ismember(fld,varied)
varied{end+1}=fld;
end
end
for j=1:length(data)
data(j).varied=varied;
end
end
end
function modifications=expand_modifications(mods)
% purpose: expand simultaneous modifications into larger list
modifications={};
for i=1:size(mods,1)
% temp replace initial condition string for regexp
mods{i,2} = strrep(mods{i,2}, '(0)','__0__');
% get object list without grouping symbols: ()[]{}
objects=regexp(mods{i,1},'[^\(\)\[\]\{\},]+','match');
variables=regexp(mods{i,2},'[^\(\)\[\]\{\},]+','match');
for j=1:length(objects)
for k=1:length(variables)
thisMod = mods{i,3};
% replace original initial condition string
variables{k} = strrep(variables{k},'__0__','(0)');
if all(size(thisMod) == [1,1]) %same val for each obj and var
modifications(end+1,1:3)={objects{j},variables{k},thisMod};
elseif (size(thisMod,1) > 1) && (size(thisMod,2) == 1) %same val for each obj, diff for each var
modifications(end+1,1:3)={objects{j},variables{k},thisMod(k)};
elseif (size(thisMod,1) == 1) && (size(thisMod,2) > 1) %same val for each var, diff for each obj
modifications(end+1,1:3)={objects{j},variables{k},thisMod(j)};
elseif (size(thisMod,1) > 1) && (size(thisMod,2) > 1) %diff val for each var and obj
modifications(end+1,1:3)={objects{j},variables{k},thisMod(k,j)};
else
error('Unknown modification type (likely due to excess dims)')
end %if
end %k
end %j
end %i
end %fun