From 1ffa462e6af44c170fd40ef3aeee0d98457f0a7e Mon Sep 17 00:00:00 2001 From: Levente Nagy Date: Mon, 2 Feb 2026 16:14:22 +0100 Subject: [PATCH 01/11] COG-721 Add examples for molecule prop. read --- jupyter/01_basic_functions.ipynb | 192 +++++++++++++++++++++++++------ jupyter/mol_with_properties.mrv | 4 + 2 files changed, 158 insertions(+), 38 deletions(-) create mode 100644 jupyter/mol_with_properties.mrv diff --git a/jupyter/01_basic_functions.ipynb b/jupyter/01_basic_functions.ipynb index 3de9c46..3d17595 100644 --- a/jupyter/01_basic_functions.ipynb +++ b/jupyter/01_basic_functions.ipynb @@ -12,27 +12,31 @@ }, { "cell_type": "code", - "execution_count": 1, "id": "0fade33e-d909-44f6-a37b-ac210794ff72", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Collecting chemaxon\n", - " Using cached chemaxon-25.1.0b5-cp313-cp313-macosx_14_0_arm64.whl.metadata (1.9 kB)\n", - "Using cached chemaxon-25.1.0b5-cp313-cp313-macosx_14_0_arm64.whl (57.6 MB)\n", - "Installing collected packages: chemaxon\n", - "Successfully installed chemaxon-25.1.0b5\n" - ] + "metadata": { + "ExecuteTime": { + "end_time": "2026-02-02T15:04:24.599282942Z", + "start_time": "2026-02-02T15:04:24.100067188Z" } - ], + }, "source": [ "import sys\n", "\n", "!{sys.executable} -m pip install chemaxon" - ] + ], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 11 }, { "cell_type": "markdown", @@ -44,27 +48,32 @@ }, { "cell_type": "code", - "execution_count": 2, "id": "76ca42b3-30a1-4d4f-971c-e37d3af1c1b7", - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2026-02-02T15:04:26.813773160Z", + "start_time": "2026-02-02T15:04:26.765575067Z" + } + }, + "source": [ + "import chemaxon\n", + "\n", + "print('Version: ', chemaxon.__version__)\n", + "print('CCL version: ', chemaxon.ccl_version())\n", + "print('CCL build date:', chemaxon.ccl_build_date())" + ], "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Version: 25.1.0b5\n", - "CCL version: 25.1.3\n", - "CCL build date: 2025-04-24\n" + "Version: 0.1.0\n", + "CCL version: 25.3.5\n", + "CCL build date: 2025-11-20\n" ] } ], - "source": [ - "import chemaxon\n", - "\n", - "print('Version: ', chemaxon.__version__)\n", - "print('CCL version: ', chemaxon.ccl_version())\n", - "print('CCL build date:', chemaxon.ccl_build_date())" - ] + "execution_count": 12 }, { "cell_type": "markdown", @@ -76,27 +85,32 @@ }, { "cell_type": "code", - "execution_count": 3, "id": "8d9f4205-d0a9-467c-97e9-054d78bdde60", - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2026-02-02T15:04:30.355961566Z", + "start_time": "2026-02-02T15:04:30.314733170Z" + } + }, + "source": [ + "[lic for lic in chemaxon.licenses() if lic['product'] == 'Python API']" + ], "outputs": [ { "data": { "text/plain": [ "[{'product': 'Python API',\n", - " 'expiration': '2025-06-30',\n", - " 'licensee': 'Chemaxon',\n", + " 'expiration': '2026-02-17',\n", + " 'licensee': 'Chemaxon (Autogenerated) - lnagy@chemaxon.com',\n", " 'state': 'VALID'}]" ] }, - "execution_count": 3, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], - "source": [ - "[lic for lic in chemaxon.licenses() if lic['product'] == 'Python API']" - ] + "execution_count": 13 }, { "cell_type": "markdown", @@ -659,12 +673,114 @@ ] }, { + "metadata": {}, + "cell_type": "markdown", + "source": "### **Molecule property handling**", + "id": "6588cf0d348eed22" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "You can store custom properties in the __Molecule__ objects using the __set_property__ and __get_property__ methods. A dictionary of the __Molecule__ object's properties can also be reteived using the __get_properties_dict__ method.\n", + "\n", + "_**Note:** Modifying that dictionary will not change the properties of the __Molecule__ object. For that, you should use __set_property__ method._" + ], + "id": "d6d63c6344fc92ac" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "Supported property value types are: __str__, __int__, __float__, __bool__, __list__ (of int, float). Considering the list of scalar values, the api is aligned to the behavior of Chemaxon Java API. So, double values can only be used with dots, not with commas.", + "id": "c5c0afd0a3dd4cdd" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "#### Reading properties:", + "id": "4df4fca46fb9372d" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2026-02-02T15:13:11.699762905Z", + "start_time": "2026-02-02T15:13:11.634924189Z" + } + }, "cell_type": "code", - "execution_count": null, - "id": "02aab71e-3d23-4713-98d9-ba75d47511af", + "source": [ + "from chemaxon import open_for_import\n", + "\n", + "with open_for_import('mol_with_properties.mrv') as mol_iterator:\n", + " mols = list(mol_iterator)\n", + "\n", + "mols[0]" + ], + "id": "36b4c96ad9ab34b8", + "outputs": [ + { + "data": { + "text/plain": [ + "Molecule(_source='\\n\\nTRUEasd424.22.0asd1 2 3 4 542TRUE1.5 2.7 3.3 4.567\\n', _format='mrv', _to_svg=, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(1, 2)), Bond(type=1, atoms=(2, 3)), Bond(type=2, atoms=(3, 4)), Bond(type=1, atoms=(4, 5)), Bond(type=2, atoms=(0, 5)), Bond(type=2, atoms=(7, 8)), Bond(type=1, atoms=(8, 9)), Bond(type=2, atoms=(9, 10)), Bond(type=1, atoms=(10, 11)), Bond(type=1, atoms=(6, 7)), Bond(type=2, atoms=(6, 11)), Bond(type=1, atoms=(4, 6)), Bond(type=2, atoms=(13, 14)), Bond(type=1, atoms=(14, 15)), Bond(type=2, atoms=(15, 16)), Bond(type=1, atoms=(16, 17)), Bond(type=1, atoms=(12, 13)), Bond(type=2, atoms=(12, 17)), Bond(type=1, atoms=(9, 12))), atoms=(Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(0, 5)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(1, 2)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(1, 2)), Bond(type=1, atoms=(2, 3)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(2, 3)), Bond(type=2, atoms=(3, 4)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(3, 4)), Bond(type=1, atoms=(4, 5)), Bond(type=1, atoms=(4, 6)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(4, 5)), Bond(type=2, atoms=(0, 5)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(6, 7)), Bond(type=2, atoms=(6, 11)), Bond(type=1, atoms=(4, 6)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(7, 8)), Bond(type=1, atoms=(6, 7)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(7, 8)), Bond(type=1, atoms=(8, 9)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(8, 9)), Bond(type=2, atoms=(9, 10)), Bond(type=1, atoms=(9, 12)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(9, 10)), Bond(type=1, atoms=(10, 11)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(10, 11)), Bond(type=2, atoms=(6, 11)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(12, 13)), Bond(type=2, atoms=(12, 17)), Bond(type=1, atoms=(9, 12)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(13, 14)), Bond(type=1, atoms=(12, 13)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(13, 14)), Bond(type=1, atoms=(14, 15)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(14, 15)), Bond(type=2, atoms=(15, 16)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(15, 16)), Bond(type=1, atoms=(16, 17)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(16, 17)), Bond(type=2, atoms=(12, 17))))), native_handle=25, _to_str=, properties=[, , , , , ])" + ], + "image/svg+xml": "2.0asd1 2 3 4 542TRUE1.5 2.7 3.3 4.567\n" + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 27 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2026-02-02T15:13:20.988809472Z", + "start_time": "2026-02-02T15:13:20.915788982Z" + } + }, + "cell_type": "code", + "source": [ + "from chemaxon import open_for_import\n", + "\n", + "with open_for_import('mol_with_properties.mrv') as mol_iterator:\n", + " mols = list(mol_iterator)\n", + "\n", + "mol = mols[0]\n", + "\n", + "print(\"Number of properties: \" + str(len(mol.properties)))\n", + "print(\"\\ttest_str_property -> \" + mol.get_property(\"test_str_property\"))\n", + "print(\"\\ttest_double_property -> \" + str(mol.get_property(\"test_double_property\")))\n", + "print(\"\\ttest_int_property -> \" + str(mol.get_property(\"test_int_property\")))\n", + "print(\"\\ttest_boolean_property -> \" + str(mol.get_property(\"test_boolean_property\")))\n", + "print(\"\\ttest_int_array_property -> \" + str(mol.get_property(\"test_int_array_property\")))\n", + "print(\"\\ttest_double_array_property -> \" + str(mol.get_property(\"test_double_array_property\")))" + ], + "id": "3174830bcf4c2edd", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of properties: 6\n", + "\ttest_str_property -> asd\n", + "\ttest_double_property -> 4.2\n", + "\ttest_int_property -> 42\n", + "\ttest_boolean_property -> True\n", + "\ttest_int_array_property -> [1, 2, 3, 4, 5]\n", + "\ttest_double_array_property -> [1.2, 3.4, 5.22, 6.7889]\n" + ] + } + ], + "execution_count": 28 + }, + { "metadata": {}, + "cell_type": "code", "outputs": [], - "source": [] + "execution_count": null, + "source": "", + "id": "74d2320f725b5c63" } ], "metadata": { diff --git a/jupyter/mol_with_properties.mrv b/jupyter/mol_with_properties.mrv new file mode 100644 index 0000000..cd80e65 --- /dev/null +++ b/jupyter/mol_with_properties.mrv @@ -0,0 +1,4 @@ + + +TRUEasd424.21 2 3 4 51.2 3.4 5.22 6.78892.0asd1 2 3 4 542TRUE1.5 2.7 3.3 4.567 + \ No newline at end of file From 8870c4188bfd79aa93fda028fec62cdf1b89cfe8 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Tue, 5 May 2026 16:21:05 +0200 Subject: [PATCH 02/11] COG-721 Extend pandas examples --- jupyter/07_pandas_integration_examples.ipynb | 85 +++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/jupyter/07_pandas_integration_examples.ipynb b/jupyter/07_pandas_integration_examples.ipynb index f724308..023cb96 100644 --- a/jupyter/07_pandas_integration_examples.ipynb +++ b/jupyter/07_pandas_integration_examples.ipynb @@ -21,8 +21,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2026-02-02T15:19:21.211892562Z", - "start_time": "2026-02-02T15:19:21.143339417Z" + "end_time": "2025-12-01T14:43:22.339727Z", + "start_time": "2025-12-01T14:43:21.966248Z" } }, "cell_type": "code", @@ -276,6 +276,87 @@ } ], "execution_count": 6 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "You can also use molecule properties in __DataFrame__ objects:", + "id": "7a1336fb96c1f03f" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2026-02-02T15:22:55.201768939Z", + "start_time": "2026-02-02T15:22:55.143300052Z" + } + }, + "cell_type": "code", + "source": [ + "from chemaxon import open_for_import\n", + "\n", + "with open_for_import('mol_with_properties.mrv') as mol_iterator:\n", + " mols = list(mol_iterator)\n", + "\n", + "d = {'molecule': mols }\n", + "df_props = pd.DataFrame(data=d)\n", + "df_props['string property'] = df_props['molecule'].apply(lambda m: m.get_property('test_str_property'))\n", + "df_props['int array property'] = df_props['molecule'].apply(lambda m: m.get_property('test_int_array_property'))\n", + "\n", + "df_props" + ], + "id": "61d10376399bc9a8", + "outputs": [ + { + "data": { + "text/plain": [ + " molecule string property \\\n", + "0 C1=CC=C(C=C1)C1=CC=C(C=C1)C1=CC=CC=C1 |c:0,2,4... asd \n", + "\n", + " int array property \n", + "0 [1, 2, 3, 4, 5] " + ], + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
moleculestring propertyint array property
0C1=CC=C(C=C1)C1=CC=C(C=C1)C1=CC=CC=C1 |c:0,2,4...asd[1, 2, 3, 4, 5]
\n", + "
" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 11 } ], "metadata": { From 54a5f5dc4c5b38cb3889afbaeee3652c8cebb3e8 Mon Sep 17 00:00:00 2001 From: Levente Nagy Date: Fri, 6 Feb 2026 15:28:51 +0100 Subject: [PATCH 03/11] COG-743 Add pandas examples for property modification --- jupyter/01_basic_functions.ipynb | 141 +++++++++++++++++++++++++++---- jupyter/mol_with_properties.mrv | 2 +- 2 files changed, 124 insertions(+), 19 deletions(-) diff --git a/jupyter/01_basic_functions.ipynb b/jupyter/01_basic_functions.ipynb index 3d17595..12a1a6e 100644 --- a/jupyter/01_basic_functions.ipynb +++ b/jupyter/01_basic_functions.ipynb @@ -15,14 +15,14 @@ "id": "0fade33e-d909-44f6-a37b-ac210794ff72", "metadata": { "ExecuteTime": { - "end_time": "2026-02-02T15:04:24.599282942Z", - "start_time": "2026-02-02T15:04:24.100067188Z" + "end_time": "2026-02-06T14:26:36.918955766Z", + "start_time": "2026-02-06T14:26:36.071728786Z" } }, "source": [ - "import sys\n", + " import sys\n", "\n", - "!{sys.executable} -m pip install chemaxon" + " !{sys.executable} -m pip install chemaxon" ], "outputs": [ { @@ -31,12 +31,12 @@ "" ] }, - "execution_count": 11, + "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], - "execution_count": 11 + "execution_count": 1 }, { "cell_type": "markdown", @@ -703,8 +703,8 @@ { "metadata": { "ExecuteTime": { - "end_time": "2026-02-02T15:13:11.699762905Z", - "start_time": "2026-02-02T15:13:11.634924189Z" + "end_time": "2026-02-03T08:09:55.633222159Z", + "start_time": "2026-02-03T08:09:55.544785396Z" } }, "cell_type": "code", @@ -721,22 +721,22 @@ { "data": { "text/plain": [ - "Molecule(_source='\\n\\nTRUEasd424.22.0asd1 2 3 4 542TRUE1.5 2.7 3.3 4.567\\n', _format='mrv', _to_svg=, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(1, 2)), Bond(type=1, atoms=(2, 3)), Bond(type=2, atoms=(3, 4)), Bond(type=1, atoms=(4, 5)), Bond(type=2, atoms=(0, 5)), Bond(type=2, atoms=(7, 8)), Bond(type=1, atoms=(8, 9)), Bond(type=2, atoms=(9, 10)), Bond(type=1, atoms=(10, 11)), Bond(type=1, atoms=(6, 7)), Bond(type=2, atoms=(6, 11)), Bond(type=1, atoms=(4, 6)), Bond(type=2, atoms=(13, 14)), Bond(type=1, atoms=(14, 15)), Bond(type=2, atoms=(15, 16)), Bond(type=1, atoms=(16, 17)), Bond(type=1, atoms=(12, 13)), Bond(type=2, atoms=(12, 17)), Bond(type=1, atoms=(9, 12))), atoms=(Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(0, 5)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(1, 2)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(1, 2)), Bond(type=1, atoms=(2, 3)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(2, 3)), Bond(type=2, atoms=(3, 4)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(3, 4)), Bond(type=1, atoms=(4, 5)), Bond(type=1, atoms=(4, 6)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(4, 5)), Bond(type=2, atoms=(0, 5)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(6, 7)), Bond(type=2, atoms=(6, 11)), Bond(type=1, atoms=(4, 6)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(7, 8)), Bond(type=1, atoms=(6, 7)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(7, 8)), Bond(type=1, atoms=(8, 9)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(8, 9)), Bond(type=2, atoms=(9, 10)), Bond(type=1, atoms=(9, 12)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(9, 10)), Bond(type=1, atoms=(10, 11)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(10, 11)), Bond(type=2, atoms=(6, 11)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(12, 13)), Bond(type=2, atoms=(12, 17)), Bond(type=1, atoms=(9, 12)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(13, 14)), Bond(type=1, atoms=(12, 13)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(13, 14)), Bond(type=1, atoms=(14, 15)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(14, 15)), Bond(type=2, atoms=(15, 16)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(15, 16)), Bond(type=1, atoms=(16, 17)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(16, 17)), Bond(type=2, atoms=(12, 17))))), native_handle=25, _to_str=, properties=[, , , , , ])" + "Molecule(_source='\\n\\nTRUEasd424.2asd1 2 3 4 542TRUE1.5 2.7 3.3 4.567\\n', _format='mrv', _to_svg=, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(1, 2)), Bond(type=1, atoms=(2, 3)), Bond(type=2, atoms=(3, 4)), Bond(type=1, atoms=(4, 5)), Bond(type=2, atoms=(0, 5)), Bond(type=2, atoms=(7, 8)), Bond(type=1, atoms=(8, 9)), Bond(type=2, atoms=(9, 10)), Bond(type=1, atoms=(10, 11)), Bond(type=1, atoms=(6, 7)), Bond(type=2, atoms=(6, 11)), Bond(type=1, atoms=(4, 6)), Bond(type=2, atoms=(13, 14)), Bond(type=1, atoms=(14, 15)), Bond(type=2, atoms=(15, 16)), Bond(type=1, atoms=(16, 17)), Bond(type=1, atoms=(12, 13)), Bond(type=2, atoms=(12, 17)), Bond(type=1, atoms=(9, 12))), atoms=(Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(0, 5)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(1, 2)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(1, 2)), Bond(type=1, atoms=(2, 3)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(2, 3)), Bond(type=2, atoms=(3, 4)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(3, 4)), Bond(type=1, atoms=(4, 5)), Bond(type=1, atoms=(4, 6)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(4, 5)), Bond(type=2, atoms=(0, 5)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(6, 7)), Bond(type=2, atoms=(6, 11)), Bond(type=1, atoms=(4, 6)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(7, 8)), Bond(type=1, atoms=(6, 7)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(7, 8)), Bond(type=1, atoms=(8, 9)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(8, 9)), Bond(type=2, atoms=(9, 10)), Bond(type=1, atoms=(9, 12)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(9, 10)), Bond(type=1, atoms=(10, 11)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(10, 11)), Bond(type=2, atoms=(6, 11)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(12, 13)), Bond(type=2, atoms=(12, 17)), Bond(type=1, atoms=(9, 12)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(13, 14)), Bond(type=1, atoms=(12, 13)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(13, 14)), Bond(type=1, atoms=(14, 15)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(14, 15)), Bond(type=2, atoms=(15, 16)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(15, 16)), Bond(type=1, atoms=(16, 17)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(16, 17)), Bond(type=2, atoms=(12, 17))))), native_handle=34, _to_str=, properties=[, , , , , ])" ], - "image/svg+xml": "2.0asd1 2 3 4 542TRUE1.5 2.7 3.3 4.567\n" + "image/svg+xml": "asd1 2 3 4 542TRUE1.5 2.7 3.3 4.567\n" }, - "execution_count": 27, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], - "execution_count": 27 + "execution_count": 31 }, { "metadata": { "ExecuteTime": { - "end_time": "2026-02-02T15:13:20.988809472Z", - "start_time": "2026-02-02T15:13:20.915788982Z" + "end_time": "2026-02-03T09:24:48.581391621Z", + "start_time": "2026-02-03T09:24:48.531897571Z" } }, "cell_type": "code", @@ -754,7 +754,10 @@ "print(\"\\ttest_int_property -> \" + str(mol.get_property(\"test_int_property\")))\n", "print(\"\\ttest_boolean_property -> \" + str(mol.get_property(\"test_boolean_property\")))\n", "print(\"\\ttest_int_array_property -> \" + str(mol.get_property(\"test_int_array_property\")))\n", - "print(\"\\ttest_double_array_property -> \" + str(mol.get_property(\"test_double_array_property\")))" + "print(\"\\ttest_double_array_property -> \" + str(mol.get_property(\"test_double_array_property\")))\n", + "\n", + "print()\n", + "print(\"All properties as dict: \\n\" + str(mol.get_property_dict()))" ], "id": "3174830bcf4c2edd", "outputs": [ @@ -768,11 +771,113 @@ "\ttest_int_property -> 42\n", "\ttest_boolean_property -> True\n", "\ttest_int_array_property -> [1, 2, 3, 4, 5]\n", - "\ttest_double_array_property -> [1.2, 3.4, 5.22, 6.7889]\n" + "\ttest_double_array_property -> [1.2, 3.4, 5.22, 6.7889]\n", + "\n", + "All properties as dict: \n", + "{'test_boolean_property': True, 'test_str_property': 'asd', 'test_int_property': 42, 'test_double_property': 4.2, 'test_int_array_property': [1, 2, 3, 4, 5], 'test_double_array_property': [1.2, 3.4, 5.22, 6.7889]}\n" + ] + } + ], + "execution_count": 36 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "#### Adding properties to the molecule object:\n", + "\n", + "Supported types are: __bool__, __int__, __float__, __str__, __list__ of int, __list__ of float__. Note that the list of scalar values should be provided as a list of the corresponding type, not as a string. So, double values can only be used with dots, not with commas." + ], + "id": "ddc34a664bc27eed" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2026-02-06T14:26:44.259402624Z", + "start_time": "2026-02-06T14:26:44.197003574Z" + } + }, + "cell_type": "code", + "source": [ + "from chemaxon import import_mol\n", + "\n", + "mol = import_mol('CC(=O)NC1=CC=C(O)C=C1')\n", + "\n", + "mol.set_property('test_str_property', 'test string')\n", + "mol.set_property('test_double_property', 3.14)\n", + "mol.set_property('test_int_property', 42)\n", + "mol.set_property('test_boolean_property', True)\n", + "mol.set_property('test_int_array_property', [1, 2, 3])\n", + "mol.set_property('test_double_array_property', [1.1, 2.2, 3.3])\n", + "\n", + "print(\"Number of properties: \" + str(len(mol.properties)))\n", + "print(\"\\ttest_str_property -> \" + mol.get_property(\"test_str_property\"))\n", + "\n", + "\n", + "# Properties are persisted on export of course:\n", + "from chemaxon import export_mol\n", + "\n", + "print(export_mol(mol, 'sdf'))" + ], + "id": "cfec6f58a612938e", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of properties: 6\n", + "\ttest_str_property -> test string\n", + "\n", + " Mrv2503 02062615262D \n", + "\n", + " 11 11 0 0 0 0 999 V2000\n", + " 0.0000 3.3000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n", + " 0.0000 2.4750 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n", + " -0.7145 2.0625 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\n", + " 0.7145 2.0625 0.0000 N 0 0 0 0 0 0 0 0 0 0 0 0\n", + " 0.7145 1.2375 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n", + " 1.4289 0.8250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n", + " 1.4289 -0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n", + " 0.7145 -0.4125 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n", + " 0.7145 -1.2375 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0\n", + " 0.0000 0.0000 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n", + " 0.0000 0.8250 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0\n", + " 1 2 1 0 0 0 0\n", + " 2 3 2 0 0 0 0\n", + " 2 4 1 0 0 0 0\n", + " 4 5 1 0 0 0 0\n", + " 5 6 2 0 0 0 0\n", + " 6 7 1 0 0 0 0\n", + " 7 8 2 0 0 0 0\n", + " 8 9 1 0 0 0 0\n", + " 8 10 1 0 0 0 0\n", + " 10 11 2 0 0 0 0\n", + " 5 11 1 0 0 0 0\n", + "M END\n", + "> \n", + "test string\n", + "\n", + "> \n", + "3.14\n", + "\n", + "> \n", + "42\n", + "\n", + "> \n", + "True\n", + "\n", + "> \n", + "[1, 2, 3]\n", + "\n", + "> \n", + "[1.1, 2.2, 3.3]\n", + "\n", + "$$$$\n", + "\n" ] } ], - "execution_count": 28 + "execution_count": 2 }, { "metadata": {}, @@ -780,7 +885,7 @@ "outputs": [], "execution_count": null, "source": "", - "id": "74d2320f725b5c63" + "id": "1f169e93d6c6c99d" } ], "metadata": { diff --git a/jupyter/mol_with_properties.mrv b/jupyter/mol_with_properties.mrv index cd80e65..55439a2 100644 --- a/jupyter/mol_with_properties.mrv +++ b/jupyter/mol_with_properties.mrv @@ -1,4 +1,4 @@ -TRUEasd424.21 2 3 4 51.2 3.4 5.22 6.78892.0asd1 2 3 4 542TRUE1.5 2.7 3.3 4.567 +TRUEasd424.21 2 3 4 51.2 3.4 5.22 6.7889asd1 2 3 4 542TRUE1.5 2.7 3.3 4.567 \ No newline at end of file From edba0440859ddd757c9c24df7465585f1d51d594 Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Tue, 5 May 2026 16:22:34 +0200 Subject: [PATCH 04/11] COG-743 Clear sensitive output data --- jupyter/01_basic_functions.ipynb | 68 +++++--------------------------- 1 file changed, 9 insertions(+), 59 deletions(-) diff --git a/jupyter/01_basic_functions.ipynb b/jupyter/01_basic_functions.ipynb index 12a1a6e..c9660dc 100644 --- a/jupyter/01_basic_functions.ipynb +++ b/jupyter/01_basic_functions.ipynb @@ -13,30 +13,14 @@ { "cell_type": "code", "id": "0fade33e-d909-44f6-a37b-ac210794ff72", - "metadata": { - "ExecuteTime": { - "end_time": "2026-02-06T14:26:36.918955766Z", - "start_time": "2026-02-06T14:26:36.071728786Z" - } - }, + "metadata": {}, "source": [ " import sys\n", "\n", " !{sys.executable} -m pip install chemaxon" ], - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 1 + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -49,12 +33,7 @@ { "cell_type": "code", "id": "76ca42b3-30a1-4d4f-971c-e37d3af1c1b7", - "metadata": { - "ExecuteTime": { - "end_time": "2026-02-02T15:04:26.813773160Z", - "start_time": "2026-02-02T15:04:26.765575067Z" - } - }, + "metadata": {}, "source": [ "import chemaxon\n", "\n", @@ -62,18 +41,8 @@ "print('CCL version: ', chemaxon.ccl_version())\n", "print('CCL build date:', chemaxon.ccl_build_date())" ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Version: 0.1.0\n", - "CCL version: 25.3.5\n", - "CCL build date: 2025-11-20\n" - ] - } - ], - "execution_count": 12 + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", @@ -86,31 +55,12 @@ { "cell_type": "code", "id": "8d9f4205-d0a9-467c-97e9-054d78bdde60", - "metadata": { - "ExecuteTime": { - "end_time": "2026-02-02T15:04:30.355961566Z", - "start_time": "2026-02-02T15:04:30.314733170Z" - } - }, + "metadata": {}, "source": [ "[lic for lic in chemaxon.licenses() if lic['product'] == 'Python API']" ], - "outputs": [ - { - "data": { - "text/plain": [ - "[{'product': 'Python API',\n", - " 'expiration': '2026-02-17',\n", - " 'licensee': 'Chemaxon (Autogenerated) - lnagy@chemaxon.com',\n", - " 'state': 'VALID'}]" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 13 + "outputs": [], + "execution_count": null }, { "cell_type": "markdown", From 74f381b956e5f93a0fd6b0bb09aad2b13971c67e Mon Sep 17 00:00:00 2001 From: Levente Nagy Date: Mon, 16 Mar 2026 08:52:09 +0100 Subject: [PATCH 05/11] COG-725 Add examples for ADMET predictors --- jupyter/02_calculators.ipynb | 1118 +++++++++++++++++++++++++++------- jupyter/nci50.smiles | 50 ++ 2 files changed, 932 insertions(+), 236 deletions(-) create mode 100644 jupyter/nci50.smiles diff --git a/jupyter/02_calculators.ipynb b/jupyter/02_calculators.ipynb index d430751..78e525f 100644 --- a/jupyter/02_calculators.ipynb +++ b/jupyter/02_calculators.ipynb @@ -12,185 +12,68 @@ }, { "cell_type": "code", - "execution_count": 1, "id": "4651ecec-55a8-48d2-a76e-a5c8487ef569", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "logP: 0.91\n", - "logD[pH 9.0]: 0.78\n", - "pKa: [atom: 8, pka: 9.46 (ACIDIC)], [atom: 2, pka: -4.36 (BASIC)], [atom: 8, pka: -5.94 (BASIC)]\n", - "hlb: 14.14\n" - ] + "metadata": { + "ExecuteTime": { + "end_time": "2026-03-16T07:37:44.342663665Z", + "start_time": "2026-03-16T07:37:44.281900876Z" } - ], + }, "source": [ "from chemaxon import import_mol, logp, logd, pka, hlb\n", "\n", "mol = import_mol('CC(=O)NC1=CC=C(O)C=C1') # paracetamol\n", "\n", "print('logP: ', logp(mol))\n", - "print('logD[pH 9.0]:', logd(mol, pH=9.0))\n", + "print('logD[pH 9.0]:', logd(mol, ph=9.0))\n", "print('pKa: ', pka(mol))\n", "print('hlb: ', hlb(mol))" - ] + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "logP: 0.92\n", + "logD[pH 9.0]: 0.8\n", + "pKa: [atom: 3, pka: 16.65 (ACIDIC)], [atom: 8, pka: 9.46 (ACIDIC)], [atom: 2, pka: -4.36 (BASIC)], [atom: 8, pka: -5.94 (BASIC)]\n", + "hlb: 14.14\n" + ] + } + ], + "execution_count": 21 }, { "cell_type": "code", - "execution_count": 2, "id": "a23b02ed-fe3b-419e-95e2-a2fee78abb3f", - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2026-03-16T07:30:40.398412454Z", + "start_time": "2026-03-16T07:30:38.972522816Z" + } + }, + "source": [ + "from chemaxon import import_mol, pka\n", + "\n", + "mol = import_mol('aspirin')\n", + "\n", + "pka_result = pka(mol)\n", + "pka_result.structure" + ], "outputs": [ { "data": { - "image/svg+xml": [ - "CH3O-7.14 OOH3.41 O\n" - ], "text/plain": [ - "Molecule(_mrv='\\nTCC\\n', _mrv_to_svg=, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(1, 2)), Bond(type=1, atoms=(1, 3)), Bond(type=1, atoms=(3, 4)), Bond(type=2, atoms=(4, 5)), Bond(type=1, atoms=(5, 6)), Bond(type=2, atoms=(6, 7)), Bond(type=1, atoms=(7, 8)), Bond(type=2, atoms=(8, 9)), Bond(type=1, atoms=(4, 9)), Bond(type=1, atoms=(9, 10)), Bond(type=1, atoms=(10, 11)), Bond(type=2, atoms=(10, 12))), atoms=(Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(0, 1)),)), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(1, 2)), Bond(type=1, atoms=(1, 3)))), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=2, atoms=(1, 2)),)), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=1, atoms=(1, 3)), Bond(type=1, atoms=(3, 4)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(3, 4)), Bond(type=2, atoms=(4, 5)), Bond(type=1, atoms=(4, 9)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(4, 5)), Bond(type=1, atoms=(5, 6)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(5, 6)), Bond(type=2, atoms=(6, 7)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(6, 7)), Bond(type=1, atoms=(7, 8)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(7, 8)), Bond(type=2, atoms=(8, 9)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(8, 9)), Bond(type=1, atoms=(4, 9)), Bond(type=1, atoms=(9, 10)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(9, 10)), Bond(type=1, atoms=(10, 11)), Bond(type=2, atoms=(10, 12)))), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=1, atoms=(10, 11)),)), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=2, atoms=(10, 12)),))))" - ] + "Molecule(_source='\\nTCC\\n', _format='mrv', _to_svg=, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(1, 2)), Bond(type=1, atoms=(1, 3)), Bond(type=1, atoms=(3, 4)), Bond(type=2, atoms=(4, 5)), Bond(type=1, atoms=(5, 6)), Bond(type=2, atoms=(6, 7)), Bond(type=1, atoms=(7, 8)), Bond(type=2, atoms=(8, 9)), Bond(type=1, atoms=(4, 9)), Bond(type=1, atoms=(9, 10)), Bond(type=1, atoms=(10, 11)), Bond(type=2, atoms=(10, 12))), atoms=(Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(0, 1)),)), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(1, 2)), Bond(type=1, atoms=(1, 3)))), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=2, atoms=(1, 2)),)), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=1, atoms=(1, 3)), Bond(type=1, atoms=(3, 4)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(3, 4)), Bond(type=2, atoms=(4, 5)), Bond(type=1, atoms=(4, 9)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(4, 5)), Bond(type=1, atoms=(5, 6)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(5, 6)), Bond(type=2, atoms=(6, 7)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(6, 7)), Bond(type=1, atoms=(7, 8)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(7, 8)), Bond(type=2, atoms=(8, 9)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(8, 9)), Bond(type=1, atoms=(4, 9)), Bond(type=1, atoms=(9, 10)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(9, 10)), Bond(type=1, atoms=(10, 11)), Bond(type=2, atoms=(10, 12)))), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=1, atoms=(10, 11)),)), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=2, atoms=(10, 12)),))), native_handle=1, _to_str=, properties={})" + ], + "image/svg+xml": "CH3O-7.14 OOH3.41 O\n" }, - "execution_count": 2, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], - "source": [ - "from chemaxon import import_mol, pka\n", - "\n", - "mol = import_mol('aspirin')\n", - "\n", - "pka_result = pka(mol)\n", - "pka_result.structure" - ] + "execution_count": 7 }, { "cell_type": "markdown", @@ -445,12 +328,38 @@ }, { "cell_type": "code", - "execution_count": 6, "id": "a72c8cd9-154c-450e-80a4-58ad8a44d92c", - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2026-03-16T07:44:59.388750945Z", + "start_time": "2026-03-16T07:44:59.329950593Z" + } + }, + "source": [ + "import pandas\n", + "\n", + "mols = pandas.read_table('nci1000.smiles', names=['SMILES', 'NCI_ID'])\n", + "mols" + ], "outputs": [ { "data": { + "text/plain": [ + " SMILES NCI_ID\n", + "0 CC1=CC(=O)C=CC1=O 1\n", + "1 S(SC1=NC2=CC=CC=C2S1)C3=NC4=C(S3)C=CC=C4 2\n", + "2 OC1=C(Cl)C=C(C=C1[N+]([O-])=O)[N+]([O-])=O 3\n", + "3 [O-][N+](=O)C1=CNC(=N)S1 4\n", + "4 NC1=CC2=C(C=C1)C(=O)C3=C(C=CC=C3)C2=O 5\n", + ".. ... ...\n", + "995 OC(=O)CN(CC(O)=O)CC1=CC=CC=C1 1003\n", + "996 CC(C)N(CC(O)=O)CC(O)=O 1004\n", + "997 C1=CC=C(C=C1)C=NC(N=CC2=CC=CC=C2)C3=CC=CC=C3 1005\n", + "998 CC(C)(C)C[C]1(C)NC(=O)NC1=O 1006\n", + "999 CCOC(=O)C(C(C)C)C(=O)OCC 1007\n", + "\n", + "[1000 rows x 2 columns]" + ], "text/html": [ "
\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", + " \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", + " \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", + " \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", + " \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", + " \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", + "
SMILESNCI_IDHERG classificationHERG activityBBB scoreCNS MPO score
0CC1=CC(=O)C=CC1=O1SAFE3.5270874.4027435.707000
1S(SC1=NC2=CC=CC=C2S1)C3=NC4=C(S3)C=CC=C42SAFE5.5745224.5115653.289000
2OC1=C(Cl)C=C(C=C1[N+]([O-])=O)[N+]([O-])=O3SAFE3.9072892.9004635.199667
3[O-][N+](=O)C1=CNC(=N)S14SAFE3.9251022.6916845.500000
4NC1=CC2=C(C=C1)C(=O)C3=C(C=CC=C3)C2=O5SAFE4.3813935.0246545.455111
5OC(=O)C1=C(C=CC=C1)C2=C3C=CC(=O)C(=C3OC4=C2C=C...6SAFE4.9087933.0964533.817072
6CN(C)C1=C(Cl)C(=O)C2=C(C=CC=C2)C1=O7SAFE3.9120715.2466185.869000
7CC1=C(C2=C(C=C1)C(=O)C3=CC=CC=C3C2=O)[N+]([O-])=O8SAFE4.8551124.8730925.111222
8CC(=NO)C(C)=NO9SAFE3.5362422.3909435.500000
9C1=CC=C(C=C1)P(C2=CC=CC=C2)C3=CC=CC=C310SAFE5.2172832.1897643.000000
10CC(C)(C)C1=C(O)C=C(C(=C1)O)C(C)(C)C11SAFE4.9701645.0921223.721886
11CC1=NN(C(=O)C1)C2=CC=CC=C212SAFE3.7569505.1057595.633500
12NC1=CC=NC2=C1C=CC(=C2)Cl13TOXIC4.7727615.1787285.445500
13CCCCCC[CH]1CCCCN114TOXIC5.4885744.3668153.512570
14O=CC1=C2C=CC=CC2=CC3=C1C=CC=C315SAFE4.7929614.7037173.835298
15BrN1C(=O)CCC1=O16SAFE3.4350394.1776645.869000
16CCCCCCCCCCCCCCCC1=C(N)C=CC(=C1)O17SAFE5.8347175.1265653.250000
17C(COC1=C(C=CC=C1)C2=CC=CC=C2)OC3=CC=CC=C3C4=CC...18SAFE5.5208434.3984902.953857
18CCCCSCC19SAFE4.2692381.1939374.618301
19CC(=O)NC1=NC2=C(C=C1)C(=CC=N2)O20SAFE3.9303203.8556475.500000
20CC1=C2C=CC(=NC2=NC(=C1)O)N21SAFE4.2434923.3064295.250000
21CCOC(=O)C1=CN=C2N=C(N)C=CC2=C1O22SAFE4.0730272.9991024.972333
22CC1=CC(=NC=C1)N=CC2=CC=CC=C223SAFE4.5996995.4413344.008120
23C[N+](C)(C)CC1=CC=CC=C124SAFE3.9258322.0368025.000000
24C[N+](C)(C)C(=O)C1=CC=CC=C125SAFE3.9698884.7519545.000000
25ICCC(C1=CC=CC=C1)(C2=CC=CC=C2)C3=CC=CC=C326SAFE5.3919842.1748892.726521
26CC1=CC(=C(C[N+](C)(C)C)C(=C1)C)C27SAFE4.0767152.2036415.000000
27C[C](O)(CC(O)=O)C1=CC=C(C=C1)[N+]([O-])=O28SAFE3.8652242.4653275.144333
28CC1=CC=C(C=C1)C(=O)C2=CC=C(Cl)C=C229SAFE5.0550174.9683423.216634
29ON=CC1=CC=C(O)C=C130SAFE3.9687643.7374115.500000
30CC1=CC(=C(N)C(=C1)C)C31SAFE4.6966395.0641464.434087
31CC1=CC=C(C=C1)C(=O)C2=CC=C(C=C2)[N+]([O-])=O32SAFE4.7478135.1466064.597329
32CC(O)(C1=CC=CC=C1)C2=CC=CC=C233SAFE4.3724425.5081384.112840
33ON=CC1=CC(=CC=C1)[N+]([O-])=O34SAFE3.6671463.6047115.750000
34OC1=C2C=CC(=CC2=NC=C1[N+]([O-])=O)Cl35SAFE4.3080254.1512695.750000
35CC1=CC=CC2=NC=C(C)C(=C12)Cl36SAFE4.8105694.9866693.705625
36CCC(CC)([CH](OC(N)=O)C1=CC=CC=C1)C2=CC=CC=C237SAFE5.4762964.9706033.500000
37ON=C(CC1=CC=CC=C1)[CH](C#N)C2=CC=CC=C238SAFE4.4864345.0769574.839781
38O[CH](CC1=CC=CC=C1)C2=CC=CC=C239SAFE4.4148525.5081383.966036
39COC1=CC=C(CC2=CC=C(OC)C=C2)C=C140SAFE4.7297245.5362543.733636
40CN(C)[CH](C1=CC=CC=C1)C2=C(C)C=CC=C241TOXIC5.4047365.1918123.574593
41COC1=CC(=C(N)C(=C1)[N+]([O-])=O)[N+]([O-])=O42SAFE4.2570182.2414144.416720
42NN=C(C1=CC=CC=C1)C2=CC=CC=C243SAFE4.6509985.3865514.770296
43COC1=CC=C(C=C1)C=NO44SAFE3.7846364.5552425.750000
44C1=CC=C(C=C1)C(N=C(C2=CC=CC=C2)C3=CC=CC=C3)C4=...45SAFE5.4470823.9856303.000000
45C1=CC=C(C=C1)N=C(C2=CC=CC=C2)C3=CC=CC=C346SAFE5.2087064.7276273.000000
46CC1=C(C2=CC=CC=C2)C(=C3C=CC=CC3=N1)O47SAFE4.7986645.1938354.340492
47CCC1=[O+][Cu]2([O+]=C(CC)C1)[O+]=C(CC)CC(=[O+]...48SAFE4.9855592.8236355.000000
48OC(=O)[CH](CC1=CC=CC=C1)C2=CC=CC=C249SAFE4.2277755.0744065.240490
49CCC1=C(N)C=C(C)N=C150SAFE4.9144384.8266204.712651
\n", + "
" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 53 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "Filter out the TOXIC compounds based on their hERG classification.", + "id": "e38e8bb09a41c99c" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2026-03-16T07:49:29.758151366Z", + "start_time": "2026-03-16T07:49:29.706743346Z" + } + }, + "cell_type": "code", + "source": "mols_admet.filter(items=['SMILES', 'NCI_ID', 'HERG classification', 'HERG activity']).query('`HERG classification` == \"TOXIC\"')", + "id": "e832650c7a89f47f", + "outputs": [ + { + "data": { + "text/plain": [ + " SMILES NCI_ID HERG classification \\\n", + "12 NC1=CC=NC2=C1C=CC(=C2)Cl 13 TOXIC \n", + "13 CCCCCC[CH]1CCCCN1 14 TOXIC \n", + "40 CN(C)[CH](C1=CC=CC=C1)C2=C(C)C=CC=C2 41 TOXIC \n", + "\n", + " HERG activity \n", + "12 4.772761 \n", + "13 5.488574 \n", + "40 5.404736 " + ], + "text/html": [ + "
\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", + "
SMILESNCI_IDHERG classificationHERG activity
12NC1=CC=NC2=C1C=CC(=C2)Cl13TOXIC4.772761
13CCCCCC[CH]1CCCCN114TOXIC5.488574
40CN(C)[CH](C1=CC=CC=C1)C2=C(C)C=CC=C241TOXIC5.404736
\n", + "
" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 55 } ], "metadata": { diff --git a/jupyter/nci50.smiles b/jupyter/nci50.smiles new file mode 100644 index 0000000..471085f --- /dev/null +++ b/jupyter/nci50.smiles @@ -0,0 +1,50 @@ +CC1=CC(=O)C=CC1=O 1 +S(SC1=NC2=CC=CC=C2S1)C3=NC4=C(S3)C=CC=C4 2 +OC1=C(Cl)C=C(C=C1[N+]([O-])=O)[N+]([O-])=O 3 +[O-][N+](=O)C1=CNC(=N)S1 4 +NC1=CC2=C(C=C1)C(=O)C3=C(C=CC=C3)C2=O 5 +OC(=O)C1=C(C=CC=C1)C2=C3C=CC(=O)C(=C3OC4=C2C=CC(=C4Br)O)Br 6 +CN(C)C1=C(Cl)C(=O)C2=C(C=CC=C2)C1=O 7 +CC1=C(C2=C(C=C1)C(=O)C3=CC=CC=C3C2=O)[N+]([O-])=O 8 +CC(=NO)C(C)=NO 9 +C1=CC=C(C=C1)P(C2=CC=CC=C2)C3=CC=CC=C3 10 +CC(C)(C)C1=C(O)C=C(C(=C1)O)C(C)(C)C 11 +CC1=NN(C(=O)C1)C2=CC=CC=C2 12 +NC1=CC=NC2=C1C=CC(=C2)Cl 13 +CCCCCC[CH]1CCCCN1 14 +O=CC1=C2C=CC=CC2=CC3=C1C=CC=C3 15 +BrN1C(=O)CCC1=O 16 +CCCCCCCCCCCCCCCC1=C(N)C=CC(=C1)O 17 +C(COC1=C(C=CC=C1)C2=CC=CC=C2)OC3=CC=CC=C3C4=CC=CC=C4 18 +CCCCSCC 19 +CC(=O)NC1=NC2=C(C=C1)C(=CC=N2)O 20 +CC1=C2C=CC(=NC2=NC(=C1)O)N 21 +CCOC(=O)C1=CN=C2N=C(N)C=CC2=C1O 22 +CC1=CC(=NC=C1)N=CC2=CC=CC=C2 23 +C[N+](C)(C)CC1=CC=CC=C1 24 +C[N+](C)(C)C(=O)C1=CC=CC=C1 25 +ICCC(C1=CC=CC=C1)(C2=CC=CC=C2)C3=CC=CC=C3 26 +CC1=CC(=C(C[N+](C)(C)C)C(=C1)C)C 27 +C[C](O)(CC(O)=O)C1=CC=C(C=C1)[N+]([O-])=O 28 +CC1=CC=C(C=C1)C(=O)C2=CC=C(Cl)C=C2 29 +ON=CC1=CC=C(O)C=C1 30 +CC1=CC(=C(N)C(=C1)C)C 31 +CC1=CC=C(C=C1)C(=O)C2=CC=C(C=C2)[N+]([O-])=O 32 +CC(O)(C1=CC=CC=C1)C2=CC=CC=C2 33 +ON=CC1=CC(=CC=C1)[N+]([O-])=O 34 +OC1=C2C=CC(=CC2=NC=C1[N+]([O-])=O)Cl 35 +CC1=CC=CC2=NC=C(C)C(=C12)Cl 36 +CCC(CC)([CH](OC(N)=O)C1=CC=CC=C1)C2=CC=CC=C2 37 +ON=C(CC1=CC=CC=C1)[CH](C#N)C2=CC=CC=C2 38 +O[CH](CC1=CC=CC=C1)C2=CC=CC=C2 39 +COC1=CC=C(CC2=CC=C(OC)C=C2)C=C1 40 +CN(C)[CH](C1=CC=CC=C1)C2=C(C)C=CC=C2 41 +COC1=CC(=C(N)C(=C1)[N+]([O-])=O)[N+]([O-])=O 42 +NN=C(C1=CC=CC=C1)C2=CC=CC=C2 43 +COC1=CC=C(C=C1)C=NO 44 +C1=CC=C(C=C1)C(N=C(C2=CC=CC=C2)C3=CC=CC=C3)C4=CC=CC=C4 45 +C1=CC=C(C=C1)N=C(C2=CC=CC=C2)C3=CC=CC=C3 46 +CC1=C(C2=CC=CC=C2)C(=C3C=CC=CC3=N1)O 47 +CCC1=[O+][Cu]2([O+]=C(CC)C1)[O+]=C(CC)CC(=[O+]2)CC 48 +OC(=O)[CH](CC1=CC=CC=C1)C2=CC=CC=C2 49 +CCC1=C(N)C=C(C)N=C1 50 From 980ceb282c2f644322da7cc8a90495edc3585465 Mon Sep 17 00:00:00 2001 From: Levente Nagy Date: Mon, 16 Mar 2026 10:02:55 +0100 Subject: [PATCH 06/11] COG-725 Add examples for Isoelectric Point --- jupyter/02_calculators.ipynb | 321 +++++++++++++++++++++++++++++++++++ 1 file changed, 321 insertions(+) diff --git a/jupyter/02_calculators.ipynb b/jupyter/02_calculators.ipynb index 78e525f..40cf6cb 100644 --- a/jupyter/02_calculators.ipynb +++ b/jupyter/02_calculators.ipynb @@ -1426,6 +1426,327 @@ } ], "execution_count": 55 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### **Isoelectric point calculation**", + "id": "460ca8eb85abedbe" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2026-03-16T08:32:16.587113874Z", + "start_time": "2026-03-16T08:32:16.546646690Z" + } + }, + "cell_type": "code", + "source": [ + "from chemaxon import isoelectric_point\n", + "\n", + "glycine_mol = import_mol('C(C(=O)O)N')\n", + "\n", + "res = isoelectric_point(glycine_mol)\n", + "\n", + "print('Isoelectric point of glycine: ', res.isoelectric_point)\n", + "print('Charge distributions: \\n', res.charge_distributions)\n", + "print()" + ], + "id": "4d623f46db883daf", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Isoelectric point of glycine: 5.7764474458532655\n", + "Charge distributions: \n", + " [0.9950975988329285, 0.9846598571913905, 0.9530476031965848, 0.8652081089245873, 0.6699470037872222, 0.39094357485128406, 0.16873158347385953, 0.06031498852059858, 0.01988860103811574, 0.00635972354141523, 0.001968209077158334, 0.0004596767143161262, -0.0003717231072617455, -0.001750806299997576, -0.0056967698521620536, -0.017851775392175973, -0.0543709597689046, -0.1538533154447136, -0.36507675979409415, -0.645174948815991, -0.8518505236262278, -0.9478702541903009, -0.982905806743576, -0.9945304099769148, -0.9982638707242296, -0.9994503352013361, -0.9998261153749171, -0.9999450063148564, -0.9999826088158388]\n", + "\n", + "Charge distribution of glycine at pH 7.4: -0.014229480603322187\n" + ] + } + ], + "execution_count": 72 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2026-03-16T09:02:42.633423104Z", + "start_time": "2026-03-16T09:02:42.579911400Z" + } + }, + "cell_type": "code", + "source": [ + "res = isoelectric_point(glycine_mol, ph_step=0.5)\n", + "\n", + "rows = []\n", + "ph_val = 0.0\n", + "for charge in res.charge_distributions:\n", + " rows.append({'pH': ph_val, 'Charge distribution': charge})\n", + " ph_val += 0.5\n", + "\n", + "df = pandas.DataFrame(rows)\n", + "df" + ], + "id": "efa7a82fc57b8f03", + "outputs": [ + { + "data": { + "text/plain": [ + " pH Charge distribution\n", + "0 0.0 0.995098\n", + "1 0.5 0.984660\n", + "2 1.0 0.953048\n", + "3 1.5 0.865208\n", + "4 2.0 0.669947\n", + "5 2.5 0.390944\n", + "6 3.0 0.168732\n", + "7 3.5 0.060315\n", + "8 4.0 0.019889\n", + "9 4.5 0.006360\n", + "10 5.0 0.001968\n", + "11 5.5 0.000460\n", + "12 6.0 -0.000372\n", + "13 6.5 -0.001751\n", + "14 7.0 -0.005697\n", + "15 7.5 -0.017852\n", + "16 8.0 -0.054371\n", + "17 8.5 -0.153853\n", + "18 9.0 -0.365077\n", + "19 9.5 -0.645175\n", + "20 10.0 -0.851851\n", + "21 10.5 -0.947870\n", + "22 11.0 -0.982906\n", + "23 11.5 -0.994530\n", + "24 12.0 -0.998264\n", + "25 12.5 -0.999450\n", + "26 13.0 -0.999826\n", + "27 13.5 -0.999945\n", + "28 14.0 -0.999983" + ], + "text/html": [ + "
\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", + " \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", + "
pHCharge distribution
00.00.995098
10.50.984660
21.00.953048
31.50.865208
42.00.669947
52.50.390944
63.00.168732
73.50.060315
84.00.019889
94.50.006360
105.00.001968
115.50.000460
126.0-0.000372
136.5-0.001751
147.0-0.005697
157.5-0.017852
168.0-0.054371
178.5-0.153853
189.0-0.365077
199.5-0.645175
2010.0-0.851851
2110.5-0.947870
2211.0-0.982906
2311.5-0.994530
2412.0-0.998264
2512.5-0.999450
2613.0-0.999826
2713.5-0.999945
2814.0-0.999983
\n", + "
" + ] + }, + "execution_count": 88, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 88 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2026-03-16T09:01:30.686598128Z", + "start_time": "2026-03-16T09:01:30.503011191Z" + } + }, + "cell_type": "code", + "source": [ + "#!{sys.executable} -m pip install matplotlib\n", + "\n", + "import matplotlib\n", + "\n", + "df.plot(x='pH', y='Charge distribution', kind='line', marker='o', title='Charge Distribution vs pH for Glycine', grid=True)" + ], + "id": "8b391de8a48db2d5", + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 87, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "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/BASiQRvvvkmsrKysGjRIowcORKxsbEVxtSvXz9YW1vjhx9+wOOPP66zb/PmzWjbti38/f0BAM888wxOnjyJKVOmwMvLC+np6YiKisKVK1eq7MOSkhKEhYXhkUcewaJFixAZGYmIiAgUFxdj7ty5OmULCgrKXdidm5tb6TmA0j62t7fH66+/jueeew59+/aFtbU1AODkyZN49NFHYWtri+nTp0Mmk+Grr75Cz549sXfvXgQGBurUVd73Snm2bdsGAGVGJmvi+eefx9y5c7F582adabWioiJs2bIFzzzzjHaEcc2aNXjhhRfQtm1bzJw5E/b29vjnn38QGRmJESNGVHqeDRs2ICcnBy+//DIEQcCiRYswePBgXLp0STvqc/LkSXTv3h1NmjTBjBkzYGVlhR9++AGDBg3CTz/9VOZzR/WMSGRAWVlZIgBx4MCB1T4GgGhubi5euHBBu+3YsWMiAHHp0qXabfn5+WWOjYmJEQGI69at02779ttvRQBijx49xOLiYu32wsJC0cnJSXz44YdFlUql3b5mzRoRgPj4449rt3333XeiRCIR//77b53zrVixQgQgHjhwoNI2jRkzRrSysqpw/z///CMCEF9//XXttscff1wnhoEDB4pt27at9DwfffSRCEBMSkoqsw+AKJFIxJMnT5a7LyIiQvs+IiJCBCA+9dRTOuUmTZokAhCPHTsmiqIoJiUliQDEb7/9tso6K4utefPm4pgxY7Tvp06dKgLQ6e+cnBzR29tb9PLyEktKSkRRFMXdu3eLAERfX1+xsLBQW/bzzz8XAYgnTpwoc657Pffcc6Krq6vO5yIlJUWUSCTi3LlzRVEUxTt37ogAxI8++qjSusozZswYEYA4ZcoU7Ta1Wi3269dPNDc3F2/evKndDqDK1+HDhys9n+brcX+sgwYNEs3NzcWLFy9qt924cUO0sbERH3vsMe22ir5XKtKpUyfR3t6+zPbc3Fzx5s2b2ldWVpZ2n+Zrtnv3bu22oKAgMTAwUKeOn3/+WadcZmamaGNjIwYGBop3797VKatWq7X/HzNmjNi8efMyfeLk5CRmZGRot//2228iAHHbtm3abb179xbbtWsnFhQU6NTdrVs3sXXr1lX2BxkXp6jIoLKzswEANjY2NTouODgYLVu21L5v3749bG1tcenSJe02CwsL7f9VKhVu376NVq1a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" + }, + "metadata": {}, + "output_type": "display_data", + "jetTransient": { + "display_id": null + } + } + ], + "execution_count": 87 } ], "metadata": { From 3d1b0b0c725021022e100bb74c66f314c34219d8 Mon Sep 17 00:00:00 2001 From: Levente Nagy Date: Tue, 24 Mar 2026 10:50:25 +0100 Subject: [PATCH 07/11] COG-764 Refactor docs --- README.md | 4 +- jupyter/04_standardizer.ipynb | 22 ++++ jupyter/05_structure_checker.ipynb | 12 ++ jupyter/06_molecule_search.ipynb | 28 ++--- jupyter/08_fingerprint_calculations.ipynb | 147 ++++++++++++++++++++++ 5 files changed, 190 insertions(+), 23 deletions(-) create mode 100644 jupyter/08_fingerprint_calculations.ipynb diff --git a/README.md b/README.md index 187541f..258eb88 100644 --- a/README.md +++ b/README.md @@ -10,5 +10,5 @@ This repository contains usage examples for [Chemaxon Python API](https://docs.c ## Note -If you have any question, suggestion please feel free to contact us at -[`chemlib@chemaxon.com`](mailto:chemlib@chemaxon.com) +If you have any question, suggestion please feel free to contact us via +[FreshDesk support](https://chemaxon.freshdesk.com/a/tickets/new) diff --git a/jupyter/04_standardizer.ipynb b/jupyter/04_standardizer.ipynb index 46dae10..7cc81ed 100644 --- a/jupyter/04_standardizer.ipynb +++ b/jupyter/04_standardizer.ipynb @@ -2478,6 +2478,28 @@ "source": [ "Standardizer('ungroupsgroups..aromatize').standardize(mol_w_sgroups)" ] + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "Using XML configuration for standardizer:", + "id": "507a202d9414b975" + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": [ + "from chemaxon import import_mol, Standardizer\n", + "\n", + "configFile = \"path/to/my_config.xml\"\n", + "with open(configFile) as config:\n", + " standardizer = Standardizer(config)\n", + " mol = import_mol(\"[H].[H]C1=C([H])C([H])=C([H])C([H])=C1[H]\")\n", + " standard_mol = standardizer.standardize(mol)" + ], + "id": "44372e0f4eee37a6" } ], "metadata": { diff --git a/jupyter/05_structure_checker.ipynb b/jupyter/05_structure_checker.ipynb index 715d187..53cef01 100644 --- a/jupyter/05_structure_checker.ipynb +++ b/jupyter/05_structure_checker.ipynb @@ -1,5 +1,17 @@ { "cells": [ + { + "metadata": {}, + "cell_type": "markdown", + "source": "### **Structure Checker**", + "id": "a516f35da6f8f94a" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "For the concept of Structure Checker in general see [Structure Checker User's Guide](https://docs.chemaxon.com/latest/structure-checker_user-guide.html).", + "id": "cd0228716795281f" + }, { "cell_type": "code", "execution_count": 1, diff --git a/jupyter/06_molecule_search.ipynb b/jupyter/06_molecule_search.ipynb index 8d35147..0560b34 100644 --- a/jupyter/06_molecule_search.ipynb +++ b/jupyter/06_molecule_search.ipynb @@ -91,9 +91,7 @@ "cell_type": "markdown", "id": "696bd8fc-05a7-4b74-b700-b095fec68733", "metadata": {}, - "source": [ - "Hit indexes" - ] + "source": "### **Hit indexes**" }, { "cell_type": "code", @@ -111,9 +109,7 @@ "cell_type": "markdown", "id": "75c7ad5b-0e83-4525-a9fb-d9d65f472434", "metadata": {}, - "source": [ - "Duplicate search, setting search options" - ] + "source": "### **Duplicate search, setting search options**" }, { "cell_type": "code", @@ -131,9 +127,7 @@ "cell_type": "markdown", "id": "bca9acc0-dfe1-4a34-be7e-5892ff677905", "metadata": {}, - "source": [ - "Hit coloring" - ] + "source": "### **Hit coloring**" }, { "cell_type": "code", @@ -151,9 +145,7 @@ "cell_type": "markdown", "id": "5ef2d767-c818-4577-8322-98cc6680f375", "metadata": {}, - "source": [ - "Setting standardizer" - ] + "source": "### **Setting standardizer**" }, { "cell_type": "code", @@ -182,9 +174,7 @@ "cell_type": "markdown", "id": "a6fd2f42-6a18-4bf8-af30-a8126c92109a", "metadata": {}, - "source": [ - "No standardizer" - ] + "source": "### **No standardizer**" }, { "cell_type": "code", @@ -212,9 +202,7 @@ "cell_type": "markdown", "id": "a366b219-1232-4b65-bd10-73589713a051", "metadata": {}, - "source": [ - "Bulk Search" - ] + "source": "### **Bulk Search**" }, { "cell_type": "code", @@ -342,9 +330,7 @@ "cell_type": "markdown", "id": "06c1cba7-2407-41f4-ab96-adcbaa3f590f", "metadata": {}, - "source": [ - "Bulk search speed" - ] + "source": "### **Bulk search speed**" }, { "cell_type": "code", diff --git a/jupyter/08_fingerprint_calculations.ipynb b/jupyter/08_fingerprint_calculations.ipynb new file mode 100644 index 0000000..993361e --- /dev/null +++ b/jupyter/08_fingerprint_calculations.ipynb @@ -0,0 +1,147 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "initial_id", + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": "" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### **Fingerprint calculations**\n", + "id": "7d616c2b9d0bfbda" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "Chemaxon has a number of functions that you can use to generate fingerprints.\n", + "id": "441988c36dd15dbd" + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": [ + "from chemaxon import cfp, ecfp\n", + "cfp = cfp(mol)\n", + "ecfp = ecfp(mol, 4, 1024)" + ], + "id": "796299eb324647db" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "These functions return `chemaxon.fingerprints.fingerprint.Fingerprint` objects. You can get the fingerprints\n", + "in bytes or in binary string format." + ], + "id": "9a8cdfb35a01c4a7" + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": [ + "ecfp.to_bytes()\n", + "ecfp.to_binary_string()" + ], + "id": "f731dd656c472138" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "You can also calculate pharmacophore fingerprints:\n", + "id": "222cbcbc51b6ae4" + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": [ + "from chemaxon import pharmacophore_fp\n", + "pf = pharmacophore_fp(mol)" + ], + "id": "fba02898f19a990a" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "This method returns a `FloatVectorFingerprint`, which contains a float array.\n", + "\n", + "You can also calculate Tanimoto Dissimilarity for the fingerprints:" + ], + "id": "276808c169d1198e" + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": [ + "from chemaxon import tanimoto, ecfp, pharmacophore_fp, float_vector_tanimoto\n", + "ecfp1 = ecfp(mol, 4, 1024)\n", + "ecfp2 = ecfp(mol2, 4, 1024)\n", + "\n", + "result1 = tanimoto(ecfp1, ecfp2)\n", + "\n", + "pf1 = pharmacophore_fp(mol)\n", + "pf2 = pharmacophore_fp(mol2)\n", + "result2 = float_vector_tanimoto(pf1, pf2)" + ], + "id": "3f858051237a41e5" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "Reaction fingerprints can also be claucluated using the `reaction_fp` function.", + "id": "defbff32f7c6f3c1" + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": [ + "from chemaxon import reaction_fp, import_mol\n", + "\n", + "r_str = \"[#7:1][H:2].[#6:4][S:3]([#7,#9,#17,#35,#53:7])(=[O:5])=[O:6]>>[#6:4][S:3]([#7:1])(=[O:6])=[O:5]\"\n", + "\n", + "reaction_mol = import_mol(reaction_str)\n", + "result_reaction = reaction_fp(reaction_mol)\n", + "\n", + "result_reaction" + ], + "id": "36c51f56f3f34840" + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From b53d532f4b1fc0efd253ece31129ffd568128fe4 Mon Sep 17 00:00:00 2001 From: Levente Nagy Date: Tue, 24 Mar 2026 14:38:38 +0100 Subject: [PATCH 08/11] COG-764 Add Apache license --- LICENSE.txt | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 LICENSE.txt diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..e3c9ae0 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,209 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, +reproduction, + and distribution as defined by Sections 1 through 9 of this +document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under +common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making +modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or +Object + form, that is based on (or derived from) the Work and for which +the + editorial revisions, annotations, elaborations, or other +modifications + represent, as a whole, an original work of authorship. For the +purposes + of this License, Derivative Works shall not include works that +remain + separable from, or merely link (or bind by name) to the interfaces +of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or +additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright +owner + or by an individual or Legal Entity authorized to submit on behalf +of + the copyright owner. For the purposes of this definition, +"submitted" + means any form of electronic, verbal, or written communication +sent + to the Licensor or its representatives, including but not limited +to + communication on electronic mailing lists, source code control +systems, + and issue tracking systems that are managed by, or on behalf of, +the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a +Contribution." + + "Contributor" shall mean Licensor and any individual or Legal +Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have +made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute +must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; +or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The +contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state +otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or +modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the +trade + names, trademarks, service marks, or product names of the +Licensor, + except as required for reasonable and customary use in describing +the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or +conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this +License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, +special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by +reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS \ No newline at end of file From 4e0f6c20ed5ab877fcaefa10668351b1b4fadd17 Mon Sep 17 00:00:00 2001 From: Levente Nagy Date: Tue, 24 Mar 2026 14:40:44 +0100 Subject: [PATCH 09/11] COG-764 Clear up --- jupyter/08_fingerprint_calculations.ipynb | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/jupyter/08_fingerprint_calculations.ipynb b/jupyter/08_fingerprint_calculations.ipynb index 993361e..48112cc 100644 --- a/jupyter/08_fingerprint_calculations.ipynb +++ b/jupyter/08_fingerprint_calculations.ipynb @@ -1,15 +1,5 @@ { "cells": [ - { - "cell_type": "code", - "execution_count": null, - "id": "initial_id", - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": "" - }, { "metadata": {}, "cell_type": "markdown", From ffa5a751a8c20dc9aac9324742189590d11fd21f Mon Sep 17 00:00:00 2001 From: Levente Nagy Date: Tue, 24 Mar 2026 14:57:53 +0100 Subject: [PATCH 10/11] COG-764 Add CI pipeline --- .github/workflows/run-notebooks.yml | 91 +++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 .github/workflows/run-notebooks.yml diff --git a/.github/workflows/run-notebooks.yml b/.github/workflows/run-notebooks.yml new file mode 100644 index 0000000..0cf7a17 --- /dev/null +++ b/.github/workflows/run-notebooks.yml @@ -0,0 +1,91 @@ +name: Run Jupyter Notebooks + +on: + push: + branches: + - "**" + pull_request: + types: [opened, synchronize, reopened] + +jobs: + run-notebooks: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install dependencies + run: | + pip install --upgrade pip + pip install chemaxon jupyter nbconvert ipykernel + python -m ipykernel install --user --name python3 + + - name: Run 01_basic_functions.ipynb + run: | + jupyter nbconvert --to notebook --execute \ + --ExecutePreprocessor.timeout=600 \ + --output /tmp/01_basic_functions_executed.ipynb \ + jupyter/01_basic_functions.ipynb + + - name: Run 02_calculators.ipynb + run: | + jupyter nbconvert --to notebook --execute \ + --ExecutePreprocessor.timeout=600 \ + --output /tmp/02_calculators_executed.ipynb \ + jupyter/02_calculators.ipynb + + - name: Run 03_molecular_similarity.ipynb + run: | + jupyter nbconvert --to notebook --execute \ + --ExecutePreprocessor.timeout=600 \ + --output /tmp/03_molecular_similarity_executed.ipynb \ + jupyter/03_molecular_similarity.ipynb + + - name: Run 04_standardizer.ipynb + run: | + jupyter nbconvert --to notebook --execute \ + --ExecutePreprocessor.timeout=600 \ + --output /tmp/04_standardizer_executed.ipynb \ + jupyter/04_standardizer.ipynb + + - name: Run 05_structure_checker.ipynb + run: | + jupyter nbconvert --to notebook --execute \ + --ExecutePreprocessor.timeout=600 \ + --output /tmp/05_structure_checker_executed.ipynb \ + jupyter/05_structure_checker.ipynb + + - name: Run 06_molecule_search.ipynb + run: | + jupyter nbconvert --to notebook --execute \ + --ExecutePreprocessor.timeout=600 \ + --output /tmp/06_molecule_search_executed.ipynb \ + jupyter/06_molecule_search.ipynb + + - name: Run 07_pandas_integration_examples.ipynb + run: | + jupyter nbconvert --to notebook --execute \ + --ExecutePreprocessor.timeout=600 \ + --output /tmp/07_pandas_integration_examples_executed.ipynb \ + jupyter/07_pandas_integration_examples.ipynb + + - name: Run 08_fingerprint_calculations.ipynb + run: | + jupyter nbconvert --to notebook --execute \ + --ExecutePreprocessor.timeout=600 \ + --output /tmp/08_fingerprint_calculations_executed.ipynb \ + jupyter/08_fingerprint_calculations.ipynb + + - name: Upload executed notebooks as artifacts + if: always() + uses: actions/upload-artifact@v4 + with: + name: executed-notebooks + path: /tmp/*_executed.ipynb + retention-days: 7 \ No newline at end of file From 8baffebc7aceb660556a941b0342d8c9c171f90a Mon Sep 17 00:00:00 2001 From: Robert Wagner Date: Tue, 5 May 2026 15:34:40 +0200 Subject: [PATCH 11/11] COG-856 logd, isoelectric_point return ph as well --- jupyter/02_calculators.ipynb | 1617 +++------------------------------- 1 file changed, 115 insertions(+), 1502 deletions(-) diff --git a/jupyter/02_calculators.ipynb b/jupyter/02_calculators.ipynb index 40cf6cb..527aa8e 100644 --- a/jupyter/02_calculators.ipynb +++ b/jupyter/02_calculators.ipynb @@ -12,6 +12,7 @@ }, { "cell_type": "code", + "execution_count": null, "id": "4651ecec-55a8-48d2-a76e-a5c8487ef569", "metadata": { "ExecuteTime": { @@ -19,6 +20,7 @@ "start_time": "2026-03-16T07:37:44.281900876Z" } }, + "outputs": [], "source": [ "from chemaxon import import_mol, logp, logd, pka, hlb\n", "\n", @@ -28,23 +30,11 @@ "print('logD[pH 9.0]:', logd(mol, ph=9.0))\n", "print('pKa: ', pka(mol))\n", "print('hlb: ', hlb(mol))" - ], - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "logP: 0.92\n", - "logD[pH 9.0]: 0.8\n", - "pKa: [atom: 3, pka: 16.65 (ACIDIC)], [atom: 8, pka: 9.46 (ACIDIC)], [atom: 2, pka: -4.36 (BASIC)], [atom: 8, pka: -5.94 (BASIC)]\n", - "hlb: 14.14\n" - ] - } - ], - "execution_count": 21 + ] }, { "cell_type": "code", + "execution_count": null, "id": "a23b02ed-fe3b-419e-95e2-a2fee78abb3f", "metadata": { "ExecuteTime": { @@ -52,6 +42,7 @@ "start_time": "2026-03-16T07:30:38.972522816Z" } }, + "outputs": [], "source": [ "from chemaxon import import_mol, pka\n", "\n", @@ -59,21 +50,36 @@ "\n", "pka_result = pka(mol)\n", "pka_result.structure" - ], - "outputs": [ - { - "data": { - "text/plain": [ - "Molecule(_source='\\nTCC\\n', _format='mrv', _to_svg=, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(1, 2)), Bond(type=1, atoms=(1, 3)), Bond(type=1, atoms=(3, 4)), Bond(type=2, atoms=(4, 5)), Bond(type=1, atoms=(5, 6)), Bond(type=2, atoms=(6, 7)), Bond(type=1, atoms=(7, 8)), Bond(type=2, atoms=(8, 9)), Bond(type=1, atoms=(4, 9)), Bond(type=1, atoms=(9, 10)), Bond(type=1, atoms=(10, 11)), Bond(type=2, atoms=(10, 12))), atoms=(Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(0, 1)),)), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(0, 1)), Bond(type=2, atoms=(1, 2)), Bond(type=1, atoms=(1, 3)))), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=2, atoms=(1, 2)),)), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=1, atoms=(1, 3)), Bond(type=1, atoms=(3, 4)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(3, 4)), Bond(type=2, atoms=(4, 5)), Bond(type=1, atoms=(4, 9)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(4, 5)), Bond(type=1, atoms=(5, 6)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(5, 6)), Bond(type=2, atoms=(6, 7)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(6, 7)), Bond(type=1, atoms=(7, 8)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(7, 8)), Bond(type=2, atoms=(8, 9)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=2, atoms=(8, 9)), Bond(type=1, atoms=(4, 9)), Bond(type=1, atoms=(9, 10)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(9, 10)), Bond(type=1, atoms=(10, 11)), Bond(type=2, atoms=(10, 12)))), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=1, atoms=(10, 11)),)), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=2, atoms=(10, 12)),))), native_handle=1, _to_str=, properties={})" - ], - "image/svg+xml": "CH3O-7.14 OOH3.41 O\n" - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 7 + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "657e9aeb-8a20-47cd-8443-3df87c474e07", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "\n", + "!{sys.executable} -m pip install matplotlib" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "51086e75-7995-4010-96ef-b96444770342", + "metadata": {}, + "outputs": [], + "source": [ + "from chemaxon import logd_ph_range, PhRange\n", + "import matplotlib.pyplot as pyplt\n", + "\n", + "res = logd_ph_range(import_mol('aspirin'), PhRange(0, 14, 0.5))\n", + "pyplt.plot([r.pH for r in res],[r.logd for r in res])\n", + "pyplt.title(\"logD by pH\")\n", + "pyplt.xlabel(\"pH\")\n", + "pyplt.ylabel(\"logD\")" + ] }, { "cell_type": "markdown", @@ -87,23 +93,10 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "bc97b4ee-ecc0-41da-b0c1-de15e3dde46b", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Formula: C9H8O4\n", - "Atom count: 21\n", - "Ring count: 1\n", - "Fsp3: 0.1111111111111111\n", - "logP: 1.238089698333333\n", - "logS: -1.8489350401969602\n" - ] - } - ], + "outputs": [], "source": [ "from chemaxon import evaluate\n", "\n", @@ -125,163 +118,10 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "id": "edca4a1e-dda0-41e4-9a3c-1062765dcb24", "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "OOOO\n" - ], - "text/plain": [ - "Molecule(_mrv='\\n\\n', _mrv_to_svg=, bonds=(Bond(type=0, atoms=(0, 1)), Bond(type=0, atoms=(1, 2)), Bond(type=0, atoms=(1, 3)), Bond(type=1, atoms=(3, 4)), Bond(type=1, atoms=(4, 5)), Bond(type=0, atoms=(5, 6)), Bond(type=0, atoms=(6, 7)), Bond(type=1, atoms=(6, 8)), Bond(type=1, atoms=(8, 9)), Bond(type=4, atoms=(9, 10)), Bond(type=4, atoms=(10, 11)), Bond(type=4, atoms=(11, 12)), Bond(type=4, atoms=(12, 13)), Bond(type=4, atoms=(13, 14)), Bond(type=4, atoms=(9, 14)), Bond(type=1, atoms=(14, 15)), Bond(type=0, atoms=(5, 15)), Bond(type=0, atoms=(15, 16)), Bond(type=1, atoms=(4, 17)), Bond(type=4, atoms=(17, 18)), Bond(type=4, atoms=(18, 19)), Bond(type=4, atoms=(19, 20)), Bond(type=4, atoms=(20, 21)), Bond(type=4, atoms=(21, 22)), Bond(type=4, atoms=(17, 22))), atoms=(Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=0, atoms=(0, 1)),)), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=0, atoms=(0, 1)), Bond(type=0, atoms=(1, 2)), Bond(type=0, atoms=(1, 3)))), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=0, atoms=(1, 2)),)), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=0, atoms=(1, 3)), Bond(type=1, atoms=(3, 4)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(3, 4)), Bond(type=1, atoms=(4, 5)), Bond(type=1, atoms=(4, 17)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(4, 5)), Bond(type=0, atoms=(5, 6)), Bond(type=0, atoms=(5, 15)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=0, atoms=(5, 6)), Bond(type=0, atoms=(6, 7)), Bond(type=1, atoms=(6, 8)))), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=0, atoms=(6, 7)),)), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=1, atoms=(6, 8)), Bond(type=1, atoms=(8, 9)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(8, 9)), Bond(type=4, atoms=(9, 10)), Bond(type=4, atoms=(9, 14)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=4, atoms=(9, 10)), Bond(type=4, atoms=(10, 11)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=4, atoms=(10, 11)), Bond(type=4, atoms=(11, 12)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=4, atoms=(11, 12)), Bond(type=4, atoms=(12, 13)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=4, atoms=(12, 13)), Bond(type=4, atoms=(13, 14)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=4, atoms=(13, 14)), Bond(type=4, atoms=(9, 14)), Bond(type=1, atoms=(14, 15)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(14, 15)), Bond(type=0, atoms=(5, 15)), Bond(type=0, atoms=(15, 16)))), Atom(symbol='O', atom_number=8, mass_number=0, bonds=(Bond(type=0, atoms=(15, 16)),)), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=1, atoms=(4, 17)), Bond(type=4, atoms=(17, 18)), Bond(type=4, atoms=(17, 22)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=4, atoms=(17, 18)), Bond(type=4, atoms=(18, 19)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=4, atoms=(18, 19)), Bond(type=4, atoms=(19, 20)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=4, atoms=(19, 20)), Bond(type=4, atoms=(20, 21)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=4, atoms=(20, 21)), Bond(type=4, atoms=(21, 22)))), Atom(symbol='C', atom_number=6, mass_number=0, bonds=(Bond(type=4, atoms=(21, 22)), Bond(type=4, atoms=(17, 22))))))" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "warfarin = import_mol(\"warfarin\")\n", "import_mol(evaluate(warfarin, \"molFormat(genericTautomer(), 'smarts')\"))" @@ -297,29 +137,12 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "id": "abf54870-2e45-4bb6-a317-95cb3006ce92", "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Collecting pandas\n", - " Using cached pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl.metadata (89 kB)\n", - "Collecting matplotlib\n", - " Using cached matplotlib-3.10.3-cp313-cp313-macosx_11_0_arm64.whl.metadata (11 kB)\n", - "Requirement already satisfied: numpy>=1.26.0 in /opt/homebrew/Cellar/jupyterlab/4.4.1/libexec/lib/python3.13/site-packages (from pandas) (2.2.5)\n", - "...\n", - "Using cached pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl (11.3 MB)\n", - "Using cached matplotlib-3.10.3-cp313-cp313-macosx_11_0_arm64.whl (8.1 MB)\n", - "Installing collected packages: pandas, matplotlib\n", - "Successfully installed matplotlib-3.10.3 pandas-2.2.3\n" - ] - } - ], + "outputs": [], "source": [ "import sys\n", "\n", @@ -328,6 +151,7 @@ }, { "cell_type": "code", + "execution_count": null, "id": "a72c8cd9-154c-450e-80a4-58ad8a44d92c", "metadata": { "ExecuteTime": { @@ -335,125 +159,17 @@ "start_time": "2026-03-16T07:44:59.329950593Z" } }, + "outputs": [], "source": [ "import pandas\n", "\n", "mols = pandas.read_table('nci1000.smiles', names=['SMILES', 'NCI_ID'])\n", "mols" - ], - "outputs": [ - { - "data": { - "text/plain": [ - " SMILES NCI_ID\n", - "0 CC1=CC(=O)C=CC1=O 1\n", - "1 S(SC1=NC2=CC=CC=C2S1)C3=NC4=C(S3)C=CC=C4 2\n", - "2 OC1=C(Cl)C=C(C=C1[N+]([O-])=O)[N+]([O-])=O 3\n", - "3 [O-][N+](=O)C1=CNC(=N)S1 4\n", - "4 NC1=CC2=C(C=C1)C(=O)C3=C(C=CC=C3)C2=O 5\n", - ".. ... ...\n", - "995 OC(=O)CN(CC(O)=O)CC1=CC=CC=C1 1003\n", - "996 CC(C)N(CC(O)=O)CC(O)=O 1004\n", - "997 C1=CC=C(C=C1)C=NC(N=CC2=CC=CC=C2)C3=CC=CC=C3 1005\n", - "998 CC(C)(C)C[C]1(C)NC(=O)NC1=O 1006\n", - "999 CCOC(=O)C(C(C)C)C(=O)OCC 1007\n", - "\n", - "[1000 rows x 2 columns]" - ], - "text/html": [ - "
\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", - "
SMILESNCI_ID
0CC1=CC(=O)C=CC1=O1
1S(SC1=NC2=CC=CC=C2S1)C3=NC4=C(S3)C=CC=C42
2OC1=C(Cl)C=C(C=C1[N+]([O-])=O)[N+]([O-])=O3
3[O-][N+](=O)C1=CNC(=N)S14
4NC1=CC2=C(C=C1)C(=O)C3=C(C=CC=C3)C2=O5
.........
995OC(=O)CN(CC(O)=O)CC1=CC=CC=C11003
996CC(C)N(CC(O)=O)CC(O)=O1004
997C1=CC=C(C=C1)C=NC(N=CC2=CC=CC=C2)C3=CC=CC=C31005
998CC(C)(C)C[C]1(C)NC(=O)NC1=O1006
999CCOC(=O)C(C(C)C)C(=O)OCC1007
\n", - "

1000 rows × 2 columns

\n", - "
" - ] - }, - "execution_count": 49, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 49 + ] }, { "cell_type": "code", + "execution_count": null, "id": "4e7eace2-925b-4b32-b8f4-cde853fbf7ff", "metadata": { "ExecuteTime": { @@ -461,239 +177,52 @@ "start_time": "2026-03-16T07:30:04.107512383Z" } }, + "outputs": [], "source": [ "mols['LOGP'] = mols.apply(lambda row: round(logp(import_mol(row['SMILES'])), 2), axis = 'columns')\n", "mols['LOGD[3.0]'] = mols.apply(lambda row: logd(import_mol(row['SMILES']), ph=3.0), axis = 'columns')\n", "mols['LOGD[7.4]'] = mols.apply(lambda row: logd(import_mol(row['SMILES']), ph=7.4), axis = 'columns')\n", "mols['LOGD[11.0]'] = mols.apply(lambda row: logd(import_mol(row['SMILES']), ph=11.0), axis = 'columns')\n", "mols" - ], - "outputs": [ - { - "data": { - "text/plain": [ - " SMILES NCI_ID LOGP LOGD[3.0] \\\n", - "0 CC1=CC(=O)C=CC1=O 1 1.24 1.24 \n", - "1 S(SC1=NC2=CC=CC=C2S1)C3=NC4=C(S3)C=CC=C4 2 6.22 6.22 \n", - "2 OC1=C(Cl)C=C(C=C1[N+]([O-])=O)[N+]([O-])=O 3 2.15 1.96 \n", - "3 [O-][N+](=O)C1=CNC(=N)S1 4 -0.22 -1.69 \n", - "4 NC1=CC2=C(C=C1)C(=O)C3=C(C=CC=C3)C2=O 5 2.09 2.04 \n", - ".. ... ... ... ... \n", - "995 OC(=O)CN(CC(O)=O)CC1=CC=CC=C1 1003 -2.08 -2.08 \n", - "996 CC(C)N(CC(O)=O)CC(O)=O 1004 -3.16 -3.92 \n", - "997 C1=CC=C(C=C1)C=NC(N=CC2=CC=CC=C2)C3=CC=CC=C3 1005 5.72 5.72 \n", - "998 CC(C)(C)C[C]1(C)NC(=O)NC1=O 1006 1.19 1.19 \n", - "999 CCOC(=O)C(C(C)C)C(=O)OCC 1007 2.02 2.02 \n", - "\n", - " LOGD[7.4] LOGD[11.0] \n", - "0 1.24 1.24 \n", - "1 6.22 6.22 \n", - "2 0.25 0.25 \n", - "3 -0.27 -0.33 \n", - "4 2.09 2.09 \n", - ".. ... ... \n", - "995 -5.27 -6.17 \n", - "996 -6.30 -6.31 \n", - "997 5.72 5.72 \n", - "998 1.19 0.04 \n", - "999 2.02 2.02 \n", - "\n", - "[1000 rows x 6 columns]" - ], - "text/html": [ - "
\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", - " \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", - "
SMILESNCI_IDLOGPLOGD[3.0]LOGD[7.4]LOGD[11.0]
0CC1=CC(=O)C=CC1=O11.241.241.241.24
1S(SC1=NC2=CC=CC=C2S1)C3=NC4=C(S3)C=CC=C426.226.226.226.22
2OC1=C(Cl)C=C(C=C1[N+]([O-])=O)[N+]([O-])=O32.151.960.250.25
3[O-][N+](=O)C1=CNC(=N)S14-0.22-1.69-0.27-0.33
4NC1=CC2=C(C=C1)C(=O)C3=C(C=CC=C3)C2=O52.092.042.092.09
.....................
995OC(=O)CN(CC(O)=O)CC1=CC=CC=C11003-2.08-2.08-5.27-6.17
996CC(C)N(CC(O)=O)CC(O)=O1004-3.16-3.92-6.30-6.31
997C1=CC=C(C=C1)C=NC(N=CC2=CC=CC=C2)C3=CC=CC=C310055.725.725.725.72
998CC(C)(C)C[C]1(C)NC(=O)NC1=O10061.191.191.190.04
999CCOC(=O)C(C(C)C)C(=O)OCC10072.022.022.022.02
\n", - "

1000 rows × 6 columns

\n", - "
" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 6 + ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "id": "1eb642b1-4087-4f7e-90f6-6d0cc6891abe", "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[,\n", - " ],\n", - " [,\n", - " ]], dtype=object)" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "mols.hist(['LOGP', 'LOGD[3.0]', 'LOGD[7.4]', 'LOGD[11.0]'], bins=50)" ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "### **ADMET predictors**", - "id": "3342b6123213a517" + "id": "3342b6123213a517", + "metadata": {}, + "source": [ + "### **ADMET predictors**" + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "There are four endpoints available in the Chemaxon Python API falling into the ADMET predictions category: _herg_classifiaction_, _herg_activity_, _bbb_ (Blood-Brain Barrier) and _cns_mpo_ (CNS Multiparameter Optimisation).", - "id": "b55ece180fc11860" + "id": "b55ece180fc11860", + "metadata": {}, + "source": [ + "There are four endpoints available in the Chemaxon Python API falling into the ADMET predictions category: _herg_classifiaction_, _herg_activity_, _bbb_ (Blood-Brain Barrier) and _cns_mpo_ (CNS Multiparameter Optimisation)." + ] }, { + "cell_type": "code", + "execution_count": null, + "id": "283cae5aef6dbd02", "metadata": { "ExecuteTime": { "end_time": "2026-03-16T07:51:06.979709769Z", "start_time": "2026-03-16T07:51:06.856689261Z" } }, - "cell_type": "code", + "outputs": [], "source": [ "from chemaxon import herg_classification, herg_activity, bbb, cns_mpo\n", "\n", @@ -703,32 +232,19 @@ "print('HERG activity: ', herg_activity(mol).value)\n", "print('BBB score: ', bbb(mol).score)\n", "print('CNS MPO score: ', cns_mpo(mol).score)" - ], - "id": "283cae5aef6dbd02", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "CC(=O)NC1=CC=C(O)C=C1 |c:9,t:4,6| (aspirin)\n", - "\n", - "HERG classification: SAFE\n", - "HERG activity: 3.7293231167545913\n", - "BBB score: 4.486641814314721\n", - "CNS MPO score: 5.5\n" - ] - } - ], - "execution_count": 58 + ] }, { + "cell_type": "code", + "execution_count": null, + "id": "b919537734868299", "metadata": { "ExecuteTime": { "end_time": "2026-03-16T07:47:48.713812526Z", "start_time": "2026-03-16T07:47:46.021149489Z" } }, - "cell_type": "code", + "outputs": [], "source": [ "mols_admet = pandas.read_table('nci50.smiles', names=['SMILES', 'NCI_ID'])\n", "\n", @@ -738,709 +254,50 @@ "mols_admet['CNS MPO score'] = mols_admet.apply(lambda row: cns_mpo(import_mol(row['SMILES'])).score, axis = 'columns')\n", "\n", "mols_admet" - ], - "id": "b919537734868299", - "outputs": [ - { - "data": { - "text/plain": [ - " SMILES NCI_ID \\\n", - "0 CC1=CC(=O)C=CC1=O 1 \n", - "1 S(SC1=NC2=CC=CC=C2S1)C3=NC4=C(S3)C=CC=C4 2 \n", - "2 OC1=C(Cl)C=C(C=C1[N+]([O-])=O)[N+]([O-])=O 3 \n", - "3 [O-][N+](=O)C1=CNC(=N)S1 4 \n", - "4 NC1=CC2=C(C=C1)C(=O)C3=C(C=CC=C3)C2=O 5 \n", - "5 OC(=O)C1=C(C=CC=C1)C2=C3C=CC(=O)C(=C3OC4=C2C=C... 6 \n", - "6 CN(C)C1=C(Cl)C(=O)C2=C(C=CC=C2)C1=O 7 \n", - "7 CC1=C(C2=C(C=C1)C(=O)C3=CC=CC=C3C2=O)[N+]([O-])=O 8 \n", - "8 CC(=NO)C(C)=NO 9 \n", - "9 C1=CC=C(C=C1)P(C2=CC=CC=C2)C3=CC=CC=C3 10 \n", - "10 CC(C)(C)C1=C(O)C=C(C(=C1)O)C(C)(C)C 11 \n", - "11 CC1=NN(C(=O)C1)C2=CC=CC=C2 12 \n", - "12 NC1=CC=NC2=C1C=CC(=C2)Cl 13 \n", - "13 CCCCCC[CH]1CCCCN1 14 \n", - "14 O=CC1=C2C=CC=CC2=CC3=C1C=CC=C3 15 \n", - "15 BrN1C(=O)CCC1=O 16 \n", - "16 CCCCCCCCCCCCCCCC1=C(N)C=CC(=C1)O 17 \n", - "17 C(COC1=C(C=CC=C1)C2=CC=CC=C2)OC3=CC=CC=C3C4=CC... 18 \n", - "18 CCCCSCC 19 \n", - "19 CC(=O)NC1=NC2=C(C=C1)C(=CC=N2)O 20 \n", - "20 CC1=C2C=CC(=NC2=NC(=C1)O)N 21 \n", - "21 CCOC(=O)C1=CN=C2N=C(N)C=CC2=C1O 22 \n", - "22 CC1=CC(=NC=C1)N=CC2=CC=CC=C2 23 \n", - "23 C[N+](C)(C)CC1=CC=CC=C1 24 \n", - "24 C[N+](C)(C)C(=O)C1=CC=CC=C1 25 \n", - "25 ICCC(C1=CC=CC=C1)(C2=CC=CC=C2)C3=CC=CC=C3 26 \n", - "26 CC1=CC(=C(C[N+](C)(C)C)C(=C1)C)C 27 \n", - "27 C[C](O)(CC(O)=O)C1=CC=C(C=C1)[N+]([O-])=O 28 \n", - "28 CC1=CC=C(C=C1)C(=O)C2=CC=C(Cl)C=C2 29 \n", - "29 ON=CC1=CC=C(O)C=C1 30 \n", - "30 CC1=CC(=C(N)C(=C1)C)C 31 \n", - "31 CC1=CC=C(C=C1)C(=O)C2=CC=C(C=C2)[N+]([O-])=O 32 \n", - "32 CC(O)(C1=CC=CC=C1)C2=CC=CC=C2 33 \n", - "33 ON=CC1=CC(=CC=C1)[N+]([O-])=O 34 \n", - "34 OC1=C2C=CC(=CC2=NC=C1[N+]([O-])=O)Cl 35 \n", - "35 CC1=CC=CC2=NC=C(C)C(=C12)Cl 36 \n", - "36 CCC(CC)([CH](OC(N)=O)C1=CC=CC=C1)C2=CC=CC=C2 37 \n", - "37 ON=C(CC1=CC=CC=C1)[CH](C#N)C2=CC=CC=C2 38 \n", - "38 O[CH](CC1=CC=CC=C1)C2=CC=CC=C2 39 \n", - "39 COC1=CC=C(CC2=CC=C(OC)C=C2)C=C1 40 \n", - "40 CN(C)[CH](C1=CC=CC=C1)C2=C(C)C=CC=C2 41 \n", - "41 COC1=CC(=C(N)C(=C1)[N+]([O-])=O)[N+]([O-])=O 42 \n", - "42 NN=C(C1=CC=CC=C1)C2=CC=CC=C2 43 \n", - "43 COC1=CC=C(C=C1)C=NO 44 \n", - "44 C1=CC=C(C=C1)C(N=C(C2=CC=CC=C2)C3=CC=CC=C3)C4=... 45 \n", - "45 C1=CC=C(C=C1)N=C(C2=CC=CC=C2)C3=CC=CC=C3 46 \n", - "46 CC1=C(C2=CC=CC=C2)C(=C3C=CC=CC3=N1)O 47 \n", - "47 CCC1=[O+][Cu]2([O+]=C(CC)C1)[O+]=C(CC)CC(=[O+]... 48 \n", - "48 OC(=O)[CH](CC1=CC=CC=C1)C2=CC=CC=C2 49 \n", - "49 CCC1=C(N)C=C(C)N=C1 50 \n", - "\n", - " HERG classification HERG activity BBB score CNS MPO score \n", - "0 SAFE 3.527087 4.402743 5.707000 \n", - "1 SAFE 5.574522 4.511565 3.289000 \n", - "2 SAFE 3.907289 2.900463 5.199667 \n", - "3 SAFE 3.925102 2.691684 5.500000 \n", - "4 SAFE 4.381393 5.024654 5.455111 \n", - "5 SAFE 4.908793 3.096453 3.817072 \n", - "6 SAFE 3.912071 5.246618 5.869000 \n", - "7 SAFE 4.855112 4.873092 5.111222 \n", - "8 SAFE 3.536242 2.390943 5.500000 \n", - "9 SAFE 5.217283 2.189764 3.000000 \n", - "10 SAFE 4.970164 5.092122 3.721886 \n", - "11 SAFE 3.756950 5.105759 5.633500 \n", - "12 TOXIC 4.772761 5.178728 5.445500 \n", - "13 TOXIC 5.488574 4.366815 3.512570 \n", - "14 SAFE 4.792961 4.703717 3.835298 \n", - "15 SAFE 3.435039 4.177664 5.869000 \n", - "16 SAFE 5.834717 5.126565 3.250000 \n", - "17 SAFE 5.520843 4.398490 2.953857 \n", - "18 SAFE 4.269238 1.193937 4.618301 \n", - "19 SAFE 3.930320 3.855647 5.500000 \n", - "20 SAFE 4.243492 3.306429 5.250000 \n", - "21 SAFE 4.073027 2.999102 4.972333 \n", - "22 SAFE 4.599699 5.441334 4.008120 \n", - "23 SAFE 3.925832 2.036802 5.000000 \n", - "24 SAFE 3.969888 4.751954 5.000000 \n", - "25 SAFE 5.391984 2.174889 2.726521 \n", - "26 SAFE 4.076715 2.203641 5.000000 \n", - "27 SAFE 3.865224 2.465327 5.144333 \n", - "28 SAFE 5.055017 4.968342 3.216634 \n", - "29 SAFE 3.968764 3.737411 5.500000 \n", - "30 SAFE 4.696639 5.064146 4.434087 \n", - "31 SAFE 4.747813 5.146606 4.597329 \n", - "32 SAFE 4.372442 5.508138 4.112840 \n", - "33 SAFE 3.667146 3.604711 5.750000 \n", - "34 SAFE 4.308025 4.151269 5.750000 \n", - "35 SAFE 4.810569 4.986669 3.705625 \n", - "36 SAFE 5.476296 4.970603 3.500000 \n", - "37 SAFE 4.486434 5.076957 4.839781 \n", - "38 SAFE 4.414852 5.508138 3.966036 \n", - "39 SAFE 4.729724 5.536254 3.733636 \n", - "40 TOXIC 5.404736 5.191812 3.574593 \n", - "41 SAFE 4.257018 2.241414 4.416720 \n", - "42 SAFE 4.650998 5.386551 4.770296 \n", - "43 SAFE 3.784636 4.555242 5.750000 \n", - "44 SAFE 5.447082 3.985630 3.000000 \n", - "45 SAFE 5.208706 4.727627 3.000000 \n", - "46 SAFE 4.798664 5.193835 4.340492 \n", - "47 SAFE 4.985559 2.823635 5.000000 \n", - "48 SAFE 4.227775 5.074406 5.240490 \n", - "49 SAFE 4.914438 4.826620 4.712651 " - ], - "text/html": [ - "
\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", - " \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", - " \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", - " \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", - " \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", - " \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", - "
SMILESNCI_IDHERG classificationHERG activityBBB scoreCNS MPO score
0CC1=CC(=O)C=CC1=O1SAFE3.5270874.4027435.707000
1S(SC1=NC2=CC=CC=C2S1)C3=NC4=C(S3)C=CC=C42SAFE5.5745224.5115653.289000
2OC1=C(Cl)C=C(C=C1[N+]([O-])=O)[N+]([O-])=O3SAFE3.9072892.9004635.199667
3[O-][N+](=O)C1=CNC(=N)S14SAFE3.9251022.6916845.500000
4NC1=CC2=C(C=C1)C(=O)C3=C(C=CC=C3)C2=O5SAFE4.3813935.0246545.455111
5OC(=O)C1=C(C=CC=C1)C2=C3C=CC(=O)C(=C3OC4=C2C=C...6SAFE4.9087933.0964533.817072
6CN(C)C1=C(Cl)C(=O)C2=C(C=CC=C2)C1=O7SAFE3.9120715.2466185.869000
7CC1=C(C2=C(C=C1)C(=O)C3=CC=CC=C3C2=O)[N+]([O-])=O8SAFE4.8551124.8730925.111222
8CC(=NO)C(C)=NO9SAFE3.5362422.3909435.500000
9C1=CC=C(C=C1)P(C2=CC=CC=C2)C3=CC=CC=C310SAFE5.2172832.1897643.000000
10CC(C)(C)C1=C(O)C=C(C(=C1)O)C(C)(C)C11SAFE4.9701645.0921223.721886
11CC1=NN(C(=O)C1)C2=CC=CC=C212SAFE3.7569505.1057595.633500
12NC1=CC=NC2=C1C=CC(=C2)Cl13TOXIC4.7727615.1787285.445500
13CCCCCC[CH]1CCCCN114TOXIC5.4885744.3668153.512570
14O=CC1=C2C=CC=CC2=CC3=C1C=CC=C315SAFE4.7929614.7037173.835298
15BrN1C(=O)CCC1=O16SAFE3.4350394.1776645.869000
16CCCCCCCCCCCCCCCC1=C(N)C=CC(=C1)O17SAFE5.8347175.1265653.250000
17C(COC1=C(C=CC=C1)C2=CC=CC=C2)OC3=CC=CC=C3C4=CC...18SAFE5.5208434.3984902.953857
18CCCCSCC19SAFE4.2692381.1939374.618301
19CC(=O)NC1=NC2=C(C=C1)C(=CC=N2)O20SAFE3.9303203.8556475.500000
20CC1=C2C=CC(=NC2=NC(=C1)O)N21SAFE4.2434923.3064295.250000
21CCOC(=O)C1=CN=C2N=C(N)C=CC2=C1O22SAFE4.0730272.9991024.972333
22CC1=CC(=NC=C1)N=CC2=CC=CC=C223SAFE4.5996995.4413344.008120
23C[N+](C)(C)CC1=CC=CC=C124SAFE3.9258322.0368025.000000
24C[N+](C)(C)C(=O)C1=CC=CC=C125SAFE3.9698884.7519545.000000
25ICCC(C1=CC=CC=C1)(C2=CC=CC=C2)C3=CC=CC=C326SAFE5.3919842.1748892.726521
26CC1=CC(=C(C[N+](C)(C)C)C(=C1)C)C27SAFE4.0767152.2036415.000000
27C[C](O)(CC(O)=O)C1=CC=C(C=C1)[N+]([O-])=O28SAFE3.8652242.4653275.144333
28CC1=CC=C(C=C1)C(=O)C2=CC=C(Cl)C=C229SAFE5.0550174.9683423.216634
29ON=CC1=CC=C(O)C=C130SAFE3.9687643.7374115.500000
30CC1=CC(=C(N)C(=C1)C)C31SAFE4.6966395.0641464.434087
31CC1=CC=C(C=C1)C(=O)C2=CC=C(C=C2)[N+]([O-])=O32SAFE4.7478135.1466064.597329
32CC(O)(C1=CC=CC=C1)C2=CC=CC=C233SAFE4.3724425.5081384.112840
33ON=CC1=CC(=CC=C1)[N+]([O-])=O34SAFE3.6671463.6047115.750000
34OC1=C2C=CC(=CC2=NC=C1[N+]([O-])=O)Cl35SAFE4.3080254.1512695.750000
35CC1=CC=CC2=NC=C(C)C(=C12)Cl36SAFE4.8105694.9866693.705625
36CCC(CC)([CH](OC(N)=O)C1=CC=CC=C1)C2=CC=CC=C237SAFE5.4762964.9706033.500000
37ON=C(CC1=CC=CC=C1)[CH](C#N)C2=CC=CC=C238SAFE4.4864345.0769574.839781
38O[CH](CC1=CC=CC=C1)C2=CC=CC=C239SAFE4.4148525.5081383.966036
39COC1=CC=C(CC2=CC=C(OC)C=C2)C=C140SAFE4.7297245.5362543.733636
40CN(C)[CH](C1=CC=CC=C1)C2=C(C)C=CC=C241TOXIC5.4047365.1918123.574593
41COC1=CC(=C(N)C(=C1)[N+]([O-])=O)[N+]([O-])=O42SAFE4.2570182.2414144.416720
42NN=C(C1=CC=CC=C1)C2=CC=CC=C243SAFE4.6509985.3865514.770296
43COC1=CC=C(C=C1)C=NO44SAFE3.7846364.5552425.750000
44C1=CC=C(C=C1)C(N=C(C2=CC=CC=C2)C3=CC=CC=C3)C4=...45SAFE5.4470823.9856303.000000
45C1=CC=C(C=C1)N=C(C2=CC=CC=C2)C3=CC=CC=C346SAFE5.2087064.7276273.000000
46CC1=C(C2=CC=CC=C2)C(=C3C=CC=CC3=N1)O47SAFE4.7986645.1938354.340492
47CCC1=[O+][Cu]2([O+]=C(CC)C1)[O+]=C(CC)CC(=[O+]...48SAFE4.9855592.8236355.000000
48OC(=O)[CH](CC1=CC=CC=C1)C2=CC=CC=C249SAFE4.2277755.0744065.240490
49CCC1=C(N)C=C(C)N=C150SAFE4.9144384.8266204.712651
\n", - "
" - ] - }, - "execution_count": 53, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 53 + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "Filter out the TOXIC compounds based on their hERG classification.", - "id": "e38e8bb09a41c99c" + "id": "e38e8bb09a41c99c", + "metadata": {}, + "source": [ + "Filter out the TOXIC compounds based on their hERG classification." + ] }, { + "cell_type": "code", + "execution_count": null, + "id": "e832650c7a89f47f", "metadata": { "ExecuteTime": { "end_time": "2026-03-16T07:49:29.758151366Z", "start_time": "2026-03-16T07:49:29.706743346Z" } }, - "cell_type": "code", - "source": "mols_admet.filter(items=['SMILES', 'NCI_ID', 'HERG classification', 'HERG activity']).query('`HERG classification` == \"TOXIC\"')", - "id": "e832650c7a89f47f", - "outputs": [ - { - "data": { - "text/plain": [ - " SMILES NCI_ID HERG classification \\\n", - "12 NC1=CC=NC2=C1C=CC(=C2)Cl 13 TOXIC \n", - "13 CCCCCC[CH]1CCCCN1 14 TOXIC \n", - "40 CN(C)[CH](C1=CC=CC=C1)C2=C(C)C=CC=C2 41 TOXIC \n", - "\n", - " HERG activity \n", - "12 4.772761 \n", - "13 5.488574 \n", - "40 5.404736 " - ], - "text/html": [ - "
\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", - "
SMILESNCI_IDHERG classificationHERG activity
12NC1=CC=NC2=C1C=CC(=C2)Cl13TOXIC4.772761
13CCCCCC[CH]1CCCCN114TOXIC5.488574
40CN(C)[CH](C1=CC=CC=C1)C2=C(C)C=CC=C241TOXIC5.404736
\n", - "
" - ] - }, - "execution_count": 55, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 55 + "outputs": [], + "source": [ + "mols_admet.filter(items=['SMILES', 'NCI_ID', 'HERG classification', 'HERG activity']).query('`HERG classification` == \"TOXIC\"')" + ] }, { - "metadata": {}, "cell_type": "markdown", - "source": "### **Isoelectric point calculation**", - "id": "460ca8eb85abedbe" + "id": "460ca8eb85abedbe", + "metadata": {}, + "source": [ + "### **Isoelectric point calculation**" + ] }, { + "cell_type": "code", + "execution_count": null, + "id": "4d623f46db883daf", "metadata": { "ExecuteTime": { "end_time": "2026-03-16T08:32:16.587113874Z", "start_time": "2026-03-16T08:32:16.546646690Z" } }, - "cell_type": "code", + "outputs": [], "source": [ "from chemaxon import isoelectric_point\n", "\n", @@ -1451,302 +308,58 @@ "print('Isoelectric point of glycine: ', res.isoelectric_point)\n", "print('Charge distributions: \\n', res.charge_distributions)\n", "print()" - ], - "id": "4d623f46db883daf", - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Isoelectric point of glycine: 5.7764474458532655\n", - "Charge distributions: \n", - " [0.9950975988329285, 0.9846598571913905, 0.9530476031965848, 0.8652081089245873, 0.6699470037872222, 0.39094357485128406, 0.16873158347385953, 0.06031498852059858, 0.01988860103811574, 0.00635972354141523, 0.001968209077158334, 0.0004596767143161262, -0.0003717231072617455, -0.001750806299997576, -0.0056967698521620536, -0.017851775392175973, -0.0543709597689046, -0.1538533154447136, -0.36507675979409415, -0.645174948815991, -0.8518505236262278, -0.9478702541903009, -0.982905806743576, -0.9945304099769148, -0.9982638707242296, -0.9994503352013361, -0.9998261153749171, -0.9999450063148564, -0.9999826088158388]\n", - "\n", - "Charge distribution of glycine at pH 7.4: -0.014229480603322187\n" - ] - } - ], - "execution_count": 72 + ] }, { + "cell_type": "code", + "execution_count": null, + "id": "efa7a82fc57b8f03", "metadata": { "ExecuteTime": { "end_time": "2026-03-16T09:02:42.633423104Z", "start_time": "2026-03-16T09:02:42.579911400Z" } }, - "cell_type": "code", + "outputs": [], "source": [ - "res = isoelectric_point(glycine_mol, ph_step=0.5)\n", + "from chemaxon import PhRange\n", + "\n", + "res = isoelectric_point(glycine_mol, ph_range=PhRange(0, 14, 0.5))\n", "\n", "rows = []\n", - "ph_val = 0.0\n", - "for charge in res.charge_distributions:\n", - " rows.append({'pH': ph_val, 'Charge distribution': charge})\n", - " ph_val += 0.5\n", + "for charge_res in res.charge_distributions:\n", + " rows.append({'pH': charge_res.pH, 'Charge distribution': charge_res.charge})\n", "\n", "df = pandas.DataFrame(rows)\n", "df" - ], - "id": "efa7a82fc57b8f03", - "outputs": [ - { - "data": { - "text/plain": [ - " pH Charge distribution\n", - "0 0.0 0.995098\n", - "1 0.5 0.984660\n", - "2 1.0 0.953048\n", - "3 1.5 0.865208\n", - "4 2.0 0.669947\n", - "5 2.5 0.390944\n", - "6 3.0 0.168732\n", - "7 3.5 0.060315\n", - "8 4.0 0.019889\n", - "9 4.5 0.006360\n", - "10 5.0 0.001968\n", - "11 5.5 0.000460\n", - "12 6.0 -0.000372\n", - "13 6.5 -0.001751\n", - "14 7.0 -0.005697\n", - "15 7.5 -0.017852\n", - "16 8.0 -0.054371\n", - "17 8.5 -0.153853\n", - "18 9.0 -0.365077\n", - "19 9.5 -0.645175\n", - "20 10.0 -0.851851\n", - "21 10.5 -0.947870\n", - "22 11.0 -0.982906\n", - "23 11.5 -0.994530\n", - "24 12.0 -0.998264\n", - "25 12.5 -0.999450\n", - "26 13.0 -0.999826\n", - "27 13.5 -0.999945\n", - "28 14.0 -0.999983" - ], - "text/html": [ - "
\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", - " \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", - "
pHCharge distribution
00.00.995098
10.50.984660
21.00.953048
31.50.865208
42.00.669947
52.50.390944
63.00.168732
73.50.060315
84.00.019889
94.50.006360
105.00.001968
115.50.000460
126.0-0.000372
136.5-0.001751
147.0-0.005697
157.5-0.017852
168.0-0.054371
178.5-0.153853
189.0-0.365077
199.5-0.645175
2010.0-0.851851
2110.5-0.947870
2211.0-0.982906
2311.5-0.994530
2412.0-0.998264
2512.5-0.999450
2613.0-0.999826
2713.5-0.999945
2814.0-0.999983
\n", - "
" - ] - }, - "execution_count": 88, - "metadata": {}, - "output_type": "execute_result" - } - ], - "execution_count": 88 + ] }, { + "cell_type": "code", + "execution_count": null, + "id": "07b2160b-1162-4c08-afa5-40d0197fccec", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8b391de8a48db2d5", "metadata": { "ExecuteTime": { "end_time": "2026-03-16T09:01:30.686598128Z", "start_time": "2026-03-16T09:01:30.503011191Z" } }, - "cell_type": "code", + "outputs": [], "source": [ "#!{sys.executable} -m pip install matplotlib\n", "\n", "import matplotlib\n", "\n", "df.plot(x='pH', y='Charge distribution', kind='line', marker='o', title='Charge Distribution vs pH for Glycine', grid=True)" - ], - "id": "8b391de8a48db2d5", - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 87, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "text/plain": [ - "
" - ], - "image/png": "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/BASiQRvvvkmsrKysGjRIowcORKxsbEVxtSvXz9YW1vjhx9+wOOPP66zb/PmzWjbti38/f0BAM888wxOnjyJKVOmwMvLC+np6YiKisKVK1eq7MOSkhKEhYXhkUcewaJFixAZGYmIiAgUFxdj7ty5OmULCgrKXdidm5tb6TmA0j62t7fH66+/jueeew59+/aFtbU1AODkyZN49NFHYWtri+nTp0Mmk+Grr75Cz549sXfvXgQGBurUVd73Snm2bdsGAGVGJmvi+eefx9y5c7F582adabWioiJs2bIFzzzzjHaEcc2aNXjhhRfQtm1bzJw5E/b29vjnn38QGRmJESNGVHqeDRs2ICcnBy+//DIEQcCiRYswePBgXLp0STvqc/LkSXTv3h1NmjTBjBkzYGVlhR9++AGDBg3CTz/9VOZzR/WMSGRAWVlZIgBx4MCB1T4GgGhubi5euHBBu+3YsWMiAHHp0qXabfn5+WWOjYmJEQGI69at02779ttvRQBijx49xOLiYu32wsJC0cnJSXz44YdFlUql3b5mzRoRgPj4449rt3333XeiRCIR//77b53zrVixQgQgHjhwoNI2jRkzRrSysqpw/z///CMCEF9//XXttscff1wnhoEDB4pt27at9DwfffSRCEBMSkoqsw+AKJFIxJMnT5a7LyIiQvs+IiJCBCA+9dRTOuUmTZokAhCPHTsmiqIoJiUliQDEb7/9tso6K4utefPm4pgxY7Tvp06dKgLQ6e+cnBzR29tb9PLyEktKSkRRFMXdu3eLAERfX1+xsLBQW/bzzz8XAYgnTpwoc657Pffcc6Krq6vO5yIlJUWUSCTi3LlzRVEUxTt37ogAxI8++qjSusozZswYEYA4ZcoU7Ta1Wi3269dPNDc3F2/evKndDqDK1+HDhys9n+brcX+sgwYNEs3NzcWLFy9qt924cUO0sbERH3vsMe22ir5XKtKpUyfR3t6+zPbc3Fzx5s2b2ldWVpZ2n+Zrtnv3bu22oKAgMTAwUKeOn3/+WadcZmamaGNjIwYGBop3797VKatWq7X/HzNmjNi8efMyfeLk5CRmZGRot//2228iAHHbtm3abb179xbbtWsnFhQU6NTdrVs3sXXr1lX2BxkXp6jIoLKzswEANjY2NTouODgYLVu21L5v3749bG1tcenSJe02CwsL7f9VKhVu376NVq1a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" - }, - "metadata": {}, - "output_type": "display_data", - "jetTransient": { - "display_id": null - } - } - ], - "execution_count": 87 + ] } ], "metadata": { @@ -1765,7 +378,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.13.3" + "version": "3.12.3" } }, "nbformat": 4,