Skip to content

Commit b65c591

Browse files
committed
Merge branch 'dev' of github.com:Fxe/ModelSEEDpy into dev
2 parents 1dd84b3 + eb785b2 commit b65c591

16 files changed

+1823
-190
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,7 @@ dmypy.json
132132
# Pyre type checker
133133
.pyre/
134134

135+
.pydevproject
136+
.settings/*
137+
*data/*
135138
*.lp

modelseedpy/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,14 @@
3838
MSBuilder,
3939
MSMedia,
4040
MSGrowthPhenotypes,
41+
MSGrowthPhenotype,
4142
MSModelUtil,
4243
FBAHelper,
4344
MSEditorAPI,
4445
MSATPCorrection,
4546
MSGapfill,
4647
MSEquation,
48+
MSModelReport
4749
)
4850
from modelseedpy.core.exceptions import *
4951

modelseedpy/biochem/modelseed_biochem.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ class ModelSEEDBiochem:
495495
@staticmethod
496496
def get(create_if_missing=True):
497497
if not ModelSEEDBiochem.default_biochemistry:
498-
ModelSEEDBiochem.default_biochemistry = from_local2(
498+
ModelSEEDBiochem.default_biochemistry = from_local(
499499
config.get("biochem", "path")
500500
)
501501
return ModelSEEDBiochem.default_biochemistry

modelseedpy/core/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
from modelseedpy.core.mseditorapi import MSEditorAPI, MSEquation
1010
from modelseedpy.core.msgapfill import MSGapfill
1111
from modelseedpy.core.msatpcorrection import MSATPCorrection
12-
from modelseedpy.core.msgrowthphenotypes import MSGrowthPhenotypes
12+
from modelseedpy.core.msgrowthphenotypes import MSGrowthPhenotypes, MSGrowthPhenotype
1313
from modelseedpy.core.msmodelutl import MSModelUtil
1414
from modelseedpy.core.mstemplate import MSTemplateBuilder
15+
from modelseedpy.core.msmodelreport import MSModelReport
1516
from modelseedpy.core.exceptions import *
Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
# -*- coding: utf-8 -*-
2+
import logging
3+
import re
4+
import time
5+
import json
6+
import sys
7+
import pandas as pd
8+
import cobra
9+
from cobra import DictList
10+
11+
# from builtins import None
12+
13+
logger = logging.getLogger(__name__)
14+
logger.setLevel(
15+
logging.INFO
16+
) # When debugging - set this to INFO then change needed messages below from DEBUG to INFO
17+
18+
#Class structure
19+
#AnnotationOntology -> Features/Events/Terms/Ontologies
20+
# AnnotationOntologyOntology -> Events/Terms
21+
# AnnotationOntologyEvent -> Features/Ontology
22+
# AnnotationOntologyFeature -> Term+Event->Evidence
23+
# AnnotationOntologyTerm -> Ontology/Events/Featurs
24+
# AnnotationOntologyEvidence -> --
25+
26+
allowable_score_types = ["probability","evalue","bitscore","identity","qalignstart","qalignstop","salignstart","salignstop","kmerhits","tmscore","rmsd","hmmscore"]
27+
28+
class AnnotationOntologyEvidence:
29+
def __init__(self,scores={},ref_entity=None,entity_type=None):
30+
self.ref_entity=ref_entity
31+
self.entity_type=entity_type
32+
self.scores=scores
33+
for item in self.scores:
34+
if item not in allowable_score_types:
35+
logger.warning(item+" not an allowable score type!")
36+
37+
def to_data(self):
38+
return {
39+
"ref_entity":self.ref_entity,
40+
"entity_type":self.entity_type,
41+
"scores":self.scores
42+
}
43+
44+
class AnnotationOntologyTerm:
45+
def __init__(self,parent,term_id,ontology):
46+
self.id = term_id
47+
self.parent = parent
48+
self.ontology = ontology
49+
self.ontology.add_term(self)
50+
self.parent.add_term(self)
51+
self.msrxns = set()
52+
self.events = {}
53+
self.features = {}
54+
55+
def add_msrxns(self,rxn_ids):
56+
for rxn_id in rxn_ids:
57+
if rxn_id[0:6] == "MSRXN:":
58+
rxn_id = rxn_id[6:]
59+
self.msrxns.update([rxn_id])
60+
61+
def add_event(self,event):
62+
self.events[event.id] = event
63+
64+
def add_feature(self,feature):
65+
self.features[feature.id] = feature
66+
67+
class AnnotationOntologyOntology:
68+
def __init__(self,parent,ontology_id):
69+
self.id = ontology_id
70+
self.parent = parent
71+
self.events = {}
72+
self.terms = {}
73+
74+
def add_event(self,event):
75+
self.events[event.id] = event
76+
77+
def add_term(self,term):
78+
self.terms[term.id] = term
79+
80+
class AnnotationOntologyFeature:
81+
def __init__(self,parent,feature_id,type=None):
82+
self.id = feature_id
83+
self.parent = parent
84+
parent.add_feature(self)
85+
self.type = type
86+
self.event_terms = {}
87+
self.term_events = {}
88+
89+
def add_event_term(self,event,term,scores={},ref_entity=None,entity_type=None):
90+
if event.id not in self.event_terms:
91+
self.event_terms[event.id] = {}
92+
self.event_terms[event.id][term.id] = AnnotationOntologyEvidence(scores,ref_entity,entity_type)
93+
if term.id not in self.term_events:
94+
self.term_events[term.id] = {}
95+
self.term_events[term.id][event.id] = self.event_terms[event.id][term.id]
96+
97+
def get_associated_terms(self,prioritized_event_list=None,ontologies=None,merge_all=False,translate_to_rast=False):
98+
output = {}
99+
for term_id in self.term_events:
100+
term = self.parent.terms[term_id]
101+
if not ontologies or term.ontology.id in ontologies:
102+
if merge_all or not prioritized_event_list:
103+
for event_id in self.term_events[term_id]:
104+
if not prioritized_event_list or event_id in prioritized_event_list:
105+
if term not in output:
106+
output[term] = []
107+
output[term].append(self.term_events[term_id][event_id].to_data())
108+
else:
109+
for event_id in prioritized_event_list:
110+
if event_id in self.term_events[term_id]:
111+
rxns = self.parent.terms[term_id].msrxns;
112+
if len(rxns) > 0:
113+
if term not in output:
114+
output[term] = []
115+
output[term].append(self.term_events[term_id][event_id].to_data())
116+
break
117+
return output
118+
119+
def get_associated_reactions(self,prioritized_event_list=None,ontologies=None,merge_all=False):
120+
output = {}
121+
for term_id in self.term_events:
122+
if not ontologies or self.parent.terms[term_id].ontology.id in ontologies:
123+
if merge_all or not prioritized_event_list:
124+
for event_id in self.term_events[term_id]:
125+
if not prioritized_event_list or event_id in prioritized_event_list:
126+
rxns = self.parent.terms[term_id].msrxns;
127+
for rxn_id in rxns:
128+
if rxn_id not in output:
129+
output[rxn_id] = []
130+
output[rxn_id].append(self.term_events[term_id][event_id].to_data())
131+
else:
132+
for event_id in prioritized_event_list:
133+
if event_id in self.term_events[term_id]:
134+
rxns = self.parent.terms[term_id].msrxns;
135+
for rxn_id in rxns:
136+
if rxn_id not in output:
137+
output[rxn_id] = []
138+
output[rxn_id].append(self.term_events[term_id][event_id].to_data())
139+
if len(rxns) > 0:
140+
break
141+
return output
142+
143+
class AnnotationOntologyEvent:
144+
def __init__(self,parent,event_id,ontology_id,method,method_version=None,description=None,timestamp=None):
145+
self.id = event_id
146+
self.parent = parent
147+
#Linking ontology
148+
self.ontology = self.parent.add_ontology(ontology_id)
149+
self.ontology.add_event(self)
150+
if not description:
151+
self.description = ""#TODO
152+
else:
153+
self.description = description
154+
self.method = method
155+
self.method_version = method_version
156+
self.timestamp = timestamp
157+
self.features = {}
158+
159+
@staticmethod
160+
def from_data(data,parent):
161+
if "method_version" not in data:
162+
data["method_version"] = None
163+
if "description" not in data:
164+
data["description"] = None
165+
if "timestamp" not in data:
166+
data["timestamp"] = None
167+
self = AnnotationOntologyEvent(parent,data["event_id"],data["ontology_id"],data["method"],data["method_version"],data["description"],data["timestamp"])
168+
if "ontology_terms" in data:
169+
for feature_id in data["ontology_terms"]:
170+
feature = self.parent.add_feature(feature_id)
171+
self.add_feature(feature)
172+
for item in data["ontology_terms"][feature_id]:
173+
term = self.parent.add_term(item["term"],self.ontology)
174+
scores = {}
175+
ref_entity = None
176+
entity_type = None
177+
if "evidence" in item:
178+
if "scores" in item["evidence"]:
179+
scores = item["evidence"]["scores"]
180+
if "reference" in item["evidence"]:
181+
ref_entity = item["evidence"]["reference"][1]
182+
entity_type = item["evidence"]["reference"][0]
183+
feature.add_event_term(self,term,scores,ref_entity,entity_type)
184+
if "modelseed_ids" in item:
185+
term.add_msrxns(item["modelseed_ids"])
186+
return self
187+
188+
def add_feature(self,feature):
189+
self.features[feature.id] = feature
190+
191+
def to_data(self):
192+
data = {
193+
"event_id" : self.event_id,
194+
"description" : self.event_id,
195+
"ontology_id" : self.ontology_id,
196+
"method" : self.method,
197+
"method_version" : self.method_version,
198+
"timestamp" : self.timestamp,
199+
"ontology_terms" : {}
200+
}
201+
for feature in self.features:
202+
data["ontology_terms"][feature] = {
203+
"term":None#TODO
204+
}
205+
206+
class AnnotationOntology:
207+
mdlutls = {}
208+
209+
@staticmethod
210+
def from_kbase_data(data,genome_ref=None,data_dir=None):
211+
self = AnnotationOntology(genome_ref,data_dir)
212+
if "feature_types" in data:
213+
self.feature_types = data["feature_types"]
214+
if "events" in data:
215+
for event in data["events"]:
216+
self.events += [AnnotationOntologyEvent.from_data(event,self)]
217+
return self
218+
219+
def __init__(self,genome_ref,data_dir):
220+
self.genome_ref = genome_ref
221+
self.events = DictList()
222+
self.terms = {}
223+
self.ontologies = {}
224+
self.genes = {}
225+
self.cdss = {}
226+
self.data_dir = data_dir
227+
self.noncodings = {}
228+
self.feature_types = {}
229+
self.term_names = {}
230+
231+
def get_term_name(self,term):
232+
if term.ontology.id not in self.term_names:
233+
self.term_names[term.ontology.id] = {}
234+
if term.ontology.id in ["SSO","AntiSmash","EC","TC","META","RO","KO","GO"]:
235+
with open(self.data_dir + "/"+term.ontology.id+"_dictionary.json") as json_file:
236+
ontology = json.load(json_file)
237+
for item in ontology["term_hash"]:
238+
self.term_names[term.ontology.id][item] = ontology["term_hash"][item]["name"]
239+
if term.id not in self.term_names[term.ontology.id]:
240+
return "Unknown"
241+
return self.term_names[term.ontology.id][term.id]
242+
243+
def get_gene_term_hash(self,prioritized_event_list=None,ontologies=None,merge_all=False,cds_features=False,translate_to_rast=True):
244+
output = {}
245+
feature_hash = self.genes
246+
if len(self.genes) == 0 or (cds_features and len(self.cdss) == 0):
247+
feature_hash = self.cdss
248+
for feature_id in feature_hash:
249+
feature = feature_hash[feature_id]
250+
if feature not in output:
251+
output[feature] = {}
252+
output[feature] = feature.get_associated_terms(prioritized_event_list,ontologies,merge_all,translate_to_rast)
253+
return output
254+
255+
def get_reaction_gene_hash(self,prioritized_event_list=None,ontologies=None,merge_all=False,cds_features=False):
256+
output = {}
257+
feature_hash = self.genes
258+
if len(self.genes) == 0 or (cds_features and len(self.cdss) == 0):
259+
feature_hash = self.cdss
260+
for feature_id in feature_hash:
261+
reactions = feature_hash[feature_id].get_associated_reactions(prioritized_event_list,ontologies,merge_all)
262+
for rxn_id in reactions:
263+
if rxn_id not in output:
264+
output[rxn_id] = {}
265+
if feature_id not in output[rxn_id]:
266+
output[rxn_id][feature_id] = []
267+
output[rxn_id][feature_id].append(reactions[rxn_id])
268+
return output
269+
270+
def add_term(self,term_or_id,ontology=None):
271+
if not isinstance(term_or_id, AnnotationOntologyTerm):
272+
if term_or_id in self.terms:
273+
return self.terms[term_or_id]
274+
else:
275+
return AnnotationOntologyTerm(self,term_or_id,ontology)
276+
if term_or_id.id in self.terms:
277+
logger.critical("Term with id "+term_or_id.id+" already in annotation!")
278+
return self.terms[term_or_id.id]
279+
else:
280+
self.terms[term_or_id.id] = term_or_id
281+
282+
def add_ontology(self,ontology_or_id):
283+
if not isinstance(ontology_or_id, AnnotationOntologyOntology):
284+
if ontology_or_id in self.ontologies:
285+
return self.ontologies[ontology_or_id]
286+
else:
287+
return AnnotationOntologyOntology(self,ontology_or_id)
288+
if ontology_or_id.id in self.ontologies:
289+
logger.critical("Ontology with id "+ontology_or_id.id+" already in annotation!")
290+
return self.ontologies[ontology_or_id.id]
291+
else:
292+
self.ontologies[ontology_or_id.id] = ontology_or_id
293+
294+
def get_feature_hash(self,feature_id):
295+
feature_hash = self.genes
296+
if feature_id in self.feature_types:
297+
if self.feature_types[feature_id] == "cds":
298+
feature_hash = self.cdss
299+
elif self.feature_types[feature_id] == "noncoding":
300+
feature_hash = self.noncodings
301+
return feature_hash
302+
303+
def add_feature(self,feature_or_id):
304+
feature_hash = None
305+
if not isinstance(feature_or_id, AnnotationOntologyFeature):
306+
feature_hash = self.get_feature_hash(feature_or_id)
307+
if feature_or_id in feature_hash:
308+
return feature_hash[feature_or_id]
309+
else:
310+
feature_or_id = AnnotationOntologyFeature(self,feature_or_id)
311+
if not feature_hash:
312+
feature_hash = self.get_feature_hash(feature_or_id.id)
313+
if feature_or_id.id not in feature_hash:
314+
feature_hash[feature_or_id.id] = feature_or_id
315+
return feature_hash[feature_or_id.id]

0 commit comments

Comments
 (0)