@@ -11,10 +11,16 @@ def template():
11
11
return MSTemplateBuilder .from_dict (json .load (fh )).build ()
12
12
13
13
14
+ @pytest .fixture
15
+ def template_genome_scale ():
16
+ with open ('./tests/test_data/template_genome_scale_bigg.json' , 'r' ) as fh :
17
+ return MSTemplateBuilder .from_dict (json .load (fh )).build ()
18
+
19
+
14
20
@pytest .fixture
15
21
def get_model ():
16
22
17
- def _method (ko = None ):
23
+ def _method (ko = None , added_compounds = None , added_reactions = None ):
18
24
if ko is None :
19
25
ko = []
20
26
with open ('./tests/test_data/e_coli_core.json' , 'r' ) as fh :
@@ -36,6 +42,13 @@ def _method(ko=None):
36
42
r ['id' ] += '_' + 'c0' # hack cause there is only combo between e0 and c0
37
43
38
44
model_json ['reactions' ] = [x for x in model_json ['reactions' ] if x ['id' ] not in ko ]
45
+
46
+ if added_compounds :
47
+ for o in added_compounds :
48
+ model_json ['metabolites' ].append (o )
49
+ if added_reactions :
50
+ for o in added_reactions :
51
+ model_json ['reactions' ].append (o )
39
52
model = cobra .io .from_json (json .dumps (model_json ))
40
53
model .reactions .ATPM_c0 .lower_bound = 0
41
54
model .reactions .ATPM_c0 .upper_bound = 1000
@@ -68,25 +81,143 @@ def media_acetate_aerobic():
68
81
return media
69
82
70
83
84
+ @pytest .fixture
85
+ def media_genome_scale_glucose_aerobic ():
86
+ media = MSMedia .from_dict ({
87
+ 'glc__D' : (- 10 , 1000 ),
88
+ 'o2' : (- 1000 , 1000 ),
89
+ 'h' : (- 1000 , 1000 ),
90
+ 'h2o' : (- 1000 , 1000 ),
91
+ 'pi' : (- 1000 , 1000 ),
92
+ 'co2' : (- 1000 , 1000 ),
93
+ 'nh4' : (- 1000 , 1000 ),
94
+ 'k' : (- 1000 , 1000 ),
95
+ })
96
+ return media
97
+
98
+
71
99
@pytest .fixture
72
100
def media_all_aerobic (media_glucose_aerobic , media_acetate_aerobic ):
73
101
return [media_glucose_aerobic , media_acetate_aerobic ]
74
102
75
103
104
+ @pytest .fixture
105
+ def get_model_with_infinite_atp_loop (get_model , template_genome_scale ):
106
+
107
+ def _method (ko = None ):
108
+ added_compounds = [{
109
+ 'id' : 'k_c0' ,
110
+ 'name' : 'K [c]' ,
111
+ 'compartment' : 'c0' ,
112
+ 'charge' : 1 ,
113
+ 'formula' : 'K' ,
114
+ 'notes' : {},
115
+ 'annotation' : {'sbo' : 'SBO:0000247' }
116
+ }, {
117
+ 'id' : 'k_e0' ,
118
+ 'name' : 'K [e]' ,
119
+ 'compartment' : 'e0' ,
120
+ 'charge' : 1 ,
121
+ 'formula' : 'K' ,
122
+ 'notes' : {},
123
+ 'annotation' : {'sbo' : 'SBO:0000247' }
124
+ }]
125
+ added_reactions = [{
126
+ 'id' : 'EX_k_e0' ,
127
+ 'name' : 'K exchange' ,
128
+ 'metabolites' : {'k_e0' : - 1.0 },
129
+ 'lower_bound' : - 1000 ,
130
+ 'upper_bound' : 1000.0 ,
131
+ 'gene_reaction_rule' : '' ,
132
+ 'subsystem' : 'Extracellular exchange' ,
133
+ 'notes' : {},
134
+ 'annotation' : {}
135
+ }]
136
+ model = get_model (ko , added_compounds , added_reactions )
137
+ model .reactions .get_by_id ('BIOMASS_Ecoli_core_w_GAM_c0' ).add_metabolites ({
138
+ model .metabolites .get_by_id ('k_c0' ): 0.01
139
+ })
140
+ model .add_reactions ([template_genome_scale .reactions .Kt2r_c .to_reaction (model )])
141
+ model .add_reactions ([template_genome_scale .reactions .Ktex_c .to_reaction (model )])
142
+ model .medium = {
143
+ 'EX_co2_e0' : 1000.0 ,
144
+ 'EX_glc__D_e0' : 10.0 ,
145
+ 'EX_h_e0' : 1000.0 ,
146
+ 'EX_h2o_e0' : 1000.0 ,
147
+ 'EX_nh4_e0' : 1000.0 ,
148
+ 'EX_o2_e0' : 1000.0 ,
149
+ 'EX_pi_e0' : 1000.0 ,
150
+ 'EX_k_e0' : 1000.0
151
+ }
152
+
153
+ return model
154
+
155
+ return _method
156
+
157
+
158
+ def test_infinite_atp_model_growth_boost (get_model_with_infinite_atp_loop , template , template_genome_scale , media_glucose_aerobic ):
159
+ model = get_model_with_infinite_atp_loop ()
160
+ solution = model .optimize ()
161
+ assert solution .objective_value > 1.2 # should be around 1.316
162
+ assert solution .status == 'optimal'
163
+
164
+
76
165
def test_ms_atp_correction1 (get_model , template , media_all_aerobic ):
77
- model = get_model (["GLCpts_c0" , "NADH16_c0" , "GLCpts_c0 " , "O2t_c0" ])
166
+ model = get_model (["GLCpts_c0" , "NADH16_c0" , "CYTBD_c0 " , "O2t_c0" ])
78
167
atp_correction = MSATPCorrection (model , template , media_all_aerobic , atp_hydrolysis_id = 'ATPM_c0' )
79
168
atp_correction .evaluate_growth_media ()
80
- print ('non_core_reactions' , len (atp_correction .noncore_reactions ),
81
- 'other_compartments' , len (atp_correction .other_compartments ),
82
- 'original_bounds' , len (atp_correction .original_bounds ))
83
- for media in atp_correction .media_gapfill_stats :
84
- print (media , atp_correction .media_gapfill_stats [media ])
169
+ assert len (atp_correction .noncore_reactions ) == 1 # the biomass
170
+ assert len (atp_correction .other_compartments ) == 0 # none
171
+ assert len (atp_correction .original_bounds ) == 70 # 70 reactions
172
+
173
+ """
174
+ glc/o2 {'reversed': {}, 'new': {'GLCpts_c0': '>'}}
175
+ ac/o2 {'reversed': {}, 'new': {'CYTBD_c0': '>', 'NADH16_c0': '>', 'O2t_c0': '>'}}
176
+ """
85
177
atp_correction .determine_growth_media ()
86
- print (atp_correction .selected_media )
178
+
179
+ assert len (atp_correction .selected_media ) == 1 # selects glucose
180
+
181
+ atp_correction .apply_growth_media_gapfilling ()
182
+
87
183
media_eval = atp_correction .evaluate_growth_media ()
88
- print ( media_eval )
184
+
89
185
atp_correction .expand_model_to_genome_scale ()
90
186
tests = atp_correction .build_tests ()
91
- print (tests )
92
- assert True
187
+
188
+ assert tests
189
+ assert len (tests ) == 1
190
+ assert tests [0 ]['threshold' ] > 0
191
+ assert tests [0 ]['objective' ] == 'ATPM_c0'
192
+
193
+
194
+ def test_ms_atp_correction_and_gap_fill1 (get_model_with_infinite_atp_loop , template , template_genome_scale ,
195
+ media_glucose_aerobic , media_genome_scale_glucose_aerobic ):
196
+ from modelseedpy import MSGapfill
197
+
198
+ model = get_model_with_infinite_atp_loop (['GLCpts_c0' , 'GLUSy_c0' , 'GLUDy_c0' ])
199
+ model .reactions .ATPM_c0 .lower_bound = 0
200
+ model .reactions .ATPM_c0 .upper_bound = 1000
201
+
202
+ atp_correction = MSATPCorrection (model , template , [media_glucose_aerobic ], atp_hydrolysis_id = 'ATPM_c0' )
203
+ tests = atp_correction .run_atp_correction ()
204
+
205
+ # expected tests = [{'media': MSMedia object, 'is_max_threshold': True, 'threshold': 21.0, 'objective': 'ATPM_c0'}]
206
+
207
+ assert tests
208
+ assert len (tests ) == 1
209
+ assert tests [0 ]['threshold' ] > 0
210
+ assert tests [0 ]['objective' ] == 'ATPM_c0'
211
+
212
+ gap_fill = MSGapfill (model , [template_genome_scale ], [], tests , {}, [])
213
+ result = gap_fill .run_gapfilling (media_genome_scale_glucose_aerobic , 'BIOMASS_Ecoli_core_w_GAM_c0' , minimum_obj = 0.1 )
214
+
215
+ # either GLUSy_c0 or GLUDy_c0 should be gap filled for glutamate
216
+
217
+ assert result
218
+ assert len (result ['new' ]) == 1
219
+ assert 'GLUSy_c0' in result ['new' ] or 'GLUDy_c0' in result ['new' ]
220
+
221
+ model = gap_fill .integrate_gapfill_solution (result )
222
+
223
+ assert model
0 commit comments