mmodel#

GitHub version PyPI version shields.io PyPI pyversions Unittests DOI

mmodel is a lightweight and modular model-building framework for small-scale and nonlinear models. The package aims to solve scientific program prototyping and distribution difficulties, making it easier to create modular, fast, and user-friendly packages.

For using mmodel in a complex scientific workflow, please refer to the mrfmsim on how mmodel improves the development of magnetic resonance force microscopy (MRFM) experiments.

Quickstart#

To create a nonlinear model that has the result of (x + y)log(x + y, base):

import math
import numpy as np

def func(sum_xy, log_xy):
    """Function that adds a value to the multiplied inputs."""

    return sum_xy * log_xy + 6

The graph is defined using grouped edges (the NetworkX syntax of edge the definition also works.)

from mmodel import Graph, Model, Node, MemHandler
# create graph edges
grouped_edges = [
    ("add", ["log", "function node"]),
    ("log", "function node"),
]

The functions are then added to node attributes. The order of definition is node_name, node_func, output, input (if different from original function), and modifiers.

# define note objects
node_objects = [
    Node("add", np.add, ["x", "y"], "sum_xy"),
    Node("log", math.log,  ["sum_xy", "log_base"], "log_xy"),
    Node("function node", func, output="result"),
]

G = Graph(name="example_graph")
G.add_grouped_edges_from(grouped_edges)
G.set_node_objects_from(node_objects)

To define the model, the name, graph, and handler need to be specified. Additional parameters include modifiers, descriptions, and returns lists. The input parameters of the model are determined based on the node information.

example_model = Model("example_model", G, handler=MemHandler, doc="Test model.")

The model behaves like a Python function with additional metadata. The graph can be plotted using the visualize method.

>>> print(example_model)
example_model(log_base, x, y)
returns: result
graph: example_graph
handler: MemHandler

Test model.

>>> example_model(2, 5, 3) # (5 + 3)log(5 + 3, 2) + 6
30.0

>>> example_model.visualize()

The resulting graph contains the model metadata and detailed node information.

One key feature of mmodel that differs from other workflows is modifiers, which modify callables post-definition. Modifiers work on both the node level and model level.

Example: Use loop_input modifier on the graph to loop the nodes that require the “log_base” parameter.

from mmodel.modifier import loop_input

H = G.subgraph(inputs=["log_base"])
H.name = "example_subgraph"
loop_node = Model("submodel", H, handler=MemHandler)

looped_G = G.replace_subgraph(
    H,
    Node("loop_node", loop_node, output="looped_z", modifiers=[loop_input("log_base")]),
)
looped_G.name = "looped_graph"

looped_model = Model("looped_model", looped_G, loop_node.handler)

We can inspect the loop node as well as the new model.

>>> print(looped_model)
looped_model(log_base, x, y)
returns: looped_z
graph: looped_graph
handler: MemHandler

>>> print(looped_model.get_node_object("loop_node"))
submodel(log_base, sum_xy)
return: looped_z
functype: <class 'mmodel.model.Model'>
modifiers:
- loop_input('log_base')

>>> looped_model([2, 4], 5, 3) # (5 + 3)log(5 + 3, 2) + 6
[30.0, 18.0]

Use the visualize method to draw the graph. For a graph, a simple diagram with only node names shown, and for a model, the diagram shows detailed node and model information. Customized plotting objects can be created using the Visualizer class.

G.visualize()
# draw the graph and output to a pdf file
example_model.visualize(outfile="example.pdf")

Installation#

Graphviz installation#

To view the graph, Graphviz needs to be installed: Graphviz Installation For Windows installation, please choose “add Graphviz to the system PATH for all users/current users” during the setup.

For macOS systems, sometimes brew install results in an unexpected installation path, it is recommended to install with conda:

conda install -c conda-forge pygraphviz

MModel installation#

pip install mmodel

Development installation#

MModel uses poetry as the build system. The package works with both pip and poetry installation.

To install dependencies for “test” and “docs”:

pip install .[test] .[docs]

To run the tests in different Python environments and cases (py310, py311, coverage and docs):

tox

To create the documentation, run under the “/docs” directory:

make html

Citing mmdoel#

The work was published in the Journal of Chemical Physics.

BibTex:

@article{Sun2023jul,
  title = {mmodel: A Workflow Framework to Accelerate the Development of Experimental Simulations},
  author = {Sun, Peter and Marohn, John A.},
  year = {2023},
  month = {Jul},
  journal = {The Journal of Chemical Physics},
  volume = {159},
  number = {4},
  pages = {044801},
  doi = {10.1063/5.0155617},
  url = {https://pubs.aip.org/jcp/article/159/4/044801/2904249/mmodel-A-workflow-framework-to-accelerate-the}
}

License#

MModel is distributed with the 3-clause BSD license.:

Copyright (C) 2022 - 2024
Peter Sun <hs859@cornell.edu>
John Marohn <jam99@cornell.edu>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

* Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above
    copyright notice, this list of conditions and the following
    disclaimer in the documentation and/or other materials provided
    with the distribution.

* Neither the name of the NetworkX Developers nor the names of its
    contributors may be used to endorse or promote products derived
    from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Indices and tables#