{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Using the InteractiveMolecule widget\n",
    "\n",
    "For this example we need to install RDKit. Note that you will need conda to install RDKit."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```shell\n",
    "!conda install -c conda-forge rdkit\n",
    "```"
   ]
  },
  {
   "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": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-16T20:00:03.114149Z",
     "iopub.status.busy": "2022-06-16T20:00:03.113899Z",
     "iopub.status.idle": "2022-06-16T20:00:03.784142Z",
     "shell.execute_reply": "2022-06-16T20:00:03.783475Z"
    }
   },
   "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 [1]\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": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-16T20:00:03.787587Z",
     "iopub.status.busy": "2022-06-16T20:00:03.787325Z",
     "iopub.status.idle": "2022-06-16T20:00:03.791935Z",
     "shell.execute_reply": "2022-06-16T20:00:03.791287Z"
    }
   },
   "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": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-16T20:00:03.795128Z",
     "iopub.status.busy": "2022-06-16T20:00:03.794876Z",
     "iopub.status.idle": "2022-06-16T20:00:03.815911Z",
     "shell.execute_reply": "2022-06-16T20:00:03.815212Z"
    }
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'Chem' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "Input \u001b[0;32mIn [3]\u001b[0m, in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0m atom_data \u001b[38;5;241m=\u001b[39m \u001b[43mfeaturize_mol\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mCC(C)CC1=CC=C(C=C1)C(C)C(=O)O\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m      2\u001b[0m atom_data\u001b[38;5;241m.\u001b[39mhead()\n",
      "Input \u001b[0;32mIn [2]\u001b[0m, in \u001b[0;36mfeaturize_mol\u001b[0;34m(smiles)\u001b[0m\n\u001b[1;32m      3\u001b[0m feature_dict \u001b[38;5;241m=\u001b[39m {\n\u001b[1;32m      4\u001b[0m     \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mChiral Tag\u001b[39m\u001b[38;5;124m'\u001b[39m: [],\n\u001b[1;32m      5\u001b[0m     \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mFormal Charge\u001b[39m\u001b[38;5;124m'\u001b[39m: [],\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m      8\u001b[0m     \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mTotal Valence\u001b[39m\u001b[38;5;124m'\u001b[39m: []\n\u001b[1;32m      9\u001b[0m }\n\u001b[1;32m     11\u001b[0m \u001b[38;5;66;03m# Get atoms from SMILES\u001b[39;00m\n\u001b[0;32m---> 12\u001b[0m atoms \u001b[38;5;241m=\u001b[39m \u001b[43mChem\u001b[49m\u001b[38;5;241m.\u001b[39mMolFromSmiles(smiles)\u001b[38;5;241m.\u001b[39mGetAtoms()\n\u001b[1;32m     14\u001b[0m \u001b[38;5;66;03m# Use RDKit to get all the atom properties\u001b[39;00m\n\u001b[1;32m     15\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m atom \u001b[38;5;129;01min\u001b[39;00m atoms:\n",
      "\u001b[0;31mNameError\u001b[0m: name 'Chem' is not defined"
     ]
    }
   ],
   "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": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-16T20:00:03.819458Z",
     "iopub.status.busy": "2022-06-16T20:00:03.818870Z",
     "iopub.status.idle": "2022-06-16T20:00:03.830975Z",
     "shell.execute_reply": "2022-06-16T20:00:03.830366Z"
    }
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'atom_data' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "Input \u001b[0;32mIn [4]\u001b[0m, in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0m w \u001b[38;5;241m=\u001b[39m tcw\u001b[38;5;241m.\u001b[39mInteractiveMolecule(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mCC(C)CC1=CC=C(C=C1)C(C)C(=O)O\u001b[39m\u001b[38;5;124m'\u001b[39m, data\u001b[38;5;241m=\u001b[39m\u001b[43matom_data\u001b[49m)\n",
      "\u001b[0;31mNameError\u001b[0m: name 'atom_data' is not defined"
     ]
    }
   ],
   "source": [
    "w = tcw.InteractiveMolecule('CC(C)CC1=CC=C(C=C1)C(C)C(=O)O', data=atom_data)\n",
    "# w # Uncomment this line to run locally"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div align='center'>\n",
    "<img src='https://raw.githubusercontent.com/tridentbio/trident-chemwidgets/master/examples/gifs/interactive_molecule_demo_small.gif'/>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The value of the widget will match what you typed into the input."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2022-06-16T20:00:03.834288Z",
     "iopub.status.busy": "2022-06-16T20:00:03.834053Z",
     "iopub.status.idle": "2022-06-16T20:00:03.845680Z",
     "shell.execute_reply": "2022-06-16T20:00:03.845079Z"
    }
   },
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'w' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "Input \u001b[0;32mIn [5]\u001b[0m, in \u001b[0;36m<cell line: 1>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mw\u001b[49m\u001b[38;5;241m.\u001b[39msmiles\n",
      "\u001b[0;31mNameError\u001b[0m: name 'w' is not defined"
     ]
    }
   ],
   "source": [
    "w.smiles"
   ]
  }
 ],
 "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.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
