Skip to content

Commit

Permalink
GraphDescriptors (#6)
Browse files Browse the repository at this point in the history
* add graph_descriptors

* update doc
  • Loading branch information
TieuLongPhan authored Oct 23, 2024
1 parent 168b806 commit 3a17786
Show file tree
Hide file tree
Showing 7 changed files with 610 additions and 3 deletions.
Empty file added Test/SynGraph/__init__.py
Empty file.
176 changes: 176 additions & 0 deletions Test/SynGraph/test_graph_descriptors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
import unittest
import networkx as nx
from synutility.SynGraph.graph_descriptors import GraphDescriptor


class TestGraphDescriptor(unittest.TestCase):

def setUp(self):
# Creating different types of graphs
self.acyclic_graph = nx.balanced_tree(
r=2, h=3
) # Creates a balanced binary tree, which is acyclic
self.single_cyclic_graph = nx.cycle_graph(5) # Creates a cycle with 5 nodes
self.complex_cyclic_graph = (
nx.house_x_graph()
) # Known small graph with multiple cycles
self.empty_graph = nx.Graph() # Empty graph for testing

# Set up the graph
self.graph = nx.Graph()
self.graph.add_node(
11,
element="N",
charge=0,
hcount=1,
aromatic=False,
atom_map=11,
isomer="N",
partial_charge=-0.313,
hybridization="SP3",
in_ring=True,
explicit_valence=3,
implicit_hcount=0,
neighbors=["C", "C"],
)
self.graph.add_node(
35,
element="H",
charge=0,
hcount=0,
aromatic=False,
atom_map=11,
isomer="N",
partial_charge=0,
hybridization="0",
in_ring=False,
explicit_valence=0,
implicit_hcount=0,
)
self.graph.add_node(
28,
element="C",
charge=0,
hcount=0,
aromatic=True,
atom_map=28,
isomer="N",
partial_charge=0.063,
hybridization="SP2",
in_ring=True,
explicit_valence=4,
implicit_hcount=0,
neighbors=["Br", "C", "C"],
)
self.graph.add_node(
29,
element="Br",
charge=0,
hcount=0,
aromatic=False,
atom_map=29,
isomer="N",
partial_charge=-0.047,
hybridization="SP3",
in_ring=False,
explicit_valence=1,
implicit_hcount=0,
neighbors=["C"],
)

# Adding edges with their attributes
self.graph.add_edge(11, 35, order=(1.0, 0), standard_order=1.0)
self.graph.add_edge(11, 28, order=(0, 1.0), standard_order=-1.0)
self.graph.add_edge(35, 29, order=(0, 1.0), standard_order=-1.0)
self.graph.add_edge(28, 29, order=(1.0, 0), standard_order=1.0)
# Prepare the data dictionary
self.data = [{"RC": self.graph}]

def test_is_acyclic_graph(self):
self.assertTrue(GraphDescriptor.is_acyclic_graph(self.acyclic_graph))
self.assertFalse(GraphDescriptor.is_acyclic_graph(self.single_cyclic_graph))
self.assertFalse(GraphDescriptor.is_acyclic_graph(self.complex_cyclic_graph))
self.assertFalse(GraphDescriptor.is_acyclic_graph(self.empty_graph))

def test_is_single_cyclic_graph(self):
self.assertFalse(GraphDescriptor.is_single_cyclic_graph(self.acyclic_graph))
self.assertTrue(
GraphDescriptor.is_single_cyclic_graph(self.single_cyclic_graph)
)
self.assertFalse(
GraphDescriptor.is_single_cyclic_graph(self.complex_cyclic_graph)
)
self.assertFalse(GraphDescriptor.is_single_cyclic_graph(self.empty_graph))

def test_is_complex_cyclic_graph(self):
self.assertFalse(GraphDescriptor.is_complex_cyclic_graph(self.acyclic_graph))
self.assertFalse(
GraphDescriptor.is_complex_cyclic_graph(self.single_cyclic_graph)
)
self.assertTrue(
GraphDescriptor.is_complex_cyclic_graph(self.complex_cyclic_graph)
)
self.assertFalse(GraphDescriptor.is_complex_cyclic_graph(self.empty_graph))

def test_check_graph_type(self):
self.assertEqual(
GraphDescriptor.check_graph_type(self.acyclic_graph), "Acyclic"
)
self.assertEqual(
GraphDescriptor.check_graph_type(self.single_cyclic_graph), "Single Cyclic"
)
self.assertEqual(
GraphDescriptor.check_graph_type(self.complex_cyclic_graph),
"Combinatorial Cyclic",
)
self.assertEqual(
GraphDescriptor.check_graph_type(self.empty_graph), "Empty Graph"
)

def test_get_cycle_member_rings(self):
self.assertEqual(GraphDescriptor.get_cycle_member_rings(self.acyclic_graph), [])
self.assertEqual(
GraphDescriptor.get_cycle_member_rings(self.single_cyclic_graph), [5]
)
self.assertEqual(
GraphDescriptor.get_cycle_member_rings(self.complex_cyclic_graph),
[3, 3, 3, 3],
)
self.assertEqual(GraphDescriptor.get_cycle_member_rings(self.empty_graph), [])

def test_get_element_count(self):
# Expected results
expected_element_count = {"N": 1, "H": 1, "C": 1, "Br": 1}

# Test get_element_count
self.assertEqual(
GraphDescriptor.get_element_count(self.graph), expected_element_count
)

def test_get_descriptors(self):
# Expected output after processing
expected_output = [
{
"RC": self.graph,
"topo": "Single Cyclic", # Adjust based on expected graph type analysis
"cycle": [
4
], # Expected cycle results, to be filled after actual function implementation
"atom_count": {"N": 1, "H": 1, "C": 1, "Br": 1},
"rtype": "Elementary", # Expected reaction type
"rstep": 1, # This should be based on the actual cycles count
}
]

# Run the descriptor function
GraphDescriptor.get_descriptors(self.data, "RC")

# Validate that the data has been enhanced correctly
for obtained, expected in zip(self.data, expected_output):
print("Hi", obtained)
print("hiii", expected)
self.assertDictEqual(obtained, expected)


if __name__ == "__main__":
unittest.main()
67 changes: 65 additions & 2 deletions doc/getting_started.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,76 @@
.. _getting-started-synutility:

===============
Getting Started
===============

Welcome to the **synutility** documentation. This guide will assist you in setting up **synutility**, a versatile toolkit designed to streamline and enhance your workflows.

Introduction
------------

**synutility** is designed to provide tools and functions that simplify complex tasks and improve productivity. It is essential for professionals looking to optimize their processes efficiently.

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

Installing **synutility** is straightforward using pip, the Python package installer. For a more controlled and conflict-free environment, we recommend setting up **synutility** within a virtual environment.

Requirements
------------

Before installing **synutility**, ensure you have Python 3.11 or later installed on your machine. The use of a virtual environment is recommended to avoid conflicts with other Python packages.

Creating a Virtual Environment (Optional)
-----------------------------------------

Setting up a virtual environment for **synutility** is an optional but recommended step. It isolates the installation and dependencies of **synutility** from other Python projects, which helps prevent conflicts and maintain a clean workspace.

1. **Create a virtual environment**:

Use the following command to create a virtual environment named `synutility_env`. This step requires the `conda` package manager, which can be installed via the Anaconda distribution.

.. code-block:: bash
conda create -n synutility_env python=3.11
2. **Activate the virtual environment**:

Once the environment is created, activate it using:

.. code-block:: bash
conda activate synutility_env
Installing **synutility** via Pip
---------------------------------

After setting up and activating your virtual environment, install **synutility** using pip by running the following command:

.. code-block:: bash
pip install synutility
This command will download and install the latest version of **synutility** along with its required dependencies.

Getting Started with **synutility**
===================================

After installation, you can begin using **synutility** by importing it into your Python scripts or interactive sessions. Here’s a quick example to get you started:

.. code-block:: python
import synutility
result = synutility.example_function('Hello, World!')
print(result)
Further Resources
=================

Spliting Functions
==================
For more detailed documentation, usage examples, and API guides, visit the [official **synutility** documentation](https://tieulongphan.github.io/SynUtils).

Support
-------

If you encounter any issues or require assistance, please refer to the community support forums or file an issue on the [**synutility** GitHub page](https://github.com/TieuLongPhan/SynUtils/issues).

Empty file added synutility/SynGraph/__init__.py
Empty file.
Loading

0 comments on commit 3a17786

Please sign in to comment.