diff --git a/conversion/addIdentifierPrefix.m b/conversion/addIdentifierPrefix.m index 3f0629da..cf6b205f 100644 --- a/conversion/addIdentifierPrefix.m +++ b/conversion/addIdentifierPrefix.m @@ -60,10 +60,8 @@ currField = strcat(currPrefix, currField); hasChanged(toChangeIdx(i)) = true; - if strcmp(currName,'genes') - model.grRules = regexprep(model.grRules, '(\<[0-9_a-zA-Z])', 'G_$1'); - model.grRules = regexprep(model.grRules, ' G_or ', ' or '); - model.grRules = regexprep(model.grRules, ' G_and ', ' and '); + if strcmp(currName,'genes') && isfield(model,'grRules') + model.grRules = cellfun(@(r) prefixGenes(r,currPrefix), model.grRules, 'UniformOutput', false); end model.(currName) = currField; end @@ -72,3 +70,19 @@ hasChanged = modelFields(hasChanged,:); hasChanged = append('model.', hasChanged(:,1), ' (', hasChanged(:,2), ' prefix)'); end + + +function rule = prefixGenes(rule, prefix) +% Prefix every gene in a grRule, leaving "and", "or" and brackets alone. A +% gene is everything between spaces and brackets, so ids that contain +% "-", "." or ":" get one prefix, not one per word. +[tokens, separators] = regexp(rule, '[^\s()]+', 'match', 'split'); +out = separators{1}; +for i = 1:numel(tokens) + if ~any(strcmpi(tokens{i}, {'and','or'})) + tokens{i} = [prefix tokens{i}]; + end + out = [out tokens{i} separators{i+1}]; %#ok +end +rule = out; +end diff --git a/doc/conversion/addIdentifierPrefix.html b/doc/conversion/addIdentifierPrefix.html index 24266779..4c7b682d 100644 --- a/doc/conversion/addIdentifierPrefix.html +++ b/doc/conversion/addIdentifierPrefix.html @@ -72,7 +72,9 @@

CROSS-REFERENCE INFORMATION ^
 </ul>
 <!-- crossreference -->
 
-
+<h2><a name=SUBFUNCTIONS ^

+

SOURCE CODE ^

0001 function [model, hasChanged]=addIdentifierPrefix(model,varargin)
@@ -137,18 +139,32 @@ 

SOURCE CODE ^if strcmp(currName,'genes') -0064 model.grRules = regexprep(model.grRules, '(\<[0-9_a-zA-Z])', 'G_$1'); -0065 model.grRules = regexprep(model.grRules, ' G_or ', ' or '); -0066 model.grRules = regexprep(model.grRules, ' G_and ', ' and '); -0067 end -0068 model.(currName) = currField; -0069 end -0070 end -0071 -0072 hasChanged = modelFields(hasChanged,:); -0073 hasChanged = append('model.', hasChanged(:,1), ' (', hasChanged(:,2), ' prefix)'); -0074 end

+0063 if strcmp(currName,'genes') && isfield(model,'grRules') +0064 model.grRules = cellfun(@(r) prefixGenes(r,currPrefix), model.grRules, 'UniformOutput', false); +0065 end +0066 model.(currName) = currField; +0067 end +0068 end +0069 +0070 hasChanged = modelFields(hasChanged,:); +0071 hasChanged = append('model.', hasChanged(:,1), ' (', hasChanged(:,2), ' prefix)'); +0072 end +0073 +0074 +0075 function rule = prefixGenes(rule, prefix) +0076 % Prefix every gene in a grRule, leaving "and", "or" and brackets alone. A +0077 % gene is everything between spaces and brackets, so ids that contain +0078 % "-", "." or ":" get one prefix, not one per word. +0079 [tokens, separators] = regexp(rule, '[^\s()]+', 'match', 'split'); +0080 out = separators{1}; +0081 for i = 1:numel(tokens) +0082 if ~any(strcmpi(tokens{i}, {'and','or'})) +0083 tokens{i} = [prefix tokens{i}]; +0084 end +0085 out = [out tokens{i} separators{i+1}]; %#ok<AGROW> +0086 end +0087 rule = out; +0088 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/testing/function_tests/tConversion.m b/testing/function_tests/tConversion.m index 53ed7d5a..1c2d4195 100644 --- a/testing/function_tests/tConversion.m +++ b/testing/function_tests/tConversion.m @@ -12,6 +12,17 @@ function identifierPrefixRoundTrip(testCase) testCase.verifyEqual(mr.genes, testCase.model.genes); end + function identifierPrefixKeepsGenesWithPunctuationWhole(testCase) + % A gene id with "-", "." or ":" gets one prefix in grRules, the + % same one it gets in model.genes, so the two still match. + m = testCase.model; + m.genes = [m.genes; {'5-HT1A'; 'b2:1'}]; + m.grRules{1} = '5-HT1A and (b2:1 or 5-HT1A)'; + [mp, ~] = addIdentifierPrefix(m, 'fields', {'genes'}); + testCase.verifyEqual(mp.grRules{1}, 'G_5-HT1A and (G_b2:1 or G_5-HT1A)'); + testCase.verifyTrue(all(ismember(getGenesFromGrRules(mp.grRules(1)), mp.genes))); + end + function removeIdentifierPrefixSkipsMissingFields(testCase) % A model missing an optional field (genes, metNames, rxnNames, % id) must not make the default field list throw; it should