|
| 1 | +function line = addEnv(origModel, biomass, desiredProduct, varargin) |
| 2 | +% addEnv adds envelope to figure |
| 3 | +% Algorithm is able to knock out genes as well as reactions to produce |
| 4 | +% production envelope |
| 5 | +% |
| 6 | +% USAGE: |
| 7 | +% line = addEnv(origModel, biomass, desiredProduct, 'KnockOuts', knockouts, 'colour', colour, 'prodMol', prodMol, 'subUptake', subUptake, 'molarSum', molarSum) |
| 8 | +% |
| 9 | +% INPUTS: |
| 10 | +% origModel COBRA model structure [struct] |
| 11 | +% biomass Reaction name of biomass [char] |
| 12 | +% desiredProduct Reaction name of desired product [char] |
| 13 | +% |
| 14 | +% OPTIONAL INPUTS: |
| 15 | +% KnockOuts (opt) List of knockouts for production envelope [cell array] (default: {}) |
| 16 | +% colour (opt) Short name for colour of line to plot [anything that can be colour in matlab] (default: 'r' (red)) |
| 17 | +% prodMol (opt) Molar mass of target product for yield plot [double] |
| 18 | +% subUptake (opt) Uptake of substrate for yield plot [double] |
| 19 | +% molarSum (opt) Molar mass of substrate for yield plot [double] |
| 20 | +% |
| 21 | +% OUTPUTS |
| 22 | +% line Line data for plot function |
| 23 | +% |
| 24 | +% NOTES |
| 25 | +% Sometimes last point of envelope drops to zero (might be rounding error) |
| 26 | +% but this function connects last points of lines so the graph creates |
| 27 | +% continuous line. |
| 28 | +% This algorithm only adds graph. It does not change labels. |
| 29 | +% |
| 30 | +% EXAMPLE: |
| 31 | +% line = addEnv(model, 'BIOMASS_Ecoli', 'EX_ac_e', {'GHMT2r','GND','SUCCt2r','SUCD4','AKGt2r','GLUt2r'}, 'm') |
| 32 | +% |
| 33 | +% AUTHORS: |
| 34 | +% Created by Kristaps Berzins 31/10/2022 |
| 35 | +% Modified by Kristaps Berzins 30/09/2024 |
| 36 | + |
| 37 | +parser = inputParser(); |
| 38 | +parser.addRequired('model', @(x) isstruct(x) && isfield(x, 'S') && isfield(origModel, 'rxns')... |
| 39 | + && isfield(origModel, 'mets') && isfield(origModel, 'lb') && isfield(origModel, 'ub') && isfield(origModel, 'b')... |
| 40 | + && isfield(origModel, 'c')) |
| 41 | +parser.addRequired('biomass', @(x) any(validatestring(x, origModel.rxns))) |
| 42 | +parser.addRequired('desiredProduct', @(x) any(validatestring(x, origModel.rxns))) |
| 43 | +parser.addOptional('KnockOuts', {}, @(x) iscell(x) && ismatrix(x)) |
| 44 | +parser.addOptional('colour', 'r', @(x) any(validatecolor(x))) |
| 45 | +parser.addOptional('prodMol', [], @(x) isnumeric(x)) |
| 46 | +parser.addOptional('subUptake', 10, @(x) isnumeric(x)) |
| 47 | +parser.addOptional('molarSum', 180, @(x) isnumeric(x)) |
| 48 | + |
| 49 | +parser.parse(origModel, biomass, desiredProduct, varargin{:}); |
| 50 | +origModel = parser.Results.model; |
| 51 | +biomass = parser.Results.biomass; |
| 52 | +desiredProduct = parser.Results.desiredProduct; |
| 53 | +KnockOuts = parser.Results.KnockOuts; |
| 54 | +colour = parser.Results.colour; |
| 55 | +prodMol = parser.Results.prodMol; |
| 56 | +subUptake = parser.Results.subUptake; |
| 57 | +molarSum = parser.Results.molarSum; |
| 58 | + |
| 59 | +if isempty(prodMol) |
| 60 | + prodMolIs = false; |
| 61 | +else |
| 62 | + prodMolIs = true; |
| 63 | +end |
| 64 | + |
| 65 | +model = origModel; |
| 66 | + |
| 67 | +if any(ismember(model.rxns, KnockOuts)) |
| 68 | + rxns = ismember(model.rxns, KnockOuts); |
| 69 | + model.ub(rxns) = 0; |
| 70 | + model.lb(rxns) = 0; |
| 71 | +elseif any(ismember(model.genes, KnockOuts)) |
| 72 | + model = buildRxnGeneMat(model); |
| 73 | + [model, ~, ~] = deleteModelGenes(model, KnockOuts); |
| 74 | +%elseif %Enzymes |
| 75 | +end |
| 76 | + |
| 77 | +solMin = optimizeCbModel(model, 'min'); |
| 78 | +solMax = optimizeCbModel(model, 'max'); |
| 79 | +controlFlux1 = linspace(solMin.f, solMax.f, 100)'; |
| 80 | +if nnz(controlFlux1) == 0 |
| 81 | + return; |
| 82 | +end |
| 83 | +model = changeObjective(model, desiredProduct); |
| 84 | + |
| 85 | +for i = 1:numel(controlFlux1) |
| 86 | + model = changeRxnBounds(model, biomass, controlFlux1(i), 'b'); |
| 87 | + s = optimizeCbModel(model, 'min'); Min1(i, 1) = s.f; |
| 88 | + if s.stat == 0 |
| 89 | + model = changeRxnBounds(model, biomass, controlFlux1(i) - 0.0001 * controlFlux1(i), 'b'); |
| 90 | + s = optimizeCbModel(model, 'min'); Min1(i, 1) = s.f; |
| 91 | + s = optimizeCbModel(model, 'max'); Max1(i, 1) = s.f; |
| 92 | + end |
| 93 | + s = optimizeCbModel(model, 'max'); Max1(i, 1) = s.f; |
| 94 | + if s.stat == 0 |
| 95 | + model = changeRxnBounds(model, biomass, controlFlux1(i) - 0.0001 * controlFlux1(i), 'b'); |
| 96 | + s= optimizeCbModel(model,'min');Min1(i,1)=s.f; |
| 97 | + s= optimizeCbModel(model,'max');Max1(i,1)=s.f; |
| 98 | + end |
| 99 | +end |
| 100 | + |
| 101 | +if prodMolIs |
| 102 | + controlFlux1 = controlFlux1 / subUptake * 1000 / molarSum; |
| 103 | + Max1 = Max1 / molarSum * prodMol / subUptake; |
| 104 | + Min1 = Min1 / molarSum * prodMol / subUptake; |
| 105 | +end |
| 106 | + |
| 107 | +hold on |
| 108 | +line = plot(controlFlux1, Max1, 'color', colour, 'LineWidth', 2); |
| 109 | +plot(controlFlux1, Min1, 'color', colour, 'LineWidth', 2) |
| 110 | +hold off |
| 111 | + |
0 commit comments