{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Using the InteractiveMolecule widget\n",
    "\n",
    "For this example we need to install pandas and RDKit. If you don't have these packages yet, just execute the cell bellow to install. Note that you will need conda to install RDKit."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting package metadata (current_repodata.json): done\n",
      "Solving environment: done\n",
      "\n",
      "## Package Plan ##\n",
      "\n",
      "  environment location: /usr/local/Caskroom/miniconda/base\n",
      "\n",
      "  added / updated specs:\n",
      "    - pandas\n",
      "    - rdkit\n",
      "\n",
      "\n",
      "The following packages will be downloaded:\n",
      "\n",
      "    package                    |            build\n",
      "    ---------------------------|-----------------\n",
      "    boost-1.74.0               |   py38hb0f0857_5         320 KB  conda-forge\n",
      "    conda-4.12.0               |   py38h50d1736_0        1020 KB  conda-forge\n",
      "    greenlet-1.1.2             |   py38ha048514_1          86 KB  conda-forge\n",
      "    kiwisolver-1.3.2           |   py38he9d5cce_0          52 KB\n",
      "    matplotlib-base-3.4.3      |   py38hc7d2367_2         7.3 MB  conda-forge\n",
      "    numpy-1.20.3               |   py38h5cb586d_2         5.6 MB  conda-forge\n",
      "    pillow-7.2.0               |   py38hef457fe_2         639 KB  conda-forge\n",
      "    pycairo-1.21.0             |   py38h2e817b2_1         102 KB  conda-forge\n",
      "    rdkit-2021.03.5            |   py38h0bd8f9b_0        36.4 MB  conda-forge\n",
      "    reportlab-3.5.68           |   py38hf6ac518_1         2.4 MB  conda-forge\n",
      "    sqlalchemy-1.4.36          |   py38h0dd4459_0         2.3 MB  conda-forge\n",
      "    tornado-6.1                |   py38hed1de0f_3         647 KB  conda-forge\n",
      "    ------------------------------------------------------------\n",
      "                                           Total:        56.8 MB\n",
      "\n",
      "The following NEW packages will be INSTALLED:\n",
      "\n",
      "  boost              conda-forge/osx-64::boost-1.74.0-py38hb0f0857_5\n",
      "  boost-cpp          conda-forge/osx-64::boost-cpp-1.74.0-he5d75e3_0\n",
      "  bzip2              conda-forge/osx-64::bzip2-1.0.8-h0d85af4_4\n",
      "  cairo              conda-forge/osx-64::cairo-1.16.0-ha8983da_1005\n",
      "  cycler             conda-forge/noarch::cycler-0.11.0-pyhd8ed1ab_0\n",
      "  fontconfig         conda-forge/osx-64::fontconfig-2.13.1-h10f422b_1005\n",
      "  freetype           conda-forge/osx-64::freetype-2.10.4-h4cff582_1\n",
      "  gettext            pkgs/main/osx-64::gettext-0.21.0-h7535e17_0\n",
      "  glib               pkgs/main/osx-64::glib-2.69.1-h8346a28_1\n",
      "  greenlet           conda-forge/osx-64::greenlet-1.1.2-py38ha048514_1\n",
      "  icu                conda-forge/osx-64::icu-67.1-hb1e8313_0\n",
      "  jpeg               conda-forge/osx-64::jpeg-9e-h5eb16cf_1\n",
      "  kiwisolver         pkgs/main/osx-64::kiwisolver-1.3.2-py38he9d5cce_0\n",
      "  lcms2              conda-forge/osx-64::lcms2-2.12-h577c468_0\n",
      "  libblas            conda-forge/osx-64::libblas-3.9.0-14_osx64_openblas\n",
      "  libcblas           conda-forge/osx-64::libcblas-3.9.0-14_osx64_openblas\n",
      "  libgfortran        conda-forge/osx-64::libgfortran-5.0.0-9_3_0_h6c81a4c_23\n",
      "  libgfortran5       conda-forge/osx-64::libgfortran5-9.3.0-h6c81a4c_23\n",
      "  libiconv           conda-forge/osx-64::libiconv-1.16-haf1e3a3_0\n",
      "  liblapack          conda-forge/osx-64::liblapack-3.9.0-14_osx64_openblas\n",
      "  libopenblas        conda-forge/osx-64::libopenblas-0.3.20-openmp_hb3cd9ec_0\n",
      "  libpng             conda-forge/osx-64::libpng-1.6.37-h7cec526_2\n",
      "  libtiff            pkgs/main/osx-64::libtiff-4.2.0-h87d7836_0\n",
      "  libwebp-base       conda-forge/osx-64::libwebp-base-1.2.2-h0d85af4_1\n",
      "  libxml2            conda-forge/osx-64::libxml2-2.9.10-h2c6e4a5_2\n",
      "  llvm-openmp        conda-forge/osx-64::llvm-openmp-14.0.3-ha654fa7_0\n",
      "  lz4-c              conda-forge/osx-64::lz4-c-1.9.3-he49afe7_1\n",
      "  matplotlib-base    conda-forge/osx-64::matplotlib-base-3.4.3-py38hc7d2367_2\n",
      "  numpy              conda-forge/osx-64::numpy-1.20.3-py38h5cb586d_2\n",
      "  olefile            conda-forge/noarch::olefile-0.46-pyh9f0ad1d_1\n",
      "  pandas             conda-forge/osx-64::pandas-1.4.1-py38ha53d530_0\n",
      "  pcre               conda-forge/osx-64::pcre-8.45-he49afe7_0\n",
      "  pillow             conda-forge/osx-64::pillow-7.2.0-py38hef457fe_2\n",
      "  pixman             conda-forge/osx-64::pixman-0.38.0-h01d97ff_1003\n",
      "  pycairo            conda-forge/osx-64::pycairo-1.21.0-py38h2e817b2_1\n",
      "  pyparsing          conda-forge/noarch::pyparsing-3.0.9-pyhd8ed1ab_0\n",
      "  python-dateutil    conda-forge/noarch::python-dateutil-2.8.2-pyhd8ed1ab_0\n",
      "  python_abi         conda-forge/osx-64::python_abi-3.8-2_cp38\n",
      "  pytz               conda-forge/noarch::pytz-2022.1-pyhd8ed1ab_0\n",
      "  rdkit              conda-forge/osx-64::rdkit-2021.03.5-py38h0bd8f9b_0\n",
      "  reportlab          conda-forge/osx-64::reportlab-3.5.68-py38hf6ac518_1\n",
      "  six                conda-forge/noarch::six-1.16.0-pyh6c4a22f_0\n",
      "  sqlalchemy         conda-forge/osx-64::sqlalchemy-1.4.36-py38h0dd4459_0\n",
      "  tornado            conda-forge/osx-64::tornado-6.1-py38hed1de0f_3\n",
      "  zstd               conda-forge/osx-64::zstd-1.4.9-h582d3a0_0\n",
      "\n",
      "The following packages will be UPDATED:\n",
      "\n",
      "  openssl              pkgs/main::openssl-1.1.1n-hca72f7f_0 --> conda-forge::openssl-1.1.1o-hfe4f2af_0\n",
      "\n",
      "The following packages will be SUPERSEDED by a higher-priority channel:\n",
      "\n",
      "  ca-certificates    pkgs/main::ca-certificates-2022.3.29-~ --> conda-forge::ca-certificates-2021.10.8-h033912b_0\n",
      "  certifi            pkgs/main::certifi-2021.10.8-py38hecd~ --> conda-forge::certifi-2021.10.8-py38h50d1736_2\n",
      "  conda              pkgs/main::conda-4.12.0-py38hecd8cb5_0 --> conda-forge::conda-4.12.0-py38h50d1736_0\n",
      "\n",
      "\n",
      "\n",
      "Downloading and Extracting Packages\n",
      "tornado-6.1          | 647 KB    | ##################################### | 100% \n",
      "reportlab-3.5.68     | 2.4 MB    | ##################################### | 100% \n",
      "matplotlib-base-3.4. | 7.3 MB    | ##################################### | 100% \n",
      "conda-4.12.0         | 1020 KB   | ##################################### | 100% \n",
      "greenlet-1.1.2       | 86 KB     | ##################################### | 100% \n",
      "kiwisolver-1.3.2     | 52 KB     | ##################################### | 100% \n",
      "pycairo-1.21.0       | 102 KB    | ##################################### | 100% \n",
      "sqlalchemy-1.4.36    | 2.3 MB    | ##################################### | 100% \n",
      "numpy-1.20.3         | 5.6 MB    | ##################################### | 100% \n",
      "pillow-7.2.0         | 639 KB    | ##################################### | 100% \n",
      "rdkit-2021.03.5      | 36.4 MB   | ##################################### | 100% \n",
      "boost-1.74.0         | 320 KB    | ##################################### | 100% \n",
      "Preparing transaction: done\n",
      "Verifying transaction: done\n",
      "Executing transaction: done\n"
     ]
    }
   ],
   "source": [
    "!conda install -c conda-forge -y pandas rdkit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can import the `trident_chemwidgets` and the `pandas` lib to import our csv dataset."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "ename": "ModuleNotFoundError",
     "evalue": "No module named 'rdkit'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)",
      "Input \u001b[0;32mIn [5]\u001b[0m, in \u001b[0;36m<cell line: 3>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mtrident_chemwidgets\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mtcw\u001b[39;00m\n\u001b[1;32m      2\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mpandas\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mpd\u001b[39;00m\n\u001b[0;32m----> 3\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mrdkit\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m Chem\n",
      "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'rdkit'"
     ]
    }
   ],
   "source": [
    "import trident_chemwidgets as tcw\n",
    "import pandas as pd\n",
    "from rdkit import Chem"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can create a small function to featurize our molecules with basic information per atom. \n",
    "\n",
    "**IMPORTANT:** *the order of the data rows in the pandas DataFrame or dict must match the standard ordering of atoms as returned by the RDKit `.GetAtoms()` function.* You can generate this data any way you see fit (e.g. calculated values from RDKit as in the function below or attention values from a Graph Attention Network. The only constraint is the atom ordering. If you are using RDKit-based featurizers like those from DeepChem, this standard ordering should already be the default. Take care when using cutom featurizers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def featurize_mol(smiles):\n",
    "    # Init feature dict\n",
    "    feature_dict = {\n",
    "        'Chiral Tag': [],\n",
    "        'Formal Charge': [],\n",
    "        'Mass': [],\n",
    "        'Total Hs': [],\n",
    "        'Total Valence': []\n",
    "    }\n",
    "    \n",
    "    # Get atoms from SMILES\n",
    "    atoms = Chem.MolFromSmiles(smiles).GetAtoms()\n",
    "    \n",
    "    # Use RDKit to get all the atom properties\n",
    "    for atom in atoms:\n",
    "        feature_dict['Chiral Tag'].append(atom.GetChiralTag())\n",
    "        feature_dict['Formal Charge'].append(atom.GetFormalCharge())\n",
    "        feature_dict['Mass'].append(atom.GetMass())\n",
    "        feature_dict['Total Hs'].append(atom.GetTotalNumHs())\n",
    "        feature_dict['Total Valence'].append(atom.GetTotalValence())\n",
    "        \n",
    "    return pd.DataFrame.from_dict(feature_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here we'll be exploring the atom features from the ibuprofen molecule, smiles string `CC(C)CC1=CC=C(C=C1)C(C)C(=O)O`. We'll use the function we defined above to get some data at the atom level."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "atom_data = featurize_mol('CC(C)CC1=CC=C(C=C1)C(C)C(=O)O')\n",
    "atom_data.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can use the InteractiveMolecule widget to explore the data attached to each atom."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "w = tcw.InteractiveMolecule('CC(C)CC1=CC=C(C=C1)C(C)C(=O)O', data=atom_data)\n",
    "w"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The value of the widget will match what you typed into the input."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "w.smiles"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "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.9.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
