0001 function fseof = ecFSEOF(model,prodTargetRxn,csRxn,nSteps,outputFile,filePath,modelAdapter)
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
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 if nargin < 7 || isempty(modelAdapter)
0049 modelAdapter = ModelAdapterManager.getDefault();
0050 if isempty(modelAdapter)
0051 error('Either send in a modelAdapter or set the default model adapter in the ModelAdapterManager.')
0052 end
0053 end
0054 params = modelAdapter.getParameters();
0055
0056 if nargin < 5 || isempty(outputFile)
0057 outputFile = false;
0058 end
0059
0060 if nargin < 6 || isempty(filePath)
0061 filePath = fullfile(params.path,'output');
0062 end
0063
0064 if nargin < 4 || isempty(nSteps)
0065 nSteps = 16;
0066 end
0067
0068
0069 prodTargetRxnIdx = getIndexes(model, prodTargetRxn,'rxns');
0070 csRxnIdx = getIndexes(model, csRxn,'rxns');
0071 bioRxnIdx = getIndexes(model, params.bioRxn,'rxns');
0072
0073
0074 [grRules,rxnGeneMat] = standardizeGrRules(model,true);
0075 model.grRules = grRules;
0076 model.rxnGeneMat = rxnGeneMat;
0077
0078
0079 model = setParam(model, 'obj', params.bioRxn, 1);
0080 sol = solveLP(model);
0081 if model.lb(csRxnIdx) < sol.x(csRxnIdx)
0082 printOrange(['WARNING: Carbon source lower bound was set to ' num2str(model.lb(csRxnIdx)) ...
0083 ', but the uptake rate after model optimization is ' num2str(sol.x(csRxnIdx)) '.\n']);
0084 end
0085
0086
0087
0088
0089 iniTarget = sol.x(prodTargetRxnIdx);
0090
0091
0092 model = setParam(model,'obj',prodTargetRxn,1);
0093 sol = solveLP(model,1);
0094
0095 maxTarget = sol.x(prodTargetRxnIdx) * 0.9;
0096
0097
0098
0099
0100 alpha = iniTarget:((maxTarget-iniTarget)/(nSteps-1)):maxTarget;
0101 v_matrix = zeros(length(model.rxns),length(alpha));
0102
0103
0104 progressbar('Flux Scanning with Enforced Objective Function')
0105 for i = 1:nSteps
0106
0107 model = setParam(model,'eq',prodTargetRxnIdx,alpha(i));
0108
0109
0110 model.lb(bioRxnIdx) = 0;
0111 model = setParam(model,'obj',params.bioRxn,1);
0112 sol = solveLP(model,1);
0113
0114
0115 v_matrix(:,i) = sol.x;
0116
0117 progressbar(i/nSteps)
0118 end
0119 progressbar(1)
0120
0121
0122 withGR = ~cellfun(@isempty,model.grRules);
0123 stdIdx = contains(model.grRules,'standard');
0124 withGR(stdIdx) = 0;
0125 target_rxns = model.rxns(withGR);
0126 v_matrix = v_matrix(withGR,:);
0127 rxnGeneM = model.rxnGeneMat(withGR,:);
0128
0129
0130 zero_flux = ~all(abs(v_matrix(:,1:nSteps))==0,2);
0131 target_rxns = target_rxns(zero_flux,:);
0132 v_matrix = v_matrix(zero_flux,:);
0133 rxnGeneM = rxnGeneM(zero_flux,:);
0134
0135
0136
0137
0138
0139
0140
0141 slope_rxns = zeros(size(target_rxns));
0142 targets = logical(size(target_rxns));
0143 target_type = cell(size(target_rxns));
0144 for i = 1:length(target_rxns)
0145 if issorted(abs(v_matrix(i,1:nSteps)),'strictascend')
0146
0147
0148 targets(i) = true;
0149 slope_rxns(i) = abs(v_matrix(i,nSteps-1)-v_matrix(i,1))/abs(maxTarget-maxTarget/nSteps-1);
0150 target_type(i) = {'OE'};
0151 elseif issorted(abs(v_matrix(i,1:nSteps)),'strictdescend')
0152
0153
0154
0155
0156 targets(i) = true;
0157 slope_rxns(i) = abs(v_matrix(i,nSteps-1)-v_matrix(i,1))/abs(maxTarget-maxTarget/nSteps-1);
0158 if v_matrix(i,nSteps) == 0
0159 target_type(i) = {'KO'};
0160 else
0161 target_type(i) = {'KD'};
0162 end
0163 end
0164 end
0165
0166
0167 target_rxns = target_rxns(targets);
0168 v_matrix = v_matrix(targets,:);
0169 rxnGeneM = rxnGeneM(targets,:);
0170 slope_rxns = slope_rxns(targets);
0171 target_type = target_type(targets);
0172
0173
0174 [~,order] = sort(slope_rxns,'descend');
0175 target_rxns = target_rxns(order);
0176 v_matrix = v_matrix(order,:);
0177 rxnGeneM = rxnGeneM(order,:);
0178 slope_rxns = slope_rxns(order);
0179 target_type = target_type(order);
0180
0181
0182 non_zero_slope = slope_rxns > quantile(slope_rxns,0.75);
0183 target_rxns = target_rxns(non_zero_slope);
0184 v_matrix = v_matrix(non_zero_slope,:);
0185 rxnGeneM = rxnGeneM(non_zero_slope,:);
0186 slope_rxns = slope_rxns(non_zero_slope);
0187 target_type = target_type(non_zero_slope);
0188
0189
0190 genes = model.genes(sum(rxnGeneM,1) > 0);
0191 slope_genes = zeros(size(genes));
0192 rxnGeneM = rxnGeneM(:,sum(rxnGeneM,1) > 0);
0193 target_type_genes = cell(size(genes));
0194 essentiality = cell(size(genes));
0195
0196
0197 progressbar('Checking for gene essentiality')
0198 for i = 1:numel(genes)
0199
0200
0201 usage_rxn_idx = strcmpi(model.ec.genes, genes{i});
0202 usage_rxn = strcat('usage_prot_', model.ec.enzymes(usage_rxn_idx));
0203 tempModel = setParam(model, 'eq', usage_rxn, 0);
0204 solKO = solveLP(tempModel);
0205
0206 if solKO.stat == -1 || solKO.x(bioRxnIdx) < 1e-8
0207 essentiality(i) = {'essential'};
0208 end
0209
0210
0211
0212
0213
0214
0215 rxns_for_gene = find(rxnGeneM(:,i) > 0);
0216 actions = unique(target_type(rxns_for_gene));
0217 if numel(actions) > 1
0218
0219 if any(startsWith(actions, 'OE'))
0220 target_type_genes(i) = {'OE'};
0221
0222 elseif ~any(startsWith(actions, 'OE')) && ~isequal(essentiality(i),{'essential'})
0223 target_type_genes(i) = {'KO'};
0224 else
0225 target_type_genes(i) = {'KD'};
0226 end
0227 else
0228 target_type_genes(i) = actions;
0229 end
0230
0231
0232 slope_set = slope_rxns(rxns_for_gene);
0233 slope_genes(i) = mean(slope_set);
0234
0235 progressbar(i/numel(genes))
0236 end
0237 progressbar(1)
0238
0239
0240 [~,order] = sort(slope_genes,'descend');
0241 genes = genes(order,:);
0242 slope_genes = slope_genes(order,:);
0243 target_type_genes = target_type_genes(order,:);
0244 essentiality = essentiality(order,:);
0245
0246
0247
0248
0249 fseof.alpha = alpha;
0250
0251
0252 toKeep = ~startsWith(target_rxns,'usage_prot_');
0253 rxnIdx = getIndexes(model,target_rxns(toKeep),'rxns');
0254
0255
0256 fseof.v_matrix = array2table(v_matrix(toKeep,:), ...
0257 'VariableNames', string(alpha), 'RowNames', model.rxns(rxnIdx));
0258
0259
0260 fseof.rxnTargets(:,1) = model.rxns(rxnIdx);
0261 fseof.rxnTargets(:,2) = model.rxnNames(rxnIdx);
0262 fseof.rxnTargets(:,3) = num2cell(slope_rxns(toKeep));
0263 fseof.rxnTargets(:,4) = model.grRules(rxnIdx);
0264 fseof.rxnTargets(:,5) = constructEquations(model,rxnIdx);
0265
0266
0267
0268 transportRxns = false(numel(rxnIdx),1);
0269 for i = 1:numel(rxnIdx)
0270
0271 mets = model.metNames(model.S(:,rxnIdx(i))~=0);
0272
0273 mets(startsWith(mets,'prot_')) = [];
0274
0275 transportRxns(i) = numel(mets) ~= numel(unique(mets));
0276 end
0277
0278
0279 fseof.transportTargets = fseof.rxnTargets(transportRxns,:);
0280 fseof.rxnTargets(transportRxns,:) = [];
0281
0282
0283 geneIdx = cellfun(@(x) find(strcmpi(model.genes,x)),genes);
0284 fseof.geneTargets(:,1) = genes;
0285 fseof.geneTargets(:,2) = model.geneShortNames(geneIdx);
0286 fseof.geneTargets(:,3) = num2cell(slope_genes);
0287 fseof.geneTargets(:,4) = target_type_genes;
0288 fseof.geneTargets(:,5) = essentiality;
0289
0290
0291 if outputFile
0292
0293 writetable(cell2table(fseof.geneTargets, ...
0294 'VariableNames', {'gene_IDs' 'gene_names' 'slope' 'action' 'essentiality'}), ...
0295 fullfile(filePath, 'ecFSEOF_genes.tsv'), ...
0296 'FileType', 'text', ...
0297 'Delimiter', '\t', ...
0298 'QuoteStrings', false);
0299
0300
0301 writetable(cell2table(fseof.rxnTargets, ...
0302 'VariableNames', {'rxn_IDs' 'rxnNames' 'slope' 'grRules' 'rxn_formula'}), ...
0303 fullfile(filePath, 'ecFSEOF_rxns.tsv'), ...
0304 'FileType', 'text', ...
0305 'Delimiter', '\t', ...
0306 'QuoteStrings', false);
0307
0308
0309 writetable(cell2table(fseof.transportTargets, ...
0310 'VariableNames', {'rxn_IDs' 'rxnNames' 'slope' 'grRules' 'rxn_formula'}), ...
0311 fullfile(filePath, 'ecFSEOF_transporter.tsv'), ...
0312 'FileType', 'text', ...
0313 'Delimiter', '\t', ...
0314 'QuoteStrings', false);
0315
0316 disp(['ecFSEOF results stored at: ' newline filePath]);
0317 end
0318
0319 end