Home > functions > dsAnalyze.m

dsAnalyze

PURPOSE ^

DSANALYZE - Apply an analysis function to DynaSim data, optionally saving data

SYNOPSIS ^

function result = dsAnalyze(src,funcIn,varargin)

DESCRIPTION ^

DSANALYZE - Apply an analysis function to DynaSim data, optionally saving data

 Pass a single DynaSim data structure or an array of data structures to a
 user-specified analysis function, add varied info to the results and
 optionally save the output structure.

 Usage:
   result = AnalyzeData(data,func,'option1',value1,...) % pass data or datafile name
   result = AnalyzeData(studyinfo,func,'option1',value1,...) % pass studyinfo struct
   result = AnalyzeData(study_dir,func,'option1',value1,...) % pass study_dir containing studyinfo.mat

 Inputs:
   - First input/argument:
     - data: DynaSim data structure or data file path (s)
     - studyinfo: DynaSim studyinfo structure or path to studyinfo
     - study_dir: DynaSim study directory containing studyinfo.mat
   - func: function handle or cell array of function handles pointing to plot
           or analysis function(s). Should not contain case-insensitive string
           'plot' unless is a function that returns a figure handle for plotting.
   - options: (key/value pairs are passed on to the analysis function)
     'save_results_flag'   : whether to save result {0 or 1} (default: 0)
     'result_file'         : where to save result (default: 'result.mat')
     'format'              : format for saved plots if figures are generated
                             {'svg','jpg','eps','png'} (default: 'svg')
     'varied_filename_flag': whether to make filename based on the varied
                             parameters and type of plot {0 or 1} (default: 0)
     'function_options'    : cell array of option cell arrays {'option1',value1,...}
                             in which each cell corresponds to the options for
                             the corresponding function cell. if only passing a
                             single func, can specificy function options as
                             key,val list as varargin for AnalyzeData
     'load_all_data_flag'  : whether to load all the data in studyinfo
                             at once {0 or 1} (default: 0)
     'parallel_flag' : whether to use parfor to run analysis {0 or 1} (default: 0)

 Outputs:
   - result: structure returned by the analysis function

 TODO: annotate figures with data set-specific modifications


 See also: dsSimulate

 Author: Jason Sherfey, PhD <jssherfey@gmail.com>
 Copyright (C) 2016 Jason Sherfey, Boston University, USA

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function result = dsAnalyze(src,funcIn,varargin)
0002 %DSANALYZE - Apply an analysis function to DynaSim data, optionally saving data
0003 %
0004 % Pass a single DynaSim data structure or an array of data structures to a
0005 % user-specified analysis function, add varied info to the results and
0006 % optionally save the output structure.
0007 %
0008 % Usage:
0009 %   result = AnalyzeData(data,func,'option1',value1,...) % pass data or datafile name
0010 %   result = AnalyzeData(studyinfo,func,'option1',value1,...) % pass studyinfo struct
0011 %   result = AnalyzeData(study_dir,func,'option1',value1,...) % pass study_dir containing studyinfo.mat
0012 %
0013 % Inputs:
0014 %   - First input/argument:
0015 %     - data: DynaSim data structure or data file path (s)
0016 %     - studyinfo: DynaSim studyinfo structure or path to studyinfo
0017 %     - study_dir: DynaSim study directory containing studyinfo.mat
0018 %   - func: function handle or cell array of function handles pointing to plot
0019 %           or analysis function(s). Should not contain case-insensitive string
0020 %           'plot' unless is a function that returns a figure handle for plotting.
0021 %   - options: (key/value pairs are passed on to the analysis function)
0022 %     'save_results_flag'   : whether to save result {0 or 1} (default: 0)
0023 %     'result_file'         : where to save result (default: 'result.mat')
0024 %     'format'              : format for saved plots if figures are generated
0025 %                             {'svg','jpg','eps','png'} (default: 'svg')
0026 %     'varied_filename_flag': whether to make filename based on the varied
0027 %                             parameters and type of plot {0 or 1} (default: 0)
0028 %     'function_options'    : cell array of option cell arrays {'option1',value1,...}
0029 %                             in which each cell corresponds to the options for
0030 %                             the corresponding function cell. if only passing a
0031 %                             single func, can specificy function options as
0032 %                             key,val list as varargin for AnalyzeData
0033 %     'load_all_data_flag'  : whether to load all the data in studyinfo
0034 %                             at once {0 or 1} (default: 0)
0035 %     'parallel_flag' : whether to use parfor to run analysis {0 or 1} (default: 0)
0036 %
0037 % Outputs:
0038 %   - result: structure returned by the analysis function
0039 %
0040 % TODO: annotate figures with data set-specific modifications
0041 %
0042 %
0043 % See also: dsSimulate
0044 %
0045 % Author: Jason Sherfey, PhD <jssherfey@gmail.com>
0046 % Copyright (C) 2016 Jason Sherfey, Boston University, USA
0047 
0048 %% General cases:
0049 %   - data struct (likely from SimualteModel call)
0050 %   - data struct array
0051 %   - studyinfo with load_all_data_flag==0
0052 %   - studyinfo with load_all_data_flag==1
0053 
0054 %% localfn output
0055 if ~nargin
0056   output = localfunctions; % output var name specific to this fn
0057   return
0058 end
0059 
0060 %% Check inputs
0061 options=dsCheckOptions(varargin,{...
0062   'result_file','result',[],...
0063   'save_results_flag',0,{0,1},...
0064   'format','svg',{'svg','jpg','eps','png','fig'},...
0065   'varied_filename_flag',0,{0,1},...
0066   'plot_type','waveform',{'waveform','rastergram','raster','power','rates','imagesc','heatmapFR','heatmap_sortedFR','meanFR','meanFRdens','FRpanel'},...
0067   'save_prefix',[],[],...
0068   'function_options',{},[],...
0069   'simIDs',[],[],...
0070   'load_all_data_flag',0,{0,1},...
0071   'auto_gen_test_data_flag',0,{0,1},...
0072   'unit_test_flag',0,{0,1},...
0073   'parallel_flag',0,{0,1},...     % whether to run analysis in parallel (using parfor)
0074   'auto_gen_test_data_flag',0,{0,1},...
0075   },false);
0076 
0077 %% auto_gen_test_data_flag argin
0078 if options.auto_gen_test_data_flag
0079   varargs = varargin;
0080   varargs{find(strcmp(varargs, 'auto_gen_test_data_flag'))+1} = 0;
0081   varargs(end+1:end+2) = {'unit_test_flag',1};
0082   argin = [{src},{funcIn}, varargs]; % specific to this function
0083 end
0084 
0085 
0086 %% Save data if no output is requested.
0087 if nargout<1
0088   options.save_results_flag = 1;
0089 end
0090 
0091 % varinputs = varargin;
0092 % % check if simIDs specified
0093 % if ~isempty(options.simIDs)
0094 %   if isstruct(varinputs{1})
0095 %     varinputs.simIDs = options.simIDs;
0096 %   else
0097 %     % find simIDs in varinputs
0098 %     varinputs{find(~cellfun(@isempty,strfind(varinputs(1:2:end), 'simIDs')))*2} = options.simIDs;
0099 %   end
0100 % end
0101 
0102 %% Parse src.
0103 [data, studyinfo] = parseSrc(src, options, varargin{:});
0104 % Data at this point:
0105 %   - 'data' as single struct or struct array, or empty
0106 %   - 'studyinfo' struct or empty
0107 
0108 % check if study_dir defined
0109 if isempty(studyinfo)
0110   studyinfoBool = false;
0111 else
0112   studyinfoBool = true;
0113   if ~isfield(studyinfo,'study_dir') || isempty(studyinfo.study_dir) || ~isdir(studyinfo.study_dir)
0114     studyinfo.study_dir = pwd;
0115   end
0116 end
0117 
0118 % Data at this point:
0119 %   - 'data' as single struct or struct array, or empty
0120 %   - 'studyinfo' struct with many flds or just 'study_dir' field
0121 
0122 % convert data to double precision before analysis
0123 for j = 1:length(data)
0124   for k = 1:length(data(j).labels)
0125     fld = data(j).labels{k};
0126     data(j).(fld) = double(data(j).(fld));
0127   end
0128 end
0129 
0130 % convert func to handle if not a cell array
0131 [funcIn, nFunc] = parseFuncIn(funcIn);
0132 
0133 % check if postSim
0134 postSimBool = studyinfoBool || (length(data) > 1); % since length(data)==1 and no studyinfo with SimulateModel call
0135 
0136 for fInd = 1:nFunc % loop over function inputs
0137   func = funcIn{fInd};
0138 
0139   % confirm func is function handle or convert to one if possible
0140   func = parseFunc(func);
0141 
0142   % check if plot in fn name
0143   plotFnBool = ~isempty(regexpi(func2str(func), 'plot'));
0144 
0145   % change result_file if varied_filename_flag
0146   if options.varied_filename_flag && isfield(data, 'varied')
0147     options.result_file = filenameFromVaried(options.result_file, func, data, plotFnBool, options, varargin{:});
0148   end
0149 
0150   % do analysis
0151   fprintf('\tExecuting post-processing function: %s\n',func2str(func));
0152   tstart = tic;
0153 
0154   %% Eval func
0155   if length(data)==1 || postSimBool % Don't need to add check on load_all_data_flag, since if false data is empty.
0156     result = evalFnWithArgs(fInd, data, func, options, varargin{:});
0157   else
0158     result = [];
0159   end
0160 
0161 
0162 
0163   % calc nResults
0164   if ~isempty(result)
0165     nResults = length(result);
0166   elseif ~isempty(data)
0167     nResults = length(data);
0168   else
0169     nResults = length(siminfo.simulations);
0170   end
0171 
0172   fprintf('\t\tElapsed time: %g sec\n',toc(tstart));
0173 
0174   % Dave: Not all plotting functions will return a plot handle. For
0175   % example, dsPlot2 returns a nested structure of figure, axis, and plot
0176   % handles. This command updates it.
0177   if isstruct(result)
0178       if isfield(result,'hcurr')
0179           result = result.hcurr;
0180       end
0181   end
0182 
0183   % determine if result is a plot handle or derived data
0184   if all(ishandle(result)) || plotFnBool % analysis function returned a graphics handle or has plot in fn name
0185     %% Plot Function
0186 
0187     % will save plots else return main fn
0188     if options.save_results_flag
0189       % loop through results. all results may exist or need to be made during loop
0190       for iResult = 1:nResults
0191         extension = ['.' options.format]; % '.svg'; % {.jpg,.svg}
0192 
0193         if ~postSimBool % approx nResults == 1 && ~studyinfoBool % approx ~postSimBool
0194           fname = [options.result_file extension];
0195           fPath = fname;
0196 
0197           thisResult = result(iResult);
0198         elseif studyinfoBool
0199           simID = studyinfo.simulations(iResult).sim_id;
0200           prefix = func2str(func);
0201           fname = [prefix '_sim' num2str(simID) '_plot' num2str(fInd) '_' func2str(func)];
0202 
0203           if (postSimBool && ~options.load_all_data_flag)
0204             data = loadDataFromSingleSim(simID, options, varargin);
0205 
0206             %skip if no data
0207             if isempty(data)
0208               continue
0209             end
0210 
0211             % calc result for this data
0212             thisResult = evalFnWithArgs(fInd, data, func, options, varargin);
0213           end
0214 
0215           % change result_file if varied_filename_flag
0216           if options.varied_filename_flag && isfield(data, 'varied')
0217             fname = filenameFromVaried(fname, func, data, plotFnBool, options, varargin{:});
0218           end % varied_filename_flag
0219 
0220           % make fPath
0221           fDir = fullfile(studyinfo.study_dir, 'postSimPlots');
0222           if ~exist(fDir,'dir')
0223             mkdir(fDir)
0224           end
0225           fPath = fullfile(fDir,fname);
0226         else % length(result)>1 and ~studyinfoBool
0227           fname = [options.result_file '_page' num2str(iResult) extension];
0228 
0229           % make fPath
0230           fDir = fullfile(studyinfo.study_dir, 'postSimPlots');
0231           if ~exist(fDir,'dir')
0232             mkdir(fDir)
0233           end
0234           fPath = fullfile(fDir,fname);
0235 
0236           thisResult = result(iResult);
0237         end
0238         % Data needed for plotting:
0239         %   - thisResult
0240         %   - fPath
0241 
0242         set(thisResult, 'PaperPositionMode','auto');
0243         fprintf('\t\tSaving plot: %s\n',fname);
0244 
0245         switch extension
0246           case '.svg'
0247             plot2svg(fPath,thisResult);
0248           case '.jpg'
0249             print(thisResult,fPath,'-djpeg');
0250           case '.eps'
0251             print(thisResult,fPath,'-depsc');
0252           case '.png'
0253             print(thisResult,fPath,'-dpng');
0254           case '.fig'
0255             savefig(thisResult,fPath);
0256         end
0257 
0258         if nResults > 1
0259           close(thisResult)
0260         end
0261       end %nResults
0262     end %save_results_flag
0263   else % analysis function returned derived data
0264     %% Analysis Function
0265     if isstruct(result)
0266       result = add_modifications(result, data, varargin{:});
0267 
0268       for iResult = 1:length(result)
0269         % add options to result structure
0270         if length(varargin)>1
0271           for j = 1:2:length(varargin)
0272             result(iResult).options.(varargin{j}) = varargin{j+1};
0273           end
0274         else
0275           result(iResult).options = [];
0276         end
0277       end %iResult
0278     end %isstruct
0279 
0280     % save derived data else return main function
0281     if options.save_results_flag
0282       if studyinfoBool
0283         allResults = result;
0284         clear result;
0285 
0286         for iResult = 1:nResults
0287           simID = studyinfo.simulations(iResult).sim_id;
0288 
0289           if options.load_all_data_flag
0290             result = allResults(iResult);
0291           else % load data
0292             data = loadDataFromSingleSim(simID, options, varargin);
0293 
0294             %skip if no data
0295             if isempty(data)
0296               continue
0297             end
0298 
0299             % calc result for this data
0300             result = evalFnWithArgs(fInd, data, func, options, varargin);
0301           end
0302 
0303           prefix = func2str(func);
0304           fname = [prefix '_sim' num2str(simID) '_analysis' num2str(fInd) '_' func2str(func) '.mat'];
0305 
0306           % change result_file if varied_filename_flag
0307           if options.varied_filename_flag && isfield(data, 'varied')
0308             fname = filenameFromVaried(fname, func, data, plotFnBool, options, varargin{:});
0309           end % varied_filename_flag
0310 
0311           % make fPath
0312           fDir = fullfile(studyinfo.study_dir, 'analyzedData');
0313           if ~exist(fDir,'dir')
0314             mkdir(fDir)
0315           end
0316           fPath = fullfile(fDir,fname);
0317 
0318           fprintf('\t\tSaving derived data: %s\n', fPath);
0319           save(fPath,'result','-v7.3');
0320         end %iResult
0321       else % ~studyinfoBool, whether 1 or array of struct
0322         fname = options.result_file;
0323         extension = '.mat';
0324 
0325         if ~strcmp(fname(end-3:end), extension) %check for .mat extension
0326           fname = [fname extension];
0327         end
0328 
0329         fprintf('\t\tSaving derived data: %s\n', fname);
0330         save(fname,'result','-v7.3');
0331       end % scenarios
0332     end % save_results_flag
0333   end % ishandle(result)
0334 end % fInd
0335 
0336 %% auto_gen_test_data_flag argout
0337 if options.auto_gen_test_data_flag
0338   argout = {result}; % specific to this function
0339 
0340   %dsUnitSaveAutoGenTestData(argin, argout); % TODO: check if needs to be saveAutoGenTestDir
0341 end
0342 
0343 end %main fn
0344 
0345 
0346 
0347 
0348 %% Local functions
0349 
0350 function [data, studyinfo] = parseSrc(src, options, varargin)
0351 
0352 %% auto_gen_test_data_flag argin
0353 options = dsCheckOptions(varargin,{'auto_gen_test_data_flag',0,{0,1}},false);
0354 if options.auto_gen_test_data_flag
0355   varargs = varargin;
0356   varargs{find(strcmp(varargs, 'auto_gen_test_data_flag'))+1} = 0;
0357   varargs(end+1:end+2) = {'unit_test_flag',1};
0358   argin = [{src},{options}, varargs]; % specific to this function
0359 end
0360 
0361 
0362 if isstruct(src) && isfield(src,'time') % data struct (single or array)
0363   data = src; % if length==1,then likely from SimulateModel call
0364   studyinfo = [];
0365 elseif ischar(src) %string input
0366   if options.load_all_data_flag % load data
0367     [data,studyinfo] = dsImport(src, varargin{:});
0368   else % only load studyinfo
0369     data = [];
0370     studyinfo = dsCheckStudyinfo(src);
0371   end
0372 
0373   % update study_dir
0374   if exist(src, 'file') && ~isempty(strfind(src, 'studyinfo')) %studyinfo.mat
0375     studyinfo.study_dir = fileparts2(src);
0376   elseif isdir(src) % study_dir
0377     studyinfo.study_dir = src;
0378   end
0379 end
0380 
0381 % Old Verbose Way with unnecessary checks
0382 % determine type of src
0383 % if ischar(src)
0384 %   if exist(src,'file') % data file or studyinfo.mat
0385 %     if strfind(src, 'studyinfo') %studyinfo.mat
0386 %       [data,studyinfo] = ImportData(src, varargin{:}); % load data
0387 %       studyinfo.study_dir = fileparts2(src);
0388 %     else % data file
0389 %       [data,studyinfo] = ImportData(src, varargin{:}); % load data
0390 %     end
0391 %   elseif isdir(src) % study_dir
0392 %     [data,studyinfo] = ImportData(src, varargin{:}); % load data
0393 %     studyinfo.study_dir = src;
0394 %   else
0395 %     try
0396 %       [data,studyinfo] = ImportData(src, varargin{:}); % load data
0397 %     catch
0398 %       error('Unknown source for first input/argument.')
0399 %     end
0400 %   end
0401 % elseif isstruct(src) && length(src)>1 % data file cell array
0402 %   data = src;
0403 % elseif isstruct(src) % single data struct or studyinfo struct
0404 %   if isfield(src,'time') % single data file
0405 %     data = src;
0406 %   else % studyinfo struct
0407 %     [data,studyinfo] = ImportData(src, varargin{:}); % load data
0408 %   end
0409 % elseif iscell(src) % cell array of files
0410 %   [data,studyinfo] = ImportData(src, varargin{:}); % load data
0411 % else
0412 %   try
0413 %     [data,studyinfo] = ImportData(src, varargin{:}); % load data
0414 %   catch
0415 %     error('Unknown source for first input/argument.')
0416 %   end
0417 % end
0418 %
0419 %
0420 % % make studyinfo if doesn't exist
0421 % if ~exist('studyinfo','var')
0422 %   studyinfo = [];
0423 % end
0424 
0425 %% auto_gen_test_data_flag argout
0426 if options.auto_gen_test_data_flag
0427   argout = {data, studyinfo}; % specific to this function
0428 
0429   %dsUnitSaveAutoGenTestDataLocalFn(argin, argout); % localfn
0430 end
0431 
0432 end
0433 
0434 
0435 function [funcIn, nFunc] = parseFuncIn(funcIn)
0436 % convert funcIn input to handle if not a cell array
0437 
0438 if isa(funcIn,'function_handle')
0439   nFunc = 1;
0440   funcIn = {funcIn}; % make into cell array
0441 elseif ischar(funcIn)
0442   funcIn = {str2func(funcIn)}; % convert string to fn handle
0443 
0444   if ~isfunction(funcIn)
0445     error('Post-processing function must be supplied as a function handle or function name string');
0446   end
0447 
0448   nFunc = 1;
0449 else
0450   nFunc = numel(funcIn);
0451 end
0452 end
0453 
0454 
0455 function func = parseFunc(func)
0456 if ~isa(func,'function_handle')
0457   if ischar(func)
0458     func = str2func(func); % convert string to fn handle
0459 
0460     if ~isfunction(func)
0461       error('Post-processing function must be supplied as a function handle or function name string');
0462     end
0463   else
0464     error('Post-processing function must be supplied as a function handle or function name string');
0465   end
0466 end
0467 end
0468 
0469 
0470 function filename = filenameFromVaried(filename, func, data, plotFnBool, options, varargin)
0471 % NOTE: inputs are odd since called from different sources with different
0472 %       states.
0473 
0474 %% auto_gen_test_data_flag argin
0475 options = catstruct(options, dsCheckOptions(varargin,{'auto_gen_test_data_flag',0,{0,1}},false));
0476 
0477 if options.auto_gen_test_data_flag
0478   varargs = varargin;
0479   varargs{find(strcmp(varargs, 'auto_gen_test_data_flag'))+1} = 0;
0480   varargs(end+1:end+2) = {'unit_test_flag',1};
0481   argin = [{filename}, {func}, {data}, {plotFnBool}, {options}, varargs]; % specific to this function
0482 end
0483 
0484 if isfield(options, 'save_prefix') && ~isempty(options.save_prefix)
0485   prefix = options.save_prefix;
0486 else
0487   if plotFnBool
0488     if isempty(options.function_options)
0489       plot_options = options;
0490     else
0491       plot_options = options.function_options{fInd};
0492     end
0493 
0494     fInd = regexp(options.result_file, 'plot(\d+)', 'tokens');
0495     fInd = fInd{1}{1};
0496 
0497     % check if 'plot_type' given as part of plot_options
0498     plot_options = dsCheckOptions(plot_options,{'plot_type',['plot' fInd],[]},false);
0499 
0500     prefix = plot_options.plot_type; % will be waveform by default due to CheckOptions in main fn
0501   else % ~plotFnBool
0502     prefix = func2str(func);
0503   end
0504 end
0505 
0506 filename = dsNameFromVaried(data, prefix, filename);
0507 
0508 %% auto_gen_test_data_flag argout
0509 if options.auto_gen_test_data_flag
0510   argout = {filename}; % specific to this function
0511 
0512   %dsUnitSaveAutoGenTestDataLocalFn(argin, argout); % localfn
0513 end
0514 
0515 end
0516 
0517 
0518 function result = evalFnWithArgs(fInd, data, func, options, varargin)
0519 
0520 if strcmp(reportUI,'matlab')
0521   p = gcp('nocreate');
0522 end
0523 
0524 if isempty(options.function_options)
0525   if options.parallel_flag && ~isempty(p)       % Only do parfor mode if parallel_flag is set and parpool is already running. Otherwise, this will add unncessary overhead.
0526     parfor dInd = 1:length(data)
0527       result(dInd) = feval(func,data(dInd),varargin{:});
0528     end
0529   else
0530     for dInd = 1:length(data)
0531       result(dInd) = feval(func,data(dInd),varargin{:});
0532     end
0533   end
0534 else
0535   function_options = options.function_options{fInd};
0536 
0537   if options.parallel_flag && ~isempty(p)
0538     parfor dInd = 1:length(data)
0539       result(dInd) = feval(func,data(dInd),function_options{:});
0540     end
0541   else
0542     for dInd = 1:length(data)
0543       result(dInd) = feval(func,data(dInd),function_options{:});
0544     end
0545   end
0546 end
0547 end
0548 
0549 
0550 function data = loadDataFromSingleSim(simID, options, varargin)
0551 % check if iResult in options.simIDs
0552 if isempty(options.simIDs)
0553   simIDs = simID;
0554 else
0555   simIDs = intersect(simID, options.simIDs);
0556 
0557   if isempty(simIDs) % skip if empty
0558     return
0559   end
0560 end
0561 
0562 varinputs = varargin; % create copy of varargin
0563 if isstruct(varinputs{1})
0564   varinputs.simIDs = simIDs;
0565 else
0566   % find simIDs in varinputs
0567   varinputs{find(~cellfun(@isempty,strfind(varinputs(1:2:end), 'simIDs')))*2} = simIDs;
0568 end
0569 
0570 data = ImportData(src, varinputs{:}); % load data
0571 end
0572 
0573 
0574 function result = add_modifications(result, data, varargin)
0575 % add modifications to result structure, excluding modifications made
0576 % within experiments. note: while this nested function is similar to
0577 % dsModifications2Vary called by dsSimulate, the data structure contains
0578 % all modifications (those within and across experiments; listed in 'varied').
0579 % the result structure collapses data sets from an experiment into a single
0580 % result; thus, each result corresponds to modifications across
0581 % experiments but not within them; those modifications are stored in
0582 % the simulator options.
0583 
0584 %% auto_gen_test_data_flag argin
0585 options = dsCheckOptions(varargin,{'auto_gen_test_data_flag',0,{0,1}},false);
0586 if options.auto_gen_test_data_flag
0587   varargs = varargin;
0588   varargs{find(strcmp(varargs, 'auto_gen_test_data_flag'))+1} = 0;
0589   varargs(end+1:end+2) = {'unit_test_flag',1};
0590   argin = [{result}, {data}, varargs]; % specific to this function
0591 end
0592 
0593 % #todo: The function dsModifications2Vary implements this functionality.
0594 % Consider using it here.
0595 if ~isempty(data(1).simulator_options.modifications)
0596   varied = {};
0597   mods = data(1).simulator_options.modifications;
0598   for ii = 1:length(result)
0599     for jj = 1:size(mods,1)
0600       % prepare valid field name for thing varied:
0601       fld = [mods{jj,1} '_' mods{jj,2}];
0602 
0603       % convert arrows and periods to underscores
0604       fld = regexprep(fld,'(->)|(<-)|(-)|(\.)','_');
0605 
0606       % remove brackets and parentheses
0607       fld = regexprep(fld,'[\[\]\(\)\{\}]','');
0608       result(ii).(fld) = mods{jj,3};
0609       varied{end+1} = fld;
0610     end
0611     result(ii).varied = varied;
0612     result(ii).modifications = mods;
0613   end
0614 elseif isfield(data,'varied') && length(data) == 1
0615   % add 'varied' info from data to result structure
0616   for ii = 1:length(result)
0617     result(ii).varied = data(1).varied;
0618     for jj = 1:length(data(1).varied)
0619       result(ii).(data(1).varied{jj}) = data(1).(data(1).varied{jj});
0620     end
0621   end
0622 end
0623 
0624 %% auto_gen_test_data_flag argout
0625 if options.auto_gen_test_data_flag
0626   argout = {result}; % specific to this function
0627 
0628   %dsUnitSaveAutoGenTestDataLocalFn(argin, argout); % localfn
0629 end
0630 end % add_modifications

Generated on Tue 12-Dec-2017 11:32:10 by m2html © 2005