{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "try:\n", " import google.colab\n", " %pip install -q ugropy\n", "except ImportError:\n", " pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The Groups class\n", "\n", "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/ipqa-research/ugropy/blob/main/docs/source/tutorial/easy_way.ipynb)\n", "\n", "\n", "`ugropy` is relatively straightforward to use, but let's explore what it has to \n", "offer. Now, let's start with the easy methods...\n", "\n", "We'll utilize the Groups class to retrieve the subgroups of all the models \n", "supported by `ugropy`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Basic usage: getting subgroups" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'CH3': 2, 'CH2': 1, 'CH': 1, 'CH2=C': 1, 'CH=C': 1, 'CH2CO': 1}" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from ugropy import Groups\n", "\n", "carvone = Groups(\"carvone\")\n", "\n", "carvone.unifac.subgroups" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`ugropy` utilizes `PubChemPy` ([link](https://github.com/mcs07/PubChemPy)) to\n", "access `PubChem` and retrieve the SMILES representation of the molecule.\n", "`ugropy` employs the SMILES representation along with the `rdkit`\n", "([link](https://github.com/rdkit/rdkit)) and `Pulp` ([link](https://github.com/coin-or/pulp))\n", "libraries to identify the functional groups of the molecules.\n", "\n", "The complete signature of the Groups class is as follows:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from ugropy import DefaultSolver\n", "\n", "carvone = Groups(\n", " identifier=\"carvone\",\n", " identifier_type=\"name\",\n", " solver=DefaultSolver,\n", " search_multiple_solutions=False,\n", " normal_boiling_temperature=None\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `identifier_type` argument (default: \"name\") can be set to \"name\", \"smiles\"\n", "or \"mol\".\n", "\n", "When \"name\" is set, `ugropy` will use the identifier argument to search in\n", "Pubchem for the canonical SMILES of the molecule.\n", "\n", "When \"smiles\" is set, `ugropy` uses it directly, this also means that the \n", "library will not suffer the overhead of searching on Pubchem. Try it yourself:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'CH3': 2, 'CH2': 1, 'CH': 1, 'CH2=C': 1, 'CH=C': 1, 'CH2CO': 1}" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "carvone = Groups(\n", " identifier=\"CC1=CCC(CC1=O)C(=C)C\",\n", " identifier_type=\"smiles\",\n", ")\n", "\n", "carvone.unifac.subgroups" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you are familiar with the `rdkit` library, you'll know that there are\n", "numerous ways to define a molecule (e.g., SMILES, SMARTS, PDB file, InChIKey,\n", "etc.). `ugropy` supports the provision of a Mol object from the `rdkit`\n", "library." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'CH3': 2, 'CH2': 1, 'CH': 1, 'CH2=C': 1, 'CH=C': 1, 'CH2CO': 1}" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from rdkit import Chem\n", "\n", "mol_obj = Chem.MolFromInchi(\"InChI=1S/C10H14O/c1-7(2)9-5-4-8(3)10(11)6-9/h4,9H,1,5-6H2,2-3H3\")\n", "\n", "carvone = Groups(\n", " identifier=mol_obj,\n", " identifier_type=\"mol\",\n", " normal_boiling_temperature=None\n", ")\n", "\n", "carvone.unifac.subgroups" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The current supported models are the classic liquid-vapor UNIFAC, Predictive\n", "Soave-Redlich-Kwong (PSRK), Joback, Dortmund and Abdulelah-Gani. You can access the \n", "functional groups this way:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'CH3': 2, 'CH2': 1, 'CH': 1, 'CH2=C': 1, 'CH=C': 1, 'CH2CO': 1}\n", "{'CH3': 2, 'CH2': 1, 'CH': 1, 'CH2=C': 1, 'CH=C': 1, 'CH2CO': 1}\n", "{'-CH3': 2, '=CH2': 1, '=C<': 1, 'ring-CH2-': 2, 'ring>CH-': 1, 'ring=CH-': 1, 'ring=C<': 1, '>C=O (ring)': 1}\n", "{'CH3': 2, 'CH2=C': 1, 'CH=C': 1, 'CH2CO': 1, 'CY-CH2': 1, 'CY-CH': 1}\n", "{'CH3': 2, 'CH2=C': 1, 'CH2 (cyclic)': 2, 'CH (cyclic)': 1, 'CH=C (cyclic)': 1, 'CO (cyclic)': 1}\n" ] } ], "source": [ "carvone = Groups(\"carvone\")\n", "\n", "print(carvone.unifac.subgroups)\n", "\n", "print(carvone.psrk.subgroups)\n", "\n", "print(carvone.joback.subgroups)\n", "\n", "print(carvone.dortmund.subgroups)\n", "\n", "print(carvone.agani.primary.subgroups)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Estimating thermophysical properties" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can obtain more information about the molecule from each model. For\n", "example, UNIFAC and PSRK are Excess Gibbs Models, so you can obtain the\n", "estimation of the $R$ and $Q$ values of the molecule (molecule's reduced Van\n", "der Wals volume and area)" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "UNIFAC R: 6.3751\n", "UNIFAC Q: 5.308\n", "PSRK R: 6.3751\n", "PSRK Q: 5.308\n" ] } ], "source": [ "print(\"UNIFAC R: \", carvone.unifac.r)\n", "print(\"UNIFAC Q: \", carvone.unifac.q)\n", "\n", "print(\"PSRK R: \", carvone.psrk.r)\n", "print(\"PSRK Q: \", carvone.psrk.q)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On the Joback model, you can obtain the estimation of different properties.\n", "We will discuss the properties estimators later." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.42452945182153057 dimensionless\n", "516.47 kelvin\n", "742.5207962108279 kelvin\n", "28.596757127741714 bar\n", "503.5 centimeter ** 3 / mole\n", "0.09232883692318564 bar\n" ] } ], "source": [ "print(carvone.joback.acentric_factor)\n", "print(carvone.joback.normal_boiling_point)\n", "print(carvone.joback.critical_temperature)\n", "print(carvone.joback.critical_pressure)\n", "print(carvone.joback.critical_volume)\n", "print(carvone.joback.vapor_pressure(430))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If the `normal_boiling_temperature` parameter is provided, it is used in\n", "the Joback properties calculations instead of the Joback-estimated normal\n", "boiling temperature (refer to the Joback tutorial)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally the `search_multiple_solutions` parameter is used to determine if the \n", "solver should return multiple solutions or not. If set to True, the solver will\n", "return multiple solutions if they exist. If set to False, the solver will \n", "return only one solution. The default value is False. In next sections we will\n", "explore in more detail how to obtain more solutions from the solver." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Obtaining multiple solutions" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[,\n", " ]" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Example of multiple solutions\n", "molecule = Groups(\"CCCC1=CC=C(CC(=O)OC)C=C1\", \"smiles\", search_multiple_solutions=True)\n", "\n", "molecule.unifac" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see we obtained a list of `GibbsFragmentationResult` objects. When\n", "`search_multiple_solutions` is set to True, the result will always be a list,\n", "regardless of the number of solutions found.\n", "\n", "We can check both solutions:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'CH3': 2, 'CH2': 1, 'ACH': 4, 'ACCH2': 2, 'COO': 1}\n", "{'CH3': 2, 'CH2': 1, 'ACH': 4, 'AC': 1, 'ACCH2': 1, 'CH2COO': 1}\n" ] } ], "source": [ "print(molecule.unifac[0].subgroups)\n", "print(molecule.unifac[1].subgroups)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Multiple solution searching is intended to get all the solutions for a given\n", "model and try different representations of the molecule to obtain properties.\n", "For example, different UNIFAC representations could lead to different\n", "liquid-liquid or liquid-vapor equilibrium predictions.\n", "\n", "\n", "The full documentation of the `Groups` class may be accessed in the API\n", "documentation. You can inspect the full API details using Python's built-in\n", "help(Groups), Groups?, or by visiting the official API documentation." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Visualizing your results" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Also, you can visualize your fragmentations results. Let's see the multiple\n", "solutions obtained before:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "CH3: 2CH2: 1ACH: 4ACCH2: 2COO: 1" ], "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "molecule.unifac[0].draw(width=800)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "CH3: 2CH2: 1ACH: 4AC: 1ACCH2: 1CH2COO: 1" ], "text/plain": [ "" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "molecule.unifac[1].draw(width=800)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's also draw the carvone solutions obtained before:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "CH3: 2CH2: 1CH: 1CH2=C: 1CH=C: 1CH2CO: 1" ], "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "carvone.unifac.draw(width=600)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "CH3: 2CH2: 1CH: 1CH2=C: 1CH=C: 1CH2CO: 1" ], "text/plain": [ "" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "carvone.psrk.draw(width=600)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "-CH3: 2=CH2: 1=C<: 1ring-CH2-: 2ring>CH-: 1ring=CH-: 1ring=C<: 1>C=O (ring): 1" ], "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "carvone.joback.draw(width=600)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "CH3: 2CH2=C: 1CH2 (cyclic): 2CH (cyclic): 1CH=C (cyclic): 1CO (cyclic): 1" ], "text/plain": [ "" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "carvone.agani.primary.draw(width=600)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can save the figure by doing:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "with open(\"figure.svg\", \"w\") as f:\n", " f.write(carvone.unifac.get_solution_svg(width=600))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Please, check the API documentation of the draw function to learn all their\n", "parameters:\n", "\n", "```\n", "carvone.unifac.draw?\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, lets draw the `ugropy` logo:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", " \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "CH3: 4CH2: 2C: 1ACH: 8AC: 2ACCH2: 2CH2O: 2COO: 1ugropy" ], "text/plain": [ "" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "mol = Groups(\"CCCC1=C(COC(C)(C)COC(=O)OCC)C=C(CC2=CC=CC=C2)C=C1\", \"smiles\")\n", "\n", "mol.unifac.draw(\n", " title=\"ugropy\",\n", " width=900,\n", " height=450,\n", " title_font_size=50,\n", " legend_font_size=14\n", ")\n" ] } ], "metadata": { "kernelspec": { "display_name": "ugropy", "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.12.13" } }, "nbformat": 4, "nbformat_minor": 2 }