[Feature] EnzymeLink Annotations (#152)

Co-authored-by: Tim Lorsbach <tim@lorsba.ch>
Reviewed-on: enviPath/enviPy#152
This commit is contained in:
2025-10-15 19:35:26 +13:00
parent ef697ac5f5
commit 386098b8a6
10 changed files with 352 additions and 27 deletions

View File

@ -494,6 +494,20 @@ class ChemicalIdentifierMixin(ExternalIdentifierMixin):
return self.get_external_identifier("CAS")
class KEGGIdentifierMixin(ExternalIdentifierMixin):
@property
def kegg_reaction_links(self):
return self.get_external_identifier("KEGG Reaction")
def add_kegg_reaction_id(self, kegg_id):
return self.add_external_identifier(
"KEGG Reaction", kegg_id, f"https://www.genome.jp/entry/{kegg_id}"
)
class Meta:
abstract = True
class ReactionIdentifierMixin(ExternalIdentifierMixin):
class Meta:
abstract = True
@ -1014,6 +1028,26 @@ class CompoundStructure(EnviPathModel, AliasMixin, ScenarioMixin, ChemicalIdenti
return self.compound.default_structure == self
class EnzymeLink(EnviPathModel, KEGGIdentifierMixin):
rule = models.ForeignKey("Rule", on_delete=models.CASCADE, db_index=True)
ec_number = models.TextField(blank=False, null=False, verbose_name="EC Number")
classification_level = models.IntegerField(
blank=False, null=False, verbose_name="Classification Level"
)
linking_method = models.TextField(blank=False, null=False, verbose_name="Linking Method")
reaction_evidence = models.ManyToManyField("epdb.Reaction")
edge_evidence = models.ManyToManyField("epdb.Edge")
external_identifiers = GenericRelation("ExternalIdentifier")
def _url(self):
return "{}/enzymelink/{}".format(self.rule.url, self.uuid)
def get_group(self) -> str:
return ".".join(self.ec_number.split(".")[:3]) + ".-"
class Rule(PolymorphicModel, EnviPathModel, AliasMixin, ScenarioMixin):
package = models.ForeignKey(
"epdb.Package", verbose_name="Package", on_delete=models.CASCADE, db_index=True
@ -1095,6 +1129,18 @@ class Rule(PolymorphicModel, EnviPathModel, AliasMixin, ScenarioMixin):
return new_rule
def enzymelinks(self):
return self.enzymelink_set.all()
def get_grouped_enzymelinks(self):
res = defaultdict(list)
for el in self.enzymelinks():
key = ".".join(el.ec_number.split(".")[:3]) + ".-"
res[key].append(el)
return dict(res)
class SimpleRule(Rule):
pass
@ -1437,6 +1483,16 @@ class Reaction(EnviPathModel, AliasMixin, ScenarioMixin, ReactionIdentifierMixin
id__in=Edge.objects.filter(edge_label=self).values("pathway_id")
).order_by("name")
def get_related_enzymes(self):
res = []
edges = Edge.objects.filter(edge_label=self)
for e in edges:
for scen in e.scenarios.all():
for ai in scen.additional_information.keys():
if ai == "Enzyme":
res.extend(scen.additional_information[ai])
return res
class Pathway(EnviPathModel, AliasMixin, ScenarioMixin):
package = models.ForeignKey(