def translate(mol: Chem.rdchem.Mol, new_centroid: Union[np.ndarray, List[int]], conf_id: int = -1): """Move a given conformer of a molecule to a new position. The transformation is performed in place. Args: mol: the molecule. new_centroid: the new position to move to of shape [x, y, z] conf_id: id of the conformer. """ # Get conformer conf = mol.GetConformer(conf_id) # Compute the vector for translation mol_center = rdMolTransforms.ComputeCentroid(conf) mol_center = np.array([mol_center.x, mol_center.y, mol_center.z]) # Make the transformation matrix T = np.eye(4) T[:3, 3] = new_centroid - mol_center # Transform rdMolTransforms.TransformConformer(conf, T)
def get_coords(mol: Chem.rdchem.Mol, conf_id: int = -1): """Get the coordinate of a conformer of a molecule. Args: mol: a molecule. conf_id: a conformer id. """ if mol.GetNumConformers() == 0: raise ValueError("Molecule does not have any conformers.") conf = mol.GetConformer(id=conf_id) return conf.GetPositions()
def createRDKITconf(self, mol: Chem.rdchem.Mol, conversionFactor: float = 0.1): """creates a PyGromosTools CNF type from a rdkit molecule. If a conformation exists the first one will be used. Parameters ---------- mol : Chem.rdchem.Mol Molecule, possibly with a conformation conversionFactor : float the factor used to convert length from rdkit to Gromos (default: angstrom -> nano meter = 0.1) """ inchi = Chem.MolToInchi(mol).split("/") if len(inchi) >= 2: name = inchi[1] else: name = "XXX" self.__setattr__("TITLE", TITLE("\t" + name + " created from RDKit")) # check if conformations exist else create a new one if mol.GetNumConformers() < 1: mol = Chem.AddHs(mol) AllChem.EmbedMolecule(mol) AllChem.UFFOptimizeMolecule(mol) conf = mol.GetConformer(0) # fill a list with atomP types from RDKit data atomList = [] for i in range(mol.GetNumAtoms()): x = conversionFactor * conf.GetAtomPosition(i).x y = conversionFactor * conf.GetAtomPosition(i).y z = conversionFactor * conf.GetAtomPosition(i).z atomType = mol.GetAtomWithIdx(i).GetSymbol() atomList.append(blocks.atomP(resID=1, resName=name, atomType=atomType, atomID=i + 1, xp=x, yp=y, zp=z)) # set POSITION attribute self.__setattr__("POSITION", blocks.POSITION(atomList)) # Defaults set for GENBOX - for liquid sim adjust manually self.__setattr__("GENBOX", blocks.GENBOX(pbc=1, length=[4, 4, 4], angles=[90, 90, 90]))
def return_centroids( mol: Chem.rdchem.Mol, conf_clusters: Sequence[Sequence[int]], centroids: bool = True, ) -> Union[List[Chem.rdchem.Mol], Chem.rdchem.Mol]: """Given a list of cluster indices, return one single molecule with only the centroid of the clusters of a list of molecules per cluster. Args: mol: a molecule. conf_clusters: list of cluster indices. centroids: If True, return one molecule with centroid conformers only. If False return a list of molecules per cluster with all the conformers of the cluster. """ if centroids: # Collect centroid of each cluster (first element of the list) centroid_list = [indices[0] for indices in conf_clusters] # Keep only centroid conformers mol_clone = copy.deepcopy(mol) confs = [mol_clone.GetConformers()[i] for i in centroid_list] mol.RemoveAllConformers() [mol.AddConformer(conf, assignId=True) for conf in confs] return mol else: # Create a new molecule for each cluster and add conformers to it. mols = [] for cluster in conf_clusters: m = copy.deepcopy(mol) m.RemoveAllConformers() [ m.AddConformer(mol.GetConformer(c), assignId=True) for c in cluster ] mols.append(m) return mols