How to save rdkit DrawMorganBit output as image? - python

code:
import numpy as np
from rdkit import Chem
from rdkit.Chem import Draw, AllChem, PandasTools, DataStructs
mol = Chem.MolFromSmiles('O=C1N([C##H](C)C2CC2)CC3=CC(C4=C(C)N=C(NC(C)=O)S4)=CC(S(=O)(C)=O)=C31')
bi = {}
fp = AllChem.GetMorganFingerprintAsBitVect(mol, radius=3, bitInfo=bi)
fp_arr = np.zeros(1,)
DataStructs.ConvertToNumpyArray(fp, fp_arr)
fp_arr = np.nonzero(fp_arr)[0]
for ar in fp_arr:
img = Draw.DrawMorganBit(mol, ar, bi, useSVG=True)
img.save("submol.png")
I want to create an image using DrawMorganBit to know how Molecule's fingerprint bit was generated. (Using PyCharm instead of Jupyter Notebook)
However, two problems have arisen: the kekulize problem and the image storage problem.
I dont know what's causing the kekulize problem and how to save DrawMorganBit image
rdkit version 2022.3.4
Error
kekulize problem:
rdkit.Chem.rdchem.KekulizeException: Can't kekulize mol. Unkekulized atoms: 5 6 8 9 14
save problem:
AttributeError: 'str' object has no attribute 'save'

The solution for the problem with kekulizing can be found here:
https://github.com/rdkit/rdkit/issues/5129
Your problem with saving the image is that you are trying to save an SVG as a png.
With this code you should get an image with all MorganBits.
from rdkit import Chem
from rdkit.Chem import rdMolDescriptors, Draw
drawOptions = Draw.rdMolDraw2D.MolDrawOptions()
drawOptions.prepareMolsBeforeDrawing = False
from rdkit.Chem.Draw import IPythonConsole
mol = Chem.MolFromSmiles('O=C1N([C##H](C)C2CC2)CC3=CC(C4=C(C)N=C(NC(C)=O)S4)=CC(S(=O)(C)=O)=C31')
bi = {}
fp = rdMolDescriptors.GetMorganFingerprintAsBitVect(mol, radius=2, bitInfo=bi)
tpls = [(mol, x, bi) for x in fp.GetOnBits()]
p = Draw.DrawMorganBits(tpls, molsPerRow=5, legends=[str(x) for x in fp.GetOnBits()], drawOptions=drawOptions)
p.save('submol.png')

Related

Add PNG object to a pandas dataframe

I tried to add the PNG object into a pandas dataframe, and it does not work at al:
!pip install rdkit-pypi
import pandas as pd
import numpy as np
import rdkit
from rdkit import Chem
from rdkit.Chem import AllChem
from rdkit import DataStructs
from rdkit.Chem import PandasTools
from rdkit.Chem import Draw
from rdkit.Chem.Draw import IPythonConsole
smiles_list = ['N[C#H](C(=O)O)C']
mol_list = []
for smiles in smiles_list:
mol = Chem.MolFromSmiles(smiles)
mol_list.append(mol)
img =Draw.MolsToGridImage(mol_list, molsPerRow = 4)
glycine = mol_list[0]
figure_list = []
bi = {}
fp = AllChem.GetMorganFingerprintAsBitVect(glycine, 2, nBits = 1024, bitInfo = bi)
fp_arr = np.zeros((1,))
DataStructs.ConvertToNumpyArray(fp, fp_arr)
np.nonzero(fp_arr)
list(fp.GetOnBits())
prints = [(glycine, x, bi) for x in fp.GetOnBits()]
figure = Draw.DrawMorganBits(prints, molsPerRow = 4, legends = [str(x) for x in fp.GetOnBits()])
figure_list.append(figure)
df = pd.DataFrame({'smiles': smiles_list[0]}, index = [0])
PandasTools.AddMoleculeColumnToFrame(df,'smiles','Molecule')
df['Fragments'] = figure_list
df
Instead of displaying the PNG image inside the pandas dataframe, it shows the message "<PIL.PngImagePlugin.PngImageFile image mode=RG...".
I would expect to add the PNG object into a pandas dataframe.
I used the following configuration in the googlle colab:
RDKit version: 2022.03.5
OS: Windows
Python version: Python 3.7.15
Are you using conda? No
If you are using conda, which channel did you install the rdkit from? Not applied
If you are not using conda: how did you install the RDKit? !pip install rdkit-pypi
The PNG file can be displayed inline in the pandas dataframe like shown below with the help of a few helper functions.
from IPython.display import HTML
import base64
from io import BytesIO
from PIL import Image
def get_thumbnail(path):
i = Image.open(path)
i.thumbnail((150, 150), Image.LANCZOS)
return i
def image_base64(im):
if isinstance(im, str):
im = get_thumbnail(im)
with BytesIO() as buffer:
im.save(buffer, 'jpeg')
return base64.b64encode(buffer.getvalue()).decode()
def image_formatter(im):
return f'<img src="data:image/jpeg;base64,{image_base64(im)}">'
And finally the code below returns the dataframe with the image.
HTML(df.to_html(formatters={'Fragments': image_formatter}, escape=False))

I get the error module 'keygen' has no attribute 'keygen

I have also installed the appropriate libraries but still the error is showing. The code is written below:
import keygen as kg
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
img = mpimg.imread('Images/111.png')
plt.imshow(img)
#plt.show()
#Now generating the choatic Key
height = img.shape[0]
width = img.shape[1]
key = kg.keygen(0.01,3.951,height*width)
I get error at last line.
here keygen if a function not a library code for that function.
def keygen(x,r,size):
key = []
for i in range(size):
x = r*x*(1-x)
key.append(int((x*pow(10,16))%256))
return key

scipy and numpy not error with as_matrix function

This is a "working example" that does not work. Why does this not run? scipy seems to not work.
i get this error:
File "display_map.py", line 35, in
rot_cw = R.from_quat(keyframe["rot_cw"]).as_matrix()
AttributeError: 'Rotation' object has no attribute 'as_matrix'
please can someone help me me change it. I tried reducing the version of scipy
import msgpack
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
from numpy.linalg import inv
from scipy.spatial.transform import Rotation as R
import open3d as o3d
import sys
if len(sys.argv) < 2:
print(
"ERROR: Please provide path to .msg file. Example usage is; python3 visualize_openvslam_map.py path_to.msg"
)
exit()
with open(sys.argv[1], "rb") as f:
upacked_msg = msgpack.Unpacker(f)
packed_msg = upacked_msg.unpack()
keyfarmes = packed_msg["keyframes"]
landmarks = packed_msg["landmarks"]
# FILL IN KEYFRAME POINTS(ODOMETRY) TO ARRAY
keyframe_points = []
keyframe_points_color = []
for keyframe in keyfarmes.values():
# get conversion from camera to world
trans_cw = np.matrix(keyframe["trans_cw"]).T
rot_cw = R.from_quat(keyframe["rot_cw"]).as_matrix()
# compute conversion from world to camera
rot_wc = rot_cw.T
trans_wc = -rot_wc * trans_cw
keyframe_points.append((trans_wc[0, 0], trans_wc[1, 0], trans_wc[2, 0]))
keyframe_points = np.array(keyframe_points)
keyframe_points_color = np.repeat(np.array([[0., 1., 0.]]),
keyframe_points.shape[0],
axis=0)
# FILL IN LANDMARK POINTS TO ARRAY
landmark_points = []
landmark_points_color = []
for lm in landmarks.values():
landmark_points.append(lm["pos_w"])
landmark_points_color.append([
abs(lm["pos_w"][1]) * 4,
abs(lm["pos_w"][1]) * 2,
abs(lm["pos_w"][1]) * 3
])
landmark_points = np.array(landmark_points)
landmark_points_color = np.array(landmark_points_color)
# CONSTRUCT KEYFRAME(ODOMETRY) FOR VISUALIZTION
keyframe_points_pointcloud = o3d.geometry.PointCloud()
keyframe_points_pointcloud.points = o3d.utility.Vector3dVector(keyframe_points)
keyframe_points_pointcloud.colors = o3d.utility.Vector3dVector(
keyframe_points_color)
# CONSTRUCT LANDMARK POINTCLOUD FOR VISUALIZTION
landmark_points_pointcloud = o3d.geometry.PointCloud()
landmark_points_pointcloud.points = o3d.utility.Vector3dVector(landmark_points)
landmark_points_pointcloud.colors = o3d.utility.Vector3dVector(
landmark_points_color)
# VISULIZE MAP
o3d.visualization.draw_geometries([
keyframe_points_pointcloud, landmark_points_pointcloud,
o3d.geometry.TriangleMesh.create_coordinate_frame()
])
In scipy.spatial.Rotation methods from_dcm, as_dcm were renamed to from_matrix, as_matrix respectively.

Trying to use skimage.morphology in an image processing code but get error message

I'm working thru an image processing example in python 2.7.13. The code has
import skimage.morphology as morph and then later has the line lm1 = morph.is_local_maximum(fimg). I get the error message:
File "2dlocalmaxima.py", line 29, in <module>
lm1 = morph.is_local_maximum(fimg)
AttributeError: 'module' object has no attribute 'is_local_maximum'.
I've googled this and have found many instances of this module being used. I can find no instance of this being deprecated. Am I doing something wrong? I have tried running in python 2.7.13 and 3.6. Both give same error message.
The total code from the book is:
import numpy as np
import matplotlib.pyplot as mpl
import scipy.ndimage as ndimage
import skimage.morphology as morph
# Generating data points with a non-uniform background
x = np.random.uniform(low=0, high=200, size=20).astype(int)
y = np.random.uniform(low=0, high=400, size=20).astype(int)
# Creating image with non-uniform background
func = lambda x, y: np.cos(x)+ np.sin(y)
grid_x, grid_y = np.mgrid[0:12:200j, 0:24:400j]
bkg = func(grid_x, grid_y)
bkg = bkg / np.max(bkg)
# Creating points
clean = np.zeros((200,400))
clean[(x,y)] += 5
clean = ndimage.gaussian_filter(clean, 3)
clean = clean / np.max(clean)
# Combining both the non-uniform background
# and points
fimg = bkg + clean
fimg = fimg / np.max(fimg)
# Calculating local maxima
lm1 = morph.is_local_maximum(fimg)
x1, y1 = np.where(lm1.T == True)
# Creating figure to show local maximum detection
# rate success
fig = mpl.figure(figsize=(8, 4))
ax = fig.add_subplot(111)
ax.imshow(fimg)
ax.scatter(x1, y1, s=100, facecolor='none', edgecolor='#009999')
ax.set_xlim(0,400)
ax.set_ylim(0,200)
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
fig.savefig('scikit_image_f02.pdf', bbox_inches='tight')
After searching thru different files I determined that the module is_local_maximum had its name changed to local_maxima. My code ran to completion and produced the expected result when that substitution was made.

how to display image in Mandlebrot tensorflow program.Current output is <IPython.core.display.Image object>

'''Import libraries for simulation'''
import tensorflow as tf
import numpy as np
'''Imports for visualization'''
from PIL.Image
from io import BytesIO
from IPython.display import Image, display
'''Now we'll define a function to actually display the image once we have
iteration counts'''
def DisplayFractal(a, fmt='jpeg'):
img =np.concatenate([10+20*np.cos(a_cyclic),30+50*np.sin(a_cyclic),155-
80*np.cos(a_cyclic)], 2)
img[a==a.max()] = 0
a = img
a = np.uint8(np.clip(a, 0, 255))
f = BytesIO()
PIL.Image.fromarray(a).save(f, fmt)
display(Image(data=f.getvalue()))
sess = tf.InteractiveSession()
# Use NumPy to create a 2D array of complex numbers
Y, X = np.mgrid[-1.3:1.3:0.005, -2:1:0.005]
Z = X+1j*Y
print(Z)
#Now we define and initialize TensorFlow tensors.
xs = tf.constant(Z.astype(np.complex64))
zs = tf.Variable(xs)
ns = tf.Variable(tf.zeros_like(xs, tf.float32))
tf.global_variables_initializer().run()
zs_ = zs*zs + xs
print(zs)
# Have we diverged with this new value?
not_diverged = tf.abs(zs_) < 4
'''
Operation to update the zs and the iteration count.
Note: We keep computing zs after they diverge! This
is very wasteful! There are better, if a little
less simple, ways to do this.
'''
step = tf.group(zs.assign(zs_), ns.assign_add(tf.cast(not_diverged,
tf.float32)))
for i in range(200): step.run()
DisplayFractal(ns.eval())
I had the same problem. You have to run the TensorFlow example in Jupyter notebook:
http://jupyter.org/
If you run it from other IDEs like (Spyder) all you will see is <IPython.core.display.Image object> in the console.
emmm,I have destroy this problem,you can take a look on my function:
def displayFractal(a,fmt='jpeg'):
a_cyclic=(6.28*a/200.0).reshape(list(a.shape)+[1])
# emmm I have changed the number. you can just continue your number
img=np.concatenate([5+10*np.cos(a_cyclic),15+25*np.sin(a_cyclic),70-40*np.cos(a_cyclic)],2)
img[a==a.max()]=0
a=img
a=np.uint8(np.clip(a,0,255))
plt.imshow(PIL.Image.fromarray(a))
plt.show()
of course you should import matplotlib .pyplot as plt at first.

Categories