Skip to content

Commit c48e82e

Browse files
committed
updated unit tests and did some bugfixes in the pam_generation script
1 parent 2330596 commit c48e82e

File tree

6 files changed

+86
-50
lines changed

6 files changed

+86
-50
lines changed

src/PAModelpy/utils/pam_generation.py

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -90,19 +90,19 @@ def parse_gpr_information(gpr_info:str,
9090
if genes is None: return gpr_list
9191

9292
#convert the genes to the associated proteins
93-
enzyme_relations = []
94-
if '_'in enzyme_id:
95-
enzyme_relations = [enzyme_id.split('_')]
96-
for sublist in gpr_list:
97-
enz_sublist = []
98-
for item in sublist:
99-
if item in gene2protein.keys():
100-
if '_' not in gene2protein[item]:
101-
enz_sublist.append(gene2protein[item])
102-
enzyme_relations += [enz_sublist]
103-
elif gene2protein[item].split('_') not in enzyme_relations:
104-
enzyme_relations += [gene2protein[item].split('_')]
105-
enzyme_relations = _filter_sublists(enzyme_relations, enzyme_id.split('_'), how='all')
93+
# enzyme_relations = []
94+
# if '_'in enzyme_id:
95+
enzyme_relations = [enzyme_id.split('_')]
96+
# for sublist in gpr_list:
97+
# enz_sublist = []
98+
# for item in sublist:
99+
# if item in gene2protein.keys():
100+
# if '_' not in gene2protein[item]:
101+
# enz_sublist.append(gene2protein[item])
102+
# enzyme_relations += enz_sublist
103+
# elif gene2protein[item].split('_') not in enzyme_relations:
104+
# enzyme_relations += gene2protein[item].split('_')
105+
# enzyme_relations = _filter_sublists(enzyme_relations, enzyme_id.split('_'), how='all')
106106
return sorted(gpr_list), sorted(enzyme_relations)
107107

108108
def get_protein_gene_mapping(enzyme_db: pd.DataFrame, model) -> tuple[dict, dict]:
@@ -281,22 +281,26 @@ def _order_enzyme_complex_id(enz_id:str,
281281
return "_".join(sorted(proteins))
282282

283283

284-
def parse_reaction2protein(enzyme_db: pd.DataFrame, model: cobra.Model) -> dict:
284+
def parse_reaction2protein(enzyme_db: pd.DataFrame,
285+
model: cobra.Model,
286+
other_enzyme_id_pattern: str = r'E[0-9][0-9]*') -> dict:
285287
rxn_info2protein = {}
286288
protein2gpr = defaultdict(list)
287289
#remove copy number substrings from the reaction to make it matchable to enzyme information
288290
filtered_model_reactions = [_extract_reaction_id(r.id) for r in model.reactions]
289291

290-
#make sure all enzyme complexes have an id ordered in a structured way
291-
enzyme_db['enzyme_id'] = enzyme_db['enzyme_id'].map(_order_enzyme_complex_id, na_action='ignore')
292-
293292
# replace NaN values with unique identifiers
294293
enzyme_db.loc[enzyme_db['enzyme_id'].isnull(), 'enzyme_id'] = [f'E{i}' for i in
295294
range(enzyme_db['enzyme_id'].isnull().sum())]
296295

297296
enzyme_db.loc[enzyme_db['gene'].isnull(), 'gene'] = [[f'gene_{i}'] for i in
298297
range(enzyme_db['gene'].isnull().sum())]
299298

299+
300+
#make sure all enzyme complexes have an id ordered in a structured way
301+
enzyme_db['enzyme_id'] = enzyme_db['enzyme_id'].apply(_order_enzyme_complex_id,
302+
other_enzyme_id_pattern = other_enzyme_id_pattern)
303+
300304
protein2gene, gene2protein = _get_genes_for_proteins(enzyme_db, model)
301305

302306
# parse the information for all gene-protein-reaction relations in the dataframe
Binary file not shown.
Binary file not shown.

tests/unit_tests/test_pamodel/test_pam_generation.py renamed to tests/unit_tests/test_pamodel/test_pam_setup.py

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pytest
22
import pickle
3+
import os
34
from src.PAModelpy.configuration import Config
45
from src.PAModelpy.PAModel import PAModel
56

@@ -8,6 +9,7 @@
89
from Scripts.pam_generation_uniprot_id import (set_up_ecolicore_pam, set_up_ecoli_pam, set_up_toy_pam,
910
parse_gpr_information_for_protein2genes,
1011
parse_gpr_information_for_rxn2protein)
12+
from src.PAModelpy.utils import set_up_pam
1113

1214

1315
def test_gpr_information_is_parsed_correctly():
@@ -48,11 +50,13 @@ def test_gpr_information_for_protein_is_correctly_filtered():
4850
def test_if_enzyme_complex_in_toy_pam_is_parsed_correctly():
4951
sut = set_up_toy_pam_with_enzyme_complex(sensitivity=False)
5052

51-
assert all([enz in sut.enzymes for enz in ['E1', 'E2', 'E10', 'E2_E10']])
52-
assert all([const not in sut.constraints.keys() for const in ['EC_E10_f', 'EC_E2_f']])
53-
constraint = sut.constraints['EC_E2_E10_f'].get_linear_coefficients([sut.reactions.CE_R2_E2_E10.forward_variable])
54-
assert constraint[sut.reactions.CE_R2_E2_E10.forward_variable] > 0
53+
print(sut.enzymes, sut.enzyme_variables)
5554

55+
assert all([enz in sut.enzymes for enz in ['E1', 'E10_E2']])
56+
assert all([const not in sut.constraints.keys() for const in ['EC_E10_f', 'EC_E2_f']])
57+
constraint = sut.constraints['EC_E10_E2_f'].get_linear_coefficients([sut.reactions.CE_R2_E10_E2.forward_variable])
58+
assert constraint[sut.reactions.CE_R2_E10_E2.forward_variable] > 0
59+
#
5660
def test_if_isozymes_in_toy_pam_are_parsed_correctly():
5761
sut = set_up_toy_pam_with_isozymes(sensitivity=False)
5862

@@ -102,26 +106,16 @@ def test_if_toy_pam_with_enzyme_comples_has_same_growth_rate_as_without():
102106

103107
assert sut.objective.value == pytest.approx(toy_pam.objective.value, abs = 1e-6)
104108

105-
def test_set_up_ecolicore_pam_works():
106-
sut = set_up_ecolicore_pam()
107-
sut.optimize()
108-
assert True
109-
def test_if_ecolicore_pam_optimizes():
110-
sut = set_up_ecolicore_pam()
111-
sut.optimize()
112-
assert sut.objective.value > 0
113-
114-
def test_set_up_ecoli_pam_works():
115-
sut = set_up_ecoli_pam()
116-
assert True
109+
def test_if_pamodel_can_be_pickled_and_unpickled():
110+
# Arrange
111+
pam_data_file = os.path.join('tests', 'data', 'proteinAllocationModel_iML1515_EnzymaticData_241209.xlsx')
112+
iml1515 = os.path.join('Models', 'iML1515.xml')
113+
sut = set_up_pam(pam_data_file,
114+
iml1515,
115+
sensitivity=False,
116+
adjust_reaction_ids=False)
117117

118-
def test_if_ecoli_pam_optimizes():
119-
sut = set_up_ecoli_pam()
120118
sut.optimize()
121-
assert sut.objective.value > 0
122-
123-
def test_if_pamodel_can_be_pickled_and_unpickled():
124-
sut = set_up_ecoli_pam(sensitivity=False)
125119
sut.change_reaction_bounds('EX_glc__D_e', -10, 0)
126120
sut.optimize()
127121

@@ -151,9 +145,15 @@ def set_up_toy_pam_with_enzyme_complex(sensitivity =True):
151145
Etot = 0.6*1e-3
152146
model = build_toy_gem()
153147
active_enzyme = build_active_enzyme_sector(config)
148+
154149
#add an enzyme associated to enzyme complex to the toy model
155150
active_enzyme.rxn2protein['R2']['E2']['protein_reaction_association'] = [['E2', 'E10']]
156-
active_enzyme.rxn2protein['R2']['E10']= active_enzyme.rxn2protein['R2']['E2'].copy()
151+
# active_enzyme.rxn2protein['R2']['E10']= active_enzyme.rxn2protein['R2']['E2'].copy()
152+
active_enzyme.rxn2protein['R2']['E2_E10'] = active_enzyme.rxn2protein['R2']['E2'].copy()
153+
del active_enzyme.rxn2protein['R2']['E2']
154+
155+
active_enzyme.protein2gene['E2_E10'] = [['gene2', 'gene10']]
156+
157157

158158
#build the toy model
159159
unused_enzyme = build_unused_protein_sector(config)
@@ -180,6 +180,7 @@ def set_up_toy_pam_with_isozymes(sensitivity =True):
180180
active_enzyme.rxn2protein['R2']['E2']['protein_reaction_association'] = [['E2'], ['E10']]
181181
active_enzyme.rxn2protein['R2']['E10']= active_enzyme.rxn2protein['R2']['E2'].copy()
182182

183+
183184
#build the toy model
184185
unused_enzyme = build_unused_protein_sector(config)
185186
translation_enzyme = build_translational_protein_sector(config)
@@ -209,6 +210,9 @@ def set_up_toy_pam_with_isozymes_and_enzymecomplex(sensitivity =True):
209210
active_enzyme.rxn2protein['R3']['E3']['protein_reaction_association'] = [['E3','E10', 'E11']]
210211
active_enzyme.rxn2protein['R3']['E10']= active_enzyme.rxn2protein['R3']['E3'].copy()
211212
active_enzyme.rxn2protein['R3']['E11']= active_enzyme.rxn2protein['R3']['E3'].copy()
213+
active_enzyme.rxn2protein['R3']['E3_E10_E11']= active_enzyme.rxn2protein['R3']['E3'].copy()
214+
215+
active_enzyme.protein2gene['E3_E10_E11'] = [['gene3', 'gene10', 'gene11']]
212216

213217

214218
#build the toy model

tests/unit_tests/test_pamodel/test_pamodel.py

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import pytest
22
from cobra.io import load_json_model
3+
import os
34

45
from src.PAModelpy import PAModel,Config,ActiveEnzymeSector, UnusedEnzymeSector, TransEnzymeSector, CatalyticEvent
5-
from Scripts.pam_generation_uniprot_id import set_up_ecoli_pam, set_up_ecolicore_pam
6-
from tests.unit_tests.test_pamodel.test_pam_generation import set_up_toy_pam_with_isozymes_and_enzymecomplex
6+
from tests.unit_tests.test_pamodel.test_pam_setup import set_up_toy_pam_with_isozymes_and_enzymecomplex
7+
from src.PAModelpy.utils import set_up_pam
78

89
def test_if_pamodel_change_kcat_function_works():
910
#arrange
@@ -43,7 +44,7 @@ def test_if_pamodel_change_kcat_function_works_with_catalytic_reactions():
4344
#arrange
4445
sut = set_up_ecoli_pam(sensitivity=False)
4546
input_kcat = 10
46-
enzyme_id = 'P0ABJ1'
47+
enzyme_id = 'P0ABI8_P0ABJ1_P0ABJ3_P0ABJ6'
4748
rxn_id = "CYTBO3_4pp"
4849
ce_rxn= sut.reactions.query(f'CE_{rxn_id}_{enzyme_id}')[0]
4950
enzyme_complex_id = "_".join(ce_rxn.id.split("_")[3:])
@@ -173,6 +174,7 @@ def test_if_pamodel_sensitivity_can_be_changed_false_to_true():
173174
def test_if_pamodel_sensitivity_can_be_changed_true_to_false_ecolicore():
174175
# arrange
175176
ecolicore_pam = set_up_ecolicore_pam(sensitivity=True)
177+
176178
glc_lb = -ecolicore_pam.constraints['EX_glc__D_e_lb'].ub
177179
glc_ub = ecolicore_pam.constraints['EX_glc__D_e_ub'].ub
178180

@@ -269,11 +271,13 @@ def test_if_pamodel_gets_catalyzing_enzymes_for_enzyme_object():
269271
# Arrange
270272
sut = set_up_toy_pam_with_isozymes_and_enzymecomplex(sensitivity = False)
271273
enzyme_ut = 'E10'
272-
associated_enzymes = ['E10', 'E3_E10_E11']
274+
associated_enzymes = ['E10', 'E10_E11_E3']
273275

274276
# Assert
275277
catalyzing_enzymes = sut._get_catalyzing_enzymes_for_enzyme(enzyme_ut)
276278

279+
print(catalyzing_enzymes)
280+
277281
# Assert
278282
assert all(enz in catalyzing_enzymes for enz in associated_enzymes)
279283

@@ -334,4 +338,24 @@ def assert_bounds(model_ori, model_copy):
334338
def assert_total_protein_content(model_ori, model_copy):
335339
assert model_ori.p_tot == model_copy.p_tot
336340
tot_prot_cons_id = model_ori.TOTAL_PROTEIN_CONSTRAINT_ID
337-
assert model_ori.constraints[tot_prot_cons_id].ub == model_copy.constraints[tot_prot_cons_id].ub
341+
assert model_ori.constraints[tot_prot_cons_id].ub == model_copy.constraints[tot_prot_cons_id].ub
342+
343+
def set_up_ecoli_pam(sensitivity=True):
344+
pam_data_file = os.path.join('tests', 'data', 'proteinAllocationModel_iML1515_EnzymaticData_241209.xlsx')
345+
iml1515 = os.path.join('Models', 'iML1515.xml')
346+
return set_up_pam(pam_data_file,
347+
iml1515,
348+
sensitivity=sensitivity,
349+
adjust_reaction_ids=False)
350+
351+
def set_up_ecolicore_pam(sensitivity=True):
352+
pam_data_file = os.path.join('tests', 'data',
353+
'proteinAllocationModel_iML1515_EnzymaticData_core.xlsx')
354+
ecolicore_gem = load_json_model(os.path.join('Models', 'e_coli_core.json'))
355+
356+
# Apply
357+
return set_up_pam(pam_data_file,
358+
ecolicore_gem,
359+
total_protein=0.1699,
360+
sensitivity=sensitivity,
361+
adjust_reaction_ids=True)

tests/unit_tests/test_utils/test_pam_generation.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import pytest
77

88
from Scripts.toy_ec_pam import build_toy_gem
9-
from src.utils.pam_generation import parse_reaction2protein, set_up_pam
9+
from src.PAModelpy.utils.pam_generation import parse_reaction2protein, set_up_pam
1010

1111
def test_if_rxn2protein_info_is_correctly_parsed():
1212
# Arrange
@@ -20,6 +20,8 @@ def test_if_rxn2protein_info_is_correctly_parsed():
2020
'direction':['f','f', 'f', 'f', 'b']
2121
}
2222
)
23+
print(toy_enzyme_db)
24+
2325
toy_model = build_toy_gem()
2426

2527
expected_rxn2protein = {
@@ -49,15 +51,17 @@ def test_if_rxn2protein_info_is_correctly_parsed():
4951
expected_protein2gpr = {'E1': [['gene1']], 'E2a': [['gene2a']], 'E2b_E2c': [['gene2b', 'gene2c']], 'E3': [['gene3']]}
5052

5153
# Apply
52-
rxn2protein, protein2gpr = parse_reaction2protein(toy_enzyme_db, toy_model)
54+
rxn2protein, protein2gpr = parse_reaction2protein(toy_enzyme_db,
55+
toy_model,
56+
other_enzyme_id_pattern = r'E[0-9][0-9]*[a-z]?')
5357

5458
# Assert
5559
for output_dict, expected_dict in zip([rxn2protein, protein2gpr], [expected_rxn2protein, expected_protein2gpr]):
5660
assert all([expected_dict[key] == value for key, value in output_dict.items()])
5761

5862
def test_if_set_up_pam_can_build_ecolicore_pam():
5963
#Arrange
60-
pam_data_file = os.path.join('Data', 'proteinAllocationModel_iML1515_EnzymaticData_core.xlsx')
64+
pam_data_file = os.path.join('tests','data', 'proteinAllocationModel_iML1515_EnzymaticData_core.xlsx')
6165
ecolicore_gem = cobra.io.load_json_model(os.path.join('Models', 'e_coli_core.json'))
6266

6367
#Apply
@@ -74,14 +78,14 @@ def test_if_set_up_pam_can_build_ecolicore_pam():
7478

7579
def test_if_set_up_pam_can_build_iML1515():
7680
#Arrange
77-
pam_data_file = os.path.join('Results', '1_preprocessing', 'proteinAllocationModel_iML1515_EnzymaticData_241209.xlsx')
81+
pam_data_file = os.path.join('tests','data', 'proteinAllocationModel_iML1515_EnzymaticData_241209.xlsx')
7882
iml1515 = os.path.join('Models', 'iML1515.xml')
7983

8084
#Apply
8185
pam = set_up_pam(pam_data_file,
8286
iml1515,
8387
sensitivity=False,
84-
adjust_reaction_ids=True)
88+
adjust_reaction_ids=False)
8589

8690
pam.optimize()
8791

0 commit comments

Comments
 (0)