def assess_atom(atom: Chem.Atom, bt: Chem.BondType) -> Tuple[bool, Chem.BondType]:
     if atom.GetAtomicNum() > 8:
         return True, bt
     elif len(atom.GetNeighbors()) <= 2 and atom.GetIsAromatic():
         return True, Chem.BondType.SINGLE
     elif len(atom_i.GetNeighbors()) <= 3 and not atom.GetIsAromatic():
         return True, bt
     else:
         return False, bt  # too bonded already!
Beispiel #2
0
 def from_rdkit(cls, rd_atom: Chem.Atom) -> "Atom":
     """
     Build a QUBEKit atom from an rdkit atom instance.
     """
     atomic_number = rd_atom.GetAtomicNum()
     index = rd_atom.GetIdx()
     formal_charge = rd_atom.GetFormalCharge()
     aromatic = rd_atom.GetIsAromatic()
     bonds = [a.GetIdx() for a in rd_atom.GetNeighbors()]
     # check for names in the normal places pdb, mol2 and mol
     if rd_atom.HasProp("_Name"):
         name = rd_atom.GetProp("_Name")
     elif rd_atom.HasProp("_TriposAtomName"):
         name = rd_atom.GetProp("_TriposAtomName")
     else:
         try:
             name = rd_atom.GetMonomerInfo().GetName().strip()
         except AttributeError:
             name = None
     # stereochem
     if rd_atom.HasProp("_CIPCode"):
         stereo_code = rd_atom.GetProp("_CIPCode")
     else:
         stereo_code = None
     return cls(
         atomic_number=atomic_number,
         atom_index=index,
         atom_name=name,
         formal_charge=formal_charge,
         aromatic=aromatic,
         stereochemistry=stereo_code,
         bonds=bonds,
     )
Beispiel #3
0
        def assess_atom(atom: Chem.Atom, bt: Chem.BondType) -> Tuple[bool, Chem.BondType]:
            """
            True means add, False means delete

            :param atom:
            :param bt:
            :return:
            """
            n_neigh = sum([self._is_count_valid(neigh) for neigh in atom.GetNeighbors()])
            if atom.GetAtomicNum() > 8:
                return True, bt
            elif atom.HasProp('DELETE'):  # if it is to be deleted it should be fine.
                return True, bt
            elif n_neigh <= 2 and atom.GetIsAromatic():
                return True, Chem.BondType.SINGLE
            elif n_neigh <= 3 and not atom.GetIsAromatic():
                return True, bt
            else:
                return False, bt  # too bonded already!
Beispiel #4
0
    def get_atom_hybridization(self, atom: Atom):
        if self.is_hydrogen(atom):
            return self.get_hydrogen_hybridization(atom)

        if atom.GetIsAromatic():
            return "_R"

        if self.has_hybridization(atom):
            return "_%s" % self.get_hybridization(atom)

        return ""
Beispiel #5
0
def atom_features(atom: Chem.Atom):
    return np.array(
        encoding_onehot_unk(atom.GetSymbol(), [
            'C', 'N', 'O', 'S', 'F', 'Si', 'P', 'Cl', 'Br', 'Mg', 'Na', 'Ca',
            'Fe', 'As', 'Al', 'I', 'B', 'V', 'K', 'Tl', 'Yb', 'Sb', 'Sn', 'Ag',
            'Pd', 'Co', 'Se', 'Ti', 'Zn', 'H', 'Li', 'Ge', 'Cu', 'Au', 'Ni',
            'Cd', 'In', 'Mn', 'Zr', 'Cr', 'Pt', 'Hg', 'Pb', 'Unknown'
        ]) + encoding_onehot(atom.GetDegree(), [0, 1, 2, 3, 4, 5]) +
        encoding_onehot_unk(atom.GetTotalNumHs(), [0, 1, 2, 3, 4]) +
        encoding_onehot_unk(atom.GetImplicitValence(), [0, 1, 2, 3, 4, 5]) +
        [atom.GetIsAromatic()])
Beispiel #6
0
    def _assess_atom_for_possible_bonding(self, atom: Chem.Atom,
                                          bt: Chem.BondType) -> bool:
        """
        Method for add_bond_if_possible
        True means add, False means delete

        :param atom:
        :param bt:
        :return:
        """
        n_neigh = sum(
            [self._is_count_valid(neigh) for neigh in atom.GetNeighbors()])
        if atom.GetAtomicNum() > 8:
            return True
        elif atom.HasProp(
                'DELETE'):  # if it is to be deleted it should be fine.
            return True
        elif n_neigh <= 2 and atom.GetIsAromatic():
            return True, Chem.BondType.SINGLE
        elif n_neigh <= 3 and not atom.GetIsAromatic():
            return True
        else:
            return False  # too bonded already!
    def atom_to_feat(self, atm: Chem.Atom, owning_mol: Chem.Mol, idx):
        # nb the func GetOwningMol could not be used for mol as would return different object each time
        this_atms_idx = atm.GetIdx()
        assert idx == this_atms_idx

        feat = torch.zeros(len(self), dtype=torch.float32)

        # One hot encoding of element
        try:
            feat[self.atms_to_idx[atm.GetSymbol()]] = 1.
        except KeyError as ex:
            warnings.warn(f"Ignoring the symbol {atm.GetSymbol()}")
        idx_up_to = self.number_atom_options

        # Atomic Number
        feat[idx_up_to] = float(atm.GetAtomicNum())
        idx_up_to += 1

        # Acceptor/donor
        acceptor_ids, donor_ids = self.get_acceptor_and_donor_ids(owning_mol)

        # Acceptor
        feat[idx_up_to] = float(this_atms_idx in acceptor_ids)
        idx_up_to += 1

        # Donor
        feat[idx_up_to] = float(this_atms_idx in donor_ids)
        idx_up_to += 1


        # Hybridization
        hyb_idx = self.hybridization(atm.GetHybridization())
        if hyb_idx is not None:
            feat[idx_up_to + hyb_idx] = 1.
        idx_up_to += self.number_hyb_options

        # Aromatic
        feat[idx_up_to] = float(atm.GetIsAromatic())
        idx_up_to += 1

        # Number of Hydrogens
        feat[idx_up_to] = float(atm.GetNumImplicitHs())
        idx_up_to += 1

        return feat
Beispiel #8
0
def atom_to_string(atom: Chem.Atom) -> str:

    return '{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}|{}'.format(
        atom.GetChiralTag(),
        atom.GetDegree(),
        atom.GetExplicitValence(),
        atom.GetFormalCharge(),
        atom.GetHybridization(),
        atom.GetIsAromatic(),
        atom.GetMass(),
        atom.GetNumExplicitHs(),
        atom.GetNumImplicitHs(),
        atom.GetNumRadicalElectrons(),
        atom.GetTotalDegree(),
        atom.GetTotalNumHs(),
        atom.GetTotalValence(),
        atom.IsInRing()
    )
Beispiel #9
0
def atom_feature(atom: Atom) -> Tuple[torch.Tensor, int]:
    '''
    Extract atom feature vector.

    Returns: (feature_vec, feature_dim)

    Features:
        # item            # dim
        atomic number     25
        exp-valence       7
        imp-valence       4
        hybridization     7
        Hs                5
        degree            6
        formal charge     6
        in ring           1
        aromatic          1
        mass / 100        1
        (sum)             63
    '''

    index = torch.tensor([
        ATOM_MAP[atom.GetAtomicNum()],
        atom.GetExplicitValence(),
        atom.GetImplicitValence(),
        HYBRID_MAP[atom.GetHybridization()],
        atom.GetTotalNumHs(),
        atom.GetDegree(),
        atom.GetFormalCharge() + 2,  # -2 ~ 3
        int(atom.IsInRing()),
        int(atom.GetIsAromatic())
    ]) + OFFSET

    vec = torch.zeros(ATOM_FDIM)
    vec[index] = 1.0
    vec[-1] = atom.GetMass() / 100

    return vec, ATOM_FDIM
def is_aromatic(atom: Atom) -> int:
    """If the atom is aromatic (0 or 1).
    """
    return int(atom.GetIsAromatic())