Simulation and Scoring

f_sim_score

Code

 1function [score,rst,rst_not_simd] = f_sim_score(parameters,stg,mmf)
 2
 3%Turn off Dimension analysis warning from simbiology
 4warning('off','SimBiology:DimAnalysisNotDone_MatlabFcn_Dimensionless')
 5
 6% Call the function that simulates the model
 7rst = f_prep_sim(parameters,stg,mmf);
 8
 9% Call the function that scores
10rst = f_score(rst,stg,mmf);
11
12% Get the total score explicitly for optimization functions
13score = rst.st;
14
15rst_not_simd = rmfield( rst , 'simd');
16end

Calls the function that runs the simulations and the function that scores the output of the runs.

f_prep_sim

Code

  1function rst = f_prep_sim(parameters,stg,mmf)
  2
  3% Save variables that need to be mantained over multiple function calls
  4% persistent modelobj
  5persistent sbtab
  6persistent Data
  7
  8data_model = mmf.model.data.data_model;
  9
 10% Import the data on the first run
 11if isempty(sbtab)
 12    
 13    %Find correct path for loading depending on the platform
 14    load(data_model,'Data','sbtab')
 15end
 16
 17% Set the parameters that are going to be used for the simulation to the
 18% default ones as definded in the SBTAB
 19rt.par(:,1) = [sbtab.defpar{:,2}];
 20
 21% Check if the parametrer needs to be set to the value relevant for Profile
 22% Likelihood
 23if isfield(stg,"PLind") && isfield(stg,"PLval")
 24    parameters = [parameters(1:stg.PLind-1) stg.PLval parameters(stg.PLind:end)];
 25end
 26
 27% Iterate over all the parameters of the model
 28for n = 1:size(rt.par,1)
 29    
 30    % Check that a parameter should be changed from default
 31    if stg.partest(n) > 0
 32        
 33        % Set the parameters are being tested
 34        rt.par(n) = 10.^(parameters(stg.partest(n,1)));
 35    end
 36    
 37    if isfield(stg,'tci')
 38        
 39        % Check that there are thermodynamic constraints to implement
 40        if ~isempty(stg.tci)
 41            
 42            % Choose the parameters that need to be calculated with other
 43            % parameters due to thermodynamic constraints
 44            if ismember(n,stg.tci)
 45                
 46                % Check that a parameter should be changed from default
 47                if stg.partest(n) > 0
 48                    
 49                    % Iterate over the parameters that need to be mutiplied
 50                    % for calculating the parameter that depends on the
 51                    % thermodynamic constraints
 52                    for m = 1:size(stg.tcm,2)
 53                        
 54                        % Check that the parameter that is going to be used
 55                        % to calculate the parameter dependent on
 56                        % thermodynamic constraintsis is not the default
 57                        if stg.partest(stg.tcm(n,m),1) > 0
 58                            
 59                            % Check if the parametrer needs to be set to
 60                            % the value relevant for Profile Likelihood
 61                            if isfield(stg,"PLind")
 62                                if stg.partest(stg.tcm(n,m),1) ==...
 63                                        stg.PLind
 64                                    parameters(stg.partest(...
 65                                        stg.tcm(n,m),1))...
 66                                        = stg.PLval;
 67                                end
 68                            end
 69                            
 70                            % Make the appropriate multiplications to get
 71                            % the thermodinamicly constrained parameter
 72                            rt.par(n) = rt.par(n).*(10.^...
 73                                (parameters(stg.partest(...
 74                                stg.tcm(n,m),1))));
 75                        else
 76                            
 77                            % Make the appropriate multiplications to get
 78                            % the thermodinamicly constrained parameter
 79                            rt.par(n) = rt.par(n).*...
 80                                (sbtab.defpar{stg.tcm(n,m),2});
 81                        end
 82                    end
 83                    
 84                    % Iterate over the parameters that need to be divided
 85                    % for calculating the parameter that depends on the
 86                    % thermodynamic constraints
 87                    for m = 1:size(stg.tcd,2)
 88                        
 89                        % Check that the parameter that is going to be used
 90                        % to calculate the parameter dependent on
 91                        % thermodynamic constraintsis is not the default
 92                        if stg.partest(stg.tcd(n,m),1) > 0
 93                            
 94                            % Check if the parametrer needs to be set to
 95                            % the value relevant for Profile Likelihood
 96                            if isfield(stg,"PLind")
 97                                if stg.partest(stg.tcd(n,m),1) ==...
 98                                        stg.PLind
 99                                    parameters(stg.partest(...
100                                        stg.tcd(n,m),1))...
101                                        = stg.PLval;
102                                end
103                            end
104                            % Make the appropriate divisions to get the
105                            % thermodinamicly constrained parameter
106                            rt.par(n) = rt.par(n)./(10.^...
107                                (parameters(stg.partest(...
108                                stg.tcd(n,m),1))));
109                        else
110                            
111                            % Make the appropriate divisions to get the
112                            % thermodinamicly constrained parameter
113                            rt.par(n) = rt.par(n)./...
114                                (sbtab.defpar{stg.tcd(n,m),2});
115                        end
116                    end
117                end
118            end
119        end
120    end
121end
122
123%  Set the start amount for the species in the model to 0
124rt.ssa = zeros(size(sbtab.species,1),max(stg.exprun));
125
126% Initialize the results variable
127rst = [];
128rst.parameters = rt.par;
129% Iterate over all the experiments that are being run
130for n = stg.exprun
131    
132    % Try catch used because iterations errors can happen unexectedly and
133    % we want to be able to continue simulations
134    try
135        
136        % If the correct setting is chosen display messages to console
137        if stg.simcsl
138            disp("Running dataset number " + n +...
139                " of " + stg.exprun(end))
140        end
141        
142        % Check that this is not the first time the experiments are being
143        % run and that the start values for the species are different from
144        % the previous experiment
145        if n ~= stg.exprun(1) && ...
146                min([sbtab.datasets(n).start_amount{:,2}] ==...
147                [sbtab.datasets(max(1,stg.exprun(...
148                find(stg.exprun==n)-1))).start_amount{:,2}])
149            
150            
151            % Set the values of the start amounts to the values obtained
152            % after the first equilibration
153            rt.ssa(:,n) =...
154                rt.ssa(:,stg.exprun(find(stg.exprun==n)-1));
155            if stg.simdetail
156                rt.ssa(:,n+2*stg.expn) =...
157                    rt.ssa(:,stg.exprun(find(stg.exprun==n)-1));
158            end
159        else
160            
161            % Iterate over the numbre of species that need a starting value
162            % different than 0
163            for j = 1:size(sbtab.datasets(n).start_amount,1)
164                
165                % Set the start amount of the species to the number defined
166                % in the sbtab for each experiment
167                rt.ssa(sbtab.datasets(n...
168                    ).start_amount{j,3},n+stg.expn) =...
169                    sbtab.datasets(n).start_amount{j,2};
170            end
171            
172            % Equilibrate the model
173            rst = f_sim(n+stg.expn,stg,rt,rst,mmf);
174            
175            for j = 1:size(sbtab.species,1)
176                
177                % Set the starting amount for species that after
178                % equilibrium have very low values to zero
179                if rst.simd{n+stg.expn}.Data(end,j) < 1.0e-15
180                    rt.ssa(j,n) = 0;
181                    
182                    % Set the starting amount for the rest of the species
183                else
184                    rt.ssa(j,n) =...
185                        rst.simd{n+stg.expn}.Data(end,j);
186                    if stg.simdetail
187                        rt.ssa(j,n+2*stg.expn) =...
188                            rst.simd{n+stg.expn}.Data(end,j);
189                    end
190                end
191            end
192        end
193        
194        % Simulate the model
195        rst = f_sim(n,stg,rt,rst,mmf);
196        
197        try
198            if stg.simdetail
199                rst = f_sim(n+2*stg.expn,stg,rt,rst,mmf);
200            end
201        catch
202        end
203        
204        % Check If the times of the simultaion output and the simulation
205        % data from SBTAB match, if they don't it means that the simulator
206        % didn't had enough time to run the model (happens in some
207        % unfavorable configurations of parameters, controlled by stg.maxt
208        if size(Data(n).Experiment.t,1) ~=...
209                size(rst.simd{n}.Data(:,end),1)
210            
211            % Set the simulation output to be 0, this is a non function
212            % value that the score function expects in simulations that did
213            % not worked properly
214            rst.simd{n} = 0;
215        end
216    catch
217        
218        % Set the simulation output to be 0, this is a non function value
219        % that the score function expects in simulations that did not
220        % worked properly
221        rst.simd{n} = 0;
222    end
223end
224end

Prepares the simulation making sure that an equilibration is preformed when necessary before running the main simulation.

f_sim

Code

 1function rst = f_sim(exp_n,stg,rt,rst,mmf)
 2
 3% Save variables that need to be mantained over multiple function calls
 4persistent model_run
 5persistent config_run
 6
 7% If the function is called for the first time, load the appropriate model
 8% and compile the code for simulation run
 9if isempty(model_run)
10    
11    warning('off','SimBiology:InvalidSpeciesInitAmtUnits')
12    
13    %Generate an empty array to be populated with the model suited for each
14    %equilibration and experiment%
15    model_run = cell(1,stg.expn*2);
16    config_run = cell(1,stg.expn*2);
17    
18    model_exp_default = mmf.model.data.model_exp.default;
19    model_exp_eq = mmf.model.data.model_exp.equilibration;
20    model_exp_detail = mmf.model.data.model_exp.detail;
21    
22    % Iterate over the experiments thar are being run
23    for n = stg.exprun
24        
25        if stg.simdetail
26            % Load the models for equilibrium
27            load(model_exp_detail + n + ".mat",'model_exp','config_exp')
28
29            % Place the loaded models in the correct place in the array,
30            % models for equilibrium are set to be on the second half of
31            % the array
32            model_run{n+2*stg.expn} = model_exp;
33            config_run{n+2*stg.expn} = config_exp;
34            
35            % Compile the matlab code that is going to simulate the model
36            % using matlab built in function if the option is selected in
37            % settings
38            if stg.sbioacc
39                sbioaccelerate(model_run{n+2*stg.expn},config_run{n+2*stg.expn});
40            end
41        end
42        % Load the models for equilibrium
43        load(model_exp_eq + n + ".mat",'model_exp','config_exp')
44
45        % Place the loaded models in the correct place in the array, models
46        % for equilibrium are set to be on the second half of the array
47        model_run{n+stg.expn} = model_exp;
48        config_run{n+stg.expn} = config_exp;
49        
50        % Compile the matlab code that is going to simulate the model using
51        % matlab built in function if the option is selected in settings
52        if stg.sbioacc
53            sbioaccelerate(model_run{n+stg.expn},config_run{n+stg.expn});
54        end
55        
56        % Load the models for main run
57        load(model_exp_default + n + ".mat",'model_exp','config_exp')
58        
59        % Place the loaded models in the correct place in the array, models
60        % for main run are set to be on the first half of the array
61        model_run{n} = model_exp;
62        config_run{n} = config_exp;
63        
64        % Compile the matlab code that is going to simulate the model using
65        % matlab built in function if the option is selected in settings
66        if stg.sbioacc
67            sbioaccelerate(model_run{n},config_run{n});
68        end
69    end
70end
71
72% substitute the start amount of the species in the model with the correct
73% ones for  simulations
74set(model_run{exp_n}.species(1:size(rt.ssa(:,exp_n),1)),{'InitialAmount'},num2cell(rt.ssa(:,exp_n)))
75
76% Substitute the values of the parameters in the model for the correct one
77% for simultaions
78set(model_run{exp_n}.parameters(1:size(rt.par,1)),{'Value'},num2cell(rt.par))
79
80%simulate the model using matlab built in function
81rst.simd{exp_n} = sbiosimulate(model_run{exp_n},config_run{exp_n});
82end

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.

f_score

Code

 1function rst = f_score(rst,stg,mmf)
 2
 3persistent sbtab
 4persistent Data
 5
 6data_model = mmf.model.data.data_model;
 7
 8% Import the data on the first run
 9if isempty(Data)
10    load(data_model,'Data','sbtab')
11end
12
13% Iterate over the number of experiments
14for n = stg.exprun
15    
16    % Iterate over the number of datasets per experiment
17    for j = 1:size(sbtab.datasets(n).output,2)
18        
19        % Calculate score per dataset if there are no errors
20        if rst.simd{n} ~= 0
21            
22            data = Data(n).Experiment.x(:,j);
23            data_sd = Data(n).Experiment.x_SD(:,j);
24            number_points = size(Data(n).Experiment.x(:,j),1);
25            sim_results = f_normalize(rst,stg,n,j,mmf);
26            rst.xfinal{n,1}(j) = sim_results(end);
27            
28            % Calculate score using formula that accounts for normalization
29            % with the starting point of the result
30            if stg.useLog == 4
31                rst.sd(j,n) = sum(((data-sim_results)./...
32                    (data_sd*sqrt(number_points))).^2);
33                 rst.sdtest(j,n) = sum(((data-sim_results)./...
34                     (data_sd*sqrt(number_points))).^2);
35
36%             elseif stg.useLog == 5  
37%                 rst.sd{n,1}(j) = sum(((data-sim_results)./...
38%                         (data_sd)).^2);
39            else
40                    rst.sd(j,n) = sum(((data-sim_results)./...
41                        (data_sd)).^2)/(number_points);
42                    rst.sdtest(j,n) = sum(((data-sim_results)./...
43                        (data_sd)).^2)/(number_points);
44            end
45            
46            % If there are errors output a very high score value (10^10)
47        elseif rst.simd{n} == 0 || rst.sd(n,j) == inf
48            
49                rst.sd(n,j) = stg.errorscore;
50                rst.xfinal{n,1}(j) = 0;
51%                 rst.sdtest(j,n) = stg.errorscore;
52        end
53%         rst.sd{n,1}(j)
54%         rst.sdtest(j,n)
55% max(0,log10(rst.sd{n,1}(j)));
56% max(0,log10(rst.sdtest(j,n)));
57
58        % Calculate the log10 of dataset score if option selected
59        if stg.useLog == 1
60            rst.sd(j,n) = max(0,log10(rst.sd(j,n)));
61        end
62    end
63
64    % Calculate score per experiment
65    rst.se(n,1) = sum(rst.sd(:,n));
66%     rst.setest(n,1) = sum(rst.sdtest(:,n));
67    
68    % Calculate the log10 of experiment score if option selected
69    if stg.useLog == 2
70        rst.se(n,1) = log10(rst.se(n,1));
71    end
72end
73
74% Calculate score per experiment
75rst.st = sum(rst.se);
76
77% Calculate the log10 of total score if option selected
78if stg.useLog == 3
79    rst.st = log10(rst.st);
80end
81end

Uses the results from the simulation of the model and the Data provided via the SBTAB to calculate a score for a given parameter set.