From c840d48db076bd8e1f9b123e276042576d2ec346 Mon Sep 17 00:00:00 2001 From: Eduard Kerkhoven Date: Wed, 14 Oct 2026 16:40:15 +0200 Subject: [PATCH] fix: reject gene ids that split in grRules in getModelFromHomology New-organism gene ids become gene ids of the draft model, and grRules are split at whitespace and parentheses, and by COBRA also at "|" and "&". UniProt FASTA headers such as sp|P33284|HXK_KLULA passed through and broke the draft downstream. getModelFromHomology now raises an error naming the offending ids, as raven-toolbox does. Original-commit: https://github.com/SysBioChalmers/RAVEN/commit/48b3c525792caea7ff478a5719e22faf04fb06b2 --- reconstruction/homology/getModelFromHomology.m | 16 ++++++++++++++++ testing/function_tests/tReconstruction.m | 7 +++++++ 2 files changed, 23 insertions(+) diff --git a/reconstruction/homology/getModelFromHomology.m b/reconstruction/homology/getModelFromHomology.m index ca26e70a..00866bdf 100755 --- a/reconstruction/homology/getModelFromHomology.m +++ b/reconstruction/homology/getModelFromHomology.m @@ -93,6 +93,11 @@ % unneccesary old genes, the models should not have "or"-relations in their % grRules (use expandModel). % +% The gene ids of the new organism in blastStructure become its gene ids in +% the draft model, so they cannot contain whitespace, parentheses, "|" or +% "&". FASTA headers from UniProt, such as "sp|P33284|HXK_KLULA", should be +% reduced to the accession first. +% % The resulting draft model contains only reactions associated with % orthologous genes, plus the gene-free ones with keepGeneFree. With % complexPolicy "flag", the old (original) genes involved in "and" relations @@ -423,6 +428,17 @@ finalMappings{i}=finalMappings{i}(usedNewGenes,:); end +%Gene ids end up in grRules, which are split at whitespace and parentheses, +%and which COBRA also splits at "|" and "&" +unusable=allGenes{1}(~cellfun(@isempty,regexp(allGenes{1},'[\s()|&]','once'))); +if ~isempty(unusable) + error('RAVEN:badInput',['%d gene ids of "%s" cannot be written into a grRule, '... + 'because they contain whitespace, parentheses, "|" or "&": %s. Map them '... + 'to gene ids first, or use the accession alone for UniProt headers such '... + 'as "sp|P33284|HXK_KLULA".'],numel(unusable),getModelFor,... + strjoin(unusable(1:min(3,end))',', ')); +end + %Now is it time to choose which reactions should be included from which %models. If there is a preferred order specified then each gene can only %result in reactions from one model, otherwise they should all be included diff --git a/testing/function_tests/tReconstruction.m b/testing/function_tests/tReconstruction.m index 96e3b277..b28f5179 100644 --- a/testing/function_tests/tReconstruction.m +++ b/testing/function_tests/tReconstruction.m @@ -85,6 +85,13 @@ function getModelFromHomologyComplexPolicyAndOptions(testCase) testCase.verifyEqual(flag.rxnNotes{1}, 'Included by getModelFromHomology'); end + function getModelFromHomologyRejectsGeneIdsThatSplit(testCase) + src = testCase.model; src.id = 'srcModel'; + newGenes = cellstr(strcat('sp|P', string(1:10)', '|X_BUG')); + bs = makeFakeBlastStructure([src.genes(1:10), newGenes], 'srcModel', 'tgtOrg'); + testCase.verifyError(@() getModelFromHomology({src}, bs, 'tgtOrg'), 'RAVEN:badInput'); + end + function getModelFromHomologyRejectsUnknownComplexPolicy(testCase) src = testCase.model; src.id = 'srcModel'; bs = makeFakeBlastStructure([src.genes(1:10), strcat('t_', src.genes(1:10))], 'srcModel', 'tgtOrg');