Package: mmodel
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
themrfmsimon how mmodel improves the development of magnetic resonance force
microscopy (MRFM) experiments.QuickstartTo create a nonlinear model that has the result of(x + y)log(x + y, base):importmathimportnumpyasnpdeffunc(sum_xy,log_xy):"""Function that adds a value to the multiplied inputs."""returnsum_xy*log_xy+6The graph is defined using grouped edges (thenetworkxsyntax of edge
the definition also works.)frommmodelimportModelGraph,Model,MemHandler# create graph edgesgrouped_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 objectsnode_objects=[("add",np.add,"sum_xy",["x","y"]),("log",math.log,"log_xy",["sum_xy","log_base"]),("function node",func,"result"),]G=ModelGraph(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,description="Test model.")The model behaves like a Python function, with additional metadata. The graph can
be plotted using thedrawmethod.>>>print(example_model)example_model(log_base,x,y)returns:zgraph:example_graphhandler:MemHandlerTestmodel.>>>example_model(2,5,3)# (5 + 3)log(5 + 3, 2) + 630.0>>>example_model.draw()The resulting graph contains the model metadata and detailed node information.One key feature ofmmodelthat differs from other workflow is modifiers,
which modify callables post definition. Modifiers work on both the node level
and model level.Example: Useloop_inputmodifier on the graph to loop the nodes that require the
“log_base” parameter.frommmodelimportloop_inputH=G.subgraph(inputs=["log_base"])H.name="example_subgraph"loop_node=Model("submodel",H,handler=MemHandler)looped_G=G.replace_subgraph(H,"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_zgraph:looped_graphhandler:MemHandler()>>>print(looped_model.node_metadata("loop_node"))submodel(log_base,sum_xy)return:looped_zfunctype:mmodel.Modelmodifiers:-loop_input('log_base')>>>looped_model([2,4],5,3)# (5 + 3)log(5 + 3, 2) + 6[30.0,18.0]Use thedrawmethod to draw the graph. There are three styles
“plain”, “short”, and “verbose”, which differ by the level of detail of the
node information. A graph output is displayed in Jupyter Notebook
or can be saved using the export option.G.draw(style="short")example_model.draw(style="plain",export="example.pdf")# default to draw_graphInstallationGraphviz installationTo view the graph, Graphviz needs to be installed:Graphviz InstallationFor windows installation, please choose “add Graphviz to the
system PATH for all users/current users” during the setup.MModel installationpip install mmodelDevelopment installationMModel usespoetryas
the build system. The package works with both pip and poetry
installation. For macos systems, sometimesbrew installresults
in unexpected installation path, it is recommended to install
with conda:conda install -c conda-forge pygraphvizTo install test and docs, despondencies run:pip install .[test] .[docs]To run the tests in different python environments and cases
(py38, py39, py310, py311, coverage and docs):toxTo create the documentation, run under the “/docs” directory:make html