Skip to content

Commit d5edc2e

Browse files
committed
added complete_BioMetaCyc #99
1 parent 6d8bbd4 commit d5edc2e

File tree

1 file changed

+88
-2
lines changed

1 file changed

+88
-2
lines changed

src/refinegems/curation/curate.py

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,93 @@ def update_annotations_from_others(model: libModel) -> libModel:
128128
add_cv_term_metabolites(entry, db_id, other_metab)
129129
return model
130130

131-
# @TODO
132-
# maybe add the function from SPECIMEN for BioCyc/MetaCyc annotation completion
131+
132+
def complete_BioMetaCyc(model:cobra.Model) -> cobra.Model:
133+
"""Check for existing MetaCyc and BioCyc annotations for metabolites and
134+
reactions and generate them from the other if one of the two is missing.
135+
136+
Args:
137+
model (cobra.Model): A genome-scale model to be checked
138+
for complete BioCyc/MetaCyc annotations.
139+
140+
Returns:
141+
cobra.Model: The updated model.
142+
"""
143+
144+
145+
# reactions
146+
# ---------
147+
for reac in model.reactions:
148+
# case 1: MetaCyc but not BioCyc
149+
if 'metacyc.reaction' in reac.annotation and not 'biocyc' in reac.annotation:
150+
# add database (META) information to get BioCyc ID
151+
if isinstance(reac.annotation['metacyc.reaction'], list):
152+
reac.annotation['biocyc'] = ['META:' + _ for _ in reac.annotation['metacyc.reaction']]
153+
else:
154+
reac.annotation['biocyc'] = 'META:' + reac.annotation['metacyc.reaction']
155+
# case 2: BioCyc, but no MetaCyc
156+
elif 'biocyc' in reac.annotation and not 'metacyc.reaction' in reac.annotation:
157+
# if there are multiple metacyc.reaction annotation
158+
if isinstance(reac.annotation['biocyc'], list):
159+
add_anno = []
160+
for biocyc_anno in reac.annotation['biocyc']:
161+
if ':' in biocyc_anno:
162+
# exclude organism identifier from ID to get MetaCyc ID
163+
add_anno.append(biocyc_anno.split(':')[1])
164+
else:
165+
# high possibility that information is faulty - do not use it
166+
print(F'\n\nWarning: Unexpected BioCyc annotation {biocyc_anno} for reaction {reac.id}')
167+
reac.annotation['metacyc.reaction'] = add_anno
168+
# if there is only one
169+
else:
170+
if ':' in reac.annotation['biocyc']:
171+
# exclude organism identifier from ID to get MetaCyc ID
172+
reac.annotation['metacyc.reaction'] = reac.annotation['biocyc'].split(':')[1]
173+
else:
174+
# high possibility that information is faulty - do not use it
175+
print(F'\n\nWarning: Unexpected BioCyc annotation {reac.annotation["biocyc"]} for reaction {reac.id}')
176+
# case 3: both or no = skip
177+
else:
178+
continue
179+
180+
# metabolites
181+
# -----------
182+
for meta in model.metabolites:
183+
# case 1: MetaCyc but not BioCyc
184+
if 'metacyc.compound' in meta.annotation and not 'biocyc' in meta.annotation:
185+
# add database (META) information to get BioCyc ID
186+
if isinstance(meta.annotation['metacyc.compound'],list):
187+
meta.annotation['biocyc'] = ['META:' + _ for _ in meta.annotation['metacyc.compound']]
188+
else:
189+
meta.annotation['biocyc'] = 'META:' + meta.annotation['metacyc.compound']
190+
# case 2: BioCyc, but no MetaCyc
191+
elif 'biocyc' in meta.annotation and not 'metacyc.compound' in meta.annotation:
192+
# if there are multiple metacyc.compound annotations
193+
if isinstance(meta.annotation['biocyc'], list):
194+
add_anno = []
195+
for biocyc_anno in meta.annotation['biocyc']:
196+
if ':' in biocyc_anno:
197+
# exclude organism identifier from ID to get MetaCyc ID
198+
add_anno.append(biocyc_anno.split(':')[1])
199+
else:
200+
# high possibility that information is faulty - do not use it
201+
print(F'\n\nWarning: Unexpected BioCyc annotation {biocyc_anno} for metabolite {meta.id}')
202+
meta.annotation['metacyc.compound'] = add_anno
203+
# if there is only one
204+
else:
205+
if ':' in meta.annotation['biocyc']:
206+
# exclude organism identifier from ID to get MetaCyc ID
207+
meta.annotation['metacyc.compound'] = meta.annotation['biocyc'].split(':')[1]
208+
else:
209+
# high possibility that information is faulty - do not use it
210+
print(F'\n\nWarning: Unexpected BioCyc annotation {meta.annotation["biocyc"]} for metabolite {meta.id}')
211+
# case 3: both or no = skip
212+
else:
213+
continue
214+
215+
return model
216+
217+
133218

134219
# duplicates
135220
# ----------
@@ -439,3 +524,4 @@ def resolve_duplicates(model:cobra.Model, check_reac:bool=True,
439524

440525
return model
441526

527+

0 commit comments

Comments
 (0)