Skip to content

Commit 65c7401

Browse files
Christopher Henryclaude
andcommitted
Fix build_reaction_expression to support direct gene ID matching
Fixed issue where reaction expression values were blank when converting from gene-level to reaction-level expression. The problem occurred when expression data was loaded without a genome or when model gene IDs didn't match genome feature IDs. The original code only searched through the genome object, failing to find genes with different ID formats (e.g., model has ACIAD#### but expression has ACIAD_RS#####). Changes: - First attempt direct lookup in self.features by gene ID - Fall back to genome search (which supports aliases) if direct lookup fails - This allows matching when gene IDs are identical, even without a genome - Maintains backward compatibility with genome-based alias resolution Fixes blank reaction expression values in genome-to-model conversion. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 9ffac0e commit 65c7401

File tree

1 file changed

+26
-17
lines changed

1 file changed

+26
-17
lines changed

modelseedpy/multiomics/msexpression.py

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -497,25 +497,34 @@ def build_reaction_expression(self, model, default: Optional[float] = None) -> '
497497
# Pulling the gene values from the current expression using DataFrame
498498
values = {}
499499
for gene in model.genes:
500-
feature = self.object.search_for_gene(gene.id)
501-
if feature is None:
502-
logger.debug(
503-
"Model gene " + gene.id + " not found in genome or expression"
504-
)
505-
elif feature.id not in self.features:
506-
logger.debug(
507-
"Model gene " + gene.id + " in genome but not in expression"
508-
)
500+
# First, try to find the gene directly in expression features
501+
# This handles cases where expression was loaded without a genome
502+
if gene.id in self.features:
503+
feature = self.features.get_by_id(gene.id)
509504
else:
505+
# Fallback: search through the genome object (supports aliases)
506+
feature = self.object.search_for_gene(gene.id)
507+
if feature is None:
508+
logger.debug(
509+
"Model gene " + gene.id + " not found in genome or expression"
510+
)
511+
continue
512+
if feature.id not in self.features:
513+
logger.debug(
514+
"Model gene " + gene.id + " in genome but not in expression"
515+
)
516+
continue
510517
feature = self.features.get_by_id(feature.id)
511-
for condition in self.conditions:
512-
if condition.id not in values:
513-
values[condition.id] = {}
514-
# Get value from DataFrame instead of feature.values dictionary
515-
if feature.id in self._data.index and condition.id in self._data.columns:
516-
value = self._data.loc[feature.id, condition.id]
517-
if not pd.isna(value):
518-
values[condition.id][gene.id] = value
518+
519+
# Extract expression values for this feature
520+
for condition in self.conditions:
521+
if condition.id not in values:
522+
values[condition.id] = {}
523+
# Get value from DataFrame instead of feature.values dictionary
524+
if feature.id in self._data.index and condition.id in self._data.columns:
525+
value = self._data.loc[feature.id, condition.id]
526+
if not pd.isna(value):
527+
values[condition.id][gene.id] = value
519528

520529
# Computing the reaction level values
521530
for condition in rxnexpression.conditions:

0 commit comments

Comments
 (0)