Spaces:
Running on Zero
Running on Zero
Download utils/visualization.py from LIVazquezS/Juniper_dg: direct link, hf CLI and curl.
- Browser
- Download file 4.75 kB
-
https://huggingface.co/spaces/LIVazquezS/Juniper_dg/resolve/main/utils/visualization.py
- Command line
-
hf download hf://spaces/LIVazquezS/Juniper_dg/utils/visualization.py
-
curl -L -o visualization.py https://huggingface.co/spaces/LIVazquezS/Juniper_dg/resolve/main/utils/visualization.py
4.75 kB
| import os | |
| from rdkit import Chem | |
| from rdkit.Chem import Draw, AllChem | |
| from rdkit.Geometry import Point3D | |
| from rdkit import RDLogger | |
| import imageio # What is this? | |
| import networkx as nx | |
| import numpy as np | |
| import rdkit.Chem | |
| import matplotlib.pyplot as plt | |
| class MolecularVisualization: | |
| def __init__(self, remove_h, dataset_infos): | |
| self.remove_h = remove_h | |
| self.dataset_infos = dataset_infos | |
| def mol_from_graphs(self, node_list, adjacency_matrix): | |
| """ | |
| Convert graphs to rdkit molecules | |
| node_list: the nodes of a batch of nodes (bs x n) | |
| adjacency_matrix: the adjacency_matrix of the molecule (bs x n x n) | |
| """ | |
| # dictionary to map integer value to the char of atom | |
| atom_decoder = self.dataset_infos.atom_decoder | |
| # create empty editable mol object | |
| mol = Chem.RWMol() | |
| # add atoms to mol and keep track of index | |
| node_to_idx = {} | |
| for i in range(len(node_list)): | |
| if node_list[i] == -1: | |
| continue | |
| a = Chem.Atom(atom_decoder[int(node_list[i])]) | |
| molIdx = mol.AddAtom(a) | |
| node_to_idx[i] = molIdx | |
| for ix, row in enumerate(adjacency_matrix): | |
| for iy, bond in enumerate(row): | |
| # only traverse half the symmetric matrix | |
| if iy <= ix: | |
| continue | |
| if bond == 1: | |
| bond_type = Chem.rdchem.BondType.SINGLE | |
| elif bond == 2: | |
| bond_type = Chem.rdchem.BondType.DOUBLE | |
| elif bond == 3: | |
| bond_type = Chem.rdchem.BondType.TRIPLE | |
| elif bond == 4: | |
| bond_type = Chem.rdchem.BondType.AROMATIC | |
| else: | |
| continue | |
| mol.AddBond(node_to_idx[ix], node_to_idx[iy], bond_type) | |
| try: | |
| mol = mol.GetMol() | |
| except rdkit.Chem.KekulizeException: | |
| print("Can't kekulize molecule") | |
| mol = None | |
| return mol | |
| def visualize(self, path: str, molecules: list, num_molecules_to_visualize: int): | |
| # define path to save figures | |
| if not os.path.exists(path): | |
| os.makedirs(path) | |
| # visualize the final molecules | |
| print(f"Visualizing {num_molecules_to_visualize} of {len(molecules)}") | |
| if num_molecules_to_visualize > len(molecules): | |
| print(f"Shortening to {len(molecules)}") | |
| num_molecules_to_visualize = len(molecules) | |
| for i in range(num_molecules_to_visualize): | |
| file_path = os.path.join(path, 'molecule_{}.png'.format(i)) | |
| mol = self.mol_from_graphs(molecules[i][0].numpy(), molecules[i][1].numpy()) | |
| try: | |
| Draw.MolToFile(mol, file_path) | |
| except rdkit.Chem.KekulizeException: | |
| print("Can't kekulize molecule") | |
| def visualize_chain(self, path, nodes_list, adjacency_matrix): | |
| RDLogger.DisableLog('rdApp.*') | |
| # convert graphs to the rdkit molecules | |
| mols = [self.mol_from_graphs(nodes_list[i], adjacency_matrix[i]) for i in range(nodes_list.shape[0])] | |
| # find the coordinates of atoms in the final molecule | |
| final_molecule = mols[-1] | |
| AllChem.Compute2DCoords(final_molecule) | |
| coords = [] | |
| for i, atom in enumerate(final_molecule.GetAtoms()): | |
| positions = final_molecule.GetConformer().GetAtomPosition(i) | |
| coords.append((positions.x, positions.y, positions.z)) | |
| # align all the molecules | |
| for i, mol in enumerate(mols): | |
| AllChem.Compute2DCoords(mol) | |
| conf = mol.GetConformer() | |
| for j, atom in enumerate(mol.GetAtoms()): | |
| x, y, z = coords[j] | |
| conf.SetAtomPosition(j, Point3D(x, y, z)) | |
| # draw gif | |
| save_paths = [] | |
| num_frams = nodes_list.shape[0] | |
| for frame in range(num_frams): | |
| file_name = os.path.join(path, 'fram_{}.png'.format(frame)) | |
| Draw.MolToFile(mols[frame], file_name, size=(300, 300), legend=f"Frame {frame}") | |
| save_paths.append(file_name) | |
| imgs = [imageio.imread(fn) for fn in save_paths] | |
| gif_path = os.path.join(os.path.dirname(path), '{}.gif'.format(path.split('/')[-1])) | |
| imgs.extend([imgs[-1]] * 5) | |
| imageio.mimsave(gif_path, imgs, subrectangles=True, duration=20) | |
| # draw grid image | |
| try: | |
| img = Draw.MolsToGridImage(mols, molsPerRow=10, subImgSize=(200, 200)) | |
| img.save(os.path.join(path, '{}_grid_image.png'.format(path.split('/')[-1]))) | |
| except Chem.rdchem.KekulizeException: | |
| print("Can't kekulize molecule") | |
| return mols | |