★ SMILES与分子图像的转换代码、多核心将csv中的smiles转为image

1、将一个SMILES转为图像:

A:imagemol如何处理的?(推荐做训练啥的用)

(不太好,因为线太宽,然后原子和键之间的间隙太小)

不过,大多数人都是用的这种方式做的,最好我也是这样

from rdkit import Chem
from rdkit.Chem import Draw

smiles = "CCO"
mol = Chem.MolFromSmiles(smiles)
img = Draw.MolsToGridImage([mol], molsPerRow=1, subImgSize=(256, 256))
img.save("data//1.png")

 B:另外一种处理方式(推荐自己看着用)

from rdkit import Chem
from rdkit.Chem.Draw import rdMolDraw2D

def loadSmilesAndSave(opt_smiles, opt_img_save_path):

    mol = Chem.MolFromSmiles(opt_smiles)
    drawer = rdMolDraw2D.MolDraw2DCairo(256, 256)
    opts = rdMolDraw2D.MolDrawOptions()
    # 设置杆的粗细
    opts.bondLineWidth = 3
    # 设置字母的大小
    opts.minFontSize = 15
    # 设置字母与杆的间距
    opts.additionalAtomLabelPadding = 0.2

    drawer.SetDrawOptions(opts)
    rdMolDraw2D.PrepareAndDrawMolecule(drawer, mol)
    drawer.FinishDrawing()

    drawer.WriteDrawingText(opt_img_save_path)


opt_img_save_path = "./data/test.png"
opt_smiles = "CC1C=CC=CC1NC(=O)OCC2=C(OC(=C2)[O-])C"

loadSmilesAndSave(opt_smiles, opt_img_save_path)



其他用法:

其中具体的使用方法看:MolDrawOptions() 这个库中,直接在pycharm中点进去,然后搜索“bondLineWidth ”就可以看到很多的参数:

RDKit|使用MolDraw2DCairo模块绘制分子_最会设计的科研狗的博客-CSDN博客_rdkit画分子

2、多核心将csv中的smiles转为image

import argparse
import os
import pandas as pd
from tqdm import tqdm
from rdkit import Chem
from multiprocessing import Pool, cpu_count
from rdkit.Chem import Draw
import shutil
import logging

"""
当图片数量达到百万级时,单一文件夹内文件过多,文件系统索引效率会大幅下降,导致文件读写变慢。
改为每处理200万个文件的时候就换一个子文件夹储存,最终将所有的子文件夹合并在一个主文件夹内,并将所有的子文件夹删除

python utils/smiles2Image_MutiKernel_mutiDir.py \
--csvname data/XXXdata_property_clean.csv \
--outputImageDir data/XXX/images \
--theCsvFirstLineSMILES canonical_smiles --smilesName mol_index

"""

# 配置日志
logging.basicConfig(filename='error_log.txt', level=logging.ERROR)

def draw_molecule(data):
    smiles, name, args, sub_folder_path = data
    try:
        filename = f"{name}.png"
        output_img_path = os.path.join(sub_folder_path, filename)

        mol = Chem.MolFromSmiles(smiles)
        img = Draw.MolToImage(mol, size=(args.theOutputImageResolution, args.theOutputImageResolution))
        img.save(output_img_path)

    except Exception as e:
        logging.error(f"Error processing {name} with SMILES {smiles}: {e}")

def main():
    parser = argparse.ArgumentParser(description='csv2image')
    parser.add_argument('--dataroot', type=str, default="./", help='data root')
    parser.add_argument('--csvname', type=str, default="top50.csv", help='The name of CSV')
    parser.add_argument('--smilesName', type=str, default="imageName", help='Smiles的名字,一般会有一列给出这个smiles叫什么,例如1,2,3')
    parser.add_argument('--outputImageDir', type=str, default="../data/")
    parser.add_argument('--theCsvFirstLineSMILES', type=str, default="smiles", help='CSV你要转换的列名')
    parser.add_argument('--theOutputImageResolution', type=int, default=256)
    parser.add_argument('--max_files_per_folder', type=int, default=1000000)

    args = parser.parse_args()
    csv_file_path = os.path.join(args.dataroot, args.csvname)
    main_output_dir = os.path.join(args.dataroot, args.outputImageDir)

    if not os.path.exists(main_output_dir):
        os.makedirs(main_output_dir)

    df = pd.read_csv(csv_file_path)
    smiles_values = df[args.theCsvFirstLineSMILES].values
    smiles_names = df[args.smilesName].values

    # 每个子文件夹最多存储200万个文件
    max_files_per_folder = args.max_files_per_folder
    total_files = len(smiles_values)
    folder_count = (total_files // max_files_per_folder) + 1

    data = []
    for idx, (smiles, name) in enumerate(zip(smiles_values, smiles_names)):
        sub_folder_idx = idx // max_files_per_folder
        sub_folder_path = os.path.join(main_output_dir, f"sub_folder_{sub_folder_idx}")
        if not os.path.exists(sub_folder_path):
            os.makedirs(sub_folder_path)
        data.append((smiles, name, args, sub_folder_path))

    pool_size = cpu_count()
    with Pool(pool_size) as pool:
        for _ in tqdm(pool.imap_unordered(draw_molecule, data), total=len(data)):
            pass

    # 处理完毕后,将所有子文件夹内的文件移动到主文件夹,并删除子文件夹
    print("正在合并文件夹...")
    for sub_folder_idx in range(folder_count):
        sub_folder_path = os.path.join(main_output_dir, f"sub_folder_{sub_folder_idx}")
        for file_name in os.listdir(sub_folder_path):
            shutil.move(os.path.join(sub_folder_path, file_name), os.path.join(main_output_dir, file_name))
        # 删除子文件夹
        os.rmdir(sub_folder_path)

    print("所有图片处理完成,子文件夹已经合并并删除。")

if __name__ == '__main__':
    main()

对于这种在线网址的我们可以写一个脚本,让它批量的自动执行,如何自动执行?:从图片中(批量)提取化学/分子结构——使用python进行批量提取(代码示例)_鸾镜朱颜暗换的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Pengsen Ma

太谢谢了

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值