genice_core API documentation
Description: ![Logo](https://raw.githubusercontent.com/vitroid/GenIce/develop/logo/genice-v0.png) …

# Package `genice_core`

# GenIce-core

Core algorithms of GenIce2

version 0.5.1

## Requirements

- numpy
- networkx

## Installation

GenIce-core is registered to PyPI (Python Package Index). Install with pip3.

    pip3 install genice-core

## Uninstallation

    pip3 uninstall genice-core

## API

API manual is here.

## Examples

Make an ice graph from a given undirected graph.

    import networkx as nx
    import matplotlib
    import genice_core

    # np.random.seed(12345)

    g = nx.dodecahedral_graph()  # dodecahedral 20mer
    pos = nx.spring_layout(g)

    # set orientations of the hydrogen bonds.
    dg = genice_core.ice_graph(g)

    nx.draw_networkx(dg, pos)

## Algorithms and how to cite them.

The algorithms to make a depolarized hydrogen-disordered ice are explained in these papers:

M. Matsumoto, T. Yagasaki, and H. Tanaka,"GenIce: Hydrogen-Disordered Ice Generator", J. Comput. Chem. 39, 61-64 (2017). DOI: 10.1002/jcc.25077

    @article{Matsumoto:2017bk,
        author = {Matsumoto, Masakazu and Yagasaki, Takuma and Tanaka, Hideki},
        title = {GenIce: Hydrogen-Disordered Ice Generator},
        journal = {Journal of Computational Chemistry},
        volume = {39},
        pages = {61-64},
        year = {2017}
    }

M. Matsumoto, T. Yagasaki, and H. Tanaka, “Novel Algorithm to Generate Hydrogen-Disordered Ice Structures.”, J. Chem. Info. Modeling 61 (6): 2542–46 (2021). DOI:10.1021/acs.jcim.1c00440

    @article{Matsumoto:2021,
        author = {Matsumoto, Masakazu and Yagasaki, Takuma and Tanaka, Hideki},
        title = {Novel Algorithm to Generate Hydrogen-Disordered Ice Structures},
        journal = {Journal of Chemical Information and Modeling},
        volume = {61},
        pages = {2542-2546},
        year = {2021}
    }

## How to contribute

GenIce has been available as open source software on GitHub(https://github.com/vitroid/GenIce) since 2015. Feedback, suggestions for improvements and enhancements, bug fixes, etc. are sincerely welcome. Developers and test users are also welcome. If you have any ice that is publicly available but not included in GenIce, please let me know.

Expand source code

    """
    .. include:: ../README.md
    """

    """
    Optimizes the orientations of directed paths to reduce the net dipole moment.
    """
    import numpy as np
    import networkx as nx
    from genice_core.topology import noodlize, split_into_simple_paths, balance
    from genice_core.dipole import optimize, vector_sum
    from typing import Union
    from logging import getLogger

    def ice_graph(
        g: nx.Graph,
        vertexPositions: Union[np.ndarray, None] = None,
        isPeriodicBoundary: bool = False,
        dipoleOptimizationCycles: int = 0,
        fixedEdges: Union[nx.DiGraph, None] = nx.DiGraph(),
        hook=None,
    ) -> nx.DiGraph:
        """Make a digraph that obeys the ice rules.

        A new algorithm suggested by Prof. Sakuma, Yamagata University.

        Args:
            g (nx.Graph): A ice-like undirected graph.
            vertexPositions (Union[nx.ndarray, None], optional): Positions of the vertices. Defaults to None.
            isPeriodicBoundary (bool, optional): If True, the positions are considered to be in the fractional coordinate system. Defaults to False.
            dipoleOptimizationCycles (int, optional): Number of iterations to reduce the net dipole moment. Defaults to 0 (no iteration).
            fixed (Union[nx.DiGraph, None], optional): A digraph made of edges whose directions are fixed. All edges in fixed must also be included in g. Defaults to an empty graph.

        Returns:
            nx.DiGraph: An ice graph (fixed part is excluded).
        """
        logger = getLogger()

        logger.debug(g)
        logger.debug(fixedEdges)

        if fixedEdges is not None:
            balance(fixedEdges, g, hook=hook)

        # Divide the graph into noodle graph
        dividedGraph = noodlize(g, fixedEdges)

        # Simplify paths ( paths with least crossings )
        paths = list(split_into_simple_paths(len(g), dividedGraph))

        # arrange the orientations here if you want to balance the polarization
        if vertexPositions is not None:
            if fixedEdges is not None:
                # Set the targetPol in order to cancel the polarization in fixed.
                targetPol = -vector_sum(fixedEdges, vertexPositions, isPeriodicBoundary)
            else:
                targetPol = np.zeros(3)

            paths = optimize(
                paths,
                vertexPositions,
                isPeriodicBoundary=isPeriodicBoundary,
                dipoleOptimizationCycles=dipoleOptimizationCycles,
                targetPol=targetPol,
            )

        # paths to digraph
        dg = nx.DiGraph([(i, j) for path in paths for i, j in zip(path, path[1:])])
        return dg

## Sub-modules

`genice_core.dipole`

  Optimizes the orientations of directed paths to reduce the net dipole moment.

`genice_core.topology`

  Arrange edges appropriately.

## Functions

`def ice_graph(g: networkx.classes.graph.Graph, vertexPositions: Optional[numpy.ndarray] = None, isPeriodicBoundary: bool = False, dipoleOptimizationCycles: int = 0, fixedEdges: Optional[networkx.classes.digraph.DiGraph] = <networkx.classes.digraph.DiGraph object>, hook=None) ‑> networkx.classes.digraph.DiGraph`

  Make a digraph that obeys the ice rules.

  A new algorithm suggested by Prof. Sakuma, Yamagata University.

  ## Args

  `g` :`nx.Graph`
    A ice-like undirected graph.
  `vertexPositions` :`Union[nx.ndarray, None]`, optional
    Positions of the vertices. Defaults to None.
  `isPeriodicBoundary` :`bool`, optional
    If True, the positions are considered to be in the fractional coordinate system. Defaults to False.
  `dipoleOptimizationCycles` :`int`, optional
    Number of iterations to reduce the net dipole moment. Defaults to 0 (no iteration).
  `fixed` :`Union[nx.DiGraph, None]`, optional
    A digraph made of edges whose directions are fixed. All edges in fixed must also be included in g. Defaults to an empty graph.

  ## Returns

  `nx.DiGraph`
    An ice graph (fixed part is excluded).
  Expand source code

      def ice_graph(
          g: nx.Graph,
          vertexPositions: Union[np.ndarray, None] = None,
          isPeriodicBoundary: bool = False,
          dipoleOptimizationCycles: int = 0,
          fixedEdges: Union[nx.DiGraph, None] = nx.DiGraph(),
          hook=None,
      ) -> nx.DiGraph:
          """Make a digraph that obeys the ice rules.

          A new algorithm suggested by Prof. Sakuma, Yamagata University.

          Args:
              g (nx.Graph): A ice-like undirected graph.
              vertexPositions (Union[nx.ndarray, None], optional): Positions of the vertices. Defaults to None.
              isPeriodicBoundary (bool, optional): If True, the positions are considered to be in the fractional coordinate system. Defaults to False.
              dipoleOptimizationCycles (int, optional): Number of iterations to reduce the net dipole moment. Defaults to 0 (no iteration).
              fixed (Union[nx.DiGraph, None], optional): A digraph made of edges whose directions are fixed. All edges in fixed must also be included in g. Defaults to an empty graph.

          Returns:
              nx.DiGraph: An ice graph (fixed part is excluded).
          """
          logger = getLogger()

          logger.debug(g)
          logger.debug(fixedEdges)

          if fixedEdges is not None:
              balance(fixedEdges, g, hook=hook)

          # Divide the graph into noodle graph
          dividedGraph = noodlize(g, fixedEdges)

          # Simplify paths ( paths with least crossings )
          paths = list(split_into_simple_paths(len(g), dividedGraph))

          # arrange the orientations here if you want to balance the polarization
          if vertexPositions is not None:
              if fixedEdges is not None:
                  # Set the targetPol in order to cancel the polarization in fixed.
                  targetPol = -vector_sum(fixedEdges, vertexPositions, isPeriodicBoundary)
              else:
                  targetPol = np.zeros(3)

              paths = optimize(
                  paths,
                  vertexPositions,
                  isPeriodicBoundary=isPeriodicBoundary,
                  dipoleOptimizationCycles=dipoleOptimizationCycles,
                  targetPol=targetPol,
              )

          # paths to digraph
          dg = nx.DiGraph([(i, j) for path in paths for i, j in zip(path, path[1:])])
          return dg