|
| 1 | +function [TSscore, deletedGenes, Vres] = MTA(model, rxnFBS, Vref, varargin) |
| 2 | +% Calculate Metabolic Transformation Analysis (MTA) using the the |
| 3 | +% solver CPLEX. |
| 4 | +% Code was prepared to be able to be stopped and be launched again by using |
| 5 | +% a temporary file called 'temp_MTA.mat'. |
| 6 | +% Outputs are cell array for each alpha (one simulation by alpha). It |
| 7 | +% there is only one alpha, content of cell will be returned |
| 8 | +% The code here has been based on: |
| 9 | +% Yizhak, K., Gabay, O., Cohen, H., & Ruppin, E. (2013). |
| 10 | +% 'Model-based identification of drug targets that revert disrupted |
| 11 | +% metabolism and its application to ageing'. Nature communications, 4. |
| 12 | +% http://www.nature.com/ncomms/2013/131024/ncomms3632/full/ncomms3632.html |
| 13 | +% |
| 14 | +% USAGE: |
| 15 | +% |
| 16 | +% [TSscore,deletedGenes,Vout] = MTA(model, rxnFBS, Vref, alpha, epsilon, varargin) |
| 17 | +% |
| 18 | +% INPUTS: |
| 19 | +% model: Metabolic model structure (COBRA Toolbox format). |
| 20 | +% rxnFBS: Array that contains the desired change: Forward, |
| 21 | +% Backward and Unchanged (+1;0;-1). This is calculated |
| 22 | +% from the rules and differential expression analysis. |
| 23 | +% Vref: Reference flux of the source state. |
| 24 | +% |
| 25 | +% OPTIONAL INPUTS: |
| 26 | +% alpha: Numeric value or array. Parameter of the quadratic |
| 27 | +% problem (default = 0.66) |
| 28 | +% epsilon: Numeric value or array. Minimun perturbation for each |
| 29 | +% reaction (default = 0) |
| 30 | +% rxnKO: Binary value. Calculate knock outs at reaction level |
| 31 | +% instead of gene level. (default = false) |
| 32 | +% timelimit: Time limit for the calculation of each knockout. |
| 33 | +% (default = inf) |
| 34 | +% SeparateTranscript: Character used to separate different transcripts of a gene. (default = ''). |
| 35 | +% Examples: |
| 36 | +% - SeparateTranscript = '' |
| 37 | +% - gene 10005.1 ==> gene 10005.1 |
| 38 | +% - gene 10005.2 ==> gene 10005.2 |
| 39 | +% - gene 10005.3 ==> gene 10005.3 |
| 40 | +% - SeparateTranscript = '.' |
| 41 | +% - gene 10005.1 |
| 42 | +% - gene 10005.2 ==> gene 10005 |
| 43 | +% - gene 10005.3 |
| 44 | +% numWorkers: Integer: is the maximun number of workers |
| 45 | +% used by the solver. 0 = automatic, 1 = sequential, |
| 46 | +% > 1 = parallel. (default = 0) |
| 47 | +% printLevel: Integer. 1 if the process is wanted to be shown |
| 48 | +% on the screen, 0 otherwise. (default = 1) |
| 49 | +% |
| 50 | +% OUTPUTS: |
| 51 | +% TSscore: Transformation score by each transformation |
| 52 | +% deletedGenes: The list of genes/reactions removed in each knock-out |
| 53 | +% Vres: Matrix of resulting fluxes |
| 54 | +% |
| 55 | +% .. Authors: |
| 56 | +% - Luis V. Valcarcel, 03/06/2015, University of Navarra, CIMA & TECNUN School of Engineering. |
| 57 | +% - Luis V. Valcarcel, 26/10/2018, University of Navarra, CIMA & TECNUN School of Engineering. |
| 58 | +% - Francisco J. Planes, 26/10/2018, University of Navarra, TECNUN School of Engineering. |
| 59 | + |
| 60 | +p = inputParser; % check the input information |
| 61 | + |
| 62 | +% check required arguments |
| 63 | +addRequired(p, 'model'); |
| 64 | +addRequired(p, 'rxnFBS', @isnumeric); |
| 65 | +addRequired(p, 'Vref', @isnumeric); |
| 66 | +% Check optional arguments |
| 67 | +addOptional(p, 'alpha', 0.66, @isnumeric); |
| 68 | +addOptional(p, 'epsilon', 0, @isnumeric); |
| 69 | +% Add optional name-value pair argument |
| 70 | +addParameter(p, 'rxnKO', false); |
| 71 | +addParameter(p, 'timelimit', inf, @(x)isnumeric(x)&&isscalar(x)); |
| 72 | +addParameter(p, 'SeparateTranscript', '', @(x)ischar(x)); |
| 73 | +addParameter(p, 'numWorkers', 0, @(x)isnumeric(x)&&isscalar(x)); |
| 74 | +addParameter(p, 'printLevel', 1, @(x)isnumeric(x)&&isscalar(x)); |
| 75 | +% extract variables from parser |
| 76 | +parse(p, model, rxnFBS, Vref, varargin{:}); |
| 77 | +alpha = p.Results.alpha; |
| 78 | +epsilon = p.Results.epsilon; |
| 79 | +rxnKO = p.Results.rxnKO; |
| 80 | +timelimit = p.Results.timelimit; |
| 81 | +SeparateTranscript = p.Results.SeparateTranscript; |
| 82 | +numWorkers = p.Results.numWorkers; |
| 83 | +printLevel = p.Results.printLevel; |
| 84 | + |
| 85 | +if printLevel >0 |
| 86 | + fprintf('===================================\n'); |
| 87 | + fprintf('========= MTA algorithm =========\n'); |
| 88 | + fprintf('===================================\n'); |
| 89 | + fprintf('Step 0: preprocessing: \n'); |
| 90 | +end |
| 91 | + |
| 92 | +%% Initialize variables or load previously ones |
| 93 | +% Check if there are any temporary files with the MTA information |
| 94 | + |
| 95 | +num_alphas = numel(alpha); |
| 96 | + |
| 97 | +% Calculate perturbation matrix |
| 98 | +if rxnKO |
| 99 | + geneKO.genes = model.rxns; |
| 100 | + geneKO.rxns = model.rxns; |
| 101 | + geneKO.rxns = speye(numel(model.rxns)); |
| 102 | +else |
| 103 | + geneKO = calculateGeneKOMatrix(model, SeparateTranscript, printLevel); |
| 104 | +end |
| 105 | + |
| 106 | +% Reduce the size of the problem; |
| 107 | +geneKO2 = geneKO; |
| 108 | +[geneKO.matrix,geneKO.IA,geneKO.IC ] = unique(geneKO.matrix','rows'); |
| 109 | +geneKO.matrix = geneKO.matrix'; |
| 110 | +geneKO.genes = num2cell((1:length(geneKO.IA))'); |
| 111 | + |
| 112 | +if ~exist('temp_MTA.mat','file') |
| 113 | + % counters |
| 114 | + i = 0; % counter |
| 115 | + i_alpha = 0; % counter for lphas |
| 116 | + % scores |
| 117 | + TSscore = zeros(numel(geneKO.genes),num_alphas); |
| 118 | + Vres = cell(num_alphas,1); |
| 119 | + Vres(:) = {zeros(numel(model.rxns),numel(geneKO.genes))}; |
| 120 | +else |
| 121 | + load('temp_MTA.mat'); |
| 122 | + i_alpha = max(i_alpha-1,0); |
| 123 | + i = max(i-100,0); |
| 124 | +end |
| 125 | + |
| 126 | +if printLevel >0 |
| 127 | + fprintf('-------------------\n'); |
| 128 | +end |
| 129 | + |
| 130 | +%% ---- STEP 1 : MTA ---- |
| 131 | + |
| 132 | +timerVal = tic; |
| 133 | + |
| 134 | +% treat rxnFBS to remove impossible changes |
| 135 | +rxnFBS_best = rxnFBS; |
| 136 | +rxnFBS_best(rxnFBS_best==-1 & abs(Vref)<1e-6 & model.lb==0) = 0; |
| 137 | +clear v_res |
| 138 | + |
| 139 | + |
| 140 | +while i_alpha < num_alphas |
| 141 | + i_alpha = i_alpha + 1; |
| 142 | + if printLevel >0 |
| 143 | + fprintf('\tStart MTA best scenario case for alpha = %1.2f \n',alpha(i_alpha)); |
| 144 | + end |
| 145 | + |
| 146 | + % Create the CPLEX model |
| 147 | + CplexModelBest = buildMTAproblemFromModel(model, rxnFBS_best, Vref, alpha(i_alpha), epsilon); |
| 148 | + if printLevel >0 |
| 149 | + fprintf('\tcplex model for MTA built\n'); |
| 150 | + end |
| 151 | + |
| 152 | + % perform the MIQP problem for each rxn's knock-out |
| 153 | + if printLevel >0 |
| 154 | + showprogress(0, ' MIQP Iterations for MTA'); |
| 155 | + end |
| 156 | + while i < length(geneKO.genes) |
| 157 | + for w = 1:100 |
| 158 | + i = i+1; |
| 159 | + KOrxn = find(geneKO.matrix(:,i)); |
| 160 | + v_res = MTA_MIQP (CplexModelBest, KOrxn, 'numWorkers', numWorkers, 'timelimit', timelimit, 'printLevel', printLevel); |
| 161 | + Vres{i_alpha}(:,i) = v_res; |
| 162 | + if ~isempty(KOrxn) && norm(v_res)>1 |
| 163 | + TSscore(i,i_alpha) = MTA_TS(v_res,Vref,rxnFBS_best); |
| 164 | + else |
| 165 | + % if we knock off the system, invalid solution |
| 166 | + % remove perturbations with no effect score |
| 167 | + TSscore(i,i_alpha) = -Inf; |
| 168 | + end |
| 169 | + if printLevel >0 |
| 170 | + showprogress(i/length(geneKO.genes), ' MIQP Iterations for MTA'); |
| 171 | + end |
| 172 | + % Condition to exit the for loop |
| 173 | + if i == length(geneKO.genes) |
| 174 | + break; |
| 175 | + end |
| 176 | + end |
| 177 | + try save('temp_MTA.mat', 'i','i_alpha','TSscore','Vres'); end |
| 178 | + end |
| 179 | + clear cplex_model |
| 180 | + if printLevel >0 |
| 181 | + fprintf('\tAll MIQP problems performed\n'); |
| 182 | + end |
| 183 | + i = 0; |
| 184 | +end |
| 185 | + |
| 186 | + |
| 187 | +time = toc(timerVal); |
| 188 | +if printLevel >0 |
| 189 | + fprintf('\tTime: %4.2f seconds = %4.2f minutes\n',time,time/60); |
| 190 | +end |
| 191 | +try save('temp_MTA.mat', 'i','i_alpha','TSscore','Vres'); end |
| 192 | +fprintf('-------------------\n'); |
| 193 | + |
| 194 | +%% ---- STEP 2 : Return to gene size ---- |
| 195 | + |
| 196 | +aux = geneKO; |
| 197 | +geneKO = geneKO2; |
| 198 | + |
| 199 | +% scores |
| 200 | +TSscore = TSscore(aux.IC,:); |
| 201 | +% fluxes |
| 202 | +for i=1:num_alphas |
| 203 | + Vres{i} = Vres{i}(:,aux.IC); |
| 204 | +end |
| 205 | + |
| 206 | +% Define one of the outputs |
| 207 | +deletedGenes = geneKO.genes; |
| 208 | + |
| 209 | + |
| 210 | +delete('temp_MTA.mat') |
| 211 | + |
| 212 | +end |
| 213 | + |
0 commit comments