|
| 1 | +%% Spatial Compartement FIM Comparison |
| 2 | +clear |
| 3 | +close all |
| 4 | +addpath(genpath('../../../src')); |
| 5 | + |
| 6 | +%% Compare Determinate of the Different Models Parameter Uncertanty |
| 7 | +% Params |
| 8 | +rng('shuffle'); |
| 9 | +numSamplesToGenerate = 2; |
| 10 | + |
| 11 | +% Generate Sample for Single Spatial Model |
| 12 | +GaussianSampler_4D = @SampleUniformDistribution; |
| 13 | +mins = ones(1,4).* 0.001; |
| 14 | +maxs = ones(1,4).*1000; |
| 15 | +GaussianSampler_4D(1, mins, maxs); |
| 16 | +model1Generator = @GenerateSingleSpatialStateModel; |
| 17 | +SingleSpatial_Results = GenerateTableFromSampling(model1Generator, GaussianSampler_4D, numSamplesToGenerate, nan); |
| 18 | + |
| 19 | +% Generate Samples for Two Component Spatial Model Pair to the first |
| 20 | +GaussianSampler_1D = @SampleUniformDistribution; |
| 21 | +mins = 0.001; |
| 22 | +maxs = 1000; |
| 23 | +GaussianSampler_1D(size(SingleSpatial_Results,1), mins, maxs); |
| 24 | +model2Generator = @GenerateTwoSpatialStateModel; |
| 25 | +TwoSpatial_Results = GenerateTableFromPairSamples(model2Generator, GaussianSampler_1D, 4, SingleSpatial_Results, {'kon', 'koff', 'kr', 'kd'}, 4); |
| 26 | + |
| 27 | +% Generate Samples for Two Component Spatial Model Pair to the first |
| 28 | +GaussianSampler_1D = @SampleUniformDistribution; |
| 29 | +mins = 0.001; |
| 30 | +maxs = 1000; |
| 31 | +GaussianSampler_1D(size(SingleSpatial_Results,1), mins, maxs); |
| 32 | +model3Generator = @GenerateThreeSpatialStateModel; |
| 33 | +ThreeSpatial_Results = GenerateTableFromPairSamples(model3Generator, GaussianSampler_1D, [4, 5], TwoSpatial_Results, {'kon', 'koff', 'kr', 'D', 'kd'}, 4); |
| 34 | + |
| 35 | + |
| 36 | +% Merge Results |
| 37 | +results = join(TwoSpatial_Results, ThreeSpatial_Results, Keys={'kon', 'koff', 'kr', 'kd', 'D'}); |
| 38 | +results = join(SingleSpatial_Results, results, Keys={'kon', 'koff', 'kr', 'kd'}); |
| 39 | + |
| 40 | +uniqueFileName = 'ParamSearch_' + string(datetime('now', 'Format', 'yyyyMMdd_HHmmss_SSS')) + '.mat'; |
| 41 | +fileName = fullfile(uniqueFileName); |
| 42 | +save(fileName, 'results') |
| 43 | + |
| 44 | +%% Parameter Generators |
| 45 | +function points = SampleMultiVariableGaussian(varargin) |
| 46 | + persistent numSamples means covMatrix; |
| 47 | + % If this is the first call, initialize the persistent variables |
| 48 | + % If new parameters are provided, update the persistent variables |
| 49 | + if nargin == 3 |
| 50 | + numSamples = varargin{1}; % Update number of samples |
| 51 | + means = varargin{2}; % Update mean |
| 52 | + vars = varargin{3}; % Update standard deviation |
| 53 | + covMatrix = diag(vars.^2); % Diagonal matrix with variances (std^2) on the diagonal |
| 54 | + end |
| 55 | + |
| 56 | + if ~isempty(numSamples) && ~isempty(covMatrix) && ~isempty(means) |
| 57 | + points = mvnrnd(means, covMatrix, numSamples); |
| 58 | + points(points < 0) = 0.0001; |
| 59 | + end |
| 60 | +end |
| 61 | + |
| 62 | +function points = SampleUniformDistribution(varargin) |
| 63 | + persistent numSamples mins maxs; |
| 64 | + % If this is the first call, initialize the persistent variables |
| 65 | + % If new parameters are provided, update the persistent variables |
| 66 | + if nargin == 3 |
| 67 | + numSamples = varargin{1}; % Update number of samples |
| 68 | + mins = varargin{2}; |
| 69 | + maxs = varargin{3}; |
| 70 | + end |
| 71 | + |
| 72 | + if ~isempty(numSamples) && ~isempty(mins) && ~isempty(maxs) |
| 73 | + points = rand(numSamples, length(maxs)); |
| 74 | + points = mins + (maxs-mins) .* points; |
| 75 | + end |
| 76 | +end |
| 77 | + |
| 78 | + |
| 79 | +%% Model Creation |
| 80 | +function model = GenerateSingleSpatialStateModel(varargin) |
| 81 | +%{ |
| 82 | + kon kr kd |
| 83 | +gene_off <-> gene_on -> RNA -> 0 |
| 84 | + koff |
| 85 | +%} |
| 86 | + varargin = varargin{1}; % IDK where the extra cell comes from please explain |
| 87 | + model = SSIT(); |
| 88 | + model.parameters = {'kon',varargin(1); 'koff',varargin(2); 'kr',varargin(3); 'kd',varargin(4)}; |
| 89 | + model.species = {'gene_on';'gene_off'; 'RNA'}; |
| 90 | + model.stoichiometry = [1, -1, 0, 0;... |
| 91 | + -1, 1, 0, 0;... |
| 92 | + 0, 0, 1, -1]; |
| 93 | + model.propensityFunctions = {'kon*gene_off';'koff*gene_on';'kr*gene_on'; 'kd*RNA'}; |
| 94 | + model.initialCondition = [0;1;0;]; |
| 95 | + model.summarizeModel |
| 96 | + model = model.formPropensitiesGeneral('OneComparment_SpatialModel'); |
| 97 | +end |
| 98 | + |
| 99 | +function model = GenerateTwoSpatialStateModel(varargin) |
| 100 | +%{ |
| 101 | + kon kr D kd |
| 102 | +gene_off <-> gene_on -> RNA -> Distance RNA -> 0 |
| 103 | + koff |
| 104 | +%} |
| 105 | + |
| 106 | + model = SSIT(); |
| 107 | + varargin = varargin{1}; % IDK where the extra cell comes from please explain |
| 108 | + model.parameters = {'kon',varargin(1);'koff',varargin(2);'kr',varargin(3); 'D', varargin(4); 'kd', varargin(5)}; |
| 109 | + model.species = {'gene_on';'gene_off'; 'RNA'; 'D_RNA'}; |
| 110 | + model.stoichiometry = [1, -1, 0, 0, 0;... % species x reaction |
| 111 | + -1, 1, 0, 0, 0;... |
| 112 | + 0, 0, 1, -1, 0;... |
| 113 | + 0, 0, 0, 1, -1;]; |
| 114 | + model.propensityFunctions = {'kon*gene_off';'koff*gene_on';'kr*gene_on'; 'D*RNA'; 'kd*D_RNA'}; |
| 115 | + model.initialCondition = [0;1;0;0;]; |
| 116 | + model.summarizeModel |
| 117 | + model = model.formPropensitiesGeneral('TwoComparment_SpatialModel'); |
| 118 | +end |
| 119 | + |
| 120 | +function model = GenerateThreeSpatialStateModel(varargin) |
| 121 | +%{ |
| 122 | + kon kr kt D kd |
| 123 | +gene_off <-> gene_on -> Nascent RNA -> Near RNA -> Far RNA -> 0 |
| 124 | + koff |
| 125 | +%} |
| 126 | + |
| 127 | + model = SSIT(); |
| 128 | + varargin = varargin{1}; % IDK where the extra cell comes from please explain |
| 129 | + model.parameters = {'kon',varargin(1);'koff',varargin(2);'kr',varargin(3); 'kt',varargin(4); 'D', varargin(5); 'kd', varargin(6)}; |
| 130 | + model.species = {'gene_on';'gene_off'; 'nascent_RNA'; 'close_RNA'; 'distant_RNA'}; |
| 131 | + model.stoichiometry = [1, -1, 0, 0, 0, 0;... |
| 132 | + -1, 1, 0, 0, 0, 0;... |
| 133 | + 0, 0, 1, -1, 0, 0;... |
| 134 | + 0, 0, 0, 1, -1, 0;... |
| 135 | + 0, 0, 0, 0, 1, -1;]; |
| 136 | + model.propensityFunctions = {'kon*gene_off';'koff*gene_on'; 'kr*gene_on'; 'kt*nascent_RNA'; 'D*close_RNA'; 'kd*distant_RNA'}; |
| 137 | + model.initialCondition = [0;1;0;0;0;]; |
| 138 | + model.summarizeModel |
| 139 | + model = model.formPropensitiesGeneral('ThreeComparment_SpatialModel'); |
| 140 | +end |
| 141 | + |
| 142 | + |
| 143 | +%% FSP Solver, Soles Sensitivity, Computes FIM |
| 144 | +function [FIMTotal, FSPsoln, bounds, mleCovEstimate, fimMetrics] = GenerateFSP(model) |
| 145 | + % (2) Solve FSP for model |
| 146 | + model.solutionScheme = 'FSP'; % Set solution scheme to FSP. |
| 147 | + [FSPsoln,model.fspOptions.bounds] = model.solve; % Solve the FSP analysis |
| 148 | + |
| 149 | + % (3) Solve FSP Sensitivity |
| 150 | + model.solutionScheme = 'fspSens'; % Set solutions scheme to FSP Sensitivity |
| 151 | + [sensSoln,bounds] = model.solve(FSPsoln.stateSpace); % Solve the sensitivity problem |
| 152 | + |
| 153 | + % (4) Compute FIM using FSP Sensitivity Results |
| 154 | + fimResults = model.computeFIM(sensSoln.sens); % Compute the FIM for full observations and no distortion. |
| 155 | + cellCounts = 10*ones(size(model.tSpan)); % Number of cells in each experiment. |
| 156 | + [FIMTotal,mleCovEstimate,fimMetrics] = model.evaluateExperiment(fimResults,cellCounts); |
| 157 | +end |
| 158 | + |
| 159 | + |
| 160 | +%% Compute Determinates and making them samples |
| 161 | +function determinates = CalcDeterminate(FIMTotal, fimMetrics, paramOfInterestIndex) |
| 162 | + % TODO: Add prior to known parameter |
| 163 | + % TODO: play with fimMetric IDK what these are yet |
| 164 | + % TODO: Return a determinate for each parameter unknown known and |
| 165 | + % combos |
| 166 | + totalCombinations = sum(1:nchoosek(length(paramOfInterestIndex),1)); % Calculating total elements |
| 167 | + combinations = cell(1, totalCombinations); % Preallocate a cell array |
| 168 | + index = 1; |
| 169 | + for k = 1:length(paramOfInterestIndex) |
| 170 | + % Use nchoosek to generate all k-combinations of the vector |
| 171 | + comb = nchoosek(paramOfInterestIndex, k); |
| 172 | + |
| 173 | + % Add each combination as a cell array |
| 174 | + for i = 1:size(comb, 1) |
| 175 | + combinations{index} = comb(i, :); |
| 176 | + index = index + 1; % Move to the next index |
| 177 | + end |
| 178 | + end |
| 179 | + |
| 180 | + totalVarNames = 2*length(combinations); |
| 181 | + % Initialize an empty cell array for the variable names |
| 182 | + tempNames = cell(1, totalVarNames); % Start with the base name |
| 183 | + counter = 1; |
| 184 | + for i = 1:length(combinations) |
| 185 | + comboStr = num2str(combinations{i}); % Convert combination to string |
| 186 | + comboStr = strrep(comboStr, ' ', ''); % Remove spaces from the string |
| 187 | + tempNames{counter} = [comboStr '-known_param_determinate']; % Append combination to base name |
| 188 | + tempNames{counter+1} = [comboStr '-unknown_param_determinate']; % Append combination to base name |
| 189 | + counter = counter + 2; |
| 190 | + end |
| 191 | + varNames = string(tempNames); |
| 192 | + |
| 193 | + deter = NaN(1, totalVarNames); |
| 194 | + count = 1; |
| 195 | + for j = combinations |
| 196 | + A = cell2mat(FIMTotal); |
| 197 | + for i = j |
| 198 | + % Known and Unknown Parameter determinate for a given j |
| 199 | + i = i{1}; |
| 200 | + covar_A = inv(A); |
| 201 | + if ~isnan(paramOfInterestIndex) |
| 202 | + A = A([1:i-1, i+1:end], [1:i-1, i+1:end]); |
| 203 | + covar_A = covar_A([1:i-1, i+1:end], [1:i-1, i+1:end]); |
| 204 | + end |
| 205 | + covar_B = inv(A); |
| 206 | + end |
| 207 | + |
| 208 | + known_param_determinate = det(covar_B); |
| 209 | + unknown_param_determinate = det(covar_A); |
| 210 | + deter(1, count) = known_param_determinate; |
| 211 | + deter(1, count+1) = unknown_param_determinate; |
| 212 | + count = count + 2; |
| 213 | + end |
| 214 | + determinates = array2table(deter, VariableNames=varNames); |
| 215 | +end |
| 216 | + |
| 217 | +function sample = GenerateSample(model, paramOfInterestIndex) |
| 218 | + [FIMTotal, FSPsoln, bounds, mleCovEstimate, fimMetrics] = GenerateFSP(model); |
| 219 | + |
| 220 | + determinates = CalcDeterminate(FIMTotal, fimMetrics, paramOfInterestIndex); |
| 221 | + |
| 222 | + sample = table(model.parameters{:, 2}, ... |
| 223 | + VariableNames={model.parameters{:, 1}}); % I do not understand matlab indexing {} vs () |
| 224 | + sample = [sample, determinates]; |
| 225 | +end |
| 226 | + |
| 227 | + |
| 228 | +%% Calculate many samples and concat them |
| 229 | +function results = GenerateTableFromSampling(modelGenerator, ParameterGenerator, numSampleToGen, paramOfInterestIndex) |
| 230 | + for i = 1:numSampleToGen |
| 231 | + params = ParameterGenerator(); % Generates an array of parameter |
| 232 | + model = modelGenerator(params); % Generates SSIT model |
| 233 | + sample = GenerateSample(model, paramOfInterestIndex); |
| 234 | + |
| 235 | + if ~exist('results', 'var') % Initial Condition/Preallocate |
| 236 | + width = size(sample, 2); |
| 237 | + results = table(size=[numSampleToGen, width], VariableNames=sample.Properties.VariableNames, ... |
| 238 | + VariableTypes=table2cell(varfun(@class, sample))); |
| 239 | + end |
| 240 | + |
| 241 | + results(i,:) = sample; |
| 242 | + end |
| 243 | +end |
| 244 | + |
| 245 | +function results = GenerateTableFromPairSamples(modelGenerator, ParameterGenerator, paramOfInterestIndex, t, fixedParams, nonFixedParamsIndexs) |
| 246 | + Params = t(:, fixedParams).Variables; |
| 247 | + newParams = ParameterGenerator(); |
| 248 | + counter = 1; |
| 249 | + for p = nonFixedParamsIndexs |
| 250 | + Params = [Params(:, 1:p-1), newParams(:,counter), Params(:, p:end)]; |
| 251 | + counter = counter + 1; |
| 252 | + end |
| 253 | + |
| 254 | + for i = 1:size(Params, 1) |
| 255 | + paramSet = Params(i, :); |
| 256 | + model = modelGenerator(paramSet); % Generates SSIT model |
| 257 | + sample = GenerateSample(model, paramOfInterestIndex); |
| 258 | + |
| 259 | + if ~exist('results', 'var') % Initial Condition/Preallocate |
| 260 | + width = size(sample, 2); |
| 261 | + results = table(size=[size(fixedParams, 1), width], VariableNames=sample.Properties.VariableNames, ... |
| 262 | + VariableTypes=table2cell(varfun(@class, sample))); |
| 263 | + end |
| 264 | + results(i,:) = sample; |
| 265 | + end |
| 266 | +end |
| 267 | + |
| 268 | + |
| 269 | + |
| 270 | + |
| 271 | + |
| 272 | + |
| 273 | + |
| 274 | + |
| 275 | + |
| 276 | + |
| 277 | + |
| 278 | + |
| 279 | + |
| 280 | + |
| 281 | + |
| 282 | + |
| 283 | + |
| 284 | + |
| 285 | + |
| 286 | + |
0 commit comments