Skip to main content

A package to describe and optimize for emergent behavior using chemical reaction networks (CRNs). Capable of incorporating empirical data for more precise CRN models.

Project description

EmergeX logo

EmergeX

EmergeX is a Python library for building chemical reaction networks (CRNs), simulating their dynamics, and optimizing model parameters against either desired emergent behaviors or experimental time-course data. It supports workflows where you define a reaction system, specify what the system should do, and then use gradient-based optimization to search for parameters that produce that outcome. The library supports a built-in parameter fitting pipeline. Examples of experiment fitting API implementation are coming soon (> Version 1.0.0).

Example outputs

As an example, we provide the output visualizations of the workflow shown in examples/optimizeBehaviors/smallCRN.py under assets, and are shown below. First, establish the reaction network you wish to implement. For reference, we will use the following reaction network landscape in this demonstration:

Small CRN network topology

What EmergeX does

EmergeX is organized around six main pieces:

  1. emergex.crn Build CRNs from Reaction, Component, and ReactionNetwork.
  2. emergex.core Define time spans, interruptions, simulation settings, and CRN metadata.
  3. emergex.behaviors Describe desired HIGH and LOW behaviors over selected time windows.
  4. emergex.experiments Fit model outputs to experimental signals.
  5. emergex.optimization Select free and linked parameters, then run optimization.
  6. emergex.visualization Generate plots and MP4 animations from optimization results.

This supports designing a CRN that exhibits a target behavior, and fitting a CRN model to experimental data.

Basic workflow

The standard workflow is:

  1. Build a reaction network.
  2. Define the simulation time course, including any staged additions or perturbations.
  3. Specify either target behaviors or experimental signals.
  4. Select the parameters that are allowed to vary.
  5. Run optimization.
  6. Save the result and generate visualizations.

Building a reaction network

At the lowest level, EmergeX works with reactions, components, and a reaction network container.

from emergex import Reaction, Component, ReactionNetwork

combineAB = Reaction(5e-5, "A + B -> C")
cdComplex = Reaction(1e-2, "C + D <-> CD", backwardRate = 1e0)
makeE = Reaction(3e-2, "CD -> D + E")

compA = Component("A", 100)
compB = Component("B", 80)
compD = Component("D", 5)

network = ReactionNetwork()
network.addRxns([combineAB, cdComplex, makeE])
network.addComponents([compA, compB, compD])

Important notes:

  • EmergeX does not impose units, so concentration and rate units must be internally consistent.
  • Stoichiometry is represented by repeating species names rather than by coefficients.

Direct simulation

For straightforward simulation without optimization:

network.simulateReactionFn(600, simDataResolution=201)
result = network.SimResults[-1]

This is the simplest way to inspect trajectories and verify that the network behaves sensibly before adding optimization targets.

Time spans and interruptions

EmergeX is designed for multi-step experiments where materials may be added or conditions changed during the run. A time course can be created with discontinuous changes to reaction conditions based on a pre-defined schedule.

from emergex import TimeSpan, Interruption

interrupt = Interruption(network.Components["B"], 40, interruptionType="ADD")
time_course = [
    TimeSpan(3600),
    TimeSpan(3600, [interrupt]),
]

This allows you to model pulse additions, delayed stimuli, or other multi-stage protocols.

Optimizing for behaviors

Behavior optimization is the main design workflow shown in the provided examples.

Define target behaviors

Behaviors are expressed as time windows in which a normalized signal should be high or low.

from emergex import Behavior, BehaviorGroup, BehaviorTimeCourse

def normalize_by_D(x, concs):
    return x / concs["D"]

behaviorTimeCourseObj = BehaviorTimeCourse(
    time_course,
    [
        BehaviorGroup(
            "CD",
            [
                Behavior("HIGH", 0.1 * 7200, 0.4 * 7200),
                Behavior("LOW", 0.5 * 7200, 1.0 * 7200),
            ],
            normalizeFn = normalize_by_D,
        )
    ],
)

This behavior time course describes the landscape shown in the top-left quadrant: Small CRN behavior landscape

The main abstractions are:

  • Behavior: One target state over the defined interval.
  • BehaviorGroup: The species being evaluated and the normalization rule used to score it.
  • BehaviorTimeCourse: The experiment schedule paired with the behavior groups to evaluate.

Expose free and linked parameters

The optimization run will only make use of the parameters you explicitly provide. Using the prior defined reaction and component variables, we can instatiate a list of free parameters as shown below.

from emergex import FreeParameter, LinkedParameter

freeParams = [
    FreeParameter(combineAB),
    FreeParameter(cdComplex),
    FreeParameter(makeE),
    FreeParameter(compB),
]

Use LinkedParameter when a value should be derived from another concentration or rate rather than optimized independently.

Run the optimization

from emergex import (
    CRNInfoHandler,
    OptimizeBehaviorsManager,
    CRNSimulationRunner,
    CRNOptimizationFramework,
    CompiledOptimizationData,
)

manager = OptimizeBehaviorsManager(
    CRNInfoHandler(network),
    [behaviorTimeCourseObj],
)

simuRunner = CRNSimulationRunner()
optimizer = CRNOptimizationFramework(freeParams)

result = CompiledOptimizationData(
    manager,
    simRunner,
    optimizer,
    iterationCount = 100,
    callbackFrequency = 4,
)

CompiledOptimizationData stores the optimization objective, the simulation runner, the optimization framework, and the recorded optimization history in one object.

Saving and reloading runs

Optimization runs can be saved and reloaded later.

result.save(DATA_STORE, "smallCRNOptResult")
loadedResult = CompiledOptimizationData.load(DATA_STORE / "smallCRNOptResult.pkl")

This is useful because the saved object includes dynamic helper logic such as normalization functions, interruption logic, and linked-parameter relationships.

Fitting experimental data

EmergeX also supports fitting CRN models to measured signals instead of optimizing against abstract behavior windows.

This workflow uses:

  • Signal to define a measured observable and how it is normalized,
  • Experiment to combine one or more signals over a time course,
  • ExperimentGroup to collect compatible experiments with shared evaluation times and CRN structure,
  • OptimizeExperimentsManager to turn those experiment groups into an optimization objective.

In this mode, the optimizer minimizes the mismatch between simulated normalized trajectories and supplied data points. An example of this facet of the library will be made public within the next few versions.

Visualization

EmergeX includes utilities for turning optimization runs into figures and videos.

from emergex import (
    saveBehaviorLandscapeVisualization,
    saveFreeParametersVisualization,
    saveBehaviorResultsVisualization,
    saveExperimentResultsVisualization,
)

Typical usage:

saveBehaviorLandscapeVisualization(
    manager,
    fileLocation = DATA_STORE,
    fileName = "smallCRN_landscape",
    timeUnits = "min",
)

saveFreeParametersVisualization(
    result,
    iterationList = [1, 5, 10, 20, 50, 100],
    fileLocation = DATA_STORE,
    fileName = "smallCRN_parameters",
    fps = 6,
)

saveBehaviorResultsVisualization(
    result,
    iterationList = [1, 5, 10, 20, 50, 100],
    fileLocation = DATA_STORE,
    fileName = "smallCRN_behaviors",
    fps = 6,
    timeUnits = "min",
)

Parameter evolution during optimization

Behavior evolution during optimization

With stacking:

Repository examples

The fastest way to learn the package is to run the included examples:

  • examples/crnDemonstration/smallCRN.py Direct CRN construction and simulation.
  • examples/optimizeBehaviors/smallCRN.py Minimal end-to-end behavior optimization example.
  • examples/optimizeBehaviors/loadSmallCRN.py Reload a saved optimization result and regenerate visualizations.
  • examples/optimizeBehaviors/oscillate.py A more involved behavior-optimization example.

If you are new to EmergeX, start with the small CRN demonstration first, then move to the small CRN behavior optimization example.

Citation

If you use EmergeX in your work, we request that you cite the software and include the exact version or commit used in your study.

Suggested citation:

Yancey, C., Kolisko, C., & Schulman, R. (2026). EmergeX (Version [Version that you use]) [Computer software]. GitHub. https://github.com/Yancey-Colin/EmergeX

Suggested BibTeX:

@software{yancey_kolisko_schulman_emergex_2026,
  author = {Yancey, Colin and Kolisko, Cameron and Schulman, Rebecca},
  title = {EmergeX},
  year = {2026},
  version = {1.0.0},
  url = {https://github.com/Yancey-Colin/EmergeX},
  note = {Computer software}
}

Repository metadata for citation is also provided in CITATION.cff. Thank you!

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

emergex-1.0.0.tar.gz (40.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

emergex-1.0.0-py3-none-any.whl (49.3 kB view details)

Uploaded Python 3

File details

Details for the file emergex-1.0.0.tar.gz.

File metadata

  • Download URL: emergex-1.0.0.tar.gz
  • Upload date:
  • Size: 40.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for emergex-1.0.0.tar.gz
Algorithm Hash digest
SHA256 b7f3d83ad8588ec3ad9ebaf417994819d88780922f293d4fa88cfa0982b98e1f
MD5 59338edab48c2bb9e78c3b8700aad77b
BLAKE2b-256 04bd1096442c522542a3575d9f258c77d07ac5856e1e18925336513c8b9d9e0c

See more details on using hashes here.

File details

Details for the file emergex-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: emergex-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 49.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for emergex-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7a887982c54830c4d54dcc9d27983a19a9b3b1cca2e5a26961ae2b94e9c7997f
MD5 fd5b94dee864d06342d98eea148a3c6c
BLAKE2b-256 171f58778838888669e36abd39de46ba268c99185f213f2aaa1c6c9ba1983b71

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page