0001 function [outModel, addedRxns]=ftINITFillGapsForAllTasks(model,refModel,inputFile,printOutput,rxnScores,taskStructure,params,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
0038
0039
0040
0041
0042 if isempty(rxnScores)
0043 rxnScores=ones(numel(refModel.rxns),1)*-1;
0044 end
0045
0046 if isempty(taskStructure) && ~isfile(inputFile)
0047 error('Task file %s cannot be found',string(inputFile));
0048 end
0049
0050 if strcmpi(model.id,refModel.id)
0051 fprintf('NOTE: The model and reference model have the same IDs. The ID for the reference model was set to "refModel" in order to keep track of the origin of reactions.\n');
0052 refModel.id='refModel';
0053 end
0054
0055 if any(rxnScores>=0)
0056 EM='Only negative values are allowed in rxnScores';
0057 dispEM(EM);
0058 end
0059
0060
0061 model.b=zeros(numel(model.mets),2);
0062 modelMets=upper(strcat(model.metNames,'[',model.comps(model.metComps),']'));
0063
0064
0065 largeModelMets=upper(strcat(refModel.metNames,'[',refModel.comps(refModel.metComps),']'));
0066
0067 if ~isfield(model,'unconstrained')
0068 EM='Exchange metabolites should normally not be removed from the model when using checkTasks. Inputs and outputs are defined in the task file instead. Use importModel(file,false) to import a model with exchange metabolites remaining';
0069 dispEM(EM,false);
0070 end
0071
0072 if isempty(taskStructure)
0073 taskStructure=parseTaskList(inputFile);
0074 end
0075
0076 tModel=model;
0077 addedRxns=false(numel(refModel.rxns),numel(taskStructure));
0078 supressWarnings=false;
0079 nAdded=0;
0080
0081 for i=1:numel(taskStructure)
0082 if ~taskStructure(i).shouldFail
0083
0084 tRefModel = refModel;
0085 tRxnScores = rxnScores;
0086
0087 if ~isempty(taskStructure(i).inputs)
0088 [I, J]=ismember(upper(taskStructure(i).inputs),modelMets);
0089 [I2, J2]=ismember(upper(taskStructure(i).inputs),largeModelMets);
0090 K=ismember(upper(taskStructure(i).inputs),'ALLMETS');
0091 L=~cellfun('isempty',strfind(upper(taskStructure(i).inputs),'ALLMETSIN'));
0092
0093
0094 goodMets=I|K|L;
0095 if ~all(goodMets)
0096
0097
0098 [found, metMatch]=ismember(upper(taskStructure(i).inputs(~goodMets)),largeModelMets);
0099 if ~all(found)
0100 EM=['Could not find all inputs in "[' taskStructure(i).id '] ' taskStructure(i).description '" in either model'];
0101 disp(EM);
0102 else
0103
0104 met.metNames=refModel.metNames(metMatch);
0105 met.compartments=refModel.comps(refModel.metComps(metMatch));
0106
0107
0108
0109 model=addMets(model,met);
0110 tModel=addMets(tModel,met);
0111 modelMets=[modelMets;upper(taskStructure(i).inputs(~goodMets))];
0112 end
0113
0114
0115
0116
0117 I(~goodMets)=true;
0118 J(~goodMets)=numel(modelMets)-numel(metMatch)+1:numel(modelMets);
0119 end
0120 if numel(J(I))~=numel(unique(J(I)))
0121 EM=['The constraints on some input(s) in "[' taskStructure(i).id '] ' taskStructure(i).description '" are defined more than one time'];
0122 dispEM(EM);
0123 end
0124
0125 if any(K)
0126
0127
0128
0129 if K(1)==0
0130 EM=['ALLMETS is used as an input in "[' taskStructure(i).id '] ' taskStructure(i).description '" but it it not the first metabolite in the list. Constraints defined for the metabolites before it will be over-written'];
0131 dispEM(EM,false);
0132 end
0133
0134
0135 tModel.b(:,1)=taskStructure(i).UBin(find(K,1))*-1;
0136 tRefModel.b(:,1)=taskStructure(i).UBin(find(K,1))*-1;
0137 end
0138
0139 if any(L)
0140 L=find(L);
0141 for j=1:numel(L)
0142
0143 compartment=upper(taskStructure(i).inputs{L(j)}(11:end-1));
0144
0145 C=find(ismember(upper(model.comps),compartment));
0146 if any(C)
0147
0148 tModel.b(model.metComps==C,1)=taskStructure(i).UBin(L(j))*-1;
0149 else
0150 EM=['The compartment defined for ALLMETSIN in "[' taskStructure(i).id '] ' taskStructure(i).description '" does not exist'];
0151 dispEM(EM);
0152 end
0153
0154 C=find(ismember(upper(tRefModel.comps),compartment));
0155 if any(C)
0156
0157 tRefModel.b(tRefModel.metComps==C,1)=taskStructure(i).UBin(L(j))*-1;
0158 else
0159 EM=['The compartment defined for ALLMETSIN in "[' taskStructure(i).id '] ' taskStructure(i).description '" does not exist'];
0160 dispEM(EM);
0161 end
0162 end
0163 end
0164
0165 if any(J(I))
0166 tModel.b(J(I),1)=taskStructure(i).UBin(I)*-1;
0167 tModel.b(J(I),2)=taskStructure(i).LBin(I)*-1;
0168 end
0169
0170 if any(J2(I2))
0171 tRefModel.b(J2(I2),1)=taskStructure(i).UBin(I2)*-1;
0172 tRefModel.b(J2(I2),2)=taskStructure(i).LBin(I2)*-1;
0173 end
0174 end
0175
0176 if ~isempty(taskStructure(i).outputs)
0177 [I, J]=ismember(upper(taskStructure(i).outputs),modelMets);
0178 [I2, J2]=ismember(upper(taskStructure(i).outputs),largeModelMets);
0179 K=ismember(upper(taskStructure(i).outputs),'ALLMETS');
0180 L=~cellfun('isempty',strfind(upper(taskStructure(i).outputs),'ALLMETSIN'));
0181
0182
0183 goodMets=I|K|L;
0184 if ~all(goodMets)
0185
0186
0187 [found, metMatch]=ismember(upper(taskStructure(i).outputs(~goodMets)),largeModelMets);
0188 if ~all(found)
0189 EM=['Could not find all outputs in "[' taskStructure(i).id '] ' taskStructure(i).description '" in either model'];
0190 dispEM(EM);
0191 else
0192
0193 met.metNames=refModel.metNames(metMatch);
0194 met.compartments=refModel.comps(refModel.metComps(metMatch));
0195
0196
0197
0198 model=addMets(model,met);
0199 tModel=addMets(tModel,met);
0200 modelMets=[modelMets;upper(taskStructure(i).outputs(~goodMets))];
0201 end
0202
0203
0204
0205
0206 I(~goodMets)=true;
0207 J(~goodMets)=numel(modelMets)-numel(metMatch)+1:numel(modelMets);
0208 end
0209 if numel(J(I))~=numel(unique(J(I)))
0210 EM=['The constraints on some output(s) in "[' taskStructure(i).id '] ' taskStructure(i).description '" are defined more than one time'];
0211 dispEM(EM);
0212 end
0213
0214 if any(K)
0215
0216
0217
0218 if K(1)==0
0219 EM=['ALLMETS is used as an output in "[' taskStructure(i).id '] ' taskStructure(i).description '" but it it not the first metabolite in the list. Constraints defined for the metabolites before it will be over-written'];
0220 dispEM(EM,false);
0221 end
0222
0223
0224 tModel.b(:,2)=taskStructure(i).UBout(find(K,1));
0225 tRefModel.b(:,2)=taskStructure(i).UBout(find(K,1));
0226 end
0227
0228 if any(L)
0229 L=find(L);
0230 for j=1:numel(L)
0231
0232 compartment=upper(taskStructure(i).outputs{L(j)}(11:end-1));
0233
0234 C=find(ismember(upper(model.comps),compartment));
0235 if any(C)
0236
0237 tModel.b(model.metComps==C,2)=taskStructure(i).UBout(L(j));
0238 else
0239 EM=['The compartment defined for ALLMETSIN in "[' taskStructure(i).id '] ' taskStructure(i).description '" does not exist'];
0240 dispEM(EM);
0241 end
0242
0243 C=find(ismember(upper(tRefModel.comps),compartment));
0244 if any(C)
0245
0246 tRefModel.b(tRefModel.metComps==C,2)=taskStructure(i).UBout(L(j));
0247 else
0248 EM=['The compartment defined for ALLMETSIN in "[' taskStructure(i).id '] ' taskStructure(i).description '" does not exist'];
0249 dispEM(EM);
0250 end
0251 end
0252 end
0253
0254 if any(J(I))
0255
0256
0257
0258 J = J(I);
0259 I = find(I);
0260 nonzero_LBin = tModel.b(J,2) < 0;
0261 nonzero_LBout = taskStructure(i).LBout(I) > 0;
0262 if any(nonzero_LBin & nonzero_LBout)
0263 EM=['The IN LB and OUT LB in "[' taskStructure(i).id '] ' taskStructure(i).description '" cannot be nonzero for the same metabolite'];
0264 dispEM(EM);
0265 end
0266 tModel.b(J(nonzero_LBout),1)=taskStructure(i).LBout(I(nonzero_LBout));
0267 tModel.b(J,2)=taskStructure(i).UBout(I);
0268 end
0269
0270 if any(J2(I2))
0271
0272
0273
0274 J2 = J2(I2);
0275 I2 = find(I2);
0276 nonzero_LBin = tRefModel.b(J2,2) < 0;
0277 nonzero_LBout = taskStructure(i).LBout(I2) > 0;
0278 if any(nonzero_LBin & nonzero_LBout)
0279 EM=['The IN LB and OUT LB in "[' taskStructure(i).id '] ' taskStructure(i).description '" cannot be nonzero for the same metabolite'];
0280 dispEM(EM);
0281 end
0282 tRefModel.b(J2(nonzero_LBout),1)=taskStructure(i).LBout(I2(nonzero_LBout));
0283 tRefModel.b(J2,2)=taskStructure(i).UBout(I2);
0284 end
0285 end
0286
0287
0288 if ~isempty(taskStructure(i).equations)
0289 rxn.equations=taskStructure(i).equations;
0290 rxn.lb=taskStructure(i).LBequ;
0291 rxn.ub=taskStructure(i).UBequ;
0292 rxn.rxns=strcat({'TEMPORARY_'},num2str((1:numel(taskStructure(i).equations))'));
0293 tModel=addRxns(tModel,rxn,3);
0294 tRefModel=addRxns(tRefModel,rxn,3);
0295 tRxnScores = [tRxnScores;zeros(length(rxn.lb),1)];
0296 end
0297
0298 if ~isempty(taskStructure(i).changed)
0299 tModel=setParam(tModel,'lb',taskStructure(i).changed,taskStructure(i).LBrxn);
0300 tModel=setParam(tModel,'ub',taskStructure(i).changed,taskStructure(i).UBrxn);
0301 tRefModel=setParam(tRefModel,'lb',taskStructure(i).changed,taskStructure(i).LBrxn);
0302 tRefModel=setParam(tRefModel,'ub',taskStructure(i).changed,taskStructure(i).UBrxn);
0303 end
0304
0305
0306 sol=solveLP(tModel);
0307 if isempty(sol.x)
0308
0309 failed=false;
0310 try
0311 [newRxns, newModel, exitFlag]=ftINITFillGaps(tModel,model,tRefModel,false,supressWarnings,tRxnScores,params,verbose);
0312 if exitFlag==-2
0313 EM=['"[' taskStructure(i).id '] ' taskStructure(i).description '" was aborted before reaching optimality. Consider increasing params.maxTime\n'];
0314 dispEM(EM,false);
0315 end
0316 catch e
0317 EM=['"[' taskStructure(i).id '] ' taskStructure(i).description '" could not be performed for any set of reactions\n'];
0318 dispEM(EM,false);
0319 failed=true;
0320 end
0321 if failed==false
0322 if ~isempty(newRxns)
0323 nAdded=nAdded+numel(newRxns);
0324
0325 disp(['task: ' num2str(i)])
0326 for iii = 1:numel(newRxns)
0327 disp(newRxns{iii})
0328 end
0329
0330
0331
0332
0333
0334 model = newModel;
0335
0336
0337 addedRxns(ismember(refModel.rxns,newRxns),i)=true;
0338 end
0339 if printOutput==true
0340 fprintf(['[' taskStructure(i).id '] ' taskStructure(i).description ': Added ' num2str(numel(newRxns)) ' reaction(s), ' num2str(nAdded) ' reactions added in total\n']);
0341 end
0342 end
0343 else
0344 if printOutput==true
0345 fprintf(['[' taskStructure(i).id '] ' taskStructure(i).description ': Added 0 reaction(s), ' num2str(nAdded) ' reactions added in total\n']);
0346 end
0347 end
0348 supressWarnings=true;
0349
0350
0351 if taskStructure(i).printFluxes && printOutput
0352 if ~isempty(sol.x)
0353 sol=solveLP(tModel,1);
0354 printFluxes(tModel,sol.x,false,10^-5,[],'%rxnID (%eqn):%flux\n');
0355 fprintf('\n');
0356 else
0357
0358
0359 if failed==false
0360 sol=solveLP(newModel,1);
0361 printFluxes(newModel,sol.x,false,10^-5,[],'%rxnID (%eqn):%flux\n');
0362 fprintf('\n');
0363 end
0364 end
0365 end
0366
0367 tModel=model;
0368
0369
0370 modelMets=upper(strcat(model.metNames,'[',model.comps(model.metComps),']'));
0371 else
0372 EM=['"[' taskStructure(i).id '] ' taskStructure(i).description '" is set as SHOULD FAIL. Such tasks cannot be modelled using this approach and the task is therefore ignored\n'];
0373 dispEM(EM,false);
0374 end
0375 end
0376 outModel=model;
0377 end