Sanjana Vekhande commited on
Commit
cbddf96
·
1 Parent(s): 01de07f

Fix gene parsing and apply expression mappings

Browse files
Files changed (1) hide show
  1. utils/bootstrap_genes.py +38 -23
utils/bootstrap_genes.py CHANGED
@@ -16,6 +16,23 @@ def extract_genes_from_gpa(gpa_str):
16
  keywords = {'or', 'and', 'not'}
17
  return [t for t in tokens if t.lower() not in keywords]
18
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  def read_combined_geneExpr(combined_geneExpr_filename):
20
  if not os.path.isfile(combined_geneExpr_filename):
21
  raise FileNotFoundError(f"Missing combined normalized count file, expected at {combined_geneExpr_filename}")
@@ -28,13 +45,11 @@ def is_real_gene_with_mapping(gene):
28
  def read_system_gene(model_pre_filename):
29
  rxn_df = read_model_excel(model_pre_filename, "Reactions")
30
 
31
- # Support 'genes' (stringified-list format) or fall back to 'gpaAssociation' (string format)
32
  if "genes" in rxn_df.columns:
33
  gene_col = "genes"
34
- use_ast = True
35
  elif "gpaAssociation" in rxn_df.columns:
36
  gene_col = "gpaAssociation"
37
- use_ast = False
38
  else:
39
  raise ValueError(
40
  "Reactions sheet must have a 'genes' or 'gpaAssociation' column — "
@@ -45,10 +60,7 @@ def read_system_gene(model_pre_filename):
45
  missing_gene_system_dict = {}
46
  all_genes_set = set()
47
  for system, gene_list_raw in zip(rxn_df["system"], rxn_df[gene_col]):
48
- if use_ast:
49
- gene_list = ast.literal_eval(gene_list_raw)
50
- else:
51
- gene_list = extract_genes_from_gpa(gene_list_raw)
52
 
53
  if system != "" and system not in system_genes_dict:
54
  system_genes_dict[system] = set()
@@ -64,22 +76,23 @@ def read_system_gene(model_pre_filename):
64
  missing_gene_system_dict = dict(sorted(missing_gene_system_dict.items()))
65
  return system_genes_dict, missing_gene_system_dict, all_genes_set
66
 
67
- # def map_genes(mapping_dict, system_genes_dict, all_genes_set):
68
- # system_genes_dict_new = {}
69
- # for system, gene_set in system_genes_dict.items():
70
- # gene_set_new = set()
71
- # for gene in gene_set:
72
- # if gene in mapping_dict: # TODO: if not print warning
73
- # gene_set_new.add(mapping_dict[gene])
74
- # if gene_set_new:
75
- # system_genes_dict_new[system] = gene_set_new
76
 
77
- # all_genes_set_new = set()
78
- # for gene in all_genes_set:
79
- # if gene in mapping_dict:
80
- # all_genes_set_new.add(mapping_dict[gene])
 
 
 
 
 
81
 
82
- # return system_genes_dict_new, all_genes_set_new
 
83
 
84
  def filter_geneExpr_df(combined_geneExpr_df, all_genes_set):
85
  geneExpr_df = combined_geneExpr_df.loc[combined_geneExpr_df.index.isin(all_genes_set)]
@@ -148,8 +161,10 @@ def bootstrap_genes(model_pre_filenames, mapping_filenames, species_prefixes, co
148
  # all_genes_set: set of all the real genes with mapping used in the model of that species
149
  system_genes_dict, missing_gene_system_dict, all_genes_set = read_system_gene(model_pre_filename)
150
 
151
- # map gene from model to gene in annotation(used in geneExpr file)
152
- # system_genes_dict, all_genes_set = map_genes(mapping_dict, system_genes_dict, all_genes_set)
 
 
153
 
154
  # filter to get only geneExprs for that species
155
  geneExpr_df = filter_geneExpr_df(combined_geneExpr_df, all_genes_set)
 
16
  keywords = {'or', 'and', 'not'}
17
  return [t for t in tokens if t.lower() not in keywords]
18
 
19
+ def parse_genes(gene_value):
20
+ """Parse either a stringified gene list or a boolean gene expression."""
21
+ if pd.isna(gene_value) or str(gene_value).strip() == "":
22
+ return []
23
+
24
+ if isinstance(gene_value, (list, tuple, set)):
25
+ return list(gene_value)
26
+
27
+ try:
28
+ parsed = ast.literal_eval(str(gene_value))
29
+ except (ValueError, SyntaxError):
30
+ return extract_genes_from_gpa(gene_value)
31
+
32
+ if isinstance(parsed, (list, tuple, set)):
33
+ return list(parsed)
34
+ return extract_genes_from_gpa(parsed)
35
+
36
  def read_combined_geneExpr(combined_geneExpr_filename):
37
  if not os.path.isfile(combined_geneExpr_filename):
38
  raise FileNotFoundError(f"Missing combined normalized count file, expected at {combined_geneExpr_filename}")
 
45
  def read_system_gene(model_pre_filename):
46
  rxn_df = read_model_excel(model_pre_filename, "Reactions")
47
 
48
+ # Support both stringified lists and boolean expressions in 'genes'.
49
  if "genes" in rxn_df.columns:
50
  gene_col = "genes"
 
51
  elif "gpaAssociation" in rxn_df.columns:
52
  gene_col = "gpaAssociation"
 
53
  else:
54
  raise ValueError(
55
  "Reactions sheet must have a 'genes' or 'gpaAssociation' column — "
 
60
  missing_gene_system_dict = {}
61
  all_genes_set = set()
62
  for system, gene_list_raw in zip(rxn_df["system"], rxn_df[gene_col]):
63
+ gene_list = parse_genes(gene_list_raw)
 
 
 
64
 
65
  if system != "" and system not in system_genes_dict:
66
  system_genes_dict[system] = set()
 
76
  missing_gene_system_dict = dict(sorted(missing_gene_system_dict.items()))
77
  return system_genes_dict, missing_gene_system_dict, all_genes_set
78
 
79
+ def map_genes(mapping_dict, system_genes_dict, missing_gene_system_dict, all_genes_set):
80
+ """Map model gene tags to expression IDs and retain unmapped tags for bootstrapping."""
81
+ mapped_system_genes = {}
82
+ missing_genes = dict(missing_gene_system_dict)
 
 
 
 
 
83
 
84
+ for system, gene_set in system_genes_dict.items():
85
+ mapped_genes = set()
86
+ for gene in gene_set:
87
+ if gene in mapping_dict:
88
+ mapped_genes.add(mapping_dict[gene])
89
+ else:
90
+ missing_genes.setdefault(gene, system)
91
+ if mapped_genes:
92
+ mapped_system_genes[system] = mapped_genes
93
 
94
+ mapped_all_genes = {mapping_dict[gene] for gene in all_genes_set if gene in mapping_dict}
95
+ return mapped_system_genes, dict(sorted(missing_genes.items())), mapped_all_genes
96
 
97
  def filter_geneExpr_df(combined_geneExpr_df, all_genes_set):
98
  geneExpr_df = combined_geneExpr_df.loc[combined_geneExpr_df.index.isin(all_genes_set)]
 
161
  # all_genes_set: set of all the real genes with mapping used in the model of that species
162
  system_genes_dict, missing_gene_system_dict, all_genes_set = read_system_gene(model_pre_filename)
163
 
164
+ # Map model tags to the annotation IDs used in the expression file.
165
+ system_genes_dict, missing_gene_system_dict, all_genes_set = map_genes(
166
+ mapping_dict, system_genes_dict, missing_gene_system_dict, all_genes_set
167
+ )
168
 
169
  # filter to get only geneExprs for that species
170
  geneExpr_df = filter_geneExpr_df(combined_geneExpr_df, all_genes_set)