0001 function [model, tunedKcats] = sensitivityTuning(model, desiredGrowthRate, modelAdapter, foldChange, protToIgnore, verbose)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 if nargin < 6 || isempty(verbose)
0038 verbose = true;
0039 end
0040 if nargin < 5 || isempty(protToIgnore)
0041 protToIgnore = {};
0042 end
0043 if nargin < 4 || isempty(foldChange)
0044 foldChange = 10;
0045 end
0046 if nargin < 3 || isempty(modelAdapter)
0047 modelAdapter = ModelAdapterManager.getDefault();
0048 if isempty(modelAdapter)
0049 error('Either send in a modelAdapter or set the default model adapter in the ModelAdapterManager.')
0050 end
0051 end
0052 params = modelAdapter.params;
0053 if nargin < 2 || isempty(desiredGrowthRate)
0054 desiredGrowthRate = params.gR_exp;
0055 end
0056
0057 kcatList = [];
0058 m = model;
0059 m.c = double(strcmp(m.rxns, params.bioRxn));
0060
0061 [res,hs] = solveLP(m);
0062 if isempty(res.x)
0063 error('FBA of input model gives no valid result. Reduce protein pool constraint with setProtPoolSize and/or check if exchange constraints are correctly defined.')
0064 end
0065 lastGrowth = 0;
0066 if ~m.ec.geckoLight
0067
0068 drawRxns = startsWith(m.rxns, 'usage_prot_');
0069 idxToIgnore = cellfun(@(x) find(strcmpi(model.rxns, ['usage_prot_' x])), protToIgnore);
0070 iteration = 1;
0071 while true
0072 [res,hs] = solveLP(m,0,[],hs);
0073 if (lastGrowth == res.f)
0074 printOrange('WARNING: No growth increase from increased kcats - check if the constraints on the uptake reactions are too tight.\n');
0075 break;
0076 end
0077 lastGrowth = res.f;
0078 if verbose; disp(['Iteration ' num2str(iteration) ': Growth: ' num2str(lastGrowth)]); end
0079 if (lastGrowth >= desiredGrowthRate)
0080 break;
0081 end
0082
0083
0084
0085 iteration = iteration + 1;
0086
0087 drawFluxes = zeros(length(drawRxns),1);
0088 drawFluxes(drawRxns) = res.x(drawRxns);
0089
0090 drawFluxes(idxToIgnore) = 0;
0091 [~,sel] = min(drawFluxes);
0092
0093 metSel = m.S(:,sel) < 0;
0094
0095 protFluxes = m.S(metSel,:).' .* res.x;
0096 [~,rxnSel] = min(protFluxes);
0097 kcatList = [kcatList, rxnSel];
0098 rxn = m.rxns(rxnSel);
0099 targetSubRxn = strcmp(m.ec.rxns, rxn);
0100 if ~strcmp(m.ec.source(targetSubRxn),'sensitivityTuning')
0101 oldNote = m.ec.notes{targetSubRxn};
0102 newNote = ['preTuneKcat=' num2str(m.ec.kcat(targetSubRxn)) ' | source:' m.ec.source{targetSubRxn}];
0103 if ~isempty(oldNote)
0104 newNote = [oldNote '; ' newNote];
0105 end
0106 m.ec.notes{targetSubRxn} = newNote;
0107 end
0108 m.ec.kcat(targetSubRxn) = m.ec.kcat(targetSubRxn) .* foldChange;
0109 m.ec.source(targetSubRxn) = {'sensitivityTuning'};
0110 m = applyKcatConstraints(m,targetSubRxn);
0111 end
0112
0113 else
0114 origRxns = extractAfter(m.ec.rxns,4);
0115
0116 idxToIgnore = cellfun(@(x) find(m.ec.rxnEnzMat(:, strcmpi(m.ec.enzymes, x))), protToIgnore, 'UniformOutput', false);
0117
0118 idxToIgnore = unique(cat(1, idxToIgnore{:}));
0119
0120 idxToIgnore = cellfun(@(x) find(strcmpi(m.rxns, x)), origRxns(idxToIgnore));
0121 iteration = 1;
0122 while true
0123 res = solveLP(m,0);
0124 if (lastGrowth == res.f)
0125 printOrange('No growth increase from increased kcats - check if the constraints on the uptake reactions are too tight.\n');
0126 break;
0127 end
0128 lastGrowth = res.f;
0129 if (lastGrowth >= desiredGrowthRate)
0130 break;
0131 end
0132
0133
0134
0135 if verbose; disp(['Iteration ' num2str(iteration) ': Growth: ' num2str(lastGrowth)]); end
0136 iteration = iteration + 1;
0137
0138 protPoolStoich = m.S(strcmp(m.mets, 'prot_pool'),:).';
0139 protPoolStoich(idxToIgnore) = 0;
0140 [~,sel] = min(res.x .* protPoolStoich);
0141 kcatList = [kcatList, sel];
0142 rxn = m.rxns(sel.');
0143 targetSubRxns = strcmp(origRxns, rxn);
0144 m.ec.kcat(targetSubRxns) = m.ec.kcat(targetSubRxns) .* foldChange;
0145 m = applyKcatConstraints(m,rxn);
0146 end
0147 end
0148
0149 kcatList = unique(kcatList);
0150 tunedKcats.rxns = m.rxns(kcatList);
0151 tunedKcats.rxnNames = m.rxnNames(kcatList);
0152 if ~model.ec.geckoLight
0153 [~, rxnIdx] = ismember(tunedKcats.rxns,m.ec.rxns);
0154 else
0155 [~, rxnIdx] = ismember(tunedKcats.rxns,origRxns);
0156 end
0157 tunedKcats.enzymes = cell(numel(kcatList),1);
0158 for i=1:numel(rxnIdx)
0159 [~, metIdx] = find(m.ec.rxnEnzMat(rxnIdx(i),:));
0160 tunedKcats.enzymes{i} = strjoin(m.ec.enzymes(metIdx),';');
0161 end
0162 tunedKcats.oldKcat = model.ec.kcat(rxnIdx);
0163 tunedKcats.newKcat = m.ec.kcat(rxnIdx);
0164 tunedKcats.source = model.ec.source(rxnIdx);
0165
0166 model = m;
0167 end