Exemplo n.º 1
0
 def _get_valence_difference(self, atom: Chem.Atom) -> int:
     pt = Chem.GetPeriodicTable()
     valence = self._get_atom_valence(atom)
     if self._valence_mode == 'max':
         maxv = max(pt.GetValenceList(atom.GetAtomicNum()))
         return valence - maxv
     else:
         d = pt.GetDefaultValence(atom.GetAtomicNum())
         return valence - d
Exemplo n.º 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,
     )
Exemplo n.º 3
0
 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!
    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
Exemplo n.º 5
0
def _AtomHallKierDeltas(atom: Chem.Atom, skipHs: bool = False) -> List[float]:
    """Calculate Kier & Hall atomic valence delta-values for molecular connectivity.

    From Kier L. and Hall L., J. Pharm. Sci. (1983), 72(10),1170-1173.
    """
    global periodicTable
    res = []
    n = atom.GetAtomicNum()
    if n > 1:
        nV = periodicTable.GetNOuterElecs(n)
        nHs = atom.GetTotalNumHs()
        if n < 10:
            res.append(float(nV - nHs))
        else:
            res.append(float(nV - nHs) / float(n - nV - 1))
    elif not skipHs:
        res.append(0.0)
    return res
Exemplo n.º 6
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!
Exemplo n.º 7
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
Exemplo n.º 8
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!
Exemplo n.º 9
0
def atomic_number(atom: Atom) -> int:
    """Atomic number (int).
    """
    return atom.GetAtomicNum()