From f89a208f278d84bf90ed7417b42ebf64ba9b8e39 Mon Sep 17 00:00:00 2001 From: Stefan Badelt Date: Thu, 13 Feb 2020 15:42:51 -0800 Subject: [PATCH] update get_integrator function, documentation, ode_plotter --- LICENSE | 2 +- README.md | 48 +++++++++++++++++++++------------ crnsimulator/__init__.py | 2 +- crnsimulator/odelib_template.py | 9 ++++--- crnsimulator/solver.py | 30 ++++++++++++++++----- scripts/crnsimulator | 2 +- setup.py | 4 +-- tests/test_solver.py | 4 +-- 8 files changed, 68 insertions(+), 33 deletions(-) diff --git a/LICENSE b/LICENSE index 9d039e2..b7766fa 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2017 Stefan Badelt +Copyright (c) 2017-2020 Stefan Badelt Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/README.md b/README.md index ebb0969..1554df2 100644 --- a/README.md +++ b/README.md @@ -8,17 +8,18 @@ equations (ODEs). Create a test file with your CRN: -File: ozzy.crn +File: [oscillator.crn] ``` -# Oscillator Test +# Rock-Paper-Scissors Oscillator + A + B -> B + B [k = 0.2] -B + C -> C + C [k = 0.3] -C + A -> A + A [k = 1] +B + C -> C + C [k = 0.4] +C + A -> A + A [k = 0.7] ``` And pipe it into the crnsimulator: ```sh -~$ crnsimulator -o ozzy < ozzy.crn +~$ crnsimulator -o ozzy < oscillator.crn ``` This writes the ODE system to an executable python script: `ozzy.py` @@ -35,7 +36,7 @@ You can pass the command line options for ozzy.py directly to `crnsimulator`. This will automatically simulate your ODE system. Use --force to overwrite an existing `ozzy.py` script. ```sh -~$ crnsimulator --p0 A=0.1 B=1e-2 C=1e-3 --t8 10000 -o ozzy --pyplot ozzy.pdf < ozzy.crn +~$ crnsimulator --p0 A=0.1 B=1e-2 C=1e-3 --t8 10000 -o ozzy --pyplot ozzy.pdf < oscillator.crn ``` You can specify the CRN in a single line: @@ -69,21 +70,38 @@ However, here is a small example using the above oscillating CRN. [['B', 'C'],['C','C'],0.8], [['C', 'A'],['A','A'],0.9]] >>> RG = ReactionGraph(crn) ->>> filename, odename = RG.write_ODE_lib(filename='ozzy.py') +>>> svars = ['B', 'C', 'A'] # let's enforce the order of species, because we can! +>>> filename, odename = RG.write_ODE_lib(filename='ozzy.py', sorted_vars = svars) >>> print('Wrote ODE system file:', filename) Wrote ODE system file: ozzy.py ``` -Then go ahead and execute `ozzy.py` +Then go ahead and execute `ozzy.py`: ```sh -~$ python ./ozzy.py --p0 1=1e-6 2=2e-6 3=5e-6 --t8 1e8 --pyplot ozzy.pdf +~$ python ./ozzy.py --p0 1=1e-6 2=2e-6 3=5e-6 --t8 1e8 --pyplot ozzy.pdf --atol 1e-10 --rtol 1e-10 ``` -... or load it as python library. +... or load its functions by treating it as a python library: + +```py +# Import +>>> import numpy as np +>>> from scipy.integrate import odeint +>>> from crnsimulator import get_integrator +>>> odesys = get_integrator(filename, function = odename) +>>> odeplt = get_integrator(filename, function = 'ode_plotter') +# Simulate +>>> p0 = [1e-6, 2e-6, 5e-6] # order of svars +>>> time = np.linspace(0, 1e8, num = 10_000) +>>> ny = odeint(odesys, p0, time, (None,), atol = 1e-10, rtol = 1e-10).T +# Plot +>>> odeplt(`ozzy.pdf`, time, ny, svars) +``` +... or include the prebuilt integrator in you own script (like the crnsimulator exectuable): ```py >>> from crnsimulator import get_integrator ->>> integrate = get_integrator(odename, filename) +>>> integrate = get_integrator(filename) >>> integrate(args) # args = ``` @@ -92,12 +110,8 @@ Then go ahead and execute `ozzy.py` ```sh ~$ python setup.py install ``` - -### local installation -```sh -~$ python setup.py install --user -``` ## Version -0.7 +0.7.1 +[oscillator.crn]: diff --git a/crnsimulator/__init__.py b/crnsimulator/__init__.py index 6df44b0..a9f690f 100644 --- a/crnsimulator/__init__.py +++ b/crnsimulator/__init__.py @@ -6,7 +6,7 @@ # Use at your own risk. # # -__version__ = "v0.7" +__version__ = "v0.7.1" from crnsimulator.crn_parser import parse_crn_string, parse_crn_file from crnsimulator.reactiongraph import ReactionGraph diff --git a/crnsimulator/odelib_template.py b/crnsimulator/odelib_template.py index 1a13bfb..87fb739 100644 --- a/crnsimulator/odelib_template.py +++ b/crnsimulator/odelib_template.py @@ -26,8 +26,8 @@ sns.set(style="darkgrid", font_scale=1, rc={"lines.linewidth": 2.0}) -def ode_plotter(name, t, ny, svars, log=False, labels=None, - xlim=None, ylim=None): +def ode_plotter(name, t, ny, svars, log = False, labels = None, + xlim = None, ylim = None, plim = None): """ Plots the ODE trajectories. Args: @@ -37,6 +37,9 @@ def ode_plotter(name, t, ny, svars, log=False, labels=None, svars (list[str]): A list of names for every trajectory in ny log (bool,optional): Plot data on a logarithmic time scale labels (set(),optional): Define species that appear labelled in the plot + xlim ((float,float), optional): matplotlib xlim. + ylim ((float,float), optional): matplotlib ylim. + plim (float, optional): Minimal occupancy to plot a trajectory. Defaults to None. Prints: A file containing the plot (Format *.pdf, *.png, etc.) @@ -74,7 +77,7 @@ def ode_plotter(name, t, ny, svars, log=False, labels=None, ax.plot(t, y, '--', lw=0.1, color='gray', zorder=1) else: for e, y in enumerate(ny): - if max(y) > 0.05: + if plim is None or max(y) > plim: ax.plot(t, y, '-', label=svars[e]) else: ax.plot(t, y, '--', lw=0.1, color='gray', zorder=1) diff --git a/crnsimulator/solver.py b/crnsimulator/solver.py index dca7c45..d25c2b6 100644 --- a/crnsimulator/solver.py +++ b/crnsimulator/solver.py @@ -11,13 +11,31 @@ import crnsimulator.odelib_template -def get_integrator(odename, filename): - """Workaround to avoid deprecation warnings for the imp module. +def get_integrator(filename, function = 'integrate'): + """ Wrapper for the jit import of a function from a python script. + + Note: The intended usage is to import the integrate function from the + executable produced by crnsimulator. However, it can be used to import + arbitrary functions from arbitrary python scripts. + + Args: + filename (str): The autogenerated python executable containing the odesystem. + function (str, optional): The name of the function to be imported. Defaults + to 'integrate', which is the main function of the file, but it can also + be used to import low-level functions such as 'odesystem' or 'ode_plotter'. + + Returns: + A jit import of the requested function. """ - loader = importlib.machinery.SourceFileLoader(odename, filename) - mod = types.ModuleType(loader.name) - loader.exec_module(mod) - return getattr(mod, 'integrate') + try: + loader = importlib.machinery.SourceFileLoader('my_loader', filename) + mod = types.ModuleType(loader.name) + loader.exec_module(mod) + except FileNotFoundError as err: + print(Warning('DEPRECATED - crnsimulator: Please note that the crnsimulator.solver.get_integrator function interface changed.')) + raise err + + return getattr(mod, function) def writeODElib(svars, odeM, jacobian=None, rdict=None, concvect=None, odename='odesystem', filename='./odesystem', template=None): diff --git a/scripts/crnsimulator b/scripts/crnsimulator index fc7c064..08abcfc 100644 --- a/scripts/crnsimulator +++ b/scripts/crnsimulator @@ -130,7 +130,7 @@ def main(args): print('# Simulating the ODE system, change parameters using:') print("# python {} --help ".format(filename)) - integrate = get_integrator(odename, filename) + integrate = get_integrator(filename) # ********************* # # ARGUMENT PROCESSING 2 # diff --git a/setup.py b/setup.py index fa3a992..c849108 100755 --- a/setup.py +++ b/setup.py @@ -9,13 +9,13 @@ setup( name = 'crnsimulator', - version = "0.7", + version = "0.7.1", description = 'Simulate CRNs using ODEs.', long_description = LONG_DESCRIPTION, author = 'Stefan Badelt', author_email = 'badelt@caltech.edu', url = 'https://github.com/bad-ants-fleet/crnsimulator', - download_url = 'https://github.com/bad-ants-fleet/crnsimulator/archive/v0.7.tar.gz', + download_url = 'https://github.com/bad-ants-fleet/crnsimulator/archive/v0.7.1.tar.gz', license = 'MIT', classifiers = [ 'Development Status :: 3 - Alpha', diff --git a/tests/test_solver.py b/tests/test_solver.py index 224cb04..364ec79 100644 --- a/tests/test_solver.py +++ b/tests/test_solver.py @@ -46,7 +46,7 @@ def test_crn(self): RG = ReactionGraph(crn) filename, odename = RG.write_ODE_lib(filename=self.filename) - integrate = get_integrator(odename, filename) + integrate = get_integrator(filename) self.args.p0 = ['1=0.5'] self.args.t_log = 10 @@ -85,7 +85,7 @@ def test_crn_sympy_imports(self): RG = ReactionGraph(crn) filename, odename = RG.write_ODE_lib(filename=self.filename) - integrate = get_integrator(odename, filename) + integrate = get_integrator(filename) self.args.p0 = ['S=0.5', 'cos=0.2'] self.args.t_log = 10