wip
Some checks failed
API CI / api-tests (pull_request) Failing after 20s
CI / test (pull_request) Failing after 23s

This commit is contained in:
Tim Lorsbach
2026-04-21 10:26:35 +02:00
parent 4012ac356b
commit 170f00504f
28 changed files with 653 additions and 69 deletions

View File

@ -15,6 +15,7 @@ from epdb.models import (
SimpleAmbitRule,
SimpleRDKitRule,
)
from utilities.chem import FormatConverter
class Package(EnviPathModel):
@ -114,7 +115,9 @@ class PESCompound(Compound):
# Check if we find a direct match for a given pes_link
if PESStructure.objects.filter(pes_link=pes_url, compound__package=package).exists():
return PESStructure.objects.get(pes_link=pes_url, compound__package=package).compound
# Due to normalization we might end up in having multiple structures
# All of them point to the same compound -> pick any
return PESStructure.objects.filter(pes_link=pes_url, compound__package=package).first().compound
# Generate Compound
c = PESCompound()
@ -135,19 +138,37 @@ class PESCompound(Compound):
c.save()
molfile = pes_data.get("representativeStructures", [{}])[0].get("ctab")
if molfile is None:
raise ValueError("PES data does not contain a valid mol file!")
smiles = FormatConverter.to_smiles(FormatConverter.from_molfile(molfile))
standardized_smiles = FormatConverter.standardize(smiles, remove_stereo=True)
is_standardized = standardized_smiles == smiles
if not is_standardized:
_ = CompoundStructure.create(
_ = PESStructure.create(
c,
pes_url,
molfile,
standardized_smiles,
name="Normalized structure of {}".format(name),
description="{} (in its normalized form)".format(description),
normalized_structure=True,
)
cs = CompoundStructure.create(
c, smiles, name=name, description=description, normalized_structure=is_standardized
cs = PESStructure.create(
c,
pes_url,
molfile,
smiles,
name=name,
description=description,
normalized_structure=is_standardized
)
c.default_structure = cs
@ -159,6 +180,53 @@ class PESCompound(Compound):
class PESStructure(CompoundStructure):
pes_link = models.URLField(blank=False, null=False, verbose_name="PES Link")
@staticmethod
@transaction.atomic
def create(
compound: Compound,
pes_link: str,
mol_file: str,
smiles: str,
name: str = None,
description: str = None,
*args,
**kwargs
):
if compound.pk is None:
raise ValueError("Unpersisted Compound! Persist compound first!")
cs = PESStructure()
# Clean for potential XSS
if name is not None:
cs.name = nh3.clean(name, tags=s.ALLOWED_HTML_TAGS).strip()
if description is not None:
cs.description = nh3.clean(description, tags=s.ALLOWED_HTML_TAGS).strip()
cs.smiles = smiles
cs.mol_file = mol_file
cs.pes_link = pes_link
cs.compound = compound
if "normalized_structure" in kwargs:
cs.normalized_structure = kwargs["normalized_structure"]
cs.save()
return cs
@transaction.atomic
def add_structure(
self,
smiles: str,
name: str = None,
description: str = None,
default_structure: bool = False,
*args,
**kwargs,
) -> "CompoundStructure":
raise ValueError("Not supported!")
def d3_json(self):
return {
"is_pes": True,