diff --git a/manipulation/addRxns.m b/manipulation/addRxns.m index 8bb1cb2d..3a08b335 100755 --- a/manipulation/addRxns.m +++ b/manipulation/addRxns.m @@ -252,8 +252,10 @@ %Parse the equations. This is done at this early stage since I need the %reversibility info [S, mets, badRxns, reversible]=constructS(rxnsToAdd.equations); -EM='The following equations have one or more metabolites both as substrate and product. Only the net equations will be added:'; -warning('RAVEN:warning', '%s', ravenList(EM, rxnsToAdd.rxns(badRxns))); +if any(badRxns) + EM='The following equations have one or more metabolites both as substrate and product. Only the net equations will be added:'; + warning('RAVEN:warning', '%s', ravenList(EM, rxnsToAdd.rxns(badRxns))); +end newModel.rev=[newModel.rev;reversible]; newModel.rxns=[newModel.rxns;rxnsToAdd.rxns(:)]; diff --git a/queries/constructS.m b/queries/constructS.m index ab7aa4d0..a0e6ef60 100755 --- a/queries/constructS.m +++ b/queries/constructS.m @@ -65,6 +65,10 @@ equations=strtrim(equations); equations=fixEquations(equations); +%A supplied list is authoritative, so an entry in it can be matched in full +%before the leading number of "2 oxoglutarate" is read as a coefficient. A +%list derived from the equations cannot disambiguate that. +metsSupplied=~isempty(mets); if isempty(mets) mets=parseRxnEqu(equations); end @@ -125,6 +129,11 @@ %No coefficient coeff=1; name=metabolites{j}; + elseif metsSupplied && any(strcmp(strtrim(metabolites{j}),mets)) + %The whole entry is a known metabolite, so its leading number is + %part of its name ("2 oxoglutarate") rather than a coefficient + coeff=1; + name=strtrim(metabolites{j}); else coeff=str2double(metabolites{j}(1:space(1))); diff --git a/testing/function_tests/tManipulation.m b/testing/function_tests/tManipulation.m index cebf6a1e..302ad3cd 100644 --- a/testing/function_tests/tManipulation.m +++ b/testing/function_tests/tManipulation.m @@ -85,6 +85,16 @@ function addTransportAddsRxn(testCase) testCase.verifyGreaterThan(numel(m2.rxns), numel(testCase.model.rxns)); end + function addRxnsCleanEquationDoesNotWarn(testCase) + % The "metabolite on both sides" warning must only fire for the + % equations it names, not on every call. + rxnsToAdd.rxns = {'newRxn'}; + rxnsToAdd.equations = {[testCase.model.mets{1} ' => ' testCase.model.mets{2}]}; + lastwarn(''); + evalc('addRxns(testCase.model, rxnsToAdd, 1);'); + testCase.verifyEmpty(strfind(lastwarn, 'both as substrate and product')); %#ok + end + function changeGrRulesUpdatesRule(testCase) m2 = changeGrRules(testCase.model, 'ACKr', 'b2296 and b1849', true); idx = strcmp(m2.rxns, 'ACKr'); diff --git a/testing/function_tests/tQueries.m b/testing/function_tests/tQueries.m index d9800601..6b353168 100644 --- a/testing/function_tests/tQueries.m +++ b/testing/function_tests/tQueries.m @@ -45,6 +45,24 @@ function constructSSimple(testCase) testCase.verifyEqual(full(S), [-1;-1;1]); end + function constructSLeadingNumberIsPartOfName(testCase) + % A metabolite whose name starts with a number must not have that + % number read as a stoichiometric coefficient when the metabolite + % list says the whole entry is a metabolite. + mets = {'2 oxoglutarate';'succinate'}; + [S, outMets] = constructS({'2 oxoglutarate => succinate'}, 'mets', mets); + testCase.verifyEqual(outMets, mets); + testCase.verifyEqual(full(S), [-1;1]); + end + + function constructSLeadingNumberStillReadsCoefficient(testCase) + % With no such metabolite, the leading number is a coefficient. + mets = {'oxoglutarate';'succinate'}; + [S, outMets] = constructS({'2 oxoglutarate => succinate'}, 'mets', mets); + testCase.verifyEqual(outMets, mets); + testCase.verifyEqual(full(S), [-2;1]); + end + function getAllRxnsFromGenesType(testCase) % Use a reaction that has a gene association. withGpr = testCase.model.rxns(find(~cellfun(@isempty, ...