{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 下载chembl 数据库"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ChEMBL 数据库存储路径: /LillyMol/test/data/35/data/chembl_35/chembl_35_sqlite/chembl_35.db\n"
     ]
    }
   ],
   "source": [
    "import chembl_downloader\n",
    "# 指定存储目录\n",
    "prefix = '/LillyMol/test/data'\n",
    "version = chembl_downloader.latest() # version 35\n",
    "\n",
    "# 下载并提取 ChEMBL 数据库，存放到指定目录\n",
    "path = chembl_downloader.download_extract_sqlite(version=version, prefix=[prefix])\n",
    "# chembl_downloader.download_sqlite(version)\n",
    "\n",
    "print(f\"ChEMBL 数据库存储路径: {path}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "29\n"
     ]
    }
   ],
   "source": [
    "\n",
    "CID_text = '''12560\n",
    "72493\n",
    "5280440\n",
    "6436045\n",
    "6537204\n",
    "84029\n",
    "447043\n",
    "6915744\n",
    "5282211\n",
    "6473883\n",
    "3002190\n",
    "447451\n",
    "5282521\n",
    "5282165\n",
    "5289394\n",
    "49787020\n",
    "5282165\n",
    "5282322\n",
    "5282169\n",
    "5289394\n",
    "25242512\n",
    "3002190\n",
    "447451\n",
    "6441094\n",
    "9832301\n",
    "656958\n",
    "445643\n",
    "5284616\n",
    "5282071\n",
    "'''\n",
    "\n",
    "Macrocycles_CID = CID_text.splitlines()\n",
    "print(len(Macrocycles_CID))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['12560',\n",
       " '72493',\n",
       " '5280440',\n",
       " '6436045',\n",
       " '6537204',\n",
       " '84029',\n",
       " '447043',\n",
       " '6915744',\n",
       " '5282211',\n",
       " '6473883',\n",
       " '3002190',\n",
       " '447451',\n",
       " '5282521',\n",
       " '5282165',\n",
       " '5289394',\n",
       " '49787020',\n",
       " '5282165',\n",
       " '5282322',\n",
       " '5282169',\n",
       " '5289394',\n",
       " '25242512',\n",
       " '3002190',\n",
       " '447451',\n",
       " '6441094',\n",
       " '9832301',\n",
       " '656958',\n",
       " '445643',\n",
       " '5284616',\n",
       " '5282071']"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Macrocycles_CID"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "https://pypi.org/project/PubChemPy/\n",
    "\n",
    "```python\n",
    ">>> from pubchempy import get_compounds, Compound\n",
    ">>> comp = Compound.from_cid(1423)\n",
    ">>> print(comp.isomeric_smiles)\n",
    "CCCCCCCNC1CCCC1CCCCCCC(=O)O\n",
    ">>> comps = get_compounds('Aspirin', 'name')\n",
    ">>> print(comps[0].xlogp)\n",
    "1.2\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"\\n['CCC1C(C(C(C(=O)C(CC(C(C(C(C(C(=O)O1)C)OC2CC(C(C(O2)C)O)(C)OC)C)OC3C(C(CC(O3)C)N(C)C)O)(C)O)C)C)O)(C)O',\\n 'CC1CC(C(C(O1)OC2C(CC3(CO3)C(=O)C(C(C(C(OC(=O)C(C(C2C)OC4CC(C(C(O4)C)O)OC)C)C)C)O)C)C)O)N(C)C',\\n 'CCC1C(C=C(C=CC(=O)C(CC(C(C(C(CC(=O)O1)O)C)OC2C(C(C(C(O2)C)OC3CC(C(C(O3)C)O)(C)O)N(C)C)O)CC=O)C)C)COC4C(C(C(C(O4)C)O)OC)OC',\\n 'CCC(=O)OC1CC(=O)OC(CC2C(O2)C=CC(C(CC(C(C1OC)OC3C(C(C(C(O3)C)OC4CC(C(C(O4)C)OC(=O)CC)(C)O)N(C)C)O)CC=O)C)O)C',\\n 'CCC1C(C2C(O2)(C=CC(=O)C(CC(C(C(C(CC(=O)O1)O)C)OC3C(C(CC(O3)C)N(C)C)O)CC=O)C)C)C',\\n 'CCC1C(C(C(C(=O)C(CC(C(C(C(C(C(=O)O1)C)OC2CC(C(C(O2)C)O)(C)OC)C)OC3C(C(CC(O3)C)N(C)C)O)(C)OC)C)C)O)(C)O',\\n 'CCC1C(C(C(N(CC(CC(C(C(C(C(C(=O)O1)C)OC2CC(C(C(O2)C)O)(C)OC)C)OC3C(C(CC(O3)C)N(C)C)O)(C)O)C)C)C)O)(C)O',\\n 'CCC1C(C(C(C(=NOCOCCOC)C(CC(C(C(C(C(C(=O)O1)C)OC2CC(C(C(O2)C)O)(C)OC)C)OC3C(C(CC(O3)C)N(C)C)O)(C)O)C)C)O)(C)O',\\n 'CCCC(=O)OC1C(OC(CC1(C)OC(=O)CC)OC2C(OC(C(C2N(C)C)O)OC3C(CC(C(C=CC=CCC(OC(=O)CC(C3OC)O)C)O)C)CC=O)C)C',\\n 'CCC1C(C2C(C(C(CC(C(C(C(C(C(=O)O1)C)OC3CC(C(C(O3)C)O)(C)OC)C)OC4C(C(CC(O4)C)N(C)C)O)(C)O)C)NC(O2)COCCOC)C)(C)O',\\n 'CCC1C2(C(C(C(=O)C(CC(C(C(C(=O)C(C(=O)O1)C)C)OC3C(C(CC(O3)C)N(C)C)O)(C)OC)C)C)N(C(=O)O2)CCCCN4C=C(N=C4)C5=CN=CC=C5)C',\\n 'CCC1C2(C(C(C(=O)C(CC(C(C(C(=O)C(C(=O)O1)C)C)OC3C(C(CC(O3)C)N(C)C)O)(C)OCC=CC4=CC5=CC=CC=C5N=C4)C)C)NC(=O)O2)C',\\n 'CCC1C(C=C(C=CC(=O)C(CC(C(C(C(CC(=O)O1)O)C)OC2C(C(C(C(O2)C)O)N(C)C)O)CCN3CC(CC(C3)C)C)C)C)COC4C(C(C(C(O4)C)O)OC)OC',\\n 'CC1CC=CC=CC(C(CC(C(C(C(CC(=O)O1)OC(=O)C)OC)OC2C(C(C(C(O2)C)OC3CC(C(C(O3)C)OC(=O)CC(C)C)(C)O)N(C)C)O)CC=O)C)O',\\n 'CC1CC=CC=CC(C(CC(C(C(C(CC(=O)O1)O)OC)OC2C(C(C(C(O2)C)OC3CC(C(C(O3)C)O)(C)O)N(C)C)O)CC=O)C)OC4CCC(C(O4)C)N(C)C',\\n 'CC1CC=CC=CC(C(CC(C(C(C(CC(=O)O1)OC(=O)C)OC)OC2C(C(C(C(O2)C)OC3CC(C(C(O3)C)O)(C)O)N(C)C)O)CC=O)C)OC4CCC(C(O4)C)N(C)C',\\n 'CC1CC=CC=CC(C(CC(C(C(C(CC(=O)O1)OC(=O)C)OC)OC2C(C(C(C(O2)C)OC3CC(C(C(O3)C)OC(=O)CC(C)C)(C)O)N(C)C)O)CC=O)C)O',\\n 'CC1CC=CC=CC(C(CC(C(C(C(CC(=O)O1)O)OC)OC2C(C(C(C(O2)C)OC3CC(C(C(O3)C)OC(=O)CC(C)C)(C)O)N(C)C)O)CC=O)C)O',\\n 'CCC(=O)OC1CC(=O)OC(CC=CC=CC(C(CC(C(C1OC)OC2C(C(C(C(O2)C)OC3CC(C(C(O3)C)OC(=O)CC)(C)O)N(C)C)O)CC=O)C)O)C',\\n 'CC1CC=CC=CC(C(CC(C(C(C(CC(=O)O1)O)OC)OC2C(C(C(C(O2)C)OC3CC(C(C(O3)C)O)(C)O)N(C)C)O)CC=O)C)OC4CCC(C(O4)C)N(C)C',\\n 'CCC1C2(C(C(C(=O)C(CC(C(C(C(=O)C(C(=O)O1)(C)F)C)OC3C(C(CC(O3)C)N(C)C)O)(C)OC)C)C)N(C(=O)O2)CCCCN4C=C(N=N4)C5=CC(=CC=C5)N)C']\\n\""
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from rdkit import Chem\n",
    "from rdkit.Chem.Draw import IPythonConsole\n",
    "from rdkit.Chem import Draw\n",
    "from pubchempy import get_compounds, Compound\n",
    "\n",
    "def getsmiles(cid:str):\n",
    "    return Compound.from_cid(cid) # comp.isomeric_smiles\n",
    "\n",
    "SMILES_list = []\n",
    "for cid in Macrocycles_CID:\n",
    "    SMILES_list.append(getsmiles(cid.strip()).canonical_smiles)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "29"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(SMILES_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 红霉素 SMARTS 匹配测试"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 15340 characters]",
      "text/plain": [
       "<rdkit.Chem.rdchem.Mol at 0x7fea5a28f990>"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# erythromycin match\n",
    "from rdkit import Chem\n",
    "from rdkit.Chem.Draw import IPythonConsole\n",
    "from rdkit.Chem import Draw\n",
    "erythromycin = Chem.MolFromSmiles(\"CC[C@@H]1[C@@]([C@@H]([C@H](C(=O)[C@@H](C[C@@]([C@@H]([C@H]([C@@H]([C@H](C(=O)O1)C)O[C@H]2C[C@@]([C@H]([C@@H](O2)C)O)(C)OC)C)O[C@H]3[C@@H]([C@H](C[C@H](O3)C)N(C)C)O)(C)O)C)C)O)(C)O\")\n",
    "erythromycin"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((2,), (3,), (4,), (5,), (6,), (8,), (9,), (10,), (11,), (12,), (13,), (14,), (15,), (17,))\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 16896 characters]",
      "text/plain": [
       "<rdkit.Chem.rdchem.Mol at 0x7fea5a28f990>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Define SMARTS pattern with ring size > 12\n",
    "# This is an RDKit SMARTS extension\n",
    "macro = Chem.MolFromSmarts(\"[r{12-}]\")\n",
    "print(erythromycin.GetSubstructMatches(macro))\n",
    "erythromycin"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((3, 2, 17, 15, 16, 14),)\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 15992 characters]",
      "text/plain": [
       "<rdkit.Chem.rdchem.Mol at 0x7fea5a28f990>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "macro = Chem.MolFromSmarts(\"[r12,r13,r14,r15,r16,r17,r18,r19,r20]([#6][#8][#6](=[#8])[#6])\")\n",
    "print(erythromycin.GetSubstructMatches(macro))\n",
    "erythromycin"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 多种大环内酯测试看是否能够match"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/jpeg": "[encoded data, 12052 characters]",
      "image/png": "[encoded data, 20908 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 11148 characters]",
      "image/png": "[encoded data, 19456 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 10744 characters]",
      "image/png": "[encoded data, 18508 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 11456 characters]",
      "image/png": "[encoded data, 21024 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 10520 characters]",
      "image/png": "[encoded data, 18772 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 12200 characters]",
      "image/png": "[encoded data, 20976 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 11692 characters]",
      "image/png": "[encoded data, 20676 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 10056 characters]",
      "image/png": "[encoded data, 17192 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 10620 characters]",
      "image/png": "[encoded data, 18132 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 9980 characters]",
      "image/png": "[encoded data, 16960 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "()\n",
      "()\n"
     ]
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 10252 characters]",
      "image/png": "[encoded data, 17252 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 12292 characters]",
      "image/png": "[encoded data, 23384 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 9768 characters]",
      "image/png": "[encoded data, 16608 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 10280 characters]",
      "image/png": "[encoded data, 17872 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 12292 characters]",
      "image/png": "[encoded data, 23384 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 11800 characters]",
      "image/png": "[encoded data, 20700 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 12256 characters]",
      "image/png": "[encoded data, 22404 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 9768 characters]",
      "image/png": "[encoded data, 16608 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "()\n",
      "()\n",
      "()\n"
     ]
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 11680 characters]",
      "image/png": "[encoded data, 20880 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 10864 characters]",
      "image/png": "[encoded data, 18632 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "()\n",
      "()\n",
      "()\n",
      "()\n",
      "fail : 9, success: 20\n",
      "[<rdkit.Chem.rdchem.Mol object at 0x7fea592d5fc0>, <rdkit.Chem.rdchem.Mol object at 0x7fea592d5690>, <rdkit.Chem.rdchem.Mol object at 0x7fea592d55b0>, <rdkit.Chem.rdchem.Mol object at 0x7fea592d5f50>, <rdkit.Chem.rdchem.Mol object at 0x7fea592d59a0>, <rdkit.Chem.rdchem.Mol object at 0x7fea592d7c30>, <rdkit.Chem.rdchem.Mol object at 0x7fea592d7df0>, <rdkit.Chem.rdchem.Mol object at 0x7fea592d7d10>, <rdkit.Chem.rdchem.Mol object at 0x7fea592d7d80>]\n"
     ]
    }
   ],
   "source": [
    "from rdkit.Chem import Draw\n",
    "from IPython.display import display\n",
    "from rdkit import Chem\n",
    "\n",
    "# 你的 SMARTS 模式\n",
    "macro = Chem.MolFromSmarts(\"[r12,r13,r14,r15,r16,r17,r18,r19,r20]([#6][#8][#6](=[#8])[#6])\")\n",
    "\n",
    "fail = []\n",
    "success = []\n",
    "for s in SMILES_list:\n",
    "    mol = Chem.MolFromSmiles(s)\n",
    "    result = mol.GetSubstructMatches(macro)\n",
    "    \n",
    "    if result == ():\n",
    "        print(result)\n",
    "        fail.append(mol)\n",
    "    else:\n",
    "        success.append(mol)\n",
    "        \n",
    "        # 将匹配的原子索引提取出来\n",
    "        highlight_atoms = [atom_idx for match in result for atom_idx in match]\n",
    "        \n",
    "        # 生成图像并高亮显示匹配的原子\n",
    "        img = Draw.MolToImage(mol, highlightAtoms=highlight_atoms)\n",
    "        \n",
    "        # 在 Jupyter 中显示图像\n",
    "        display(img)\n",
    "\n",
    "print(f'fail : {len(fail)}, success: {len(success)}')\n",
    "print(fail)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 调整smarts 测试\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "fail : 4, success: 25\n"
     ]
    }
   ],
   "source": [
    "from rdkit.Chem import Draw\n",
    "from IPython.display import display\n",
    "from rdkit import Chem\n",
    "\n",
    "# 你的 SMARTS 模式\n",
    "macro = Chem.MolFromSmarts(\"[r12,r13,r14,r15,r16,r17,r18,r19,r20]([#6][#8][#6](=[#8]))\")\n",
    "\n",
    "fail = []\n",
    "success = []\n",
    "for s in SMILES_list:\n",
    "    mol = Chem.MolFromSmiles(s)\n",
    "    result = mol.GetSubstructMatches(macro)\n",
    "    \n",
    "    if result == ():\n",
    "        fail.append(mol)\n",
    "    else:\n",
    "        success.append(mol)\n",
    "        \n",
    "        # 将匹配的原子索引提取出来\n",
    "        highlight_atoms = [atom_idx for match in result for atom_idx in match]\n",
    "        \n",
    "        # 生成图像并高亮显示匹配的原子\n",
    "        img = Draw.MolToImage(mol, highlightAtoms=highlight_atoms)\n",
    "        \n",
    "        # 在 Jupyter 中显示图像\n",
    "        # display(img)\n",
    "\n",
    "print(f'fail : {len(fail)}, success: {len(success)}')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "fail : 4, success: 25\n"
     ]
    }
   ],
   "source": [
    "from rdkit.Chem import Draw\n",
    "from IPython.display import display\n",
    "from rdkit import Chem\n",
    "\n",
    "# 你的 SMARTS 模式\n",
    "macro = Chem.MolFromSmarts(\"[r12,r13,r14,r15,r16,r17,r18,r19,r20]([#8][#6](=[#8]))\")\n",
    "\n",
    "fail = []\n",
    "success = []\n",
    "for s in SMILES_list:\n",
    "    mol = Chem.MolFromSmiles(s)\n",
    "    result = mol.GetSubstructMatches(macro)\n",
    "    \n",
    "    if result == ():\n",
    "        fail.append(mol)\n",
    "    else:\n",
    "        success.append(mol)\n",
    "        \n",
    "        # 将匹配的原子索引提取出来\n",
    "        highlight_atoms = [atom_idx for match in result for atom_idx in match]\n",
    "        \n",
    "        # 生成图像并高亮显示匹配的原子\n",
    "        img = Draw.MolToImage(mol, highlightAtoms=highlight_atoms)\n",
    "        \n",
    "        # 在 Jupyter 中显示图像\n",
    "        # display(img)\n",
    "\n",
    "print(f'fail : {len(fail)}, success: {len(success)}')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<rdkit.Chem.rdchem.Mol at 0x7fea592d4f90>,\n",
       " <rdkit.Chem.rdchem.Mol at 0x7fea592d5460>,\n",
       " <rdkit.Chem.rdchem.Mol at 0x7fea592d54d0>,\n",
       " <rdkit.Chem.rdchem.Mol at 0x7fea592d6180>]"
      ]
     },
     "execution_count": 29,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fail"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/jpeg": "[encoded data, 8440 characters]",
      "image/png": "[encoded data, 14148 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 10340 characters]",
      "image/png": "[encoded data, 17804 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 10812 characters]",
      "image/png": "[encoded data, 19384 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 10172 characters]",
      "image/png": "[encoded data, 17516 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "for mol in fail:\n",
    "    img = Draw.MolToImage(mol, highlightAtoms=highlight_atoms)\n",
    "    display(img)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/jpeg": "[encoded data, 8228 characters]",
      "image/png": "[encoded data, 12752 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 10208 characters]",
      "image/png": "[encoded data, 17192 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 10816 characters]",
      "image/png": "[encoded data, 18892 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 10060 characters]",
      "image/png": "[encoded data, 16740 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from rdkit.Chem import Draw\n",
    "from IPython.display import display\n",
    "\n",
    "for mol in fail:\n",
    "    img = Draw.MolToImage(mol)  # 生成图像\n",
    "    display(img)  # 在 Jupyter 中显示图像\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "from rdkit.Chem import Draw\n",
    "from rdkit import Chem\n",
    "\n",
    "# 定义 SMARTS 模式\n",
    "macro = Chem.MolFromSmarts(\"[r12,r13,r14,r15,r16,r17,r18,r19,r20]([#8][#6](=[#8]))\")\n",
    "\n",
    "# 读取 SMI 文件\n",
    "smi_file = \"/home/mambauser/LillyMol/test/1M_stratsampled_V1B.smi\"\n",
    "with open(smi_file, 'r') as f:\n",
    "    SMILES_list = [line.strip() for line in f if line.strip()]\n",
    "\n",
    "fail = []\n",
    "success = []\n",
    "\n",
    "# 遍历每个 SMILES\n",
    "for s in SMILES_list:\n",
    "    mol = Chem.MolFromSmiles(s)\n",
    "    if mol is None:\n",
    "        continue  # 跳过无效的 SMILES\n",
    "    \n",
    "    result = mol.GetSubstructMatches(macro)\n",
    "    if result == ():\n",
    "        fail.append(mol)\n",
    "    else:\n",
    "        success.append(mol)\n",
    "\n",
    "# 统计匹配结果\n",
    "total = len(success) + len(fail)\n",
    "success_rate = len(success) / total * 100 if total > 0 else 0\n",
    "\n",
    "print(f\"Total molecules: {total}\")\n",
    "print(f\"Success: {len(success)}\")\n",
    "print(f\"Fail: {len(fail)}\")\n",
    "print(f\"Success rate: {success_rate:.2f}%\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "ename": "",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m在当前单元格或上一个单元格中执行代码时 Kernel 崩溃。\n",
      "\u001b[1;31m请查看单元格中的代码，以确定故障的可能原因。\n",
      "\u001b[1;31m单击<a href='https://aka.ms/vscodeJupyterKernelCrash'>此处</a>了解详细信息。\n",
      "\u001b[1;31m有关更多详细信息，请查看 Jupyter <a href='command:jupyter.viewOutput'>log</a>。"
     ]
    }
   ],
   "source": [
    "from rdkit import Chem\n",
    "from joblib import Parallel, delayed\n",
    "\n",
    "# 定义 SMARTS 模式\n",
    "macro = Chem.MolFromSmarts(\"[r12,r13,r14,r15,r16,r17,r18,r19,r20]([#8][#6](=[#8]))\")\n",
    "\n",
    "# 读取 SMI 文件\n",
    "smi_file = \"/home/mambauser/LillyMol/test/1M_stratsampled_V1B.smi\"\n",
    "with open(smi_file, 'r') as f:\n",
    "    SMILES_list = [line.strip() for line in f if line.strip()]\n",
    "\n",
    "# 匹配函数\n",
    "def match_smarts(smiles):\n",
    "    mol = Chem.MolFromSmiles(smiles)\n",
    "    if mol is None:\n",
    "        return None, None  # 无效分子\n",
    "    result = mol.GetSubstructMatches(macro)\n",
    "    return mol, result\n",
    "\n",
    "# 使用 joblib 并行处理\n",
    "results = Parallel(n_jobs=-1)(delayed(match_smarts)(s) for s in SMILES_list)\n",
    "\n",
    "# 分离成功和失败的分子\n",
    "success = [mol for mol, result in results if result and mol is not None]\n",
    "fail = [mol for mol, result in results if not result and mol is not None]\n",
    "\n",
    "# 统计结果\n",
    "total = len(success) + len(fail)\n",
    "success_rate = len(success) / total * 100 if total > 0 else 0\n",
    "\n",
    "print(f\"Total molecules: {total}\")\n",
    "print(f\"Success: {len(success)}\")\n",
    "print(f\"Fail: {len(fail)}\")\n",
    "print(f\"Success rate: {success_rate:.2f}%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SMARTS 结构有效！\n"
     ]
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 6616 characters]",
      "image/png": "[encoded data, 7224 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from rdkit import Chem\n",
    "smarts = '[r12,r13,r14,r15,r16,r17,r18,r19,r20]C1OC(=O)C1'\n",
    "mol = Chem.MolFromSmarts(smarts)\n",
    "\n",
    "if mol:\n",
    "    print(\"SMARTS 结构有效！\")\n",
    "else:\n",
    "    print(\"SMARTS 结构无效！\")\n",
    "\n",
    "# 可视化\n",
    "from rdkit.Chem import Draw\n",
    "Draw.MolToImage(mol)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SMARTS 结构有效！\n"
     ]
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 6536 characters]",
      "image/png": "[encoded data, 9624 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from rdkit import Chem\n",
    "\n",
    "# smarts = '[r;!r3;!r4;!r5;!r6;!r7;!r8;!r9;!r10;!r11]([C]~[C]~[C]~[C]~[C]~[C]~[C]~[C]~[C]~[C]~[C]~[C]~[C]~[C][#8][C]=[#8]@[C])'  # 你的 SMARTS\n",
    "smarts = '[r12,r13,r14,r15,r16,r17,r18,r19,r20]([#6][#8][#6](=[#8])[#6])'\n",
    "mol = Chem.MolFromSmarts(smarts)\n",
    "\n",
    "if mol:\n",
    "    print(\"SMARTS 结构有效！\")\n",
    "else:\n",
    "    print(\"SMARTS 结构无效！\")\n",
    "\n",
    "# 可视化\n",
    "from rdkit.Chem import Draw\n",
    "Draw.MolToImage(mol)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((3, 2, 17, 15, 16, 14),)\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 15992 characters]",
      "text/plain": [
       "<rdkit.Chem.rdchem.Mol at 0x7f3050f94890>"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "macro = Chem.MolFromSmarts(\"[r12,r13,r14,r15,r16,r17,r18,r19,r20]([#6][#8][#6](=[#8])[#6])\")\n",
    "print(erythromycin.GetSubstructMatches(macro))\n",
    "erythromycin"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SMARTS 结构有效！\n"
     ]
    },
    {
     "data": {
      "image/jpeg": "[encoded data, 6488 characters]",
      "image/png": "[encoded data, 9576 characters]",
      "text/plain": [
       "<PIL.PngImagePlugin.PngImageFile image mode=RGB size=300x300>"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from rdkit import Chem\n",
    "\n",
    "# smarts = '[r;!r3;!r4;!r5;!r6;!r7;!r8;!r9;!r10;!r11]([C]~[C]~[C]~[C]~[C]~[C]~[C]~[C]~[C]~[C]~[C]~[C]~[C]~[C][#8][C]=[#8]@[C])'  # 你的 SMARTS\n",
    "smarts = '[r12,r13,r14,r15,r16,r17,r18,r19,r20]([#8][#6](=[#8]))'\n",
    "mol = Chem.MolFromSmarts(smarts)\n",
    "\n",
    "if mol:\n",
    "    print(\"SMARTS 结构有效！\")\n",
    "else:\n",
    "    print(\"SMARTS 结构无效！\")\n",
    "\n",
    "# 可视化\n",
    "from rdkit.Chem import Draw\n",
    "Draw.MolToImage(mol)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((2, 17, 15, 16),)\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 15716 characters]",
      "text/plain": [
       "<rdkit.Chem.rdchem.Mol at 0x7f3050f94890>"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "macro = Chem.MolFromSmarts(smarts)\n",
    "print(erythromycin.GetSubstructMatches(macro))\n",
    "erythromycin"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "lillymol",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.16"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
