From a5787acf52f28200fb75ab8a7571043eeec80ddc Mon Sep 17 00:00:00 2001 From: Heta Gandhi Date: Sat, 7 May 2022 19:25:47 -0400 Subject: [PATCH 01/26] Groomed solubility notebook for docs website --- exmol/exmol.py | 11 +- exmol/lime_data/MACCSkeys.txt | 8 +- paper2_LIME/Solubility-RNN.ipynb | 218 ++++++++++++------------------- 3 files changed, 95 insertions(+), 142 deletions(-) diff --git a/exmol/exmol.py b/exmol/exmol.py index 625641e2..25721058 100644 --- a/exmol/exmol.py +++ b/exmol/exmol.py @@ -834,6 +834,7 @@ def plot_descriptors( fig: Any = None, figure_kwargs: Dict = None, output_file: str = None, + title: str = None, ): """Plot descriptor attributions from given set of Examples are space_tstats @@ -843,6 +844,7 @@ def plot_descriptors( :param fig: Figure to plot on to :param figure_kwargs: kwargs to pass to :func:`plt.figure` :param output_file: Output file name to save the plot + :param title: Title for the plot """ from importlib_resources import files import exmol.lime_data @@ -918,7 +920,7 @@ def plot_descriptors( for rect, ti, k, ki in zip(bar1, t, keys, key_ids): # annotate patches with text desciption y = rect.get_y() + rect.get_height() / 2.0 - k = textwrap.fill(str(k), 25) + k = textwrap.fill(str(k), 20) if ti < 0: x = 0.25 skx = ( @@ -994,14 +996,17 @@ def plot_descriptors( ax.set_yticks([]) ax.invert_yaxis() ax.set_xlabel("Descriptor t-statistics", fontsize=12) - ax.set_title(f"{descriptor_type} descriptors", fontsize=12) + if title is None: + ax.set_title(f"{descriptor_type} descriptors", fontsize=12) + else: + ax.set_title(f"{title}", fontsize=12) # inset SMARTS svg images for MACCS descriptors if descriptor_type == "MACCS" or descriptor_type == "ECFP": if descriptor_type == "MACCS": print( "SMARTS annotations for MACCS descriptors were created using SMARTSviewer (smartsview.zbh.uni-hamburg.de, Copyright: ZBH, Center for Bioinformatics Hamburg) developed by K. Schomburg et. al. (J. Chem. Inf. Model. 2010, 50, 9, 1529–1535)" ) - xlim = np.max(np.absolute(t)) + 5 + xlim = np.max(np.absolute(t)) + 6 ax.set_xlim(-xlim, xlim) svg = skunk.insert(sk_dict) plt.tight_layout() diff --git a/exmol/lime_data/MACCSkeys.txt b/exmol/lime_data/MACCSkeys.txt index d3c5053e..47caa0b3 100644 --- a/exmol/lime_data/MACCSkeys.txt +++ b/exmol/lime_data/MACCSkeys.txt @@ -61,7 +61,7 @@ KeyID SMARTS KeyDescription 59 [#16]!:*:* Is there an atom bonded to S by a non-aromatic ring bond and bonded to another atom aromatically? 60 [#16]=[#8] Is there an S=O double bond? 61 *~[#16](~*)~* Is there an S bonded to at least three neighbors? -62 *@*!@*@* Is there an atom at a ring/chain boundary? When a comparison is done with another atom the path passes through the chain bond. +62 *@*!@*@* Is there an atom at a ring/chain boundary? The path passes through the chain bond. 63 [#7]=[#8] Is there an N=O, nitroso group? 64 *@*!@[#16] Is there an atom bonded to another atom by an aromatic bond and bonded to an S by a non-aromatic bond? 65 c:n Is there an aromatic bond between an aromatic C and aromatic N? @@ -105,7 +105,7 @@ KeyID SMARTS KeyDescription 103 Cl Is there a Cl atom? 104 [!#6;!#1;!H0]~*~[CH2]~* Is there a heteroatom separated from a CH2 group by any two bonds? 105 *@*(@*)@* Is there an atom with more than two ring bonds? -106 [!#6;!#1]~*(~[!#6;!#1])~[!#6;!#1] Is there an atom with at least three heteroatom neighbors? +106 [!#6;!#1]~*(~[!#6;!#1])~[!#6;!#1] Is there an atom with three heteroatom neighbors? 107 [F,Cl,Br,I]~*(~*)~* Is there an atom bonded to 3 other atoms, one of which is a halogen? 108 [CH3]~*~*~*~[CH2]~* Is there a CH3 group separated from a CH2 group by any four bonds? 109 *~[CH2]~[#8] Is there an oxymethylene group (-CH2O-)? @@ -147,9 +147,9 @@ KeyID SMARTS KeyDescription 145 *1~*~*~*~*~*~1 Is there more than one 6M ring? 146 [#8] Are there more than two O atoms? 147 [$(*~[CH2]~[CH2]~*),$([R]1@[CH2;R]@[CH2;R]1)] Are there two CH2 groups bonded by a single bond? -148 *~[!#6;!#1](~*)~* Is there an atom bonded to at least three neighbors, at least one of which is a heteroatom? +148 *~[!#6;!#1](~*)~* Is there a heteroatom bonded to at least three neighbors? 149 [C;H3,H4] Is there multiple methyl groups? -150 *!@*@*!@* Is there an atom at a ring/chain boundary? +150 *!@*@*!@* Is there an atom at a ring/chain boundary? The path passes through the ring bond. 151 [#7;!H0] Is there an N bonded to at least one H? 152 [#8]~[#6](~[#6])~[#6] Is there an O bonded to a secondary C? 153 [!#6;!#1]~[CH2]~* Is there a CH2 group bonded to two neighbors, at least one of which is a heteroatom? diff --git a/paper2_LIME/Solubility-RNN.ipynb b/paper2_LIME/Solubility-RNN.ipynb index 56aab220..d623c88d 100644 --- a/paper2_LIME/Solubility-RNN.ipynb +++ b/paper2_LIME/Solubility-RNN.ipynb @@ -1,5 +1,19 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# LIME paper: Recurrent Neural Network for Solubility Prediciton" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Import packages and set up RNN" + ] + }, { "cell_type": "code", "execution_count": null, @@ -41,7 +55,7 @@ ")\n", "color_cycle = [\"#F06060\", \"#1BBC9B\", \"#F06060\", \"#5C4B51\", \"#F3B562\", \"#6e5687\"]\n", "mpl.rcParams[\"axes.prop_cycle\"] = mpl.cycler(color=color_cycle)\n", - "mpl.rcParams[\"font.size\"] = 12\n", + "mpl.rcParams[\"font.size\"] = 10\n", "soldata = pd.read_csv(\n", " \"https://github.com/whitead/dmol-book/raw/master/data/curated-solubility-dataset.csv\"\n", ")\n", @@ -212,7 +226,8 @@ "outputs": [], "source": [ "model.compile(tf.optimizers.Adam(1e-4), loss=\"mean_squared_error\")\n", - "result = model.fit(train_data, validation_data=val_data, epochs=100, verbose=2)" + "# verbose=0 silences output, to get progress bar set verbose=1\n", + "result = model.fit(train_data, validation_data=val_data, epochs=100, verbose=0)" ] }, { @@ -287,7 +302,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Define functions used for this method" + "### Wrapper function for RNN, to use in STONED" ] }, { @@ -307,44 +322,11 @@ " return labels * valid" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Gives indices for descriptor names\n", - "def feature_dict(space):\n", - " features = {\n", - " a: b\n", - " for a, b in zip(\n", - " space[0].descriptors.descriptor_names,\n", - " np.arange(len(space[0].descriptors.descriptors)),\n", - " )\n", - " }\n", - " return features" - ] - }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Plot WLS Fit and show which descriptors matter for an instance" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Make sure SMILES doesn't contain multiple fragments\n", - "for i in soldata.SMILES:\n", - " if \".\" in i:\n", - " continue\n", - " smi = i\n", - " break\n", - "MolFromSmiles(smi)" + "### Descriptor explanations" ] }, { @@ -355,12 +337,16 @@ }, "outputs": [], "source": [ + "# Make sure SMILES doesn't contain multiple fragments\n", + "smi = soldata.SMILES[0]\n", "stoned_kwargs = {\n", " \"num_samples\": 2500,\n", " \"alphabet\": exmol.get_basic_alphabet(),\n", " \"max_mutations\": 1,\n", "}\n", - "space = exmol.sample_space(smi, predictor_function, stoned_kwargs=stoned_kwargs)" + "space = exmol.sample_space(\n", + " smi, predictor_function, stoned_kwargs=stoned_kwargs, quiet=True\n", + ")" ] }, { @@ -371,17 +357,18 @@ }, "outputs": [], "source": [ - "import scipy.stats as ss\n", - "\n", - "%matplotlib inline\n", + "from IPython.display import display, SVG\n", "\n", "desc_type = [\"Classic\", \"ECFP\", \"MACCS\"]\n", "\n", "for d in desc_type:\n", " beta = exmol.lime_explain(space, descriptor_type=d)\n", - " exmol.plot_descriptors(space, d)\n", - "\n", - "plt.show()" + " if d == \"Classic\":\n", + " exmol.plot_descriptors(space, d, output_file=f\"plots/{d}.svg\")\n", + " else:\n", + " svg = exmol.plot_descriptors(space, d, output_file=f\"plots/{d}.svg\")\n", + " plt.close()\n", + " skunk.display(svg)" ] }, { @@ -427,7 +414,7 @@ "higher = np.max(ys)\n", "\n", "# set transparency using w\n", - "normalizer = plt.Normalize(min(w), max(w))\n", + "norm = plt.Normalize(min(w), max(w))\n", "cmap = plt.cm.Oranges(w)\n", "cmap[:, -1] = w\n", "\n", @@ -459,21 +446,13 @@ "ax_dict[\"A\"].set_xlim(lower, higher)\n", "ax_dict[\"A\"].set_ylim(lower, higher)\n", "ax_dict[\"A\"].set_aspect(1.0 / ax_dict[\"A\"].get_data_ratio(), adjustable=\"box\")\n", - "cbar = plt.colorbar(sc, orientation=\"horizontal\", pad=0.15, ax=ax_dict[\"A\"])\n", + "sm = plt.cm.ScalarMappable(cmap=plt.cm.Oranges, norm=norm)\n", + "cbar = plt.colorbar(sm, orientation=\"horizontal\", pad=0.15, ax=ax_dict[\"A\"])\n", "cbar.set_label(\"Chemical similarity\")\n", "plt.tight_layout()\n", "plt.savefig(\"weighted_fit.svg\", dpi=300, bbox_inches=\"tight\", transparent=False)" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.cm.Oranges" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -483,13 +462,6 @@ "We first sample a reference chemical space, and then subsample smaller chemical spaces from this reference. Rank correlation is computed between important descriptors for the smaller subspaces and the reference space." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Get descriptor attributions for the reference space" - ] - }, { "cell_type": "code", "execution_count": null, @@ -502,7 +474,9 @@ " \"alphabet\": exmol.get_basic_alphabet(),\n", " \"max_mutations\": 2,\n", "}\n", - "space = exmol.sample_space(smi, predictor_function, stoned_kwargs=stoned_kwargs)\n", + "space = exmol.sample_space(\n", + " smi, predictor_function, stoned_kwargs=stoned_kwargs, quiet=True\n", + ")\n", "len(space)" ] }, @@ -522,8 +496,14 @@ "metadata": {}, "outputs": [], "source": [ - "# Get feature ids\n", - "features = feature_dict(space)" + "# Assign feature ids for rank comparison\n", + "features = features = {\n", + " a: b\n", + " for a, b in zip(\n", + " space[0].descriptors.descriptor_names,\n", + " np.arange(len(space[0].descriptors.descriptors)),\n", + " )\n", + "}" ] }, { @@ -532,7 +512,7 @@ "metadata": {}, "outputs": [], "source": [ - "# Get reference set of ranks for the above space\n", + "# Get set of ranks for the reference space\n", "baseline_imp = {\n", " a: b\n", " for a, b in zip(space[0].descriptors.descriptor_names, space[0].descriptors.tstats)\n", @@ -555,7 +535,6 @@ "# Get subsets and calculate lime importances - subsample - get rank correlation\n", "from scipy.stats import spearmanr\n", "\n", - "print(\"Baseline (full space):\", baseline_set[:5])\n", "plt.figure(figsize=(4, 3))\n", "N = len(space)\n", "size = np.arange(500, N, 1000)\n", @@ -564,6 +543,7 @@ " # subsample space\n", " rank_corr[f] = []\n", " for _ in range(10):\n", + " # subsample space of size f\n", " idx = np.random.choice(np.arange(N), size=f, replace=False)\n", " subspace = [space[i] for i in idx]\n", " # get desc attributions\n", @@ -579,12 +559,11 @@ " sorted(ss_imp.items(), key=lambda item: abs(item[1]), reverse=True)\n", " )\n", " ss_set = [features[x] for x in ss_imp.keys()]\n", - " # Get ranks for baseline and subsampled space\n", + " # Get ranks for subsampled space and compare with reference\n", " ranks = {a: [b] for a, b in zip(baseline_set[:5], np.arange(1, 6))}\n", " for j, s in enumerate(ss_set):\n", " if s in ranks:\n", " ranks[s].append(j + 1)\n", - " print(ranks)\n", " # compute rank correlation\n", " r = spearmanr(np.arange(1, 6), [ranks[x][1] for x in ranks])\n", " rank_corr[f].append(r.correlation)\n", @@ -610,13 +589,12 @@ "cell_type": "code", "execution_count": null, "metadata": { - "scrolled": true + "scrolled": false }, "outputs": [], "source": [ "# Mutation\n", - "\n", - "desc_type = [\"Classic\", \"MACCS\"]\n", + "desc_type = [\"Classic\"]\n", "muts = [1, 2, 3]\n", "for i in muts:\n", " stoned_kwargs = {\n", @@ -625,62 +603,42 @@ " \"min_mutations\": i,\n", " \"max_mutations\": i,\n", " }\n", - " space = exmol.sample_space(smi, predictor_function, stoned_kwargs=stoned_kwargs)\n", + " space = exmol.sample_space(\n", + " smi, predictor_function, stoned_kwargs=stoned_kwargs, quiet=True\n", + " )\n", " for d in desc_type:\n", - " # get sample t-stats\n", " exmol.lime_explain(space, descriptor_type=d)\n", - " exmol.plot_descriptors(space, d, output_file=f\"desc_{d}_mut{i}.svg\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "fig, axs = plt.subplots(1, 3, figsize=(8, 3), dpi=180, squeeze=True, sharey=True)\n", - "smi = soldata.SMILES[5]\n", - "for i, n in enumerate([1, 2, 3]):\n", - " stoned_kwargs = {\n", - " \"num_samples\": 2500,\n", - " \"alphabet\": exmol.get_basic_alphabet(),\n", - " \"min_mutations\": n,\n", - " \"max_mutations\": n,\n", - " }\n", - " space = exmol.sample_space(smi, predictor_function, stoned_kwargs=stoned_kwargs)\n", - " axs[i].hist(\n", - " [e.similarity for e in space[1:]], bins=99, edgecolor=\"none\", label=d, alpha=0.6\n", - " )\n", - " axs[i].set_title(f\"Mutations = {n}\")\n", - " axs[i].set_xlim(0, 1)\n", - "# plt.legend()\n", - "plt.tight_layout()\n", - "plt.savefig(\"rnn-mutation-hist.png\", bbox_inches=\"tight\", dpi=180)" + " exmol.plot_descriptors(\n", + " space, d, output_file=f\"desc_{d}_mut{i}.svg\", title=f\"Mutations={i}\"\n", + " )" ] }, { "cell_type": "code", "execution_count": null, "metadata": { - "scrolled": true + "scrolled": false }, "outputs": [], "source": [ "# Alphabet\n", - "\n", "basic = exmol.get_basic_alphabet()\n", "train = sf.get_alphabet_from_selfies([s for s in selfies_list if s is not None])\n", "wide = sf.get_semantic_robust_alphabet()\n", - "desc_type = [\"Classic\", \"MACCS\"]\n", + "desc_type = [\"MACCS\"]\n", "alphs = {\"Basic\": basic, \"Training Data\": train, \"SELFIES\": wide}\n", - "\n", "for a in alphs:\n", " stoned_kwargs = {\"num_samples\": 2500, \"alphabet\": alphs[a], \"max_mutations\": 2}\n", - " space = exmol.sample_space(smi, predictor_function, stoned_kwargs=stoned_kwargs)\n", + " space = exmol.sample_space(\n", + " smi, predictor_function, stoned_kwargs=stoned_kwargs, quiet=True\n", + " )\n", " for d in desc_type:\n", - " # get sample t-stats\n", " exmol.lime_explain(space, descriptor_type=d)\n", - " exmol.plot_descriptors(space, d, output_file=f\"desc_{d}_alph_{a}.svg\")" + " svg = exmol.plot_descriptors(\n", + " space, d, output_file=f\"desc_{d}_alph_{a}.svg\", title=f\"Alphabet: {a}\"\n", + " )\n", + " plt.close()\n", + " skunk.display(svg)" ] }, { @@ -690,38 +648,27 @@ "outputs": [], "source": [ "# Size of space\n", - "\n", - "tstats, beta = {\"Classic\": [], \"MACCS\": []}, {\"Classic\": [], \"MACCS\": []}\n", - "spaces = {\"Classic\": [], \"MACCS\": []}\n", - "desc_type = [\"Classic\", \"MACCS\"]\n", + "desc_type = [\"MACCS\"]\n", "space_size = [1500, 2000, 2500]\n", - "\n", - "for a in space_size:\n", + "for s in space_size:\n", " stoned_kwargs = {\n", - " \"num_samples\": a,\n", + " \"num_samples\": s,\n", " \"alphabet\": exmol.get_basic_alphabet(),\n", " \"max_mutations\": 2,\n", " }\n", - " space = exmol.sample_space(smi, predictor_function, stoned_kwargs=stoned_kwargs)\n", + " space = exmol.sample_space(\n", + " smi, predictor_function, stoned_kwargs=stoned_kwargs, quiet=True\n", + " )\n", " for d in desc_type:\n", " exmol.lime_explain(space, descriptor_type=d)\n", - " exmol.plot_descriptors(space, d, output_file=f\"desc_{d}_size_{a}.svg\")" - ] - }, - { - "attachments": { - "image.png": { - "image/png": "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e2+44YYpTYGXh0ImF9LAiy+++N133xUXF0M5YMCAgN8we+QDkj777LOPPvqIwM4777zDDjtAA+OH5RPz888/v/zyyxUVFVtsscWee+5ZUlKSUoUehYAQEAJCQAgIgcZBIEkfMHv27D322OOCCy74/vvvH3744Z122unRRx91df5ugxAF4OInnnjiKaec8u677z755JNDhw59/vnno7EoQkBVVdU111yz//77E/P6668PHz78hhtuQIsQDocRBf73v/8NHjz46aeffvvtt0866aRTTz11yZIlpLqFJwUa8hFcd6OgG0gqSg9CQAgIASEgBIRAGgJJcsD111//ww8/wKGfeuqpTz/9FBZ+2WWXLVi4AP7tZrQ8+4knnnjppZeeffbZ9957j3X/scce+9e//nXhwoVQTpgw4VbnGjt2LKlXXXXVTTfd9M0332AFmDZt2sUXX4wAMWbMGJIQMpAhXn3lVbdwjAS+QBH6BlOjp9IEQbaQ00AkACs55FAU4FvD7p+tnMd4Ndkao3ghIASEgBAQAmsegYxr7NTIJDkgEomcccYZ/fv3hw3DtpEDFi1aNHfuXG9f8BjAv+/xxx8fNGjQkCFDSGrZsuW5556LGuDdd97lEeGgY8eO5MUKgDng9NNP79Sp06hRo0j68MMPUSSgRSA+GAxiTdh2220ffOhBjAWkmsvw/pqQH4/CGiMTOCcdOJsbk9rpkK6BGxKADidYA7irSiEgBISAEFhFBFK4fsqjKTSJv954440j/m8EEgAsPBqJvvrqq23btoWLe2u3mv9JkyZtueWWGAi4SIXxl5eXjx03ljBr/b59+5IRcQF5AimhZ8+eKAlg9uPGjWvTps0GG2xgKg4EsDggTGCDqKysNAoALgwEVBypCQXiRwMSS6szNNxQ6xICQkAICAEhIARWC4G4HGDZcFlZGWx+6dKl11133W6774Z14M4770yRA2DnLP3nzZvXuXNn167fokUL+D2aA8qZMWNGly5dCLDoh9kT4HHx4sVkxOhAaaj9bUbqQkRACCDJNsAX8y36fer0qb+bPjkSBv87AsJqdVKZhYAQEAJCQAgIgYwImN19NsEN4Lj37bffwphRDLzyyito8t0kKIkkCVGgVatW2BGIgalzQbNixQqcAYlEGWD1BKz4iScMARmxBaAPsDGW8dvNAhBwmWb4/W3bt2vfrh3l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PBz9nXfe6dGjB1qB++6/79prr0WkIHXAgAH333//RhttRPlICe+9994FF1wwY8YM9AFkufvuu/fcc09vrxK7/laukvDmy3uYLw4n2pb32lSBEBACQkAICIG8I5DkHwD/vuiii8aOHfv4449/8cUXBJADTj311OnTp3sbAsvnmjRp0uzZs48++uiRI0feeOON3P/+97+3bt0aynHjxlHOscceCw3lUOxpp52GVEESWY477riBAwd++eWXn3zyCZLESSedhO6BJMj454vGYLeUb2tMOCDY52x3R2JgU5/NlsPdfTTG/bOV8xivJltjFC8EhIAQEAJCoIkgkKQPmDt37iuvvHLxxRezQIcTd+zY8a677tpss83eeuutE044gdW8y57p3U8//cQdBt+nTx+SCLPWDwaM5v+ee+7p1avX3/72N8SC9u3b33777UOHDv3444/32muvUaNGQfDPf/6zS5cumA/uvPPODTfckEgqNY4FhoHHioqC0WiN56yeJGGF7Bkvslq6HAoBGStSpBAQAkJACAiBZoNAEovt2KHjc889d8wxx7A0h7VzobovLi7G4d9KANyJtOHPP/+8VatWmA8mT5783Xffof+Hr+P9t2zZMnQAm2++ecuWLYEJ+n79+iFSfPDBBwgKSANIALgFUCzltG3bFjngjTfeMMoALkSBIOvtSCDI0j6uEmg2WKsjQkAICAEhIAQKDYEkOQA/vl122aV79+4szS1jvvfee3ED3HHHHWNRw5Vh6u79xx9/hPcfeOCBu+666/bbbw/N+PHjEQWgx/a/3nrrmfW9c+EkiEwwbdo0nqZMmYL+wMbbWvAnwCnBuhz6wjXLMBLMnG4qcjcsSA9v8dJdCAgBISAEhECuEUiSA+DrdsVPLZFIZPTo0ffdd9+ZZ5656aabuq7+tgE4AOIEALfGLoDVAEocBg855BC7CwAZAu5OUVaYYN8gWwmsfwDagg4dOqAYYEMBqSQhDaB1oFijZggES7nKSk1YlxAQAkJACAgBIZBnBJL8A9DV2+rg0A899ND555/BLKW5AABAAElEQVR/+OGHX3PNNeltYDfg22+/jRzAup/7Jptsss4666AYePTRR8877zy7iYB42DksHyWBZfaW35OXgFUGQAPfpzpoTO3RmlC7dq1btSXZ2AWM9gEtRHr9ihECQkAICAEhIARygECSHGDL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c5s2be65554OHTqQVF5eftBBB30+4XPUAw8++OC0adNefPHFPn36kNS9e/etttqKGs8991yjZjBlsznP2aePJ0HQh9kgs6gCofdyGsWmPuvFSCBXDBven3KZGP7iMKQk6rFeCFj7EVqluqkZTgw/iK3o6b2T0Y5MS8OjG4A+Fo25+qe6q1CqEBACQmAtRyB1Ip4+ffpVV1118skns1hHDsAJIAUgO/kSic4AWaFTp06LFy+eP38+ZgIiSV22bNkXX3yBzr9tm7boAIjENNCuXbtXX32Vdf/HH3/ctWvXHj162GLXXXfdAQMGvP/e+7gXmJJh47FIMOiPRKp9tQKHIwmkttNm997dnf1uwJuqcIEgYCVFJICVCgE02PqWQsnYMMOjVtwk7HqWEHbHnu0j9BICCuR1qxlCQAgUPgKp+gAY8+eff96rV68ff/yRWRh9gFmme9ZtdjomEo6OHHD22Wd/9tlnkOEi8M9//nODDTagz1OmTNlzzz0JMB0z77dv3760tJQCS0pKkB569+6NmyGpJBHo0qULdoT4Yo65vqY6HKksCZYYmcBxLTSLby6tvx0Ymsftgw8+wK6E40jG7iAUPv3001idEB9xJRk0aJB5/34/AxIb0yuvvLJo0aL11lsPJVO3bt0YnEirb7zxBo4m0PAIGbLmsccem7FwRQoBISAEhIAXgdR1NowZIQAKOD1sm0evEODmRO8KR//jjz+YiO+4444zzzxzzJgxBx54IJM7izOcADp37hwIBiiELOgVkAOYncnFBgTkALg+F0ncW7dujRhhZA6UB+HqedOmTp8xlfrZWuBWp0CzQQBWPX78eLxP3nzzzWydwtfkmmuuKSsrmzx5Mq4nr7/+Oqt/hsqzzz6LDwoGKeSDRx55ZJdddvnll18YY6Ree+21119//Q033MD9xhtvfOihh+wAy1aF4oWAEBACQsAikKoPsMt9mwZ7xqEvI1IYYG+55RYM/4N3HMyif79998MQwPrsgQceOP300xEdkCG8EzExlByJUqRxOEAgCITMBkJEBLYXUgV3o8uNFnXs3G3p4iXRiGMjsDoAaQIyvoMmGIlh6KmnnrrwwgsXLFjASEjpAeOBsfH8888jU3744YebbropMiUi5ogRI9iZUrG84sorrzzllFNg9mQ877zzhg4detttt919991Lli2ZMWPGv/71r0MO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wLm5WfhpLJR2/fXX//bbb7WMGG7CCkjjzd3wXP2Cv1/PLgSkRPy1ItF20ABOPPFELrfdcMMNR4wYMW3aNG614ZMKOWHChIicsFs2A2htR9w7DC2Wz1D61Vdf3X333UcfffSKK65o/cvIoZWTmmZraVOaYbEITOdaLIhtDMdyrYn5wlxtzJ999tlpp522wgor3HDDDeXVti2lWlFef/315557Tq/sxAfHmmuuucUWWzCAtjGb7mjLytcIVnReZ5999tVXX7355pvvt99+yyyzzBdffHHllVcifp588sl11123jIpM69tPP/206qqrYnPu1q0bb2QM/vPmzVtllVXovygyuIGRQI3S1Oo2Lgh/O2pK1tyExk2pM2fOlOOBrR5g7AFbb731Iw8/gmmqKXD8daC58f1pm+L201goPgVBKaBuYlmLyYGe8uDeYMMNVlppJdyFEpamPyR/+eWX9Abcdn/zzTcPHjxYZwSwsR122GGTJk3iensEJ55lQRpN5vPPP19vvfX+9a9/IfKV59pYHn300b322uutt95itFCaZdEUrBYtWkR/zvBgwIABbVoiMLGzPbRzjjU9/fTTq6ure/TowXCT6lW+TEBedu3adTnzLLvssvzFgIl0QXBCFKQ16ykFPoDwQw89RN90xhln+JGnR6N5MNZEGygFPJuIA8ZzYk6dOhUZf8ghhzAOY5pjwYIFv/32G2SirtHsEavEUWKbCLZ9o4Ew+7b32GOP7777jgE01PH+5ptvvv76a7Z0gxuanL/smuJuX4o099VXX32zzTajyEAYH31rUK5PKSDcOA70dZgxuLaOw9ksOUoIMwXLL7/8TTfd1DiEEglVnCkXxm/02+g0ipgtlIcffpghEHpAiSDcMjQ++ugjqHjggQdalrzFqdI7FJuirXSMOAgYxmH/93//R6eMxQx7wPXXX1++pKE2UnWef/55bBuqQn744Yfjx4/H2vH000+XI13MaKDvM0yBBD/+Q1cZ+uc//5keDRmjw1B/aOm7mZel7sk0cyLJlA3a2+677Y42cNxxx73wwguMZmjGbToIWAKWgSqTAvTIaAO6uIlSA561MKP0EGcJcmifpPAf0YK1iTduHvCwhFhH+yDXzFzBlo6O3mDs2LEMD+zsp84Y0l18+umnTLcRDTL13cwc2jq6FgdFgzlNEdZaR2tiaNfW2HSg/Aot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objoI5IZNDjBXFyutiE0xuWx1Gyzl6vfDOD5NfI3wzBgjdiNJPAFkRbFg2WDBkhqaCqGAqru3/52xnLLLnfCCScsWlQbkGFtGB2XtAz30W5//RVxKyfcYpLnc+YvMyPByJSvv77ssn9Om/b9nXfcgfXogvMvGDdu3KabbcriElTVE44/oba2hlQMcFl68uSTT6IoX/Wvq55//vljjz0W7TIejx555JEPPPDAxZdcTCinVwHk66+/ZhQ+ceLEs846m09aFqiYCi+6y9dfTxm73diu3bo9cP8DV199FedfcfwlubCmdeNNNmbjLk0POCivol7J3U4J4sybOw8Tx4wZP6Pg3n33XRdeeMH1N1z/zTffcGrWorpFU6dOnXDwBJTgZ55+5qKLLrr/gfs5Hbxfv34codGlSxVrZUaOGglKu++2+8KahWjJTz/zNEtrTz3tVAgHsy++/OKsM8/ijrE777oTklkkdM8995D7rFmzuYsc3B566CGye2PSGyedeNKihvqrrrr69NNOO+iggx5//PG9994Hkc90DKYIHNjhmJtjMo7FuSzTwTbgKztxuvUBWQxxn44DJcEB0+NkYIL458n1z4jU0g86ZfrNsWPH2rMKWgrJpWtLDliDri45kwspZKwsD+PWlGgvNNMvUa3AZ2Wa77GiHD8xm9vHxrc+OJD3IVbrCQ5iEpCZbOKJabsu2tC1R7errr1mxx13vO6660499bRELAY+WMW7deuKG8O7QooEQwyDK41tn1mAfn363HDtdb169Vl16LBbbrppK9aZHn1MpLLLqX/800EHTZg3Z27Xrt2Qwd2qq+++886VhqyMgEQv4NTqqd9OrVm48KUXX2SXyqabbwGof1566VtvTgbIUUcdnYzFjzz88DPPPItMaU2gzl/QwPbGoTo3XX+DbsMZeMuALbbcYuLEl8aN2+3F51/46Ycft99+R4+xkgoju+wfEOSDXSoqYdEtN9686qrDwuHKH6f9cO6550Lj77Nm1dUu2miDDVZeeeU11hjRt3dvFJdePXpuudnmJNlis80HrzT4lxkztt9u7GmnnTpo0DLgc+Zfz3j80cc+eP+/Kw8ewnaLFZZb/vLLLqvu1m2D9Td8+smn3pw0CUXn4YcfZpHQbbfdPmDAAKi4+OKLsRrOnzP3+muuPf64444/5ljgrLn6Gp998sm/rrhys403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Wn311VlWBnjevHkhJki6S1gVm8nSxaJFiw499FCEcUG22GILv4KHTtRee+21IbLaRA3lu9pqq9Fc1fqeljNTH3/88S677IJOvNp2220322wz5fXXX//JJ58skx5Fxu1zeetuLF988UUw9OferYHoKwukmYfd6mIFweODiI033piz25KeMjXe4klgMhEt4dtUanXo4YfJol122WW4yiS8/fbb++yzD2HQS0t11AZbm1cfL5i/wfiN5n38Ee+zBlaG89FHH6277rprr702gAynP4MCc/311zMnhxxyyNlnn02GbcBzaj/77LNTTjll/PjxO+ywgy44BLV+B/1YCH755Zd3mPCPv1v8NVTGVaVZEKJfY9l6660pAWX/KrPNuLR99NFH11lnHQSv/XfrbPYPW/zHR//5xyVLuE2Gw14+++yzVfzV8qAHoqEpZoNOO+00ZeOaO3cufUUboOTAAw+k/NsjR0YBgCpXqWlZIGOYA78pwxyPLcGaKxuu4rC5MA6zyOjOO+9M9WPHjjvuKFikW1msa665psrZjPrpp58Gyfj1mgn+gwsCuK66M0nuLo98gkKVWOGMM85gXxEsamTbLr/88iwMMLl6RyfWnX/++TwAqurFF18kpi7/kJ48Iemdd97RNXV23333cWanT5/Ohr3//vtc3c0339zoQhgie0chzFjErqPniiuuIPGcEhcdt99++6H8mWeeqfZOPdFiOUIMpvqqp2VM4MNRmoJOv9TLcTGJ6MRDvBLBcBFCwLvvvos8TqECNfHvSy8T4S3i/zrlbf90dyCITO/dRbviYKMZd9ttt6lTp2aYLcU1lQFwLwtwQKPQ0NIeu966FjM/oHR01FFHbb/99iY3aAeEsyUwPJP/5cSjjjm6+S0a0q/u9tprr4TOwFSWq7lVtcYSY7f4/amkEBhODkEeTzjhhIyl2qQrZcuct/TAQw/avQ7CQrDC0UcfLbVmEVFHPACBygEHHJDBFrAqGSwCd2HKlClSGl/8928m7rbrP+06EQC2iA9p2h75AZBvuOGG8+fP15cvTXifzP+nn3763nvv8UiOPPJI1FbprJXzlsNKK0TBGmMNpvqYsasxa5wPM1V92748rPwAQ6Vzt9lmG4b2nnvuUTbTeEdibHxyBfiYVXbESEgADoEfcN555wn4DjroIDGBSSUWgv4999yTSRMgosos3nDDDSNHjrzxxhulDcSv/hO8xDvbFoEo01wdQlfKWESbkE42SahdjQh1yqTxV+gROhTYvvvuy7sKjLcShgwwSVVT6OwKVc1I0CkzIWjmBESNFp5Y4VQDD6bainHlC0rM4mrxA9KwCtaLMl1p7ugXEugqXcid8P8YBmQgfubMmdQQPVUA1Btm4WQG2OZeGnZY0Ombb77JRlLBHaJakZvb7WIO+a8ftl9xAAATbElEQVSFyLC6PH711VezZ8+mwU0EoZo8eTKe3HnnnTWwAt9XQdbaqnn8ySf+ftw43jywrLLjjz+e7excCCNU8Fief7vmT956520moljNGlUiEA7o6aefjiSrOGMpQlUDzmPeSk2deeaZ1o5H9Hu1xx57ZJV5PO6446QDq+LdEtWAKkPbE088YTvyq98tErVrbpiFWgVhHlWp37BUzD1u3DhyW4WpdnrvvfeadOYAvNTCv86ezTmTPgHDjRB00cDVttVyFc9Ay3y+E088Mfx5/PHHrXTdQQ7PI488ksxfXzgLV20rmDXiFP73Bc+mBLP5xQqzxgXpv5gNKz8Ap6688kpmSRYofIys4J3VQlbsEYSPVjtjxjMwT/wAGwd98bfDegSYHkl+VB122GHViVGPDNZrwoQJwLzaaqutJk6cGEXskWWVRubqhgbwrg7padkcWgQcc8wxGMKXDAwCSndyADYX84hmmYBCEheKlaU3YWiJvIuVRJwOsioWL16MmNBT8PNFYlDDZH60LJyQhRawAuOVA661Ks27WBBV21uhreItRVvpN4TZscJAj4bDbTcciVbslZqKqgI/BEQ2j5f922CDDUJz89thUIOrLCIDkzGGyYXVCpSpbJN0sWXIV+P78gC4blaoJVwga6zItKq0BMydyzw6CHLWWWdRO7qjlNLWq275AaEB2ttuu00XSeTUKNQdMHmm9dZbj9Rdeuml3OJCrVfga01qj+klkBoKTiQpixdOY9i/L45FAe6wgI177703XY0YQ6gpFmSYvqq3KsiWPFDZGMyyq0oDJU+1loEbhYBHTAiWYe5RPkDuRCrFmgolDLMEoWnKI00lLBQnVOmsltHm0V3ciOfUl7IrMPwzNsuONj5QJkIdWVvD5Lmmle6ooAhAFW1f5fqhyr7OO6wU9Y7MSMNaFZZxzsKUEzGj1xjNORg7dmwGYsFzx4TagFkyie4eDRABWH/XXXcpyLo7FZKZ4HwoEEEJdkKp9yV/WmKHm3CII70C6ecFjchv5XqrpkcUQpuzJDSdDBtXIB2F1JQbvogfBFl6dBYA4p1w+fV//ZqUy3NIIThA1N8DKR0MwzJ466239MWpqnWHHlOpHvpQ7hyT8gUXXDBnzpyokvRc42QNTwfUfdvUyrRuuSwRP+xyVDT9ustX6dTMOl8pByMztN1221mxZFKqYNrUab/Y/xe9oOpb+lqVliqZhpZBWNjYCmrlrsNV5pDnbV7KEa2w2vBNE7PtcfqV03+76LcsnCQi2VYjB8ZscCuVS8PCi8ZSXXq0LdOtfOuttzquxcnLEVripyHeZtU3WO233yofNRRU/S+EYDgdd7Dx76eNGmL23UsNw8AVFrjbv3vhhRfAoxaUgjuqvtvi25rgzz0wv//f3zP8bJKzAlli8MOQq4ank0cWXRB84YUXQqILV7CF87rOEFL51FNPiea5d4Q2g2ru2rTKB4TnRkTrmhceQDNk5zVlXthvHhKZgVMlyy31G92OY6j1qLKvHo0FhdQCGM0/+eQTfFAQNlihk0+YPGHHCXZvGbXPP//ciVeJmXPOOUe61Oz0hbNN/bDyA7jhnHf6lzXNmDGuYcD8YMeIH26yySYWZ4SJWDxw/wPqrRN5Zgu1DY8G/Upfutcp6yVLEy+EEKgxqVk/okaFdOEgccqEwDXrkVmi8z332nPQBPS/IUeVAztu7DiSmlZW4/PPP1/oURAVCf2zLH9jm23iRLkB3Ntpp53KEPrf4+AgfaRg0z0K1+Qictq0adIDyFbmzzm+5BeaX3n1FbpYdrHxc2k+LxsxArAecdXS6vWncUy7XvglhS3mURSld127262knYGRWGU7QfYLbRyeeuqpxx537EbjN7KViOCwenCMGmgrpOJqrzkzUKq6C4+ltCqr2WDsD/6GwJAWMqyexuCRiw3YjEd/9Sh3QQztSK+UuBiauyY3oJW5qxqhkPfQQw9J82KgdQ1M3vHqq68WkFD01AsYa4TujtB2a0S6Q4we7XTI4oQqA7FmmR+9sDT0iU1xi4IfoHcy6U7XuWvbLF0qYZOCVoBfMhLmUM615RItWLDAYNdY3U93N4Qzl9F1a1DwwGxdCJdLaEE1WeBIIpz6wtWQB9ICt45stEsJtKGBHmb4CwCylXuk84McfmEV5ROXGjMF7sqZNW8NxKOhFapqBYbM/hF1Z9QmdPfddzdqEaPNOxzwU/QHH3ywQdmmkXVwN6dOJfNW+QEgXfjD9i39WK2Gu8XjsPIDsgAo1jJQ4mslWABqsB4ffTbjoxRcU0M+MjHupUkXCzryr8BMNsmm6P0YflEiMx+Y+fXirwmNZcaGCbhpogBk/ub+29xfnv5L+S6xiEntIlXNqPABQ0gVl185RFJhJ598MmcTPJJwzzG3Rq5pKcCaP1mTrqSGHLmyDjFQQrUZc3drsAudxYkO9+xZ2AJAHj4jw/LAUiky2V0xEAJUoj9T7O4rze5S1RKbHqUfTVx6X7hw4f3330/1WNWEgSsj7SmzIqGiuQAFJCMkrJEbcGiAH1AUSkv8Xa9EJ8XkytLoOv4VASE9EK6SYfTgOQNDeEwKn8CjfAwT7nwfJ4DecL7EkTRCziLaRtQksxkkZXIByOVA7jLFps/UU82A8+rcc8/lFojeSnzSOTcgR4AeUwgxRmFPOtaFyy7T6ZiU/BP/EoANAr6+LAXbycA30wCV8Np2O4YYiLMRyuThww8/ZGhhsMlNA5SGRocAdzDalvpOCnjLFUMAaxc8s2bN4q7pxRoXinBE9GUGZ9wyQ4aV8hEHIwDBfYnuGqPXEE/DZlXCz7gCZqQLnYZWyl0poJDpYW7wR6fuvDE1RREZDs9g1KhRmbh0Wi075WezFbxv2RyCNi8yAfCwbvSbUIegAvDRhFhCGgBn7C2yF4Ojf1j5AQwqxpF1d/ONX6ac9bIw1Fic1oZNO8ouHGfwFDDXfXDsa98qa4N9DVVlsmmNKRdOYWIBEAiPsjpjx47lNwRGOMutM/E2FLJr0L6jDt/iw4g/j3C4Ekl/+OMflNEsZZLjM9akLXZil2UWprnni1vpO1Lo7T4/20dlh5S0b26apFWky5hSbPFIcftAXyvTbSPAnq6CM0TS8mIX6s8rBQ4iOu16nHTSSb0mUo+m0jfWgkjEUFhcD2SLLAkeBeQLbGlPZbNvPWfIyoYjhWBcRqQc4cnbIbij0xajMwoIG4LuvpcuSDIhl5sRKCmv8sNVmMkqJdjuPJ0rlQIysq1MzLxKZZmX1JhiNtLlrWVufrVytJDysYjoer9VYHU7IBy1EyTduhsFJ5LLjiq902/S0QU5L0e6kX5b+D8L/VuE+AfOILMcYEJ/GY4aNDu+cPjhhysYF6/FnR2yW0+AfdVCJwAjKj1dREYR1Z2+hLl33HFHCM53j5jMS7PMnXg49thjA0Y7xSMJZJkvj5weDreaDFaywbikeapjB9bdy9QgyV1fLq6/A0woZ6SMjmCwTdZ76TQEF7I1Iave8oo0ESSE+WrI1Q033uBsgQMHJM2EOg3A5xNqmqmCcECFYeUH0KH0Ly+e6Jtjc8CRtz1shShbkA63D4g7XQG2/gmBbJv/hxaElq7gAFUuJtbZ8hDsLTkQOIplaRNTy/sr4tsVYvpCQmR9vMD9t4VBbQGz2n+6/k/jmvDNkYoSAQfVicnkj6SqMTorSnK1L8xdrEck11hA42DH/vvvb4oRWeyWt+jRHfbaAxLECCCQbZ2oZFwBcAi6GJP1NbSRq460u4xInVqcAfvuP6fx/43+xKHhu0gF+QAaDC1GQUc7DM2kV+k30ToVJIWHPVWR1X6HsmxoAiYHrDCfQmjZdYbvFQ64eAApB5h/efHFF/u4V7gWgCoSaEmjiLnktDmsDtCwQ4xZILVqmIWOk1Kh0yjYkldeeYWBId66sH9fSFKWnPDYWLx//svUaVNvvvlmoQVDornvlbQiqAUeBhczXGqsHS6OzLOtK9qVYwFVA2ZEw1Q3xrHsKk06LMDP/omeJcY57hwOj1RT0GbUN910E93okitVb1H/aEQjIYEbqILBLJR5BGCMPn2Uv4xmY0FxRsqnkFoFLpUdFsyLjizquE26tvEkFtUvBtL/0oEEA9k64qKprMqkqTFNXlFiVJZXxoXhajThEwgU05Y2lsGimY06NYOhHAuG0yUFhx053I5xVmYZnUMuzKo0oHpX6hkwE0CkClgvCj5QRJVNRLObrnN4FXm6Nm2EnjTr+qqrrrLe7OdZct4upfSvpPaCsIITYfan+Sscf/nD1CMAVeoZXVKLSPIqapRvl8MAo5VKXgKCq6wuaLtbwA2KSc7cMhCohQZdWAPWlfNfPADGla+NTm+Rh88cF6rNxqdHwGXqu0tbDZvo3/q0zm0T6lenKEEYvczWYjIKBaYGQs+iH/dcTBQ+25auYev1Y8TMHQ297uv7xe+LQaGVGLcMuU2hRipIDRlFwlZ7VR7DQ/cscDPOobf8A4C9tBBfxLICU1oNohD8GiKGWhPj1hB6TE0piJ6djUilho4yoKS5awDoDJjtDKaFKaKULCLmWYEvHgBjYWI7H0uNBl1Dy91PfSEmJImPWXGX2Jd/YDvSRf9gtbyIHGr5KBd8LryiwcaNG+cgtqCLluAMQQs/deEx32YvA//O3xpty33UODA28q1ljqNHldY4d9+4uF+ybiZCZjqQggEOTbREte9MMTqjygCH5rQq99Ij+JShEvSKgWNTCmSbQmuneDAOxYrRxslJX1PYJJOp3nXXXZNiwg6umS0WJn8oycR3/qAeSSGHWpqaDaAX1PBzvSUloYrrx+OTCRA92JIUc2SPA+TgXbyBDBUxFBwrJTx17g/r2HtdM2NYxymRf+Ml8GaMAoUWnh1uThXHi3YgdvFVB9LngGHRQ4mbX6lL2XULOw61fTKf3uFtUpeYaT3AjiTjQnM868z+EPBTBMDrN5uTJk2SmLUgBQcMPzrpa7kKZxvp1jGjx0joCS7lAGw/M1GSQ1JB0c5DQGeZgPS1YMECx4/tCuNYeTWcCoTBREj7ywvivFGraT/AIkjAwIv1yV6J27wt0wSVci5lC9xbq9hZtrI0FFzLoDraUC+ZeSfSOeKC3QTHteGEqgyTVvQ1Y8rA/DyJxdsMnxpEEmPKit0yXnosDdXrziiAdWssNRo82kaR9mfaMTB9YaaUhlGrdAaIRrKo8wph1IJWathaFNYQaiURImjm1sQJ4EDA1s8zdDVs7R8REwJIml2M1157jZpSY01RCGy/b/wwkEVwrAEq42LdrX0KIZgL/cgONkxoULtMoQUg0+GOCZFDKT2v1EDlUu98Wntqv32r2TC7JGNpUjLB5+LzOtYucc1W+QHa5kiLJTNDjHSvmWC3mBLhlzCxfFKLkDRLeamxGnmyMhMkBp3sqxXL12ZuGRJefK9pq+KXufKtnWw2Z1acwb92qsgZC6JWLu6CX2kUyzK9xNpuN0+rpa9axdzFMpsquYJLPgs21zjpO2/nQmpdxKG2T8R3kUiove3pY3glz3/77bdTamQPnQhmFfCKw45d4ZhDGJQCgJ//88+NwtB6Slgb5MIOWRN6tg3MSv3KpKBfAE28TU0ZSxHsWgFAalJwtzpMU3KKpq8KX7D1VTCzdoh9zcRWFYR9AS+3XtdBoiCNxMCLOJfbqgBoxS7aByw1BVt1UM3lwBs7aXFGjx4gz1UkXSk7UkcZMqKWcJZJMyUta5y0dXC4/2MRP7DKzz33XEtsKgc6nGoTmQnHRasYjMVV7ctbsYFoIdF8eZVWVWxVPC3LMKt3NyOiC+FH/5sv3yP+1mVYeUoY8dJLL0kdi8B4ss5TSCI5ic2xqg4CmyxOJ8hkunK2vPq262WmyGFXMZ+EMOTkzyFPa8mECVWl3xmMaGFv1bAWfDqRZTb5uk5PG4QYaGsTgP1RfpJdtxIDqeR1qqEIkDdq5KgSmrRB2PVXJN7nFWIEmDm/SHK17AWkelpyCE4GtCSAmJVwyonMuPmBDM24bboxE6l9jaIl5l5Urgg09GJccApwndlUkHOmE/yul3LEY7k9Zl6iMcox7wFNlj0FITuFI9NGCZjx5XbaBqBKNqUhuuC+yyq1aVJeZcdavCRgFR+X+irOUlkrRDxse0nIMaLOSQiuwAyIFTWctUdMthY4N76Cs6mX7FR/aKMwRXS87VVXWTUHm2qYa49mQRcPPvigPEE5wFGD6WRcojsJFUlKORs6CuZmbDQDMgSEQtbqGJsha4Q1P2ZqKDr7DvjmgBTz1wzWsmYY+gGRcqONPLnjqStsqnIhAExah2uyirNlOROMBj0CkNQy/eSbQlFJfBEQCr0FbBm0xDPElShpXEtTUhSoKwQgPnmnMFBl4fnQUIgoHRV60mkqUw4z1eAk2pIxGxra2vdSo9yjKx4At0bb78Wp0i8yMK1MaPtRrLxvl/L7Lxwv9jj57ay+5Y4o/ClypeBabqsqAAx866wd1jcIqwADKmte4FHCMPueNnuOpb59oUZAFWH7hrrjefj9ItJiIFJZA2VFe/zewmyCJEp9ACytC3978poJaA8fAjgNMp0CaNuaThe1pKoZc0uwlpVo8NGjZAOfphpHFWAA8LuM173UK9Qeq6/alzkf+UjE+aTHfvVYP/XJ/wPryKga7fINJQAAAABJRU5ErkJggg==" - } - }, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### AqSolDB dataset\n", - "\n", - "Compounds can be classified according to solubility values (LogS); Compounds with 0 and higher solubility value are highly soluble, those in the range of 0 to −2 are soluble, those in the range of −2 to −4 are slightly soluble and insoluble if less than −4.\n", - "\n", - "![image.png](attachment:image.png)" + " svg = exmol.plot_descriptors(\n", + " space,\n", + " d,\n", + " output_file=f\"desc_{d}_size_{a}.svg\",\n", + " title=f\"Chemical space size={s}\",\n", + " )\n", + " plt.close()\n", + " skunk.display(svg)" ] } ], @@ -730,7 +677,8 @@ "hash": "abc1ef2aae668f29add333aedc207234808b19831866b8480f007a054a2482dc" }, "kernelspec": { - "display_name": "Python 3.7.13 64-bit ('exmol': conda)", + "display_name": "Python 3 (ipykernel)", + "language": "python", "name": "python3" }, "language_info": { @@ -743,7 +691,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.13" + "version": "3.7.11" } }, "nbformat": 4, From 9467f57aa7e70f14fb9888c685524adaf0be4c15 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Wed, 22 Feb 2023 11:27:55 -0500 Subject: [PATCH 02/26] Added langchain and improve NLE --- docs/source/changelog.rst | 4 +-- exmol/exmol.py | 59 +++++++++++++++++---------------------- setup.py | 1 + tests/test_exmol.py | 2 ++ 4 files changed, 31 insertions(+), 35 deletions(-) diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 7256ce56..cf351f23 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -1,10 +1,10 @@ Change Log ========== -v3.0.2 +v3.0.2 (2023-02-23) ------------------- * Now try to find largest component with multiple compounds separated via `.` in SMILES - +* Added langchain for text explanations v3.0.1 (2023-02-02) diff --git a/exmol/exmol.py b/exmol/exmol.py index c53a4dc4..60a2ca88 100644 --- a/exmol/exmol.py +++ b/exmol/exmol.py @@ -26,7 +26,8 @@ from rdkit.Chem.Draw import MolToImage as mol2img, DrawMorganBit # type: ignore from rdkit.Chem import rdchem # type: ignore from rdkit.DataStructs.cDataStructs import BulkTanimotoSimilarity, TanimotoSimilarity # type: ignore - +import langchain.llms as llms +import langchain.prompts as prompts from . import stoned from .plot_utils import _mol_images, _image_scatter, _bit2atoms @@ -1331,45 +1332,37 @@ def merge_text_explains( return pos + joint -_text_prompt = """ -The following are a series of questions about molecules that connect their structure to a property, along with how important each question is for the molecular property. An answer of "Yes" means that the question was true and that attribute of structure contributed to the molecular property. An answer of "Counterfactual" means the lack of that attribute contributed to the molecular property. A summary paragraph is given below, which only summarizes on the most important structure-property relationships. - -Property: [PROPERTY] -[TEXT] -Summary: The molecular property "[PROPERTY]" can be explained""" +_prompt = ( + "The following is information about molecules that connect their structure " + 'to the property "{property}". ' + "The information is attributes of molecules expressed as questions with answers and " + "relative importance for the property. " + 'An answer of "Counterfactual" means the lack of that ' + "attribute contributed to the molecular property. " + "Using this information, provide a comprehensive explanation (25-50 words) " + 'for the molecular property "{property}". Only use the information below.\n\n' + "{text}\n\n" + "Explanation:" +) -def text_prompt( +def text_explain_generate( text_explanations: List[Tuple[str, float]], property_name: str, - open_ai_key: Optional[str] = None, + llm: Optional[llms.BaseLLM] = None, ) -> str: - """Insert text explanations into template, and optionally send to OpenAI.""" - result = _text_prompt.replace("[PROPERTY]", property_name) + """Insert text explanations into template, and generate explanation.""" # want to have negative examples at the end text_explanations.sort(key=lambda x: x[1], reverse=True) - result = result.replace("[TEXT]", "".join([f"{t[0]}" for t in text_explanations])) - if open_ai_key is not None: - import openai - - openai.api_key = open_ai_key - response = openai.Completion.create( - model="text-davinci-003", - prompt=result, - temperature=0.7, - max_tokens=256, - top_p=1, - frequency_penalty=0, - presence_penalty=0, - ) - completion = response["choices"][0]["text"] - return ( - 'The molecular property "' - + property_name - + '" can be explained' - + completion - ) - return result + text = "".join([f"{x[0]}" for x in text_explanations]) + prompt_template = prompts.PromptTemplate( + input_variables=["property", "text"], template=_prompt + ) + prompt = prompt_template.format(property=property_name, text=text) + if llm is None: + llm = llms.OpenAI(temperature=0.05) + print(prompt) + return llm(prompt) def text_explain( diff --git a/setup.py b/setup.py index 8c6655b2..5ac96dd1 100644 --- a/setup.py +++ b/setup.py @@ -28,6 +28,7 @@ "skunk >= 0.4.0", "importlib-resources", "synspace", + "langchain", ], test_suite="tests", long_description=long_description, diff --git a/tests/test_exmol.py b/tests/test_exmol.py index 7eaaff7c..e9465c32 100644 --- a/tests/test_exmol.py +++ b/tests/test_exmol.py @@ -450,6 +450,8 @@ def model(s, se): s = exmol.text_explain(samples1, "ECFP") assert len(s) > 0, "No explanation generated" + e = exmol.text_explain_generate(s, "catalyst for dimerization") + print(e) samples2 = exmol.sample_space( "O=C(NCC1CCCCC1N)C2=CC=CC=C2C3=CC=C(F)C=C3C(=O)NC4CCCCC4", model, batched=False ) From 7ccd2a19dd0600def35a8019f058c2b937641242 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Wed, 22 Feb 2023 14:21:13 -0500 Subject: [PATCH 03/26] Tweaked prompt --- exmol/exmol.py | 3 +-- tests/test_exmol.py | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exmol/exmol.py b/exmol/exmol.py index 60a2ca88..fc601619 100644 --- a/exmol/exmol.py +++ b/exmol/exmol.py @@ -1340,7 +1340,7 @@ def merge_text_explains( 'An answer of "Counterfactual" means the lack of that ' "attribute contributed to the molecular property. " "Using this information, provide a comprehensive explanation (25-50 words) " - 'for the molecular property "{property}". Only use the information below.\n\n' + 'for the molecular property "{property}". Only use the information below, but you can rephrase it.\n\n' "{text}\n\n" "Explanation:" ) @@ -1361,7 +1361,6 @@ def text_explain_generate( prompt = prompt_template.format(property=property_name, text=text) if llm is None: llm = llms.OpenAI(temperature=0.05) - print(prompt) return llm(prompt) diff --git a/tests/test_exmol.py b/tests/test_exmol.py index e9465c32..48667ebd 100644 --- a/tests/test_exmol.py +++ b/tests/test_exmol.py @@ -446,12 +446,13 @@ def model(s, se): s = exmol.text_explain(samples, "MACCS") assert len(s) > 0, "No explanation generated" + e = exmol.text_explain_generate(s, "catalyst for dimerization") + print(e) + samples1 = exmol.sample_space("c1cc(C(=O)O)c(OC(=O)C)cc1", model, batched=False) s = exmol.text_explain(samples1, "ECFP") assert len(s) > 0, "No explanation generated" - e = exmol.text_explain_generate(s, "catalyst for dimerization") - print(e) samples2 = exmol.sample_space( "O=C(NCC1CCCCC1N)C2=CC=CC=C2C3=CC=C(F)C=C3C(=O)NC4CCCCC4", model, batched=False ) From 094071738810eab5e3cf553fa93717e22502e732 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Wed, 22 Feb 2023 15:30:06 -0500 Subject: [PATCH 04/26] Updated notebook --- paper2_LIME/Solubility-RNN.ipynb | 35 ++++++++++++-------------------- tests/test_exmol.py | 3 +-- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/paper2_LIME/Solubility-RNN.ipynb b/paper2_LIME/Solubility-RNN.ipynb index 793e31c0..f08c9a48 100644 --- a/paper2_LIME/Solubility-RNN.ipynb +++ b/paper2_LIME/Solubility-RNN.ipynb @@ -117,16 +117,23 @@ "\n", "aug_data = 10\n", "\n", + "def largest_mol(smiles):\n", + " ss = smiles.split('.')\n", + " ss.sort(key = lambda a: len(a))\n", + " return ss[-1]\n", + "\n", "aug_smiles = []\n", "aug_solubilities = []\n", "for sml, sol in zip(smiles, solubilities):\n", + " sml = largest_mol(sml)\n", + " if len(sml) =< 6:\n", + " continue # ion or metal \n", " new_smls = []\n", " new_smls.append(sml)\n", " aug_solubilities.append(sol)\n", " for _ in range(aug_data):\n", " try:\n", " new_sml = _randomize_smiles(MolFromSmiles(sml))\n", - " print(new_sml)\n", " if new_sml not in new_smls:\n", " new_smls.append(new_sml)\n", " aug_solubilities.append(sol)\n", @@ -295,9 +302,9 @@ }, "outputs": [], "source": [ - "model.compile(tf.optimizers.Adam(1e-4), loss=\"mean_squared_error\")\n", + "model.compile(tf.optimizers.Adam(1e-3), loss=\"mean_squared_error\")\n", "# verbose=0 silences output, to get progress bar set verbose=1\n", - "result = model.fit(train_data, validation_data=val_data, epochs=100, verbose=0)" + "result = model.fit(train_data, validation_data=val_data, epochs=25)" ] }, { @@ -465,25 +472,9 @@ "exmol.lime_explain(space, \"maccs\")\n", "s2_maccs = exmol.text_explain(space, \"maccs\", presence_thresh=0.1)\n", "\n", - "# print(f's1_ecfp: {s1_ecfp}\\n')\n", - "# print(f's2_maccs: {s2_maccs}\\n')\n", - "\n", "explanation_list = exmol.merge_text_explains(s1_ecfp, s2_maccs, filter=1.96)[:5]\n", - "\n", - "# explanation_list = exmol.merge_text_explains(ecfp_standardized,maccs_standardized, filter=1.96)[:5]\n", - "prompt = exmol.text_prompt(explanation_list, f\"solubility\")\n", - "# print(f\"Prompt: {prompt}\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "openAIKey = \"\" # Add in open AI key here to get NLE\n", - "nle = exmol.text_prompt(explanation_list, f\"Aqueous Solubility\", open_ai_key=openAIKey)\n", - "print(f\"NLE: {nle}\")" + "explanation = exmol.text_explain_generate(explanation_list, \"solubility\")\n", + "print(explanation)" ] }, { @@ -849,7 +840,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.13" + "version": "3.9.12" } }, "nbformat": 4, diff --git a/tests/test_exmol.py b/tests/test_exmol.py index 48667ebd..65eea769 100644 --- a/tests/test_exmol.py +++ b/tests/test_exmol.py @@ -446,8 +446,7 @@ def model(s, se): s = exmol.text_explain(samples, "MACCS") assert len(s) > 0, "No explanation generated" - e = exmol.text_explain_generate(s, "catalyst for dimerization") - print(e) + # e = exmol.text_explain_generate(s, "catalyst for dimerization") samples1 = exmol.sample_space("c1cc(C(=O)O)c(OC(=O)C)cc1", model, batched=False) s = exmol.text_explain(samples1, "ECFP") From 2b068655de7904ca47087cf67b05f9f2f0eeec89 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Wed, 22 Feb 2023 16:56:32 -0500 Subject: [PATCH 05/26] Added correlation direction --- exmol/exmol.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/exmol/exmol.py b/exmol/exmol.py index fc601619..0215966d 100644 --- a/exmol/exmol.py +++ b/exmol/exmol.py @@ -1354,7 +1354,13 @@ def text_explain_generate( """Insert text explanations into template, and generate explanation.""" # want to have negative examples at the end text_explanations.sort(key=lambda x: x[1], reverse=True) - text = "".join([f"{x[0]}" for x in text_explanations]) + text = "\n".join( + [ + f"{x[0][:-1]}. {'Positive' if x[1] > 0 else 'Negative'} correlation." + for x in text_explanations + ] + ) + print(text) prompt_template = prompts.PromptTemplate( input_variables=["property", "text"], template=_prompt ) From 1131b67d3ea01e35cf9232a433c2949f168b70f1 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Wed, 22 Feb 2023 17:49:40 -0500 Subject: [PATCH 06/26] More work on prompt --- exmol/exmol.py | 23 ++++++++++++----------- tests/test_exmol.py | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/exmol/exmol.py b/exmol/exmol.py index 0215966d..a9a13afc 100644 --- a/exmol/exmol.py +++ b/exmol/exmol.py @@ -1333,14 +1333,15 @@ def merge_text_explains( _prompt = ( - "The following is information about molecules that connect their structure " - 'to the property "{property}". ' + "The following is information about molecules that connect their structures " + 'to the property called "{property}." ' "The information is attributes of molecules expressed as questions with answers and " - "relative importance for the property. " - 'An answer of "Counterfactual" means the lack of that ' - "attribute contributed to the molecular property. " - "Using this information, provide a comprehensive explanation (25-50 words) " - 'for the molecular property "{property}". Only use the information below, but you can rephrase it.\n\n' + "relative importance. " + "Using all aspects of this information, propose an explanation (50-150 words) " + 'for the molecular property "{property}." ' + "Only use the information below. Answer in a scientific " + 'tone and make use of counterfactuals (e.g., "If X were present, {property} would be negatively...").' + "\n\n" "{text}\n\n" "Explanation:" ) @@ -1356,11 +1357,11 @@ def text_explain_generate( text_explanations.sort(key=lambda x: x[1], reverse=True) text = "\n".join( [ - f"{x[0][:-1]}. {'Positive' if x[1] > 0 else 'Negative'} correlation." + # f"{x[0][:-1]} {'Positive' if x[1] > 0 else 'Negative'} correlation." + f"{x[0][:-1]}." for x in text_explanations ] ) - print(text) prompt_template = prompts.PromptTemplate( input_variables=["property", "text"], template=_prompt ) @@ -1442,10 +1443,10 @@ def text_explain( if neg_count == count - 2: # don't want to have only negative examples continue - kind = "No (Counterfactual)." + kind = "No and it would be negatively correlated with property (counterfactual)." neg_count += 1 elif present / nbases > presence_thresh and v > 0: - kind = "Yes." + kind = "Yes and this is positively correlated with property." pos_count += 1 else: continue diff --git a/tests/test_exmol.py b/tests/test_exmol.py index 65eea769..3269e13b 100644 --- a/tests/test_exmol.py +++ b/tests/test_exmol.py @@ -446,7 +446,7 @@ def model(s, se): s = exmol.text_explain(samples, "MACCS") assert len(s) > 0, "No explanation generated" - # e = exmol.text_explain_generate(s, "catalyst for dimerization") + e = exmol.text_explain_generate(s, "soluble in water") samples1 = exmol.sample_space("c1cc(C(=O)O)c(OC(=O)C)cc1", model, batched=False) s = exmol.text_explain(samples1, "ECFP") From e75480b1b42760d97fb071abca9200a8f2b4094e Mon Sep 17 00:00:00 2001 From: Andrew White Date: Thu, 23 Feb 2023 23:41:29 -0500 Subject: [PATCH 07/26] Updated prompt for single vs multi molecules --- exmol/exmol.py | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/exmol/exmol.py b/exmol/exmol.py index a9a13afc..1bcf8bc7 100644 --- a/exmol/exmol.py +++ b/exmol/exmol.py @@ -1332,7 +1332,7 @@ def merge_text_explains( return pos + joint -_prompt = ( +_multi_prompt = ( "The following is information about molecules that connect their structures " 'to the property called "{property}." ' "The information is attributes of molecules expressed as questions with answers and " @@ -1346,13 +1346,35 @@ def merge_text_explains( "Explanation:" ) +_single_prompt = ( + "The following is information about a specific molecule that connects its structure " + 'to the property "{property}." ' + "The information is structural attributes expressed as questions with answers and " + "relative importance. " + "Using all aspects of this information, propose an explanation (50-150 words) " + 'for relationship between this molecule\'s structure and its property "{property}." ' + "Only use the information below. Answer in a scientific " + 'tone and make use of counterfactuals (e.g., "If X were present, {property} would be negatively...").' + "\n\n" + "{text}\n\n" + "Explanation:" +) + def text_explain_generate( text_explanations: List[Tuple[str, float]], property_name: str, llm: Optional[llms.BaseLLM] = None, + single: bool = True, ) -> str: - """Insert text explanations into template, and generate explanation.""" + """Insert text explanations into template, and generate explanation. + + Args: + text_explanations: List of text explanations. + property_name: Name of property. + llm: Language model to use. + single: Whether to use a prompt about a single molecule or multiple molecules. + """ # want to have negative examples at the end text_explanations.sort(key=lambda x: x[1], reverse=True) text = "\n".join( @@ -1363,7 +1385,8 @@ def text_explain_generate( ] ) prompt_template = prompts.PromptTemplate( - input_variables=["property", "text"], template=_prompt + input_variables=["property", "text"], + template=_single_prompt if single else _multi_prompt, ) prompt = prompt_template.format(property=property_name, text=text) if llm is None: From 3a8c20fbfcf09a5625d2de40fd34d846a386e9b6 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Fri, 24 Feb 2023 01:14:06 -0500 Subject: [PATCH 08/26] More prompt refinement --- exmol/exmol.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exmol/exmol.py b/exmol/exmol.py index 1bcf8bc7..a1279048 100644 --- a/exmol/exmol.py +++ b/exmol/exmol.py @@ -1352,9 +1352,9 @@ def merge_text_explains( "The information is structural attributes expressed as questions with answers and " "relative importance. " "Using all aspects of this information, propose an explanation (50-150 words) " - 'for relationship between this molecule\'s structure and its property "{property}." ' + 'for this molecule\'s property "{property}." ' "Only use the information below. Answer in a scientific " - 'tone and make use of counterfactuals (e.g., "If X were present, {property} would be negatively...").' + 'tone and make use of counterfactuals (e.g., "If X were present, its {property} would be negatively...").' "\n\n" "{text}\n\n" "Explanation:" From 92f420346de676465bdbc2e7818d51b615135e70 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Fri, 24 Feb 2023 04:11:09 -0500 Subject: [PATCH 09/26] Model changes --- paper2_LIME/Solubility-RNN.ipynb | 83 ++++++++++++++++---------------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/paper2_LIME/Solubility-RNN.ipynb b/paper2_LIME/Solubility-RNN.ipynb index f08c9a48..3075cc28 100644 --- a/paper2_LIME/Solubility-RNN.ipynb +++ b/paper2_LIME/Solubility-RNN.ipynb @@ -20,15 +20,11 @@ "metadata": {}, "outputs": [], "source": [ - "import os\n", - "\n", - "os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"0\"\n", "import pandas as pd\n", "import matplotlib.pyplot as plt\n", "from matplotlib.patches import Rectangle, FancyBboxPatch\n", "from matplotlib.offsetbox import AnnotationBbox\n", "import seaborn as sns\n", - "import textwrap\n", "import skunk\n", "import matplotlib as mpl\n", "import numpy as np\n", @@ -38,6 +34,8 @@ "from dataclasses import dataclass\n", "from rdkit.Chem.Draw import rdDepictor, MolsToGridImage\n", "from rdkit.Chem import MolFromSmiles, MACCSkeys\n", + "import random\n", + "\n", "\n", "rdDepictor.SetPreferCoordGen(True)\n", "import matplotlib.pyplot as plt\n", @@ -69,7 +67,8 @@ " \"https://github.com/whitead/dmol-book/raw/main/data/curated-solubility-dataset.csv\"\n", ")\n", "features_start_at = list(soldata.columns).index(\"MolWt\")\n", - "np.random.seed(0)" + "np.random.seed(0)\n", + "random.seed(0)" ] }, { @@ -79,7 +78,7 @@ "outputs": [], "source": [ "# scramble them\n", - "soldata = soldata.sample(frac=1, random_state=0).reset_index(drop=True)\n", + "soldata = soldata.sample(frac=0.01, random_state=0).reset_index(drop=True)\n", "soldata.head()" ] }, @@ -110,24 +109,24 @@ }, "outputs": [], "source": [ - "import random\n", - "\n", "smiles = list(soldata[\"SMILES\"])\n", "solubilities = list(soldata[\"Solubility\"])\n", "\n", "aug_data = 10\n", "\n", + "\n", "def largest_mol(smiles):\n", - " ss = smiles.split('.')\n", - " ss.sort(key = lambda a: len(a))\n", + " ss = smiles.split(\".\")\n", + " ss.sort(key=lambda a: len(a))\n", " return ss[-1]\n", "\n", + "\n", "aug_smiles = []\n", "aug_solubilities = []\n", "for sml, sol in zip(smiles, solubilities):\n", " sml = largest_mol(sml)\n", - " if len(sml) =< 6:\n", - " continue # ion or metal \n", + " if len(sml) <= 4:\n", + " continue # ion or metal\n", " new_smls = []\n", " new_smls.append(sml)\n", " aug_solubilities.append(sol)\n", @@ -173,7 +172,7 @@ "data_vocab = set(\n", " sf.get_alphabet_from_selfies([s for s in selfies_list if s is not None])\n", ")\n", - "vocab = ['[nop]']\n", + "vocab = [\"[nop]\"]\n", "vocab.extend(list(data_vocab.union(basic)))\n", "vocab_stoi = {o: i for o, i in zip(vocab, range(len(vocab)))}\n", "\n", @@ -181,8 +180,6 @@ "def selfies2ints(s):\n", " result = []\n", " for token in sf.split_selfies(s):\n", - " if token == '.':\n", - " continue # ?\n", " if token in vocab_stoi:\n", " result.append(vocab_stoi[token])\n", " else:\n", @@ -197,14 +194,10 @@ "\n", "# test them out\n", "s = selfies_list[0]\n", - "print('selfies:', s)\n", + "print(\"selfies:\", s)\n", "v = selfies2ints(s)\n", - "print('selfies2ints:', v)\n", - "so = ints2selfies(v)\n", - "print('ints2selfes:', so)\n", - "assert so == s.replace(\n", - " '.', ''\n", - ") # make sure '.' is removed from Selfies string during assertion" + "print(\"selfies2ints:\", v)\n", + "so = ints2selfies(v)" ] }, { @@ -246,20 +239,25 @@ "source": [ "# now get sequences\n", "encoded = [selfies2ints(s) for s in selfies_list if s is not None]\n", + "# check for non-Nones\n", + "dsolubilities = aug_df_AqSolDB.Solubility.values[[s is not None for s in selfies_list]]\n", "padded_seqs = tf.keras.preprocessing.sequence.pad_sequences(encoded, padding=\"post\")\n", "\n", + "# Should be shuffled from the beginning, so no worries\n", + "N = len(padded_seqs)\n", + "split = int(0.1 * N)\n", + "\n", "# Now build dataset\n", - "data = tf.data.Dataset.from_tensor_slices(\n", + "test_data = tf.data.Dataset.from_tensor_slices(\n", + " (padded_seqs[:split], dsolubilities[:split])\n", + ").batch(config.batch_size)\n", + "\n", + "nontest = tf.data.Dataset.from_tensor_slices(\n", " (\n", - " padded_seqs,\n", - " aug_df_AqSolDB.Solubility.iloc[[bool(s) for s in selfies_list]].values,\n", + " padded_seqs[split:],\n", + " dsolubilities[split:],\n", " )\n", ")\n", - "# now split into val, test, train and batch\n", - "N = len(data)\n", - "split = int(0.1 * N)\n", - "test_data = data.take(split).batch(config.batch_size)\n", - "nontest = data.skip(split)\n", "val_data, train_data = nontest.take(split).batch(config.batch_size), nontest.skip(\n", " split\n", ").shuffle(config.buffer_size).batch(config.batch_size).prefetch(\n", @@ -285,7 +283,7 @@ ")\n", "\n", "# RNN layer\n", - "model.add(tf.keras.layers.GRU(config.rnn_units))\n", + "model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(config.rnn_units)))\n", "# a dense hidden layer\n", "model.add(tf.keras.layers.Dense(config.hidden_dim, activation=\"relu\"))\n", "# regression, so no activation\n", @@ -302,7 +300,7 @@ }, "outputs": [], "source": [ - "model.compile(tf.optimizers.Adam(1e-3), loss=\"mean_squared_error\")\n", + "model.compile(tf.optimizers.Adam(1e-4), loss=\"mean_squared_error\")\n", "# verbose=0 silences output, to get progress bar set verbose=1\n", "result = model.fit(train_data, validation_data=val_data, epochs=25)" ] @@ -418,7 +416,7 @@ "smi = \"CCCCC(=O)N(CC1=CC=C(C=C1)C2=C(C=CC=C2)C3=NN=N[NH]3)C(C(C)C)C(O)=O\" # mol1 - not soluble\n", "# smi = \"CC(CC(=O)NC1=CC=CC=C1)C(=O)O\" #mol2 - highly soluble\n", "stoned_kwargs = {\n", - " \"num_samples\": 2500,\n", + " \"num_samples\": 5000,\n", " \"alphabet\": exmol.get_basic_alphabet(),\n", " \"max_mutations\": 1,\n", "}\n", @@ -468,12 +466,11 @@ "outputs": [], "source": [ "exmol.lime_explain(space, \"ecfp\")\n", - "s1_ecfp = exmol.text_explain(space, \"ecfp\", presence_thresh=0.1)\n", + "s1_ecfp = exmol.text_explain(space, \"ecfp\")\n", "exmol.lime_explain(space, \"maccs\")\n", - "s2_maccs = exmol.text_explain(space, \"maccs\", presence_thresh=0.1)\n", - "\n", - "explanation_list = exmol.merge_text_explains(s1_ecfp, s2_maccs, filter=1.96)[:5]\n", - "explanation = exmol.text_explain_generate(explanation_list, \"solubility\")\n", + "s2_maccs = exmol.text_explain(space, \"maccs\")\n", + "explanation_list = exmol.merge_text_explains(s1_ecfp[:3], s2_maccs[:3])\n", + "explanation = exmol.text_explain_generate(explanation_list, \"aqueous solubility\")\n", "print(explanation)" ] }, @@ -822,9 +819,6 @@ } ], "metadata": { - "interpreter": { - "hash": "abc1ef2aae668f29add333aedc207234808b19831866b8480f007a054a2482dc" - }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", @@ -840,7 +834,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.12" + "version": "3.8.11" + }, + "vscode": { + "interpreter": { + "hash": "3e5a039a7a113538395a7d74f5574b0c5900118222149a18efb009bf03645fce" + } } }, "nbformat": 4, From 1a37f5b53ac6ffb0fa39ac69ea618c1f92525de5 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Fri, 24 Feb 2023 04:11:48 -0500 Subject: [PATCH 10/26] Removed oai key dependency --- paper2_LIME/Solubility-RNN.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/paper2_LIME/Solubility-RNN.ipynb b/paper2_LIME/Solubility-RNN.ipynb index 3075cc28..5d1ca904 100644 --- a/paper2_LIME/Solubility-RNN.ipynb +++ b/paper2_LIME/Solubility-RNN.ipynb @@ -470,8 +470,8 @@ "exmol.lime_explain(space, \"maccs\")\n", "s2_maccs = exmol.text_explain(space, \"maccs\")\n", "explanation_list = exmol.merge_text_explains(s1_ecfp[:3], s2_maccs[:3])\n", - "explanation = exmol.text_explain_generate(explanation_list, \"aqueous solubility\")\n", - "print(explanation)" + "# explanation = exmol.text_explain_generate(explanation_list, \"aqueous solubility\")\n", + "# print(explanation)" ] }, { From c32146995a445902f2deaa18b5650348b4ea84a1 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Thu, 2 Mar 2023 10:52:51 -0500 Subject: [PATCH 11/26] Updated notebook experiments --- paper2_LIME/Solubility-RNN.ipynb | 35 +++++++++++++++++--------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/paper2_LIME/Solubility-RNN.ipynb b/paper2_LIME/Solubility-RNN.ipynb index 5d1ca904..fa4f87e2 100644 --- a/paper2_LIME/Solubility-RNN.ipynb +++ b/paper2_LIME/Solubility-RNN.ipynb @@ -216,16 +216,18 @@ " embedding_dim: int\n", " rnn_units: int\n", " hidden_dim: int\n", + " drop_rate: float\n", "\n", "\n", "config = Config(\n", " vocab_size=len(vocab),\n", " example_number=len(selfies_list),\n", - " batch_size=16,\n", + " batch_size=128,\n", " buffer_size=10000,\n", - " embedding_dim=256,\n", - " hidden_dim=128,\n", - " rnn_units=128,\n", + " embedding_dim=64,\n", + " hidden_dim=32,\n", + " rnn_units=64,\n", + " drop_rate=0.20,\n", ")" ] }, @@ -281,11 +283,13 @@ " input_dim=config.vocab_size, output_dim=config.embedding_dim, mask_zero=True\n", " )\n", ")\n", - "\n", + "model.add(tf.keras.layers.Dropout(config.drop_rate))\n", "# RNN layer\n", "model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(config.rnn_units)))\n", + "model.add(tf.keras.layers.Dropout(config.drop_rate))\n", "# a dense hidden layer\n", "model.add(tf.keras.layers.Dense(config.hidden_dim, activation=\"relu\"))\n", + "model.add(tf.keras.layers.Dropout(config.drop_rate))\n", "# regression, so no activation\n", "model.add(tf.keras.layers.Dense(1))\n", "\n", @@ -300,9 +304,9 @@ }, "outputs": [], "source": [ - "model.compile(tf.optimizers.Adam(1e-4), loss=\"mean_squared_error\")\n", + "model.compile(tf.optimizers.Adam(1e-3), loss=\"mean_squared_error\")\n", "# verbose=0 silences output, to get progress bar set verbose=1\n", - "result = model.fit(train_data, validation_data=val_data, epochs=25)" + "result = model.fit(train_data, validation_data=val_data, epochs=50)" ] }, { @@ -393,7 +397,7 @@ " valid = [1.0 if sum(e) > 0 else np.nan for e in encoded]\n", " encoded = [np.nan_to_num(e, nan=0) for e in encoded]\n", " padded_seqs = tf.keras.preprocessing.sequence.pad_sequences(encoded, padding=\"post\")\n", - " labels = np.reshape(model.predict(padded_seqs), (-1))\n", + " labels = np.reshape(model(padded_seqs, training=False), (-1))\n", " return labels * valid" ] }, @@ -415,14 +419,16 @@ "# Make sure SMILES doesn't contain multiple fragments\n", "smi = \"CCCCC(=O)N(CC1=CC=C(C=C1)C2=C(C=CC=C2)C3=NN=N[NH]3)C(C(C)C)C(O)=O\" # mol1 - not soluble\n", "# smi = \"CC(CC(=O)NC1=CC=CC=C1)C(=O)O\" #mol2 - highly soluble\n", + "af = exmol.get_basic_alphabet()\n", "stoned_kwargs = {\n", " \"num_samples\": 5000,\n", - " \"alphabet\": exmol.get_basic_alphabet(),\n", - " \"max_mutations\": 1,\n", + " \"alphabet\": af,\n", + " \"max_mutations\": 2,\n", "}\n", "space = exmol.sample_space(\n", " smi, predictor_function, stoned_kwargs=stoned_kwargs, quiet=True\n", - ")" + ")\n", + "print(len(space))" ] }, { @@ -467,11 +473,8 @@ "source": [ "exmol.lime_explain(space, \"ecfp\")\n", "s1_ecfp = exmol.text_explain(space, \"ecfp\")\n", - "exmol.lime_explain(space, \"maccs\")\n", - "s2_maccs = exmol.text_explain(space, \"maccs\")\n", - "explanation_list = exmol.merge_text_explains(s1_ecfp[:3], s2_maccs[:3])\n", - "# explanation = exmol.text_explain_generate(explanation_list, \"aqueous solubility\")\n", - "# print(explanation)" + "explanation = exmol.text_explain_generate(s1_ecfp, \"aqueous solubility\")\n", + "print(explanation)" ] }, { From 27b775c9a654b63ec76a167fe3ec83b3d79f2d47 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Wed, 8 Mar 2023 16:19:57 -0500 Subject: [PATCH 12/26] Fixed old text generate code --- paper2_LIME/Tutorial.ipynb | 16 ++++------------ paper3_Scents/GeneratingScentExplanations.ipynb | 9 ++------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/paper2_LIME/Tutorial.ipynb b/paper2_LIME/Tutorial.ipynb index a04aee22..ca5e52e0 100644 --- a/paper2_LIME/Tutorial.ipynb +++ b/paper2_LIME/Tutorial.ipynb @@ -218,30 +218,22 @@ ] }, { - "cell_type": "code", - "execution_count": null, - "id": "4284e742", - "metadata": {}, - "outputs": [], - "source": [ - "print(exmol.text_prompt(e, property_name=\"active\"))" - ] - }, - { + "attachments": {}, "cell_type": "markdown", "id": "80053549", "metadata": {}, "source": [ - "Or you can pass it directly, by installing the `openai` package and putting an openAI key in" + "Or you can pass it directly, by installing the `langchain` package and setting-up an [openai key](https://langchain.readthedocs.io/en/latest/ecosystem/openai.html)" ] }, { + "attachments": {}, "cell_type": "markdown", "id": "39af078f", "metadata": {}, "source": [ "```python\n", - "print(exmol.text_prompt(e, property_name=\"active\", open_ai_key=XXXXXXXXXXXXX))\n", + "print(exmol.text_explain_generate(e, property_name=\"active\"))\n", "```\n", "\n", "```\n", diff --git a/paper3_Scents/GeneratingScentExplanations.ipynb b/paper3_Scents/GeneratingScentExplanations.ipynb index 9039d045..7d50a877 100644 --- a/paper3_Scents/GeneratingScentExplanations.ipynb +++ b/paper3_Scents/GeneratingScentExplanations.ipynb @@ -1040,13 +1040,8 @@ "explanation_list = exmol.merge_text_explains(s1_ecfp, s2_maccs, filter=1.96)[:5]\n", "\n", "# explanation_list = exmol.merge_text_explains(ecfp_standardized,maccs_standardized, filter=1.96)[:5]\n", - "prompt = exmol.text_prompt(explanation_list, f\"{scent} scent\")\n", - "print(f\"Prompt: {prompt}\")\n", - "\n", - "# To create NLE from prompt, uncomment code below\n", - "# openAIKey = '' #Add in open AI key here to get NLE\n", - "# nle = exmol.text_prompt(explanation_list, f'{scent} scent', open_ai_key=openAIKey))\n", - "# print(f'NLE: {nle}')" + "# nle = exmol.text_explain_generate(explanation_list, f\"{scent} scent\")\n", + "# print(f\"Prompt: {nle}\")" ] }, { From 174cd59af1a02f94c3c00cf3fe120476894620b6 Mon Sep 17 00:00:00 2001 From: Andrew White Date: Wed, 8 Mar 2023 17:02:27 -0500 Subject: [PATCH 13/26] Addded OAI key --- .github/workflows/build.yml | 2 ++ .github/workflows/tests.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c46603de..835b5f8a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,6 +29,8 @@ jobs: run: | pip install . - name: Run Test + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: | pytest tests --doctest-modules --junitxml=junit/test-results.xml --cov=com --cov-report=xml --cov-report=html # mypy -p exmol --ignore-missing-imports diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 70ab4852..9446cdda 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -32,6 +32,8 @@ jobs: run: | pip install . - name: Run Test + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: | pytest tests # mypy -p exmol --ignore-missing-imports From 7b552e59395986c36bb369f6c0d9e94fcef201c9 Mon Sep 17 00:00:00 2001 From: Heta Gandhi Date: Thu, 9 Mar 2023 11:49:32 -0500 Subject: [PATCH 14/26] merge with main --- paper2_LIME/Solubility-RNN.ipynb | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/paper2_LIME/Solubility-RNN.ipynb b/paper2_LIME/Solubility-RNN.ipynb index fa4f87e2..a0a96a29 100644 --- a/paper2_LIME/Solubility-RNN.ipynb +++ b/paper2_LIME/Solubility-RNN.ipynb @@ -206,7 +206,6 @@ "metadata": {}, "outputs": [], "source": [ - "# creating an object\n", "@dataclass\n", "class Config:\n", " vocab_size: int\n", @@ -306,7 +305,7 @@ "source": [ "model.compile(tf.optimizers.Adam(1e-3), loss=\"mean_squared_error\")\n", "# verbose=0 silences output, to get progress bar set verbose=1\n", - "result = model.fit(train_data, validation_data=val_data, epochs=50)" + "result = model.fit(train_data, validation_data=val_data, epochs=50) # , verbose=0)" ] }, { @@ -523,6 +522,25 @@ ")" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Text explanations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "exmol.lime_explain(filtered_space, \"ecfp\")\n", + "s1_ecfp = exmol.text_explain(filtered_space, \"ecfp\")\n", + "explanation = exmol.text_explain_generate(s1_ecfp, \"aqueous solubility\")\n", + "print(explanation)" + ] + }, { "cell_type": "markdown", "metadata": {}, From 3b550172ae510206202c3ba6b0b2d511d383ea6a Mon Sep 17 00:00:00 2001 From: Andrew White Date: Thu, 9 Mar 2023 13:58:24 -0500 Subject: [PATCH 15/26] Added openai to dev requirements --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 75ac169d..c4363f6b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ mypy pytest pytest-cov click +openai From 6e8359410b06a45f0608485ce88bdbb759b3d7ac Mon Sep 17 00:00:00 2001 From: Andrew White Date: Thu, 9 Mar 2023 16:45:29 -0500 Subject: [PATCH 16/26] Added OAI Key and uncommented explains --- .github/workflows/paper.yml | 6 ++++++ paper2_LIME/Tutorial.ipynb | 15 +++++---------- paper3_Scents/GeneratingScentExplanations.ipynb | 4 ++-- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.github/workflows/paper.yml b/.github/workflows/paper.yml index eae4a1de..32ee953f 100644 --- a/.github/workflows/paper.yml +++ b/.github/workflows/paper.yml @@ -28,14 +28,20 @@ jobs: run: | pip install -r paper1_CFs/requirements.txt - name: Run paper1 experiments + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: jupyter nbconvert --ExecutePreprocessor.timeout=-1 --execute "paper1_CFs/*.ipynb" --to notebook --output-dir='temp' --clear-output - name: Install paper2 depends run: | pip install -r paper2_LIME/requirements.txt - name: Run paper2 experiments + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: jupyter nbconvert --ExecutePreprocessor.timeout=-1 --execute "paper2_LIME/*.ipynb" --to notebook --output-dir='temp' --clear-output - name: Install paper3 depends run: | pip install -r paper3_Scents/requirements.txt - name: Run paper3 experiments + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: jupyter nbconvert --ExecutePreprocessor.timeout=-1 --execute "paper3_Scents/*.ipynb" --to notebook --output-dir='temp' --clear-output diff --git a/paper2_LIME/Tutorial.ipynb b/paper2_LIME/Tutorial.ipynb index ca5e52e0..e73e9d63 100644 --- a/paper2_LIME/Tutorial.ipynb +++ b/paper2_LIME/Tutorial.ipynb @@ -227,18 +227,13 @@ ] }, { - "attachments": {}, - "cell_type": "markdown", - "id": "39af078f", + "cell_type": "code", + "execution_count": null, + "id": "0fa7f45c", "metadata": {}, + "outputs": [], "source": [ - "```python\n", - "print(exmol.text_explain_generate(e, property_name=\"active\"))\n", - "```\n", - "\n", - "```\n", - "The molecular property \"active\" can be explained by the presence of a primary alcohol, which is a very important attribute for this property.\n", - "```" + "print(exmol.text_explain_generate(e, property_name=\"active\"))" ] } ], diff --git a/paper3_Scents/GeneratingScentExplanations.ipynb b/paper3_Scents/GeneratingScentExplanations.ipynb index 7d50a877..bbc9d3df 100644 --- a/paper3_Scents/GeneratingScentExplanations.ipynb +++ b/paper3_Scents/GeneratingScentExplanations.ipynb @@ -1040,8 +1040,8 @@ "explanation_list = exmol.merge_text_explains(s1_ecfp, s2_maccs, filter=1.96)[:5]\n", "\n", "# explanation_list = exmol.merge_text_explains(ecfp_standardized,maccs_standardized, filter=1.96)[:5]\n", - "# nle = exmol.text_explain_generate(explanation_list, f\"{scent} scent\")\n", - "# print(f\"Prompt: {nle}\")" + "nle = exmol.text_explain_generate(explanation_list, f\"{scent} scent\")\n", + "print(nle)" ] }, { From 2de9cb50223254a811ba160e2848d8b6d09f54ad Mon Sep 17 00:00:00 2001 From: Heta Gandhi Date: Mon, 27 Nov 2023 09:12:22 -0800 Subject: [PATCH 17/26] Adding BBB notebook --- paper2_LIME/BBB-RNN.ipynb | 692 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 692 insertions(+) create mode 100644 paper2_LIME/BBB-RNN.ipynb diff --git a/paper2_LIME/BBB-RNN.ipynb b/paper2_LIME/BBB-RNN.ipynb new file mode 100644 index 00000000..f21c160e --- /dev/null +++ b/paper2_LIME/BBB-RNN.ipynb @@ -0,0 +1,692 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# LIME paper: Recurrent Neural Network for Blood brain barrier permeation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Import packages and set up RNN" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "\n", + "os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"0\"\n", + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "from matplotlib.patches import Rectangle, FancyBboxPatch\n", + "from matplotlib.offsetbox import AnnotationBbox\n", + "import seaborn as sns\n", + "import textwrap\n", + "import skunk\n", + "import matplotlib as mpl\n", + "import numpy as np\n", + "import tensorflow as tf\n", + "import selfies as sf\n", + "import exmol\n", + "from dataclasses import dataclass\n", + "from rdkit.Chem.Draw import rdDepictor, MolsToGridImage\n", + "from rdkit.Chem import MolFromSmiles, MACCSkeys\n", + "\n", + "rdDepictor.SetPreferCoordGen(True)\n", + "import matplotlib.font_manager as font_manager\n", + "import urllib.request\n", + "\n", + "urllib.request.urlretrieve(\n", + " \"https://github.com/google/fonts/raw/main/ofl/ibmplexmono/IBMPlexMono-Regular.ttf\",\n", + " \"IBMPlexMono-Regular.ttf\",\n", + ")\n", + "fe = font_manager.FontEntry(fname=\"IBMPlexMono-Regular.ttf\", name=\"plexmono\")\n", + "font_manager.fontManager.ttflist.append(fe)\n", + "plt.rcParams.update(\n", + " {\n", + " \"axes.facecolor\": \"#f5f4e9\",\n", + " \"grid.color\": \"#AAAAAA\",\n", + " \"axes.edgecolor\": \"#333333\",\n", + " \"figure.facecolor\": \"#FFFFFF\",\n", + " \"axes.grid\": False,\n", + " \"axes.prop_cycle\": plt.cycler(\"color\", plt.cm.Dark2.colors),\n", + " \"font.family\": fe.name,\n", + " \"figure.figsize\": (3.5, 3.5 / 1.2),\n", + " \"ytick.left\": True,\n", + " \"xtick.bottom\": True,\n", + " }\n", + ")\n", + "\n", + "color_cycle = [\"#F06060\", \"#1BBC9B\", \"#F06060\", \"#5C4B51\", \"#F3B562\", \"#6e5687\"]\n", + "mpl.rcParams[\"axes.prop_cycle\"] = mpl.cycler(color=color_cycle)\n", + "mpl.rcParams[\"font.size\"] = 10\n", + "bbb_data = pd.read_csv(\"../paper1_CFs/BBBP.csv\")\n", + "# features_start_at = list(bbb_data.columns).index(\"MolWt\")\n", + "np.random.seed(0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# scramble them\n", + "bbb_data = bbb_data.sample(frac=1, random_state=0).reset_index(drop=True)\n", + "bbb_data.head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from rdkit.Chem import MolToSmiles\n", + "\n", + "\n", + "def _randomize_smiles(mol, isomericSmiles=True):\n", + " return MolToSmiles(\n", + " mol,\n", + " canonical=False,\n", + " doRandom=True,\n", + " isomericSmiles=isomericSmiles,\n", + " kekuleSmiles=random.random() < 0.5,\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import random\n", + "\n", + "smiles = list(bbb_data[\"smiles\"])\n", + "permeabilities = list(bbb_data[\"p_np\"])\n", + "\n", + "aug_data = 0\n", + "\n", + "aug_smiles = []\n", + "aug_perm = []\n", + "for sml, sol in zip(smiles, permeabilities):\n", + " new_smls = []\n", + " new_smls.append(sml)\n", + " aug_perm.append(sol)\n", + " for _ in range(aug_data):\n", + " try:\n", + " new_sml = _randomize_smiles(MolFromSmiles(sml))\n", + " # print(new_sml)\n", + " if new_sml not in new_smls:\n", + " new_smls.append(new_sml)\n", + " aug_perm.append(sol)\n", + " except:\n", + " continue\n", + " aug_smiles.extend(new_smls)\n", + "\n", + "aug_df_bbb = pd.DataFrame(data={\"smiles\": aug_smiles, \"p_np\": aug_perm})\n", + "\n", + "print(f\"The dataset was augmented from {len(bbb_data)} to {len(aug_df_bbb)}.\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "selfies_list = []\n", + "for i, s in enumerate(aug_df_bbb.smiles):\n", + " try:\n", + " selfies_list.append(sf.encoder(exmol.sanitize_smiles(s)[1]))\n", + " except (sf.EncoderError, TypeError):\n", + " selfies_list.append(None)\n", + " bbb_data.smiles[i] = exmol.sanitize_smiles(s)[1]\n", + "len(selfies_list)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "basic = set(exmol.get_basic_alphabet())\n", + "data_vocab = set(\n", + " sf.get_alphabet_from_selfies([s for s in selfies_list if s is not None])\n", + ")\n", + "vocab = ['[nop]']\n", + "vocab.extend(list(data_vocab.union(basic)))\n", + "vocab_stoi = {o: i for o, i in zip(vocab, range(len(vocab)))}\n", + "\n", + "\n", + "def selfies2ints(s):\n", + " result = []\n", + " for token in sf.split_selfies(s):\n", + " if token == '.':\n", + " continue # ?\n", + " if token in vocab_stoi:\n", + " result.append(vocab_stoi[token])\n", + " else:\n", + " print(token)\n", + " result.append(np.nan)\n", + " # print('Warning')\n", + " return result\n", + "\n", + "\n", + "def ints2selfies(v):\n", + " return \"\".join([vocab[i] for i in v])\n", + "\n", + "\n", + "# test them out\n", + "s = selfies_list[0]\n", + "print('selfies:', s)\n", + "v = selfies2ints(s)\n", + "print('selfies2ints:', v)\n", + "so = ints2selfies(v)\n", + "print('ints2selfes:', so)\n", + "assert so == s.replace(\n", + " '.', ''\n", + ") # make sure '.' is removed from Selfies string during assertion" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# creating an object\n", + "@dataclass\n", + "class Config:\n", + " vocab_size: int\n", + " example_number: int\n", + " batch_size: int\n", + " buffer_size: int\n", + " embedding_dim: int\n", + " rnn_units: int\n", + " hidden_dim: int\n", + " drop_rate: float\n", + "\n", + "\n", + "config = Config(\n", + " vocab_size=len(vocab),\n", + " example_number=len(selfies_list),\n", + " batch_size=128,\n", + " buffer_size=10000,\n", + " embedding_dim=64,\n", + " hidden_dim=32,\n", + " rnn_units=64,\n", + " drop_rate=0.20,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# now get sequences\n", + "encoded = [selfies2ints(s) for s in selfies_list if s is not None]\n", + "padded_seqs = tf.keras.preprocessing.sequence.pad_sequences(encoded, padding=\"post\")\n", + "\n", + "permeabilities = aug_df_bbb.p_np.values[[bool(s) for s in selfies_list]]\n", + "\n", + "# Should be shuffled from the beginning, so no worries\n", + "N = len(padded_seqs)\n", + "split = int(0.1 * N)\n", + "\n", + "# Now build dataset\n", + "test_data = tf.data.Dataset.from_tensor_slices(\n", + " (padded_seqs[:split], permeabilities[:split])\n", + ").batch(config.batch_size)\n", + "\n", + "nontest = tf.data.Dataset.from_tensor_slices(\n", + " (\n", + " padded_seqs[split:],\n", + " permeabilities[split:],\n", + " )\n", + ")\n", + "\n", + "val_data, train_data = nontest.take(split).batch(config.batch_size), nontest.skip(\n", + " split\n", + ").shuffle(config.buffer_size).batch(config.batch_size).prefetch(\n", + " tf.data.experimental.AUTOTUNE\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "model = tf.keras.Sequential()\n", + "\n", + "# make embedding and indicate that 0 should be treated as padding mask\n", + "model.add(\n", + " tf.keras.layers.Embedding(\n", + " input_dim=config.vocab_size, output_dim=config.embedding_dim, mask_zero=True\n", + " )\n", + ")\n", + "model.add(tf.keras.layers.Dropout(config.drop_rate))\n", + "# RNN layer\n", + "model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(config.rnn_units)))\n", + "model.add(tf.keras.layers.Dropout(config.drop_rate))\n", + "# a dense hidden layer\n", + "model.add(tf.keras.layers.Dense(config.hidden_dim, activation=\"relu\"))\n", + "model.add(tf.keras.layers.Dropout(config.drop_rate))\n", + "# regression, so no activation\n", + "model.add(tf.keras.layers.Dense(1))\n", + "\n", + "model.summary()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "model.compile(\n", + " tf.optimizers.Adam(1e-3),\n", + " loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),\n", + " metrics=[\"accuracy\"],\n", + ")\n", + "# verbose=0 silences output, to get progress bar set verbose=1\n", + "result = model.fit(train_data, validation_data=val_data, epochs=100, verbose=1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "model.save(\"bbbp-rnn\")\n", + "# model = tf.keras.models.load_model('solubility-rnn-accurate/')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# plot test data\n", + "fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))\n", + "ax1.plot(result.history[\"loss\"], label=\"training\")\n", + "ax1.plot(result.history[\"val_loss\"], label=\"validation\")\n", + "ax1.legend()\n", + "ax1.set_xlabel(\"Epoch\")\n", + "ax1.set_ylabel(\"Loss\")\n", + "\n", + "ax2.plot(result.history[\"accuracy\"], label=\"training\")\n", + "ax2.plot(result.history[\"val_accuracy\"], label=\"validation\")\n", + "ax2.legend()\n", + "ax2.set_xlabel(\"Epoch\")\n", + "ax2.set_ylabel(\"Accuracy\")\n", + "fig.tight_layout()\n", + "fig.savefig(\"bbp-rnn-loss-acc.png\", dpi=180)\n", + "fig.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from sklearn.metrics import roc_curve\n", + "from sklearn.metrics import auc\n", + "\n", + "prediction = []\n", + "test_y = []\n", + "\n", + "for x, y in test_data:\n", + " prediction.extend(model(x).numpy().flatten())\n", + " test_y.extend(y.numpy().flatten())\n", + "\n", + "prediction = np.array(prediction).flatten()\n", + "test_y = np.array(test_y)\n", + "\n", + "fpr_keras, tpr_keras, thresholds_keras = roc_curve(test_y, prediction)\n", + "auc_keras = auc(fpr_keras, tpr_keras)\n", + "\n", + "plt.figure(figsize=(5, 3.5), dpi=100)\n", + "plt.plot(fpr_keras, tpr_keras, label=\"AUC = {:.3f}\".format(auc_keras))\n", + "plt.plot([0, 1], [0, 1], linestyle=\"--\")\n", + "plt.xlabel(\"False Positive Rate\")\n", + "plt.ylabel(\"True Positive Rate\")\n", + "plt.legend()\n", + "plt.savefig(\"bbbp-rnn-roc.png\", dpi=300)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## LIME explanations\n", + "\n", + "In the following example, we find out what descriptors influence solubility of a molecules. For example, let's say we have a molecule with LogS=1.5. We create a perturbed chemical space around that molecule using `stoned` method and then use `lime` to find out which descriptors affect solubility predictions for that molecule. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Wrapper function for RNN, to use in STONED" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Predictor function is used as input to sample_space function\n", + "def predictor_function(smile_list, selfies):\n", + " if len(selfies) < 1:\n", + " selfies = [sf.encoder(s) for s in smile_list]\n", + " encoded = [selfies2ints(s) for s in selfies]\n", + " # check for nans\n", + " valid = [1.0 if sum(e) > 0 else np.nan for e in encoded]\n", + " encoded = [np.nan_to_num(e, nan=0) for e in encoded]\n", + " padded_seqs = tf.keras.preprocessing.sequence.pad_sequences(encoded, padding=\"post\")\n", + " labels = np.reshape(model.predict(padded_seqs), (-1))\n", + " return labels" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Other ploting utilities" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "def space_fit_plot(space, beta, mode=\"regression\"):\n", + " fkw = {\"figsize\": (10, 4)}\n", + " font = {\"family\": \"normal\", \"weight\": \"normal\", \"size\": 16}\n", + "\n", + " fig = plt.figure(figsize=(10, 5))\n", + " mpl.rc(\"axes\", titlesize=12)\n", + " mpl.rc(\"font\", size=16)\n", + " ax_dict = fig.subplot_mosaic(\"AABBB\")\n", + "\n", + " # Plot space by fit\n", + " svg = exmol.plot_utils.plot_space_by_fit(\n", + " space,\n", + " [space[0]],\n", + " figure_kwargs=fkw,\n", + " mol_size=(200, 200),\n", + " offset=1,\n", + " ax=ax_dict[\"B\"],\n", + " beta=beta,\n", + " )\n", + " # Compute y_wls\n", + " w = np.array([1 / (1 + (1 / (e.similarity + 0.000001) - 1) ** 5) for e in space])\n", + " non_zero = w > 10 ** (-6)\n", + " w = w[non_zero]\n", + " N = w.shape[0]\n", + "\n", + " ys = np.array([e.yhat for e in space])[non_zero].reshape(N).astype(float)\n", + " x_mat = np.array([list(e.descriptors.descriptors) for e in space])[\n", + " non_zero\n", + " ].reshape(N, -1)\n", + " y_wls = x_mat @ beta\n", + " y_wls += np.mean(ys)\n", + "\n", + " lower = np.min(ys)\n", + " higher = np.max(ys)\n", + "\n", + " # set transparency using w\n", + " norm = plt.Normalize(min(w), max(w))\n", + " cmap = plt.cm.Oranges(w)\n", + " cmap[:, -1] = w\n", + "\n", + " def weighted_mean(x, w):\n", + " return np.sum(x * w) / np.sum(w)\n", + "\n", + " def weighted_cov(x, y, w):\n", + " return np.sum(\n", + " w * (x - weighted_mean(x, w)) * (y - weighted_mean(y, w))\n", + " ) / np.sum(w)\n", + "\n", + " def weighted_correlation(x, y, w):\n", + " return weighted_cov(x, y, w) / np.sqrt(\n", + " weighted_cov(x, x, w) * weighted_cov(y, y, w)\n", + " )\n", + "\n", + " corr = weighted_correlation(ys, y_wls, w)\n", + "\n", + " if mode == \"regression\":\n", + " ax_dict[\"A\"].plot(\n", + " np.linspace(lower, higher, 100),\n", + " np.linspace(lower, higher, 100),\n", + " \"--\",\n", + " linewidth=2,\n", + " )\n", + " sc = ax_dict[\"A\"].scatter(ys, y_wls, s=50, marker=\".\", c=cmap, cmap=cmap)\n", + " ax_dict[\"A\"].text(\n", + " max(ys) - 10,\n", + " min(ys) + 1,\n", + " f\"weighted \\ncorrelation = {corr:.3f}\",\n", + " fontsize=10,\n", + " )\n", + " ax_dict[\"A\"].set_xlabel(r\"$\\hat{y}$\")\n", + " ax_dict[\"A\"].set_ylabel(r\"$g$\")\n", + " ax_dict[\"A\"].set_title(\"Weighted Least Squares Fit\")\n", + " ax_dict[\"A\"].set_xlim(lower, higher)\n", + " ax_dict[\"A\"].set_ylim(lower, higher)\n", + " ax_dict[\"A\"].set_aspect(1.0 / ax_dict[\"A\"].get_data_ratio(), adjustable=\"box\")\n", + " sm = plt.cm.ScalarMappable(cmap=plt.cm.Oranges, norm=norm)\n", + " cbar = plt.colorbar(sm, orientation=\"horizontal\", pad=0.15, ax=ax_dict[\"A\"])\n", + " cbar.set_label(\"Chemical similarity\")\n", + " plt.tight_layout()\n", + " plt.savefig(\"weighted_fit.svg\", dpi=300, bbox_inches=\"tight\", transparent=False)\n", + " if mode == \"classification\":\n", + " fpr_keras, tpr_keras, thresholds_keras = roc_curve(ys, y_wls)\n", + " auc_keras = auc(fpr_keras, tpr_keras)\n", + " ax_dict[\"A\"].plot(fpr_keras, tpr_keras, label=\"AUC = {:.3f}\".format(auc_keras))\n", + " ax_dict[\"A\"].plot([0, 1], [0, 1], linestyle=\"--\")\n", + " ax_dict[\"A\"].set_xlabel(\"False Positive Rate\")\n", + " ax_dict[\"A\"].set_ylabel(\"True Positive Rate\")\n", + " ax_dict[\"A\"].set_aspect(1.0 / ax_dict[\"A\"].get_data_ratio(), adjustable=\"box\")\n", + " ax_dict[\"A\"].legend()\n", + " plt.tight_layout()\n", + " plt.savefig(\"space_fit.svg\", dpi=300)\n", + " plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Descriptor explanations" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# smi = 'Cc1onc(-c2ccccc2Cl)c1C(=O)NC1C(=O)N2C1SC(C)(C)C2C(=O)O'\n", + "# smi = soldata.SMILES[1400]\n", + "ibuprofen = \"CC(C)CC1=CC=C(C=C1)C(C)C(=O)O\" # ibuprofen is known to cross BBB\n", + "nicotine = bbb_data.smiles[bbb_data.name == \"nicotine\"].values[0] # treat anxiety\n", + "caffeine = bbb_data.smiles[bbb_data.name == \"caffeine\"].values[0]\n", + "chlorpromazine = \"CN(CCCN1c2ccccc2Sc2c1cc(Cl)cc2)C\"\n", + "gleevec = \"Cc1ccc(cc1Nc2nccc(n2)c3cccnc3)NC(=O)c4ccc(cc4)CN5CCN(CC5)C\"\n", + "# mol = MolFromSmiles(smi)\n", + "# from rdkit.Chem.Draw import MolToFile\n", + "\n", + "# MolToFile(mol, 'mol_paper.svg')\n", + "predictor_function([ibuprofen, nicotine, caffeine, chlorpromazine, gleevec], [])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "diazepam = \"CN1C(=O)CN=C(C2=C1C=CC(=C2)Cl)C3=CC=CC=C3\"\n", + "predictor_function([diazepam], [])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "# Make sure SMILES doesn't contain multiple fragments\n", + "# smi = soldata.SMILES[1400]\n", + "# print(smi)\n", + "alprozolam = \"CC1=NN=C2N1C3=C(C=C(C=C3)Cl)C(=NC2)C4=CC=CC=C4\"\n", + "stoned_kwargs = {\n", + " \"num_samples\": 5000,\n", + " \"alphabet\": exmol.get_basic_alphabet(),\n", + " \"max_mutations\": 1,\n", + "}\n", + "space = exmol.sample_space(alprozolam, predictor_function, stoned_kwargs=stoned_kwargs)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Filter space\n", + "from synspace.reos import REOS\n", + "\n", + "reos = REOS()\n", + "\n", + "filtered_space = []\n", + "for e in space:\n", + " if reos.process_mol(MolFromSmiles(e.smiles)) == (\"ok\", \"ok\"):\n", + " filtered_space.append(e)\n", + "\n", + "len(filtered_space)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "from IPython.display import display, SVG\n", + "\n", + "desc_type = [\"Classic\", \"ECFP\", \"MACCS\"]\n", + "fkw = {\"figsize\": (6, 4)}\n", + "for d in desc_type:\n", + " beta = exmol.lime_explain(filtered_space, descriptor_type=d)\n", + " if d == \"Classic\":\n", + " exmol.plot_descriptors(filtered_space, output_file=f\"alprozolam_{d}.svg\")\n", + " else:\n", + " svg = exmol.plot_descriptors(\n", + " filtered_space, output_file=f\"alprozolam_{d}.svg\", return_svg=True\n", + " )\n", + " plt.close()\n", + " skunk.display(svg)\n", + " space_fit_plot(filtered_space, beta, mode=\"regression\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": false + }, + "outputs": [], + "source": [ + "exmol.lime_explain(filtered_space, \"ECFP\")\n", + "_ = exmol.plot_utils.similarity_map_using_tstats(filtered_space[0], return_svg=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "display(SVG(_))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "OPEN_AI_KEY = os.environ.get(\"OPENAI_API_KEY\")\n", + "exmol.lime_explain(filtered_space, \"ecfp\")\n", + "s1_ecfp = exmol.text_explain(filtered_space, \"ecfp\")\n", + "explanation = exmol.text_explain_generate(s1_ecfp, \"aqueous solubility\")\n", + "print(explanation)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "interpreter": { + "hash": "abc1ef2aae668f29add333aedc207234808b19831866b8480f007a054a2482dc" + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.7.13" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} From 1a40851c51459b58c3ad484c68db3ff76ac7a826 Mon Sep 17 00:00:00 2001 From: Heta Gandhi Date: Mon, 4 Dec 2023 08:29:37 -0800 Subject: [PATCH 18/26] testing pre-commit --- paper2_LIME/BBB-RNN.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paper2_LIME/BBB-RNN.ipynb b/paper2_LIME/BBB-RNN.ipynb index f21c160e..54ee07ea 100644 --- a/paper2_LIME/BBB-RNN.ipynb +++ b/paper2_LIME/BBB-RNN.ipynb @@ -684,7 +684,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.13" + "version": "3.7.12" } }, "nbformat": 4, From 2e7a69a3ea763de457fcd6f1eae4150d437949a8 Mon Sep 17 00:00:00 2001 From: geemi725 Date: Thu, 7 Dec 2023 15:22:55 +0100 Subject: [PATCH 19/26] remove langchain dependency --- exmol/exmol.py | 25 +++++++++++++++---------- paper2_LIME/RF-lime.ipynb | 11 +++++++---- paper2_LIME/Solubility-RNN.ipynb | 9 ++------- paper2_LIME/requirements.txt | 1 + 4 files changed, 25 insertions(+), 21 deletions(-) diff --git a/exmol/exmol.py b/exmol/exmol.py index eabe072a..12914d12 100644 --- a/exmol/exmol.py +++ b/exmol/exmol.py @@ -27,9 +27,8 @@ from rdkit.Chem.Draw import MolToImage as mol2img, DrawMorganBit # type: ignore from rdkit.Chem import rdchem # type: ignore from rdkit.DataStructs.cDataStructs import BulkTanimotoSimilarity, TanimotoSimilarity # type: ignore -import langchain.llms as llms -import langchain.prompts as prompts +import openai from . import stoned from .plot_utils import _mol_images, _image_scatter, _bit2atoms from .data import * @@ -392,6 +391,7 @@ def _check_alphabet_consistency( alphabet_symbols = _alphabet_to_elements(set(alphabet_symbols)) # find all elements in smiles (Upper alpha or upper alpha followed by lower alpha) smiles_symbols = set(re.findall(r"[A-Z][a-z]?", smiles)) + if check and not smiles_symbols.issubset(alphabet_symbols): # show which symbols are not in alphabet raise ValueError( @@ -1410,7 +1410,7 @@ def merge_text_explains( def text_explain_generate( text_explanations: List[Tuple[str, float]], property_name: str, - llm: Optional[llms.BaseLLM] = None, + llm_model: str = 'gpt-4', single: bool = True, ) -> str: """Insert text explanations into template, and generate explanation. @@ -1430,14 +1430,19 @@ def text_explain_generate( for x in text_explanations ] ) - prompt_template = prompts.PromptTemplate( - input_variables=["property", "text"], - template=_single_prompt if single else _multi_prompt, - ) + + prompt_template = _single_prompt if single else _multi_prompt prompt = prompt_template.format(property=property_name, text=text) - if llm is None: - llm = llms.OpenAI(temperature=0.05) - return llm(prompt) + + messages = [{"role": "system", "content": "Your goal is to explain which molecular features are important to its properties based on the given text."}, + {"role": "user", "content": prompt}] + response = openai.ChatCompletion.create( + model=llm_model, + messages=messages, + temperature=0.05, + ) + + return response.choices[0].message["content"] def text_explain( diff --git a/paper2_LIME/RF-lime.ipynb b/paper2_LIME/RF-lime.ipynb index e14a2fa3..a8b4b6be 100644 --- a/paper2_LIME/RF-lime.ipynb +++ b/paper2_LIME/RF-lime.ipynb @@ -30,7 +30,7 @@ "import numpy as np\n", "import mordred, mordred.descriptors\n", "from mordred import HydrogenBond, Polarizability\n", - "from mordred import SLogP, AcidBase, BertzCT, Aromatic, BondCount, AtomCount\n", + "from mordred import SLogP, AcidBase, Aromatic, BondCount, AtomCount\n", "from mordred import Calculator\n", "\n", "import exmol as exmol\n", @@ -38,7 +38,6 @@ "import os\n", "from sklearn.ensemble import RandomForestRegressor\n", "from sklearn.model_selection import train_test_split\n", - "from sklearn.metrics import roc_auc_score, plot_roc_curve\n", "\n", "os.environ[\"CUDA_VISIBLE_DEVICES\"] = \"0\"\n", "rdDepictor.SetPreferCoordGen(True)\n", @@ -50,6 +49,9 @@ "soldata = pd.read_csv(\n", " \"https://github.com/whitead/dmol-book/raw/main/data/curated-solubility-dataset.csv\"\n", ")\n", + "#drop smile with containing 'P'\n", + "soldata = soldata[soldata[\"SMILES\"].str.contains(\"P\") == False]\n", + "\n", "features_start_at = list(soldata.columns).index(\"MolWt\")" ] }, @@ -97,7 +99,8 @@ "outputs": [], "source": [ "raw_features = np.array(raw_features)\n", - "labels = soldata[\"Solubility\"]" + "labels = soldata[\"Solubility\"]\n", + "print(len(labels)==len(molecules))" ] }, { @@ -197,7 +200,7 @@ "metadata": {}, "outputs": [], "source": [ - "smi = soldata.SMILES[1500]\n", + "smi = soldata.SMILES[150]\n", "stoned_kwargs = {\n", " \"num_samples\": 2000,\n", " \"alphabet\": exmol.get_basic_alphabet(),\n", diff --git a/paper2_LIME/Solubility-RNN.ipynb b/paper2_LIME/Solubility-RNN.ipynb index 450e2355..e37352f7 100644 --- a/paper2_LIME/Solubility-RNN.ipynb +++ b/paper2_LIME/Solubility-RNN.ipynb @@ -22,10 +22,6 @@ "source": [ "import pandas as pd\n", "import matplotlib.pyplot as plt\n", - "from matplotlib.patches import Rectangle, FancyBboxPatch\n", - "from matplotlib.offsetbox import AnnotationBbox\n", - "import seaborn as sns\n", - "import skunk\n", "import matplotlib as mpl\n", "import numpy as np\n", "import tensorflow as tf\n", @@ -33,10 +29,8 @@ "import exmol\n", "from dataclasses import dataclass\n", "from rdkit.Chem.Draw import rdDepictor, MolsToGridImage\n", - "from rdkit.Chem import MolFromSmiles, MACCSkeys\n", + "from rdkit.Chem import MolFromSmiles\n", "import random\n", - "\n", - "\n", "rdDepictor.SetPreferCoordGen(True)\n", "import matplotlib.pyplot as plt\n", "import matplotlib.font_manager as font_manager\n", @@ -66,6 +60,7 @@ "soldata = pd.read_csv(\n", " \"https://github.com/whitead/dmol-book/raw/main/data/curated-solubility-dataset.csv\"\n", ")\n", + "\n", "features_start_at = list(soldata.columns).index(\"MolWt\")\n", "np.random.seed(0)\n", "random.seed(0)" diff --git a/paper2_LIME/requirements.txt b/paper2_LIME/requirements.txt index afd9ef0d..a14ed138 100644 --- a/paper2_LIME/requirements.txt +++ b/paper2_LIME/requirements.txt @@ -4,3 +4,4 @@ jupyter seaborn pandas tensorflow>=2.4 + From a932c8b34f754ca13e41df64f5be8f165118dca8 Mon Sep 17 00:00:00 2001 From: geemi725 Date: Thu, 7 Dec 2023 15:23:52 +0100 Subject: [PATCH 20/26] remove langchain from setup.py --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index 2333f616..8c6655b2 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,6 @@ "skunk >= 0.4.0", "importlib-resources", "synspace", - "langchain==0.0.343", ], test_suite="tests", long_description=long_description, From bf6aeb3683ca4811ca807f00d84f013fec70b22a Mon Sep 17 00:00:00 2001 From: Heta Gandhi Date: Thu, 7 Dec 2023 10:28:11 -0800 Subject: [PATCH 21/26] Fixed pre-commit phew --- .pre-commit-config.yaml | 6 +++--- paper2_LIME/BBB-RNN.ipynb | 28 +++++++--------------------- 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3416cbc7..32f933ec 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,12 +1,12 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.2.3 + rev: v4.5.0 hooks: - - id: trailing-whitespace - id: check-yaml - id: end-of-file-fixer + - id: trailing-whitespace - id: mixed-line-ending - - repo: https://github.com/psf/black + - repo: https://github.com/psf/black-pre-commit-mirror rev: "23.11.0" hooks: - id: black diff --git a/paper2_LIME/BBB-RNN.ipynb b/paper2_LIME/BBB-RNN.ipynb index 54ee07ea..70b5a764 100644 --- a/paper2_LIME/BBB-RNN.ipynb +++ b/paper2_LIME/BBB-RNN.ipynb @@ -232,9 +232,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "scrolled": true - }, + "metadata": {}, "outputs": [], "source": [ "# now get sequences\n", @@ -269,9 +267,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "scrolled": false - }, + "metadata": {}, "outputs": [], "source": [ "model = tf.keras.Sequential()\n", @@ -298,9 +294,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "scrolled": true - }, + "metadata": {}, "outputs": [], "source": [ "model.compile(\n", @@ -423,9 +417,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "scrolled": false - }, + "metadata": {}, "outputs": [], "source": [ "def space_fit_plot(space, beta, mode=\"regression\"):\n", @@ -562,9 +554,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "scrolled": true - }, + "metadata": {}, "outputs": [], "source": [ "# Make sure SMILES doesn't contain multiple fragments\n", @@ -601,9 +591,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "scrolled": false - }, + "metadata": {}, "outputs": [], "source": [ "from IPython.display import display, SVG\n", @@ -626,9 +614,7 @@ { "cell_type": "code", "execution_count": null, - "metadata": { - "scrolled": false - }, + "metadata": {}, "outputs": [], "source": [ "exmol.lime_explain(filtered_space, \"ECFP\")\n", From c14cbd7243a44678c8ec493fbea0b1143a36cf43 Mon Sep 17 00:00:00 2001 From: Heta Gandhi Date: Thu, 7 Dec 2023 10:51:52 -0800 Subject: [PATCH 22/26] merge with Geemi's changes --- exmol/exmol.py | 15 ++++++++++----- paper2_LIME/requirements.txt | 1 - 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/exmol/exmol.py b/exmol/exmol.py index 12914d12..a51da1b9 100644 --- a/exmol/exmol.py +++ b/exmol/exmol.py @@ -391,7 +391,7 @@ def _check_alphabet_consistency( alphabet_symbols = _alphabet_to_elements(set(alphabet_symbols)) # find all elements in smiles (Upper alpha or upper alpha followed by lower alpha) smiles_symbols = set(re.findall(r"[A-Z][a-z]?", smiles)) - + if check and not smiles_symbols.issubset(alphabet_symbols): # show which symbols are not in alphabet raise ValueError( @@ -1410,7 +1410,7 @@ def merge_text_explains( def text_explain_generate( text_explanations: List[Tuple[str, float]], property_name: str, - llm_model: str = 'gpt-4', + llm_model: str = "gpt-4", single: bool = True, ) -> str: """Insert text explanations into template, and generate explanation. @@ -1430,12 +1430,17 @@ def text_explain_generate( for x in text_explanations ] ) - + prompt_template = _single_prompt if single else _multi_prompt prompt = prompt_template.format(property=property_name, text=text) - messages = [{"role": "system", "content": "Your goal is to explain which molecular features are important to its properties based on the given text."}, - {"role": "user", "content": prompt}] + messages = [ + { + "role": "system", + "content": "Your goal is to explain which molecular features are important to its properties based on the given text.", + }, + {"role": "user", "content": prompt}, + ] response = openai.ChatCompletion.create( model=llm_model, messages=messages, diff --git a/paper2_LIME/requirements.txt b/paper2_LIME/requirements.txt index a14ed138..afd9ef0d 100644 --- a/paper2_LIME/requirements.txt +++ b/paper2_LIME/requirements.txt @@ -4,4 +4,3 @@ jupyter seaborn pandas tensorflow>=2.4 - From 558393b2a122e790babc75cfd076bb1253ea5832 Mon Sep 17 00:00:00 2001 From: Heta Gandhi Date: Thu, 7 Dec 2023 11:11:18 -0800 Subject: [PATCH 23/26] Ran openai migrate, test_synspace_anybond failing? --- exmol/exmol.py | 10 +++++----- tests/test_exmol.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/exmol/exmol.py b/exmol/exmol.py index a51da1b9..fcb8e1aa 100644 --- a/exmol/exmol.py +++ b/exmol/exmol.py @@ -28,7 +28,9 @@ from rdkit.Chem import rdchem # type: ignore from rdkit.DataStructs.cDataStructs import BulkTanimotoSimilarity, TanimotoSimilarity # type: ignore -import openai +from openai import OpenAI + +client = OpenAI() from . import stoned from .plot_utils import _mol_images, _image_scatter, _bit2atoms from .data import * @@ -1441,10 +1443,8 @@ def text_explain_generate( }, {"role": "user", "content": prompt}, ] - response = openai.ChatCompletion.create( - model=llm_model, - messages=messages, - temperature=0.05, + response = client.chat.completions.create( + model=llm_model, messages=messages, temperature=0.05 ) return response.choices[0].message["content"] diff --git a/tests/test_exmol.py b/tests/test_exmol.py index 9c9bf236..ae64bd25 100644 --- a/tests/test_exmol.py +++ b/tests/test_exmol.py @@ -458,7 +458,7 @@ def model(s, se): s = exmol.text_explain(samples, "MACCS") assert len(s) > 0, "No explanation generated" - e = exmol.text_explain_generate(s, "soluble in water") + e = exmol.text_explain_generate([s], "soluble in water") samples1 = exmol.sample_space("c1cc(C(=O)O)c(OC(=O)C)cc1", model, batched=False) s = exmol.text_explain(samples1, "ECFP") From 89924f4cacd75bd394429bafb995c52003a4858c Mon Sep 17 00:00:00 2001 From: Heta Gandhi Date: Thu, 7 Dec 2023 11:21:30 -0800 Subject: [PATCH 24/26] made suggested change in chat completion response output --- exmol/exmol.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exmol/exmol.py b/exmol/exmol.py index fcb8e1aa..a26a5de4 100644 --- a/exmol/exmol.py +++ b/exmol/exmol.py @@ -1447,7 +1447,7 @@ def text_explain_generate( model=llm_model, messages=messages, temperature=0.05 ) - return response.choices[0].message["content"] + return response.choices[0].message.content def text_explain( From 8ff1371ca6d19e87db95b80553b3a3e17b075dc1 Mon Sep 17 00:00:00 2001 From: Heta Gandhi Date: Thu, 7 Dec 2023 11:34:04 -0800 Subject: [PATCH 25/26] py310 seems to resolve typing TypeAliasType import error --- .github/workflows/paper.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/paper.yml b/.github/workflows/paper.yml index 32ee953f..16b67375 100644 --- a/.github/workflows/paper.yml +++ b/.github/workflows/paper.yml @@ -13,10 +13,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Set up Python 3.8 + - name: Set up Python 3.10 uses: actions/setup-python@v2 with: - python-version: "3.8" + python-version: "3.10" - name: Install dependencies run: | python -m pip install --upgrade pip From 2ec0797d60b25fd21678c7b3a8a59f7ae22f1f9a Mon Sep 17 00:00:00 2001 From: Heta Gandhi Date: Sat, 1 Jun 2024 17:32:13 -0700 Subject: [PATCH 26/26] Try MolToRandomSmilesVect with a ramsom seed for consist chem space --- exmol/stoned/stoned.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/exmol/stoned/stoned.py b/exmol/stoned/stoned.py index 27198aba..de4ea887 100644 --- a/exmol/stoned/stoned.py +++ b/exmol/stoned/stoned.py @@ -214,6 +214,7 @@ from rdkit import Chem # type: ignore from rdkit.Chem import MolFromSmiles as smi2mol # type: ignore from rdkit.Chem import MolToSmiles as mol2smi # type: ignore +from rdkit.Chem import MolToRandomSmilesVect # type: ignore from rdkit.Chem import AllChem # type: ignore from rdkit.DataStructs.cDataStructs import TanimotoSimilarity # type: ignore @@ -237,9 +238,10 @@ def randomize_smiles(mol): if not mol: return None - return mol2smi( - mol, canonical=False, doRandom=True, isomericSmiles=True, kekuleSmiles=True - ) + # return mol2smi( + # mol, canonical=False, doRandom=True, isomericSmiles=True, kekuleSmiles=True + # ) + return MolToRandomSmilesVect(mol, 1, isomericSmiles=True, kekuleSmiles=True, randomSeed=np.random.randint(0,100))[0] def largest_mol(smiles):