Beispiel #1
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,
     )
 def _get_atom_descriptors(self, atom: Chem.Atom) -> dict:
     return {
         'name': self._get_pdb_atomname(atom),
         'rtype': atom.GetProp('_rType'),
         'mtype': ' X  ',
         'partial': atom.GetDoubleProp('_GasteigerCharge')
     }
Beispiel #3
0
 def _get_origin(cls, atom: Chem.Atom) -> List[str]:
     if atom.HasProp('_Origin'):
         o = atom.GetProp('_Origin')
         if o != 'none':
             return json.loads(o)
         else:
             return []
     else:
         return []
def stereochemistry(atom: Atom) -> str:
    """CIP sterochemistry label (string).
    """
    mol = atom.GetOwningMol()
    if not mol.HasProp('_CIPLabelsAssigned'):
        rdCIPLabeler.AssignCIPLabels(mol)
        mol.SetProp('_CIPLabelsAssigned', '1')

    return atom.GetProp('_CIPCode') if atom.HasProp('_CIPCode') else ''
Beispiel #5
0
    def _add_bond_if_possible(self,
                              mol,
                              first: Chem.Atom,
                              second: Chem.Atom,
                              provenance='other_novel'):
        """
        This method is used by _copy_bonding, but triggered when force=False

        :param mol:
        :param first:
        :param second:
        :param provenance:
        :return:
        """
        # --- Prep
        first_idx = first.GetIdx()
        second_idx = second.GetIdx()
        present_bond = mol.GetBondBetweenAtoms(first_idx, second_idx)
        if second.HasProp('_ring_bond'):
            bt = getattr(Chem.BondType, second.GetProp('_ring_bond'))
        else:
            bt = None
        # === Bond already exists series ============================================
        # --- Bond already exists and not bond type is specified
        if present_bond is not None and bt is None:
            self.journal.debug(
                f'Bond between {first_idx} and {second_idx} already exists')
            return True  # exists
        # --- Bond already exists but has an error
        elif present_bond is not None and present_bond.GetBondType() is None:
            present_bond.SetBondType(Chem.BondType.SINGLE)
            return True
        # --- Bond already exists and matches the expected bond type
        elif present_bond is not None and bt.name == present_bond.GetBondType(
        ).name:
            return True
        # --- Bond already exists but does not match the expected bond type
        elif present_bond is not None:
            present_bond.SetBondType(bt)
            return True
        # === Assess if new bond should be added ============================================
        # --- Don't add if it would make a triangle
        elif self._is_would_be_triangle(first, second):
            self.journal.debug(
                f'Bond between {first_idx} and {second_idx} would make a triangle, skipping'
            )
            return False
        # --- Don't add if it would make a square
        elif self._is_would_be_square(first, second):
            self.journal.debug(
                f'Bond between {first_idx} and {second_idx} would make a square, skipping'
            )
            return False
        # --- Don't add if it would ruin the warhead
        elif self._is_connected_warhead(second, first):
            self.journal.debug(
                f'Bond between {first_idx} and {second_idx} would break a warhead, skipping'
            )
            return False
        # --- New bond is green lit
        elif self._assess_atom_for_possible_bonding(
                first, bt) and self._assess_atom_for_possible_bonding(
                    second, bt):
            mol.AddBond(first_idx, second_idx,
                        bt if bt is not None else Chem.BondType.SINGLE)
            new_bond = mol.GetBondBetweenAtoms(first_idx, second_idx)
            BondProvenance.set_bond(new_bond, provenance)
            return True
        # --- New bond is no go
        else:
            # len(Chem.GetMolFrags(mol, sanitizeFrags=False)) ought to be checked.
            # however, join_neighboring gets called by emergency bonding so should be fine.
            return False  # too bonded etc.