Simulation and Scoring

f_sim_score

Code

 1function [score, rst, rst_not_simd] = ...
 2    f_sim_score(parameters, stg, model_folders, i, j)
 3% This function calculates the total score of a given model by simulating
 4% its performance and scoring the results.
 5%
 6% Inputs:
 7% - parameters: A double containing the model's parameters necessary for
 8% the simulation.
 9% - stg: A structure containing the settings and configurations for the
10% simulation and scoring process.
11% - model_folders: A structure containing the paths to the folders where
12% the model and other relevant files are stored.
13%
14% Outputs:
15% - score: A scalar value representing the total score of the model's
16% performance.
17% - rst: A structure containing the results of the simulation and scoring
18% process.
19% - rst_not_simd: A structure containing the results of the simulation and
20% scoring process with the 'simd' field removed.
21%
22% Used Functions:
23% - f_prep_sim: Simulates the model using the provided parameters,
24% settings, and model folders.
25% - f_score: Calculates the score of the model based on the results of the
26% simulation.
27%
28% Variables:
29% Loaded:
30% - None.
31%
32% Initialized:
33% - None.
34%
35% Persistent:
36% - None.
37%
38
39%Turn off Dimension analysis warning from SimBiology
40warning('off','SimBiology:DimAnalysisNotDone_MatlabFcn_Dimensionless')
41
42% Call the function that simulates the model
43rst = f_prep_sim(parameters, stg, model_folders, i, j);
44
45% Call the function that scores
46rst = f_score(rst, stg, model_folders);
47
48% Get the total score explicitly for optimization functions
49score = rst.st;
50
51rst_not_simd = rmfield( rst , 'simd');
52end

This function, f_sim_score, calculates the total score of a given model by simulating the model and scoring its performance. The function takes three input arguments: parameters, stg, and model_folders. The output of the function includes the total score (score), the result of the simulation and scoring (rst), and the result of the simulation and scoring without the ‘simd’ field (rst_not_simd).

  • Inputs

    • stg - Structure containing the settings and configurations for the simulation and scoring process.

    • parameters - Double containing the model’s parameters that are necessary for the simulation.

    • model_folders: Structure containing the paths to the folders where the model and other relevant files are stored.

  • Outputs

    • score - rst.st Scalar value representing the total score of the model’s performance.

    • rst - rst.simd, rst.xfinal, rst.sd, rst.se, and rst.st Structure containing the results of the simulation and scoring process.

    • rst_not_simd - rst.xfinal, rst.sd, rst.se, and rst.st Structure containing the results of the simulation and scoring process with the ‘simd’ field removed.

  • Calls

    • f_prep_sim This function simulates the model using the provided parameters, settings, and model folders.

    • f_score This function calculates the score of the model based on the results of the simulation.

f_prep_sim

Code

  1function result = f_prep_sim(parameters, settings, model_folders, i, j)
  2% This function prepares the parameters for a simulation by setting them to
  3% the default values defined in the SBTAB and then updating any parameters
  4% that are being tested. The parameters are also adjusted according to any
  5% thermodynamic constraints.
  6%
  7% Inputs:
  8% - parameters: Array of parameter values to be tested
  9% - settings: Structure containing various settings for the simulation
 10% - model_folders: Structure with folder paths for model data
 11% - i, j: Indices for tracking simulations
 12%
 13% Outputs:
 14% - result: Structure with simulation results and updated parameter values
 15%
 16% Used Functions:
 17% - update_simulation_parameters: Function to update simulation parameters
 18% - f_sim: Function to run the simulation
 19%
 20% Variables:
 21% Loaded:
 22% - Data: Array of structures containing experimental data
 23% - sbtab: SBTAB structure containing default parameters and species
 24% information
 25%
 26% Initialized:
 27% - sim_par: Array of simulation parameters
 28% - ssa: Array of species start amounts
 29%
 30% Persistent:
 31% - sbtab: SBTAB structure containing default parameters and species
 32% information
 33% - Data: Array of structures containing experimental data
 34
 35% Save variables across multiple function calls
 36persistent sbtab Data
 37
 38% Load data on the first run
 39if isempty(sbtab) || isempty(Data)
 40    if isfield(model_folders, 'model') && isfield(model_folders.model, ...
 41            'data') && isfield(model_folders.model.data, 'data_model')
 42        data_model_path = model_folders.model.data.data_model;
 43        load(data_model_path, 'Data', 'sbtab')
 44    else
 45        error(['Data model not found in model_folders.' ...
 46            ' Please check the folder paths.'])
 47    end
 48end
 49
 50% Set simulation parameters to default values from SBtab
 51if isfield(sbtab, 'defpar')
 52    sim_par(:, 1) = [sbtab.defpar{:, 2}]; %simulation_parameters
 53else
 54    error(['Default parameters not found in SBtab.' ...
 55        ' Ensure SBtab is properly formatted.'])
 56end
 57
 58% Update parameters for Profile Likelihood if needed
 59if isfield(settings, 'PLind') && isfield(settings, 'PLval')
 60    if settings.PLind > 0 && settings.PLind <= length(parameters) + 1
 61        % add stg.PLval in the midle of other parameters
 62        parameters = ...
 63            [parameters(1:settings.PLind - 1), settings.PLval, ...
 64            parameters(settings.PLind:end)];
 65    else
 66        error(['PLind is out of bounds.' ...
 67            ' It should be within the range of parameter indices.'])
 68    end
 69end
 70
 71% Update simulation parameters
 72sim_par = ...
 73    update_simulation_parameters(sim_par, parameters, settings, sbtab);
 74
 75% Initialize the result structure
 76result = struct();
 77result.parameters = sim_par;
 78
 79% Validate experiment run settings
 80if ~isempty(settings.exprun) && isnumeric(settings.exprun)
 81    result.simd = cell(1, max(settings.exprun));
 82else
 83    error(['stg.exprun is invalid.' ...
 84        ' Ensure exprun is a non - empty numeric array.'])
 85end
 86
 87success_eq = zeros(1, settings.exprun(end));
 88error_list_E = "";
 89
 90if settings.simcsl
 91    prep_sim_tic = tic;
 92end
 93
 94% Run simulations for each experiment
 95for exp_indx = settings.exprun
 96
 97    prev_success = success_eq(max(settings.exprun(1), exp_indx - 1));
 98    % Equilibration
 99    [species_start_amounts, success_eq(exp_indx), error_type] =...
100        equilibrate_2(exp_indx, settings, sim_par, result, ...
101        model_folders, sbtab, prev_success);
102
103    % Main simulation
104    if success_eq(exp_indx)
105
106        tolerance_settings = ...
107            create_tolerance_settings(exp_indx, settings, 0);
108
109        [~, error_type, result] = ...
110            run_with_tolerances(@(success) f_sim(exp_indx, settings, ...
111            sim_par, species_start_amounts, result, ...
112            model_folders, success), tolerance_settings, result);
113
114        % if ~success_sim
115        %     disp("n: " + n + " E" + (n - 1) + " fail_sim_2" + ...
116        %         " last error: " + ME.identifier)
117        %     result.simd{exp_indx} = 0;
118        % end
119
120        % Run detailed simulation if required
121        if settings.simdetail
122            [~, error_type, result] = ...
123                run_with_tolerances(@(success) f_sim(exp_indx + 2 * ...
124                settings.expn, settings, sim_par, species_start_amounts, ...
125                result, model_folders, success), tolerance_settings, ...
126                result);
127        end
128
129        % Check simulation output times
130        if result.simd{exp_indx} ~= 0 && ...
131                size(Data(exp_indx).Experiment.t, 1) ~= ...
132                size(result.simd{exp_indx}.Data(:, end), 1)
133            % disp("n: " + n + " E" + (n - 1) + " fail_sim_out_time" + ...
134            %     " time_sim:  " + size(result.simd{n}.Data(:, end), 1) + ...
135            %     " data_time: " + size(Data(n).Experiment.t, 1))
136            error_type = "st"; %simulation time
137            result.simd{exp_indx} = 0;
138        end
139    else
140        result.simd{exp_indx} = 0;
141    end
142    if result.simd{exp_indx} == 0
143        error_list_E = append(error_list_E, ...
144            ((exp_indx - 1) + error_type + " "));
145    end
146
147end
148
149% Display progress and errors if necessary
150if settings.simcsl && ~(error_list_E == "")
151    disp("i: " + i + " j: " + j + " E: " + error_list_E + ...
152        " time: " + toc(prep_sim_tic))
153end
154end
155
156function tolerance_settings = ...
157    create_tolerance_settings(exp_indx, settings, equilibrate)
158% Create a structure for tolerance settings
159tolerance_settings = ...
160    struct('exp_indx', exp_indx, 'reltol', settings.reltol, 'reltol_step', ...
161    settings.reltol / 10, 'reltol_min', settings.reltol_min, ...
162    'abstol', settings.abstol, 'abstol_step', settings.abstol / 10, ...
163    'abstol_min', settings.abstol_min, 'equilibrate', equilibrate);
164end
165
166function [success, error_type, result] = ...
167    run_with_tolerances(func, tolerance_settings, result)
168% Run a function with varying tolerance settings until it succeeds
169success = true;
170error_type = '';
171
172for reltol = tolerance_settings.reltol: - tolerance_settings.reltol_step:...
173        min(tolerance_settings.reltol_min,tolerance_settings.reltol)
174
175    % disp("reltol: " + reltol)
176    for abstol = ...
177            tolerance_settings.abstol: - tolerance_settings.abstol_step:...
178            min(tolerance_settings.abstol_min,tolerance_settings.abstol)
179        % disp("abstol: " + abstol)
180        tolerance_settings.stg.reltol = reltol;
181        tolerance_settings.stg.abstol = abstol;
182        if tolerance_settings.equilibrate
183            try
184            [result, error_type] = func();
185            success = true;
186            catch
187                error_type = "e"; %equilibration
188                success = false;
189            end
190        else
191            try
192                result = func(success);
193                success = true;
194            catch
195                % tolerance_settings.exp_indx
196                result.simd{tolerance_settings.exp_indx} = 0;
197                error_type = "s"; %simulation
198                success = false;
199            end
200        end
201        if success
202            break;
203        end
204    end
205    if success
206        break;
207    end
208end
209end
210
211function [species_start_amounts_1, success_eq, error_type] = ...
212    equilibrate_2(exp_indx, settings, sim_par, ...
213    result, model_folders, sbtab, success_eq)
214% Equilibrate the model for the specified experiment
215persistent species_start_amounts %species start amount
216error_type = "";
217
218% Check if this is not the first experiment, the start values are equal to
219% the previous experiment, and the previous simulation was valid
220is_not_first_experiment = exp_indx ~= settings.exprun(1);
221
222x = find(settings.exprun == exp_indx) - 1;
223
224start_values_equal = min([sbtab.datasets(exp_indx).start_amount{:, 2}] == ...
225    [sbtab.datasets(settings.exprun(max(x, 1))).start_amount{:, 2}]);
226previous_simulation_valid = result.simd{settings.exprun(max(x, 1))} ~= 0;
227
228if is_not_first_experiment && start_values_equal && ...
229        previous_simulation_valid && success_eq
230    % Set the start amounts based on the previous experiment
231    species_start_amounts(:, exp_indx) =...
232        species_start_amounts(:, settings.exprun(x));
233    if settings.simdetail
234        species_start_amounts(:, exp_indx + 2*settings.expn) = ...
235            species_start_amounts(:, settings.exprun(x));
236    end
237    success_eq = true;
238else
239    % Set start amounts for species with non - zero values
240    for j = 1:size(sbtab.datasets(exp_indx).start_amount, 1)
241        % Set the start amount of the species to the number defined in
242        % the sbtab for each experiment
243        species_start_amounts(sbtab.datasets(exp_indx).start_amount{j, 3}, ...
244            exp_indx + settings.expn) =...
245            sbtab.datasets(exp_indx).start_amount{j, 2};
246    end
247
248    tolerance_settings = create_tolerance_settings(exp_indx, settings, 1);
249
250    [success_eq, error_type, species_start_amounts] = ...
251        run_with_tolerances(@() equilibrate(exp_indx, settings, sim_par, ...
252        result, model_folders, sbtab, species_start_amounts, success_eq), ...
253        tolerance_settings, species_start_amounts);
254end
255species_start_amounts_1 = species_start_amounts;
256end
257
258function sim_par = ...
259    update_simulation_parameters(sim_par, parameters, settings, sbtab)
260% Update simulation parameters based on input and thermodynamic constraints
261
262% Iterate over all the parameters of the model
263for n = 1:length(sim_par)
264    % Update tested parameters
265    if settings.partest(n) > 0
266        sim_par(n) = 10 .^ parameters(settings.partest(n, 1));
267    end
268    % Update thermodynamic constrained parameters
269    if isfield(settings, 'tci') && ~isempty(settings.tci) &&...
270            ismember(n, settings.tci) && settings.partest(n) > 0
271        sim_par = ...
272            update_thermo_constrained(sim_par, parameters, settings, ...
273            n, sbtab);
274    end
275end
276end
277
278function sim_par = ...
279    update_thermo_constrained(sim_par, parameters, settings, n, sbtab)
280% Update parameters constrained by thermodynamic laws
281
282key_1 = ["tcm", "tcd"];
283key_2 = ["*", "/"];
284
285for k=1:2
286    count = 0;
287    for m = 1:size(settings.(key_1(k)), 2)
288        if settings.(key_1(k))(n, m) ~= 0
289            count = count + 1;
290        end
291    end
292    % Iterate over the parameters that need to be multiplied for
293    % calculating the parameter that depends on the thermodynamic
294    % constraints
295    for m = 1:count
296        % Check that the parameter that is going to be used to calculate
297        % the parameter dependent on thermodynamic constraints is not the
298        % default
299        if settings.partest(settings.(key_1(k))(n, m), 1) > 0
300            % Check if the parameter needs to be set to the value relevant
301            % for Profile Likelihood
302            if isfield(settings, "PLind") && ...
303                    settings.partest(settings.(key_1(k))(n, m), 1) == ...
304                    settings.PLind
305                parameters(settings.partest(settings.(key_1(k))(n, m), 1)) = ...
306                    settings.PLval;
307            end
308            % Make the appropriate multiplications to get the
309            % thermodynamically constrained parameter
310            eval("sim_par(n) = sim_par(n) " + key_2(k) + ...
311                " (10 ^ (parameters(settings.partest(" + ...
312                "settings.(key_1(k))(n, m), 1))));");
313        else
314            % Make the appropriate multiplications to get the
315            % thermodynamically constrained parameter
316            eval("sim_par(n) = sim_par(n) " + key_2(k) + ...
317                "(sbtab.defpar{settings.(key_1(k))(n, m), 2});");
318        end
319    end
320end
321end
322
323function [species_start_amounts, error_type] = ...
324    equilibrate(n, settings, sim_par, result, model_folders, sbtab, ...
325    species_start_amounts, success)
326% Equilibrate the model
327
328result = f_sim(n + settings.expn, settings, sim_par, ...
329    species_start_amounts, result, model_folders, success);
330error_type = "";
331
332if result.simd{n + settings.expn}.Time(end, 1) ~= settings.eqt
333    % disp("n: " + n + " E" + (n - 1) + " time_eq: " + ...
334    %     result.simd{n + settings.expn}.Time(end, 1) + ...
335    %     " settings.eqt: " + settings.eqt)
336    % disp("pecado")
337    error("E" + (n - 1) + " fail_eq_out_time")
338    error_type = "et"; %equilibration time
339end
340
341% Update the start amounts based on equilibrium results
342for j = 1:size(sbtab.species, 1)
343    final_amount = result.simd{n + settings.expn}.Data(end, j);
344    if final_amount < 10 ^ -10
345        species_start_amounts(j, n) = 0;
346        if settings.simdetail
347            species_start_amounts(j, n + 2 * settings.expn) = 0;
348        end
349    else
350        species_start_amounts(j, n) = final_amount;
351        if settings.simdetail
352            species_start_amounts(j, n + 2 * settings.expn) = final_amount;
353        end
354    end
355end
356end

The code defines a main function f_prep_sim and three additional helper functions update_thermo_constrained_multiplications, update_thermo_constrained_divisions, and f_sim. The main function f_prep_sim prepares the parameters for a simulation, setting default values and updating any parameters being tested. It also adjusts the parameters according to thermodynamic constraints.

The main function f_prep_sim takes the following inputs:

  • parameters: parameters for the simulation

  • :ref:`stg<stg>`: settings for the simulation

  • model_folders: folder paths for the models

And it outputs :

  • rst: results of the simulation

The function initializes several persistent variables, imports data on the first run, and sets the default parameters for the simulation.

The function checks if the parameters need to be updated for Profile Likelihood.

It iterates through all model parameters, updating tested parameters and thermodynamic constrained parameters accordingly.

The function initializes the start amount for the species in the model to 0 and sets up a loop for each experiment being run.

Within the loop, the function tries to simulate the model, performing several checks and updates. If an error occurs during the simulation, the function catches the error and sets the simulation output to 0, indicating the simulation did not work properly.

The helper functions update_thermo_constrained_multiplications and update_thermo_constrained_divisions update the parameters according to the thermodynamic constraints. They iterate through parameters that need to be multiplied or divided, respectively, and make the appropriate adjustments.

The helper function f_sim runs simulations using SimBiology models for a set of experiments. It takes the following inputs:

  • experiment_idx: indices of experiments to run

  • settings: simulation settings

  • simulation_parameters: parameter values for simulations

  • species_start_amount: start amounts for species in simulations

  • results: output variable to save simulation results

  • main_model_folders: paths for model files

It outputs:

  • results: simulation results

The function f_sim maintains the state of the loaded models between calls using persistent variables, loads the appropriate models, compiles the code for the simulation run, substitutes the start amounts of species and parameter values based on real-time results, and runs the simulation.

The simulation results are saved in the output variable, and the function can be called multiple times for different experiments. The function checks if the times of the simulation output and the simulation data from SBTAB match. If they do not match, it sets the simulation output to 0, indicating that the simulation did not work properly.

In summary, the main function f_prep_sim prepares the parameters for a simulation by setting them to the default values and then updating any parameters being tested. It adjusts the parameters according to any thermodynamic constraints and iterates through all the experiments to be run. The function then calls the helper function f_sim to run the simulation using SimBiology models for the set of experiments. The simulation results are saved in the output variable, and any errors encountered during the simulation are caught and handled appropriately.

f_sim

Code

  1function results = f_sim(experiment_idx,settings,simulation_parameters,...
  2    species_start_amount,results,main_model_folders,success)
  3% This function runs simulations using SimBiology models for a set of
  4% experiments. It loads the appropriate models and compiles the code for
  5% simulation run, then substitutes the start amounts of species and
  6% parameter values based on real-time results and runs the simulation. The
  7% results of the simulation are saved in the output variable. The function
  8% can be called multiple times for different experiments, and it maintains
  9% the state of the loaded models between calls using persistent variables.
 10%
 11% Inputs:
 12% - experiment_idx: Indices of experiments to run
 13% - settings: Simulation settings (e.g., sbioaccelerate, simdetail, expn,
 14% exprun)
 15% - simulation_parameters: Parameter values for simulations
 16% - species_start_amount: Start amounts for species in simulations
 17% - results: Output variable to save simulation results
 18% - main_model_folders: Paths for model files (e.g., model_exp_default,
 19% model_exp_eq, model_exp_detail)
 20%
 21% Outputs:
 22% - results: Simulation results (e.g., simd)
 23%
 24% Functions called:
 25% - sbioaccelerate: Compile model code for faster simulation run
 26% - sbiosimulate: Run simulation of SimBiology model with specified
 27% configuration
 28%
 29% Variables:
 30% Loaded:
 31% - model_exp: SimBiology model for each experiment
 32% - config_exp: SimBiology model configuration for each experiment
 33%
 34% Initialized:
 35% None
 36%
 37% Persistent:
 38% - models: Cell array containing the SimBiology models for each experiment
 39% - configs: Cell array containing the configurations for each SimBiology
 40% model
 41
 42% Save variables that need to be mantained over multiple function calls
 43persistent models
 44persistent configs
 45
 46rel_tol_ind = abs(log10(settings.reltol_min)-log10(settings.reltol))+1;
 47abs_tol_ind = abs(log10(settings.abstol_min)-log10(settings.abstol))+1;
 48% If the function is called for the first time, load the appropriate model
 49% and compile the code for simulation run
 50if isempty(models)
 51
 52    % Turn off warning messages
 53    warning('off','all')
 54
 55    % Generate an empty array to be populated with the model suited for
 56    % each equilibration and experiment
 57    models = cell(1, 1, settings.expn * (2 + settings.simdetail));
 58    configs = cell(1, 1, settings.expn * (2 + settings.simdetail));
 59
 60    % Set the file paths for the different models
 61    model_exp_default = main_model_folders.model.data.model_exp.default;
 62    model_exp_eq = main_model_folders.model.data.model_exp.equilibration;
 63    model_exp_detail = main_model_folders.model.data.model_exp.detail;
 64
 65    % Iterate over the experiments thar are being run
 66    for n = settings.exprun
 67        for j = 1:rel_tol_ind
 68            for k = 1:abs_tol_ind
 69                % Load and compile SimBiology models for each experiment
 70
 71                % Load models for main simulation
 72                load(model_exp_default + n + ".mat", 'model_exp', ...
 73                    'config_exp')
 74                models{j, k, n} = model_exp;
 75                configs{j, k, n} = config_exp;
 76
 77                % Load models for equilibrium
 78                load(model_exp_eq + n + ".mat", 'model_exp', 'config_exp')
 79                models{j, k, n+settings.expn} = model_exp;
 80                configs{j, k, n+settings.expn} = config_exp;
 81
 82                % Load models for detailed simulation
 83                if settings.simdetail
 84                    load(model_exp_detail + n + ".mat", 'model_exp', ...
 85                        'config_exp')
 86                    models{j, k, n+2*settings.expn} = model_exp;
 87                    configs{j, k, n+2*settings.expn} = config_exp;
 88                end
 89                % Compile the model code if the option is selected in
 90                % settings
 91                if settings.sbioacc
 92                    sbioaccelerate(models{j, k, n}, configs{j,k,n});
 93                    sbioaccelerate(models{j, k, n+settings.expn}, ...
 94                        configs{j, k, n+settings.expn});
 95                    if settings.simdetail
 96                        sbioaccelerate(models{j, k, n+2*settings.expn}, ...
 97                            configs{j, k, n+2*settings.expn});
 98                    end
 99                end
100            end
101        end
102    end
103end
104
105% substitute the start amount of the species in the model with the correct
106% ones for  simulations
107set(models{rel_tol_ind,abs_tol_ind,experiment_idx}.species(...
108    1:size(species_start_amount(:,experiment_idx),1)),...
109    {'InitialAmount'}, num2cell(species_start_amount(:,experiment_idx)));
110
111% Substitute the values of the parameters in the model for the correct one
112% for simultaions
113set(models{rel_tol_ind,abs_tol_ind,experiment_idx}.parameters(...
114    1:size(simulation_parameters,1)),...
115    {'Value'}, num2cell(simulation_parameters));
116
117if ~success
118    configs_fail = configs{rel_tol_ind,abs_tol_ind,experiment_idx};
119    configs_fail.SolverOptions.AbsoluteTolerance = settings.abstol;
120    configs_fail.SolverOptions.RelativeTolerance = settings.reltol;
121    results.simd{experiment_idx} = ...
122    sbiosimulate(models{rel_tol_ind,abs_tol_ind,experiment_idx},...
123        configs_fail);
124else
125    % simulate the model using matlab built in function
126    results.simd{experiment_idx} = ...
127        sbiosimulate(models{rel_tol_ind,abs_tol_ind,experiment_idx},...
128        configs{rel_tol_ind,abs_tol_ind,experiment_idx});
129end
130end

Description

Simulates the model with the provided configurations. The first time it is run it loads a representation of the model and the simulation, and compiles this information to C code.

Input Arguments

  • exp_n - (double) Unique number to identify the model for each experiment or equilibrium reaction (it needs a new model object for each one)

  • stg - stg.expn, stg.name, stg.sbioacc

  • rt

    • rt.ssa - (double) steady state amounts

    • rt.par - (double) All parameters of the model, takes the default ones from SBtab and then replaces the ones being worked on.

  • rst - rst.simd

Output Arguments

Functions called - Sbioaccelerate, Sbiosimulate Loaded variables - Ready to run model, Ready to run model equilibration

f_score

Code

  1function results = f_score(results, settings, model_folders)
  2% This function calculates the score for a set of simulated results by
  3% comparing them to experimental data. It computes the score for each
  4% dataset and experiment and then calculates the total score based on the
  5% selected scoring strategy. The score serves as a metric for comparing the
  6% accuracy of different simulations or models.
  7%
  8% Inputs:
  9% - rst: Structure containing the simulation results and scores.
 10% - stg: Structure containing the settings for the scoring strategy, such
 11% as the option to use log10 scaling, error score, and other options.
 12% - mmf: Structure containing the model directory information.
 13%
 14% Outputs:
 15% - rst: Updated structure containing the calculated scores for each
 16% dataset, experiment, and the total score.
 17%
 18% Used Functions:
 19% - calculate_score_per_experiment: Calculates the score for each
 20% experiment.
 21% - calculate_score_per_dataset: Calculates the score for each dataset in
 22% an experiment.
 23% - f_normalize: Normalizes the simulation results for a dataset.
 24%
 25% Variables:
 26% Loaded:
 27% - Data: Experimental data.
 28% - sbtab: sbtab structure containing dataset information.
 29%
 30% Persistent:
 31% - sbtab: sbtab structure containing dataset information (persistent).
 32% - Data: Experimental data (persistent).
 33
 34persistent sbtab
 35persistent Data
 36
 37data_model = model_folders.model.data.data_model;
 38
 39% Import the data on the first run
 40if isempty(Data)
 41    load(data_model,'Data','sbtab')
 42end
 43
 44% Iterate over the number of experiments
 45for n = settings.exprun
 46    results = calculate_score_per_experiment(results, settings, n, ...
 47        model_folders, sbtab, Data);
 48end
 49
 50% Calculate the total score
 51results.st = sum(results.se);
 52
 53% Calculate the log10 of total score if option selected
 54if settings.useLog == 3
 55    results.st = log10(results.st);
 56end
 57end
 58
 59function results = ...
 60    calculate_score_per_experiment(results, settings, n, model_folders, ...
 61    sbtab, Data)
 62
 63% Iterate over the number of datasets per experiment
 64for j = 1:size(sbtab.datasets(n).output, 2)
 65    results = ...
 66        calculate_score_per_dataset(results, settings, n, j, ...
 67        model_folders, Data);
 68end
 69% Calculate score per experiment
 70results.se(n, 1) = sum(results.sd(:, n));
 71
 72% Calculate the log10 of experiment score if option selected
 73if settings.useLog == 2
 74    results.se(n, 1) = log10(results.se(n, 1));
 75end
 76
 77end
 78
 79function results = ...
 80    calculate_score_per_dataset(results, settings, n, j, model_folders, ...
 81    Data)
 82
 83% Calculate score per dataset if there are no errors
 84if results.simd{n} ~= 0
 85    data = Data(n).Experiment.x(:, j);
 86    data_sd = Data(n).Experiment.x_SD(:, j);
 87
 88    number_points = size(Data(n).Experiment.x(:, j), 1);
 89    [sim_results_norm,~,sim_results] = ...
 90        f_normalize(results, settings, n, j, model_folders);
 91
 92    if ~isempty(sim_results_norm)
 93        sim_results = sim_results_norm;
 94    end
 95    results.xfinal{n, 1}(j) = sim_results(end);
 96
 97    % Calculate score using formula that accounts for normalization
 98    % with the starting point of the result
 99    switch settings.useLog
100        case {0, 2, 3}
101            results.sd(j, n) = ...
102                sum(((data - sim_results) ./ (data_sd)).^2) / ...
103                number_points;
104        case 1
105            results.sd(j, n) = ...
106                max(0, log10(sum(((data - sim_results) ./ ...
107                (data_sd)).^2) / number_points));
108        case 4
109            results.sd(j, n) = ...
110                sum(((data - sim_results) ./ ...
111                (data_sd * sqrt(number_points))).^2);
112        otherwise
113            error('Invalid value for stage.useLog: %d', settings.useLog);
114    end
115
116    if results.sd(j, n) == inf || isnan(results.sd(j, n))
117        results.sd(j, n) = settings.errorscore;
118        results.xfinal{n, 1}(j) = 0;
119    end
120
121    % If there are errors output a very high score value (10^10)
122elseif results.simd{n} == 0 %|| rst.sd(j, n) == inf || isnan(rst.sd(j, n))
123    switch settings.useLog
124        case {1}
125            results.sd(j, n) = log10(settings.errorscore);
126        case {0, 2, 3, 4}
127            results.sd(j, n) = settings.errorscore;
128    end
129    results.xfinal{n, 1}(j) = 0;
130end
131end

Description

The f_score function computes the score for a given set of simulated results by comparing them with the experimental data. The function calculates the score for each dataset and experiment, and then computes the total score based on the selected scoring strategy. The score serves as a metric for comparing the accuracy of different simulations or models.

Input Arguments

  • rst: Structure containing the simulation results and scores.

  • stg: Structure containing the settings for the scoring strategy, such as the option to use log10 scaling, error score, and other options.

  • mmf: Structure containing the model information, including the data model.

Output Arguments

  • rst.st: Updated structure containing the calculated scores for each dataset, experiment, and the total score.

Example

% Define the input structures and settings
stg.useLog = 1;
stg.errorscore = 1e10;
stg.exprun = 1:3;
mmf.model.data.data_model = matlab model file
rst.simd = matlab output from f_prep_sim

% Call the f_score function
rst = f_score(rst, stg, mmf);

This example demonstrates how to call the f_score function with the input structures and settings. The function calculates the scores for the given simulation results based on the scoring strategy defined in the stg structure.

f_normalize

Code

  1function [sim_results_norm,sim_results_detailed,sim_results] = ...
  2f_normalize(results, settings, exp_number, output_number, model_folders)
  3% This function processes and normalizes simulation results based on a
  4% specified normalization method. It accepts a set of inputs, including the
  5% simulation results, settings, experiment and output numbers, and a model
  6% metafile structure. The function returns normalized simulation results,
  7% along with detailed normalized simulation results if the 'simdetail'
  8% setting is enabled.
  9%
 10% Inputs:
 11% - rst: Structure containing the simulation results and scores
 12% - stg: Structure containing the settings for the simulation
 13% - exp_number: An integer representing the experiment number
 14% - output_number: An integer representing the output number
 15% - mmf: Structure containing the model directory information
 16%
 17% Outputs:
 18% - sim_results: A matrix containing the normalized simulation results
 19% - sim_results_detailed: A matrix containing the detailed normalized
 20% simulation results (if stg.simdetail is true)
 21%
 22% Used Functions:
 23% - extract_data: Helper function to extract data from the simulation
 24% results
 25%
 26% Variables
 27% Persistent:
 28% - sbtab: SBtab structure
 29% - Data: Loaded data from the model
 30% - sb: Structure containing experiment IDs
 31
 32persistent sbtab
 33persistent Data
 34persistent sb
 35
 36sim_results_norm = [];
 37
 38% Load Data and sbtab if empty
 39if isempty(Data)
 40    load(model_folders.model.data.data_model, 'Data', 'sbtab','sb')
 41end
 42
 43% Extract the data from the simulation results
 44sim_results = extract_data(results, exp_number, output_number, sbtab);
 45sim_results_detailed = [];
 46
 47% Check if detailed simulation results are requested
 48if settings.simdetail
 49    sim_results_detailed =...
 50        extract_data(results, exp_number + 2 * settings.expn, ...
 51        output_number, sbtab);
 52end
 53
 54% Get the normalization method
 55normalize = sbtab.datasets(exp_number).Normalize;
 56
 57% Perform normalization if a method is specified
 58if ~isempty(normalize)
 59    output_ID = sbtab.datasets(exp_number).output_ID{output_number}{:};
 60    norm_factor = extract_data(results, exp_number, output_number, sbtab);
 61    sim_results_norm = sim_results;
 62
 63    % Normalize by the maximum value
 64    if contains(normalize, 'Max') && contains(normalize, output_ID)
 65        max_norm = max(norm_factor);
 66        if max_norm == 0
 67            max_norm = 1;
 68        end
 69        sim_results_norm = sim_results / max_norm;
 70        if settings.simdetail
 71            sim_results_detailed = sim_results_detailed / max_norm;
 72        end
 73    end
 74
 75    % Normalize to a value between 0 and 1
 76    if contains(normalize, 'Norm') && contains(normalize, output_ID)
 77        max_norm = max(norm_factor(2:end));% Here because sometimes the first value presents strange results
 78        min_norm = min(norm_factor(2:end));% Here because sometimes the first value presents strange results
 79        if max_norm-min_norm == 0
 80            max_norm = 1;
 81            min_norm = 0;
 82        end
 83        sim_results_norm = (sim_results-min_norm) / (max_norm-min_norm);
 84        sim_results_norm(1) = sim_results_norm(2);% Here because sometimes the first value presents strange results
 85        if settings.simdetail
 86            sim_results_detailed = (sim_results_detailed-min_norm) / (max_norm-min_norm);
 87        end
 88    end
 89
 90
 91    % Normalize by the minimum value
 92    % if contains(normalize, 'Min') && contains(normalize, output_ID)
 93    % 
 94    %     min_norm = min(norm_factor);
 95    %     sim_results = sim_results / min_norm;
 96    %     min_norm
 97    %     if settings.simdetail
 98    %         sim_results_detailed = sim_results_detailed / min_norm;
 99    %     end
100    % end
101
102    % Normalize by time-dependent factors
103    if contains(normalize, 'Time') && contains(normalize, output_ID)
104        t_size = size(Data(exp_number).Experiment.t, 1);
105        for n = 1:t_size
106            exp_ID = getfield(sb, ['E' num2str(exp_number - 1) '.ID'], n);
107            if contains(normalize, exp_ID)
108                sim_results_norm = sim_results / norm_factor(n);
109                if settings.simdetail
110                    sim_results_detailed = ...
111                    sim_results_detailed / norm_factor(n);
112                end
113            end
114        end
115    end
116end
117end
118
119% Helper function to extract data
120function data = extract_data(results, exp_number, output_number, sbtab)
121% Helper function to extract data from the simulation results
122% Input arguments:
123% rst  - Structure containing the simulation results and scores.
124% stg  - Structure containing the settings for the simulation.
125% output_number - An integer representing the output number.
126% sbtab - SBtab structure
127% Output argument:
128% data - extracted data from the simulation results
129    data = results.simd{1, exp_number}.Data(:, end - ...
130        size(sbtab.datasets(exp_number).output, 2) + output_number);
131end

Description

The f_normalize function processes and normalizes simulation results based on a specified normalization method. It accepts a set of inputs, including the simulation results, settings, experiment and output numbers, and a model metafile structure. The function returns normalized simulation results, along with detailed normalized simulation results if the ‘simdetail’ setting is enabled.

Input Arguments

  • rst: A structure containing the simulation results.

  • stg: A structure containing the settings for the simulation.

  • exp_number: An integer representing the experiment number.

  • output_number: An integer representing the output number.

  • mmf: A structure containing the model metafile information.

Output Arguments

  • sim_results: A matrix containing the normalized simulation results.

  • sim_results_detailed: A matrix containing the detailed normalized simulation results (if stg.simdetail is true).