diff --git a/actions/ost-compare-structures b/actions/ost-compare-structures index ec843dba9c75eb81f2c568efe90e13d14d7cf05c..e89b4c7d972ac297f1a6ea4d43fc84585736a603 100644 --- a/actions/ost-compare-structures +++ b/actions/ost-compare-structures @@ -84,6 +84,7 @@ import math import ost from ost import io from ost.mol.alg import scoring +from ost.mol.alg import scoring_base def _ParseArgs(): parser = argparse.ArgumentParser(description = __doc__, @@ -758,23 +759,13 @@ def _LoadStructure(structure_path, sformat, fault_tolerant, bu_id): ost.PushVerbosityLevel(ost.LogLevel.Error) # Load the structure if sformat == "mmcif": - if bu_id is not None: - cif_entity, cif_seqres, cif_info = \ - io.LoadMMCIF(structure_path, info=True, seqres=True, - fault_tolerant=fault_tolerant) - for biounit in cif_info.biounits: - if biounit.id == bu_id: - entity = ost.mol.alg.CreateBU(cif_entity, biounit) - break - else: - raise RuntimeError(f"No biounit found with ID '{bu_id}'.") - else: - entity = io.LoadMMCIF(structure_path, - fault_tolerant = fault_tolerant) + entity = scoring_base.MMCIFPrep(structure_path, + fault_tolerant=fault_tolerant, + biounit=bu_id) if len(entity.residues) == 0: raise Exception(f"No residues found in file: {structure_path}") else: - entity = io.LoadPDB(structure_path, fault_tolerant = fault_tolerant) + entity = scoring_base.PDBPrep(structure_path, fault_tolerant = fault_tolerant) if len(entity.residues) == 0: raise Exception(f"No residues found in file: {structure_path}") diff --git a/modules/mol/alg/doc/molalg.rst b/modules/mol/alg/doc/molalg.rst index aab9fc5e207fa376d227ae4dd3fe8ec4e720f9fe..85ab68af64f8ff944463b1b07d6d5668007fb072 100644 --- a/modules/mol/alg/doc/molalg.rst +++ b/modules/mol/alg/doc/molalg.rst @@ -11,13 +11,14 @@ Submodules :maxdepth: 1 chain_mapping - contact_score - dockq - helix_kinks + scoring_base + scoring ligand_scoring qsscore - scoring + contact_score + dockq stereochemistry + helix_kinks structure_analysis trajectory_analysis diff --git a/modules/mol/alg/pymod/CMakeLists.txt b/modules/mol/alg/pymod/CMakeLists.txt index a487f3c4fa43da731d7ffa1aa8ead9a79d6dfef8..a134816d5ad97679c8243d4854b526be5b7bb2f5 100644 --- a/modules/mol/alg/pymod/CMakeLists.txt +++ b/modules/mol/alg/pymod/CMakeLists.txt @@ -36,6 +36,7 @@ set(OST_MOL_ALG_PYMOD_MODULES ligand_scoring_scrmsd.py ligand_scoring_lddtpli.py bb_lddt.py + scoring_base.py ) if (NOT ENABLE_STATIC) diff --git a/modules/mol/alg/pymod/ligand_scoring_base.py b/modules/mol/alg/pymod/ligand_scoring_base.py index bdda481e0355eb3632b77c80b8936af8de741216..75642ae06ad0c97a817a6786cbdb585aaf679d48 100644 --- a/modules/mol/alg/pymod/ligand_scoring_base.py +++ b/modules/mol/alg/pymod/ligand_scoring_base.py @@ -3,13 +3,11 @@ import numpy as np import networkx import ost -from ost import io from ost import mol from ost import conop from ost import LogWarning, LogScript, LogInfo, LogVerbose, LogDebug, GetVerbosityLevel, PushVerbosityLevel, PopVerbosityLevel from ost.mol.alg import chain_mapping - @contextmanager def _SinkVerbosityLevel(n=1): """ Context manager to temporarily reduce the verbosity level by n. @@ -50,179 +48,6 @@ def _QualifiedResidueNotation(r): ins_code=resnum.ins_code.strip("\u0000"), ) - -def CleanHydrogens(ent, clib): - """ Ligand scoring helper - Returns copy of *ent* without hydrogens - - Non-standard hydrogen naming can cause trouble in residue property - assignment which is done by the :class:`ost.conop.RuleBasedProcessor` when - loading. In fact, residue property assignment is not done for every residue - that has unknown atoms according to the chemical component dictionary. This - function therefore re-processes the entity after removing hydrogens. - - :param ent: Entity to clean - :type ent: :class:`ost.mol.EntityHandle`/:class:`ost.mol.EntityView` - :param clib: Compound library to perform re-processing after hydrogen - removal. - :type clib: :class:`ost.conop.CompoundLib` - :returns: Cleaned and re-processed ent - """ - cleaned_ent = mol.CreateEntityFromView(ent.Select( - "ele != H and ele != D"), include_exlusive_atoms=False) - # process again to set missing residue properties due to non standard - # hydrogens - processor = conop.RuleBasedProcessor(clib) - processor.Process(cleaned_ent) - return cleaned_ent - - -def MMCIFPrep(mmcif_path, biounit=None, extract_nonpoly=False, - fault_tolerant=False, allow_heuristic_conn=False): - """ Ligand scoring helper - Prepares :class:`LigandScorer` input from mmCIF - - Only performs gentle cleanup of hydrogen atoms. Further cleanup is delegated - to :class:`LigandScorer`. - - :param mmcif_path: Path to mmCIF file that contains polymer and optionally - non-polymer entities - :type mmcif_path: :class:`str` - :param biounit: If given, construct specified biounit from mmCIF AU - :type biounit: :class:`str` - :param extract_nonpoly: Additionally returns a list of - :class:`ost.mol.EntityHandle` - objects representing all non-polymer (ligand) - entities. - :type extract_nonpoly: :class:`bool` - :param fault_tolerant: Passed as parameter to :func:`ost.io.LoadMMCIF` - :type fault_tolerant: :class:`bool` - :param allow_heuristic_conn: Only relevant if extract_nonpoly is True. - The chemical component dictionary is relevant - for connectivity information. By default, we - enforce the presence of each non-polymer in - the dictionary to ensure correct connectity. - If you enable this flag, you allow the use - of a distance based heuristic as fallback. - With all its consequences in ligand matching. - :type allow_heuristic_conn: :class:`bool` - :returns: :class:`ost.mol.EntityHandle` which only contains polymer - entities representing the receptor structure. If *extract_nonpoly* - is True, a tuple is returned which additionally contains a - :class:`list` of :class:`ost.mol.EntityHandle`, where each - :class:`ost.mol.EntityHandle` represents a non-polymer (ligand). - """ - clib = conop.GetDefaultLib() - if not clib: - ost.LogError("A compound library is required. " - "Please refer to the OpenStructure website: " - "https://openstructure.org/docs/conop/compoundlib/.") - raise RuntimeError("No compound library found") - - mmcif_entity, mmcif_info = io.LoadMMCIF(mmcif_path, info=True, - fault_tolerant=fault_tolerant) - mmcif_entity = CleanHydrogens(mmcif_entity, clib) - - # get AU chain names representing polymer entities - polymer_entity_ids = mmcif_info.GetEntityIdsOfType("polymer") - polymer_chain_names = list() - for ch in mmcif_entity.chains: - if mmcif_info.GetMMCifEntityIdTr(ch.name) in polymer_entity_ids: - polymer_chain_names.append(ch.name) - - # get AU chain names representing non-polymer entities - non_polymer_entity_ids = mmcif_info.GetEntityIdsOfType("non-polymer") - non_polymer_chain_names = list() - for ch in mmcif_entity.chains: - if mmcif_info.GetMMCifEntityIdTr(ch.name) in non_polymer_entity_ids: - non_polymer_chain_names.append(ch.name) - - # construct biounit if necessary - if biounit is not None: - biounit_found = False - for bu in mmcif_info.biounits: - if bu.id == biounit: - mmcif_entity = mol.alg.CreateBU(mmcif_entity, bu) - biounit_found = True - break - if not biounit_found: - raise RuntimeError(f"Specified biounit '{biounit}' not in " - f"{mmcif_path}") - - # assign generic properties for selection later on - non_poly_id = 0 - for ch in mmcif_entity.chains: - cname = None - if biounit is not None: - # if a biounit is constructed, you get chain names like: 1.YOLO - # we cannot simply split by '.' since '.' is an allowed character - # in chain names. => split by first occurence - dot_index = ch.name.find('.') - if dot_index == -1: - cname = ch.name - else: - cname = ch.name[dot_index+1:] - else: - cname = ch.name - - if cname in polymer_chain_names: - ch.SetIntProp("poly", 1) - if cname in non_polymer_chain_names: - ch.SetIntProp("nonpolyid", non_poly_id) - non_poly_id += 1 - - poly_sel = mmcif_entity.Select("gcpoly:0=1") - poly_ent = mol.CreateEntityFromView(poly_sel, True) - - if extract_nonpoly == False: - return poly_ent - - non_poly_sel = mmcif_entity.Select("gcnonpoly:0=1") - non_poly_entities = list() - for i in range(non_poly_id): - view = mmcif_entity.Select(f"gcnonpolyid:{non_poly_id}={i}") - if view.GetResidueCount() != 1: - raise RuntimeError(f"Expect non-polymer entities in " - f"{mmcif_path} to contain exactly 1 " - f"residue. Got {ch.GetResidueCount()} " - f"in chain {ch.name}") - if not allow_heuristic_conn: - compound = clib.FindCompound(view.residues[0].name) - if compound is None: - raise RuntimeError(f"Can only extract non-polymer entities if " - f"respective residues are available in PDB " - f"component dictionary. Can't find " - f"\"{view.residues[0].name}\"") - - non_poly_entities.append(mol.CreateEntityFromView(view, True)) - - return (poly_ent, non_poly_entities) - - -def PDBPrep(pdb_path, fault_tolerant=False): - """ Ligand scoring helper - Prepares :class:`LigandScorer` input from PDB - - Only performs gentle cleanup of hydrogen atoms. Further cleanup is delegated - to :class:`LigandScorer`. There is no logic to extract ligands from PDB - files. Ligands must be provided separately as SDF files in these cases. - - :param pdb_path: Path to PDB file that contains polymer entities - :type pdb_path: :class:`str` - :param fault_tolerant: Passed as parameter to :func:`ost.io.LoadPDB` - :type fault_tolerant: :class:`bool` - :returns: :class:`EntityHandle` from loaded file. - """ - clib = conop.GetDefaultLib() - if not clib: - ost.LogError("A compound library is required. " - "Please refer to the OpenStructure website: " - "https://openstructure.org/docs/conop/compoundlib/.") - raise RuntimeError("No compound library found") - - pdb_entity = io.LoadPDB(pdb_path, fault_tolerant=fault_tolerant) - pdb_entity = CleanHydrogens(pdb_entity, clib) - - return pdb_entity - - class LigandScorer: """ Scorer to compute various small molecule ligand (non polymer) scores. @@ -290,7 +115,8 @@ class LigandScorer: structures (protein, nucleic acids) must still follow the usual rules and contain only residues from the compound library. Structures are cleaned up according to constructor documentation. We advise to - use the :func:`MMCIFPrep` and :func:`PDBPrep` for loading which already + use the :func:`ost.mol.alg.scoring_base.MMCIFPrep` and + :func:`ost.mol.alg.scoring_base.PDBPrep` for loading which already clean hydrogens and, in the case of MMCIF, optionally extract ligands ready to be used by the :class:`LigandScorer` based on "non-polymer" entity types. In case of PDB file format, ligands must be loaded separately as SDF files. @@ -309,6 +135,8 @@ class LigandScorer: Here is an example of how to setup a scorer:: from ost.mol.alg.ligand_scoring_scrmsd import SCRMSDScorer + from ost.mol.alg.scoring_base import MMCIFPrep + from ost.mol.alg.scoring_base import PDBPrep # Load data # Structure model in PDB format, containing the receptor only @@ -1721,7 +1549,6 @@ class DisconnectedGraphError(Exception): pass # specify public interface -__all__ = ('CleanHydrogens', 'MMCIFPrep', 'PDBPrep', - 'LigandScorer', 'ComputeSymmetries', 'NoSymmetryError', +__all__ = ('LigandScorer', 'ComputeSymmetries', 'NoSymmetryError', 'NoIsomorphicSymmetryError', 'TooManySymmetriesError', 'DisconnectedGraphError') diff --git a/modules/mol/alg/pymod/scoring_base.py b/modules/mol/alg/pymod/scoring_base.py new file mode 100644 index 0000000000000000000000000000000000000000..3aa58a5d04ad26137f14d65eb9d4501d5c9a7332 --- /dev/null +++ b/modules/mol/alg/pymod/scoring_base.py @@ -0,0 +1,178 @@ +import ost +from ost import io +from ost import conop +from ost import mol + + +def CleanHydrogens(ent, clib): + """ Scoring helper - Returns copy of *ent* without hydrogens + + Non-standard hydrogen naming can cause trouble in residue property + assignment which is done by the :class:`ost.conop.RuleBasedProcessor` when + loading. In fact, residue property assignment is not done for every residue + that has unknown atoms according to the chemical component dictionary. This + function therefore re-processes the entity after removing hydrogens. + + :param ent: Entity to clean + :type ent: :class:`ost.mol.EntityHandle`/:class:`ost.mol.EntityView` + :param clib: Compound library to perform re-processing after hydrogen + removal. + :type clib: :class:`ost.conop.CompoundLib` + :returns: Cleaned and re-processed ent + """ + cleaned_ent = mol.CreateEntityFromView(ent.Select( + "ele != H and ele != D"), include_exlusive_atoms=False) + # process again to set missing residue properties due to non standard + # hydrogens + processor = conop.RuleBasedProcessor(clib) + processor.Process(cleaned_ent) + return cleaned_ent + + +def MMCIFPrep(mmcif_path, biounit=None, extract_nonpoly=False, + fault_tolerant=False, allow_heuristic_conn=False): + """ Scoring helper - Prepares input from mmCIF + + Only performs gentle cleanup of hydrogen atoms. Further cleanup is delegated + to scoring classes. + + :param mmcif_path: Path to mmCIF file that contains polymer and optionally + non-polymer entities + :type mmcif_path: :class:`str` + :param biounit: If given, construct specified biounit from mmCIF AU + :type biounit: :class:`str` + :param extract_nonpoly: Additionally returns a list of + :class:`ost.mol.EntityHandle` + objects representing all non-polymer (ligand) + entities. + :type extract_nonpoly: :class:`bool` + :param fault_tolerant: Passed as parameter to :func:`ost.io.LoadMMCIF` + :type fault_tolerant: :class:`bool` + :param allow_heuristic_conn: Only relevant if extract_nonpoly is True. + The chemical component dictionary is relevant + for connectivity information. By default, we + enforce the presence of each non-polymer in + the dictionary to ensure correct connectity. + If you enable this flag, you allow the use + of a distance based heuristic as fallback. + With all its consequences in ligand matching. + :type allow_heuristic_conn: :class:`bool` + :returns: :class:`ost.mol.EntityHandle` which only contains polymer + entities representing the receptor structure. If *extract_nonpoly* + is True, a tuple is returned which additionally contains a + :class:`list` of :class:`ost.mol.EntityHandle`, where each + :class:`ost.mol.EntityHandle` represents a non-polymer (ligand). + """ + clib = conop.GetDefaultLib() + if not clib: + ost.LogError("A compound library is required. " + "Please refer to the OpenStructure website: " + "https://openstructure.org/docs/conop/compoundlib/.") + raise RuntimeError("No compound library found") + + mmcif_entity, mmcif_info = io.LoadMMCIF(mmcif_path, info=True, + fault_tolerant=fault_tolerant) + mmcif_entity = CleanHydrogens(mmcif_entity, clib) + + # get AU chain names representing polymer entities + polymer_entity_ids = mmcif_info.GetEntityIdsOfType("polymer") + polymer_chain_names = list() + for ch in mmcif_entity.chains: + if mmcif_info.GetMMCifEntityIdTr(ch.name) in polymer_entity_ids: + polymer_chain_names.append(ch.name) + + # get AU chain names representing non-polymer entities + non_polymer_entity_ids = mmcif_info.GetEntityIdsOfType("non-polymer") + non_polymer_chain_names = list() + for ch in mmcif_entity.chains: + if mmcif_info.GetMMCifEntityIdTr(ch.name) in non_polymer_entity_ids: + non_polymer_chain_names.append(ch.name) + + # construct biounit if necessary + if biounit is not None: + biounit_found = False + for bu in mmcif_info.biounits: + if bu.id == biounit: + mmcif_entity = mol.alg.CreateBU(mmcif_entity, bu) + biounit_found = True + break + if not biounit_found: + raise RuntimeError(f"Specified biounit '{biounit}' not in " + f"{mmcif_path}") + + # assign generic properties for selection later on + non_poly_id = 0 + for ch in mmcif_entity.chains: + cname = None + if biounit is not None: + # if a biounit is constructed, you get chain names like: 1.YOLO + # we cannot simply split by '.' since '.' is an allowed character + # in chain names. => split by first occurence + dot_index = ch.name.find('.') + if dot_index == -1: + cname = ch.name + else: + cname = ch.name[dot_index+1:] + else: + cname = ch.name + + if cname in polymer_chain_names: + ch.SetIntProp("poly", 1) + if cname in non_polymer_chain_names: + ch.SetIntProp("nonpolyid", non_poly_id) + non_poly_id += 1 + + poly_sel = mmcif_entity.Select("gcpoly:0=1") + poly_ent = mol.CreateEntityFromView(poly_sel, True) + + if extract_nonpoly == False: + return poly_ent + + non_poly_sel = mmcif_entity.Select("gcnonpoly:0=1") + non_poly_entities = list() + for i in range(non_poly_id): + view = mmcif_entity.Select(f"gcnonpolyid:{non_poly_id}={i}") + if view.GetResidueCount() != 1: + raise RuntimeError(f"Expect non-polymer entities in " + f"{mmcif_path} to contain exactly 1 " + f"residue. Got {ch.GetResidueCount()} " + f"in chain {ch.name}") + if not allow_heuristic_conn: + compound = clib.FindCompound(view.residues[0].name) + if compound is None: + raise RuntimeError(f"Can only extract non-polymer entities if " + f"respective residues are available in PDB " + f"component dictionary. Can't find " + f"\"{view.residues[0].name}\"") + + non_poly_entities.append(mol.CreateEntityFromView(view, True)) + + return (poly_ent, non_poly_entities) + + +def PDBPrep(pdb_path, fault_tolerant=False): + """ Scoring helper - Prepares scoring input from PDB + + Only performs gentle cleanup of hydrogen atoms. Further cleanup is delegated + to scoring classes. There is no logic to extract ligands from PDB + files. Ligands must be provided separately as SDF files in these cases. + + :param pdb_path: Path to PDB file that contains polymer entities + :type pdb_path: :class:`str` + :param fault_tolerant: Passed as parameter to :func:`ost.io.LoadPDB` + :type fault_tolerant: :class:`bool` + :returns: :class:`EntityHandle` from loaded file. + """ + clib = conop.GetDefaultLib() + if not clib: + ost.LogError("A compound library is required. " + "Please refer to the OpenStructure website: " + "https://openstructure.org/docs/conop/compoundlib/.") + raise RuntimeError("No compound library found") + + pdb_entity = io.LoadPDB(pdb_path, fault_tolerant=fault_tolerant) + pdb_entity = CleanHydrogens(pdb_entity, clib) + + return pdb_entity + +__all__ = ('CleanHydrogens', 'MMCIFPrep', 'PDBPrep') diff --git a/modules/mol/alg/tests/test_ligand_scoring.py b/modules/mol/alg/tests/test_ligand_scoring.py index 6e09ebe70b749f54e66faf0c1a9aec657a82ab1a..56f23f3c2d37631b689623084142929429076616 100644 --- a/modules/mol/alg/tests/test_ligand_scoring.py +++ b/modules/mol/alg/tests/test_ligand_scoring.py @@ -8,6 +8,7 @@ from ost import io, mol, geom, conop, seq # check if we can import: fails if numpy or scipy not available try: from ost.mol.alg.ligand_scoring_base import * + from ost.mol.alg import scoring_base from ost.mol.alg import ligand_scoring_base from ost.mol.alg import ligand_scoring_scrmsd from ost.mol.alg import ligand_scoring_lddtpli @@ -56,10 +57,10 @@ class TestLigandScoringFancy(unittest.TestCase): """Test that we can extract ligands from mmCIF files. """ # they're extracted in the MMCIFPrep function actually - trg, trg_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), - extract_nonpoly=True) - mdl, mdl_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("P84080_model_02.cif.gz"), - extract_nonpoly=True) + trg, trg_lig = scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), + extract_nonpoly=True) + mdl, mdl_lig = scoring_base.MMCIFPrep(_GetTestfilePath("P84080_model_02.cif.gz"), + extract_nonpoly=True) sc = LigandScorer(mdl, trg, mdl_lig, trg_lig) @@ -85,9 +86,9 @@ class TestLigandScoringFancy(unittest.TestCase): io.SaveEntity(lig_ent, "%s_ligand_%d.sdf" % (prefix, lig_num)) lig_num += 1 """ - mdl = ligand_scoring_base.PDBPrep(_GetTestfilePath("P84080_model_02_nolig.pdb")) + mdl = scoring_base.PDBPrep(_GetTestfilePath("P84080_model_02_nolig.pdb")) mdl_ligs = [_LoadEntity("P84080_model_02_ligand_0.sdf")] - trg = ligand_scoring_base.PDBPrep(_GetTestfilePath("1r8q_protein.pdb.gz")) + trg = scoring_base.PDBPrep(_GetTestfilePath("1r8q_protein.pdb.gz")) trg_ligs = [_LoadEntity("1r8q_ligand_%d.sdf" % i) for i in range(7)] # Pass entities @@ -112,9 +113,9 @@ class TestLigandScoringFancy(unittest.TestCase): """Test that we reject input if multiple ligands with the same chain name/residue number are given. """ - mdl = ligand_scoring_base.PDBPrep(_GetTestfilePath("P84080_model_02_nolig.pdb")) + mdl = scoring_base.PDBPrep(_GetTestfilePath("P84080_model_02_nolig.pdb")) mdl_ligs = [_LoadEntity("P84080_model_02_ligand_0.sdf")] - trg = ligand_scoring_base.PDBPrep(_GetTestfilePath("1r8q_protein.pdb.gz")) + trg = scoring_base.PDBPrep(_GetTestfilePath("1r8q_protein.pdb.gz")) trg_ligs = [_LoadEntity("1r8q_ligand_%d.sdf" % i) for i in range(7)] # Reject identical model ligands @@ -241,9 +242,9 @@ class TestLigandScoringFancy(unittest.TestCase): def test_compute_rmsd_scores(self): """Test that _compute_scores works. """ - trg, trg_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), - extract_nonpoly=True) - mdl = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("P84080_model_02.cif.gz")) + trg, trg_lig = scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), + extract_nonpoly=True) + mdl = scoring_base.MMCIFPrep(_GetTestfilePath("P84080_model_02.cif.gz")) mdl_lig = io.LoadEntity(os.path.join('testfiles', "P84080_model_02_ligand_0.sdf")) sc = ligand_scoring_scrmsd.SCRMSDScorer(mdl, trg, [mdl_lig], trg_lig) @@ -260,10 +261,10 @@ class TestLigandScoringFancy(unittest.TestCase): [np.nan]]), decimal=5) def test_compute_lddtpli_scores(self): - trg, trg_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), - extract_nonpoly=True) + trg, trg_lig = scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), + extract_nonpoly=True) - mdl = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("P84080_model_02.cif.gz")) + mdl = scoring_base.MMCIFPrep(_GetTestfilePath("P84080_model_02.cif.gz")) mdl_lig = io.LoadEntity(os.path.join('testfiles', "P84080_model_02_ligand_0.sdf")) @@ -367,10 +368,10 @@ class TestLigandScoringFancy(unittest.TestCase): lig.GetAtomCount()), 5) def test_assignment(self): - trg, trg_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), - extract_nonpoly = True) - mdl, mdl_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("P84080_model_02.cif.gz"), - extract_nonpoly = True) + trg, trg_lig = scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), + extract_nonpoly = True) + mdl, mdl_lig = scoring_base.MMCIFPrep(_GetTestfilePath("P84080_model_02.cif.gz"), + extract_nonpoly = True) sc = ligand_scoring_scrmsd.SCRMSDScorer(mdl, trg, mdl_lig, trg_lig) self.assertEqual(sc.assignment, [(1, 0)]) @@ -381,10 +382,10 @@ class TestLigandScoringFancy(unittest.TestCase): """Test that the scores are computed correctly """ # 4C0A has more ligands - trg, trg_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), + trg, trg_lig = scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), extract_nonpoly = True) - trg_4c0a, trg_4c0a_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("4c0a.cif.gz"), + trg_4c0a, trg_4c0a_lig = scoring_base.MMCIFPrep(_GetTestfilePath("4c0a.cif.gz"), extract_nonpoly = True) sc = ligand_scoring_scrmsd.SCRMSDScorer(trg, trg_4c0a, trg_lig, trg_4c0a_lig) expected_keys = {"J", "F"} @@ -411,11 +412,11 @@ class TestLigandScoringFancy(unittest.TestCase): """Test that the scores are computed correctly """ # 4C0A has more ligands - trg, trg_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), - extract_nonpoly = True) + trg, trg_lig = scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), + extract_nonpoly = True) - trg_4c0a, trg_4c0a_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("4c0a.cif.gz"), - extract_nonpoly = True) + trg_4c0a, trg_4c0a_lig = scoring_base.MMCIFPrep(_GetTestfilePath("4c0a.cif.gz"), + extract_nonpoly = True) sc = ligand_scoring_lddtpli.LDDTPLIScorer(trg, trg_4c0a, trg_lig, trg_4c0a_lig, add_mdl_contacts=False, @@ -458,8 +459,8 @@ class TestLigandScoringFancy(unittest.TestCase): other ligands, peptides and short oligomers into account for superposition. When that's the case this test should be adapter """ - trg, trg_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("1SSP.cif.gz"), - extract_nonpoly=True) + trg, trg_lig = scoring_base.MMCIFPrep(_GetTestfilePath("1SSP.cif.gz"), + extract_nonpoly=True) sc = ligand_scoring_scrmsd.SCRMSDScorer(trg, trg, trg_lig, trg_lig) expected_bs_ref_res = ['C.GLY62', 'C.GLN63', 'C.ASP64', 'C.PRO65', 'C.TYR66', 'C.CYS76', 'C.PHE77', 'C.ASN123', 'C.HIS187'] @@ -502,9 +503,9 @@ class TestLigandScoringFancy(unittest.TestCase): the ligand RET was wrongly assigned to short copies of OLA that float around and yielded higher scores. Here we test that this is resolved correctly.""" - mdl = ligand_scoring_base.PDBPrep(_GetTestfilePath("6jyf_mdl.pdb")) - trg, trg_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("6jyf_trg.cif"), - extract_nonpoly=True) + mdl = scoring_base.PDBPrep(_GetTestfilePath("6jyf_mdl.pdb")) + trg, trg_lig = scoring_base.MMCIFPrep(_GetTestfilePath("6jyf_trg.cif"), + extract_nonpoly=True) mdl_lig = _LoadEntity("6jyf_RET_pred.sdf") mdl_lig_full = _LoadEntity("6jyf_RET_pred_complete.sdf") @@ -604,8 +605,8 @@ class TestLigandScoringFancy(unittest.TestCase): trg = _LoadMMCIF("1r8q.cif.gz").Copy() - trg, trg_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), - extract_nonpoly=True) + trg, trg_lig = scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), + extract_nonpoly=True) mdl = trg.Copy() mdl_lig = [l.Copy() for l in trg_lig] @@ -669,9 +670,9 @@ class TestLigandScoringFancy(unittest.TestCase): disambiguate the RMSDs). - We get LDDT-PLI = None with RMSD assignment """ - trg = ligand_scoring_base.PDBPrep(_GetTestfilePath("T1118v1.pdb")) + trg = scoring_base.PDBPrep(_GetTestfilePath("T1118v1.pdb")) trg_lig = _LoadEntity("T1118v1_001.sdf") - mdl = ligand_scoring_base.PDBPrep(_GetTestfilePath("T1118v1LG035_1.pdb")) + mdl = scoring_base.PDBPrep(_GetTestfilePath("T1118v1LG035_1.pdb")) mdl_lig = _LoadEntity("T1118v1LG035_1_1_1.sdf") # Ensure it's unassigned in LDDT @@ -725,10 +726,10 @@ class TestLigandScoringFancy(unittest.TestCase): def test_unassigned_reasons(self): """Test reasons for being unassigned.""" - trg, trg_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), - extract_nonpoly=True) - mdl, mdl_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("P84080_model_02.cif.gz"), - extract_nonpoly=True) + trg, trg_lig = scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), + extract_nonpoly=True) + mdl, mdl_lig = scoring_base.MMCIFPrep(_GetTestfilePath("P84080_model_02.cif.gz"), + extract_nonpoly=True) # Add interesting ligands to model and target mdl_lig_ent = mol.CreateEntity() @@ -901,10 +902,10 @@ class TestLigandScoringFancy(unittest.TestCase): def test_cleanup_polymer_ent(self): - trg, trg_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), - extract_nonpoly=True) - mdl, mdl_lig = ligand_scoring_base.MMCIFPrep(_GetTestfilePath("P84080_model_02.cif.gz"), - extract_nonpoly=True) + trg, trg_lig = scoring_base.MMCIFPrep(_GetTestfilePath("1r8q.cif.gz"), + extract_nonpoly=True) + mdl, mdl_lig = scoring_base.MMCIFPrep(_GetTestfilePath("P84080_model_02.cif.gz"), + extract_nonpoly=True) # check hydrogen cleanup trg_with_h = trg.Copy()