Ejemplo n.º 1
0
def fill_serial_numbers(pdb: Pdb):
    """The reduce program can add hydrogens to ligands, those hydrogens will have no atom serial numbers
    RDKit will give parse error on a PDB block with atoms without an atom serial number.

    This method adds serial ids and bonds those hydrogens to their heavy atom based on it's name

    Args:
        pdb: The pdb to fill serial ids in

    """
    model = pdb.model()
    max_serial_number = max(
        [a.atom_id() for a in model.atoms() if a.atom_id()])
    for mol in model.molecules(generic=True):
        for a in mol.atoms(element='H'):
            if a.atom_id() != 0:
                continue
            max_serial_number += 1
            # a.atom_id() is not a setter, so set it using private prop
            a._id = max_serial_number
            hgrp = a.name()[1]
            bonded = False
            for heavy in mol.atoms(exclude='H'):
                oname = heavy.name()
                if len(oname) > 1 and oname[1] == hgrp:
                    logger.info('Binding {0}:{1} with {2}:{3}'.format(
                        a.atom_id(), a.name(), heavy.atom_id(), heavy.name()))
                    heavy.bond(a)
                    bonded = True
            if not bonded:
                logger.warning('Unable to bind {0}:{1} to heavy atom'.format(
                    a.atom_id(), a.name()))
Ejemplo n.º 2
0
def remove_unwanted_molecules(pdb: Pdb):
    """Remove unwanted molecules from model

    Cleans pdb by removing molecules which:
        * Have name in UNWANTED_HETEROS list
        * Is out side LIGAND_MAX_MASS..LIGAND_MIN_MASS mass range
        * Have name already processed (aka removes duplicates)

    Removing is done in-place.

    Args:
        pdb: Atomium PDB entry containing possible unwanted molecules

    """
    unique_names = set()
    model = pdb.model()
    for mol in sorted(model.molecules(generic=True),
                      key=lambda m: m.molecule_id()):
        is_unwanted = mol.name() in UNWANTED_HETEROS
        in_mass_range = LIGAND_MIN_MASS < mol.mass() < LIGAND_MAX_MASS
        seen_before = mol.name() in unique_names
        if is_unwanted or not in_mass_range or seen_before:
            model.remove_molecule(mol)
        else:
            unique_names.add(mol.name())
Ejemplo n.º 3
0
def ligands(pdb: Pdb, ligand_expo: Dict[str, Mol]) -> List[Ligand]:
    """Ligands of a pdb

    Args:
        pdb: The pdb
        ligand_expo: Dictionary with molecules of ligand expo

    Raises:
        NoLigands: When PDB has no ligands

    Returns:
        List of ligands, ordered by name
    """
    model = pdb.model()
    ligs = {}
    for amol in model.molecules(generic=True):
        amol_id = amol.molecule_id()
        # Workaround for atomium 0.8 as to handle molecules with resID 0
        # NOTE: was fixed in 0.11.1, but other changes break kripo
        if amol_id[1:]=="":
             amol._id = amol_id + '0'
             amol_id = amol.molecule_id()
        
        lig_id = pdb.code().lower() + '_' + amol.name() + '_1_' + amol_id[0] + '_' + amol_id[1:]
        try:
            lig = ligand_expo[lig_id]
            plig = protonate_molecule(lig)
            ligs[lig_id] = Ligand(amol, plig)
        except KeyError:
            logger.warning('Unable to find {0} in ligand expo db, skipping'.format(lig_id))
            pass

    if not ligs:
        raise NoLigands()
    return sorted(ligs.values(), key=lambda l: l.name())
Ejemplo n.º 4
0
def ligands(pdb: Pdb, ligand_expo: Dict[str, Mol]) -> List[Ligand]:
    """Ligands of a pdb

    Args:
        pdb: The pdb
        ligand_expo: Dictionary with molecules of ligand expo

    Raises:
        NoLigands: When PDB has no ligands

    Returns:
        List of ligands, ordered by name
    """
    model = pdb.model()
    ligs = {}
    for amol in model.molecules(generic=True):
        amol_id = amol.molecule_id()
        lig_id = pdb.code().lower() + '_' + amol.name(
        ) + '_1_' + amol_id[0] + '_' + amol_id[1:]
        try:
            lig = ligand_expo[lig_id]
            plig = protonate_molecule(lig)
            ligs[lig_id] = Ligand(amol, plig)
        except KeyError:
            logger.warning(
                'Unable to find {0} in ligand expo db, skipping'.format(
                    lig_id))
            pass

    if not ligs:
        raise NoLigands()
    return sorted(ligs.values(), key=lambda l: l.name())
Ejemplo n.º 5
0
def remove_non_contacting_molecules(pdb: Pdb):
    """Remove unwanted molecules from model

    Cleans pdb by removing molecules which:
        * Is more then MAX_CONTACT_DISTANCE away from protein

    Removing is done in-place.

    Args:
        pdb: Atomium PDB entry containing possible unwanted molecules

    """
    model = pdb.model()
    for mol in sorted(model.molecules(generic=True), key=lambda m: m.molecule_id()):
        in_contact_with_protein = ligand_contacts_protein(mol, model)
        if not in_contact_with_protein:
            try:
                model.remove_molecule(mol)
            except KeyError:
                # in 1efr was unable to delete atom with key 22969, ignore error
                pass