Skip to content

Commit

Permalink
Doc build
Browse files Browse the repository at this point in the history
  • Loading branch information
GitHub Action committed Sep 5, 2024
0 parents commit d4eda43
Show file tree
Hide file tree
Showing 73 changed files with 7,684 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .buildinfo
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: 9cf4d0d6805e81865f50473ee73df2e7
tags: 645f666f9bcd5a90fca523b33c5a78b7
Binary file added .doctrees/environment.pickle
Binary file not shown.
Binary file added .doctrees/functional_groups.doctree
Binary file not shown.
Binary file added .doctrees/getting_started.doctree
Binary file not shown.
Binary file added .doctrees/graph_syntax.doctree
Binary file not shown.
Binary file added .doctrees/index.doctree
Binary file not shown.
Binary file added .doctrees/proxy_collection.doctree
Binary file not shown.
Binary file added .doctrees/references.doctree
Binary file not shown.
Empty file added .nojekyll
Empty file.
Binary file added _images/caffeine_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/diels_alder_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/labeled_node_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/multiple_anchor_example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/proxy_collection_DAReactionProxy.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/proxy_collection_DAReactionProxy_EDG.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added _images/proxy_collection_DAReactionProxy_EWG.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
96 changes: 96 additions & 0 deletions _sources/functional_groups.rst.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
=================
Functional Groups
=================

FGUtils provides a class :py:class:`~fgutils.query.FGQuery` to retrieve a
molecules functional groups. It can be used directly with the preconfigured
list of functional groups as listed in `Functional Group Tree`_ or by
specifying your own patterns using :py:class:`~fgutils.fgconfig.FGConfig`
and :py:class:`~fgutils.fgconfig.FGConfigProvider`.

Get functional groups in molecule
=================================

Common functional groups of a molecule can be retrieved by the
:py:class:`~fgutils.query.FGQuery` class. The query can directly use the
molecules SMILES or the molecular graph representation of the compound as
networkx graph. The following example demonstrates how to get the functional
groups from *acetylsalicylic acid*::

>>> from fgutils import FGQuery

>>> smiles = "O=C(C)Oc1ccccc1C(=O)O" # acetylsalicylic acid
>>> query = FGQuery()
>>> query.get(smiles)
[("ester", [0, 1, 3]), ("carboxylic_acid", [10, 11, 12])]


Get changing groups in reaction
===============================

The extended :ref:`graph-syntax` enables the description of reaction
mechanisms by specifying bond changes in ``<>`` brackets. Functional group
patterns can therefor also specify bond changes. Querying bond changes can be
used to look for a changing functional groups in a reaction. The following
example demonstrates how to check for a nucleophilic addition-elimination
reaction on a carbonyl group::

>>> from fgutils.query import FGQuery, FGConfig

>>> smiles = "[C:1][C:2](=[O:3])[O:4][C:5].[O:6]>>[C:1][C:2](=[O:3])[O:6].[O:4][C:5]"
>>> fgconfig = FGConfig(name="carbonyl-AE", pattern="C(=O)(<0,1>R)<1,0>R")
>>> query = FGQuery(config=fgconfig, require_implicit_hydrogen=False)
>>> query.get(smiles)
[("carbonyl-AE", [2, 3, 4, 6])]


Functional Group Tree
=====================

.. code-block::
Functional Group Parents Pattern
--------------------------------------------------------------------------
ether [ROOT] ROR
├── ketal [ether] RC(OR)(OR)R
│ ├── acetal [ketal] RC(OC)(OC)H
│ └── hemiketal [ketal, alcohol] RC(OH)(OR)R
│ └── hemiacetal [hemiketal] RC(OC)(OH)H
├── ester [ketone, ether] RC(=O)OR
│ ├── anhydride [ester] RC(=O)OC(=O)R
│ ├── peroxy_acid [ester, peroxide] RC(=O)OOH
│ ├── carbamate [ester, amide] ROC(=O)N(R)R
│ └── carboxylic_acid [ester, alcohol] RC(=O)OH
├── alcohol [ether] COH
│ ├── hemiketal [ketal, alcohol] RC(OH)(OR)R
│ │ └── hemiacetal [hemiketal] RC(OC)(OH)H
│ ├── carboxylic_acid [ester, alcohol] RC(=O)OH
│ ├── enol [alcohol] C=COH
│ ├── primary_alcohol [alcohol] CCOH
│ │ └── secondary_alcohol [primary_alcohol] C(C)(C)OH
│ │ └── tertiary_alcohol [secondary_alcohol] C(C)(C)(C)OH
│ └── phenol [alcohol] C:COH
└── peroxide [ether] ROOR
└── peroxy_acid [ester, peroxide] RC(=O)OOH
thioether [ROOT] RSR
└── thioester [ketone, thioether] RC(=O)SR
amine [ROOT] RN(R)R
├── amide [ketone, amine] RC(=O)N(R)R
│ └── carbamate [ester, amide] ROC(=O)N(R)R
└── anilin [amine] C:CN(R)R
carbonyl [ROOT] C(=O)
├── ketene [carbonyl] RC(R)=C=O
└── ketone [carbonyl] RC(=O)R
├── amide [ketone, amine] RC(=O)N(R)R
│ └── carbamate [ester, amide] ROC(=O)N(R)R
├── thioester [ketone, thioether] RC(=O)SR
├── ester [ketone, ether] RC(=O)OR
│ ├── anhydride [ester] RC(=O)OC(=O)R
│ ├── peroxy_acid [ester, peroxide] RC(=O)OOH
│ ├── carbamate [ester, amide] ROC(=O)N(R)R
│ └── carboxylic_acid [ester, alcohol] RC(=O)OH
├── acyl_chloride [ketone] RC(=O)Cl
└── aldehyde [ketone] RC(=O)H
nitrose [ROOT] RN=O
└── nitro [nitrose] RN(=O)O
nitrile [ROOT] RC#N
15 changes: 15 additions & 0 deletions _sources/getting_started.rst.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
===============
Getting Started
===============

Installation
============


Query Functional Groups
=======================



A Simple Reaction Proxy
=======================
186 changes: 186 additions & 0 deletions _sources/graph_syntax.rst.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
.. _graph-syntax:

============
Graph Syntax
============

FGUtils has its own graph description language. The syntax is closely related
to the SMILES format for molecules and reactions. It is kind of an extenstion
to SMILES to support modeling ITS graphs and reaction patterns. To convert the
SMILES-like description into a graph object use the
:py:class:`~fgutils.parse.Parser` class. The Caffeine molecular graph can be
obtained as follows::

import matplotlib.pyplot as plt
from fgutils import Parser
from fgutils.vis import plot_as_mol

parser = Parser()
mol = parser("CN1C=NC2=C1C(=O)N(C(=O)N2C)C")

fig, ax = plt.subplots(1, 1)
plot_as_mol(mol, ax)
plt.show()

.. image:: figures/caffeine_example.png
:width: 300

Besides parsing common SMILES it is possible to generate molecule-like graphs
with more abstract nodes, i.e., arbitrary node labels. Arbitrary node labels
are surrounded by ``{}`` (e.g. ``{label}``). This abstract labeling can be used
to substitute nodes with specific patterns. In this context the labels are
group names of :py:class:`~fgutils.proxy.ProxyGroup` objects. A ProxyGroup
defines a set of sub-graphs to be replaced for the labeled node. This can be
done by using a :py:class:`~fgutils.proxy.Proxy`. Propyl acetate can be created
by replacing the labeled node with the propyl group::

import matplotlib.pyplot as plt
from fgutils import Parser
from fgutils.proxy import MolProxy, ProxyGroup
from fgutils.vis import GraphVisualizer

pattern = "CC(=O)O{propyl}"
propyl_group = ProxyGroup("propyl", "CCC")
parser = Parser()
proxy = MolProxy(pattern, propyl_group, parser=parser)

g = parser(pattern)
mol = next(proxy)

vis = GraphVisualizer()
fig, ax = plt.subplots(1, 2, dpi=100, figsize=(12, 3))
vis.plot(g, ax[0], title="Core Pattern")
vis.plot(mol, ax[1], title="Generated Molecule")
plt.show()

.. image:: figures/labeled_node_example.png
:width: 600


.. note::

A node can have more than one label. This can be done by separating the
labels with a comma, e.g.: ``{label_1,label_2}``.

In the example above the ProxyGroup has only one subgraph pattern. In general,
a ProxyGroup is a collection of several possible subgraphs from which one is
selected when a new sample is instantiated. To get more information on how
graphs are sample take a look at the :py:class:`~fgutils.proxy.GraphSampler`
class and the :py:class:`~fgutils.proxy.ProxyGroup` constructor. By default a
pattern has one anchor at index 0. If you need more control over how a subgraph
is inserted into a parent graph you can instantiate the
:py:class:`~fgutils.proxy.ProxyGraph` class. For a ProxyGraph you can provide a
list of anchor node indices. The insertion of the subgraph into the parent
depends on the number of anchor nodes in the subgraph and the number of edges
to the labeled node in the parent. The first edge in the parent connects to the
first anchor node in the subgraph and so forth. The following example
demonstrates the insertion with multiple anchor nodes::

import matplotlib.pyplot as plt
from fgutils.proxy import MolProxy, ProxyGroup, ProxyGraph, Parser
from fgutils.vis import GraphVisualizer

pattern = "N{g}C{g}(O)C"
g_1 = ProxyGroup("g", ProxyGraph("C1CCCCC1", anchor=[1, 3]))
g_2 = ProxyGroup("g", ProxyGraph("C1CCCCC1", anchor=[1, 3, 4]))

parser = Parser()
proxy1 = MolProxy(pattern, g_1)
proxy2 = MolProxy(pattern, g_2)

parent_graph = parser(pattern)
mol1 = next(proxy1)
mol2 = next(proxy2)

vis = GraphVisualizer(show_edge_labels=False)
fig, ax = plt.subplots(1, 3, dpi=200, figsize=(20, 3))
vis.plot(parent_graph, ax[0], title="parent")
vis.plot(mol1, ax[1], title="2 anchor nodes")
vis.plot(mol2, ax[2], title="3 anchor nodes")
plt.show()

.. image:: figures/multiple_anchor_example.png
:width: 1000

Another extension to the SMILES notation is the encoding of bond changes. This
feature is required to model reaction mechanisms as ITS graph. Changing bonds
are surrounded by ``<>`` (e.g. ``<1, 2>`` for the formation of a double bond
from a single bond). The extended notation allows the automated generation of
reaction examples with complete atom-to-atom maps. The following code snippet
demonstrates the generation of a few Diels-Alder reactions. The **diene** and
**dienophile** groups can of course be extended to increase varaity of the
samples::


import random
import matplotlib.pyplot as plt
from fgutils.proxy import ProxyGroup, ProxyGraph, ReactionProxy
from fgutils.proxy_collection.common import common_groups
from fgutils.vis import plot_reaction, plot_its
from fgutils.chem.its import get_its


electron_donating_group = ProxyGroup(
"electron_donating_group",
["{methyl}", "{ethyl}", "{propyl}", "{aryl}", "{amine}"],
)
electron_withdrawing_group = ProxyGroup(
"electron_withdrawing_group",
["{alkohol}", "{ether}", "{aldehyde}", "{ester}", "{nitrile}"],
)
diene_group = ProxyGroup(
"diene",
ProxyGraph("C<2,1>C<1,2>C<2,1>C{electron_donating_group}", anchor=[0, 3]),
)
dienophile_group = ProxyGroup(
"dienophile",
ProxyGraph("C<2,1>C{electron_withdrawing_group}", anchor=[0, 1]),
)
groups = common_groups + [
electron_donating_group,
electron_withdrawing_group,
diene_group,
dienophile_group,
]

proxy = ReactionProxy("{diene}1<0,1>{dienophile}<0,1>1", groups)

n = 4
fig, ax = plt.subplots(n, 2, width_ratios=[2, 1], figsize=(20, n * 4))
for i, (g, h) in enumerate(random.sample(list(proxy), n)):
plot_reaction(g, h, ax[i, 0], title="Reaction")
plot_its(get_its(g, h), ax[i, 1], title="ITS Graph")
plt.tight_layout()
plt.show()

.. image:: figures/diels_alder_example.png
:width: 1000

This proxy can now generate Diels-Alder reaction samples. A few of the results
are shown in the figure above. On the left side the reaction and on the right
side the resulting ITS. The results are balanced and have complete atom-to-atom
maps. The atom-to-atom maps are correct as long as the configuration makes
sence in the chemical domain. Note that the synthesizability of the generated
samples can not be guaranteed. It soley depends on what ProxyGroups and
ProxyGraphs are configured. For a comprehensive Diels-Alder reaction proxy take
a look at the
:py:class:`~fgutils.proxy_collection.diels_alder_proxy.DielsAlderProxy` class
and the section TODO. This class is also able to generate negative Diels-Alder
reaction samples, i.e., reactions where a Diels-Alder graph transformation rule
is theoretically applicable but the reaction will never happen in reality.

.. note::

The ``electron_donating_group`` and ``electron_withdrawing_group`` serve as
a collection of other groups to simplify the notation. They consist of a
single node with multiple labels. When iterating the next sample from the
proxy the labeled nodes get replaced by the pattern from one of the groups.
The group/label is chosen randomly with uniform distribution.


.. warning::

The call ``list(proxy)`` will generate all possible instantiations at once.
Depending on the configuration this can take a long time to complete. If the
core ProxyGroup graph sampling is not unique this can even result in an
endless loop.
16 changes: 16 additions & 0 deletions _sources/index.rst.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.. FGUtils documentation master file, created by
sphinx-quickstart on Tue Aug 20 09:10:34 2024.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to FGUtils's documentation!
===================================

.. toctree::
:maxdepth: 1

getting_started
functional_groups
graph_syntax
proxy_collection
references
Loading

0 comments on commit d4eda43

Please sign in to comment.